More renaming and rearranging, fixed typo from earlier commit, tweaked splash and title screen code

This commit is contained in:
Maruno17
2021-04-05 00:04:18 +01:00
parent 5b0960337a
commit f541a13c9b
69 changed files with 180 additions and 69 deletions

View File

@@ -0,0 +1,154 @@
#===============================================================================
# ** Game_Screen
#-------------------------------------------------------------------------------
# This class handles screen maintenance data, such as change in color tone,
# flashing, etc. Refer to "$game_screen" for the instance of this class.
#===============================================================================
class Game_Screen
#-----------------------------------------------------------------------------
# * Public Instance Variables
#-----------------------------------------------------------------------------
attr_reader :brightness # brightness
attr_reader :tone # color tone
attr_reader :flash_color # flash color
attr_reader :shake # shake positioning
attr_reader :pictures # pictures
attr_reader :weather_type # weather type
attr_reader :weather_max # max number of weather sprites
attr_accessor :weather_duration # ticks in which the weather should fade in
#-----------------------------------------------------------------------------
# * Object Initialization
#-----------------------------------------------------------------------------
def initialize
@brightness = 255
@fadeout_duration = 0
@fadein_duration = 0
@tone = Tone.new(0, 0, 0, 0)
@tone_target = Tone.new(0, 0, 0, 0)
@tone_duration = 0
@flash_color = Color.new(0, 0, 0, 0)
@flash_duration = 0
@shake_power = 0
@shake_speed = 0
@shake_duration = 0
@shake_direction = 1
@shake = 0
@pictures = [nil]
for i in 1..100
@pictures.push(Game_Picture.new(i))
end
@weather_type = 0
@weather_max = 0.0
@weather_duration = 0
end
#-----------------------------------------------------------------------------
# * Start Changing Color Tone
# tone : color tone
# duration : time
#-----------------------------------------------------------------------------
def start_tone_change(tone, duration)
@tone_target = tone.clone
@tone_duration = duration
if @tone_duration == 0
@tone = @tone_target.clone
end
end
#-----------------------------------------------------------------------------
# * Start Flashing
# color : color
# duration : time
#-----------------------------------------------------------------------------
def start_flash(color, duration)
@flash_color = color.clone
@flash_duration = duration
end
#-----------------------------------------------------------------------------
# * Start Shaking
# power : strength
# speed : speed
# duration : time
#-----------------------------------------------------------------------------
def start_shake(power, speed, duration)
@shake_power = power
@shake_speed = speed
@shake_duration = duration
end
#-----------------------------------------------------------------------------
# * Set Weather
# type : type
# power : strength
# duration : time
#-----------------------------------------------------------------------------
def weather(type, power, duration)
@weather_type = GameData::Weather.get(type).id
@weather_max = (power + 1) * RPG::Weather::MAX_SPRITES / 10
@weather_duration = duration # In 1/20ths of a seconds
end
#-----------------------------------------------------------------------------
# * Frame Update
#-----------------------------------------------------------------------------
def update
if @fadeout_duration && @fadeout_duration>=1
d = @fadeout_duration
@brightness = (@brightness*(d-1))/d
@fadeout_duration -= 1
end
if @fadein_duration && @fadein_duration>=1
d = @fadein_duration
@brightness = (@brightness*(d-1)+255)/d
@fadein_duration -= 1
end
if @tone_duration>=1
d = @tone_duration
@tone.red = (@tone.red*(d-1)+@tone_target.red)/d
@tone.green = (@tone.green*(d-1)+@tone_target.green)/d
@tone.blue = (@tone.blue*(d-1)+@tone_target.blue)/d
@tone.gray = (@tone.gray*(d-1)+@tone_target.gray)/d
@tone_duration -= 1
end
if @flash_duration>=1
d = @flash_duration
@flash_color.alpha = @flash_color.alpha*(d-1)/d
@flash_duration -= 1
end
if @shake_duration>=1 or @shake!=0
delta = (@shake_power*@shake_speed*@shake_direction)/10.0
if @shake_duration<=1 and @shake*(@shake+delta)<0
@shake = 0
else
@shake += delta
end
@shake_direction = -1 if @shake>@shake_power*2
@shake_direction = 1 if @shake<-@shake_power*2
@shake_duration -= 1 if @shake_duration>=1
end
if $game_temp.in_battle
for i in 51..100
@pictures[i].update
end
else
for i in 1..50
@pictures[i].update
end
end
end
end
#===============================================================================
#
#===============================================================================
def pbToneChangeAll(tone,duration)
$game_screen.start_tone_change(tone,duration*Graphics.frame_rate/20)
for picture in $game_screen.pictures
picture.start_tone_change(tone,duration*Graphics.frame_rate/20) if picture
end
end
def pbShake(power,speed,frames)
$game_screen.start_shake(power,speed,frames*Graphics.frame_rate/20)
end
def pbFlash(color,frames)
$game_screen.start_flash(color,frames*Graphics.frame_rate/20)
end

View File

@@ -0,0 +1,61 @@
#===============================================================================
# ** Game_Temp
#-------------------------------------------------------------------------------
# This class handles temporary data that is not included with save data.
# Refer to "$game_temp" for the instance of this class.
#===============================================================================
class Game_Temp
attr_accessor :message_window_showing # message window showing
attr_accessor :common_event_id # common event ID
attr_accessor :in_battle # in-battle flag
attr_accessor :battle_abort # battle flag: interrupt
attr_accessor :battleback_name # battleback file name
attr_accessor :in_menu # menu is open
attr_accessor :menu_beep # menu: play sound effect flag
attr_accessor :menu_calling # menu calling flag
attr_accessor :debug_calling # debug calling flag
attr_accessor :player_transferring # player place movement flag
attr_accessor :player_new_map_id # player destination: map ID
attr_accessor :player_new_x # player destination: x-coordinate
attr_accessor :player_new_y # player destination: y-coordinate
attr_accessor :player_new_direction # player destination: direction
attr_accessor :transition_processing # transition processing flag
attr_accessor :transition_name # transition file name
attr_accessor :to_title # return to title screen flag
attr_accessor :fadestate # for sprite hashes
attr_accessor :background_bitmap
attr_accessor :message_window_showing
attr_accessor :transition_processing
attr_accessor :mart_prices
#-----------------------------------------------------------------------------
# * Object Initialization
#-----------------------------------------------------------------------------
def initialize
@message_window_showing = false
@common_event_id = 0
@in_battle = false
@battle_abort = false
@battleback_name = ''
@in_menu = false
@menu_beep = false
@menu_calling = false
@debug_calling = false
@player_transferring = false
@player_new_map_id = 0
@player_new_x = 0
@player_new_y = 0
@player_new_direction = 0
@transition_processing = false
@transition_name = ""
@to_title = false
@fadestate = 0
@background_bitmap = nil
@message_window_showing = false
@transition_processing = false
@mart_prices = {}
end
def clear_mart_prices
@mart_prices = {}
end
end

View File

@@ -0,0 +1,36 @@
#===============================================================================
# ** Game_Switches
#-------------------------------------------------------------------------------
# This class handles switches. It's a wrapper for the built-in class "Array."
# Refer to "$game_switches" for the instance of this class.
#===============================================================================
class Game_Switches
#-----------------------------------------------------------------------------
# * Object Initialization
#-----------------------------------------------------------------------------
def initialize
@data = []
end
#-----------------------------------------------------------------------------
# * Get Switch
# switch_id : switch ID
#-----------------------------------------------------------------------------
def [](switch_id)
if switch_id<=5000 and @data[switch_id]!=nil
return @data[switch_id]
else
return false
end
end
#-----------------------------------------------------------------------------
# * Set Switch
# switch_id : switch ID
# value : ON (true) / OFF (false)
#-----------------------------------------------------------------------------
def []=(switch_id, value)
if switch_id<=5000
@data[switch_id] = value
end
end
end

View File

@@ -0,0 +1,36 @@
#===============================================================================
# ** Game_Variables
#-------------------------------------------------------------------------------
# This class handles variables. It's a wrapper for the built-in class "Array."
# Refer to "$game_variables" for the instance of this class.
#===============================================================================
class Game_Variables
#-----------------------------------------------------------------------------
# * Object Initialization
#-----------------------------------------------------------------------------
def initialize
@data = []
end
#-----------------------------------------------------------------------------
# * Get Variable
# variable_id : variable ID
#-----------------------------------------------------------------------------
def [](variable_id)
if variable_id<=5000 and @data[variable_id]!=nil
return @data[variable_id]
else
return 0
end
end
#-----------------------------------------------------------------------------
# * Set Variable
# variable_id : variable ID
# value : the variable's value
#-----------------------------------------------------------------------------
def []=(variable_id, value)
if variable_id<=5000
@data[variable_id] = value
end
end
end

View File

@@ -0,0 +1,30 @@
#===============================================================================
# ** Game_SelfSwitches
#-------------------------------------------------------------------------------
# This class handles self switches. It's a wrapper for the built-in class
# "Hash." Refer to "$game_self_switches" for the instance of this class.
#===============================================================================
class Game_SelfSwitches
#-----------------------------------------------------------------------------
# * Object Initialization
#-----------------------------------------------------------------------------
def initialize
@data = {}
end
#-----------------------------------------------------------------------------
# * Get Self Switch
# key : key
#-----------------------------------------------------------------------------
def [](key)
return (@data[key]==true) ? true : false
end
#-----------------------------------------------------------------------------
# * Set Self Switch
# key : key
# value : ON (true) / OFF (false)
#-----------------------------------------------------------------------------
def []=(key, value)
@data[key] = value
end
end

View File

@@ -0,0 +1,286 @@
#==============================================================================
# ** Game_System
#------------------------------------------------------------------------------
# This class handles data surrounding the system. Backround music, etc.
# is managed here as well. Refer to "$game_system" for the instance of
# this class.
#==============================================================================
class Game_System
attr_reader :map_interpreter # map event interpreter
attr_reader :battle_interpreter # battle event interpreter
attr_accessor :timer # timer
attr_accessor :timer_working # timer working flag
attr_accessor :save_disabled # save forbidden
attr_accessor :menu_disabled # menu forbidden
attr_accessor :encounter_disabled # encounter forbidden
attr_accessor :message_position # text option: positioning
attr_accessor :message_frame # text option: window frame
attr_accessor :save_count # save count
attr_accessor :magic_number # magic number
attr_accessor :autoscroll_x_speed
attr_accessor :autoscroll_y_speed
attr_accessor :bgm_position
def initialize
@map_interpreter = Interpreter.new(0, true)
@battle_interpreter = Interpreter.new(0, false)
@timer = 0
@timer_working = false
@save_disabled = false
@menu_disabled = false
@encounter_disabled = false
@message_position = 2
@message_frame = 0
@save_count = 0
@magic_number = 0
@autoscroll_x_speed = 0
@autoscroll_y_speed = 0
@bgm_position = 0
@bgs_position = 0
end
################################################################################
def bgm_play(bgm)
old_pos = @bgm_position
@bgm_position = 0
bgm_play_internal(bgm,0)
@bgm_position = old_pos
end
def bgm_play_internal2(name,volume,pitch,position) # :nodoc:
vol = volume
vol *= $PokemonSystem.bgmvolume/100.0
vol = vol.to_i
begin
Audio.bgm_play(name,vol,pitch,position)
rescue ArgumentError
Audio.bgm_play(name,vol,pitch)
end
end
def bgm_play_internal(bgm,position) # :nodoc:
@bgm_position = position if !@bgm_paused
@playing_bgm = (bgm==nil) ? nil : bgm.clone
if bgm!=nil and bgm.name!=""
if FileTest.audio_exist?("Audio/BGM/"+bgm.name)
bgm_play_internal2("Audio/BGM/"+bgm.name,
bgm.volume,bgm.pitch,@bgm_position) if !@defaultBGM
end
else
@bgm_position = position if !@bgm_paused
@playing_bgm = nil
Audio.bgm_stop if !@defaultBGM
end
if @defaultBGM
bgm_play_internal2("Audio/BGM/"+@defaultBGM.name,
@defaultBGM.volume,@defaultBGM.pitch,@bgm_position)
end
Graphics.frame_reset
end
def bgm_pause(fadetime=0.0) # :nodoc:
pos = Audio.bgm_pos rescue 0
self.bgm_fade(fadetime) if fadetime>0.0
@bgm_position = pos
@bgm_paused = true
end
def bgm_unpause # :nodoc:
@bgm_position = 0
@bgm_paused = false
end
def bgm_resume(bgm) # :nodoc:
if @bgm_paused
self.bgm_play_internal(bgm,@bgm_position)
@bgm_position = 0
@bgm_paused = false
end
end
def bgm_stop # :nodoc:
@bgm_position = 0 if !@bgm_paused
@playing_bgm = nil
Audio.bgm_stop if !@defaultBGM
end
def bgm_fade(time) # :nodoc:
@bgm_position = 0 if !@bgm_paused
@playing_bgm = nil
Audio.bgm_fade((time*1000).floor) if !@defaultBGM
end
def playing_bgm
return @playing_bgm
end
# Saves the currently playing background music for later playback.
def bgm_memorize
@memorized_bgm = @playing_bgm
end
# Plays the currently memorized background music
def bgm_restore
bgm_play(@memorized_bgm)
end
# Returns an RPG::AudioFile object for the currently playing background music
def getPlayingBGM
return (@playing_bgm) ? @playing_bgm.clone : nil
end
def setDefaultBGM(bgm,volume=80,pitch=100)
bgm = RPG::AudioFile.new(bgm,volume,pitch) if bgm.is_a?(String)
if bgm!=nil and bgm.name!=""
@defaultBGM = nil
self.bgm_play(bgm)
@defaultBGM = bgm.clone
else
@defaultBGM = nil
self.bgm_play(@playing_bgm)
end
end
################################################################################
def me_play(me)
me = RPG::AudioFile.new(me) if me.is_a?(String)
if me!=nil and me.name!=""
if FileTest.audio_exist?("Audio/ME/"+me.name)
vol = me.volume
vol *= $PokemonSystem.bgmvolume/100.0
vol = vol.to_i
Audio.me_play("Audio/ME/"+me.name,vol,me.pitch)
end
else
Audio.me_stop
end
Graphics.frame_reset
end
################################################################################
def bgs_play(bgs)
@playing_bgs = (bgs==nil) ? nil : bgs.clone
if bgs!=nil and bgs.name!=""
if FileTest.audio_exist?("Audio/BGS/"+bgs.name)
vol = bgs.volume
vol *= $PokemonSystem.sevolume/100.0
vol = vol.to_i
Audio.bgs_play("Audio/BGS/"+bgs.name,vol,bgs.pitch)
end
else
@bgs_position = 0
@playing_bgs = nil
Audio.bgs_stop
end
Graphics.frame_reset
end
def bgs_pause(fadetime=0.0) # :nodoc:
if fadetime>0.0
self.bgs_fade(fadetime)
else
self.bgs_stop
end
@bgs_paused = true
end
def bgs_unpause # :nodoc:
@bgs_paused = false
end
def bgs_resume(bgs) # :nodoc:
if @bgs_paused
self.bgs_play(bgs)
@bgs_paused = false
end
end
def bgs_stop
@bgs_position = 0
@playing_bgs = nil
Audio.bgs_stop
end
def bgs_fade(time)
@bgs_position = 0
@playing_bgs = nil
Audio.bgs_fade((time*1000).floor)
end
def playing_bgs
return @playing_bgs
end
def bgs_memorize
@memorized_bgs = @playing_bgs
end
def bgs_restore
bgs_play(@memorized_bgs)
end
def getPlayingBGS
return (@playing_bgs) ? @playing_bgs.clone : nil
end
################################################################################
def se_play(se)
se = RPG::AudioFile.new(se) if se.is_a?(String)
if se!=nil and se.name!="" && FileTest.audio_exist?("Audio/SE/"+se.name)
vol = se.volume
vol *= $PokemonSystem.sevolume/100.0
vol = vol.to_i
Audio.se_play("Audio/SE/"+se.name,vol,se.pitch)
end
end
def se_stop
Audio.se_stop
end
################################################################################
def battle_bgm
return (@battle_bgm) ? @battle_bgm : $data_system.battle_bgm
end
def battle_bgm=(battle_bgm)
@battle_bgm = battle_bgm
end
def battle_end_me
return (@battle_end_me) ? @battle_end_me : $data_system.battle_end_me
end
def battle_end_me=(battle_end_me)
@battle_end_me = battle_end_me
end
################################################################################
def windowskin_name
if @windowskin_name==nil
return $data_system.windowskin_name
else
return @windowskin_name
end
end
def windowskin_name=(windowskin_name)
@windowskin_name = windowskin_name
end
def update
@timer -= 1 if @timer_working and @timer>0
if Input.trigger?(Input::Z) && pbCurrentEventCommentInput(1,"Cut Scene")
event = @map_interpreter.get_character(0)
@map_interpreter.pbSetSelfSwitch(event.id,"A",true)
@map_interpreter.command_end
event.start
end
end
end

View File

@@ -0,0 +1,156 @@
#===============================================================================
# ** Game_Picture
#-------------------------------------------------------------------------------
# This class handles the picture. It's used within the Game_Screen class
# ($game_screen).
#===============================================================================
class Game_Picture
#-----------------------------------------------------------------------------
# * Public Instance Variables
#-----------------------------------------------------------------------------
attr_reader :number # picture number
attr_reader :name # file name
attr_reader :origin # starting point
attr_reader :x # x-coordinate
attr_reader :y # y-coordinate
attr_reader :zoom_x # x directional zoom rate
attr_reader :zoom_y # y directional zoom rate
attr_reader :opacity # opacity level
attr_reader :blend_type # blend method
attr_reader :tone # color tone
attr_reader :angle # rotation angle
#-----------------------------------------------------------------------------
# * Object Initialization
# number : picture number
#-----------------------------------------------------------------------------
def initialize(number)
@number = number
@name = ""
@origin = 0
@x = 0.0
@y = 0.0
@zoom_x = 100.0
@zoom_y = 100.0
@opacity = 255.0
@blend_type = 1
@duration = 0
@target_x = @x
@target_y = @y
@target_zoom_x = @zoom_x
@target_zoom_y = @zoom_y
@target_opacity = @opacity
@tone = Tone.new(0, 0, 0, 0)
@tone_target = Tone.new(0, 0, 0, 0)
@tone_duration = 0
@angle = 0
@rotate_speed = 0
end
#-----------------------------------------------------------------------------
# * Show Picture
# name : file name
# origin : starting point
# x : x-coordinate
# y : y-coordinate
# zoom_x : x directional zoom rate
# zoom_y : y directional zoom rate
# opacity : opacity level
# blend_type : blend method
#-----------------------------------------------------------------------------
def show(name, origin, x, y, zoom_x, zoom_y, opacity, blend_type)
@name = name
@origin = origin
@x = x.to_f
@y = y.to_f
@zoom_x = zoom_x.to_f
@zoom_y = zoom_y.to_f
@opacity = opacity.to_f
@blend_type = blend_type ? blend_type : 0
@duration = 0
@target_x = @x
@target_y = @y
@target_zoom_x = @zoom_x
@target_zoom_y = @zoom_y
@target_opacity = @opacity
@tone = Tone.new(0, 0, 0, 0)
@tone_target = Tone.new(0, 0, 0, 0)
@tone_duration = 0
@angle = 0
@rotate_speed = 0
end
#-----------------------------------------------------------------------------
# * Move Picture
# duration : time
# origin : starting point
# x : x-coordinate
# y : y-coordinate
# zoom_x : x directional zoom rate
# zoom_y : y directional zoom rate
# opacity : opacity level
# blend_type : blend method
#-----------------------------------------------------------------------------
def move(duration, origin, x, y, zoom_x, zoom_y, opacity, blend_type)
@duration = duration
@origin = origin
@target_x = x.to_f
@target_y = y.to_f
@target_zoom_x = zoom_x.to_f
@target_zoom_y = zoom_y.to_f
@target_opacity = opacity.to_f
@blend_type = blend_type ? blend_type : 0
end
#-----------------------------------------------------------------------------
# * Change Rotation Speed
# speed : rotation speed
#-----------------------------------------------------------------------------
def rotate(speed)
@rotate_speed = speed
end
#-----------------------------------------------------------------------------
# * Start Change of Color Tone
# tone : color tone
# duration : time
#-----------------------------------------------------------------------------
def start_tone_change(tone, duration)
@tone_target = tone.clone
@tone_duration = duration
if @tone_duration == 0
@tone = @tone_target.clone
end
end
#-----------------------------------------------------------------------------
# * Erase Picture
#-----------------------------------------------------------------------------
def erase
@name = ""
end
#-----------------------------------------------------------------------------
# * Frame Update
#-----------------------------------------------------------------------------
def update
if @duration >= 1
d = @duration
@x = (@x * (d - 1) + @target_x) / d
@y = (@y * (d - 1) + @target_y) / d
@zoom_x = (@zoom_x * (d - 1) + @target_zoom_x) / d
@zoom_y = (@zoom_y * (d - 1) + @target_zoom_y) / d
@opacity = (@opacity * (d - 1) + @target_opacity) / d
@duration -= 1
end
if @tone_duration >= 1
d = @tone_duration
@tone.red = (@tone.red * (d - 1) + @tone_target.red) / d
@tone.green = (@tone.green * (d - 1) + @tone_target.green) / d
@tone.blue = (@tone.blue * (d - 1) + @tone_target.blue) / d
@tone.gray = (@tone.gray * (d - 1) + @tone_target.gray) / d
@tone_duration -= 1
end
if @rotate_speed != 0
@angle += @rotate_speed / 2.0
while @angle < 0
@angle += 360
end
@angle %= 360
end
end
end

View File

@@ -0,0 +1,468 @@
#==============================================================================
# ** Game_Map
#------------------------------------------------------------------------------
# This class handles the map. It includes scrolling and passable determining
# functions. Refer to "$game_map" for the instance of this class.
#==============================================================================
class Game_Map
attr_accessor :map_id
attr_accessor :tileset_name # tileset file name
attr_accessor :autotile_names # autotile file name
attr_reader :passages # passage table
attr_reader :priorities # priority table
attr_reader :terrain_tags # terrain tag table
attr_reader :events # events
attr_accessor :panorama_name # panorama file name
attr_accessor :panorama_hue # panorama hue
attr_accessor :fog_name # fog file name
attr_accessor :fog_hue # fog hue
attr_accessor :fog_opacity # fog opacity level
attr_accessor :fog_blend_type # fog blending method
attr_accessor :fog_zoom # fog zoom rate
attr_accessor :fog_sx # fog sx
attr_accessor :fog_sy # fog sy
attr_reader :fog_ox # fog x-coordinate starting point
attr_reader :fog_oy # fog y-coordinate starting point
attr_reader :fog_tone # fog color tone
attr_accessor :battleback_name # battleback file name
attr_reader :display_x # display x-coordinate * 128
attr_reader :display_y # display y-coordinate * 128
attr_accessor :need_refresh # refresh request flag
TILE_WIDTH = 32
TILE_HEIGHT = 32
X_SUBPIXELS = 4
Y_SUBPIXELS = 4
REAL_RES_X = TILE_WIDTH * X_SUBPIXELS
REAL_RES_Y = TILE_HEIGHT * Y_SUBPIXELS
def initialize
@map_id = 0
@display_x = 0
@display_y = 0
end
def setup(map_id)
@map_id = map_id
@map = load_data(sprintf("Data/Map%03d.rxdata",map_id))
tileset = $data_tilesets[@map.tileset_id]
updateTileset
@fog_ox = 0
@fog_oy = 0
@fog_tone = Tone.new(0, 0, 0, 0)
@fog_tone_target = Tone.new(0, 0, 0, 0)
@fog_tone_duration = 0
@fog_opacity_duration = 0
@fog_opacity_target = 0
self.display_x = 0
self.display_y = 0
@need_refresh = false
Events.onMapCreate.trigger(self,map_id,@map,tileset)
@events = {}
for i in @map.events.keys
@events[i] = Game_Event.new(@map_id, @map.events[i],self)
end
# TODO: These should be moved to Spriteset_Global as we only need one copy of them.
@common_events = {}
for i in 1...$data_common_events.size
@common_events[i] = Game_CommonEvent.new(i)
end
@scroll_direction = 2
@scroll_rest = 0
@scroll_speed = 4
end
def updateTileset
tileset = $data_tilesets[@map.tileset_id]
@tileset_name = tileset.tileset_name
@autotile_names = tileset.autotile_names
@panorama_name = tileset.panorama_name
@panorama_hue = tileset.panorama_hue
@fog_name = tileset.fog_name
@fog_hue = tileset.fog_hue
@fog_opacity = tileset.fog_opacity
@fog_blend_type = tileset.fog_blend_type
@fog_zoom = tileset.fog_zoom
@fog_sx = tileset.fog_sx
@fog_sy = tileset.fog_sy
@battleback_name = tileset.battleback_name
@passages = tileset.passages
@priorities = tileset.priorities
@terrain_tags = tileset.terrain_tags
end
def width; return @map.width; end
def height; return @map.height; end
def encounter_list; return @map.encounter_list; end
def encounter_step; return @map.encounter_step; end
def data; return @map.data; end
def name
ret = pbGetMessage(MessageTypes::MapNames,@map_id)
ret.gsub!(/\\PN/,$Trainer.name) if $Trainer
return ret
end
#-----------------------------------------------------------------------------
# * Autoplays background music
# Plays music called "[normal BGM]_n" if it's night time and it exists
#-----------------------------------------------------------------------------
def autoplayAsCue
if @map.autoplay_bgm
if PBDayNight.isNight? && FileTest.audio_exist?("Audio/BGM/"+ @map.bgm.name+ "_n")
pbCueBGM(@map.bgm.name+"_n",1.0,@map.bgm.volume,@map.bgm.pitch)
else
pbCueBGM(@map.bgm,1.0)
end
end
if @map.autoplay_bgs
pbBGSPlay(@map.bgs)
end
end
#-----------------------------------------------------------------------------
# * Plays background music
# Plays music called "[normal BGM]_n" if it's night time and it exists
#-----------------------------------------------------------------------------
def autoplay
if @map.autoplay_bgm
if PBDayNight.isNight? && FileTest.audio_exist?("Audio/BGM/"+ @map.bgm.name+ "_n")
pbBGMPlay(@map.bgm.name+"_n",@map.bgm.volume,@map.bgm.pitch)
else
pbBGMPlay(@map.bgm)
end
end
if @map.autoplay_bgs
pbBGSPlay(@map.bgs)
end
end
def valid?(x, y)
return (x>=0 and x<width and y>=0 and y<height)
end
def validLax?(x, y)
return (x>=-10 and x<=width+10 and y>=-10 and y<=height+10)
end
def passable?(x, y, d, self_event = nil)
return false if !valid?(x, y)
bit = (1 << (d / 2 - 1)) & 0x0f
for event in events.values
next if event.tile_id <= 0
next if event == self_event
next if !event.at_coordinate?(x, y)
next if event.through
next if GameData::TerrainTag.try_get(@terrain_tags[event.tile_id]).ignore_passability
passage = @passages[event.tile_id]
return false if passage & bit != 0
return false if passage & 0x0f == 0x0f
return true if @priorities[event.tile_id] == 0
end
return playerPassable?(x, y, d, self_event) if self_event==$game_player
# All other events
newx = x
newy = y
case d
when 1
newx -= 1
newy += 1
when 2
newy += 1
when 3
newx += 1
newy += 1
when 4
newx -= 1
when 6
newx += 1
when 7
newx -= 1
newy -= 1
when 8
newy -= 1
when 9
newx += 1
newy -= 1
end
return false if !valid?(newx, newy)
for i in [2, 1, 0]
tile_id = data[x, y, i]
terrain = GameData::TerrainTag.try_get(@terrain_tags[tile_id])
# If already on water, only allow movement to another water tile
if self_event != nil && terrain.can_surf_freely
for j in [2, 1, 0]
facing_tile_id = data[newx, newy, j]
return false if facing_tile_id == nil
facing_terrain = GameData::TerrainTag.try_get(@terrain_tags[facing_tile_id])
if facing_terrain.id != :None && !facing_terrain.ignore_passability
return facing_terrain.can_surf_freely
end
end
return false
# Can't walk onto ice
elsif terrain.ice
return false
elsif self_event != nil && self_event.x == x && self_event.y == y
# Can't walk onto ledges
for j in [2, 1, 0]
facing_tile_id = data[newx, newy, j]
return false if facing_tile_id == nil
return false if GameData::TerrainTag.try_get(@terrain_tags[facing_tile_id]).ledge
break
end
end
# Regular passability checks
if !terrain || !terrain.ignore_passability
passage = @passages[tile_id]
return false if passage & bit != 0 || passage & 0x0f == 0x0f
return true if @priorities[tile_id] == 0
end
end
return true
end
def playerPassable?(x, y, d, self_event = nil)
bit = (1 << (d / 2 - 1)) & 0x0f
for i in [2, 1, 0]
tile_id = data[x, y, i]
terrain = GameData::TerrainTag.try_get(@terrain_tags[tile_id])
passage = @passages[tile_id]
if terrain
# Ignore bridge tiles if not on a bridge
next if terrain.bridge && $PokemonGlobal.bridge == 0
# Make water tiles passable if player is surfing
return true if $PokemonGlobal.surfing && terrain.can_surf && !terrain.waterfall
# Prevent cycling in really tall grass/on ice
return false if $PokemonGlobal.bicycle && terrain.must_walk
# Depend on passability of bridge tile if on bridge
if terrain.bridge && $PokemonGlobal.bridge > 0
return (passage & bit == 0 && passage & 0x0f != 0x0f)
end
end
# Regular passability checks
if !terrain || !terrain.ignore_passability
return false if passage & bit != 0 || passage & 0x0f == 0x0f
return true if @priorities[tile_id] == 0
end
end
return true
end
# Returns whether the position x,y is fully passable (there is no blocking
# event there, and the tile is fully passable in all directions)
def passableStrict?(x, y, d, self_event = nil)
return false if !valid?(x, y)
for event in events.values
next if event == self_event || event.tile_id < 0 || event.through
next if !event.at_coordinate?(x, y)
next if GameData::TerrainTag.try_get(@terrain_tags[event.tile_id]).ignore_passability
return false if @passages[event.tile_id] & 0x0f != 0
return true if @priorities[event.tile_id] == 0
end
for i in [2, 1, 0]
tile_id = data[x, y, i]
next if GameData::TerrainTag.try_get(@terrain_tags[tile_id]).ignore_passability
return false if @passages[tile_id] & 0x0f != 0
return true if @priorities[tile_id] == 0
end
return true
end
def bush?(x,y)
for i in [2, 1, 0]
tile_id = data[x, y, i]
return false if GameData::TerrainTag.try_get(@terrain_tags[tile_id]).bridge &&
$PokemonGlobal.bridge > 0
return true if @passages[tile_id] & 0x40 == 0x40
end
return false
end
def deepBush?(x,y)
for i in [2, 1, 0]
tile_id = data[x, y, i]
terrain = GameData::TerrainTag.try_get(@terrain_tags[tile_id])
return false if terrain.bridge && $PokemonGlobal.bridge > 0
return true if terrain.deep_bush && @passages[tile_id] & 0x40 == 0x40
end
return false
end
def counter?(x,y)
for i in [2, 1, 0]
tile_id = data[x, y, i]
passage = @passages[tile_id]
return true if passage & 0x80 == 0x80
end
return false
end
def terrain_tag(x,y,countBridge=false)
if valid?(x, y)
for i in [2, 1, 0]
tile_id = data[x, y, i]
terrain = GameData::TerrainTag.try_get(@terrain_tags[tile_id])
next if terrain.id == :None || terrain.ignore_passability
next if !countBridge && terrain.bridge && $PokemonGlobal.bridge == 0
return terrain
end
end
return GameData::TerrainTag.get(:None)
end
# Unused.
def check_event(x,y)
for event in self.events.values
return event.id if event.at_coordinate?(x, y)
end
end
def display_x=(value)
return if @display_x == value
@display_x = value
if GameData::MapMetadata.exists?(self.map_id) && GameData::MapMetadata.get(self.map_id).snap_edges
max_x = (self.width - Graphics.width*1.0/TILE_WIDTH) * REAL_RES_X
@display_x = [0, [@display_x, max_x].min].max
end
$MapFactory.setMapsInRange if $MapFactory
end
def display_y=(value)
return if @display_y == value
@display_y = value
if GameData::MapMetadata.exists?(self.map_id) && GameData::MapMetadata.get(self.map_id).snap_edges
max_y = (self.height - Graphics.height*1.0/TILE_HEIGHT) * REAL_RES_Y
@display_y = [0, [@display_y, max_y].min].max
end
$MapFactory.setMapsInRange if $MapFactory
end
def scroll_up(distance)
self.display_y -= distance
end
def scroll_down(distance)
self.display_y += distance
end
def scroll_left(distance)
self.display_x -= distance
end
def scroll_right(distance)
self.display_x += distance
end
def start_scroll(direction, distance, speed)
@scroll_direction = direction
if direction==2 || direction==8 # down or up
@scroll_rest = distance * REAL_RES_Y
else
@scroll_rest = distance * REAL_RES_X
end
@scroll_speed = speed
end
def scrolling?
return @scroll_rest > 0
end
def start_fog_tone_change(tone,duration)
@fog_tone_target = tone.clone
@fog_tone_duration = duration
if @fog_tone_duration == 0
@fog_tone = @fog_tone_target.clone
end
end
def start_fog_opacity_change(opacity,duration)
@fog_opacity_target = opacity*1.0
@fog_opacity_duration = duration
if @fog_opacity_duration==0
@fog_opacity = @fog_opacity_target
end
end
def refresh
for event in @events.values
event.refresh
end
for common_event in @common_events.values
common_event.refresh
end
@need_refresh = false
end
def update
# refresh maps if necessary
if $MapFactory
for i in $MapFactory.maps
i.refresh if i.need_refresh
end
$MapFactory.setCurrentMap
end
# If scrolling
if @scroll_rest>0
distance = (1<<@scroll_speed)*40.0/Graphics.frame_rate
distance = @scroll_rest if distance>@scroll_rest
case @scroll_direction
when 2 then scroll_down(distance)
when 4 then scroll_left(distance)
when 6 then scroll_right(distance)
when 8 then scroll_up(distance)
end
@scroll_rest -= distance
end
# Only update events that are on-screen
for event in @events.values
event.update
end
# Update common events
for common_event in @common_events.values
common_event.update
end
# Update fog
@fog_ox -= @fog_sx/8.0
@fog_oy -= @fog_sy/8.0
if @fog_tone_duration>=1
d = @fog_tone_duration
target = @fog_tone_target
@fog_tone.red = (@fog_tone.red * (d - 1) + target.red) / d
@fog_tone.green = (@fog_tone.green * (d - 1) + target.green) / d
@fog_tone.blue = (@fog_tone.blue * (d - 1) + target.blue) / d
@fog_tone.gray = (@fog_tone.gray * (d - 1) + target.gray) / d
@fog_tone_duration -= 1
end
if @fog_opacity_duration >= 1
d = @fog_opacity_duration
@fog_opacity = (@fog_opacity * (d - 1) + @fog_opacity_target) / d
@fog_opacity_duration -= 1
end
end
end
#===============================================================================
#
#===============================================================================
def pbScrollMap(direction,distance,speed)
if speed==0
case direction
when 2 then $game_map.scroll_down(distance * Game_Map::REAL_RES_Y)
when 4 then $game_map.scroll_left(distance * Game_Map::REAL_RES_X)
when 6 then $game_map.scroll_right(distance * Game_Map::REAL_RES_X)
when 8 then $game_map.scroll_up(distance * Game_Map::REAL_RES_Y)
end
else
$game_map.start_scroll(direction, distance, speed)
oldx = $game_map.display_x
oldy = $game_map.display_y
loop do
Graphics.update
Input.update
break if !$game_map.scrolling?
pbUpdateSceneMap
break if $game_map.display_x==oldx && $game_map.display_y==oldy
oldx = $game_map.display_x
oldy = $game_map.display_y
end
end
end

View File

@@ -0,0 +1,194 @@
#===============================================================================
# ** Map Autoscroll
#-------------------------------------------------------------------------------
# Wachunga
# Version 1.02
# 2005-12-18
#===============================================================================
=begin
This script supplements the built-in "Scroll Map" event command with the
aim of simplifying cutscenes (and map scrolling in general). Whereas the
normal event command requires a direction and number of tiles to scroll,
Map Autoscroll scrolls the map to center on the tile whose x and y
coordinates are given.
FEATURES
- automatic map scrolling to given x,y coordinate (or player)
- destination is fixed, so it's possible to scroll to same place even if
origin is variable (e.g. moving NPC)
- variable speed (just like "Scroll Map" event command)
- diagonal scrolling supported
SETUP
Instead of a "Scroll Map" event command, use the "Call Script" command
and enter on the following on the first line:
autoscroll(x,y)
(replacing "x" and "y" with the x and y coordinates of the tile to scroll to)
To specify a scroll speed other than the default (4), use:
autoscroll(x,y,speed)
(now also replacing "speed" with the scroll speed from 1-6)
Diagonal scrolling happens automatically when the destination is diagonal
relative to the starting point (i.e., not directly up, down, left or right).
To scroll to the player, instead use the following:
autoscroll_player(speed)
Note: because of how the interpreter and the "Call Script" event command
are setup, the call to autoscroll(...) can only be on the first line of
the "Call Script" event command (and not flowing down to subsequent lines).
For example, the following call may not work as expected:
autoscroll($game_variables[1],
$game_variables[2])
(since the long argument names require dropping down to a second line)
A work-around is to setup new variables with shorter names in a preceding
(separate) "Call Script" event command:
@x = $game_variables[1]
@y = $game_variables[2]
and then use those as arguments:
autoscroll(@x,@y)
The renaming must be in a separate "Call Script" because otherwise
the call to autoscroll(...) isn't on the first line.
Originally requested by militantmilo80:
http://www.rmxp.net/forums/index.php?showtopic=29519
=end
class Interpreter
SCROLL_SPEED_DEFAULT = 4
#-----------------------------------------------------------------------------
# * Map Autoscroll to Coordinates
# x : x coordinate to scroll to and center on
# y : y coordinate to scroll to and center on
# speed : (optional) scroll speed (from 1-6, default being 4)
#-----------------------------------------------------------------------------
def autoscroll(x,y,speed=SCROLL_SPEED_DEFAULT)
if $game_map.scrolling?
return false
elsif not $game_map.valid?(x,y)
print 'Map Autoscroll: given x,y is invalid'
return command_skip
elsif not (1..6).include?(speed)
print 'Map Autoscroll: invalid speed (1-6 only)'
return command_skip
end
center_x = (Graphics.width/2 - Game_Map::TILE_WIDTH/2) * 4 # X coordinate in the center of the screen
center_y = (Graphics.height/2 - Game_Map::TILE_HEIGHT/2) * 4 # Y coordinate in the center of the screen
max_x = ($game_map.width - Graphics.width*1.0/Game_Map::TILE_WIDTH) * 4 * Game_Map::TILE_WIDTH
max_y = ($game_map.height - Graphics.height*1.0/Game_Map::TILE_HEIGHT) * 4 * Game_Map::TILE_HEIGHT
count_x = ($game_map.display_x - [0,[x*Game_Map::REAL_RES_X-center_x,max_x].min].max)/Game_Map::REAL_RES_X
count_y = ($game_map.display_y - [0,[y*Game_Map::REAL_RES_Y-center_y,max_y].min].max)/Game_Map::REAL_RES_Y
if not @diag
@diag = true
dir = nil
if count_x > 0
if count_y > 0
dir = 7
elsif count_y < 0
dir = 1
end
elsif count_x < 0
if count_y > 0
dir = 9
elsif count_y < 0
dir = 3
end
end
count = [count_x.abs,count_y.abs].min
else
@diag = false
dir = nil
if count_x != 0 and count_y != 0
return false
elsif count_x > 0
dir = 4
elsif count_x < 0
dir = 6
elsif count_y > 0
dir = 8
elsif count_y < 0
dir = 2
end
count = count_x != 0 ? count_x.abs : count_y.abs
end
$game_map.start_scroll(dir, count, speed) if dir != nil
if @diag
return false
else
return true
end
end
#-----------------------------------------------------------------------------
# * Map Autoscroll (to Player)
# speed : (optional) scroll speed (from 1-6, default being 4)
#-----------------------------------------------------------------------------
def autoscroll_player(speed=SCROLL_SPEED_DEFAULT)
autoscroll($game_player.x,$game_player.y,speed)
end
end
class Game_Map
def scroll_downright(distance)
@display_x = [@display_x + distance,
(self.width - Graphics.width*1.0/TILE_WIDTH) * REAL_RES_X].min
@display_y = [@display_y + distance,
(self.height - Graphics.height*1.0/TILE_HEIGHT) * REAL_RES_Y].min
end
def scroll_downleft(distance)
@display_x = [@display_x - distance, 0].max
@display_y = [@display_y + distance,
(self.height - Graphics.height*1.0/TILE_HEIGHT) * REAL_RES_Y].min
end
def scroll_upright(distance)
@display_x = [@display_x + distance,
(self.width - Graphics.width*1.0/TILE_WIDTH) * REAL_RES_X].min
@display_y = [@display_y - distance, 0].max
end
def scroll_upleft(distance)
@display_x = [@display_x - distance, 0].max
@display_y = [@display_y - distance, 0].max
end
def update_scrolling
# If scrolling
if @scroll_rest > 0
# Change from scroll speed to distance in map coordinates
distance = (1<<@scroll_speed)*40/Graphics.frame_rate
distance = @scroll_rest if distance>@scroll_rest
# Execute scrolling
case @scroll_direction
when 1 then scroll_downleft(distance)
when 2 then scroll_down(distance)
when 3 then scroll_downright(distance)
when 4 then scroll_left(distance)
when 6 then scroll_right(distance)
when 7 then scroll_upleft(distance)
when 8 then scroll_up(distance)
when 9 then scroll_upright(distance)
end
# Subtract distance scrolled
@scroll_rest -= distance
end
end
end

View File

@@ -0,0 +1,528 @@
#===============================================================================
# Map Factory (allows multiple maps to be loaded at once and connected)
#===============================================================================
class PokemonMapFactory
attr_reader :maps
def initialize(id)
@maps = []
@fixup = false
@mapChanged = false # transient instance variable
setup(id)
end
# Clears all maps and sets up the current map with id. This function also sets
# the positions of neighboring maps and notifies the game system of a map
# change.
def setup(id)
@maps.clear
@maps[0] = Game_Map.new
@mapIndex = 0
oldID = ($game_map) ? $game_map.map_id : 0
setMapChanging(id,@maps[0]) if oldID!=0 && oldID!=@maps[0].map_id
$game_map = @maps[0]
@maps[0].setup(id)
setMapsInRange
setMapChanged(oldID)
end
def map
@mapIndex = 0 if !@mapIndex || @mapIndex<0
return @maps[@mapIndex] if @maps[@mapIndex]
raise "No maps in save file... (mapIndex=#{@mapIndex})" if @maps.length==0
for i in 0...@maps.length
if @maps[i]
echo("Using next map, may be incorrect (mapIndex=#{@mapIndex}, length=#{@maps.length})")
return @maps[i]
end
raise "No maps in save file... (all maps empty; mapIndex=#{@mapIndex})"
end
end
def hasMap?(id)
for map in @maps
return true if map.map_id==id
end
return false
end
def getMapIndex(id)
for i in 0...@maps.length
return i if @maps[i].map_id==id
end
return -1
end
def getMap(id,add=true)
for map in @maps
return map if map.map_id==id
end
map = Game_Map.new
map.setup(id)
@maps.push(map) if add
return map
end
def getMapNoAdd(id)
return getMap(id,false)
end
def getNewMap(playerX,playerY)
id = $game_map.map_id
conns = MapFactoryHelper.getMapConnections
if conns[id]
for conn in conns[id]
mapidB = nil
newx = 0
newy = 0
if conn[0] == id
mapidB = conn[3]
mapB = MapFactoryHelper.getMapDims(conn[3])
newx = conn[4] - conn[1] + playerX
newy = conn[5] - conn[2] + playerY
else
mapidB = conn[0]
mapB = MapFactoryHelper.getMapDims(conn[0])
newx = conn[1] - conn[4] + playerX
newy = conn[2] - conn[5] + playerY
end
if newx >= 0 && newx < mapB[0] && newy >= 0 && newy < mapB[1]
return [getMap(mapidB), newx, newy]
end
end
end
return nil
end
# Detects whether the player has moved onto a connected map, and if so, causes
# their transfer to that map.
def setCurrentMap
return if $game_player.moving?
return if $game_map.valid?($game_player.x,$game_player.y)
newmap = getNewMap($game_player.x,$game_player.y)
return if !newmap
oldmap=$game_map.map_id
if oldmap!=0 && oldmap!=newmap[0].map_id
setMapChanging(newmap[0].map_id,newmap[0])
end
$game_map = newmap[0]
@mapIndex = getMapIndex($game_map.map_id)
$game_player.moveto(newmap[1],newmap[2])
$game_map.update
pbAutoplayOnTransition
$game_map.refresh
setMapChanged(oldmap)
$game_screen.weather_duration = 20
end
def setMapsInRange
return if @fixup
@fixup = true
id = $game_map.map_id
conns = MapFactoryHelper.getMapConnections
if conns[id]
for conn in conns[id]
if conn[0] == id
mapA = getMap(conn[0])
newdispx = (conn[4] - conn[1]) * Game_Map::REAL_RES_X + mapA.display_x
newdispy = (conn[5] - conn[2]) * Game_Map::REAL_RES_Y + mapA.display_y
if hasMap?(conn[3]) || MapFactoryHelper.mapInRangeById?(conn[3], newdispx, newdispy)
mapB = getMap(conn[3])
mapB.display_x = newdispx if mapB.display_x != newdispx
mapB.display_y = newdispy if mapB.display_y != newdispy
end
else
mapA = getMap(conn[3])
newdispx = (conn[1] - conn[4]) * Game_Map::REAL_RES_X + mapA.display_x
newdispy = (conn[2] - conn[5]) * Game_Map::REAL_RES_Y + mapA.display_y
if hasMap?(conn[0]) || MapFactoryHelper.mapInRangeById?(conn[0], newdispx, newdispy)
mapB = getMap(conn[0])
mapB.display_x = newdispx if mapB.display_x != newdispx
mapB.display_y = newdispy if mapB.display_y != newdispy
end
end
end
end
@fixup = false
end
def setMapChanging(newID,newMap)
Events.onMapChanging.trigger(self,newID,newMap)
end
def setMapChanged(prevMap)
Events.onMapChange.trigger(self,prevMap)
@mapChanged = true
end
def setSceneStarted(scene)
Events.onMapSceneChange.trigger(self,scene,@mapChanged)
@mapChanged = false
end
# Similar to Game_Player#passable?, but supports map connections
def isPassableFromEdge?(x, y)
return true if $game_map.valid?(x, y)
newmap = getNewMap(x, y)
return false if !newmap
return isPassable?(newmap[0].map_id, newmap[1], newmap[2])
end
def isPassable?(mapID, x, y, thisEvent = nil)
thisEvent = $game_player if !thisEvent
map = getMapNoAdd(mapID)
return false if !map
return false if !map.valid?(x, y)
return true if thisEvent.through
# Check passability of tile
if thisEvent.is_a?(Game_Player)
return false unless ($DEBUG && Input.press?(Input::CTRL)) ||
map.passable?(x, y, 0, thisEvent)
else
return false unless map.passable?(x, y, 0, thisEvent)
end
# Check passability of event(s) in that spot
for event in map.events.values
next if event == thisEvent || !event.at_coordinate?(x, y)
return false if !event.through && event.character_name != ""
end
# Check passability of player
if !thisEvent.is_a?(Game_Player)
if $game_map.map_id == mapID && $game_player.x == x && $game_player.y == y
return false if !$game_player.through && $game_player.character_name != ""
end
end
return true
end
# Only used by dependent events
def isPassableStrict?(mapID,x,y,thisEvent=nil)
thisEvent = $game_player if !thisEvent
map = getMapNoAdd(mapID)
return false if !map
return false if !map.valid?(x,y)
return true if thisEvent.through
if thisEvent==$game_player
if !($DEBUG && Input.press?(Input::CTRL))
return false if !map.passableStrict?(x,y,0,thisEvent)
end
else
return false if !map.passableStrict?(x,y,0,thisEvent)
end
for event in map.events.values
next if event == thisEvent || !event.at_coordinate?(x, y)
return false if !event.through && event.character_name!=""
end
return true
end
def getTerrainTag(mapid,x,y,countBridge=false)
map = getMapNoAdd(mapid)
return map.terrain_tag(x,y,countBridge)
end
# NOTE: Assumes the event is 1x1 tile in size. Only returns one terrain tag.
def getFacingTerrainTag(dir=nil,event=nil)
tile = getFacingTile(dir,event)
return GameData::TerrainTag.get(:None) if !tile
return getTerrainTag(tile[0],tile[1],tile[2])
end
def getTerrainTagFromCoords(mapid,x,y,countBridge=false)
tile = getRealTilePos(mapid,x,y)
return GameData::TerrainTag.get(:None) if !tile
return getTerrainTag(tile[0],tile[1],tile[2])
end
def areConnected?(mapID1, mapID2)
return true if mapID1 == mapID2
conns = MapFactoryHelper.getMapConnections
if conns[mapID1]
for conn in conns[mapID1]
return true if conn[0] == mapID2 || conn[3] == mapID2
end
end
return false
end
def getRelativePos(thisMapID, thisX, thisY, otherMapID, otherX, otherY)
if thisMapID == otherMapID # Both events share the same map
return [otherX - thisX, otherY - thisY]
end
conns = MapFactoryHelper.getMapConnections
if conns[thisMapID]
for conn in conns[thisMapID]
if conn[0] == otherMapID
posX = thisX + conn[1] - conn[4] + otherX
posY = thisY + conn[2] - conn[5] + otherY
return [posX, posY]
else
posX = thisX + conn[4] - conn[1] + otherX
posY = thisY + conn[5] - conn[2] + otherY
return [posX, posY]
end
end
end
return [0, 0]
end
# Gets the distance from this event to another event. Example: If this event's
# coordinates are (2,5) and the other event's coordinates are (5,1), returns
# the array (3,-4), because (5-2=3) and (1-5=-4).
def getThisAndOtherEventRelativePos(thisEvent,otherEvent)
return [0,0] if !thisEvent || !otherEvent
return getRelativePos(
thisEvent.map.map_id,thisEvent.x,thisEvent.y,
otherEvent.map.map_id,otherEvent.x,otherEvent.y)
end
def getThisAndOtherPosRelativePos(thisEvent,otherMapID,otherX,otherY)
return [0,0] if !thisEvent
return getRelativePos(
thisEvent.map.map_id,thisEvent.x,thisEvent.y,otherMapID,otherX,otherY)
end
# Unused
def getOffsetEventPos(event,xOffset,yOffset)
event = $game_player if !event
return nil if !event
return getRealTilePos(event.map.map_id,event.x+xOffset,event.y+yOffset)
end
# NOTE: Assumes the event is 1x1 tile in size. Only returns one tile.
def getFacingTile(direction=nil,event=nil,steps=1)
event = $game_player if event==nil
return [0,0,0] if !event
x = event.x
y = event.y
id = event.map.map_id
direction = event.direction if direction==nil
return getFacingTileFromPos(id,x,y,direction,steps)
end
def getFacingTileFromPos(mapID,x,y,direction=0,steps=1)
id = mapID
case direction
when 1
x -= steps
y += steps
when 2
y += steps
when 3
x += steps
y += steps
when 4
x -= steps
when 6
x += steps
when 7
x -= steps
y -= steps
when 8
y -= steps
when 9
x += steps
y -= steps
else
return [id,x,y]
end
return getRealTilePos(mapID,x,y)
end
def getRealTilePos(mapID, x, y)
id = mapID
return [id, x, y] if getMapNoAdd(id).valid?(x, y)
conns = MapFactoryHelper.getMapConnections
if conns[id]
for conn in conns[id]
if conn[0] == id
newX = x + conn[4] - conn[1]
newY = y + conn[5] - conn[2]
next if newX < 0 || newY < 0
dims = MapFactoryHelper.getMapDims(conn[3])
next if newX >= dims[0] || newY >= dims[1]
return [conn[3], newX, newY]
else
newX = x + conn[1] - conn[4]
newY = y + conn[2] - conn[5]
next if newX < 0 || newY < 0
dims = MapFactoryHelper.getMapDims(conn[0])
next if newX >= dims[0] || newY >= dims[1]
return [conn[0], newX, newY]
end
end
end
return nil
end
def getFacingCoords(x,y,direction=0,steps=1)
case direction
when 1
x -= steps
y += steps
when 2
y += steps
when 3
x += steps
y += steps
when 4
x -= steps
when 6
x += steps
when 7
x -= steps
y -= steps
when 8
y -= steps
when 9
x += steps
y -= steps
end
return [x,y]
end
def updateMaps(scene)
updateMapsInternal
$MapFactory.setSceneStarted(scene) if @mapChanged
end
def updateMapsInternal
return if $game_player.moving?
if !MapFactoryHelper.hasConnections?($game_map.map_id)
return if @maps.length==1
for i in 0...@maps.length
@maps[i] = nil if $game_map.map_id!=@maps[i].map_id
end
@maps.compact!
@mapIndex = getMapIndex($game_map.map_id)
return
end
setMapsInRange
deleted = false
for i in 0...@maps.length
next if MapFactoryHelper.mapInRange?(@maps[i])
@maps[i] = nil
deleted = true
end
if deleted
@maps.compact!
@mapIndex = getMapIndex($game_map.map_id)
end
end
end
#===============================================================================
# Map Factory Helper (stores map connection and size data and calculations
# involving them)
#===============================================================================
module MapFactoryHelper
@@MapConnections = nil
@@MapDims = nil
def self.clear
@@MapConnections = nil
@@MapDims = nil
end
def self.getMapConnections
if !@@MapConnections
@@MapConnections = []
conns = load_data("Data/map_connections.dat")
conns.each do |conn|
# Ensure both maps in a connection are valid
dimensions = getMapDims(conn[0])
next if dimensions[0] == 0 || dimensions[1] == 0
dimensions = getMapDims(conn[3])
next if dimensions[0] == 0 || dimensions[1] == 0
# Convert first map's edge and coordinate to pair of coordinates
edge = getMapEdge(conn[0], conn[1])
case conn[1]
when "N", "S"
conn[1] = conn[2]
conn[2] = edge
when "E", "W"
conn[1] = edge
end
# Convert second map's edge and coordinate to pair of coordinates
edge = getMapEdge(conn[3], conn[4])
case conn[4]
when "N", "S"
conn[4] = conn[5]
conn[5] = edge
when "E", "W"
conn[4] = edge
end
# Add connection to arrays for both maps
@@MapConnections[conn[0]] = [] if !@@MapConnections[conn[0]]
@@MapConnections[conn[0]].push(conn)
@@MapConnections[conn[3]] = [] if !@@MapConnections[conn[3]]
@@MapConnections[conn[3]].push(conn)
end
end
return @@MapConnections
end
def self.hasConnections?(id)
conns = MapFactoryHelper.getMapConnections
return conns[id] ? true : false
end
# Gets the height and width of the map with id
def self.getMapDims(id)
# Create cache if doesn't exist
@@MapDims = [] if !@@MapDims
# Add map to cache if can't be found
if !@@MapDims[id]
begin
map = load_data(sprintf("Data/Map%03d.rxdata", id))
@@MapDims[id] = [map.width,map.height]
rescue
@@MapDims[id] = [0,0]
end
end
# Return map in cache
return @@MapDims[id]
end
# Returns the X or Y coordinate of an edge on the map with id.
# Considers the special strings "N","W","E","S"
def self.getMapEdge(id,edge)
return 0 if edge=="N" || edge=="W"
dims = getMapDims(id) # Get dimensions
return dims[0] if edge=="E"
return dims[1] if edge=="S"
return dims[0] # real dimension (use width)
end
def self.mapInRange?(map)
range = 6 # Number of tiles
dispx = map.display_x
dispy = map.display_y
return false if dispx >= (map.width + range) * Game_Map::REAL_RES_X
return false if dispy >= (map.height + range) * Game_Map::REAL_RES_Y
return false if dispx <= -(Graphics.width + range * Game_Map::TILE_WIDTH) * Game_Map::X_SUBPIXELS
return false if dispy <= -(Graphics.height + range * Game_Map::TILE_HEIGHT) * Game_Map::Y_SUBPIXELS
return true
end
def self.mapInRangeById?(id,dispx,dispy)
range = 6 # Number of tiles
dims = MapFactoryHelper.getMapDims(id)
return false if dispx >= (dims[0] + range) * Game_Map::REAL_RES_X
return false if dispy >= (dims[1] + range) * Game_Map::REAL_RES_Y
return false if dispx <= -(Graphics.width + range * Game_Map::TILE_WIDTH) * Game_Map::X_SUBPIXELS
return false if dispy <= -(Graphics.height + range * Game_Map::TILE_HEIGHT) * Game_Map::Y_SUBPIXELS
return true
end
end
#===============================================================================
#
#===============================================================================
# Unused
def updateTilesets
maps = $MapFactory.maps
for map in maps
map.updateTileset if map
end
end

View File

@@ -0,0 +1,924 @@
class Game_Character
attr_reader :id
attr_reader :original_x
attr_reader :original_y
attr_reader :x
attr_reader :y
attr_reader :real_x
attr_reader :real_y
attr_accessor :width
attr_accessor :height
attr_accessor :sprite_size
attr_reader :tile_id
attr_accessor :character_name
attr_accessor :character_hue
attr_reader :opacity
attr_reader :blend_type
attr_reader :direction
attr_accessor :pattern
attr_reader :pattern_surf
attr_accessor :lock_pattern
attr_reader :move_route_forcing
attr_accessor :through
attr_accessor :animation_id
attr_accessor :transparent
attr_reader :move_speed
attr_accessor :walk_anime
attr_writer :bob_height
def initialize(map=nil)
@map = map
@id = 0
@original_x = 0
@original_y = 0
@x = 0
@y = 0
@real_x = 0
@real_y = 0
@width = 1
@height = 1
@sprite_size = [Game_Map::TILE_WIDTH, Game_Map::TILE_HEIGHT]
@tile_id = 0
@character_name = ""
@character_hue = 0
@opacity = 255
@blend_type = 0
@direction = 2
@pattern = 0
@pattern_surf = 0
@lock_pattern = false
@move_route_forcing = false
@through = false
@animation_id = 0
@transparent = false
@original_direction = 2
@original_pattern = 0
@move_type = 0
self.move_speed = 3
self.move_frequency = 6
@move_route = nil
@move_route_index = 0
@original_move_route = nil
@original_move_route_index = 0
@walk_anime = true # Whether character should animate while moving
@step_anime = false # Whether character should animate while still
@direction_fix = false
@always_on_top = false
@anime_count = 0
@stop_count = 0
@jump_peak = 0 # Max height while jumping
@jump_distance = 0 # Total distance of jump
@jump_distance_left = 0 # Distance left to travel
@jump_count = 0 # Frames left in a stationary jump
@bob_height = 0
@wait_count = 0
@moved_this_frame = false
@locked = false
@prelock_direction = 0
end
def at_coordinate?(check_x, check_y)
return check_x >= @x && check_x < @x + @width &&
check_y > @y - @height && check_y <= @y
end
def in_line_with_coordinate?(check_x, check_y)
return (check_x >= @x && check_x < @x + @width) ||
(check_y > @y - @height && check_y <= @y)
end
def each_occupied_tile
for i in @x...(@x + @width)
for j in (@y - @height + 1)..@y
yield i, j
end
end
end
def move_speed=(val)
return if val==@move_speed
@move_speed = val
# @move_speed_real is the number of quarter-pixels to move each frame. There
# are 128 quarter-pixels per tile. By default, it is calculated from
# @move_speed and has these values (assuming 40 fps):
# 1 => 3.2 # 40 frames per tile
# 2 => 6.4 # 20 frames per tile
# 3 => 12.8 # 10 frames per tile - walking speed
# 4 => 25.6 # 5 frames per tile - running speed (2x walking speed)
# 5 => 32 # 4 frames per tile - cycling speed (1.25x running speed)
# 6 => 64 # 2 frames per tile
self.move_speed_real = (val == 6) ? 64 : (val == 5) ? 32 : (2 ** (val + 1)) * 0.8
end
def move_speed_real
self.move_speed = @move_speed if !@move_speed_real
return @move_speed_real
end
def move_speed_real=(val)
@move_speed_real = val * 40.0 / Graphics.frame_rate
end
def jump_speed_real
self.jump_speed_real = (2 ** (3 + 1)) * 0.8 if !@jump_speed_real # 3 is walking speed
return @jump_speed_real
end
def jump_speed_real=(val)
@jump_speed_real = val * 40.0 / Graphics.frame_rate
end
def move_frequency=(val)
return if val==@move_frequency
@move_frequency = val
# @move_frequency_real is the number of frames to wait between each action
# in a move route (not forced). Specifically, this is the number of frames
# to wait after the character stops moving because of the previous action.
# By default, it is calculated from @move_frequency and has these values
# (assuming 40 fps):
# 1 => 190 # 4.75 seconds
# 2 => 144 # 3.6 seconds
# 3 => 102 # 2.55 seconds
# 4 => 64 # 1.6 seconds
# 5 => 30 # 0.75 seconds
# 6 => 0 # 0 seconds, i.e. continuous movement
self.move_frequency_real = (40 - val * 2) * (6 - val)
end
def move_frequency_real
self.move_frequency = @move_frequency if !@move_frequency_real
return @move_frequency_real
end
def move_frequency_real=(val)
@move_frequency_real = val * Graphics.frame_rate / 40.0
end
def bob_height
@bob_height = 0 if !@bob_height
return @bob_height
end
def lock
return if @locked
@prelock_direction = 0 # Was @direction but disabled
turn_toward_player
@locked = true
end
def minilock
@prelock_direction = 0 # Was @direction but disabled
@locked = true
end
def lock?
return @locked
end
def unlock
return unless @locked
@locked = false
@direction = @prelock_direction if !@direction_fix and @prelock_direction != 0
end
#=============================================================================
# Information from map data
#=============================================================================
def map
return (@map) ? @map : $game_map
end
def terrain_tag
return self.map.terrain_tag(@x, @y)
end
def bush_depth
return 0 if @tile_id > 0 || @always_on_top or jumping?
xbehind = @x + (@direction==4 ? 1 : @direction==6 ? -1 : 0)
ybehind = @y + (@direction==8 ? 1 : @direction==2 ? -1 : 0)
return Game_Map::TILE_HEIGHT if self.map.deepBush?(@x, @y) and self.map.deepBush?(xbehind, ybehind)
return 12 if !moving? and self.map.bush?(@x, @y)
return 0
end
#=============================================================================
# Passability
#=============================================================================
def passable?(x, y, d, strict = false)
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
return false unless self.map.valid?(new_x, new_y)
return true if @through
if strict
return false unless self.map.passableStrict?(x, y, d, self)
return false unless self.map.passableStrict?(new_x, new_y, 10 - d, self)
else
return false unless self.map.passable?(x, y, d, self)
return false unless self.map.passable?(new_x, new_y, 10 - d, self)
end
for event in self.map.events.values
next if self == event || !event.at_coordinate?(new_x, new_y) || event.through
return false if self != $game_player || event.character_name != ""
end
if $game_player.x == new_x and $game_player.y == new_y
return false if !$game_player.through && @character_name != ""
end
return true
end
def can_move_from_coordinate?(start_x, start_y, dir, strict = false)
case dir
when 2, 8 # Down, up
y_diff = (dir == 8) ? @height - 1 : 0
for i in start_x...(start_x + @width)
return false if !passable?(i, start_y - y_diff, dir, strict)
end
return true
when 4, 6 # Left, right
x_diff = (dir == 6) ? @width - 1 : 0
for i in (start_y - @height + 1)..start_y
return false if !passable?(start_x + x_diff, i, dir, strict)
end
return true
when 1, 3 # Down diagonals
# Treated as moving down first and then horizontally, because that
# describes which tiles the character's feet touch
for i in start_x...(start_x + @width)
return false if !passable?(i, start_y, 2, strict)
end
x_diff = (dir == 3) ? @width - 1 : 0
for i in (start_y - @height + 1)..start_y
return false if !passable?(start_x + x_diff, i + 1, dir + 3, strict)
end
return true
when 7, 9 # Up diagonals
# Treated as moving horizontally first and then up, because that describes
# which tiles the character's feet touch
x_diff = (dir == 9) ? @width - 1 : 0
for i in (start_y - @height + 1)..start_y
return false if !passable?(start_x + x_diff, i, dir - 3, strict)
end
x_offset = (dir == 9) ? 1 : -1
for i in start_x...(start_x + @width)
return false if !passable?(i + x_offset, start_y - @height + 1, 8, strict)
end
return true
end
return false
end
def can_move_in_direction?(dir, strict = false)
return can_move_from_coordinate?(@x, @y, dir, strict)
end
#=============================================================================
# Screen position of the character
#=============================================================================
def screen_x
ret = ((@real_x - self.map.display_x) / Game_Map::X_SUBPIXELS).round
ret += @width * Game_Map::TILE_WIDTH / 2
return ret
end
def screen_y_ground
ret = ((@real_y - self.map.display_y) / Game_Map::Y_SUBPIXELS).round
ret += Game_Map::TILE_HEIGHT
return ret
end
def screen_y
ret = screen_y_ground
if jumping?
if @jump_count > 0
jump_fraction = ((@jump_count * jump_speed_real / Game_Map::REAL_RES_X) - 0.5).abs # 0.5 to 0 to 0.5
else
jump_fraction = ((@jump_distance_left / @jump_distance) - 0.5).abs # 0.5 to 0 to 0.5
end
ret += @jump_peak * (4 * jump_fraction**2 - 1)
end
return ret
end
def screen_z(height = 0)
return 999 if @always_on_top
z = screen_y_ground
if @tile_id > 0
begin
return z + self.map.priorities[@tile_id] * 32
rescue
raise "Event's graphic is an out-of-range tile (event #{@id}, map #{self.map.map_id})"
end
end
# Add z if height exceeds 32
return z + ((height > Game_Map::TILE_HEIGHT) ? Game_Map::TILE_HEIGHT - 1 : 0)
end
#=============================================================================
# Movement
#=============================================================================
def moving?
return @real_x != @x * Game_Map::REAL_RES_X ||
@real_y != @y * Game_Map::REAL_RES_Y
end
def jumping?
return (@jump_distance_left || 0) > 0 || @jump_count > 0
end
def straighten
@pattern = 0 if @walk_anime or @step_anime
@anime_count = 0
@prelock_direction = 0
end
def force_move_route(move_route)
if @original_move_route == nil
@original_move_route = @move_route
@original_move_route_index = @move_route_index
end
@move_route = move_route
@move_route_index = 0
@move_route_forcing = true
@prelock_direction = 0
@wait_count = 0
move_type_custom
end
def moveto(x, y)
@x = x % self.map.width
@y = y % self.map.height
@real_x = @x * Game_Map::REAL_RES_X
@real_y = @y * Game_Map::REAL_RES_Y
@prelock_direction = 0
triggerLeaveTile
end
def triggerLeaveTile
if @oldX && @oldY && @oldMap &&
(@oldX!=self.x || @oldY!=self.y || @oldMap!=self.map.map_id)
Events.onLeaveTile.trigger(self,self,@oldMap,@oldX,@oldY)
end
@oldX = self.x
@oldY = self.y
@oldMap = self.map.map_id
end
def increase_steps
@stop_count = 0
triggerLeaveTile
end
#=============================================================================
# Movement commands
#=============================================================================
def move_type_random
case rand(6)
when 0..3 then move_random
when 4 then move_forward
when 5 then @stop_count = 0
end
end
def move_type_toward_player
sx = @x + @width / 2.0 - ($game_player.x + $game_player.width / 2.0)
sy = @y - @height / 2.0 - ($game_player.y - $game_player.height / 2.0)
if sx.abs + sy.abs >= 20
move_random
return
end
case rand(6)
when 0..3 then move_toward_player
when 4 then move_random
when 5 then move_forward
end
end
def move_type_custom
return if jumping? or moving?
while @move_route_index < @move_route.list.size
command = @move_route.list[@move_route_index]
if command.code == 0
if @move_route.repeat
@move_route_index = 0
else
if @move_route_forcing
@move_route_forcing = false
@move_route = @original_move_route
@move_route_index = @original_move_route_index
@original_move_route = nil
end
@stop_count = 0
end
return
end
if command.code <= 14
case command.code
when 1 then move_down
when 2 then move_left
when 3 then move_right
when 4 then move_up
when 5 then move_lower_left
when 6 then move_lower_right
when 7 then move_upper_left
when 8 then move_upper_right
when 9 then move_random
when 10 then move_toward_player
when 11 then move_away_from_player
when 12 then move_forward
when 13 then move_backward
when 14 then jump(command.parameters[0], command.parameters[1])
end
@move_route_index += 1 if @move_route.skippable or moving? or jumping?
return
end
if command.code == 15 # Wait
@wait_count = (command.parameters[0] * Graphics.frame_rate / 20) - 1
@move_route_index += 1
return
end
if command.code >= 16 and command.code <= 26
case command.code
when 16 then turn_down
when 17 then turn_left
when 18 then turn_right
when 19 then turn_up
when 20 then turn_right_90
when 21 then turn_left_90
when 22 then turn_180
when 23 then turn_right_or_left_90
when 24 then turn_random
when 25 then turn_toward_player
when 26 then turn_away_from_player
end
@move_route_index += 1
return
end
if command.code >= 27
case command.code
when 27
$game_switches[command.parameters[0]] = true
self.map.need_refresh = true
when 28
$game_switches[command.parameters[0]] = false
self.map.need_refresh = true
when 29 then self.move_speed = command.parameters[0]
when 30 then self.move_frequency = command.parameters[0]
when 31 then @walk_anime = true
when 32 then @walk_anime = false
when 33 then @step_anime = true
when 34 then @step_anime = false
when 35 then @direction_fix = true
when 36 then @direction_fix = false
when 37 then @through = true
when 38 then @through = false
when 39 then @always_on_top = true
when 40 then @always_on_top = false
when 41
@tile_id = 0
@character_name = command.parameters[0]
@character_hue = command.parameters[1]
if @original_direction != command.parameters[2]
@direction = command.parameters[2]
@original_direction = @direction
@prelock_direction = 0
end
if @original_pattern != command.parameters[3]
@pattern = command.parameters[3]
@original_pattern = @pattern
end
when 42 then @opacity = command.parameters[0]
when 43 then @blend_type = command.parameters[0]
when 44 then pbSEPlay(command.parameters[0])
when 45 then eval(command.parameters[0])
end
@move_route_index += 1
end
end
end
def move_generic(dir, turn_enabled = true)
turn_generic(dir) if turn_enabled
x_offset = (dir == 4) ? -1 : (dir == 6) ? 1 : 0
y_offset = (dir == 8) ? -1 : (dir == 2) ? 1 : 0
if can_move_in_direction?(dir)
turn_generic(dir)
@x += x_offset
@y += y_offset
increase_steps
else
check_event_trigger_touch(@x + x_offset, @y + y_offset)
end
end
def move_down(turn_enabled = true)
move_generic(2, turn_enabled)
end
def move_left(turn_enabled = true)
move_generic(4, turn_enabled)
end
def move_right(turn_enabled = true)
move_generic(6, turn_enabled)
end
def move_up(turn_enabled = true)
move_generic(8, turn_enabled)
end
def move_upper_left
unless @direction_fix
@direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction)
end
if can_move_in_direction?(7)
@x -= 1
@y -= 1
increase_steps
end
end
def move_upper_right
unless @direction_fix
@direction = (@direction == 4 ? 6 : @direction == 2 ? 8 : @direction)
end
if can_move_in_direction?(9)
@x += 1
@y -= 1
increase_steps
end
end
def move_lower_left
unless @direction_fix
@direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction)
end
if can_move_in_direction?(1)
@x -= 1
@y += 1
increase_steps
end
end
def move_lower_right
unless @direction_fix
@direction = (@direction == 4 ? 6 : @direction == 8 ? 2 : @direction)
end
if can_move_in_direction?(3)
@x += 1
@y += 1
increase_steps
end
end
def moveLeft90 # anticlockwise
case self.direction
when 2 then move_right # down
when 4 then move_down # left
when 6 then move_up # right
when 8 then move_left # up
end
end
def moveRight90 # clockwise
case self.direction
when 2 then move_left # down
when 4 then move_up # left
when 6 then move_down # right
when 8 then move_right # up
end
end
def move_random
case rand(4)
when 0 then move_down(false)
when 1 then move_left(false)
when 2 then move_right(false)
when 3 then move_up(false)
end
end
def move_random_range(xrange=-1,yrange=-1)
dirs = [] # 0=down, 1=left, 2=right, 3=up
if xrange<0
dirs.push(1); dirs.push(2)
elsif xrange>0
dirs.push(1) if @x > @original_x - xrange
dirs.push(2) if @x < @original_x + xrange
end
if yrange<0
dirs.push(0); dirs.push(3)
elsif yrange>0
dirs.push(0) if @y < @original_y + yrange
dirs.push(3) if @y > @original_y - yrange
end
return if dirs.length==0
case dirs[rand(dirs.length)]
when 0 then move_down(false)
when 1 then move_left(false)
when 2 then move_right(false)
when 3 then move_up(false)
end
end
def move_random_UD(range=-1)
move_random_range(0,range)
end
def move_random_LR(range=-1)
move_random_range(range,0)
end
def move_toward_player
sx = @x + @width / 2.0 - ($game_player.x + $game_player.width / 2.0)
sy = @y - @height / 2.0 - ($game_player.y - $game_player.height / 2.0)
return if sx == 0 and sy == 0
abs_sx = sx.abs
abs_sy = sy.abs
if abs_sx == abs_sy
(rand(2) == 0) ? abs_sx += 1 : abs_sy += 1
end
if abs_sx > abs_sy
(sx > 0) ? move_left : move_right
if not moving? and sy != 0
(sy > 0) ? move_up : move_down
end
else
(sy > 0) ? move_up : move_down
if not moving? and sx != 0
(sx > 0) ? move_left : move_right
end
end
end
def move_away_from_player
sx = @x + @width / 2.0 - ($game_player.x + $game_player.width / 2.0)
sy = @y - @height / 2.0 - ($game_player.y - $game_player.height / 2.0)
return if sx == 0 and sy == 0
abs_sx = sx.abs
abs_sy = sy.abs
if abs_sx == abs_sy
(rand(2) == 0) ? abs_sx += 1 : abs_sy += 1
end
if abs_sx > abs_sy
(sx > 0) ? move_right : move_left
if not moving? and sy != 0
(sy > 0) ? move_down : move_up
end
else
(sy > 0) ? move_down : move_up
if not moving? and sx != 0
(sx > 0) ? move_right : move_left
end
end
end
def move_forward
case @direction
when 2 then move_down(false)
when 4 then move_left(false)
when 6 then move_right(false)
when 8 then move_up(false)
end
end
def move_backward
last_direction_fix = @direction_fix
@direction_fix = true
case @direction
when 2 then move_up(false)
when 4 then move_right(false)
when 6 then move_left(false)
when 8 then move_down(false)
end
@direction_fix = last_direction_fix
end
def jump(x_plus, y_plus)
if x_plus != 0 || y_plus != 0
if x_plus.abs > y_plus.abs
(x_plus < 0) ? turn_left : turn_right
else
(y_plus < 0) ? turn_up : turn_down
end
each_occupied_tile { |i, j| return if !passable?(i + x_plus, j + y_plus, 0) }
end
@x = @x + x_plus
@y = @y + y_plus
real_distance = Math::sqrt(x_plus * x_plus + y_plus * y_plus)
distance = [1, real_distance].max
@jump_peak = distance * Game_Map::TILE_HEIGHT * 3 / 8 # 3/4 of tile for ledge jumping
@jump_distance = [x_plus.abs * Game_Map::REAL_RES_X, y_plus.abs * Game_Map::REAL_RES_Y].max
@jump_distance_left = 1 # Just needs to be non-zero
if real_distance > 0 # Jumping to somewhere else
@jump_count = 0
else # Jumping on the spot
@jump_speed_real = nil # Reset jump speed
@jump_count = Game_Map::REAL_RES_X / jump_speed_real # Number of frames to jump one tile
end
@stop_count = 0
if self.is_a?(Game_Player)
$PokemonTemp.dependentEvents.pbMoveDependentEvents
end
triggerLeaveTile
end
def jumpForward
case self.direction
when 2 then jump(0,1) # down
when 4 then jump(-1,0) # left
when 6 then jump(1,0) # right
when 8 then jump(0,-1) # up
end
end
def jumpBackward
case self.direction
when 2 then jump(0,-1) # down
when 4 then jump(1,0) # left
when 6 then jump(-1,0) # right
when 8 then jump(0,1) # up
end
end
def turn_generic(dir)
return if @direction_fix
oldDirection = @direction
@direction = dir
@stop_count = 0
pbCheckEventTriggerAfterTurning if dir != oldDirection
end
def turn_down; turn_generic(2); end
def turn_left; turn_generic(4); end
def turn_right; turn_generic(6); end
def turn_up; turn_generic(8); end
def turn_right_90
case @direction
when 2 then turn_left
when 4 then turn_up
when 6 then turn_down
when 8 then turn_right
end
end
def turn_left_90
case @direction
when 2 then turn_right
when 4 then turn_down
when 6 then turn_up
when 8 then turn_left
end
end
def turn_180
case @direction
when 2 then turn_up
when 4 then turn_right
when 6 then turn_left
when 8 then turn_down
end
end
def turn_right_or_left_90
(rand(2) == 0) ? turn_right_90 : turn_left_90
end
def turn_random
case rand(4)
when 0 then turn_up
when 1 then turn_right
when 2 then turn_left
when 3 then turn_down
end
end
def turn_toward_player
sx = @x + @width / 2.0 - ($game_player.x + $game_player.width / 2.0)
sy = @y - @height / 2.0 - ($game_player.y - $game_player.height / 2.0)
return if sx == 0 and sy == 0
if sx.abs > sy.abs
(sx > 0) ? turn_left : turn_right
else
(sy > 0) ? turn_up : turn_down
end
end
def turn_away_from_player
sx = @x + @width / 2.0 - ($game_player.x + $game_player.width / 2.0)
sy = @y - @height / 2.0 - ($game_player.y - $game_player.height / 2.0)
return if sx == 0 and sy == 0
if sx.abs > sy.abs
(sx > 0) ? turn_right : turn_left
else
(sy > 0) ? turn_down : turn_up
end
end
#=============================================================================
# Updating
#=============================================================================
def update
@moved_last_frame = @moved_this_frame
if !$game_temp.in_menu
# Update command
update_command
# Update movement
(moving? || jumping?) ? update_move : update_stop
end
# Update animation
update_pattern
end
def update_command
if @wait_count > 0
@wait_count -= 1
elsif @move_route_forcing
move_type_custom
elsif !@starting && !lock? && !moving? && !jumping?
update_command_new
end
end
def update_command_new
# @stop_count is the number of frames since the last movement finished.
# @move_frequency has these values:
# 1 => @stop_count > 190 # 4.75 seconds
# 2 => @stop_count > 144 # 3.6 seconds
# 3 => @stop_count > 102 # 2.55 seconds
# 4 => @stop_count > 64 # 1.6 seconds
# 5 => @stop_count > 30 # 0.75 seconds
# 6 => @stop_count > 0 # 0 seconds
if @stop_count >= self.move_frequency_real
case @move_type
when 1 then move_type_random
when 2 then move_type_toward_player
when 3 then move_type_custom
end
end
end
def update_move
# Move the character (the 0.1 catches rounding errors)
distance = (jumping?) ? jump_speed_real : move_speed_real
dest_x = @x * Game_Map::REAL_RES_X
dest_y = @y * Game_Map::REAL_RES_Y
if @real_x < dest_x
@real_x += distance
@real_x = dest_x if @real_x > dest_x - 0.1
else
@real_x -= distance
@real_x = dest_x if @real_x < dest_x + 0.1
end
if @real_y < dest_y
@real_y += distance
@real_y = dest_y if @real_y > dest_y - 0.1
else
@real_y -= distance
@real_y = dest_y if @real_y < dest_y + 0.1
end
# Refresh how far is left to travel in a jump
if jumping?
@jump_count -= 1 if @jump_count > 0 # For stationary jumps only
@jump_distance_left = [(dest_x - @real_x).abs, (dest_y - @real_y).abs].max
end
# End of a step, so perform events that happen at this time
Events.onStepTakenFieldMovement.trigger(self, self) if !jumping? && !moving?
# Increment animation counter
@anime_count += 1 if @walk_anime || @step_anime
@moved_this_frame = true
end
def update_stop
@anime_count += 1 if @step_anime
@stop_count += 1 if !@starting && !lock?
@moved_this_frame = false
end
def update_pattern
return if @lock_pattern
# return if @jump_count > 0 # Don't animate if jumping on the spot
# Character has stopped moving, return to original pattern
if @moved_last_frame && !@moved_this_frame && !@step_anime
@pattern = @original_pattern
@anime_count = 0
return
end
# Character has started to move, change pattern immediately
if !@moved_last_frame && @moved_this_frame && !@step_anime
@pattern = (@pattern + 1) % 4 if @walk_anime
@anime_count = 0
return
end
# Calculate how many frames each pattern should display for, i.e. the time
# it takes to move half a tile (or a whole tile if cycling). We assume the
# game uses square tiles.
real_speed = (jumping?) ? jump_speed_real : move_speed_real
frames_per_pattern = Game_Map::REAL_RES_X / (real_speed * 2.0)
frames_per_pattern *= 2 if move_speed == 6 # Cycling/fastest speed
return if @anime_count < frames_per_pattern
# Advance to the next animation frame
@pattern = (@pattern + 1) % 4
@anime_count -= frames_per_pattern
end
end

View File

@@ -0,0 +1,268 @@
class Game_Event < Game_Character
attr_reader :map_id
attr_reader :trigger
attr_reader :list
attr_reader :starting
attr_reader :tempSwitches # Temporary self-switches
attr_accessor :need_refresh
def initialize(map_id, event, map=nil)
super(map)
@map_id = map_id
@event = event
@id = @event.id
@original_x = @event.x
@original_y = @event.y
if @event.name[/size\((\d+),(\d+)\)/i]
@width = $~[1].to_i
@height = $~[2].to_i
end
@erased = false
@starting = false
@need_refresh = false
@route_erased = false
@through = true
@to_update = true
@tempSwitches = {}
moveto(@event.x, @event.y) if map
refresh
end
def id; return @event.id; end
def name; return @event.name; end
def set_starting
@starting = true
end
def clear_starting
@starting = false
end
def start
@starting = true if @list.size > 1
end
def erase
@erased = true
refresh
end
def erase_route
@route_erased = true
refresh
end
def tsOn?(c)
return @tempSwitches && @tempSwitches[c]==true
end
def tsOff?(c)
return !@tempSwitches || !@tempSwitches[c]
end
def setTempSwitchOn(c)
@tempSwitches[c]=true
refresh
end
def setTempSwitchOff(c)
@tempSwitches[c]=false
refresh
end
def isOff?(c)
return !$game_self_switches[[@map_id,@event.id,c]]
end
def switchIsOn?(id)
switchname = $data_system.switches[id]
return false if !switchname
if switchname[/^s\:/]
return eval($~.post_match)
else
return $game_switches[id]
end
end
def variable
return nil if !$PokemonGlobal.eventvars
return $PokemonGlobal.eventvars[[@map_id,@event.id]]
end
def setVariable(variable)
$PokemonGlobal.eventvars[[@map_id,@event.id]]=variable
end
def varAsInt
return 0 if !$PokemonGlobal.eventvars
return $PokemonGlobal.eventvars[[@map_id,@event.id]].to_i
end
def expired?(secs=86400)
ontime=self.variable
time=pbGetTimeNow
return ontime && (time.to_i>ontime+secs)
end
def expiredDays?(days=1)
ontime=self.variable.to_i
return false if !ontime
now=pbGetTimeNow
elapsed=(now.to_i-ontime)/86400
elapsed+=1 if (now.to_i-ontime)%86400>(now.hour*3600+now.min*60+now.sec)
return elapsed>=days
end
def cooledDown?(seconds)
return true if expired?(seconds) && tsOff?("A")
self.need_refresh = true
return false
end
def cooledDownDays?(days)
return true if expiredDays?(days) && tsOff?("A")
self.need_refresh = true
return false
end
def onEvent?
return @map_id == $game_map.map_id && at_coordinate?($game_player.x, $game_player.y)
end
def over_trigger?
return false if @character_name != "" && !@through
return false if @event.name[/hiddenitem/i]
each_occupied_tile do |i, j|
return true if self.map.passable?(i, j, 0, $game_player)
end
return false
end
def pbCheckEventTriggerAfterTurning
return if $game_system.map_interpreter.running? || @starting
if @event.name[/trainer\((\d+)\)/i]
distance = $~[1].to_i
if @trigger==2 && pbEventCanReachPlayer?(self,$game_player,distance)
start if !jumping? && !over_trigger?
end
end
end
def check_event_trigger_touch(x, y)
return if $game_system.map_interpreter.running?
return if @trigger != 2 # Event touch
return if !at_coordinate?($game_player.x, $game_player.y)
return if jumping? || over_trigger?
start
end
def check_event_trigger_auto
if @trigger == 2 # Event touch
if at_coordinate?($game_player.x, $game_player.y)
start if not jumping? and over_trigger?
end
elsif @trigger == 3 # Autorun
start
end
end
def refresh
new_page = nil
unless @erased
for page in @event.pages.reverse
c = page.condition
next if c.switch1_valid && !switchIsOn?(c.switch1_id)
next if c.switch2_valid && !switchIsOn?(c.switch2_id)
next if c.variable_valid && $game_variables[c.variable_id] < c.variable_value
if c.self_switch_valid
key = [@map_id, @event.id, c.self_switch_ch]
next if $game_self_switches[key] != true
end
new_page = page
break
end
end
return if new_page == @page
@page = new_page
clear_starting
if @page == nil
@tile_id = 0
@character_name = ""
@character_hue = 0
@move_type = 0
@through = true
@trigger = nil
@list = nil
@interpreter = nil
return
end
@tile_id = @page.graphic.tile_id
@character_name = @page.graphic.character_name
@character_hue = @page.graphic.character_hue
if @original_direction != @page.graphic.direction
@direction = @page.graphic.direction
@original_direction = @direction
@prelock_direction = 0
end
if @original_pattern != @page.graphic.pattern
@pattern = @page.graphic.pattern
@original_pattern = @pattern
end
@opacity = @page.graphic.opacity
@blend_type = @page.graphic.blend_type
@move_type = @page.move_type
self.move_speed = @page.move_speed
self.move_frequency = @page.move_frequency
@move_route = (@route_erased) ? RPG::MoveRoute.new : @page.move_route
@move_route_index = 0
@move_route_forcing = false
@walk_anime = @page.walk_anime
@step_anime = @page.step_anime
@direction_fix = @page.direction_fix
@through = @page.through
@always_on_top = @page.always_on_top
@trigger = @page.trigger
@list = @page.list
@interpreter = nil
if @trigger == 4 # Parallel Process
@interpreter = Interpreter.new
end
check_event_trigger_auto
end
def should_update?(recalc=false)
return @to_update if !recalc
return true if $PokemonSystem.tilemap==2
return true if @trigger && (@trigger == 3 || @trigger == 4)
return true if @move_route_forcing
return true if @event.name[/update/i]
range = 2 # Number of tiles
return false if self.screen_x - @sprite_size[0]/2 > Graphics.width + range * Game_Map::TILE_WIDTH
return false if self.screen_x + @sprite_size[0]/2 < -range * Game_Map::TILE_WIDTH
return false if self.screen_y_ground - @sprite_size[1] > Graphics.height + range * Game_Map::TILE_HEIGHT
return false if self.screen_y_ground < -range * Game_Map::TILE_HEIGHT
return true
end
def update
@to_update = should_update?(true)
return if !@to_update
last_moving = moving?
super
if !moving? && last_moving
$game_player.pbCheckEventTriggerFromDistance([2])
end
if @need_refresh
@need_refresh = false
refresh
end
check_event_trigger_auto
if @interpreter != nil
unless @interpreter.running?
@interpreter.setup(@list, @event.id, @map_id)
end
@interpreter.update
end
end
end

View File

@@ -0,0 +1,475 @@
#===============================================================================
# ** Game_Player
#-------------------------------------------------------------------------------
# This class handles the player. Its functions include event starting
# determinants and map scrolling. Refer to "$game_player" for the one
# instance of this class.
#===============================================================================
class Game_Player < Game_Character
attr_accessor :bump_se
attr_accessor :charsetData
attr_accessor :encounter_count
SCREEN_CENTER_X = (Settings::SCREEN_WIDTH / 2 - Game_Map::TILE_WIDTH / 2) * Game_Map::X_SUBPIXELS
SCREEN_CENTER_Y = (Settings::SCREEN_HEIGHT / 2 - Game_Map::TILE_HEIGHT / 2) * Game_Map::Y_SUBPIXELS
def initialize(*arg)
super(*arg)
@lastdir=0
@lastdirframe=0
@bump_se=0
end
def map
@map = nil
return $game_map
end
def bush_depth
return 0 if @tile_id > 0 || @always_on_top
xbehind = (@direction==4) ? @x+1 : (@direction==6) ? @x-1 : @x
ybehind = (@direction==8) ? @y+1 : (@direction==2) ? @y-1 : @y
# Both current tile and previous tile are on the same map; just return super
return super if $game_map.valid?(@x,@y) && $game_map.valid?(xbehind,ybehind)
# The current or the previous tile is on a different map; consult MapFactory
return 0 if !$MapFactory
# Get map and coordinates of the current tile
if $game_map.valid?(@x,@y)
heremap = self.map; herex = @x; herey = @y
else
newhere = $MapFactory.getNewMap(@x,@y)
return 0 unless newhere && newhere[0] # Map not found
heremap = newhere[0]; herex = newhere[1]; herey = newhere[2]
end
# Get map and coordinates of the previous tile
newbehind = $MapFactory.getNewMap(xbehind,ybehind)
if $game_map.valid?(xbehind,ybehind)
behindmap = self.map; behindx = xbehind; behindy = ybehind
else
return 0 unless newbehind && newbehind[0] # Map not found
behindmap = newbehind[0]; behindx = newbehind[1]; behindy = newbehind[2]
end
# Return bush depth
if !jumping?
return 32 if heremap.deepBush?(herex, herey) && behindmap.deepBush?(behindx, behindy)
return 12 if heremap.bush?(herex, herey) && !moving?
end
return 0
end
def pbHasDependentEvents?
return $PokemonGlobal.dependentEvents.length>0
end
def bump_into_object
return if @bump_se && @bump_se>0
pbSEPlay("Player bump")
@bump_se = Graphics.frame_rate/4
end
def move_generic(dir, turn_enabled = true)
turn_generic(dir, true) if turn_enabled
if !$PokemonTemp.encounterTriggered
x_offset = (dir == 4) ? -1 : (dir == 6) ? 1 : 0
y_offset = (dir == 8) ? -1 : (dir == 2) ? 1 : 0
if can_move_in_direction?(dir)
return if pbLedge(x_offset, y_offset)
return if pbEndSurf(x_offset, y_offset)
turn_generic(dir, true)
if !$PokemonTemp.encounterTriggered
@x += x_offset
@y += y_offset
$PokemonTemp.dependentEvents.pbMoveDependentEvents
increase_steps
end
else
if !check_event_trigger_touch(@x + x_offset, @y + y_offset)
bump_into_object
end
end
end
$PokemonTemp.encounterTriggered = false
end
def turn_generic(dir, keep_enc_indicator = false)
old_direction = @direction
super(dir)
if @direction != old_direction && !@move_route_forcing && !pbMapInterpreterRunning?
Events.onChangeDirection.trigger(self, self)
$PokemonTemp.encounterTriggered = false if !keep_enc_indicator
end
end
def pbTriggeredTrainerEvents(triggers,checkIfRunning=true)
result = []
# If event is running
return result if checkIfRunning && $game_system.map_interpreter.running?
# All event loops
for event in $game_map.events.values
next if !event.name[/trainer\((\d+)\)/i]
distance = $~[1].to_i
# If event coordinates and triggers are consistent
if pbEventCanReachPlayer?(event,self,distance) and triggers.include?(event.trigger)
# If starting determinant is front event (other than jumping)
result.push(event) if not event.jumping? and not event.over_trigger?
end
end
return result
end
def pbTriggeredCounterEvents(triggers,checkIfRunning=true)
result = []
# If event is running
return result if checkIfRunning && $game_system.map_interpreter.running?
# All event loops
for event in $game_map.events.values
next if !event.name[/counter\((\d+)\)/i]
distance = $~[1].to_i
# If event coordinates and triggers are consistent
if pbEventFacesPlayer?(event,self,distance) and triggers.include?(event.trigger)
# If starting determinant is front event (other than jumping)
result.push(event) if not event.jumping? and not event.over_trigger?
end
end
return result
end
def pbCheckEventTriggerAfterTurning; end
def pbCheckEventTriggerFromDistance(triggers)
ret = pbTriggeredTrainerEvents(triggers)
ret.concat(pbTriggeredCounterEvents(triggers))
return false if ret.length==0
for event in ret
event.start
end
return true
end
def pbTerrainTag(countBridge = false)
return $MapFactory.getTerrainTag(self.map.map_id, @x, @y, countBridge) if $MapFactory
return $game_map.terrain_tag(@x, @y, countBridge)
end
def pbFacingEvent(ignoreInterpreter=false)
return nil if $game_system.map_interpreter.running? && !ignoreInterpreter
# Check the tile in front of the player for events
new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
return nil if !$game_map.valid?(new_x, new_y)
for event in $game_map.events.values
next if !event.at_coordinate?(new_x, new_y)
next if event.jumping? || event.over_trigger?
return event
end
# If the tile in front is a counter, check one tile beyond that for events
if $game_map.counter?(new_x, new_y)
new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
for event in $game_map.events.values
next if !event.at_coordinate?(new_x, new_y)
next if event.jumping? || event.over_trigger?
return event
end
end
return nil
end
def pbFacingTerrainTag(dir = nil)
dir = self.direction if !dir
return $MapFactory.getFacingTerrainTag(dir, self) if $MapFactory
facing = pbFacingTile(dir, self)
return $game_map.terrain_tag(facing[1], facing[2])
end
#-----------------------------------------------------------------------------
# * Passable Determinants
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8)
# * 0 = Determines if all directions are impassable (for jumping)
#-----------------------------------------------------------------------------
def passable?(x, y, d, strict = false)
# Get new coordinates
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
# If coordinates are outside of map
return false if !$game_map.validLax?(new_x, new_y)
if !$game_map.valid?(new_x, new_y)
return false if !$MapFactory
return $MapFactory.isPassableFromEdge?(new_x, new_y)
end
# If debug mode is ON and Ctrl key was pressed
return true if $DEBUG and Input.press?(Input::CTRL)
return super
end
#-----------------------------------------------------------------------------
# * Set Map Display Position to Center of Screen
#-----------------------------------------------------------------------------
def center(x, y)
self.map.display_x = x * Game_Map::REAL_RES_X - SCREEN_CENTER_X
self.map.display_y = y * Game_Map::REAL_RES_Y - SCREEN_CENTER_Y
end
#-----------------------------------------------------------------------------
# * Move to Designated Position
# x : x-coordinate
# y : y-coordinate
#-----------------------------------------------------------------------------
def moveto(x, y)
super
# Centering
center(x, y)
# Make encounter count
make_encounter_count
end
#-----------------------------------------------------------------------------
# * Make Encounter Count
#-----------------------------------------------------------------------------
def make_encounter_count
# Image of two dice rolling
if $game_map.map_id != 0
n = $game_map.encounter_step
@encounter_count = rand(n) + rand(n) + 1
end
end
#-----------------------------------------------------------------------------
# * Refresh
#-----------------------------------------------------------------------------
def refresh
@opacity = 255
@blend_type = 0
end
#-----------------------------------------------------------------------------
# * Trigger event(s) at the same coordinates as self with the appropriate
# trigger(s) that can be triggered
#-----------------------------------------------------------------------------
def check_event_trigger_here(triggers)
result = false
# If event is running
return result if $game_system.map_interpreter.running?
# All event loops
for event in $game_map.events.values
# If event coordinates and triggers are consistent
next if !event.at_coordinate?(@x, @y)
next if !triggers.include?(event.trigger)
# If starting determinant is same position event (other than jumping)
next if event.jumping? || !event.over_trigger?
event.start
result = true
end
return result
end
#-----------------------------------------------------------------------------
# * Front Event Starting Determinant
#-----------------------------------------------------------------------------
def check_event_trigger_there(triggers)
result = false
# If event is running
return result if $game_system.map_interpreter.running?
# Calculate front event coordinates
new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
return false if !$game_map.valid?(new_x, new_y)
# All event loops
for event in $game_map.events.values
# If event coordinates and triggers are consistent
next if !event.at_coordinate?(new_x, new_y)
next if !triggers.include?(event.trigger)
# If starting determinant is front event (other than jumping)
next if event.jumping? || event.over_trigger?
event.start
result = true
end
# If fitting event is not found
if result == false
# If front tile is a counter
if $game_map.counter?(new_x, new_y)
# Calculate coordinates of 1 tile further away
new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
return false if !$game_map.valid?(new_x, new_y)
# All event loops
for event in $game_map.events.values
# If event coordinates and triggers are consistent
next if !event.at_coordinate?(new_x, new_y)
next if !triggers.include?(event.trigger)
# If starting determinant is front event (other than jumping)
next if event.jumping? || event.over_trigger?
event.start
result = true
end
end
end
return result
end
#-----------------------------------------------------------------------------
# * Touch Event Starting Determinant
#-----------------------------------------------------------------------------
def check_event_trigger_touch(x, y)
result = false
# If event is running
return result if $game_system.map_interpreter.running?
# All event loops
for event in $game_map.events.values
# If event coordinates and triggers are consistent
next if !event.at_coordinate?(x, y)
if event.name[/trainer\((\d+)\)/i]
distance = $~[1].to_i
next if !pbEventCanReachPlayer?(event,self,distance)
elsif event.name[/counter\((\d+)\)/i]
distance = $~[1].to_i
next if !pbEventFacesPlayer?(event,self,distance)
end
next if ![1,2].include?(event.trigger)
# If starting determinant is front event (other than jumping)
next if event.jumping? || event.over_trigger?
event.start
result = true
end
return result
end
#-----------------------------------------------------------------------------
# * Frame Update
#-----------------------------------------------------------------------------
def update
last_real_x = @real_x
last_real_y = @real_y
super
update_screen_position(last_real_x, last_real_y)
# Update dependent events
$PokemonTemp.dependentEvents.updateDependentEvents
# Count down the time between allowed bump sounds
@bump_se -= 1 if @bump_se && @bump_se>0
# Finish up dismounting from surfing
if $PokemonTemp.endSurf && !moving?
pbCancelVehicles
$PokemonTemp.surfJump = nil
$PokemonTemp.endSurf = false
end
update_event_triggering
end
def update_command_new
dir = Input.dir4
unless pbMapInterpreterRunning? || $game_temp.message_window_showing ||
$PokemonTemp.miniupdate || $game_temp.in_menu
# Move player in the direction the directional button is being pressed
if @moved_last_frame ||
(dir > 0 && dir == @lastdir && Graphics.frame_count - @lastdirframe > Graphics.frame_rate / 20)
case dir
when 2 then move_down
when 4 then move_left
when 6 then move_right
when 8 then move_up
end
elsif dir != @lastdir
case dir
when 2 then turn_down
when 4 then turn_left
when 6 then turn_right
when 8 then turn_up
end
end
end
# Record last direction input
@lastdirframe = Graphics.frame_count if dir != @lastdir
@lastdir = dir
end
# Center player on-screen
def update_screen_position(last_real_x, last_real_y)
return if self.map.scrolling? || !(@moved_last_frame || @moved_this_frame)
self.map.display_x = @real_x - SCREEN_CENTER_X
self.map.display_y = @real_y - SCREEN_CENTER_Y
end
def update_event_triggering
return if moving?
# Try triggering events upon walking into them/in front of them
if @moved_this_frame
$PokemonTemp.dependentEvents.pbTurnDependentEvents
result = pbCheckEventTriggerFromDistance([2])
# Event determinant is via touch of same position event
result |= check_event_trigger_here([1,2])
# No events triggered, try other event triggers upon finishing a step
pbOnStepTaken(result)
end
# If C button was pressed, try to manually interact with events
if Input.trigger?(Input::USE) && !$PokemonTemp.miniupdate
# Same position and front event determinant
check_event_trigger_here([0])
check_event_trigger_there([0,2])
end
end
end
def pbGetPlayerCharset(meta,charset,trainer=nil,force=false)
trainer = $Trainer if !trainer
outfit = (trainer) ? trainer.outfit : 0
if $game_player && $game_player.charsetData && !force
return nil if $game_player.charsetData[0]==$PokemonGlobal.playerID &&
$game_player.charsetData[1]==charset &&
$game_player.charsetData[2]==outfit
end
$game_player.charsetData = [$PokemonGlobal.playerID,charset,outfit] if $game_player
ret = meta[charset]
ret = meta[1] if !ret || ret==""
if pbResolveBitmap("Graphics/Characters/"+ret+"_"+outfit.to_s)
ret = ret+"_"+outfit.to_s
end
return ret
end
def pbUpdateVehicle
meta = GameData::Metadata.get_player($PokemonGlobal.playerID)
if meta
charset = 1 # Regular graphic
if $PokemonGlobal.diving; charset = 5 # Diving graphic
elsif $PokemonGlobal.surfing; charset = 3 # Surfing graphic
elsif $PokemonGlobal.bicycle; charset = 2 # Bicycle graphic
end
newCharName = pbGetPlayerCharset(meta,charset)
$game_player.character_name = newCharName if newCharName
end
end
def pbCancelVehicles(destination=nil)
$PokemonGlobal.surfing = false
$PokemonGlobal.diving = false
$PokemonGlobal.bicycle = false if !destination || !pbCanUseBike?(destination)
pbUpdateVehicle
end
def pbCanUseBike?(map_id)
map_metadata = GameData::MapMetadata.try_get(map_id)
return false if !map_metadata
return true if map_metadata.always_bicycle
val = map_metadata.can_bicycle || map_metadata.outdoor_map
return (val) ? true : false
end
def pbMountBike
return if $PokemonGlobal.bicycle
$PokemonGlobal.bicycle = true
pbUpdateVehicle
bike_bgm = GameData::Metadata.get.bicycle_BGM
pbCueBGM(bike_bgm, 0.5) if bike_bgm
pbPokeRadarCancel
end
def pbDismountBike
return if !$PokemonGlobal.bicycle
$PokemonGlobal.bicycle = false
pbUpdateVehicle
$game_map.autoplayAsCue
end

View File

@@ -0,0 +1,102 @@
class Game_Player < Game_Character
@@bobFrameSpeed = 1.0/15
def fullPattern
case self.direction
when 2 then return self.pattern
when 4 then return self.pattern + 4
when 6 then return self.pattern + 8
when 8 then return self.pattern + 12
end
return 0
end
def setDefaultCharName(chname,pattern,lockpattern=false)
return if pattern<0 || pattern>=16
@defaultCharacterName = chname
@direction = [2,4,6,8][pattern/4]
@pattern = pattern%4
@lock_pattern = lockpattern
end
def pbCanRun?
return false if $game_temp.in_menu || $game_temp.in_battle ||
@move_route_forcing || $game_temp.message_window_showing ||
pbMapInterpreterRunning?
input = ($PokemonSystem.runstyle == 1) ^ Input.press?(Input::SPECIAL)
return input && $PokemonGlobal.runningShoes && !jumping? &&
!$PokemonGlobal.diving && !$PokemonGlobal.surfing &&
!$PokemonGlobal.bicycle && !$game_player.pbTerrainTag.must_walk
end
def pbIsRunning?
return moving? && !@move_route_forcing && pbCanRun?
end
def character_name
@defaultCharacterName = "" if !@defaultCharacterName
return @defaultCharacterName if @defaultCharacterName!=""
if !@move_route_forcing && $PokemonGlobal.playerID>=0
meta = GameData::Metadata.get_player($PokemonGlobal.playerID)
if meta && !$PokemonGlobal.bicycle && !$PokemonGlobal.diving && !$PokemonGlobal.surfing
charset = 1 # Display normal character sprite
if pbCanRun? && (moving? || @wasmoving) && Input.dir4!=0 && meta[4] && meta[4]!=""
charset = 4 # Display running character sprite
end
newCharName = pbGetPlayerCharset(meta,charset)
@character_name = newCharName if newCharName
@wasmoving = moving?
end
end
return @character_name
end
def update_command
if $game_player.pbTerrainTag.ice
self.move_speed = 4 # Sliding on ice
elsif !moving? && !@move_route_forcing && $PokemonGlobal
if $PokemonGlobal.bicycle
self.move_speed = 5 # Cycling
elsif pbCanRun? || $PokemonGlobal.surfing
self.move_speed = 4 # Running, surfing
else
self.move_speed = 3 # Walking, diving
end
end
super
end
def update_pattern
if $PokemonGlobal.surfing || $PokemonGlobal.diving
p = ((Graphics.frame_count%60)*@@bobFrameSpeed).floor
@pattern = p if !@lock_pattern
@pattern_surf = p
@bob_height = (p>=2) ? 2 : 0
else
@bob_height = 0
super
end
end
end
=begin
class Game_Character
alias update_old2 update
def update
if self.is_a?(Game_Event)
if @dependentEvents
for i in 0...@dependentEvents.length
if @dependentEvents[i][0]==$game_map.map_id &&
@dependentEvents[i][1]==self.id
self.move_speed_real = $game_player.move_speed_real
break
end
end
end
end
update_old2
end
end
=end

View File

@@ -0,0 +1,81 @@
#===============================================================================
# ** Game_CommonEvent
#-------------------------------------------------------------------------------
# This class handles common events. It includes execution of parallel process
# event. This class is used within the Game_Map class ($game_map).
#===============================================================================
class Game_CommonEvent
#-----------------------------------------------------------------------------
# * Object Initialization
# common_event_id : common event ID
#-----------------------------------------------------------------------------
def initialize(common_event_id)
@common_event_id = common_event_id
@interpreter = nil
refresh
end
#-----------------------------------------------------------------------------
# * Get Name
#-----------------------------------------------------------------------------
def name
return $data_common_events[@common_event_id].name
end
#-----------------------------------------------------------------------------
# * Get Trigger
#-----------------------------------------------------------------------------
def trigger
return $data_common_events[@common_event_id].trigger
end
#-----------------------------------------------------------------------------
# * Get Condition Switch ID
#-----------------------------------------------------------------------------
def switch_id
return $data_common_events[@common_event_id].switch_id
end
#-----------------------------------------------------------------------------
# * Get List of Event Commands
#-----------------------------------------------------------------------------
def list
return $data_common_events[@common_event_id].list
end
#-----------------------------------------------------------------------------
# * Checks if switch is on
#-----------------------------------------------------------------------------
def switchIsOn?(id)
switchName = $data_system.switches[id]
return false if !switchName
if switchName[/^s\:/]
return eval($~.post_match)
else
return $game_switches[id]
end
end
#-----------------------------------------------------------------------------
# * Refresh
#-----------------------------------------------------------------------------
def refresh
# Create an interpreter for parallel process if necessary
if self.trigger == 2 and switchIsOn?(self.switch_id)
if @interpreter == nil
@interpreter = Interpreter.new
end
else
@interpreter = nil
end
end
#-----------------------------------------------------------------------------
# * Frame Update
#-----------------------------------------------------------------------------
def update
# If parallel process is valid
if @interpreter != nil
# If not running
unless @interpreter.running?
# Set up event
@interpreter.setup(self.list, 0)
end
# Update interpreter
@interpreter.update
end
end
end

View File

@@ -0,0 +1,565 @@
class PokemonTemp
attr_writer :dependentEvents
def dependentEvents
@dependentEvents = DependentEvents.new if !@dependentEvents
return @dependentEvents
end
end
def pbRemoveDependencies()
$PokemonTemp.dependentEvents.removeAllEvents()
pbDeregisterPartner() rescue nil
end
def pbAddDependency(event)
$PokemonTemp.dependentEvents.addEvent(event)
end
def pbRemoveDependency(event)
$PokemonTemp.dependentEvents.removeEvent(event)
end
def pbAddDependency2(eventID, eventName, commonEvent)
$PokemonTemp.dependentEvents.addEvent($game_map.events[eventID],eventName,commonEvent)
end
# Gets the Game_Character object associated with a dependent event.
def pbGetDependency(eventName)
return $PokemonTemp.dependentEvents.getEventByName(eventName)
end
def pbRemoveDependency2(eventName)
$PokemonTemp.dependentEvents.removeEventByName(eventName)
end
class PokemonGlobalMetadata
attr_writer :dependentEvents
def dependentEvents
@dependentEvents = [] if !@dependentEvents
return @dependentEvents
end
end
def pbTestPass(follower,x,y,_direction=nil)
return $MapFactory.isPassableStrict?(follower.map.map_id,x,y,follower)
end
# Same map only
def moveThrough(follower,direction)
oldThrough=follower.through
follower.through=true
case direction
when 2 then follower.move_down
when 4 then follower.move_left
when 6 then follower.move_right
when 8 then follower.move_up
end
follower.through=oldThrough
end
# Same map only
def moveFancy(follower,direction)
deltaX=(direction == 6 ? 1 : (direction == 4 ? -1 : 0))
deltaY=(direction == 2 ? 1 : (direction == 8 ? -1 : 0))
newX = follower.x + deltaX
newY = follower.y + deltaY
# Move if new position is the player's, or the new position is passable,
# or the current position is not passable
if ($game_player.x==newX && $game_player.y==newY) ||
pbTestPass(follower,newX,newY,0) ||
!pbTestPass(follower,follower.x,follower.y,0)
oldThrough=follower.through
follower.through=true
case direction
when 2 then follower.move_down
when 4 then follower.move_left
when 6 then follower.move_right
when 8 then follower.move_up
end
follower.through=oldThrough
end
end
# Same map only
def jumpFancy(follower,direction,leader)
deltaX=(direction == 6 ? 2 : (direction == 4 ? -2 : 0))
deltaY=(direction == 2 ? 2 : (direction == 8 ? -2 : 0))
halfDeltaX=(direction == 6 ? 1 : (direction == 4 ? -1 : 0))
halfDeltaY=(direction == 2 ? 1 : (direction == 8 ? -1 : 0))
middle=pbTestPass(follower,follower.x+halfDeltaX,follower.y+halfDeltaY,0)
ending=pbTestPass(follower,follower.x+deltaX, follower.y+deltaY, 0)
if middle
moveFancy(follower,direction)
moveFancy(follower,direction)
elsif ending
if pbTestPass(follower,follower.x,follower.y,0)
if leader.jumping?
follower.jump_speed_real = leader.jump_speed_real * Graphics.frame_rate / 40.0
else
follower.jump_speed_real = leader.move_speed_real * Graphics.frame_rate / 20.0
end
follower.jump(deltaX,deltaY)
else
moveThrough(follower,direction)
moveThrough(follower,direction)
end
end
end
def pbFancyMoveTo(follower,newX,newY,leader)
if follower.x-newX==-1 && follower.y==newY
moveFancy(follower,6)
elsif follower.x-newX==1 && follower.y==newY
moveFancy(follower,4)
elsif follower.y-newY==-1 && follower.x==newX
moveFancy(follower,2)
elsif follower.y-newY==1 && follower.x==newX
moveFancy(follower,8)
elsif follower.x-newX==-2 && follower.y==newY
jumpFancy(follower,6,leader)
elsif follower.x-newX==2 && follower.y==newY
jumpFancy(follower,4,leader)
elsif follower.y-newY==-2 && follower.x==newX
jumpFancy(follower,2,leader)
elsif follower.y-newY==2 && follower.x==newX
jumpFancy(follower,8,leader)
elsif follower.x!=newX || follower.y!=newY
follower.moveto(newX,newY)
end
end
class DependentEvents
attr_reader :lastUpdate
def createEvent(eventData)
rpgEvent = RPG::Event.new(eventData[3],eventData[4])
rpgEvent.id = eventData[1]
if eventData[9]
# Must setup common event list here and now
commonEvent = Game_CommonEvent.new(eventData[9])
rpgEvent.pages[0].list = commonEvent.list
end
newEvent = Game_Event.new(eventData[0],rpgEvent,$MapFactory.getMap(eventData[2]))
newEvent.character_name = eventData[6]
newEvent.character_hue = eventData[7]
case eventData[5] # direction
when 2 then newEvent.turn_down
when 4 then newEvent.turn_left
when 6 then newEvent.turn_right
when 8 then newEvent.turn_up
end
return newEvent
end
def initialize
# Original map, Event ID, Current map, X, Y, Direction
events=$PokemonGlobal.dependentEvents
@realEvents=[]
@lastUpdate=-1
for event in events
@realEvents.push(createEvent(event))
end
end
def pbEnsureEvent(event, newMapID)
events=$PokemonGlobal.dependentEvents
for i in 0...events.length
# Check original map ID and original event ID
if events[i][0]==event.map_id && events[i][1]==event.id
# Change current map ID
events[i][2]=newMapID
newEvent=createEvent(events[i])
# Replace event
@realEvents[i]=newEvent
@lastUpdate+=1
return i
end
end
return -1
end
def pbFollowEventAcrossMaps(leader,follower,instant=false,leaderIsTrueLeader=true)
d=leader.direction
areConnected=$MapFactory.areConnected?(leader.map.map_id,follower.map.map_id)
# Get the rear facing tile of leader
facingDirection=10-d
if !leaderIsTrueLeader && areConnected
relativePos=$MapFactory.getThisAndOtherEventRelativePos(leader,follower)
# Assumes leader and follower are both 1x1 tile in size
if (relativePos[1]==0 && relativePos[0]==2) # 2 spaces to the right of leader
facingDirection=6
elsif (relativePos[1]==0 && relativePos[0]==-2) # 2 spaces to the left of leader
facingDirection=4
elsif relativePos[1]==-2 && relativePos[0]==0 # 2 spaces above leader
facingDirection=8
elsif relativePos[1]==2 && relativePos[0]==0 # 2 spaces below leader
facingDirection=2
end
end
facings=[facingDirection] # Get facing from behind
# facings.push([0,0,4,0,8,0,2,0,6][d]) # Get right facing
# facings.push([0,0,6,0,2,0,8,0,4][d]) # Get left facing
if !leaderIsTrueLeader
facings.push(d) # Get forward facing
end
mapTile=nil
if areConnected
bestRelativePos=-1
oldthrough=follower.through
follower.through=false
for i in 0...facings.length
facing=facings[i]
tile=$MapFactory.getFacingTile(facing,leader)
# Assumes leader is 1x1 tile in size
passable=tile && $MapFactory.isPassableStrict?(tile[0],tile[1],tile[2],follower)
if i==0 && !passable && tile &&
$MapFactory.getTerrainTag(tile[0],tile[1],tile[2]).ledge
# If the tile isn't passable and the tile is a ledge,
# get tile from further behind
tile=$MapFactory.getFacingTileFromPos(tile[0],tile[1],tile[2],facing)
passable=tile && $MapFactory.isPassableStrict?(tile[0],tile[1],tile[2],follower)
end
if passable
relativePos=$MapFactory.getThisAndOtherPosRelativePos(
follower,tile[0],tile[1],tile[2])
# Assumes follower is 1x1 tile in size
distance=Math.sqrt(relativePos[0]*relativePos[0]+relativePos[1]*relativePos[1])
if bestRelativePos==-1 || bestRelativePos>distance
bestRelativePos=distance
mapTile=tile
end
if i==0 && distance<=1 # Prefer behind if tile can move up to 1 space
break
end
end
end
follower.through=oldthrough
else
tile=$MapFactory.getFacingTile(facings[0],leader)
# Assumes leader is 1x1 tile in size
passable=tile && $MapFactory.isPassableStrict?(tile[0],tile[1],tile[2],follower)
mapTile=passable ? mapTile : nil
end
if mapTile && follower.map.map_id==mapTile[0]
# Follower is on same map
newX=mapTile[1]
newY=mapTile[2]
deltaX=(d == 6 ? -1 : d == 4 ? 1 : 0)
deltaY=(d == 2 ? -1 : d == 8 ? 1 : 0)
posX = newX + deltaX
posY = newY + deltaY
follower.move_speed=leader.move_speed # sync movespeed
if (follower.x-newX==-1 && follower.y==newY) ||
(follower.x-newX==1 && follower.y==newY) ||
(follower.y-newY==-1 && follower.x==newX) ||
(follower.y-newY==1 && follower.x==newX)
if instant
follower.moveto(newX,newY)
else
pbFancyMoveTo(follower,newX,newY,leader)
end
elsif (follower.x-newX==-2 && follower.y==newY) ||
(follower.x-newX==2 && follower.y==newY) ||
(follower.y-newY==-2 && follower.x==newX) ||
(follower.y-newY==2 && follower.x==newX)
if instant
follower.moveto(newX,newY)
else
pbFancyMoveTo(follower,newX,newY,leader)
end
elsif follower.x!=posX || follower.y!=posY
if instant
follower.moveto(newX,newY)
else
pbFancyMoveTo(follower,posX,posY,leader)
pbFancyMoveTo(follower,newX,newY,leader)
end
end
else
if !mapTile
# Make current position into leader's position
mapTile=[leader.map.map_id,leader.x,leader.y]
end
if follower.map.map_id==mapTile[0]
# Follower is on same map as leader
follower.moveto(leader.x,leader.y)
else
# Follower will move to different map
events=$PokemonGlobal.dependentEvents
eventIndex=pbEnsureEvent(follower,mapTile[0])
if eventIndex>=0
newFollower=@realEvents[eventIndex]
newEventData=events[eventIndex]
newFollower.moveto(mapTile[1],mapTile[2])
newEventData[3]=mapTile[1]
newEventData[4]=mapTile[2]
if mapTile[0]==leader.map.map_id
end
end
end
end
end
def debugEcho
self.eachEvent { |e,d|
echoln d
echoln [e.map_id,e.map.map_id,e.id]
}
end
def pbMapChangeMoveDependentEvents
events=$PokemonGlobal.dependentEvents
updateDependentEvents
leader=$game_player
for i in 0...events.length
event=@realEvents[i]
pbFollowEventAcrossMaps(leader,event,true,i==0)
# Update X and Y for this event
events[i][3]=event.x
events[i][4]=event.y
events[i][5]=event.direction
# Set leader to this event
leader=event
end
end
def pbMoveDependentEvents
events=$PokemonGlobal.dependentEvents
updateDependentEvents
leader=$game_player
for i in 0...events.length
event=@realEvents[i]
pbFollowEventAcrossMaps(leader,event,false,i==0)
# Update X and Y for this event
events[i][3]=event.x
events[i][4]=event.y
events[i][5]=event.direction
# Set leader to this event
leader=event
end
end
def pbTurnDependentEvents
events=$PokemonGlobal.dependentEvents
updateDependentEvents
leader=$game_player
for i in 0...events.length
event=@realEvents[i]
pbTurnTowardEvent(event,leader)
# Update direction for this event
events[i][5]=event.direction
# Set leader to this event
leader=event
end
end
def eachEvent
events=$PokemonGlobal.dependentEvents
for i in 0...events.length
yield @realEvents[i],events[i]
end
end
def updateDependentEvents
events=$PokemonGlobal.dependentEvents
return if events.length==0
for i in 0...events.length
event=@realEvents[i]
next if !@realEvents[i]
event.transparent=$game_player.transparent
if event.jumping? || event.moving? ||
!($game_player.jumping? || $game_player.moving?)
event.update
elsif !event.starting
event.set_starting
event.update
event.clear_starting
end
events[i][3]=event.x
events[i][4]=event.y
events[i][5]=event.direction
end
# Check event triggers
if Input.trigger?(Input::USE) && !$game_temp.in_menu && !$game_temp.in_battle &&
!$game_player.move_route_forcing && !$game_temp.message_window_showing &&
!pbMapInterpreterRunning?
# Get position of tile facing the player
facingTile=$MapFactory.getFacingTile()
# Assumes player is 1x1 tile in size
self.eachEvent { |e,d|
next if !d[9]
if e.at_coordinate?($game_player.x, $game_player.y)
# On same position
if not e.jumping? && (!e.respond_to?("over_trigger") || e.over_trigger?)
if e.list.size>1
# Start event
$game_map.refresh if $game_map.need_refresh
e.lock
pbMapInterpreter.setup(e.list,e.id,e.map.map_id)
end
end
elsif facingTile && e.map.map_id==facingTile[0] &&
e.at_coordinate?(facingTile[1], facingTile[2])
# On facing tile
if not e.jumping? && (!e.respond_to?("over_trigger") || !e.over_trigger?)
if e.list.size>1
# Start event
$game_map.refresh if $game_map.need_refresh
e.lock
pbMapInterpreter.setup(e.list,e.id,e.map.map_id)
end
end
end
}
end
end
def removeEvent(event)
events=$PokemonGlobal.dependentEvents
mapid=$game_map.map_id
for i in 0...events.length
if events[i][2]==mapid && # Refer to current map
events[i][0]==event.map_id && # Event's map ID is original ID
events[i][1]==event.id
events[i]=nil
@realEvents[i]=nil
@lastUpdate+=1
end
events.compact!
@realEvents.compact!
end
end
def getEventByName(name)
events=$PokemonGlobal.dependentEvents
for i in 0...events.length
if events[i] && events[i][8]==name # Arbitrary name given to dependent event
return @realEvents[i]
end
end
return nil
end
def removeAllEvents
events=$PokemonGlobal.dependentEvents
events.clear
@realEvents.clear
@lastUpdate+=1
end
def removeEventByName(name)
events=$PokemonGlobal.dependentEvents
for i in 0...events.length
if events[i] && events[i][8]==name # Arbitrary name given to dependent event
events[i]=nil
@realEvents[i]=nil
@lastUpdate+=1
end
events.compact!
@realEvents.compact!
end
end
def addEvent(event,eventName=nil,commonEvent=nil)
return if !event
events=$PokemonGlobal.dependentEvents
for i in 0...events.length
if events[i] && events[i][0]==$game_map.map_id && events[i][1]==event.id
# Already exists
return
end
end
# Original map ID, original event ID, current map ID,
# event X, event Y, event direction,
# event's filename,
# event's hue, event's name, common event ID
eventData=[
$game_map.map_id,event.id,$game_map.map_id,
event.x,event.y,event.direction,
event.character_name.clone,
event.character_hue,eventName,commonEvent
]
newEvent=createEvent(eventData)
events.push(eventData)
@realEvents.push(newEvent)
@lastUpdate+=1
event.erase
end
end
class DependentEventSprites
def initialize(viewport,map)
@disposed=false
@sprites=[]
@map=map
@viewport=viewport
refresh
@lastUpdate=nil
end
def refresh
for sprite in @sprites
sprite.dispose
end
@sprites.clear
$PokemonTemp.dependentEvents.eachEvent { |event,data|
if data[0]==@map.map_id # Check original map
@map.events[data[1]].erase
end
if data[2]==@map.map_id # Check current map
@sprites.push(Sprite_Character.new(@viewport,event))
end
}
end
def update
if $PokemonTemp.dependentEvents.lastUpdate!=@lastUpdate
refresh
@lastUpdate=$PokemonTemp.dependentEvents.lastUpdate
end
for sprite in @sprites
sprite.update
end
end
def dispose
return if @disposed
for sprite in @sprites
sprite.dispose
end
@sprites.clear
@disposed=true
end
def disposed?
@disposed
end
end
Events.onSpritesetCreate += proc { |_sender,e|
spriteset = e[0] # Spriteset being created
viewport = e[1] # Viewport used for tilemap and characters
map = spriteset.map # Map associated with the spriteset (not necessarily the current map)
spriteset.addUserSprite(DependentEventSprites.new(viewport,map))
}
Events.onMapSceneChange += proc { |_sender,e|
mapChanged = e[1]
if mapChanged
$PokemonTemp.dependentEvents.pbMapChangeMoveDependentEvents
end
}