While being on a small part-time work related to RMXP as a game designer, I encountered with a small problem, which is slightly slowed down the development process. I'm used Blizz-ABS as a combat system, but for the original concept it's need to use a script associated with a maps wrap - the use of "map-linker" scripts like Continuous Maps aren't suitable.
However, its compatibility with BABS isn't too good, but other similar scripts for RMXP with the needed effect simply isn't find.
Description of problems:
1) The scrolling of wrapped map isn't going on the standard way - when player approaches to the end of the map, camera centered on the player and showing a necessary part of the map in the window, but after the transfer to the other end of map camera sharply fast scrolls to the standard RMXP mode at this positions.
2) Sprite_Character class isn't good on compatibility - displaying of enemy sprites on the visible screen-part of the wrapped map doesn't happen - they appear only after the transfer to the other end of the map.
Other problems associated with the scripting part wasn't detected. That script is located above the BABS.
#--------------------------------------------------------------------------
# Game_Temp (edit)
# Script to check for "_wrap" in the map name.
#--------------------------------------------------------------------------
class Game_Temp
attr_reader :map_infos
attr_reader :outside_array
alias wrap_original_game_temp_initialize initialize
def initialize
wrap_original_game_temp_initialize
@map_infos = load_data("Data/MapInfos.rxdata")
@outside_array=Array.new
for key in @map_infos.keys
@outside_array[key]=@map_infos[key].name.include?("_wrap")
end
for key in @map_infos.keys
@map_infos[key] = @map_infos[key].name
@map_infos[key].delete!("_wrap")
end
end
end
#--------------------------------------------------------------------------
# Game_Map
#--------------------------------------------------------------------------
class Game_Map
attr_accessor :wrap
alias wrap_original_game_map_scroll_left scroll_left
alias wrap_original_game_map_scroll_right scroll_right
alias wrap_original_game_map_scroll_up scroll_up
alias wrap_original_game_map_scroll_down scroll_down
# Left
def scroll_left(distance)
unless $game_temp.outside_array[$game_map.map_id]
wrap_original_game_map_scroll_left(distance)
else
@display_x = [@display_x - distance].max
end
end
# Right
def scroll_right(distance)
unless $game_temp.outside_array[$game_map.map_id]
wrap_original_game_map_scroll_right(distance)
else
@display_x = [@display_x + distance].min
end
end
# Top
def scroll_up(distance)
unless $game_temp.outside_array[$game_map.map_id]
wrap_original_game_map_scroll_up(distance)
else
@display_y = [@display_y - distance].max
end
end
# Bottom
def scroll_down(distance)
unless $game_temp.outside_array[$game_map.map_id]
wrap_original_game_map_scroll_down(distance)
else
@display_y = [@display_y + distance].min
end
end
end
#--------------------------------------------------------------------------
# Game_Player
#--------------------------------------------------------------------------
class Game_Player
alias wrap_original_game_player_center center
def center(x, y)
unless $game_temp.outside_array[$game_map.map_id]
wrap_original_game_player_center(x, y)
else
max_x = ($game_map.width + 20) * 128
max_y = ($game_map.height + 15) * 128
$game_map.display_x = [-20 * 128, [x * 128 - CENTER_X, max_x].min].max
$game_map.display_y = [-15 * 128, [y * 128 - CENTER_Y, max_y].min].max
end
end
end
#--------------------------------------------------------------------------
# Check_Coordinates
#--------------------------------------------------------------------------
class Check_Coordinates
#------------------------------------------------------------------------
# Handles left edge
#------------------------------------------------------------------------
def refresh_left
unless $game_temp.outside_array[$game_map.map_id]
else
if $game_player.real_x == 0
if Input.press?(Input::LEFT)
def $game_player.passable?(x, y, d)
return true
end
@left_trigger = true
end
end
end
end
#------------------------------------------------------------------------
# Handles right edge
#------------------------------------------------------------------------
def refresh_right
unless $game_temp.outside_array[$game_map.map_id]
else
@map_width_max = ($game_map.width - 1) * 128
if $game_player.real_x == @map_width_max
if Input.press?(Input::RIGHT)
def $game_player.passable?(x, y, d)
return true
end
@right_trigger = true
end
end
end
end
#------------------------------------------------------------------------
# Handles top edge
#------------------------------------------------------------------------
def refresh_top
unless $game_temp.outside_array[$game_map.map_id]
else
if $game_player.real_y == 0
if Input.press?(Input::UP)
def $game_player.passable?(x, y, d)
return true
end
@top_trigger = true
end
end
end
end
#------------------------------------------------------------------------
# Handles bottom edge
#------------------------------------------------------------------------
def refresh_bottom
unless $game_temp.outside_array[$game_map.map_id]
else
@map_height_max = ($game_map.height - 1) * 128
if $game_player.real_y == @map_height_max
if Input.press?(Input::DOWN)
def $game_player.passable?(x, y, d)
return true
end
@bottom_trigger = true
end
end
end
end
#------------------------------------------------------------------------
# Left teleport
#------------------------------------------------------------------------
def left_trigger
if @left_trigger == true
if $game_player.real_x == -128
$game_player.moveto(($game_map.width - 1), $game_player.y)
def $game_player.passable?(x, y, d)
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
unless $game_map.valid?(new_x, new_y)
return false
end
if $DEBUG and Input.press?(Input::CTRL)
return true
end
super
end
@left_trigger = false
end
end
end
#------------------------------------------------------------------------
# Right teleport
#------------------------------------------------------------------------
def right_trigger
if @right_trigger == true
if $game_player.real_x == ($game_map.width * 128)
$game_player.moveto(0, $game_player.y)
def $game_player.passable?(x, y, d)
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
unless $game_map.valid?(new_x, new_y)
return false
end
if $DEBUG and Input.press?(Input::CTRL)
return true
end
super
end
@right_trigger = false
end
end
end
#------------------------------------------------------------------------
# Top teleport
#------------------------------------------------------------------------
def top_trigger
if @top_trigger == true
if $game_player.real_y == -128
$game_player.moveto($game_player.x, ($game_map.height - 1))
def $game_player.passable?(x, y, d)
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
unless $game_map.valid?(new_x, new_y)
return false
end
if $DEBUG and Input.press?(Input::CTRL)
return true
end
super
end
@top_trigger = false
end
end
end
#------------------------------------------------------------------------
# Bottom teleport
#------------------------------------------------------------------------
def bottom_trigger
if @bottom_trigger == true
if $game_player.real_y == ($game_map.height * 128)
$game_player.moveto($game_player.x, 0)
def $game_player.passable?(x, y, d)
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
unless $game_map.valid?(new_x, new_y)
return false
end
if $DEBUG and Input.press?(Input::CTRL)
return true
end
super
end
@bottom_trigger = false
end
end
end
end
#--------------------------------------------------------------------------
# Sprite_Duplicate
#--------------------------------------------------------------------------
class Sprite_Duplicate < RPG::Sprite
attr_accessor :character # @character is the original event
def initialize(viewport, character = nil, x = 0, y = 0)
@x = x
@y = y
super(viewport)
@character = character
@z=@character.screen_z
update
end
def update
super
if @tile_id != @character.tile_id or
@character_name != @character.character_name or
@character_hue != @character.character_hue
@tile_id = @character.tile_id
@character_name = @character.character_name
@character_hue = @character.character_hue
if @tile_id >= 384
self.bitmap = RPG::Cache.tile($game_map.tileset_name, @tile_id, @character.character_hue)
self.src_rect.set(0, 0, 32, 32)
self.ox = 16
self.oy = 32
else
self.bitmap = RPG::Cache.character(@character.character_name, @character.character_hue)
@cw = bitmap.width / 4
@ch = bitmap.height / 4
self.ox = @cw / 2
self.oy = @ch
end
end
self.visible = (not @character.transparent)
if @tile_id == 0
sx = @character.pattern * @cw
sy = (@character.direction - 2) / 2 * @ch
self.src_rect.set(sx, sy, @cw, @ch)
end
# The coordinates of the duplicate event sprite. They are relative to the original event,
# so the duplicates will move and act as the original does; except the z coordinate,
# as when the original sprite would be of range, the duplicate would not appear.
self.x = @character.screen_x + @x
self.y = @character.screen_y + @y
self.z = @z
self.opacity = @character.opacity
self.blend_type = @character.blend_type
self.bush_depth = @character.bush_depth
if @character.animation_id != 0
animation = $data_animations[@character.animation_id]
animation(animation, true)
@character.animation_id = 0
end
end
end
#--------------------------------------------------------------------------
# Sprite_Character
#--------------------------------------------------------------------------
class Sprite_Character < RPG::Sprite
alias wrap_original_sprite_character_initialize initialize
alias wrap_original_sprite_character_update update
def initialize(viewport, character = nil)
unless $game_temp.outside_array[$game_map.map_id]
wrap_original_sprite_character_initialize(viewport, character)
else
@character = character
super(viewport)
if $game_map.wrap == nil
$game_map.wrap = []
end
# 8 duplicates are created, stored in the $game_map.wrap array
if character.is_a?(Game_Event)
$game_map.wrap.push(Sprite_Duplicate.new(viewport, character, (-$game_map.width * 32), 0))
$game_map.wrap.push(Sprite_Duplicate.new(viewport, character, 0, (-$game_map.height * 32)))
$game_map.wrap.push(Sprite_Duplicate.new(viewport, character, ($game_map.width * 32), 0))
$game_map.wrap.push(Sprite_Duplicate.new(viewport, character, 0, ($game_map.height * 32)))
$game_map.wrap.push(Sprite_Duplicate.new(viewport, character, (-$game_map.width * 32), (-$game_map.height * 32)))
$game_map.wrap.push(Sprite_Duplicate.new(viewport, character, ($game_map.width * 32), ($game_map.height * 32)))
$game_map.wrap.push(Sprite_Duplicate.new(viewport, character, (-$game_map.width * 32), ($game_map.height * 32)))
$game_map.wrap.push(Sprite_Duplicate.new(viewport, character, ($game_map.width * 32), (-$game_map.height * 32)))
end
wrap_original_sprite_character_initialize(viewport, @character)
end
end
#------------------------------------------------------------------------
# Updates each sprite in the $game_map.wrap array
#------------------------------------------------------------------------
def update
unless $game_temp.outside_array[$game_map.map_id]
wrap_original_sprite_character_update
else
wrap_original_sprite_character_update
if $game_map.wrap != [] and character.is_a?(Game_Player)
for duplicate in $game_map.wrap
if duplicate != nil
duplicate.update
end
end
end
end
end
end
#--------------------------------------------------------------------------
# Spriteset_Map
#--------------------------------------------------------------------------
class Spriteset_Map
alias wrap_original_spriteset_map_initialize initialize
def initialize
$game_map.wrap=nil
wrap_original_spriteset_map_initialize
end
end
#--------------------------------------------------------------------------
# Scene_Save edit
# Prevent save errors
#--------------------------------------------------------------------------
class Scene_Save < Scene_File
alias wrap_original_scene_save_write_save_data write_save_data
def write_save_data(file)
$game_map.wrap = nil
wrap_original_scene_save_write_save_data(file)
end
end
#--------------------------------------------------------------------------
# Scene Map
#--------------------------------------------------------------------------
class Scene_Map
$coordinate_check = Check_Coordinates.new
alias wrap_original_scene_map_update update
def update
unless $game_temp.outside_array[$game_map.map_id]
wrap_original_scene_map_update
else
$coordinate_check.refresh_left
$coordinate_check.refresh_right
$coordinate_check.refresh_top
$coordinate_check.refresh_bottom
$coordinate_check.left_trigger
$coordinate_check.right_trigger
$coordinate_check.top_trigger
$coordinate_check.bottom_trigger
wrap_original_scene_map_update
end
end
end
However, its compatibility with BABS isn't too good, but other similar scripts for RMXP with the needed effect simply isn't find.
Description of problems:
1) The scrolling of wrapped map isn't going on the standard way - when player approaches to the end of the map, camera centered on the player and showing a necessary part of the map in the window, but after the transfer to the other end of map camera sharply fast scrolls to the standard RMXP mode at this positions.
2) Sprite_Character class isn't good on compatibility - displaying of enemy sprites on the visible screen-part of the wrapped map doesn't happen - they appear only after the transfer to the other end of the map.
Other problems associated with the scripting part wasn't detected. That script is located above the BABS.