Bem vindo, Visitante
Faça
Login
ou
Registre-se
por favor.
Ou forneça o usuario e senha para fazer o login rapido!
[-]
home
|
arquivo
|
envie o seu
|
quem somos
|
portal
|
Pokéstarter
Inicio
Scripts
Imagens
Outros
RPG_Sprite
[
Selecionar
] [
-
]
class SpriteAnimation @@_animations = [] @@_reference_count = {} def initialize(sprite) @sprite=sprite end %w[ x y ox oy viewport flash src_rect opacity ].each_with_index do |s, i| eval <<-__END__ def #{s}(*arg) @sprite.#{s}(*arg) end __END__ end def self.clear @@_animations.clear end def dispose dispose_animation dispose_loop_animation end def animation(animation, hit) dispose_animation @_animation = animation return if @_animation == nil @_animation_hit = hit @_animation_duration = @_animation.frame_max animation_name = @_animation.animation_name animation_hue = @_animation.animation_hue bitmap = RPG::Cache.animation(animation_name, animation_hue) if @@_reference_count.include?(bitmap) @@_reference_count[bitmap] += 1 else @@_reference_count[bitmap] = 1 end @_animation_sprites = [] if @_animation.position != 3 or not @@_animations.include?(animation) for i in 0..15 sprite = ::Sprite.new(self.viewport) sprite.bitmap = bitmap sprite.visible = false @_animation_sprites.push(sprite) end unless @@_animations.include?(animation) @@_animations.push(animation) end end update_animation end def loop_animation(animation) return if animation == @_loop_animation dispose_loop_animation @_loop_animation = animation return if @_loop_animation == nil @_loop_animation_index = 0 animation_name = @_loop_animation.animation_name animation_hue = @_loop_animation.animation_hue bitmap = RPG::Cache.animation(animation_name, animation_hue) if @@_reference_count.include?(bitmap) @@_reference_count[bitmap] += 1 else @@_reference_count[bitmap] = 1 end @_loop_animation_sprites = [] for i in 0..15 sprite = ::Sprite.new(self.viewport) sprite.bitmap = bitmap sprite.visible = false @_loop_animation_sprites.push(sprite) end update_loop_animation end def dispose_animation if @_animation_sprites != nil sprite = @_animation_sprites[0] if sprite != nil @@_reference_count[sprite.bitmap] -= 1 if @@_reference_count[sprite.bitmap] == 0 sprite.bitmap.dispose end end for sprite in @_animation_sprites sprite.dispose end @_animation_sprites = nil @_animation = nil end end def dispose_loop_animation if @_loop_animation_sprites != nil sprite = @_loop_animation_sprites[0] if sprite != nil @@_reference_count[sprite.bitmap] -= 1 if @@_reference_count[sprite.bitmap] == 0 sprite.bitmap.dispose end end for sprite in @_loop_animation_sprites sprite.dispose end @_loop_animation_sprites = nil @_loop_animation = nil end end def active? @_loop_animation_sprites != nil || @_animation_sprites != nil end def effect? @_animation_duration > 0 end def update if @_animation != nil and (Graphics.frame_count % 2 == 0) @_animation_duration -= 1 update_animation end if @_loop_animation != nil and (Graphics.frame_count % 2 == 0) update_loop_animation @_loop_animation_index += 1 @_loop_animation_index %= @_loop_animation.frame_max end end def update_animation if @_animation_duration > 0 frame_index = @_animation.frame_max - @_animation_duration cell_data = @_animation.frames[frame_index].cell_data position = @_animation.position animation_set_sprites(@_animation_sprites, cell_data, position) for timing in @_animation.timings if timing.frame == frame_index animation_process_timing(timing, @_animation_hit) end end else dispose_animation end end def update_loop_animation frame_index = @_loop_animation_index cell_data = @_loop_animation.frames[frame_index].cell_data position = @_loop_animation.position animation_set_sprites(@_loop_animation_sprites, cell_data, position) for timing in @_loop_animation.timings if timing.frame == frame_index animation_process_timing(timing, true) end end end def animation_set_sprites(sprites, cell_data, position) for i in 0..15 sprite = sprites[i] pattern = cell_data[i, 0] if sprite == nil or pattern == nil or pattern == -1 sprite.visible = false if sprite != nil next end sprite.visible = true sprite.src_rect.set(pattern % 5 * 192, pattern / 5 * 192, 192, 192) if position == 3 if self.viewport != nil sprite.x = self.viewport.rect.width / 2 sprite.y = self.viewport.rect.height - 160 else sprite.x = 320 sprite.y = 240 end else sprite.x = self.x - self.ox + self.src_rect.width / 2 sprite.y = self.y - self.oy + self.src_rect.height / 2 sprite.y -= self.src_rect.height / 4 if position == 0 sprite.y += self.src_rect.height / 4 if position == 2 end sprite.x += cell_data[i, 1] sprite.y += cell_data[i, 2] sprite.z = 2000 sprite.ox = 96 sprite.oy = 96 sprite.zoom_x = cell_data[i, 3] / 100.0 sprite.zoom_y = cell_data[i, 3] / 100.0 sprite.angle = cell_data[i, 4] sprite.mirror = (cell_data[i, 5] == 1) sprite.opacity = cell_data[i, 6] * self.opacity / 255.0 sprite.blend_type = cell_data[i, 7] end end def animation_process_timing(timing, hit) if (timing.condition == 0) or (timing.condition == 1 and hit == true) or (timing.condition == 2 and hit == false) if timing.se.name != "" se = timing.se Audio.se_play("Audio/SE/" + se.name, se.volume, se.pitch) end case timing.flash_scope when 1 self.flash(timing.flash_color, timing.flash_duration * 2) when 2 if self.viewport != nil self.viewport.flash(timing.flash_color, timing.flash_duration * 2) end when 3 self.flash(nil, timing.flash_duration * 2) end end end def x=(x) sx = x - self.x if sx != 0 if @_animation_sprites != nil for i in 0..15 @_animation_sprites[i].x += sx end end if @_loop_animation_sprites != nil for i in 0..15 @_loop_animation_sprites[i].x += sx end end end end def y=(y) sy = y - self.y if sy != 0 if @_animation_sprites != nil for i in 0..15 @_animation_sprites[i].y += sy end end if @_loop_animation_sprites != nil for i in 0..15 @_loop_animation_sprites[i].y += sy end end end end end module RPG class Sprite < ::Sprite def initialize(viewport = nil) super(viewport) @_whiten_duration = 0 @_appear_duration = 0 @_escape_duration = 0 @_collapse_duration = 0 @_damage_duration = 0 @_animation_duration = 0 @_blink = false @animations=[] @loopAnimations=[] end def dispose dispose_damage dispose_animation dispose_loop_animation super end def whiten self.blend_type = 0 self.color.set(255, 255, 255, 128) self.opacity = 255 @_whiten_duration = 16 @_appear_duration = 0 @_escape_duration = 0 @_collapse_duration = 0 end def appear self.blend_type = 0 self.color.set(0, 0, 0, 0) self.opacity = 0 @_appear_duration = 16 @_whiten_duration = 0 @_escape_duration = 0 @_collapse_duration = 0 end def escape self.blend_type = 0 self.color.set(0, 0, 0, 0) self.opacity = 255 @_escape_duration = 32 @_whiten_duration = 0 @_appear_duration = 0 @_collapse_duration = 0 end def collapse self.blend_type = 1 self.color.set(255, 64, 64, 255) self.opacity = 255 @_collapse_duration = 48 @_whiten_duration = 0 @_appear_duration = 0 @_escape_duration = 0 end def damage(value, critical) dispose_damage if value.is_a?(Numeric) damage_string = value.abs.to_s else damage_string = value.to_s end bitmap = Bitmap.new(160, 48) bitmap.font.name = "Arial Black" bitmap.font.size = 32 bitmap.font.color.set(0, 0, 0) bitmap.draw_text(-1, 12-1, 160, 36, damage_string, 1) bitmap.draw_text(+1, 12-1, 160, 36, damage_string, 1) bitmap.draw_text(-1, 12+1, 160, 36, damage_string, 1) bitmap.draw_text(+1, 12+1, 160, 36, damage_string, 1) if value.is_a?(Numeric) and value < 0 bitmap.font.color.set(176, 255, 144) else bitmap.font.color.set(255, 255, 255) end bitmap.draw_text(0, 12, 160, 36, damage_string, 1) if critical bitmap.font.size = 20 bitmap.font.color.set(0, 0, 0) bitmap.draw_text(-1, -1, 160, 20, "CRITICAL", 1) bitmap.draw_text(+1, -1, 160, 20, "CRITICAL", 1) bitmap.draw_text(-1, +1, 160, 20, "CRITICAL", 1) bitmap.draw_text(+1, +1, 160, 20, "CRITICAL", 1) bitmap.font.color.set(255, 255, 255) bitmap.draw_text(0, 0, 160, 20, "CRITICAL", 1) end @_damage_sprite = ::Sprite.new(self.viewport) @_damage_sprite.bitmap = bitmap @_damage_sprite.ox = 80 @_damage_sprite.oy = 20 @_damage_sprite.x = self.x @_damage_sprite.y = self.y - self.oy / 2 @_damage_sprite.z = 3000 @_damage_duration = 40 end def pushAnimation(array,anim) for i in 0...array.length if !array[i] || !array[i].active? array[i]=anim return end end array.push(anim) end def animation(animation, hit) anim=SpriteAnimation.new(self) anim.animation(animation,hit) pushAnimation(@animations,anim) end def loop_animation(animation) anim=SpriteAnimation.new(self) anim.loop_animation(animation) pushAnimation(@loopAnimations,anim) end def dispose_damage if @_damage_sprite != nil @_damage_sprite.bitmap.dispose @_damage_sprite.dispose @_damage_sprite = nil @_damage_duration = 0 end end def dispose_animation for a in @animations a.dispose_animation if a end @animations.clear end def dispose_loop_animation for a in @loopAnimations a.dispose_loop_animation if a end @loopAnimations.clear end def blink_on unless @_blink @_blink = true @_blink_count = 0 end end def blink_off if @_blink @_blink = false self.color.set(0, 0, 0, 0) end end def blink? @_blink end def effect? return true if @_whiten_duration > 0 or @_appear_duration > 0 or @_escape_duration > 0 or @_collapse_duration > 0 or @_damage_duration > 0 for a in @animations return true if a.effect? end return false end def update super if @_whiten_duration > 0 @_whiten_duration -= 1 self.color.alpha = 128 - (16 - @_whiten_duration) * 10 end if @_appear_duration > 0 @_appear_duration -= 1 self.opacity = (16 - @_appear_duration) * 16 end if @_escape_duration > 0 @_escape_duration -= 1 self.opacity = 256 - (32 - @_escape_duration) * 10 end if @_collapse_duration > 0 @_collapse_duration -= 1 self.opacity = 256 - (48 - @_collapse_duration) * 6 end if @_damage_duration > 0 @_damage_duration -= 1 case @_damage_duration when 38..39 @_damage_sprite.y -= 4 when 36..37 @_damage_sprite.y -= 2 when 34..35 @_damage_sprite.y += 2 when 28..33 @_damage_sprite.y += 4 end @_damage_sprite.opacity = 256 - (12 - @_damage_duration) * 32 if @_damage_duration == 0 dispose_damage end end for a in @animations a.update end for a in @loopAnimations a.update end if @_blink @_blink_count = (@_blink_count + 1) % 32 if @_blink_count < 16 alpha = (16 - @_blink_count) * 6 else alpha = (@_blink_count - 16) * 6 end self.color.set(255, 255, 255, alpha) end SpriteAnimation.clear end def update_animation for a in @animations a.update_animation if a && a.active? end end def update_loop_animation for a in @loopAnimations a.update_loop_animation if a && a.active? end end def x=(x) sx = x - self.x for a in @animations a.x=x if a end for a in @loopAnimations a.x=x if a end super end def y=(y) sy = y - self.y for a in @animations a.x=x if a end for a in @loopAnimations a.x=x if a end super end end end
Game Temp
[
Selecionar
] [
-
]
#============================================================================== # ** 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 #-------------------------------------------------------------------------- # * Public Instance Variables #-------------------------------------------------------------------------- attr_accessor :map_bgm # map music (for battle memory) attr_accessor :message_text # message text attr_accessor :message_proc # message callback (Proc) attr_accessor :choice_start # show choices: opening line attr_accessor :choice_max # show choices: number of items attr_accessor :choice_cancel_type # show choices: cancel attr_accessor :choice_proc # show choices: callback (Proc) attr_accessor :num_input_start # input number: opening line attr_accessor :num_input_variable_id # input number: variable ID attr_accessor :num_input_digits_max # input number: digit amount 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_calling # battle calling flag attr_accessor :battle_troop_id # battle troop ID attr_accessor :battle_can_escape # battle flag: escape possible attr_accessor :battle_can_lose # battle flag: losing possible attr_accessor :battle_proc # battle callback (Proc) attr_accessor :battle_turn # number of battle turns attr_accessor :battle_event_flags # battle event flags: completed attr_accessor :battle_abort # battle flag: interrupt attr_accessor :battle_main_phase # battle flag: main phase attr_accessor :battleback_name # battleback file name attr_accessor :forcing_battler # battler being forced into action attr_accessor :shop_calling # shop calling flag attr_accessor :shop_goods # list of shop goods attr_accessor :name_calling # name input: calling flag attr_accessor :name_actor_id # name input: actor ID attr_accessor :name_max_char # name input: max character count attr_accessor :menu_calling # menu calling flag attr_accessor :menu_beep # menu: play sound effect flag attr_accessor :save_calling # save 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 :gameover # game over flag attr_accessor :to_title # return to title screen flag attr_accessor :last_file_index # last save file no. attr_accessor :debug_top_row # debug screen: for saving conditions attr_accessor :debug_index # debug screen: for saving conditions #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize @map_bgm = nil @message_text = nil @message_proc = nil @choice_start = 99 @choice_max = 0 @choice_cancel_type = 0 @choice_proc = nil @num_input_start = 99 @num_input_variable_id = 0 @num_input_digits_max = 0 @message_window_showing = false @common_event_id = 0 @in_battle = false @battle_calling = false @battle_troop_id = 0 @battle_can_escape = false @battle_can_lose = false @battle_proc = nil @battle_turn = 0 @battle_event_flags = {} @battle_abort = false @battle_main_phase = false @battleback_name = '' @forcing_battler = nil @shop_calling = false @shop_id = 0 @name_calling = false @name_actor_id = 0 @name_max_char = 0 @menu_calling = false @menu_beep = false @save_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 = "" @gameover = false @to_title = false @last_file_index = 0 @debug_top_row = 0 @debug_index = 0 end end
Game_Switches
[
Selecionar
] [
-
]
#============================================================================== # ** 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
Game_Variables
[
Selecionar
] [
-
]
#============================================================================== # ** 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
Game_SelfSwitches
[
Selecionar
] [
-
]
#============================================================================== # ** 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
Game_Screen
[
Selecionar
] [
-
]
#============================================================================== # ** 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 :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 #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize @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_type_target = 0 @weather_max_target = 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_target = type if @weather_type_target != 0 @weather_type = @weather_type_target end if @weather_type_target == 0 @weather_max_target = 0.0 else @weather_max_target = (power + 1) * 4.0 end @weather_duration = duration if @weather_duration == 0 @weather_type = @weather_type_target @weather_max = @weather_max_target end end #-------------------------------------------------------------------------- # * Frame Update #-------------------------------------------------------------------------- def update 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 if @shake > @shake_power * 2 @shake_direction = -1 end if @shake < - @shake_power * 2 @shake_direction = 1 end if @shake_duration >= 1 @shake_duration -= 1 end end if @weather_duration >= 1 d = @weather_duration @weather_max = (@weather_max * (d - 1) + @weather_max_target) / d @weather_duration -= 1 if @weather_duration == 0 @weather_type = @weather_type_target end 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
Game_Picture
[
Selecionar
] [
-
]
#============================================================================== # ** 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 @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 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
Game_Map
[
Selecionar
] [
-
]
class Game_Map attr_accessor :tileset_name attr_accessor :autotile_names attr_accessor :panorama_name attr_accessor :panorama_hue attr_accessor :fog_name attr_accessor :fog_hue attr_accessor :fog_opacity attr_accessor :fog_blend_type attr_accessor :fog_zoom attr_accessor :fog_sx attr_accessor :fog_sy attr_accessor :battleback_name attr_accessor :display_x attr_accessor :display_y attr_accessor :need_refresh attr_reader :passages attr_reader :priorities attr_reader :terrain_tags attr_reader :events attr_reader :fog_ox attr_reader :fog_oy attr_reader :fog_tone attr_reader :mapsInRange 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] @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 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 @common_events = {} for i in 1...$data_common_events.size @common_events[i] = Game_CommonEvent.new(i) end @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 @scroll_direction = 2 @scroll_rest = 0 @scroll_speed = 4 end def map_id return @map_id 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 autoplayAsCue if @map.autoplay_bgm # Checks whether the map has an autoplay BGM if (Time.now.hour<6||Time.now.hour>=20) && # Checks if it's night time - the values are editable FileTest.audio_exist?("Audio/BGM/"+ @map.bgm.name+ "n") # Checks whether a BGM file with the filename [normal BGM]n exists pbCueBGM( RPG::AudioFile.new(@map.bgm.name+"n", @map.bgm.volume,@map.bgm.pitch),1.0) # Plays it else pbCueBGM(@map.bgm,1.0) # Plays the normal BGM end end if @map.autoplay_bgs $game_system.bgs_play(@map.bgs) end end def autoplay if @map.autoplay_bgm # Checks whether the map has an autoplay BGM if (Time.now.hour<6||Time.now.hour>=20) && # Checks if it's night time - the values are editable FileTest.audio_exist?("Audio/BGM/"+ @map.bgm.name+ "n") # Checks whether a BGM file with the filename [normal BGM]n exists $game_system.bgm_play(@map.bgm.name+"n", @map.bgm.volume,@map.bgm.pitch) # Plays it else $game_system.bgm_play(@map.bgm) # Plays the normal BGM end end if @map.autoplay_bgs $game_system.bgs_play(@map.bgs) end end def refresh if @map_id > 0 for event in @events.values event.refresh end for common_event in @common_events.values common_event.refresh end end @need_refresh = false end def scroll_down(distance) @display_y = [@display_y + distance, (self.height - 15) * 128].min end def scroll_left(distance) @display_x = [@display_x - distance, 0].max end def scroll_right(distance) @display_x = [@display_x + distance, (self.width - 20) * 128].min end def scroll_up(distance) @display_y = [@display_y - distance, 0].max 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 if event.tile_id >= 0 and event != self_event and event.x == x and event.y == y and not event.through return false if @passages[event.tile_id] & bit != 0 return false if @passages[event.tile_id] & 0x0f == 0x0f return true if @priorities[event.tile_id] == 0 end end for i in [2, 1, 0] tile_id = data[x, y, i] if tile_id == nil return false # Make water tiles passable if player is surfing elsif pbIsPassableWaterTag?(@terrain_tags[tile_id]) && $PokemonGlobal.surfing return true elsif @passages[tile_id] & bit != 0 return false elsif @passages[tile_id] & 0x0f == 0x0f return false elsif @priorities[tile_id] == 0 return true end end return true end def passableStrict?(x, y, d, self_event = nil) return false if !valid?(x, y) for event in events.values if event.tile_id >= 0 and event != self_event and event.x == x and event.y == y and not event.through return false if @passages[event.tile_id] & 0x0f !=0 return true if @priorities[event.tile_id] == 0 end end for i in [2, 1, 0] tile_id = data[x, y, i] return false if tile_id == nil return false if @passages[tile_id] & 0x0f !=0 return true if @priorities[tile_id] == 0 end return true end def bush?(x, y) if @map_id != 0 for i in [2, 1, 0] tile_id = data[x, y, i] if tile_id == nil return false elsif @passages[tile_id] & 0x40 == 0x40 return true end end end return false end def counter?(x, y) if @map_id != 0 for i in [2, 1, 0] tile_id = data[x, y, i] if tile_id == nil return false elsif @passages[tile_id] && @passages[tile_id] & 0x80 == 0x80 return true end end end return false end def terrain_tag(x, y) if @map_id != 0 for i in [2, 1, 0] tile_id = data[x, y, i] if tile_id == nil return 0 elsif @terrain_tags[tile_id] && @terrain_tags[tile_id] > 0 return @terrain_tags[tile_id] end end end return 0 end def check_event(x, y) for event in self.events.values if event.x == x and event.y == y return event.id end end end def start_scroll(direction, distance, speed) @scroll_direction = direction @scroll_rest = distance * 128 @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 in_range?(object) return true if $PokemonSystem.tilemap==2 screne_x = display_x screne_x -= 256 screne_y = display_y screne_y -= 256 screne_width = display_x screne_width += Graphics.width*4+256 # 2816 screne_height = display_y screne_height += Graphics.height*4+256 # 2176 return false if object.real_x <= screne_x return false if object.real_x >= screne_width return false if object.real_y <= screne_y return false if object.real_y >= screne_height return true end def update if $MapFactory for i in $MapFactory.maps i.refresh if i.need_refresh end $MapFactory.setCurrentMap end if @scroll_rest > 0 distance = 2 ** @scroll_speed case @scroll_direction when 2 scroll_down(distance) when 4 scroll_left(distance) when 6 scroll_right(distance) when 8 scroll_up(distance) end @scroll_rest -= distance end for event in @events.values if in_range?(event) or event.trigger == 3 or event.trigger == 4 event.update end end for common_event in @common_events.values common_event.update end @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 class Game_Map def name return pbGetMessage(MessageTypes::MapNames,self.map_id) end end
Game_CommonEvent
[
Selecionar
] [
-
]
#============================================================================== # ** 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 #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh # Create an interpreter for parallel process if necessary if self.trigger == 2 and $game_switches[self.switch_id] == true 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
Game_Character_1
[
Selecionar
] [
-
]
class Game_Character attr_reader :id attr_reader :x attr_reader :y attr_reader :real_x attr_reader :real_y attr_reader :tile_id attr_accessor :character_name attr_accessor :character_hue attr_reader :opacity attr_reader :blend_type attr_reader :direction attr_reader :pattern attr_reader :move_route_forcing attr_accessor :through attr_accessor :animation_id attr_accessor :transparent attr_reader :map attr_accessor :move_speed attr_accessor :walk_anime def map return @map ? @map : $game_map end def initialize(map=nil) @map=map @id = 0 @x = 0 @y = 0 @real_x = 0 @real_y = 0 @tile_id = 0 @character_name = "" @character_hue = 0 @opacity = 255 @blend_type = 0 @direction = 2 @pattern = 0 @move_route_forcing = false @through = false @animation_id = 0 @transparent = false @original_direction = 2 @original_pattern = 0 @move_type = 0 @move_speed = 4 @move_frequency = 6 @move_route = nil @move_route_index = 0 @original_move_route = nil @original_move_route_index = 0 @walk_anime = true @step_anime = false @direction_fix = false @always_on_top = false @anime_count = 0 @stop_count = 0 @jump_count = 0 @jump_peak = 0 @wait_count = 0 @locked = false @prelock_direction = 0 end def map return @map end def moving? return (@real_x != @x * 4 * Game_Map::TILEWIDTH or @real_y != @y * 4 * Game_Map::TILEHEIGHT) end def jumping? return @jump_count > 0 end def straighten if @walk_anime or @step_anime @pattern = 0 end @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 passableEx?(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) else return false unless self.map.passable?(x, y, d, self) return false unless self.map.passable?(new_x, new_y, 10 - d) end for event in self.map.events.values if event.x == new_x and event.y == new_y unless event.through return false if self != $game_player || event.character_name != "" end end end if $game_player.x == new_x and $game_player.y == new_y unless $game_player.through return false if @character_name != "" end end return true end def passable?(x,y,d) return passableEx?(x,y,d,false) end def passableStrict?(x,y,d) return passableEx?(x,y,d,true) end def lock if @locked return end @prelock_direction = @direction turn_toward_player @locked = true end def lock? return @locked end def unlock unless @locked return end @locked = false unless @direction_fix if @prelock_direction != 0 @direction = @prelock_direction end end end def moveto(x, y) @x = x % self.map.width @y = y % self.map.height @real_x = @x * Game_Map.realResX @real_y = @y * Game_Map.realResY @prelock_direction = 0 end def screen_x return (@real_x - self.map.display_x + 3) / 4 + (Game_Map::TILEWIDTH/2) end def screen_y y = (@real_y - self.map.display_y + 3) / 4 + (Game_Map::TILEHEIGHT) if jumping? if @jump_count >= @jump_peak n = @jump_count - @jump_peak else n = @jump_peak - @jump_count end return y - (@jump_peak * @jump_peak - n * n) / 2 else return y end end def screen_z(height = 0) if @always_on_top return 999 end z = (@real_y - self.map.display_y + 3) / 4 + 32 if @tile_id > 0 return z + self.map.priorities[@tile_id] * 32 else # Add Z if height exceeds 32 return z + ((height > 32) ? 31 : 0) end end def bush_depth if @tile_id > 0 or @always_on_top return 0 end if @jump_count <= 0 and self.map.bush?(@x, @y) return 12 else return 0 end end def terrain_tag return self.map.terrain_tag(@x, @y) end end
Game_Character_2
[
Selecionar
] [
-
]
class Game_Character def update if jumping? update_jump elsif moving? update_move else update_stop end if @anime_count > 18 - @move_speed * 2 if not @step_anime and @stop_count > 0 @pattern = @original_pattern else @pattern = (@pattern + 1) % 4 end @anime_count = 0 end if @wait_count > 0 @wait_count -= 1 return end if @move_route_forcing move_type_custom return end if @starting or lock? return end if @stop_count > (40 - @move_frequency * 2) * (6 - @move_frequency) case @move_type when 1 move_type_random when 2 move_type_toward_player when 3 move_type_custom end end end def update_jump @jump_count -= 1 @real_x = (@real_x * @jump_count + @x * Game_Map.realResX) / (@jump_count + 1) @real_y = (@real_y * @jump_count + @y * Game_Map.realResY) / (@jump_count + 1) end def update_move distance = 2 ** @move_speed realResX=Game_Map.realResX realResY=Game_Map.realResY if @y * realResY > @real_y @real_y = [@real_y + distance, @y * realResY].min end if @x * realResX < @real_x @real_x = [@real_x - distance, @x * realResX].max end if @x * realResX > @real_x @real_x = [@real_x + distance, @x * realResX].min end if @y * realResY < @real_y @real_y = [@real_y - distance, @y * realResY].max end if @walk_anime @anime_count += 1.5 elsif @step_anime @anime_count += 1 end end def update_stop if @step_anime @anime_count += 1 elsif @pattern != @original_pattern @anime_count += 1.5 end unless @starting or lock? @stop_count += 1 end end def move_type_random case rand(6) when 0..3 move_random when 4 move_forward when 5 @stop_count = 0 end end def move_type_toward_player sx = @x - $game_player.x sy = @y - $game_player.y abs_sx = sx > 0 ? sx : -sx abs_sy = sy > 0 ? sy : -sy if sx + sy >= 20 move_random return end case rand(6) when 0..3 move_toward_player when 4 move_random when 5 move_forward end end def move_type_custom if jumping? or moving? return end 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 end unless @move_route.repeat if @move_route_forcing and not @move_route.repeat @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 move_down when 2 move_left when 3 move_right when 4 move_up when 5 move_lower_left when 6 move_lower_right when 7 move_upper_left when 8 move_upper_right when 9 move_random when 10 move_toward_player when 11 move_away_from_player when 12 move_forward when 13 move_backward when 14 jump(command.parameters[0], command.parameters[1]) end if not @move_route.skippable and not moving? and not jumping? return end @move_route_index += 1 return end if command.code == 15 @wait_count = command.parameters[0] * 2 - 1 @move_route_index += 1 return end if command.code >= 16 and command.code <= 26 case command.code when 16 turn_down when 17 turn_left when 18 turn_right when 19 turn_up when 20 turn_right_90 when 21 turn_left_90 when 22 turn_180 when 23 turn_right_or_left_90 when 24 turn_random when 25 turn_toward_player when 26 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 @move_speed = command.parameters[0] when 30 @move_frequency = command.parameters[0] when 31 @walk_anime = true when 32 @walk_anime = false when 33 @step_anime = true when 34 @step_anime = false when 35 @direction_fix = true when 36 @direction_fix = false when 37 @through = true when 38 @through = false when 39 @always_on_top = true when 40 @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 @opacity = command.parameters[0] when 43 @blend_type = command.parameters[0] when 44 $game_system.se_play(command.parameters[0]) when 45 result = eval(command.parameters[0]) end @move_route_index += 1 end end end def increase_steps @stop_count = 0 end end
Game_Character_3
[
Selecionar
] [
-
]
class Game_Character def move_down(turn_enabled = true) if turn_enabled turn_down end if passable?(@x, @y, 2) turn_down @y += 1 increase_steps else check_event_trigger_touch(@x, @y+1) end end def move_left(turn_enabled = true) if turn_enabled turn_left end if passable?(@x, @y, 4) turn_left @x -= 1 increase_steps else check_event_trigger_touch(@x-1, @y) end end def move_right(turn_enabled = true) if turn_enabled turn_right end if passable?(@x, @y, 6) turn_right @x += 1 increase_steps else check_event_trigger_touch(@x+1, @y) end end def move_up(turn_enabled = true) if turn_enabled turn_up end if passable?(@x, @y, 8) turn_up @y -= 1 increase_steps else check_event_trigger_touch(@x, @y-1) end end def move_lower_left unless @direction_fix @direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction) end if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 4)) or (passable?(@x, @y, 4) and passable?(@x - 1, @y, 2)) @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 (passable?(@x, @y, 2) and passable?(@x, @y + 1, 6)) or (passable?(@x, @y, 6) and passable?(@x + 1, @y, 2)) @x += 1 @y += 1 increase_steps end end def move_upper_left unless @direction_fix @direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction) end if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 4)) or (passable?(@x, @y, 4) and passable?(@x - 1, @y, 8)) @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 (passable?(@x, @y, 8) and passable?(@x, @y - 1, 6)) or (passable?(@x, @y, 6) and passable?(@x + 1, @y, 8)) @x += 1 @y -= 1 increase_steps end end def move_random case rand(4) when 0 move_down(false) when 1 move_left(false) when 2 move_right(false) when 3 move_up(false) end end def move_toward_player sx = @x - $game_player.x sy = @y - $game_player.y if sx == 0 and sy == 0 return end 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 - $game_player.x sy = @y - $game_player.y if sx == 0 and sy == 0 return end 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 move_down(false) when 4 move_left(false) when 6 move_right(false) when 8 move_up(false) end end def move_backward last_direction_fix = @direction_fix @direction_fix = true case @direction when 2 move_up(false) when 4 move_right(false) when 6 move_left(false) when 8 move_down(false) end @direction_fix = last_direction_fix end def jump(x_plus, y_plus) if x_plus != 0 or 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 end new_x = @x + x_plus new_y = @y + y_plus if (x_plus == 0 and y_plus == 0) or passable?(new_x, new_y, 0) straighten @x = new_x @y = new_y distance = x_plus * x_plus + y_plus * y_plus @jump_peak = 10 + distance - @move_speed @jump_peak = @jump_peak.floor @jump_count = @jump_peak * 2 @stop_count = 0 if self.is_a?(Game_Player) $PokemonTemp.dependentEvents.pbJumpDependentEvents end end end def turnGeneric(dir) unless @direction_fix oldDirection=@direction @direction=dir @stop_count=0 if dir!=oldDirection pbCheckEventTriggerAfterTurning end end end def turn_down; turnGeneric(2); end def turn_left; turnGeneric(4); end def turn_right; turnGeneric(6); end def turn_up; turnGeneric(8); end def turn_right_90 case @direction when 2 turn_left when 4 turn_up when 6 turn_down when 8 turn_right end end def turn_left_90 case @direction when 2 turn_right when 4 turn_down when 6 turn_up when 8 turn_left end end def turn_180 case @direction when 2 turn_up when 4 turn_right when 6 turn_left when 8 turn_down end end def turn_right_or_left_90 if rand(2) == 0 turn_right_90 else turn_left_90 end end def turn_random case rand(4) when 0 turn_up when 1 turn_right when 2 turn_left when 3 turn_down end end def turn_toward_player sx = @x - $game_player.x sy = @y - $game_player.y if sx == 0 and sy == 0 return end 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 - $game_player.x sy = @y - $game_player.y if sx == 0 and sy == 0 return end if sx.abs > sy.abs sx > 0 ? turn_right : turn_left else sy > 0 ? turn_down : turn_up end end end
Game_Event
[
Selecionar
] [
-
]
class Game_Event < Game_Character attr_reader :trigger attr_reader :list attr_reader :starting attr_reader :keypress # Event triggered by a key press 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 @erased = false @starting = false @keypress=false @need_refresh=false @route_erased=false @through = true @tempSwitches={} moveto(@event.x, @event.y) if map refresh end def map_id @map_id end def clear_starting @starting = false end def over_trigger? if @character_name != "" and not @through return false end unless self.map.passable?(@x, @y, 0) return false end return true end def start(keypress=false) if @list.size > 1 @starting = true @keypress=keypress end end def erase @erased = true refresh end def erase_route @route_erased=true refresh end def name return @event.name end def id return @event.id end def pbCheckEventTriggerAfterTurning if $game_system.map_interpreter.running? return end if @event.name[/^Trainer\\((\\d+)\\)$/] distance=$~[1].to_i if @trigger == 2 and pbEventCanReachPlayer?(self,$game_player,distance) if not jumping? and not over_trigger? start end end end 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 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 return ontime && (Time.now.to_i>ontime+secs) end def onEvent? return @map_id==$game_map.map_id && $game_player.x==self.x && $game_player.y==self.y 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 refresh new_page = nil unless @erased for page in @event.pages.reverse c = page.condition if c.switch1_valid if !switchIsOn?(c.switch1_id) next end end if c.switch2_valid if !switchIsOn?(c.switch2_id) next end end if c.variable_valid if $game_variables[c.variable_id] < c.variable_value next end end if c.self_switch_valid key = [@map_id, @event.id, c.self_switch_ch] if $game_self_switches[key] != true next end end new_page = page break end end if new_page == @page return end @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 @move_speed = @page.move_speed * 1.25 @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 @interpreter = Interpreter.new end check_event_trigger_auto end def check_event_trigger_touch(x, y) if $game_system.map_interpreter.running? return end return if @trigger!=2 return if x != $game_player.x || y != $game_player.y if not jumping? and not over_trigger? start end end def check_event_trigger_auto if @trigger == 2 and @x == $game_player.x and @y == $game_player.y if not jumping? and over_trigger? start end end if @trigger == 3 start end end def 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) end @interpreter.update end end end
Game_Player
[
Selecionar
] [
-
]
#============================================================================== # ** 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. #============================================================================== 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 def pbRemoveDependency2(eventName) $PokemonTemp.dependentEvents.removeEventByName(eventName) end class Game_Player < Game_Character def map @map=nil return $game_map end #-------------------------------------------------------------------------- # * Invariables #-------------------------------------------------------------------------- def initialize(*arg) super(*arg) @lastdir=0 @lastdirframe=0 end def pbHasDependentEvents? return $PokemonGlobal.dependentEvents.length>0 end def move_down(turn_enabled = true) if turn_enabled turn_down end pbBridgeCheck(2) if passable?(@x, @y, 2) return if pbLedge(0,1) return if pbEndSurf(0,1) turn_down @y += 1 $PokemonTemp.dependentEvents.pbMoveDependentEvents increase_steps else if !check_event_trigger_touch(@x, @y+1) Audio.se_play("Audio/SE/bump.wav") end end end def move_left(turn_enabled = true) if turn_enabled turn_left end pbBridgeCheck(4) if passable?(@x, @y, 4) return if pbLedge(-1,0) return if pbEndSurf(-1,0) turn_left @x -= 1 $PokemonTemp.dependentEvents.pbMoveDependentEvents increase_steps else if !check_event_trigger_touch(@x-1, @y) Audio.se_play("Audio/SE/bump.wav") end end end def move_right(turn_enabled = true) if turn_enabled turn_right end pbBridgeCheck(6) if passable?(@x, @y, 6) return if pbLedge(1,0) return if pbEndSurf(1,0) turn_right @x += 1 $PokemonTemp.dependentEvents.pbMoveDependentEvents increase_steps else if !check_event_trigger_touch(@x+1, @y) Audio.se_play("Audio/SE/bump.wav") end end end def move_up(turn_enabled = true) if turn_enabled turn_up end pbBridgeCheck(8) if passable?(@x, @y, 8) return if pbLedge(0,-1) return if pbEndSurf(0,-1) turn_up @y -= 1 $PokemonTemp.dependentEvents.pbMoveDependentEvents increase_steps else if !check_event_trigger_touch(@x, @y-1) Audio.se_play("Audio/SE/bump.wav") end end end def pbTriggeredTrainerEvents(triggers,checkIfRunning=true) result = [] # If event is running if checkIfRunning && $game_system.map_interpreter.running? return result end # All event loops for event in $game_map.events.values next if !event.name[/^Trainer\\((\\d+)\\)$/] 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) if not event.jumping? and not event.over_trigger? result.push(event) end end end return result end def pbTriggeredCounterEvents(triggers,checkIfRunning=true) result = [] # If event is running if checkIfRunning && $game_system.map_interpreter.running? return result end # All event loops for event in $game_map.events.values next if !event.name[/^Counter\\((\\d+)\\)$/] 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) if not event.jumping? and not event.over_trigger? result.push(event) end 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 pbFacingEvent if $game_system.map_interpreter.running? return nil end new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0) new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0) for event in $game_map.events.values if event.x == new_x and event.y == new_y if not event.jumping? and not event.over_trigger? return event end end end 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 if event.x == new_x and event.y == new_y if not event.jumping? and not event.over_trigger? return event end end end end return nil 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) # 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 unless $game_map.validLax?(new_x, new_y) # Impassable return false end 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 if $DEBUG and Input.press?(Input::CTRL) # Passable return true end super end #-------------------------------------------------------------------------- # * Set Map Display Position to Center of Screen #-------------------------------------------------------------------------- def center(x, y) center_x = (Graphics.width/2 - 16) * 4 # Center screen x-coordinate * 4 center_y = (Graphics.height/2 - 16) * 4 # Center screen y-coordinate * 4 max_x = ($game_map.width - Graphics.width/32.0) * 128 max_y = ($game_map.height - Graphics.height/32.0) * 128 $game_map.display_x = [0, [x * 128 - center_x, max_x].min].max $game_map.display_y = [0, [y * 128 - center_y, max_y].min].max 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 #-------------------------------------------------------------------------- # * Increase Steps #-------------------------------------------------------------------------- def increase_steps super end #-------------------------------------------------------------------------- # * Get Encounter Count #-------------------------------------------------------------------------- def encounter_count return @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 #-------------------------------------------------------------------------- # * Same Position Starting Determinant #-------------------------------------------------------------------------- def check_event_trigger_here(triggers,keypress=false) result = false # If event is running if $game_system.map_interpreter.running? return result end # All event loops for event in $game_map.events.values # If event coordinates and triggers are consistent if event.x == @x and event.y == @y and triggers.include?(event.trigger) # If starting determinant is same position event (other than jumping) if not event.jumping? and event.over_trigger? event.start(keypress) result = true end end end return result end #-------------------------------------------------------------------------- # * Front Envent Starting Determinant #-------------------------------------------------------------------------- def check_event_trigger_there(triggers,keypress=false) result = false # If event is running if $game_system.map_interpreter.running? return result end # Calculate front event coordinates new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0) new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0) # All event loops for event in $game_map.events.values # If event coordinates and triggers are consistent if event.x == new_x and event.y == new_y and triggers.include?(event.trigger) # If starting determinant is front event (other than jumping) if not event.jumping? and (keypress || !event.over_trigger?) event.start(keypress) result = true end end 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 1 tile inside coordinates new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0) new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 : 0) # All event loops for event in $game_map.events.values # If event coordinates and triggers are consistent if event.x == new_x and event.y == new_y and triggers.include?(event.trigger) # If starting determinant is front event (other than jumping) if not event.jumping? and (keypress || !event.over_trigger?) event.start result = true end end end end end return result end #-------------------------------------------------------------------------- # * Touch Event Starting Determinant #-------------------------------------------------------------------------- def check_event_trigger_touch(x, y) result = false # If event is running if $game_system.map_interpreter.running? return result end # All event loops for event in $game_map.events.values if event.name[/^Trainer\\((\\d+)\\)$/] distance=$~[1].to_i next if !pbEventCanReachPlayer?(event,self,distance) end if event.name[/^Counter\\((\\d+)\\)$/] distance=$~[1].to_i next if !pbEventFacesPlayer?(event,self,distance) end # If event coordinates and triggers are consistent if event.x == x and event.y == y and [1,2].include?(event.trigger) # If starting determinant is front event (other than jumping) if not event.jumping? and not event.over_trigger? event.start result = true end end end return result end #-------------------------------------------------------------------------- # * Frame Update #-------------------------------------------------------------------------- def update # Remember whether or not moving in local variables last_moving = moving? # If moving, event running, move route forcing, and message window # display are all not occurring dir=Input.dir4 unless moving? or $game_system.map_interpreter.running? or @move_route_forcing or $game_temp.message_window_showing or $PokemonTemp.miniupdate # Move player in the direction the directional button is being pressed if dir==@lastdir && Graphics.frame_count-@lastdirframe>2 case dir when 2 move_down when 4 move_left when 6 move_right when 8 move_up end elsif dir!=@lastdir case dir when 2 turn_down when 4 turn_left when 6 turn_right when 8 turn_up end end end $PokemonTemp.dependentEvents.updateDependentEvents if dir!=@lastdir @lastdirframe=Graphics.frame_count end @lastdir=dir # Remember coordinates in local variables last_real_x = @real_x last_real_y = @real_y super center_x = (Graphics.width/2 - 16) * 4 # Center screen x-coordinate * 4 center_y = (Graphics.height/2 - 16) * 4 # Center screen y-coordinate * 4 # If character moves down and is positioned lower than the center # of the screen if @real_y > last_real_y and @real_y - $game_map.display_y > center_y # Scroll map down $game_map.scroll_down(@real_y - last_real_y) end # If character moves left and is positioned more let on-screen than # center if @real_x < last_real_x and @real_x - $game_map.display_x < center_x # Scroll map left $game_map.scroll_left(last_real_x - @real_x) end # If character moves right and is positioned more right on-screen than # center if @real_x > last_real_x and @real_x - $game_map.display_x > center_x # Scroll map right $game_map.scroll_right(@real_x - last_real_x) end # If character moves up and is positioned higher than the center # of the screen if @real_y < last_real_y and @real_y - $game_map.display_y < center_y # Scroll map up $game_map.scroll_up(last_real_y - @real_y) end # If not moving unless moving? # If player was moving last time if last_moving $PokemonTemp.dependentEvents.pbTurnDependentEvents result = pbCheckEventTriggerFromDistance([2]) # Event determinant is via touch of same position event result |= check_event_trigger_here([1,2]) # If event which started does not exist Kernel.pbOnStepTaken(result) # *Added function call if result == false # Disregard if debug mode is ON and ctrl key was pressed unless $DEBUG and Input.press?(Input::CTRL) # Encounter countdown if @encounter_count > 0 @encounter_count -= 1 end end end end # If C button was pressed if Input.trigger?(Input::C) && !$PokemonTemp.miniupdate # Same position and front event determinant check_event_trigger_here([0],true) check_event_trigger_there([0,2],true) # *Modified to prevent unnecessary triggers end end end end
Sprite_Character
[
Selecionar
] [
-
]
class Sprite_Character < RPG::Sprite attr_accessor :character def initialize(viewport, character = nil) super(viewport) @character = character update end def pbBushDepthBitmap(bitmap,depth) ret=Bitmap.new(bitmap.width,bitmap.height) charheight=ret.height/4 for i in 0...4 cy=charheight-depth-2 y=i*charheight ret.blt(0,y,bitmap, Rect.new(0,y,ret.width,cy)) if cy>=0 ret.blt(0,y+cy,bitmap, Rect.new(0,y+cy,ret.width,2),170) if cy>=0 ret.blt(0,y+cy+2,bitmap, Rect.new(0,y+cy+2,ret.width,2),85) if cy+2>=0 end return ret end def pbBushDepthTile(bitmap,depth) ret=Bitmap.new(bitmap.width,bitmap.height) charheight=ret.height cy=charheight-depth-2 y=charheight ret.blt(0,y,bitmap, Rect.new(0,y,ret.width,cy)) if cy>=0 ret.blt(0,y+cy,bitmap, Rect.new(0,y+cy,ret.width,2),170) if cy>=0 ret.blt(0,y+cy+2,bitmap, Rect.new(0,y+cy+2,ret.width,2),85) if cy+2>=0 return ret end def dispose @bushbitmap.dispose if @bushbitmap @bushbitmap=nil super end def update super if @tile_id != @character.tile_id or @character_name != @character.character_name or @character_hue != @character.character_hue @tile_id = @character.tile_id @character_name = @character.character_name @character_hue = @character.character_hue if @tile_id >= 384 @charbitmap.dispose if @charbitmap @charbitmap = RPG::Cache.tile(@character.map.tileset_name, @tile_id, @character.character_hue) @bushbitmap.dispose if @bushbitmap @bushbitmap=nil @cw = 32 # added @ch = 32 # added self.src_rect.set(0, 0, 32, 32) self.ox = Game_Map::TILEWIDTH/2 self.oy = Game_Map::TILEHEIGHT else @charbitmap.dispose if @charbitmap @charbitmap = RPG::Cache.character(@character.character_name, @character.character_hue) @bushbitmap.dispose if @bushbitmap @bushbitmap=nil @cw = @charbitmap.width / 4 @ch = @charbitmap.height / 4 self.ox = @cw / 2 self.oy = @ch end end if @character.bush_depth==0 self.bitmap=@charbitmap else if !@bushbitmap if @tile_id >= 384 @bushbitmap=pbBushDepthTile(@charbitmap,12) else @bushbitmap=pbBushDepthBitmap(@charbitmap,12) end end self.bitmap=@bushbitmap end self.visible = (not @character.transparent) if @tile_id == 0 sx = @character.pattern * @cw sy = (@character.direction - 2) / 2 * @ch self.src_rect.set(sx, sy, @cw, @ch) end if self.visible if $PokemonSystem.tilemap==0 || (@character.is_a?(Game_Event) && @character.name=="RegularTone") self.tone.set(0,0,0,0) else pbDayNightTint(self) end end self.x = @character.screen_x self.y = @character.screen_y self.z = @character.screen_z(@ch) self.opacity = @character.opacity self.blend_type = @character.blend_type # self.bush_depth = @character.bush_depth if @character.animation_id != 0 animation = $data_animations[@character.animation_id] animation(animation, true) @character.animation_id = 0 end end end
Sprite_Picture
[
Selecionar
] [
-
]
class Sprite_Picture def initialize(viewport, picture) @viewport = viewport @picture = picture @sprite = nil update end def dispose if @sprite @sprite.dispose end end def update @sprite.update if @sprite # If picture file name is different from current one if @picture_name != @picture.name # Remember file name to instance variables @picture_name = @picture.name # If file name is not empty if @picture_name != "" # Get picture graphic @sprite.dispose if @sprite @sprite=GifSprite.new("Graphics/Pictures/"+@picture_name,@viewport) end end # If file name is empty if @picture_name == "" # Set sprite to invisible if @sprite @sprite.dispose if @sprite @sprite=nil end return end # Set sprite to visible @sprite.visible = true # Set transfer starting point if @picture.origin == 0 @sprite.ox = 0 @sprite.oy = 0 else @sprite.ox = @sprite.bitmap.width / 2 @sprite.oy = @sprite.bitmap.height / 2 end # Set sprite coordinates @sprite.x = @picture.x @sprite.y = @picture.y @sprite.z = @picture.number # Set zoom rate, opacity level, and blend method @sprite.zoom_x = @picture.zoom_x / 100.0 @sprite.zoom_y = @picture.zoom_y / 100.0 @sprite.opacity = @picture.opacity @sprite.blend_type = @picture.blend_type # Set rotation angle and color tone @sprite.angle = @picture.angle @sprite.tone = @picture.tone end end
Sprite_Timer
[
Selecionar
] [
-
]
class Sprite_Timer def initialize @timer=nil @total_sec=nil @disposed=false end def dispose @timer.dispose if @timer @timer=nil @disposed=true end def disposed? @disposed end def update return if disposed? if $game_system.timer_working if !@timer @timer=Window_AdvancedTextPokemon.newWithSize("", Graphics.width-120,0,120,64) @timer.z=99998 end curtime=$game_system.timer / Graphics.frame_rate if curtime != @total_sec # Calculate total number of seconds @total_sec = curtime # Make a string for displaying the timer min = @total_sec / 60 sec = @total_sec % 60 @timer.text = _ISPRINTF("<ac>{1:02d}:{2:02d}", min, sec) end end end end
Spriteset_Map
[
Selecionar
] [
-
]
class Spriteset_Map attr_reader :map def initialize(map=nil) @map=map ? map : $game_map @viewport1 = Viewport.new(0, 0, Graphics.width,Graphics.height) @viewport1a = Viewport.new(0, 0, Graphics.width,Graphics.height) @viewport2 = Viewport.new(0, 0, Graphics.width,Graphics.height) @viewport3 = Viewport.new(0, 0, Graphics.width,Graphics.height) @viewport1a.z = 100 @viewport2.z = 200 @viewport3.z = 500 @tilemap = TilemapLoader.new(@viewport1) @tilemap.tileset = RPG::Cache.tileset(@map.tileset_name) for i in 0..6 autotile_name = @map.autotile_names[i] @tilemap.autotiles[i] = RPG::Cache.autotile(autotile_name) end @tilemap.map_data = @map.data @tilemap.priorities = @map.priorities @panorama = AnimatedPlane.new(@viewport1) @panorama.z = -1000 @fog = AnimatedPlane.new(@viewport1) @fog.z = 3000 @reflectedSprites=[] @character_sprites = [] for i in @map.events.keys.sort sprite = Sprite_Character.new(@viewport1, @map.events[i]) @character_sprites.push(sprite) @reflectedSprites.push(ReflectedSprite.new(sprite,@map.events[i],@viewport1)) end playersprite=Sprite_Character.new(@viewport1, $game_player) @reflectedSprites.push( ReflectedSprite.new(playersprite,$game_player,@viewport1) ) @character_sprites.push(playersprite) @weather = RPG::Weather.new(@viewport1a) @picture_sprites = [] for i in 1..50 @picture_sprites.push(Sprite_Picture.new(@viewport2, $game_screen.pictures[i])) end @timer_sprite = Sprite_Timer.new Kernel.pbOnSpritesetCreate(self,@viewport1) update end class ReflectedSprite def initialize(sprite,event,viewport=nil) @rsprite=sprite @sprite=nil @event=event @disposed=false @viewport=viewport update end def dispose if !@disposed @sprite.dispose if @sprite @sprite=nil @disposed=true end end def disposed? @disposed end def update return if disposed? currentY=@event.real_y.to_i/(4*Game_Map::TILEHEIGHT) limit=@rsprite.src_rect.height shouldShow=false # Clipping at Y i=0 while i<@rsprite.src_rect.height+Game_Map::TILEHEIGHT nextY=currentY+1+(i>>5) if @event.map.terrain_tag(@event.x,nextY)!=6 limit= ((nextY * (4*Game_Map::TILEHEIGHT))-@event.map.display_y+3).to_i/4 limit-=@rsprite.y break else shouldShow=true end i+=Game_Map::TILEHEIGHT end if limit>0 && shouldShow # Just-in-time creation of sprite if !@sprite @sprite=Sprite.new(@viewport) end else # Just-in-time disposal of sprite if @sprite @sprite.dispose @sprite=nil end return end if @sprite x=@rsprite.x-@rsprite.ox y=@rsprite.y-@rsprite.oy width=@rsprite.src_rect.width height=@rsprite.src_rect.height frame=(Graphics.frame_count%40)/10 if frame==1 @sprite.zoom_x=1.1 elsif frame==3 @sprite.zoom_x=0.9 else @sprite.zoom_x=1.0 end tileX=@event.map.display_x @sprite.x=x+width/2 @sprite.y=y+height+height/2 @sprite.ox=width/2 @sprite.oy=height/2 @sprite.angle=180 @sprite.z=@rsprite.z @sprite.mirror=true @sprite.bitmap=@rsprite.bitmap @sprite.tone=@rsprite.tone @sprite.opacity=@rsprite.opacity/2 @sprite.src_rect=@rsprite.src_rect currentY=@event.real_y.to_i/(4*Game_Map::TILEHEIGHT) if limit<@sprite.src_rect.height diff=@sprite.src_rect.height-limit @sprite.src_rect.y+=diff @sprite.src_rect.height=limit @sprite.y-=diff end end end end def dispose @tilemap.tileset.dispose for i in 0..6 @tilemap.autotiles[i].dispose end @tilemap.dispose @panorama.dispose @fog.dispose for sprite in @character_sprites sprite.dispose end for sprite in @reflectedSprites sprite.dispose end @weather.dispose for sprite in @picture_sprites sprite.dispose end @timer_sprite.dispose @viewport1.dispose @viewport2.dispose @viewport3.dispose @tilemap=nil @panorama=nil @fog=nil @character_sprites.clear @reflectedSprites.clear @weather=nil @picture_sprites.clear @viewport1=nil @viewport2=nil @viewport3=nil @timer_sprite=nil end def in_range?(object) return true if $PokemonSystem.tilemap==2 screne_x = @map.display_x screne_x -= 256 screne_y = @map.display_y screne_y -= 256 screne_width = @map.display_x screne_width += Graphics.width*4+256 # 2816 screne_height = @map.display_y screne_height += Graphics.height*4+256 # 2176 return false if object.real_x <= screne_x return false if object.real_x >= screne_width return false if object.real_y <= screne_y return false if object.real_y >= screne_height return true end def update if @panorama_name != @map.panorama_name or @panorama_hue != @map.panorama_hue @panorama_name = @map.panorama_name @panorama_hue = @map.panorama_hue if @panorama.bitmap != nil @panorama.setPanorama(nil) end if @panorama_name != "" @panorama.setPanorama(@panorama_name, @panorama_hue) end Graphics.frame_reset end if @fog_name != @map.fog_name or @fog_hue != @map.fog_hue @fog_name = @map.fog_name @fog_hue = @map.fog_hue if @fog.bitmap != nil @fog.setFog(nil) end if @fog_name != "" @fog.setFog(@fog_name, @fog_hue) end Graphics.frame_reset end tmox = @map.display_x.to_i / 4 tmoy = @map.display_y.to_i / 4 @tilemap.ox=tmox @tilemap.oy=tmoy if $PokemonSystem.tilemap!=2 @viewport1.rect.x=[-tmox,0].max @viewport1.rect.y=[-tmoy,0].max @viewport1.rect.width= [@tilemap.map_data.xsize*Game_Map::TILEWIDTH-tmox,Graphics.width].min @viewport1.rect.height= [@tilemap.map_data.ysize*Game_Map::TILEHEIGHT-tmoy,Graphics.height].min @viewport1.ox=[-tmox,0].max @viewport1.oy=[-tmoy,0].max else @viewport1.rect.set(0,0,Graphics.width,Graphics.height) @viewport1.ox=0 @viewport1.oy=0 end @viewport1.ox += $game_screen.shake @tilemap.update @panorama.ox = @map.display_x / 8 @panorama.oy = @map.display_y / 8 @fog.zoom_x = @map.fog_zoom / 100.0 @fog.zoom_y = @map.fog_zoom / 100.0 @fog.opacity = @map.fog_opacity @fog.blend_type = @map.fog_blend_type @fog.ox = @map.display_x / 4 + @map.fog_ox @fog.oy = @map.display_y / 4 + @map.fog_oy @fog.tone = @map.fog_tone @panorama.update @fog.update for sprite in @character_sprites if sprite.character.is_a?(Game_Event) if sprite.character.trigger == 3 || sprite.character.trigger == 4 || in_range?(sprite.character) sprite.update end else sprite.update end end for sprite in @reflectedSprites sprite.update end if self.map!=$game_map @weather.max-=2 if @weather.max>0 @weather.type = 0 if @weather.max==0 @weather.ox = 0 if @weather.max==0 @weather.oy = 0 if @weather.max==0 else @weather.type = $game_screen.weather_type @weather.max = $game_screen.weather_max @weather.ox = @map.display_x / 4 @weather.oy = @map.display_y / 4 end @weather.update for sprite in @picture_sprites sprite.update end @timer_sprite.update @viewport1.tone = $game_screen.tone @viewport1a.ox += $game_screen.shake @viewport3.color = $game_screen.flash_color @viewport1.update @viewport1a.update @viewport3.update end end
Interpreter
[
Selecionar
] [
-
]
#============================================================================== # ** Interpreter #------------------------------------------------------------------------------ # This interpreter runs event commands. This class is used within the # Game_System class and the Game_Event class. #============================================================================== class Interpreter #-------------------------------------------------------------------------- # * Object Initialization # depth : nest depth # main : main flag #-------------------------------------------------------------------------- def initialize(depth = 0, main = false) @depth = depth @main = main # Depth goes up to level 100 if depth > 100 print("Common event call has exceeded maximum limit.") exit end # Clear inner situation of interpreter clear end def clear @map_id = 0 # map ID when starting up @event_id = 0 # event ID @message_waiting = false # waiting for message to end @move_route_waiting = false # waiting for move completion @button_input_variable_id = 0 # button input variable ID @wait_count = 0 # wait count @child_interpreter = nil # child interpreter @branch = {} # branch data end #-------------------------------------------------------------------------- # * Event Setup # list : list of event commands # event_id : event ID #-------------------------------------------------------------------------- def setup(list, event_id) # Clear inner situation of interpreter clear # Remember map ID @map_id = $game_map.map_id # Remember event ID @event_id = event_id # Remember list of event commands @list = list # Initialize index @index = 0 # Clear branch data hash @branch.clear end def running? return @list != nil end def setup_starting_event # Refresh map if necessary if $game_map.need_refresh $game_map.refresh end # If common event call is reserved if $game_temp.common_event_id > 0 # Set up event setup($data_common_events[$game_temp.common_event_id].list, 0) # Release reservation $game_temp.common_event_id = 0 return end # Loop (map events) for event in $game_map.events.values # If running event is found if event.starting # If not auto run if event.trigger < 3 # Clear starting flag event.clear_starting # Lock event.lock end # Set up event setup(event.list, event.id) return end end # Loop (common events) for common_event in $data_common_events.compact # If trigger is auto run, and condition switch is ON if common_event.trigger == 1 and $game_switches[common_event.switch_id] == true # Set up event setup(common_event.list, 0) return end end end #-------------------------------------------------------------------------- # * Frame Update #-------------------------------------------------------------------------- def update # Initialize loop count @loop_count = 0 # Loop loop do # Add 1 to loop count @loop_count += 1 # If 100 event commands ran if @loop_count > 100 # Call Graphics.update for freeze prevention Graphics.update @loop_count = 0 end # If map is different than event startup time if $game_map.map_id != @map_id # Change event ID to 0 @event_id = 0 end # If a child interpreter exists if @child_interpreter != nil # Update child interpreter @child_interpreter.update # If child interpreter is finished running unless @child_interpreter.running? # Delete child interpreter @child_interpreter = nil end # If child interpreter still exists if @child_interpreter != nil return end end # If waiting for message to end if @message_waiting return end # If waiting for move to end if @move_route_waiting # If player is forcing move route if $game_player.move_route_forcing return end # Loop (map events) for event in $game_map.events.values # If this event is forcing move route if event.move_route_forcing return end end # Clear move end waiting flag @move_route_waiting = false end # If waiting for button input if @button_input_variable_id > 0 # Run button input processing input_button return end # If waiting if @wait_count > 0 # Decrease wait count @wait_count -= 1 return end # If an action forcing battler exists if $game_temp.forcing_battler != nil return end # If a call flag is set for each type of screen if $game_temp.battle_calling or $game_temp.shop_calling or $game_temp.name_calling or $game_temp.menu_calling or $game_temp.save_calling or $game_temp.gameover return end # If list of event commands is empty if @list == nil # If main map event if @main # Set up starting event setup_starting_event end # If nothing was set up if @list == nil return end end # If return value is false when trying to execute event command if execute_command == false return end # Advance index @index += 1 end end #-------------------------------------------------------------------------- # * Button Input #-------------------------------------------------------------------------- def input_button # Determine pressed button n = 0 for i in 1..18 if Input.trigger?(i) n = i end end # If button was pressed if n > 0 # Change value of variables $game_variables[@button_input_variable_id] = n $game_map.need_refresh = true # End button input @button_input_variable_id = 0 end end #-------------------------------------------------------------------------- # * Setup Choices #-------------------------------------------------------------------------- def setup_choices(parameters) # Set choice item count to choice_max $game_temp.choice_max = parameters[0].size # Set choice to message_text for text in parameters[0] $game_temp.message_text += text + "\\n" end # Set cancel processing $game_temp.choice_cancel_type = parameters[1] # Set callback current_indent = @list[@index].indent $game_temp.choice_proc = Proc.new { |n| @branch[current_indent] = n } end def command_dummy return true end def pbExecuteScript(script) begin result = eval(script) return result rescue SyntaxError event=get_character(0) message=$!.message # Analyze script to make error message more helpful script.each_line {|line| line.gsub!(/\\s+$/,"") if line[/\\:\\:\\s*$/] message+="\\r\\n***Line '#{line}' can't begin with '::', try putting the next\\r\\nword on the same line, e.g.: 'PBSpecies::MEW'" end if line[/^\\s*\\(/] message+="\\r\\n***Line '#{line}' shouldn't begin with '(', try putting '(' at\\r\\nthe end of the last line" end } message+="\\r\\n***Full script:\\r\\n#{script}" s="" if event && $game_map mapname="???" mapname=$game_map.name rescue nil raise "Script error within event #{event.id}, map #{$game_map.map_id} (#{mapname}):\\r\\n#{message}\\r\\n" elsif $game_map mapname="???" mapname=$game_map.name rescue nil raise "Script error within map #{$game_map.map_id} (#{mapname}):\\r\\n#{message}\\r\\n" else raise "Script error in interpreter:\\r\\n#{message}\\r\\n" end return false rescue event=get_character(0) s="" for bt in $!.backtrace[0,10] s+=bt+"\\r\\n" end s.gsub!(/Section(\\d+)/){$RGSS_SCRIPTS[$1.to_i][1]} if event && $game_map mapname="???" mapname=$game_map.name rescue nil raise "Script error within event #{event.id}, map #{$game_map.map_id} (#{mapname}):\\r\\n#{$!.message}\\r\\n#{s}" elsif $game_map mapname="???" mapname=$game_map.name rescue nil raise "Script error within map #{$game_map.map_id} (#{mapname}):\\r\\n#{$!.message}\\r\\n#{s}" else raise "Script error in interpreter:\\r\\n#{$!.message}\\r\\n#{s}" end return false end end #-------------------------------------------------------------------------- # * Event Command Execution #-------------------------------------------------------------------------- def execute_command # If last to arrive for list of event commands if @index >= @list.size - 1 # End event command_end # Continue return true end # Make event command parameters available for reference via @parameters @parameters = @list[@index].parameters # Branch by command code case @list[@index].code when 101 # Show Text return command_101 when 102 # Show Choices return command_102 when 402 # When [**] return command_402 when 403 # When Cancel return command_403 when 103 # Input Number return command_103 when 104 # Change Text Options return command_104 when 105 # Button Input Processing return command_105 when 106 # Wait return command_106 when 111 # Conditional Branch return command_111 when 411 # Else return command_411 when 112 # Loop return command_112 when 413 # Repeat Above return command_413 when 113 # Break Loop return command_113 when 115 # Exit Event Processing return command_115 when 116 # Erase Event return command_116 when 117 # Call Common Event return command_117 when 118 # Label return command_118 when 119 # Jump to Label return command_119 when 121 # Control Switches return command_121 when 122 # Control Variables return command_122 when 123 # Control Self Switch return command_123 when 124 # Control Timer return command_124 when 125 # Change Gold return command_125 when 126 # Change Items return command_126 when 127 # Change Weapons return command_127 when 128 # Change Armor return command_128 when 129 # Change Party Member return command_129 when 131 # Change Windowskin return command_131 when 132 # Change Battle BGM return command_132 when 133 # Change Battle End ME return command_133 when 134 # Change Save Access return command_134 when 135 # Change Menu Access return command_135 when 136 # Change Encounter return command_136 when 201 # Transfer Player return command_201 when 202 # Set Event Location return command_202 when 203 # Scroll Map return command_203 when 204 # Change Map Settings return command_204 when 205 # Change Fog Color Tone return command_205 when 206 # Change Fog Opacity return command_206 when 207 # Show Animation return command_207 when 208 # Change Transparent Flag return command_208 when 209 # Set Move Route return command_209 when 210 # Wait for Move's Completion return command_210 when 221 # Prepare for Transition return command_221 when 222 # Execute Transition return command_222 when 223 # Change Screen Color Tone return command_223 when 224 # Screen Flash return command_224 when 225 # Screen Shake return command_225 when 231 # Show Picture return command_231 when 232 # Move Picture return command_232 when 233 # Rotate Picture return command_233 when 234 # Change Picture Color Tone return command_234 when 235 # Erase Picture return command_235 when 236 # Set Weather Effects return command_236 when 241 # Play BGM return command_241 when 242 # Fade Out BGM return command_242 when 245 # Play BGS return command_245 when 246 # Fade Out BGS return command_246 when 247 # Memorize BGM/BGS return command_247 when 248 # Restore BGM/BGS return command_248 when 249 # Play ME return command_249 when 250 # Play SE return command_250 when 251 # Stop SE return command_251 when 301 # Battle Processing return command_301 when 601 # If Win return command_601 when 602 # If Escape return command_602 when 603 # If Lose return command_603 when 302 # Shop Processing return command_302 when 303 # Name Input Processing return command_303 when 311 # Change HP return command_311 when 312 # Change SP return command_312 when 313 # Change State return command_313 when 314 # Recover All return command_314 when 315 # Change EXP return command_315 when 316 # Change Level return command_316 when 317 # Change Parameters return command_317 when 318 # Change Skills return command_318 when 319 # Change Equipment return command_319 when 320 # Change Actor Name return command_320 when 321 # Change Actor Class return command_321 when 322 # Change Actor Graphic return command_322 when 331 # Change Enemy HP return command_331 when 332 # Change Enemy SP return command_332 when 333 # Change Enemy State return command_333 when 334 # Enemy Recover All return command_334 when 335 # Enemy Appearance return command_335 when 336 # Enemy Transform return command_336 when 337 # Show Battle Animation return command_337 when 338 # Deal Damage return command_338 when 339 # Force Action return command_339 when 340 # Abort Battle return command_340 when 351 # Call Menu Screen return command_351 when 352 # Call Save Screen return command_352 when 353 # Game Over return command_353 when 354 # Return to Title Screen return command_354 when 355 # Script return command_355 else # Other return true end end def command_dummy return true end #-------------------------------------------------------------------------- # * End Event #-------------------------------------------------------------------------- def command_end # Clear list of event commands @list = nil # If main map event and event ID are valid if @main and @event_id > 0 # Unlock event $game_map.events[@event_id].unlock end end #-------------------------------------------------------------------------- # * Command Skip #-------------------------------------------------------------------------- def command_skip # Get indent indent = @list[@index].indent # Loop loop do # If next event command is at the same level as indent if @list[@index+1].indent == indent # Continue return true end # Advance index @index += 1 end end #-------------------------------------------------------------------------- # * Get Character # parameter : parameter #-------------------------------------------------------------------------- def get_character(parameter) # Branch by parameter case parameter when -1 # player return $game_player when 0 # this event events = $game_map.events return events == nil ? nil : events[@event_id] else # specific event events = $game_map.events return events == nil ? nil : events[parameter] end end #-------------------------------------------------------------------------- # * Calculate Operated Value # operation : operation # operand_type : operand type (0: invariable 1: variable) # operand : operand (number or variable ID) #-------------------------------------------------------------------------- def operate_value(operation, operand_type, operand) # Get operand if operand_type == 0 value = operand else value = $game_variables[operand] end # Reverse sign of integer if operation is [decrease] if operation == 1 value = -value end # Return value return value end #-------------------------------------------------------------------------- # * Show Text #-------------------------------------------------------------------------- def command_101 # If other text has been set to message_text if $game_temp.message_text != nil # End return false end # Set message end waiting flag and callback @message_waiting = true $game_temp.message_proc = Proc.new { @message_waiting = false } # Set message text on first line $game_temp.message_text = @list[@index].parameters[0] + "\\n" line_count = 1 # Loop loop do # If next event command text is on the second line or after if @list[@index+1].code == 401 # Add the second line or after to message_text $game_temp.message_text += @list[@index+1].parameters[0] + "\\n" line_count += 1 # If event command is not on the second line or after else # If next event command is show choices if @list[@index+1].code == 102 # If choices fit on screen if @list[@index+1].parameters[0].size <= 4 - line_count # Advance index @index += 1 # Choices setup $game_temp.choice_start = line_count setup_choices(@list[@index].parameters) end # If next event command is input number elsif @list[@index+1].code == 103 # If number input window fits on screen if line_count < 4 # Advance index @index += 1 # Number input setup $game_temp.num_input_start = line_count $game_temp.num_input_variable_id = @list[@index].parameters[0] $game_temp.num_input_digits_max = @list[@index].parameters[1] end end # Continue return true end # Advance index @index += 1 end end #-------------------------------------------------------------------------- # * Show Choices #-------------------------------------------------------------------------- def command_102 # If text has been set to message_text if $game_temp.message_text != nil # End return false end # Set message end waiting flag and callback @message_waiting = true $game_temp.message_proc = Proc.new { @message_waiting = false } # Choices setup $game_temp.message_text = "" $game_temp.choice_start = 0 setup_choices(@parameters) # Continue return true end #-------------------------------------------------------------------------- # * When [**] #-------------------------------------------------------------------------- def command_402 # If fitting choices are selected if @branch[@list[@index].indent] == @parameters[0] # Delete branch data @branch.delete(@list[@index].indent) # Continue return true end # If it doesn't meet the condition: command skip return command_skip end #-------------------------------------------------------------------------- # * When Cancel #-------------------------------------------------------------------------- def command_403 # If choices are cancelled if @branch[@list[@index].indent] == 4 # Delete branch data @branch.delete(@list[@index].indent) # Continue return true end # If it doen't meet the condition: command skip return command_skip end #-------------------------------------------------------------------------- # * Input Number #-------------------------------------------------------------------------- def command_103 # If text has been set to message_text if $game_temp.message_text != nil # End return false end # Set message end waiting flag and callback @message_waiting = true $game_temp.message_proc = Proc.new { @message_waiting = false } # Number input setup $game_temp.message_text = "" $game_temp.num_input_start = 0 $game_temp.num_input_variable_id = @parameters[0] $game_temp.num_input_digits_max = @parameters[1] # Continue return true end #-------------------------------------------------------------------------- # * Change Text Options #-------------------------------------------------------------------------- def command_104 # If message is showing if $game_temp.message_window_showing # End return false end # Change each option $game_system.message_position = @parameters[0] $game_system.message_frame = @parameters[1] # Continue return true end #-------------------------------------------------------------------------- # * Button Input Processing #-------------------------------------------------------------------------- def command_105 # Set variable ID for button input @button_input_variable_id = @parameters[0] # Advance index @index += 1 # End return false end #-------------------------------------------------------------------------- # * Wait #-------------------------------------------------------------------------- def command_106 # Set wait count @wait_count = @parameters[0] * 2 # Continue return true end #-------------------------------------------------------------------------- # * Conditional Branch #-------------------------------------------------------------------------- def command_111 # Initialize local variable: result result = false case @parameters[0] when 0 # switch result = ($game_switches[@parameters[1]] == (@parameters[2] == 0)) when 1 # variable value1 = $game_variables[@parameters[1]] if @parameters[2] == 0 value2 = @parameters[3] else value2 = $game_variables[@parameters[3]] end case @parameters[4] when 0 # value1 is equal to value2 result = (value1 == value2) when 1 # value1 is greater than or equal to value2 result = (value1 >= value2) when 2 # value1 is less than or equal to value2 result = (value1 <= value2) when 3 # value1 is greater than value2 result = (value1 > value2) when 4 # value1 is less than value2 result = (value1 < value2) when 5 # value1 is not equal to value2 result = (value1 != value2) end when 2 # self switch if @event_id > 0 key = [$game_map.map_id, @event_id, @parameters[1]] if @parameters[2] == 0 result = ($game_self_switches[key] == true) else result = ($game_self_switches[key] != true) end end when 3 # timer if $game_system.timer_working sec = $game_system.timer / Graphics.frame_rate if @parameters[2] == 0 result = (sec >= @parameters[1]) else result = (sec <= @parameters[1]) end end when 4, 5 # actor, enemy when 6 # character character = get_character(@parameters[1]) if character != nil result = (character.direction == @parameters[2]) end when 7 if @parameters[2] == 0 result = $Trainer && ($Trainer.money >= @parameters[1]) else result = $Trainer && ($Trainer.money <= @parameters[1]) end when 8, 9, 10 # item, weapon, armor when 11 # button result = (Input.press?(@parameters[1])) when 12 # script result = pbExecuteScript(@parameters[1]) end # Store determinant results in hash @branch[@list[@index].indent] = result # If determinant results are true if @branch[@list[@index].indent] == true # Delete branch data @branch.delete(@list[@index].indent) # Continue return true end # If it doesn't meet the conditions: command skip return command_skip end #-------------------------------------------------------------------------- # * Else #-------------------------------------------------------------------------- def command_411 # If determinant results are false if @branch[@list[@index].indent] == false # Delete branch data @branch.delete(@list[@index].indent) # Continue return true end # If it doesn't meet the conditions: command skip return command_skip end #-------------------------------------------------------------------------- # * Loop #-------------------------------------------------------------------------- def command_112 # Continue return true end #-------------------------------------------------------------------------- # * Repeat Above #-------------------------------------------------------------------------- def command_413 # Get indent indent = @list[@index].indent # Loop loop do # Return index @index -= 1 # If this event command is the same level as indent if @list[@index].indent == indent # Continue return true end end end #-------------------------------------------------------------------------- # * Break Loop #-------------------------------------------------------------------------- def command_113 # Get indent indent = @list[@index].indent # Copy index to temporary variables temp_index = @index # Loop loop do # Advance index temp_index += 1 # If a fitting loop was not found if temp_index >= @list.size-1 # Continue return true end # If this event command is [repeat above] and indent is shallow if @list[temp_index].code == 413 and @list[temp_index].indent < indent # Update index @index = temp_index # Continue return true end end end #-------------------------------------------------------------------------- # * Exit Event Processing #-------------------------------------------------------------------------- def command_115 # End event command_end # Continue return true end #-------------------------------------------------------------------------- # * Erase Event #-------------------------------------------------------------------------- def command_116 # If event ID is valid if @event_id > 0 # Erase event $game_map.events[@event_id].erase end # Advance index @index += 1 # End return false end #-------------------------------------------------------------------------- # * Call Common Event #-------------------------------------------------------------------------- def command_117 # Get common event common_event = $data_common_events[@parameters[0]] # If common event is valid if common_event != nil # Make child interpreter @child_interpreter = Interpreter.new(@depth + 1) @child_interpreter.setup(common_event.list, @event_id) end # Continue return true end #-------------------------------------------------------------------------- # * Label #-------------------------------------------------------------------------- def command_118 # Continue return true end #-------------------------------------------------------------------------- # * Jump to Label #-------------------------------------------------------------------------- def command_119 # Get label name label_name = @parameters[0] # Initialize temporary variables temp_index = 0 # Loop loop do # If a fitting label was not found if temp_index >= @list.size-1 # Continue return true end # If this event command is a designated label name if @list[temp_index].code == 118 and @list[temp_index].parameters[0] == label_name # Update index @index = temp_index # Continue return true end # Advance index temp_index += 1 end end #-------------------------------------------------------------------------- # * Control Switches #-------------------------------------------------------------------------- def command_121 # Loop for group control for i in @parameters[0] .. @parameters[1] # Change switch $game_switches[i] = (@parameters[2] == 0) end # Refresh map $game_map.need_refresh = true # Continue return true end #-------------------------------------------------------------------------- # * Control Variables #-------------------------------------------------------------------------- def command_122 # Initialize value value = 0 # Branch with operand case @parameters[3] when 0 # invariable value = @parameters[4] when 1 # variable value = $game_variables[@parameters[4]] when 2 # random number value = @parameters[4] + rand(@parameters[5] - @parameters[4] + 1) when 3, 4, 5 # item, actor, enemy when 6 # character character = get_character(@parameters[4]) if character != nil case @parameters[5] when 0 # x-coordinate value = character.x when 1 # y-coordinate value = character.y when 2 # direction value = character.direction when 3 # screen x-coordinate value = character.screen_x when 4 # screen y-coordinate value = character.screen_y when 5 # terrain tag value = character.terrain_tag end end when 7 # other case @parameters[4] when 0 # map ID value = $game_map.map_id when 1, 3 # number of party members, steps when 2 # gold value = $Trainer ? $Trainer.money : 0 when 4 # play time value = Graphics.frame_count / Graphics.frame_rate when 5 # timer value = $game_system.timer / Graphics.frame_rate when 6 # save count value = $game_system.save_count end end # Loop for group control for i in @parameters[0] .. @parameters[1] # Branch with control case @parameters[2] when 0 # substitute $game_variables[i] = value when 1 # add $game_variables[i] += value when 2 # subtract $game_variables[i] -= value when 3 # multiply $game_variables[i] *= value when 4 # divide if value != 0 $game_variables[i] /= value end when 5 # remainder if value != 0 $game_variables[i] %= value end end # Maximum limit check if $game_variables[i] > 99999999 $game_variables[i] = 99999999 end # Minimum limit check if $game_variables[i] < -99999999 $game_variables[i] = -99999999 end end # Refresh map $game_map.need_refresh = true # Continue return true end #-------------------------------------------------------------------------- # * Control Self Switch #-------------------------------------------------------------------------- def command_123 # If event ID is valid if @event_id > 0 # Make a self switch key key = [$game_map.map_id, @event_id, @parameters[0]] # Change self switches $game_self_switches[key] = (@parameters[1] == 0) end # Refresh map $game_map.need_refresh = true # Continue return true end #-------------------------------------------------------------------------- # * Control Timer #-------------------------------------------------------------------------- def command_124 # If started if @parameters[0] == 0 $game_system.timer = @parameters[1] * Graphics.frame_rate $game_system.timer_working = true end # If stopped if @parameters[0] == 1 $game_system.timer_working = false end # Continue return true end alias command_125 command_dummy # Change Gold alias command_126 command_dummy # Change Items alias command_127 command_dummy # Change Weapons alias command_128 command_dummy # Change Armor alias command_129 command_dummy # Change Party Member #-------------------------------------------------------------------------- # * Change Windowskin #-------------------------------------------------------------------------- def command_131 # Change windowskin file name $game_system.windowskin_name = @parameters[0] # Continue return true end #-------------------------------------------------------------------------- # * Change Battle BGM #-------------------------------------------------------------------------- def command_132 # Change battle BGM $game_system.battle_bgm = @parameters[0] # Continue return true end #-------------------------------------------------------------------------- # * Change Battle End ME #-------------------------------------------------------------------------- def command_133 # Change battle end ME $game_system.battle_end_me = @parameters[0] # Continue return true end #-------------------------------------------------------------------------- # * Change Save Access #-------------------------------------------------------------------------- def command_134 # Change save access flag $game_system.save_disabled = (@parameters[0] == 0) # Continue return true end #-------------------------------------------------------------------------- # * Change Menu Access #-------------------------------------------------------------------------- def command_135 # Change menu access flag $game_system.menu_disabled = (@parameters[0] == 0) # Continue return true end #-------------------------------------------------------------------------- # * Change Encounter #-------------------------------------------------------------------------- def command_136 # Change encounter flag $game_system.encounter_disabled = (@parameters[0] == 0) # Make encounter count $game_player.make_encounter_count # Continue return true end #-------------------------------------------------------------------------- # * Transfer Player #-------------------------------------------------------------------------- def command_201 # If in battle if $game_temp.in_battle # Continue return true end # If transferring player, showing message, or processing transition if $game_temp.player_transferring or $game_temp.message_window_showing or $game_temp.transition_processing # End return false end # Set transferring player flag $game_temp.player_transferring = true # If appointment method is [direct appointment] if @parameters[0] == 0 # Set player move destination $game_temp.player_new_map_id = @parameters[1] $game_temp.player_new_x = @parameters[2] $game_temp.player_new_y = @parameters[3] $game_temp.player_new_direction = @parameters[4] # If appointment method is [appoint with variables] else # Set player move destination $game_temp.player_new_map_id = $game_variables[@parameters[1]] $game_temp.player_new_x = $game_variables[@parameters[2]] $game_temp.player_new_y = $game_variables[@parameters[3]] $game_temp.player_new_direction = @parameters[4] end # Advance index @index += 1 # If fade is set if @parameters[5] == 0 # Prepare for transition Graphics.freeze # Set transition processing flag $game_temp.transition_processing = true $game_temp.transition_name = "" end # End return false end #-------------------------------------------------------------------------- # * Set Event Location #-------------------------------------------------------------------------- def command_202 # If in battle if $game_temp.in_battle # Continue return true end # Get character character = get_character(@parameters[0]) # If no character exists if character == nil # Continue return true end # If appointment method is [direct appointment] if @parameters[1] == 0 # Set character position character.moveto(@parameters[2], @parameters[3]) # If appointment method is [appoint with variables] elsif @parameters[1] == 1 # Set character position character.moveto($game_variables[@parameters[2]], $game_variables[@parameters[3]]) # If appointment method is [exchange with another event] else old_x = character.x old_y = character.y character2 = get_character(@parameters[2]) if character2 != nil character.moveto(character2.x, character2.y) character2.moveto(old_x, old_y) end end # Set character direction case @parameters[4] when 8 # up character.turn_up when 6 # right character.turn_right when 2 # down character.turn_down when 4 # left character.turn_left end # Continue return true end #-------------------------------------------------------------------------- # * Scroll Map #-------------------------------------------------------------------------- def command_203 # If in battle if $game_temp.in_battle # Continue return true end # If already scrolling if $game_map.scrolling? # End return false end # Start scroll $game_map.start_scroll(@parameters[0], @parameters[1], @parameters[2]) # Continue return true end #-------------------------------------------------------------------------- # * Change Map Settings #-------------------------------------------------------------------------- def command_204 case @parameters[0] when 0 # panorama $game_map.panorama_name = @parameters[1] $game_map.panorama_hue = @parameters[2] when 1 # fog $game_map.fog_name = @parameters[1] $game_map.fog_hue = @parameters[2] $game_map.fog_opacity = @parameters[3] $game_map.fog_blend_type = @parameters[4] $game_map.fog_zoom = @parameters[5] $game_map.fog_sx = @parameters[6] $game_map.fog_sy = @parameters[7] when 2 # battleback $game_map.battleback_name = @parameters[1] $game_temp.battleback_name = @parameters[1] end # Continue return true end #-------------------------------------------------------------------------- # * Change Fog Color Tone #-------------------------------------------------------------------------- def command_205 # Start color tone change $game_map.start_fog_tone_change(@parameters[0], @parameters[1] * 2) # Continue return true end #-------------------------------------------------------------------------- # * Change Fog Opacity #-------------------------------------------------------------------------- def command_206 # Start opacity level change $game_map.start_fog_opacity_change(@parameters[0], @parameters[1] * 2) # Continue return true end #-------------------------------------------------------------------------- # * Show Animation #-------------------------------------------------------------------------- def command_207 # Get character character = get_character(@parameters[0]) # If no character exists if character == nil # Continue return true end # Set animation ID character.animation_id = @parameters[1] # Continue return true end #-------------------------------------------------------------------------- # * Change Transparent Flag #-------------------------------------------------------------------------- def command_208 # Change player transparent flag $game_player.transparent = (@parameters[0] == 0) # Continue return true end #-------------------------------------------------------------------------- # * Set Move Route #-------------------------------------------------------------------------- def command_209 # Get character character = get_character(@parameters[0]) # If no character exists if character == nil # Continue return true end # Force move route character.force_move_route(@parameters[1]) # Continue return true end #-------------------------------------------------------------------------- # * Wait for Move's Completion #-------------------------------------------------------------------------- def command_210 # If not in battle unless $game_temp.in_battle # Set move route completion waiting flag @move_route_waiting = true end # Continue return true end #-------------------------------------------------------------------------- # * Prepare for Transition #-------------------------------------------------------------------------- def command_221 # If showing message window if $game_temp.message_window_showing # End return false end # Prepare for transition Graphics.freeze # Continue return true end #-------------------------------------------------------------------------- # * Execute Transition #-------------------------------------------------------------------------- def command_222 # If transition processing flag is already set if $game_temp.transition_processing # End return false end # Set transition processing flag $game_temp.transition_processing = true $game_temp.transition_name = @parameters[0] # Advance index @index += 1 # End return false end #-------------------------------------------------------------------------- # * Change Screen Color Tone #-------------------------------------------------------------------------- def command_223 # Start changing color tone $game_screen.start_tone_change(@parameters[0], @parameters[1] * 2) # Continue return true end #-------------------------------------------------------------------------- # * Screen Flash #-------------------------------------------------------------------------- def command_224 # Start flash $game_screen.start_flash(@parameters[0], @parameters[1] * 2) # Continue return true end #-------------------------------------------------------------------------- # * Screen Shake #-------------------------------------------------------------------------- def command_225 # Start shake $game_screen.start_shake(@parameters[0], @parameters[1], @parameters[2] * 2) # Continue return true end #-------------------------------------------------------------------------- # * Show Picture #-------------------------------------------------------------------------- def command_231 # Get picture number number = @parameters[0] + ($game_temp.in_battle ? 50 : 0) # If appointment method is [direct appointment] if @parameters[3] == 0 x = @parameters[4] y = @parameters[5] # If appointment method is [appoint with variables] else x = $game_variables[@parameters[4]] y = $game_variables[@parameters[5]] end # Show picture $game_screen.pictures[number].show(@parameters[1], @parameters[2], x, y, @parameters[6], @parameters[7], @parameters[8], @parameters[9]) # Continue return true end #-------------------------------------------------------------------------- # * Move Picture #-------------------------------------------------------------------------- def command_232 # Get picture number number = @parameters[0] + ($game_temp.in_battle ? 50 : 0) # If appointment method is [direct appointment] if @parameters[3] == 0 x = @parameters[4] y = @parameters[5] # If appointment method is [appoint with variables] else x = $game_variables[@parameters[4]] y = $game_variables[@parameters[5]] end # Move picture $game_screen.pictures[number].move(@parameters[1] * 2, @parameters[2], x, y, @parameters[6], @parameters[7], @parameters[8], @parameters[9]) # Continue return true end #-------------------------------------------------------------------------- # * Rotate Picture #-------------------------------------------------------------------------- def command_233 # Get picture number number = @parameters[0] + ($game_temp.in_battle ? 50 : 0) # Set rotation speed $game_screen.pictures[number].rotate(@parameters[1]) # Continue return true end #-------------------------------------------------------------------------- # * Change Picture Color Tone #-------------------------------------------------------------------------- def command_234 # Get picture number number = @parameters[0] + ($game_temp.in_battle ? 50 : 0) # Start changing color tone $game_screen.pictures[number].start_tone_change(@parameters[1], @parameters[2] * 2) # Continue return true end #-------------------------------------------------------------------------- # * Erase Picture #-------------------------------------------------------------------------- def command_235 # Get picture number number = @parameters[0] + ($game_temp.in_battle ? 50 : 0) # Erase picture $game_screen.pictures[number].erase # Continue return true end #-------------------------------------------------------------------------- # * Set Weather Effects #-------------------------------------------------------------------------- def command_236 # Set Weather Effects $game_screen.weather(@parameters[0], @parameters[1], @parameters[2]) # Continue return true end #-------------------------------------------------------------------------- # * Play BGM #-------------------------------------------------------------------------- def command_241 # Play BGM $game_system.bgm_play(@parameters[0]) # Continue return true end #-------------------------------------------------------------------------- # * Fade Out BGM #-------------------------------------------------------------------------- def command_242 # Fade out BGM $game_system.bgm_fade(@parameters[0]) # Continue return true end #-------------------------------------------------------------------------- # * Play BGS #-------------------------------------------------------------------------- def command_245 # Play BGS $game_system.bgs_play(@parameters[0]) # Continue return true end #-------------------------------------------------------------------------- # * Fade Out BGS #-------------------------------------------------------------------------- def command_246 # Fade out BGS $game_system.bgs_fade(@parameters[0]) # Continue return true end #-------------------------------------------------------------------------- # * Memorize BGM/BGS #-------------------------------------------------------------------------- def command_247 # Memorize BGM/BGS $game_system.bgm_memorize $game_system.bgs_memorize # Continue return true end #-------------------------------------------------------------------------- # * Restore BGM/BGS #-------------------------------------------------------------------------- def command_248 # Restore BGM/BGS $game_system.bgm_restore $game_system.bgs_restore # Continue return true end #-------------------------------------------------------------------------- # * Play ME #-------------------------------------------------------------------------- def command_249 # Play ME $game_system.me_play(@parameters[0]) # Continue return true end #-------------------------------------------------------------------------- # * Play SE #-------------------------------------------------------------------------- def command_250 # Play SE $game_system.se_play(@parameters[0]) # Continue return true end #-------------------------------------------------------------------------- # * Stop SE #-------------------------------------------------------------------------- def command_251 # Stop SE Audio.se_stop # Continue return true end def command_if(value) if @branch[@list[@index].indent] == value @branch.delete(@list[@index].indent) return true end return command_skip end alias command_301 command_dummy # Battle Processing def command_601; command_if(0); end # If Win def command_602; command_if(1); end # If Escape def command_603; command_if(2); end # If Lose alias command_302 command_dummy # Shop Processing alias command_303 command_dummy # Name Processing alias command_311 command_dummy # Change HP alias command_312 command_dummy # Change SP alias command_313 command_dummy # Change State alias command_314 command_dummy # Recover All alias command_315 command_dummy # Change EXP alias command_316 command_dummy # Change Level alias command_317 command_dummy # Change Parameters alias command_318 command_dummy # Change Skills alias command_319 command_dummy # Change Equipment alias command_320 command_dummy # Change Actor Name alias command_321 command_dummy # Change Actor Class alias command_322 command_dummy # Change Actor Graphic alias command_331 command_dummy # Change Enemy HP alias command_332 command_dummy # Change Enemy SP alias command_333 command_dummy # Change Enemy State alias command_334 command_dummy # Enemy Recover All alias command_335 command_dummy # Enemy Appearance alias command_336 command_dummy # Enemy Transform alias command_337 command_dummy # Show Battle Animation alias command_338 command_dummy # Deal Damage alias command_339 command_dummy # Force Action alias command_340 command_dummy # Abort Battle #-------------------------------------------------------------------------- # * Call Menu Screen #-------------------------------------------------------------------------- def command_351 # Set menu calling flag $game_temp.menu_calling = true # Advance index @index += 1 # End return false end #-------------------------------------------------------------------------- # * Call Save Screen #-------------------------------------------------------------------------- def command_352 # Set save calling flag $game_temp.save_calling = true # Advance index @index += 1 # End return false end #-------------------------------------------------------------------------- # * Game Over #-------------------------------------------------------------------------- def command_353 # Set game over flag $game_temp.gameover = true # End return false end #-------------------------------------------------------------------------- # * Return to Title Screen #-------------------------------------------------------------------------- def command_354 # Set return to title screen flag $game_temp.to_title = true # End return false end #-------------------------------------------------------------------------- # * Script #-------------------------------------------------------------------------- def command_355 script = @list[@index].parameters[0] + "\\n" loop do if @list[@index+1].code == 655 || @list[@index+1].code == 355 script += @list[@index+1].parameters[0] + "\\n" else break end @index += 1 end result = pbExecuteScript(script) return true end end
Scene_Intro
[
Selecionar
] [
-
]
#============================================================================== # Splash Screen #============================================================================== # Sephiroth Spawn # 01.08.06 # Version 2 # Modified by Harshboy/Flameguru #-------------------------------------------------------------------------- # Call Using $scene = Scene_Intro.new([pics], splash_screen) #============================================================================== #============================================================================== # ** Scene_Intro #============================================================================== class Scene_Intro #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize(pics, splash = nil) @pics, @splash = pics, splash end def setTitle(sprite,title) @cache={} if !@cache if @currentTitle!=title sprite.setBitmap("Graphics/Titles/#{title}") @currentTitle=title end end #-------------------------------------------------------------------------- # * Main Processing #-------------------------------------------------------------------------- def main # Loads Data System and Game System data_system = load_data("Data/System.rxdata") game_system = Game_System.new # Loads the Title.mid in Audio/BGM game_system.bgm_play(data_system.title_bgm) # Instance Variables @item, @speed, @o_speed, @phase = 0, 15, 20, 0 # Background Images @sprite = GifSprite.new setTitle(@sprite, @pics[@item]) @sprite.opacity = 5 # Start Logo @start = GifSprite.new setTitle(@start,"Start") @start.y, @start.z, @start.opacity = 250, 10, 0 # Execute transition Graphics.transition # Main loop while $scene == self # Update game screen Graphics.update # Update input information Input.update # Frame update @sprite.update case @phase when 0; intro_update # Into Updating when 1; splash_update # Splash Updating when 2; to_splash_update # From Intro To Splash Transition when 3; to_title_update # From Splash to Title Transtion when 4; toDeleteUpdate end end # Prepare for transition Graphics.freeze # Dispose of Sprites if @cache for i in @cache.values i.dispose end end @sprite.dispose @start.dispose end #-------------------------------------------------------------------------- # * Frame Update : Intro Images #-------------------------------------------------------------------------- def intro_update # If C is pressed if Input.trigger?(Input::C) && @speed>=0 @phase = @splash.nil? ? 3 : 2 end # Updates Sprite Opacity @sprite.opacity += @speed # Changes Direction @speed *= -1 if @sprite.opacity >= 255 # Change Sprite if @sprite.opacity <= 0 @item += 1 @speed *= -1 @item == @pics.size ? @phase = @splash.nil? ? 3 : 2 : setTitle(@sprite,@pics[@item]) end end #-------------------------------------------------------------------------- # * Frame Update : Splash Image #-------------------------------------------------------------------------- def splash_update # If C is pressed if Input.trigger?(Input::C) @phase = 3 end if Input.press?(Input::DOWN) && Input.press?(Input::CTRL) && Input.press?(Input::B) @phase=4 end # Loads Sprite Splash Bitmap setTitle(@sprite,@splash) # Updates Start Logo Opacity @start.opacity += @o_speed # Changes Direction @o_speed *= -1 if @start.opacity >= 255 || @start.opacity <= 0 # Updates Splash @sprite.opacity += @speed if @sprite.opacity < 255 end #-------------------------------------------------------------------------- # * Frame Update : Intro To Splash Transistion #-------------------------------------------------------------------------- def to_splash_update @sprite.opacity > 0 ? @sprite.opacity -= @speed : @phase = 1 end #-------------------------------------------------------------------------- # * Frame Update : Splash To Title Transistion #-------------------------------------------------------------------------- def to_title_update # Decrease Splash Opacity @sprite.opacity -= @speed if @sprite.opacity > 0 # Decresh Start Logo Opacity @start.opacity -= @speed if @start.opacity > 0 # Proceed to Title Screen if @sprite.opacity <= 0 && @start.opacity <= 0 Audio.bgm_stop sscene=PokemonLoadScene.new sscreen=PokemonLoad.new(sscene) sscreen.pbStartLoadScreen end end def toDeleteUpdate # Decrease Splash Opacity @sprite.opacity -= @speed if @sprite.opacity > 0 # Decresh Start Logo Opacity @start.opacity -= @speed if @start.opacity > 0 # Proceed to Title Screen if @sprite.opacity <= 0 && @start.opacity <= 0 Audio.bgm_stop sscene=PokemonLoadScene.new sscreen=PokemonLoad.new(sscene) sscreen.pbStartDeleteScreen end end end
Scene_Map
[
Selecionar
] [
-
]
=begin Modified Scene_Map class for Pokémon. =end class Scene_Map def spriteset for i in @spritesets.values return i if i.map==$game_map end return @spritesets.values[0] end def disposeSpritesets for i in @spritesets.keys if @spritesets[i] @spritesets[i].dispose @spritesets[i]=nil end end @spritesets.clear @spritesets={} end def createSpritesets @spritesets={} for map in $MapFactory.maps @spritesets[map.map_id]=Spriteset_Map.new(map) end $MapFactory.setSceneChanged(self,$PokemonTemp.mapChanged) $PokemonTemp.mapChanged=false updateSpritesets end def updateMaps for map in $MapFactory.maps map.update end $MapFactory.updateMaps if $PokemonTemp.mapChanged $PokemonTemp.mapChanged=false $MapFactory.setSceneChanged(self,true) end end def updateSpritesets @spritesets={} if !@spritesets keys=@spritesets.keys.clone for i in keys if !$MapFactory.hasMap?(i) @spritesets[i].dispose if @spritesets[i] @spritesets[i]=nil @spritesets.delete(i) else @spritesets[i].update end end for map in $MapFactory.maps if !@spritesets[map.map_id] @spritesets[map.map_id]=Spriteset_Map.new(map) end end Events.onMapUpdate.trigger(self) end def main createSpritesets Graphics.transition loop do Graphics.update Input.update update if $scene != self break end end Graphics.freeze disposeSpritesets if $game_temp.to_title Graphics.transition Graphics.freeze end end def miniupdate $PokemonTemp.miniupdate=true if $PokemonTemp loop do updateMaps $game_player.update $game_system.update $game_screen.update unless $game_temp.player_transferring break end transfer_player if $game_temp.transition_processing break end end updateSpritesets $PokemonTemp.miniupdate=false if $PokemonTemp end def update loop do updateMaps $game_system.map_interpreter.update $game_player.update $game_system.update $game_screen.update unless $game_temp.player_transferring break end transfer_player if $game_temp.transition_processing break end end updateSpritesets if $game_temp.to_title $scene = pbCallTitle return end if $game_temp.transition_processing $game_temp.transition_processing = false if $game_temp.transition_name == "" Graphics.transition(20) else Graphics.transition(40, "Graphics/Transitions/" + $game_temp.transition_name) end end if $game_temp.message_window_showing return end if Input.trigger?(Input::C) unless $game_system.map_interpreter.running? $PokemonTemp.hiddenMoveEventCalling=true end end if Input.trigger?(Input::B) unless $game_system.map_interpreter.running? or $game_system.menu_disabled $game_temp.menu_calling = true $game_temp.menu_beep = true end end if Input.trigger?(Input::F5) unless $game_system.map_interpreter.running? $PokemonTemp.keyItemCalling = true if $PokemonTemp end end if $DEBUG and Input.press?(Input::F9) $game_temp.debug_calling = true end unless $game_player.moving? if $game_temp.battle_calling call_battle elsif $game_temp.shop_calling call_shop elsif $game_temp.name_calling call_name elsif $game_temp.menu_calling call_menu elsif $game_temp.save_calling call_save elsif $game_temp.debug_calling call_debug elsif $PokemonTemp && $PokemonTemp.keyItemCalling $PokemonTemp.keyItemCalling=false $game_player.straighten Kernel.pbUseKeyItem elsif $PokemonTemp && $PokemonTemp.hiddenMoveEventCalling Kernel.pbHiddenMoveEvent end end end def call_name $game_temp.name_calling = false $game_player.straighten $game_map.update $scene = Scene_Name.new end def call_menu $game_temp.menu_calling = false $game_player.straighten $game_map.update sscene=PokemonMenu_Scene.new sscreen=PokemonMenu.new(sscene) sscreen.pbStartPokemonMenu end def call_debug $game_temp.debug_calling = false $game_system.se_play($data_system.decision_se) $game_player.straighten $scene = Scene_Debug.new end def autofade(mapid) playingBGM=$game_system.playing_bgm playingBGS=$game_system.playing_bgs return if !playingBGM && !playingBGS map=load_data(sprintf("Data/Map%03d.rxdata", mapid)) if playingBGM && map.autoplay_bgm if playingBGM.name!=map.bgm.name $game_system.bgm_fade(0.8) end end if playingBGS && map.autoplay_bgs if playingBGS.name!=map.bgs.name $game_system.bgs_fade(0.8) end end Graphics.frame_reset end def transfer_player(cancelVehicles=true) $game_temp.player_transferring = false Events.onMapTransferring.trigger( self,$game_temp.player_new_map_id,cancelVehicles) autofade($game_temp.player_new_map_id) if $game_map.map_id != $game_temp.player_new_map_id $MapFactory.setup($game_temp.player_new_map_id) end $game_player.moveto($game_temp.player_new_x, $game_temp.player_new_y) case $game_temp.player_new_direction when 2 $game_player.turn_down when 4 $game_player.turn_left when 6 $game_player.turn_right when 8 $game_player.turn_up end $game_player.straighten $game_map.update disposeSpritesets GC.start createSpritesets if $game_temp.transition_processing $game_temp.transition_processing = false Graphics.transition(20) end $game_map.autoplay Graphics.frame_reset Input.update end end
Win32API_
[
Selecionar
] [
-
]
class Win32API @@RGSSWINDOW=nil @@GetCurrentThreadId=Win32API.new('kernel32','GetCurrentThreadId', '%w()','l') @@GetWindowThreadProcessId=Win32API.new('user32','GetWindowThreadProcessId', '%w(l p)','l') @@FindWindowEx=Win32API.new('user32','FindWindowEx', '%w(l l p p)','l') def Win32API.SetWindowText(text) hWnd = pbFindRgssWindow swp = Win32API.new('user32', 'SetWindowTextA', %(l, p), 'i') swp.call(hWnd, text) end # Added by Peter O. as a more reliable way to get the RGSS window def Win32API.pbFindRgssWindow return @@RGSSWINDOW if @@RGSSWINDOW processid=[0].pack('l') threadid=@@GetCurrentThreadId.call nextwindow=0 begin nextwindow=@@FindWindowEx.call(0,nextwindow,"RGSS Player",0) if nextwindow wndthreadid=@@GetWindowThreadProcessId.call(nextwindow,processid) if wndthreadid==threadid @@RGSSWINDOW=nextwindow return @@RGSSWINDOW end end end until nextwindow==0 raise "Can't find RGSS player window" return 0 end def Win32API.GetPrivateProfileString(section, key) val = "\\0"*256 gps = Win32API.new('kernel32', 'GetPrivateProfileString',%w(p p p p l p), 'l') gps.call(section, key, "", val, 256, ".\\\\Game.ini") val.delete!("\\0") return val end def Win32API.SetWindowPos(w, h) hWnd = pbFindRgssWindow windowrect=Win32API.GetWindowRect clientsize=Win32API.client_size xExtra=windowrect.width-clientsize[0] yExtra=windowrect.height-clientsize[1] swp = Win32API.new('user32', 'SetWindowPos', %(l, l, i, i, i, i, i), 'i') win = swp.call(hWnd, 0, windowrect.x, windowrect.y, w+xExtra,h+yExtra, 0) return win end def Win32API.client_size hWnd = pbFindRgssWindow rect = [0, 0, 0, 0].pack('l4') Win32API.new('user32', 'GetClientRect', %w(l p), 'i').call(hWnd, rect) width, height = rect.unpack('l4')[2..3] return width, height end def Win32API.GetWindowRect hWnd = pbFindRgssWindow rect = [0, 0, 0, 0].pack('l4') Win32API.new('user32', 'GetWindowRect', %w(l p), 'i').call(hWnd, rect) x,y,width, height = rect.unpack('l4') return Rect.new(x,y,width-x,height-y) end end
Resolution_
[
Selecionar
] [
-
]
class Game_Map TILEWIDTH = 32 TILEHEIGHT = 32 def self.realResX return 4 * TILEWIDTH end def self.realResY return 4 * TILEHEIGHT end def display_x=(value) @display_x=value $MapFactory.setMapsInRange if $MapFactory end def display_y=(value) @display_y=value $MapFactory.setMapsInRange if $MapFactory end def start_scroll(direction, distance, speed) @scroll_direction = direction if direction==2 || direction==8 @scroll_rest = distance * Game_Map.realResY else @scroll_rest = distance * Game_Map.realResX end @scroll_speed = speed 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 scroll_up(distance) self.display_y-=distance end end class Game_Player < Game_Character def center(x, y) center_x = (Graphics.width/2 - Game_Map::TILEWIDTH/2) * 4 # X coordinate in the center of the screen center_y = (Graphics.height/2 - Game_Map::TILEHEIGHT/2) * 4 # Y coordinate in the center of the screen max_x = ($game_map.width - Graphics.width*1.0/Game_Map::TILEWIDTH) * Game_Map.realResX max_y = ($game_map.height - Graphics.height*1.0/Game_Map::TILEHEIGHT) * Game_Map.realResY dispx=x * Game_Map.realResX - center_x dispy=y * Game_Map.realResY - center_y $game_map.display_x = dispx#[0, [dispx, max_x].min].max $game_map.display_y = dispy#[0, [dispy, max_y].min].max end end
Scene_Movie
[
Selecionar
] [
-
]
########################################################### class Scene_Movie ########################################################### #Created by SoundSpawn ########################################################### #Fixed by Popper ########################################################### #Instruction # 1) Movies must in in a new folder called Movies in your directory # 2)If you call this script from and event (EG: Call Script: $scene = Scene_Movie.new("INTRO") ) # 3) Have fun playin movies with this script!!! ########################################################### def initialize(movie) @movie_name = Dir.getwd()+"\\\\Movies\\\\"+movie+".avi" main end def main @temp = Win32API.pbFindRgssWindow.to_s movie = Win32API.new('winmm','mciSendString','%w(p,p,l,l)','V') movie.call("open \\""+@movie_name+"\\" alias FILE style 1073741824 parent " + @temp.to_s,0,0,0) @message = Win32API.new('user32','SendMessage','%w(l,l,l,l)','V') @detector = Win32API.new('user32','GetSystemMetrics','%w(l)','L') @width = @detector.call(0) if @width == 640 #fullscreen Graphics.update sleep(0.1) Graphics.update sleep(0.1) Graphics.update sleep(0.1) #fullscreen end status = " " * 255 movie.call("play FILE",0,0,0) loop do sleep(0.1) @message.call(@temp.to_i,11,0,0) Graphics.update @message.call(@temp.to_i,11,1,0) Input.update movie.call("status FILE mode",status,255,0) true_status = status.unpack("aaaa") if true_status.to_s != "play" break end if Input.trigger?(Input::B) $scene = Scene_Map.new break end end $scene = Scene_Map.new end end
SCene_Credits
[
Selecionar
] [
-
]
CREDITS_FONT = ["Calligraph421 BT", "Viner Hand ITC", "Arial", "Times New Roman"] CREDITS_SIZE = 24 CREDITS_OUTLINE = Color.new(0,0,127, 255) CREDITS_SHADOW = Color.new(0,0,0, 100) CREDITS_FILL = Color.new(255,255,255, 255) #============================================================================== # ¦ Scene_Credits #------------------------------------------------------------------------------ # Scrolls the credits you make below. Original Author unknown. Edited by # MiDas Mike so it doesn't play over the Title, but runs by calling the following: # $scene = Scene_Credits.new # New Edit 3/6/2007 11:14 PM by AvatarMonkeyKirby. # Ok, what I've done is changed the part of the script that was supposed to make # the credits automatically end so that way they actually end! Yes, they will # actually end when the credits are finished! So, that will make the people you # should give credit to now is: UNKOWN, MiDas Mike, and AvatarMonkeyKirby. # -sincerly yours, # Your Beloved # Oh yea, and I also added a line of code that fades out the BGM so it fades # sooner and smoother. #============================================================================== class Scene_Credits # This next piece of code is the credits. #Start Editing CREDIT=<<_END_ _END_ #Stop Editing def main #------------------------------- # Animated Background Setup #------------------------------- @sprite = Sprite.new #@sprite.bitmap = RPG::Cache.title($data_system.title_name) @backgroundList = ["Black"] #Edit this to the title screen(s) you wish to show in the background. They do repeat. @backgroundGameFrameCount = 0 # Number of game frames per background frame. @backgroundG_BFrameCount = 3.4 @sprite.bitmap = RPG::Cache.title(@backgroundList[0]) #------------------ # Credits txt Setup #------------------ credit_lines = CREDIT.split(/\\n/) credit_bitmap = Bitmap.new(640,32 * credit_lines.size) credit_lines.each_index do |i| line = credit_lines[i] credit_bitmap.font.name = CREDITS_FONT credit_bitmap.font.size = CREDITS_SIZE x = 0 credit_bitmap.font.color = CREDITS_OUTLINE credit_bitmap.draw_text(0 + 1,i * 32 + 1,640,32,line,1) credit_bitmap.draw_text(0 - 1,i * 32 + 1,640,32,line,1) credit_bitmap.draw_text(0 + 1,i * 32 - 1,640,32,line,1) credit_bitmap.draw_text(0 - 1,i * 32 - 1,640,32,line,1) credit_bitmap.font.color = CREDITS_SHADOW credit_bitmap.draw_text(0,i * 32 + 8,640,32,line,1) credit_bitmap.font.color = CREDITS_FILL credit_bitmap.draw_text(0,i * 32,640,32,line,1) end @credit_sprite = Sprite.new(Viewport.new(0,50,640,380)) @credit_sprite.bitmap = credit_bitmap @credit_sprite.z = 9998 @credit_sprite.oy = -430 #-430 @frame_index = 0 @last_flag = false #-------- # Setup #-------- #Stops all audio but background music. Audio.me_stop Audio.bgs_stop Audio.se_stop Graphics.transition loop do Graphics.update Input.update update if $scene != self break end end Graphics.freeze @sprite.dispose @credit_sprite.dispose end ##Checks if credits bitmap has reached it's ending point def last? if @frame_index > (@credit_sprite.bitmap.height + 500) $scene = Scene_Map.new Audio.bgm_fade(10000) #aprox 10 seconds return true end return false end #Check if the credits should be cancelled def cancel? if Input.trigger?(Input::C) $scene = Scene_Map.new return true end return false end def update @backgroundGameFrameCount = @backgroundGameFrameCount + 1 if @backgroundGameFrameCount >= @backgroundG_BFrameCount @backgroundGameFrameCount = 0 # Add current background frame to the end @backgroundList = @backgroundList << @backgroundList[0] # and drop it from the first position @backgroundList.delete_at(0) @sprite.bitmap = RPG::Cache.title(@backgroundList[0]) end return if cancel? return if last? @credit_sprite.oy += 1 #this is the speed that the text scrolls. 1 is default #The fastest I'd recomend is 5, after that it gets hard to read. @frame_index += 1 #This should fix the non-self-ending credits end end
PokeGear
[
Selecionar
] [
-
]
#============================================================================== # - Scene_Pokegear #------------------------------------------------------------------------------ # Modified By Harshboy # Modified by Peter O. # Also Modified By OblivionMew #============================================================================== class Scene_Pokegear #-------------------------------------------------------------------------- # initialize #-------------------------------------------------------------------------- def initialize(menu_index = 0) @menu_index = menu_index end #-------------------------------------------------------------------------- # main #-------------------------------------------------------------------------- def main # Main Menu settings you can add or change these commands=[ _INTL("Map"), _INTL("Radio"), _INTL("Phone"), _INTL("Exit") ] @command_window = Window_CommandPokemon.new(commands,160) @command_window.index = @menu_index @command_window.x = (Graphics.width - @command_window.width) - 8 @command_window.y = 640 @card = GifSprite.new @card.setBitmap("Graphics/Pictures/Pokegearback") @card.x = 0 @card.y = 0 @map_icon = Sprite.new @map_icon.bitmap = RPG::Cache.picture("mapicon") @map_icon.x = 0 @map_icon.y = 57 @button_up = Sprite.new @button_up.bitmap = RPG::Cache.picture("buttonunp") @button_up.x = 320 @button_up.y = 80 @button_down = Sprite.new @button_down.bitmap = RPG::Cache.picture("buttonunp") @button_down.x = 320 @button_down.y = 165 @arr_icon=AnimatedSprite.create("Graphics/Pictures/selarr.png",8,1) @arr_icon.x = 60 @arr_icon.y = 57 @arr_icon.start @radio_icon = Sprite.new @radio_icon.bitmap = RPG::Cache.picture("radicon") @radio_icon.x = 0 @radio_icon.y = 109 @arr_icon.z=99999 @phone_icon = Sprite.new @phone_icon.bitmap = RPG::Cache.picture("phonicon") @phone_icon.x = 0 @phone_icon.y = 161 @exit_icon = Sprite.new @exit_icon.bitmap = RPG::Cache.picture("exicon") @exit_icon.x = 0 @exit_icon.y = 265 @trainer = Sprite.new @trainer.x = 360 @trainer.y = 80 @trainer.zoom_x = 1.0 @trainer.zoom_y = 1.0 @trainer.z = 99999 @trainer.bitmap = RPG::Cache.character( sprintf("trainer%03d.png",$Trainer.trainertype),0 ) @info = Window_UnformattedTextPokemon.new("") @info.height = Graphics.height / 4 + 16 @info.width = Graphics.width / 2 + 74 @info.x = 160 @info.y = Graphics.height - @info.height @info.z = 99999 @info.letterbyletter=false @target_window = Window_UnformattedTextPokemon.new("") @target_window.visible = false @target_window.active = false @target_window.letterbyletter=false Graphics.transition loop do Graphics.update Input.update update if $scene != self break end end @target_window.dispose Graphics.freeze @command_window.dispose @trainer.dispose @card.bitmap.dispose @info.dispose @arr_icon.dispose @map_icon.dispose @phone_icon.dispose @radio_icon.dispose @exit_icon.dispose @button_up.dispose @button_down.dispose end #-------------------------------------------------------------------------- # update the scene #-------------------------------------------------------------------------- def update @arr_icon.update @command_window.update @info.update if Input.press?(Input::UP) @button_up.bitmap = RPG::Cache.picture("buttonp") else @button_up.bitmap = RPG::Cache.picture("buttonunp") end if Input.press?(Input::DOWN) @button_down.bitmap = RPG::Cache.picture("buttonp") else @button_down.bitmap = RPG::Cache.picture("buttonunp") end case @command_window.index when 0 @map_icon.x = 32 @phone_icon.x = 0 @radio_icon.x = 0 @exit_icon.x = 0 @arr_icon.y=57 when 1 @map_icon.x = 0 @phone_icon.x = 0 @radio_icon.x = 32 @exit_icon.x = 0 @arr_icon.y=109 when 2 @map_icon.x = 0 @phone_icon.x = 32 @radio_icon.x = 0 @exit_icon.x = 0 @arr_icon.y=161 when 3 @map_icon.x = 0 @phone_icon.x = 0 @radio_icon.x = 0 @exit_icon.x = 32 @arr_icon.y=265 end #update command window and the info if it's active if @command_window.active update_command update_info return end end #-------------------------------------------------------------------------- # update the command window #-------------------------------------------------------------------------- def update_command if Input.trigger?(Input::B) $game_system.se_play($data_system.cancel_se) $scene = Scene_Map.new return end if Input.trigger?(Input::C) case @command_window.index when 0 $game_system.se_play($data_system.decision_se) pbFadeOutIn(99999) { scene=PokemonRegionMapScene.new screen=PokemonRegionMap.new(scene) screen.pbStartScreen } when 1 $game_system.se_play($data_system.decision_se) $scene = Scene_Jukebox.new when 2 $game_system.se_play($data_system.decision_se) pbFadeOutIn(99999) { PokemonPhoneScene.new.start } when 3 $game_system.se_play($data_system.decision_se) $scene = Scene_Map.new end return end end def update_info case @command_window.index when 0 @info.text=_INTL("A Map\\r\\nShows visited Places.") when 1 @info.text=_INTL("A Radio\\r\\nUsed to listen to Music.") when 2 @info.text=_INTL("A Phone\\r\\nUsed to call People.") when 3 @info.text=_INTL("Closes the PokeGear and returns to the game.") end end end
PokeGear_Radio
[
Selecionar
] [
-
]
#------------------------------------------------------------------------------ # ** Scene_iPod # ** Created by xLeD (Scene_Jukebox) # ** Modified by Harshboy #------------------------------------------------------------------------------ # This class performs menu screen processing. #============================================================================== class Scene_Jukebox #-------------------------------------------------------------------------- # * Object Initialization # menu_index : command cursor's initial position #-------------------------------------------------------------------------- def initialize(menu_index = 0) @menu_index = menu_index end #-------------------------------------------------------------------------- # * Main Processing #-------------------------------------------------------------------------- def main # Make song command window @spriteset = Spriteset_Map.new fadein = true # Makes the text window @Background = Sprite.new @Background.bitmap = RPG::Cache.picture("iPod") @Background.z += 255 @Background.opacity = 255 @choices=[ _INTL("March"), _INTL("Lullaby"), _INTL("Oak"), _INTL("Custom"), _INTL("Exit") ] @command_window = Window_CommandPokemon.new(@choices,160) @command_window.index = @menu_index @command_window.height=160 @command_window.width=176 @command_window.x = 150 @command_window.y = 130 @command_window.z=256 @command_window.opacity = 0 @custom=false # Execute transition Graphics.transition # Main loop loop do # Update game screen Graphics.update # Update input information Input.update # Frame update update # Abort loop if screen is changed if $scene != self break end end # Prepares for transition Graphics.freeze # Disposes the windows @command_window.dispose @spriteset.dispose @Background.dispose end #-------------------------------------------------------------------------- # * Frame Update #-------------------------------------------------------------------------- def update # Update windows @command_window.update if @custom updateCustom else update_command end return end #-------------------------------------------------------------------------- # * Frame Update (when command window is active) #-------------------------------------------------------------------------- def updateCustom if Input.trigger?(Input::B) @command_window.commands=@choices @command_window.index=3 @custom=false return end if Input.trigger?(Input::C) $PokemonMap.whiteFluteUsed=false if $PokemonMap $PokemonMap.blackFluteUsed=false if $PokemonMap if @command_window.index==0 $game_system.setDefaultBGM(nil) else $game_system.setDefaultBGM( @command_window.commands[@command_window.index] ) end end end def update_command # If B button was pressed if Input.trigger?(Input::B) # Play cancel SE $game_system.se_play($data_system.cancel_se) # Switch to map screen $scene = Scene_Pokegear.new return end # If C button was pressed if Input.trigger?(Input::C) # Branch by command window cursor position case @command_window.index when 0 $game_system.se_play($data_system.decision_se) $game_system.bgm_play(RPG::AudioFile.new("Radio - March", 100, 100)) $PokemonMap.whiteFluteUsed=true if $PokemonMap $PokemonMap.blackFluteUsed=false if $PokemonMap when 1 $game_system.se_play($data_system.decision_se) $game_system.bgm_play(RPG::AudioFile.new("Radio - Lullaby", 100, 100)) $PokemonMap.blackFluteUsed=true if $PokemonMap $PokemonMap.whiteFluteUsed=false if $PokemonMap when 2 $game_system.se_play($data_system.decision_se) $game_system.bgm_play(RPG::AudioFile.new("Radio - Oak", 100, 100)) $PokemonMap.whiteFluteUsed=false if $PokemonMap $PokemonMap.blackFluteUsed=false if $PokemonMap when 3 files=[_INTL("(Default)")] Dir.chdir("Audio/BGM/"){ Dir.glob("*.mp3"){|f| files.push(f) } Dir.glob("*.MP3"){|f| files.push(f) } Dir.glob("*.mid"){|f| files.push(f) } Dir.glob("*.MID"){|f| files.push(f) } } @command_window.commands=files @command_window.index=0 @custom=true when 4 $game_system.se_play($data_system.decision_se) $scene = Scene_Pokegear.new end return end end end
Walk_Run
[
Selecionar
] [
-
]
class Game_Player def fullPattern case self.direction when 2 return self.pattern when 4 return 4+self.pattern when 6 return 8+self.pattern when 8 return 12+self.pattern else return 0 end end def setDefaultCharName(chname,pattern) return if pattern<0||pattern>=16 @defaultCharacterName=chname @direction=[2,4,6,8][pattern/4] @pattern=pattern%4 end def pbCanRun? return Input.press?(Input::A) && $PokemonGlobal.runningShoes && ( pbGetMetadata($game_map.map_id,MetadataOutdoor) || ($PokemonEncounters && $PokemonEncounters.isCave?) ) end def character_name if !@defaultCharacterName @defaultCharacterName="" end if @defaultCharacterName!="" return @defaultCharacterName end if !$game_system.map_interpreter.running? && !moving? && !@move_route_forcing && $PokemonGlobal meta=pbGetMetadata(0,MetadataPlayerA+$PokemonGlobal.playerID) if $PokemonGlobal.playerID>=0 && meta && !$PokemonGlobal.bicycle && !$PokemonGlobal.diving && !$PokemonGlobal.surfing if meta[5] && meta[5]!="" && Input.dir4!=0 && pbCanRun? # Display running character sprite @character_name=meta[5] else # Display normal character sprite @character_name=meta[1] end end end return @character_name end alias update_old update def update if !$game_system.map_interpreter.running? && !moving? && !@move_route_forcing && $PokemonGlobal if $PokemonGlobal.bicycle @move_speed = 5.2 elsif pbCanRun? @move_speed = 4.8 else @move_speed = 3.8 end end update_old end end 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 && @move_speed=$game_player.move_speed break end end end end update_old2 end end
Map_Scroll
[
Selecionar
] [
-
]
#============================================================================== # ** 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::TILEWIDTH/2) * 4 # X coordinate in the center of the screen center_y = (Graphics.height/2 - Game_Map::TILEHEIGHT/2) * 4 # Y coordinate in the center of the screen max_x = ($game_map.width - Graphics.width*1.0/Game_Map::TILEWIDTH) * 4 * Game_Map::TILEWIDTH max_y = ($game_map.height - Graphics.height*1.0/Game_Map::TILEHEIGHT) * 4 * Game_Map::TILEHEIGHT count_x = ($game_map.display_x - [0,[x*Game_Map.realResX-center_x,max_x].min].max)/Game_Map.realResX count_y = ($game_map.display_y - [0,[y*Game_Map.realResY-center_y,max_y].min].max)/Game_Map.realResY 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/Game_Map::TILEWIDTH) * Game_Map.realResX].min @display_y = [@display_y + distance, (self.height - Graphics.height*1.0/Game_Map::TILEHEIGHT) * Game_Map.realResY].min end def scroll_downleft(distance) @display_x = [@display_x - distance, 0].max @display_y = [@display_y + distance, (self.height - Graphics.height*1.0/Game_Map::TILEHEIGHT) * Game_Map.realResY].min end def scroll_upright(distance) @display_x = [@display_x + distance, (self.width - Graphics.width*1.0/Game_Map::TILEWIDTH) * Game_Map.realResX].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 = 2 ** @scroll_speed # Execute scrolling case @scroll_direction #------------------------------------------------------------------------------ # Begin Map Autoscroll Edit #------------------------------------------------------------------------------ when 1 # down left scroll_downleft(distance) #------------------------------------------------------------------------------ # End Map Autoscroll Edit #------------------------------------------------------------------------------ when 2 # Down scroll_down(distance) #------------------------------------------------------------------------------ # Begin Map Autoscroll Edit #------------------------------------------------------------------------------ when 3 # down right scroll_downright(distance) #------------------------------------------------------------------------------ # End Map Autoscroll Edit #------------------------------------------------------------------------------ when 4 # Left scroll_left(distance) when 6 # Right scroll_right(distance) #------------------------------------------------------------------------------ # Begin Map Autoscroll Edit #------------------------------------------------------------------------------ when 7 # up left scroll_upleft(distance) #------------------------------------------------------------------------------ # End Map Autoscroll Edit #------------------------------------------------------------------------------ when 8 # Up scroll_up(distance) #------------------------------------------------------------------------------ # Begin Map Autoscroll Edit #------------------------------------------------------------------------------ when 9 # up right scroll_upright(distance) #------------------------------------------------------------------------------ # End Map Autoscroll Edit #------------------------------------------------------------------------------ end # Subtract distance scrolled @scroll_rest -= distance end end end
Game_System
[
Selecionar
] [
-
]
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 end def audioBgmPlay(str,vol,pitch,position) Audio.bgm_play(str,vol,pitch,position) end def audioBgmFade(time) Audio.bgm_fade(time) end def audioBgmStop Audio.bgm_stop end def bgm_play_ex(bgm,volume,pitch,setplaying,position=0) if bgm.is_a?(String) bgm=RPG::AudioFile.new(bgm,volume,pitch) end if setplaying @playing_bgm = bgm==nil ? nil : bgm.clone end if bgm != nil and bgm.name != "" unless FileTest.audio_exist?("Audio/BGM/"+ bgm.name) if $DEBUG print "BGM File not found, game will continue playing.\\nFile : " + bgm.name end else audioBgmPlay("Audio/BGM/" + bgm.name, bgm.volume, bgm.pitch,position) if !@defaultBGM end else audioBgmStop if !@defaultBGM end if @defaultBGM audioBgmPlay("Audio/BGM/"+@defaultBGM.name, @defaultBGM.volume,@defaultBGM.pitch,position) end Graphics.frame_reset end def bgm_play(bgm,volume=100,pitch=100,position=0) bgm_play_ex(bgm,volume,pitch,true,position) end def bgm_pause; end def bgs_pause; end def bgm_resume(bgm,volume=100,pitch=100); end def bgs_resume(bgm,volume=100,pitch=100); end def bgm_stop @bgm_position=0 @playing_bgm = nil audioBgmStop if !@defaultBGM end def bgm_fade(time) @playing_bgm = nil audioBgmFade((time * 1000).floor) if !@defaultBGM end def getPlayingBGM return @playing_bgm ? @playing_bgm.clone : nil end def bgm_memorize @memorized_bgm = @playing_bgm end def bgm_restore bgm_play(@memorized_bgm) end def bgs_play(bgs,volume=100,pitch=100) if bgs.is_a?(String) bgs=RPG::AudioFile.new(bgs,volume,pitch) end @playing_bgs = bgs==nil ? nil : bgs.clone if bgs != nil and bgs.name != "" unless FileTest.audio_exist?("Audio/BGS/"+ bgs.name) if $DEBUG print "BGS File not found, game will continue playing. \\nFile : " + bgs.name end else Audio.bgs_play("Audio/BGS/" + bgs.name, bgs.volume, bgs.pitch) end else Audio.bgs_stop end Graphics.frame_reset end def bgs_fade(time) @playing_bgs = nil Audio.bgs_fade(time * 1000) end def bgs_stop @bgs_position=0 @playing_bgs = nil Audio.bgs_stop end def getPlayingBGS return @playing_bgs ? @playing_bgs.clone : nil end def bgs_memorize @memorized_bgs = @playing_bgs end def bgs_restore bgs_play(@memorized_bgs) end def setDefaultBGM(bgm,volume=100,pitch=100) if bgm.is_a?(String) bgm=RPG::AudioFile.new(bgm,volume,pitch) end if bgm != nil and bgm.name != "" @defaultBGM=bgm==nil ? nil : bgm.clone Audio.bgm_play("Audio/BGM/"+bgm.name) else @defaultBGM=nil self.bgm_play(@playing_bgm) end end def me_play(me) if me.is_a?(String) me=RPG::AudioFile.new(me) end if me != nil and me.name != "" unless FileTest.audio_exist?("Audio/ME/"+me.name) if $DEBUG print "ME File not found, game will continue playing. \\nFile : " + me.name end else Audio.me_play("Audio/ME/" + me.name, me.volume, me.pitch) end else Audio.me_stop end Graphics.frame_reset end def se_play(se) if se.is_a?(String) se=RPG::AudioFile.new(se) end if se != nil and se.name != "" unless FileTest.audio_exist?("Audio/SE/"+ se.name) if $DEBUG print "SE File not found, game will continue playing. \\nFile : " + se.name end else Audio.se_play("Audio/SE/" + se.name, se.volume, se.pitch) end end end def se_stop Audio.se_stop end def playing_bgm return @playing_bgm end def playing_bgs return @playing_bgs 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 battle_bgm if @battle_bgm == nil return $data_system.battle_bgm else return @battle_bgm end end def battle_bgm=(battle_bgm) @battle_bgm = battle_bgm end def battle_end_me if @battle_end_me == nil return $data_system.battle_end_me else return @battle_end_me end end def battle_end_me=(battle_end_me) @battle_end_me = battle_end_me end def update if @timer_working and @timer > 0 @timer -= 1 end $game_temp.updateDayNightTone if pbCurrentEventCommentInput(1,"Cut Scene") && Input.trigger?(Input::F5) event=@map_interpreter.get_character(0) @map_interpreter.pbSetSelfSwitch(event.id,"A",true) @map_interpreter.command_end event.start end end end class Game_Temp def dayNightTone if !@dayNightTone @dayNightTone=Tone.new(0,0,0) @dayNightToneNeedUpdate=true end if @dayNightToneNeedUpdate pbSetDayNightTone(@dayNightTone) @dayNightToneNeedUpdate=false end return @dayNightTone end def updateDayNightTone @dayNightToneNeedUpdate=true end end
Animation_Sprite
[
Selecionar
] [
-
]
=begin A sprite whose sole purpose is to display an animation. This sprite can be displayed anywhere on the map and is disposed automatically when its animation is finished. =end class AnimationSprite < RPG::Sprite def initialize(animID,map,tileX,tileY,viewport=nil) super(viewport) @tileX=tileX @tileY=tileY self.bitmap=Bitmap.new(1,1) self.bitmap.clear @map=map self.x=((@tileX*Game_Map.realResX)-@map.display_x+3)/4+(Game_Map::TILEWIDTH/2) self.y=((@tileY*Game_Map.realResY)-@map.display_y+3)/4+(Game_Map::TILEHEIGHT) self.animation($data_animations[animID],true) end def dispose self.bitmap.dispose super end def update if !self.disposed? self.x=((@tileX*Game_Map.realResX)-@map.display_x+3)/4+(Game_Map::TILEWIDTH/2) self.y=((@tileY*Game_Map.realResY)-@map.display_y+3)/4+(Game_Map::TILEHEIGHT) super self.dispose if !self.effect? end end end =begin Modifying Spriteset_Map =end def pbDayNightTint(object) if !$scene.is_a?(Scene_Map) return else if $game_map && pbGetMetadata($game_map.map_id,1) tone=$game_temp.dayNightTone object.tone.set(tone.red,tone.green,tone.blue,tone.gray) else object.tone.set(0,0,0,0) end end end class Spriteset_Map alias _animationSprite_initialize initialize alias _animationSprite_update update alias _animationSprite_dispose dispose def initialize(map=nil) @usersprites=[] _animationSprite_initialize(map) end def addUserAnimation(animID,x,y) viewport=Viewport.new(0,0,Graphics.width,Graphics.height) viewport.z=99999 sprite=AnimationSprite.new(animID,$game_map,x,y,viewport) addUserSprite(sprite) return sprite end def addUserSprite(sprite) for i in 0...@usersprites.length if @usersprites[i]==nil || @usersprites[i].disposed? @usersprites[i]=sprite return end end @usersprites.push(sprite) end def dispose _animationSprite_dispose for i in 0...@usersprites.length @usersprites[i].dispose end @usersprites.clear end def update return if @tilemap.disposed? if $PokemonSystem.tilemap==0 if self.map==$game_map pbDayNightTint(@viewport3) else @viewport3.tone.set(0,0,0,0) end else pbDayNightTint(@tilemap) @viewport3.tone.set(0,0,0,0) end _animationSprite_update for i in 0...@usersprites.length @usersprites[i].update if !@usersprites[i].disposed? end end end
Debug_Console
[
Selecionar
] [
-
]
module Console attr_reader :bufferHandle GENERIC_READ = 0x80000000 GENERIC_WRITE = 0x40000000 FILE_SHARE_READ = 0x00000001 FILE_SHARE_WRITE = 0x00000002 CONSOLE_TEXTMODE_BUFFER = 0x00000001 def Console::AllocConsole return @apiAllocConsole.call end def Console::CreateConsoleScreenBuffer(dwDesiredAccess,dwShareMode,dwFlags) return @apiCreateConsoleScreenBuffer.call(dwDesiredAccess,dwShareMode,nil,dwFlags,nil) end def Console::WriteConsole(lpBuffer) hFile = @bufferHandle return if !hFile return @apiWriteConsole.call(hFile,lpBuffer,lpBuffer.size,0,0) end def Console::ReadConsole(lpBuffer) hFile = @bufferHandle return @apiReadConsole.call(hFile,lpBuffer,lpBuffer.size,0,0) end def Console::SetConsoleActiveScreenBuffer(hScreenBuffer) return @apiSetConsoleActiveScreenBuffer.call(hScreenBuffer) end def Console::SetConsoleScreenBufferSize(hScreenBuffer,x,y) return @apiSetConsoleScreenBufferSize.call(hScreenBuffer,[x,y].pack("vv")) end def Console::SetConsoleTitle(title) return @apiSetConsoleTitle.call(title) end def self.setup_console unless $DEBUG return end @apiAllocConsole = Win32API.new("kernel32","AllocConsole","","l") @apiCreateConsoleScreenBuffer = Win32API.new("kernel32","CreateConsoleScreenBuffer","nnpnp","l") @apiSetConsoleActiveScreenBuffer = Win32API.new("kernel32","SetConsoleActiveScreenBuffer","l","s") @apiWriteConsole = Win32API.new("kernel32","WriteConsole","lpnnn","S") @apiReadConsole = Win32API.new("kernel32","ReadConsole","lpnnn","S") @apiSetConsoleScreenBufferSize = Win32API.new("kernel32","SetConsoleScreenBufferSize","lp","S") @apiSetConsoleTitle = Win32API.new("kernel32","SetConsoleTitle","p","s") access = (GENERIC_READ | GENERIC_WRITE) sharemode = (FILE_SHARE_READ | FILE_SHARE_WRITE) returnCode = AllocConsole() @bufferHandle = CreateConsoleScreenBuffer(access,sharemode,CONSOLE_TEXTMODE_BUFFER) f = File.open("Game.ini") lines = f.readlines() s = lines[3] len = s.size title = (s[6,len - 7]) SetConsoleScreenBufferSize(@bufferHandle,100,2000) SetConsoleTitle("Debug Console -- #{title}") echo "#{title} Output Window\\n" echo "-------------------------------\\n" echo "If you are seeing this window, you are running\\n" echo "#{title} in Debug Mode. This means\\n" echo "that you're either playing a Debug Version, or\\n" echo "you are playing from within RPG Maker XP.\\n" echo "\\n" echo "Closing this window will close the game. If \\n" echo "you want to get rid of this window, run the\\n" echo "program from the Shell, or download a Release\\n" echo "version.\\n" echo "\\n" echo "Gameplay will be paused while the console has\\n" echo "focus. To resume playing, switch to the Game\\n" echo "Window.\\n" echo "-------------------------------\\n" echo "Debug Output:\\n" echo "-------------------------------\\n\\n" SetConsoleActiveScreenBuffer(@bufferHandle) end def self.readInput length=20 buffer=0.chr*length eventsread=0.chr*4 done=false input="" while !done echo("waiting for input") begin @apiReadConsole.call(@bufferHandle,buffer,1,eventsread) rescue Hangup return end offset=0 events=eventsread.unpack("V") echo("got input [eventsread #{events}") for i in 0...events[0] keyevent=buffer[offset,20] keyevent=keyevent.unpack("vCvvvvV") if keyevent[0]==1 && keyevent[1]>0 input+=keyevent[4].chr if keyevent[4].chr=="\\n" done=true break end end offset+=20 end end return input end def self.readInput2 buffer=0.chr done=false input="" eventsread=0.chr*4 while !done if ReadConsole(buffer)==0 getlast = Win32API.new("kernel32","GetLastError","","n") echo(sprintf("failed (%d)\\r\\n",getlast.call())) break end offset=0 events=eventsread.unpack("V") if events[0]>0 echo("got input [eventsread #{events}][buffer #{buffer}]\\r\\n") key=buffer[0,events[0]] input+=key if key=="\\n" break end Graphics.update end end return input end def self.get_input echo self.readInput2 end end module Kernel def echo(string) unless $DEBUG return end Console::WriteConsole(string.is_a?(String) ? string : string.inspect) end def echoln(string) echo(string) echo("\\r\\n") end end
Sockets
[
Selecionar
] [
-
]
module Win32 #-------------------------------------------------------------------------- # ● Retrieves data from a pointer. #-------------------------------------------------------------------------- def copymem(len) buf = "\\0" * len Win32API.new("kernel32", "RtlMoveMemory", "ppl", "").call(buf, self, len) buf end end # Extends the numeric class. class Numeric include Win32 end # Extends the string class. class String include Win32 end #============================================================================== #End #============================================================================== #=============================================================================== # ** Module Winsock - Maps out the functions held in the Winsock DLL. #------------------------------------------------------------------------------- # Author Ruby # Version 1.8.1 #=============================================================================== #------------------------------------------------------------------------------- # Begin SDK Enabled Check #------------------------------------------------------------------------------- module Winsock DLL = "ws2_32" #-------------------------------------------------------------------------- # * Accept Connection #-------------------------------------------------------------------------- def self.accept(*args) Win32API.new(DLL, "accept", "ppl", "l").call(*args) end #-------------------------------------------------------------------------- # * Bind #-------------------------------------------------------------------------- def self.bind(*args) Win32API.new(DLL, "bind", "ppl", "l").call(*args) end #-------------------------------------------------------------------------- # * Close Socket #-------------------------------------------------------------------------- def self.closesocket(*args) Win32API.new(DLL, "closesocket", "p", "l").call(*args) end #-------------------------------------------------------------------------- # * Connect #-------------------------------------------------------------------------- def self.connect(*args) Win32API.new(DLL, "connect", "ppl", "l").call(*args) end #-------------------------------------------------------------------------- # * Get host (Using Adress) #-------------------------------------------------------------------------- def self.gethostbyaddr(*args) Win32API.new(DLL, "gethostbyaddr", "pll", "l").call(*args) end #-------------------------------------------------------------------------- # * Get host (Using Name) #-------------------------------------------------------------------------- def self.gethostbyname(*args) Win32API.new(DLL, "gethostbyname", "p", "l").call(*args) end #-------------------------------------------------------------------------- # * Get host's Name #-------------------------------------------------------------------------- def self.gethostname(*args) Win32API.new(DLL, "gethostname", "pl", "").call(*args) end #-------------------------------------------------------------------------- # * Get Server (Using Name) #-------------------------------------------------------------------------- def self.getservbyname(*args) Win32API.new(DLL, "getservbyname", "pp", "p").call(*args) end #-------------------------------------------------------------------------- # * Convert Host Long To Network Long #-------------------------------------------------------------------------- def self.htonl(*args) Win32API.new(DLL, "htonl", "l", "l").call(*args) end #-------------------------------------------------------------------------- # * Convert Host Short To Network Short #-------------------------------------------------------------------------- def self.htons(*args) Win32API.new(DLL, "htons", "l", "l").call(*args) end #-------------------------------------------------------------------------- # * Inet Adress #-------------------------------------------------------------------------- def self.inet_addr(*args) Win32API.new(DLL, "inet_addr", "p", "l").call(*args) end #-------------------------------------------------------------------------- # * Inet N To A #-------------------------------------------------------------------------- def self.inet_ntoa(*args) Win32API.new(DLL, "inet_ntoa", "l", "p").call(*args) end #-------------------------------------------------------------------------- # * Listen #-------------------------------------------------------------------------- def self.listen(*args) Win32API.new(DLL, "listen", "pl", "l").call(*args) end #-------------------------------------------------------------------------- # * Recieve #-------------------------------------------------------------------------- def self.recv(*args) Win32API.new(DLL, "recv", "ppll", "l").call(*args) end #-------------------------------------------------------------------------- # * Select #-------------------------------------------------------------------------- def self.select(*args) Win32API.new(DLL, "select", "lpppp", "l").call(*args) end #-------------------------------------------------------------------------- # * Send #-------------------------------------------------------------------------- def self.send(*args) Win32API.new(DLL, "send", "ppll", "l").call(*args) end #-------------------------------------------------------------------------- # * Set Socket Options #-------------------------------------------------------------------------- def self.setsockopt(*args) Win32API.new(DLL, "setsockopt", "pllpl", "l").call(*args) end #-------------------------------------------------------------------------- # * Shutdown #-------------------------------------------------------------------------- def self.shutdown(*args) Win32API.new(DLL, "shutdown", "pl", "l").call(*args) end #-------------------------------------------------------------------------- # * Socket #-------------------------------------------------------------------------- def self.socket(*args) Win32API.new(DLL, "socket", "lll", "l").call(*args) end #-------------------------------------------------------------------------- # * Get Last Error #-------------------------------------------------------------------------- def self.WSAGetLastError(*args) Win32API.new(DLL, "WSAGetLastError", "", "l").call(*args) end end #=============================================================================== # ** Socket - Creates and manages sockets. #------------------------------------------------------------------------------- # Author Ruby # Version 1.8.1 #=============================================================================== class Socket #-------------------------------------------------------------------------- # ● Constants #-------------------------------------------------------------------------- AF_UNSPEC = 0 AF_UNIX = 1 AF_INET = 2 AF_IPX = 6 AF_APPLETALK = 16 PF_UNSPEC = 0 PF_UNIX = 1 PF_INET = 2 PF_IPX = 6 PF_APPLETALK = 16 SOCK_STREAM = 1 SOCK_DGRAM = 2 SOCK_RAW = 3 SOCK_RDM = 4 SOCK_SEQPACKET = 5 IPPROTO_IP = 0 IPPROTO_ICMP = 1 IPPROTO_IGMP = 2 IPPROTO_GGP = 3 IPPROTO_TCP = 6 IPPROTO_PUP = 12 IPPROTO_UDP = 17 IPPROTO_IDP = 22 IPPROTO_ND = 77 IPPROTO_RAW = 255 IPPROTO_MAX = 256 SOL_SOCKET = 65535 SO_DEBUG = 1 SO_REUSEADDR = 4 SO_KEEPALIVE = 8 SO_DONTROUTE = 16 SO_BROADCAST = 32 SO_LINGER = 128 SO_OOBINLINE = 256 SO_RCVLOWAT = 4100 SO_SNDTIMEO = 4101 SO_RCVTIMEO = 4102 SO_ERROR = 4103 SO_TYPE = 4104 SO_SNDBUF = 4097 SO_RCVBUF = 4098 SO_SNDLOWAT = 4099 TCP_NODELAY = 1 MSG_OOB = 1 MSG_PEEK = 2 MSG_DONTROUTE = 4 IP_OPTIONS = 1 IP_DEFAULT_MULTICAST_LOOP = 1 IP_DEFAULT_MULTICAST_TTL = 1 IP_MULTICAST_IF = 2 IP_MULTICAST_TTL = 3 IP_MULTICAST_LOOP = 4 IP_ADD_MEMBERSHIP = 5 IP_DROP_MEMBERSHIP = 6 IP_TTL = 7 IP_TOS = 8 IP_MAX_MEMBERSHIPS = 20 EAI_ADDRFAMILY = 1 EAI_AGAIN = 2 EAI_BADFLAGS = 3 EAI_FAIL = 4 EAI_FAMILY = 5 EAI_MEMORY = 6 EAI_NODATA = 7 EAI_NONAME = 8 EAI_SERVICE = 9 EAI_SOCKTYPE = 10 EAI_SYSTEM = 11 EAI_BADHINTS = 12 EAI_PROTOCOL = 13 EAI_MAX = 14 AI_PASSIVE = 1 AI_CANONNAME = 2 AI_NUMERICHOST = 4 AI_MASK = 7 AI_ALL = 256 AI_V4MAPPED_CFG = 512 AI_ADDRCONFIG = 1024 AI_DEFAULT = 1536 AI_V4MAPPED = 2048 #-------------------------------------------------------------------------- # ● Returns the associated IP address for the given hostname. #-------------------------------------------------------------------------- def self.getaddress(host) gethostbyname(host)[3].unpack("C4").join(".") end #-------------------------------------------------------------------------- # ● Returns the associated IP address for the given hostname. #-------------------------------------------------------------------------- def self.getservice(serv) case serv when Numeric return serv when String return getservbyname(serv) else raise "Please use an integer or string for services." end end #-------------------------------------------------------------------------- # ● Returns information about the given hostname. #-------------------------------------------------------------------------- def self.gethostbyname(name) raise SocketError::ENOASSOCHOST if (ptr = Winsock.gethostbyname(name)) == 0 host = ptr.copymem(16).unpack("iissi") [host[0].copymem(64).split("\\0")[0], [], host[2], host[4].copymem(4).unpack("l")[0].copymem(4)] end #-------------------------------------------------------------------------- # ● Returns the user's hostname. #-------------------------------------------------------------------------- def self.gethostname buf = "\\0" * 256 Winsock.gethostname(buf, 256) buf.strip end #-------------------------------------------------------------------------- # ● Returns information about the given service. #-------------------------------------------------------------------------- def self.getservbyname(name) case name when /echo/i return 7 when /daytime/i return 13 when /ftp/i return 21 when /telnet/i return 23 when /smtp/i return 25 when /time/i return 37 when /http/i return 80 when /pop/i return 110 else Network.testing? != 0 ? (Network.testresult(true)) : (raise "Service not recognized.") return if Network.testing? == 2 end end #-------------------------------------------------------------------------- # ● Creates an INET-sockaddr struct. #-------------------------------------------------------------------------- def self.sockaddr_in(port, host) begin [AF_INET, getservice(port)].pack("sn") + gethostbyname(host)[3] + [].pack("x8") rescue Network.testing? != 0 ? (Network.testresult(true)): (nil) return if Network.testing? == 2 rescue Hangup Network.testing? != 0 ? (Network.testresult(true)): (nil) return if Network.testing? == 2 end end #-------------------------------------------------------------------------- # ● Creates a new socket and connects it to the given host and port. #-------------------------------------------------------------------------- def self.open(*args) socket = new(*args) if block_given? begin yield socket ensure socket.close end end nil end #-------------------------------------------------------------------------- # ● Creates a new socket. #-------------------------------------------------------------------------- def initialize(domain, type, protocol) SocketError.check if (@fd = Winsock.socket(domain, type, protocol)) == -1 @fd end #-------------------------------------------------------------------------- # ● Accepts incoming connections. #-------------------------------------------------------------------------- def accept(flags = 0) buf = "\\0" * 16 SocketError.check if Winsock.accept(@fd, buf, flags) == -1 buf end #-------------------------------------------------------------------------- # ● Binds a socket to the given sockaddr. #-------------------------------------------------------------------------- def bind(sockaddr) SocketError.check if (ret = Winsock.bind(@fd, sockaddr, sockaddr.size)) == -1 ret end #-------------------------------------------------------------------------- # ● Closes a socket. #-------------------------------------------------------------------------- def close SocketError.check if (ret = Winsock.closesocket(@fd)) == -1 ret end #-------------------------------------------------------------------------- # ● Connects a socket to the given sockaddr. #-------------------------------------------------------------------------- def connect(sockaddr) return if Network.testing? == 2 SocketError.check if (ret = Winsock.connect(@fd, sockaddr, sockaddr.size)) == -1 ret end #-------------------------------------------------------------------------- # ● Listens for incoming connections. #-------------------------------------------------------------------------- def listen(backlog) SocketError.check if (ret = Winsock.listen(@fd, backlog)) == -1 ret end #-------------------------------------------------------------------------- # ● Checks waiting data's status. #-------------------------------------------------------------------------- def select(timeout) SocketError.check if (ret = Winsock.select(1, [1, @fd].pack("ll"), 0, 0, [timeout, timeout * 1000000].pack("ll"))) == -1 ret end #-------------------------------------------------------------------------- # ● Checks if data is waiting. #-------------------------------------------------------------------------- def ready? not select(0) == 0 end #-------------------------------------------------------------------------- # ● Reads data from socket. #-------------------------------------------------------------------------- def read(len) buf = "\\0" * len Win32API.new("msvcrt", "_read", "lpl", "l").call(@fd, buf, len) buf end #-------------------------------------------------------------------------- # ● Returns received data. #-------------------------------------------------------------------------- def recv(len, flags = 0) retString="" remainLen=len while remainLen > 0 buf = "\\0" * remainLen retval=Winsock.recv(@fd, buf, buf.size, flags) SocketError.check if retval == -1 # Note: Return value may not equal requested length remainLen-=retval retString+=buf[0,retval] end return retString end #-------------------------------------------------------------------------- # ● Sends data to a host. #-------------------------------------------------------------------------- def send(data, flags = 0) SocketError.check if (ret = Winsock.send(@fd, data, data.size, flags)) == -1 ret end #-------------------------------------------------------------------------- # * Recieves file from a socket # size : file size # scene : update scene boolean #-------------------------------------------------------------------------- def recv_file(size,scene=false,file="") data = [] size.times do |i| if scene == true $scene.recv_update(size,i,file) if i%((size/1000)+1)== 0 else Graphics.update if i%1024 == 0 end data << recv(1) end return data end def recvTimeout if select(1000)==0 raise Hangup.new("Timeout") end return recv(1) end #-------------------------------------------------------------------------- # * Gets #-------------------------------------------------------------------------- def gets # Create buffer message = "" # Loop Until "end of line" while (char = recv(1)) != "\\n" message += char end # Return recieved data return message end #-------------------------------------------------------------------------- # ● Writes data to socket. #-------------------------------------------------------------------------- def write(data) Win32API.new("msvcrt", "_write", "lpl", "l").call(@fd, data, 1) end end #------------------------------------------------------------------------------- # End SDK Enabled Test #------------------------------------------------------------------------------- #=============================================================================== # ** TCPSocket - Creates and manages TCP sockets. #------------------------------------------------------------------------------- # Author Ruby # Version 1.8.1 #=============================================================================== #------------------------------------------------------------------------------- # Begin SDK Enabled Check #------------------------------------------------------------------------------- class TCPSocket < Socket #-------------------------------------------------------------------------- # ● Creates a new socket and connects it to the given host and port. #-------------------------------------------------------------------------- def self.open(*args) socket = new(*args) if block_given? begin yield socket ensure socket.close end end nil end #-------------------------------------------------------------------------- # ● Creates a new socket and connects it to the given host and port. #-------------------------------------------------------------------------- def initialize(host, port) super(AF_INET, SOCK_STREAM, IPPROTO_TCP) connect(Socket.sockaddr_in(port, host)) end end #============================================================================== # ■ SocketError #------------------------------------------------------------------------------ # Default exception class for sockets. #============================================================================== class SocketError < StandardError ENOASSOCHOST = "getaddrinfo: no address associated with hostname." def self.check errno = Winsock.WSAGetLastError if not Network.testing? == 1 raise Errno.const_get(Errno.constants.detect { |c| Errno.const_get(c).new.errno == errno }) else errno != 0 ? (Network.testresult(true)) : (Network.testresult(false)) end end end
Particle_Engine
[
Selecionar
] [
-
]
# Particle Engine, Peter O., 2007-11-03 # Based on version 2 by Near Fantastica, 04.01.06 # In turn based on the Particle Engine designed by PinkMan class Particle_Engine #-------------------------------------------------------------------------- def initialize(viewport=nil,map=nil) @map=map ? map : $game_map @viewport = viewport @effect = [] @disposed=false @firsttime=true @effects={ # PinkMan's Effects "fire"=>Particle_Engine::Fire, "smoke"=>Particle_Engine::Smoke, "teleport"=>Particle_Engine::Teleport, "spirit"=>Particle_Engine::Spirit, "explosion"=>Particle_Engine::Explosion, "aura"=>Particle_Engine::Aura, # BlueScope's Effects "soot"=>Particle_Engine::Soot, "sootsmoke"=>Particle_Engine::SootSmoke, "rocket"=>Particle_Engine::Rocket, "fixteleport"=>Particle_Engine::FixedTeleport, "smokescreen"=>Particle_Engine::Smokescreen, "flare"=>Particle_Engine::Flare, "splash"=>Particle_Engine::Splash, # By Peter O. "starteleport"=>Particle_Engine::StarTeleport } end def add_effect(event) @effect[event.id]=pbParticleEffect(event) end def realloc_effect(event,particle) type = pbEventCommentInput(event, 1, "Particle Engine Type") if type.nil? particle.dispose if particle return nil end type=type[0].downcase cls=@effects[type] if cls.nil? particle.dispose if particle return nil end if !particle || !particle.is_a?(cls) particle.dispose if particle particle=cls.new(event,@viewport) end return particle end def pbParticleEffect(event) return realloc_effect(event,nil) end def remove_effect(event) return if @effect[event.id].nil? @effect[event.id].dispose @effect.delete_at(event.id) end def update if @firsttime @firsttime=false for event in @map.events.values remove_effect(event) add_effect(event) end end for i in 0...@effect.length particle=@effect[i] next if particle.nil? if particle.event.pe_refresh event=particle.event event.pe_refresh=false particle=realloc_effect(event,particle) @effect[i]=particle end particle.update if particle end end def disposed? return @disposed end def dispose return if disposed? for particle in @effect next if particle.nil? particle.dispose end @effect.clear @map=nil @disposed=true end end class ParticleEffect attr_accessor :x,:y,:z def initialize @x=0 @y=0 @z=0 end def update end def dispose end end class ParticleSprite attr_accessor :x,:y,:z,:opacity,:bitmap,:blend_type def initialize(viewport) @viewport=viewport @sprite=nil @x=0 @y=0 @z=0 @opacity=255 @bitmap=nil @blend_type=0 @minleft=0 @mintop=0 end def bitmap=(value) @bitmap=value if value @minleft=-value.width @mintop=-value.height else @minleft=0 @mintop=0 end end def dispose @sprite.dispose if @sprite end def update w=Graphics.width h=Graphics.height if !@sprite && @x>=@minleft && @y>=@mintop && @x<w && @y<h @sprite=Sprite.new(@viewport) elsif @sprite && (@x<@minleft || @y<@mintop || @x>=w || @y>=h) @sprite.dispose @sprite=nil end if @sprite @sprite.x=@x if @sprite.x!=@x @sprite.y=@y if @sprite.y!=@y @sprite.z=@z if @sprite.z!=@z @sprite.opacity=@opacity if @sprite.opacity!=@opacity @sprite.blend_type=@blend_type if @sprite.blend_type!=@blend_type @sprite.bitmap=@bitmap if @sprite.bitmap!=@bitmap end end end class ParticleEffect_Event < ParticleEffect attr_accessor :event def initialize(event,viewport=nil) @event=event @viewport=viewport @particles=[] @bitmaps={} end def setParameters(params) @randomhue,@leftright,@fade, @maxparticless,@hue,@slowdown, @ytop,@ybottom,@xleft,@xright, @xgravity,@ygravity,@xoffset,@yoffset, @opacityvar,@originalopacity=params end def loadBitmap(filename,hue) key=[filename,hue] bitmap=@bitmaps[key] if !bitmap || bitmap.disposed? bitmap=BitmapCache.fog(filename,hue) @bitmaps[key]=bitmap end return bitmap end def initParticles(filename,opacity,zOffset=0,blendtype=1) @particles = [] @particlex = [] @particley = [] @opacity = [] @startingx = self.x + @xoffset @startingy = self.y + @yoffset @screen_x = self.x @screen_y = self.y @real_x = @event.real_x @real_y = @event.real_y @filename=filename @zoffset=zOffset @bmwidth=32 @bmheight=32 for i in 0...@maxparticless @particlex[i]=-@xoffset @particley[i]=-@yoffset @particles[i] = ParticleSprite.new(@viewport) @particles[i].bitmap = loadBitmap(filename, @hue) if filename if i==0 && @particles[i].bitmap @bmwidth=@particles[i].bitmap.width @bmheight=@particles[i].bitmap.height end @particles[i].blend_type = blendtype @particles[i].y = @startingy @particles[i].x = @startingx @particles[i].z = self.z+zOffset @opacity[i] = rand(opacity/4) @particles[i].opacity = @opacity[i] @particles[i].update end end def x return ScreenPosHelper.pbScreenX(@event) end def y return ScreenPosHelper.pbScreenY(@event) end def z return ScreenPosHelper.pbScreenZ(@event) end def update if @viewport && (@viewport.rect.x >= Graphics.width || @viewport.rect.y >= Graphics.height) return end selfX=self.x selfY=self.y selfZ=self.z newRealX=@event.real_x newRealY=@event.real_y @startingx = selfX + @xoffset @startingy = selfY + @yoffset @__offsetx=(@real_x==newRealX) ? 0 : selfX-@screen_x @__offsety=(@real_y==newRealY) ? 0 : selfY-@screen_y @screen_x = selfX @screen_y = selfY @real_x = newRealX @real_y = newRealY if @opacityvar>0 && @viewport opac=(255.0/@opacityvar) minX=opac*(-@xgravity*1.0 / @slowdown).floor + @startingx maxX=opac*(@xgravity*1.0 / @slowdown).floor + @startingx minY=opac*(-@ygravity*1.0 / @slowdown).floor + @startingy maxY=@startingy minX-=@bmwidth minY-=@bmheight maxX+=@bmwidth maxY+=@bmheight if maxX<0 || maxY<0 || minX>=Graphics.width || minY>=Graphics.height echo "skipped" return end end particleZ=selfZ+@zoffset for i in 0...@maxparticless @particles[i].z = particleZ if @particles[i].y <= @ytop @particles[i].y = @startingy + @yoffset @particles[i].x = @startingx + @xoffset @particlex[i]=0.0 @particley[i]=0.0 end if @particles[i].x <= @xleft @particles[i].y = @startingy + @yoffset @particles[i].x = @startingx + @xoffset @particlex[i]=0.0 @particley[i]=0.0 end if @particles[i].y >= @ybottom @particles[i].y = @startingy + @yoffset @particles[i].x = @startingx + @xoffset @particlex[i]=0.0 @particley[i]=0.0 end if @particles[i].x >= @xright @particles[i].y = @startingy + @yoffset @particles[i].x = @startingx + @xoffset @particlex[i]=0.0 @particley[i]=0.0 end if @fade == 0 if @opacity[i] <= 0 @opacity[i] = @originalopacity @particles[i].y = @startingy + @yoffset @particles[i].x = @startingx + @xoffset @particlex[i]=0.0 @particley[i]=0.0 end else if @opacity[i] <= 0 @opacity[i] = 250 @particles[i].y = @startingy + @yoffset @particles[i].x = @startingx + @xoffset @particlex[i]=0.0 @particley[i]=0.0 end end calcParticlePos(i) if @randomhue == 1 if @hue >= 360 @hue = 0 end @hue = @hue + 0.5 @particles[i].bitmap = loadBitmap(@filename, @hue) if @filename end @opacity[i] = @opacity[i] - rand(@opacityvar) @particles[i].opacity = @opacity[i] @particles[i].update end end def calcParticlePos(i) @leftright = rand(2) if @leftright == 1 xo=(-@xgravity*1.0 / @slowdown) else xo=(@xgravity*1.0 / @slowdown) end yo=(-@ygravity*1.0 / @slowdown) @particlex[i]+=xo @particley[i]+=yo @particlex[i]-=@__offsetx @particley[i]-=@__offsety @particlex[i]=@particlex[i].floor @particley[i]=@particley[i].floor @particles[i].x=@particlex[i]+@startingx+@xoffset @particles[i].y=@particley[i]+@startingy+@yoffset end def dispose for particle in @particles particle.dispose end for bitmap in @bitmaps.values bitmap.dispose end @particles.clear @bitmaps.clear end end class Particle_Engine::Fire < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,1,20,40,0.5, -64,Graphics.height,-64,Graphics.width, 0.5,0.10,-5,-13,30,0]) initParticles("particle",250) end end class Particle_Engine::Smoke < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,0,80,20,0.5,-64, Graphics.height,-64,Graphics.width,0.5,0.10,-5,-15,5,80]) initParticles("smoke",250) end end class Particle_Engine::Teleport < ParticleEffect_Event def initialize(event,viewport) super setParameters([1,1,1,10,rand(360),1,-64, Graphics.height,-64,Graphics.width,0,3,-8,-15,20,0]) initParticles("wideportal",250) for i in 0...@maxparticless @particles[i].ox=16 @particles[i].oy=16 end end end class Particle_Engine::Spirit < ParticleEffect_Event def initialize(event,viewport) super setParameters([1,0,1,20,rand(360),0.5, -64,Graphics.height,-64,Graphics.width, 0.5,0.10,-5,-13,30,0]) initParticles("particle",250) end end class Particle_Engine::Explosion < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,1,20,0,0.5, -64,Graphics.height,-64,Graphics.width, 0.5,0.10,-5,-13,30,0]) initParticles("explosion",250) end end class Particle_Engine::Aura < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,1,20,0,1, -64,Graphics.height,-64,Graphics.width, 2,2,-5,-13,30,0]) initParticles("particle",250) end end class Particle_Engine::Soot < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,0,20,0,0.5, -64,Graphics.height,-64,Graphics.width, 0.5,0.10,-5,-15,5, 80]) initParticles("smoke",100,0,2) end end class Particle_Engine::SootSmoke < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,0,30,0,0.5, -64,Graphics.height,-64,Graphics.width, 0.5,0.10,-5,-15,5, 80]) initParticles("smoke",100,0) for i in 0...@maxparticless @particles[i].blend_type = rand(6) < 3 ? 1 : 2 end end end class Particle_Engine::Rocket < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,0,60,0,0.5, -64,Graphics.height,-64,Graphics.width, 0.5,0,-5,-15,5,80]) initParticles("smoke",100,-1) end end class Particle_Engine::FixedTeleport < ParticleEffect_Event def initialize(event,viewport) super setParameters([1,0,1,10,rand(360),1, -Graphics.height,Graphics.height,0,Graphics.width,0,3,-8,-15,20,0]) initParticles("wideportal",250) for i in 0...@maxparticless @particles[i].ox=16 @particles[i].oy=16 end end end # By Peter O. class Particle_Engine::StarTeleport < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,1,10,0,1, -Graphics.height,Graphics.height,0,Graphics.width,0,3,-8,-15,10,0]) initParticles("star",250) for i in 0...@maxparticless @particles[i].ox=48 @particles[i].oy=48 end end end class Particle_Engine::Smokescreen < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,0,450,0,0.2, -64,Graphics.height,-64,Graphics.width, 0.8,0.8,-5,-15,5,80]) initParticles(nil,100) for i in 0...@maxparticless rnd=rand(3) @opacity[i] = (rnd==0) ? 1 : 100 filename=(rnd==0) ? "explosionsmoke" : "smoke" @particles[i].bitmap = loadBitmap(filename, @hue) end end def calcParticlePos(i) if @randomhue==1 filename=(rand(3)==0) ? "explosionsmoke" : "smoke" @particles[i].bitmap = loadBitmap(filename, @hue) end multiple = 1.7 xgrav=(@xgravity*multiple/@slowdown) xgrav=-xgrav if (rand(2)==1) ygrav=(@ygravity*multiple/@slowdown) ygrav=-ygrav if (rand(2)==1) @particlex[i]+=xgrav @particley[i]+=ygrav @particlex[i]-=@__offsetx @particley[i]-=@__offsety @particlex[i]=@particlex[i].floor @particley[i]=@particley[i].floor @particles[i].x=@particlex[i]+@startingx+@xoffset @particles[i].y=@particley[i]+@startingy+@yoffset end end class Particle_Engine::Flare < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,1,30,10,1, -64,Graphics.height,-64,Graphics.width, 2,2,-5,-12,30,0]) initParticles("particle",255) end end class Particle_Engine::Splash < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,1,30,255,1, -64,Graphics.height,-64,Graphics.width, 4,2,-5,-12,30,0]) initParticles("smoke",50) end def update super for i in 0...@maxparticless @particles[i].opacity=50 @particles[i].update end end end class Game_Event < Game_Character #-------------------------------------------------------------------------- attr_accessor :pe_refresh #-------------------------------------------------------------------------- alias nf_particles_game_map_initialize initialize alias nf_particles_game_map_refresh refresh #-------------------------------------------------------------------------- def initialize(map_id,event,map=nil) @pe_refresh=false begin nf_particles_game_map_initialize(map_id, event,map) rescue ArgumentError nf_particles_game_map_initialize(map_id, event) end end #-------------------------------------------------------------------------- def refresh nf_particles_game_map_refresh @pe_refresh=true end end
PerspectiveTilemap
[
Selecionar
] [
-
]
def bltMinimapAutotile(dstBitmap,x,y,srcBitmap,id) return if id>=48 || !srcBitmap || srcBitmap.disposed? anim=0 cxTile=3 cyTile=3 tiles = TileDrawingHelper::Autotiles[id>>3][id&7] src=Rect.new(0,0,0,0) for i in 0...4 tile_position = tiles[i] - 1 src.set( tile_position % 6 * cxTile + anim, tile_position / 6 * cyTile, cxTile, cyTile) dstBitmap.blt(i%2*cxTile+x,i/2*cyTile+y, srcBitmap, src) end end def passable?(passages,tile_id) return false if tile_id == nil return false if passages[tile_id] == nil return (passages[tile_id]<15) end def getPassabilityMinimap(mapid) map=load_data(sprintf("Data/Map%03d.rxdata",mapid)) tileset=$data_tilesets[map.tileset_id] minimap=Bitmap.new("Graphics/Pictures/minimap_tiles.png") ret=Bitmap.new(map.width*6,map.height*6) passtable=Table.new(map.width,map.height) passages=tileset.passages for i in 0...map.width for j in 0...map.height pass=true for z in [2,1,0] if !passable?(passages,map.data[i,j,z]) pass=false break end end passtable[i,j]=pass ? 1 : 0 end end neighbors=TileDrawingHelper::NeighborsToTiles for i in 0...map.width for j in 0...map.height if passtable[i,j]==0 nb=TileDrawingHelper.tableNeighbors(passtable,i,j) tile=neighbors[nb] bltMinimapAutotile(ret,i*6,j*6,minimap,tile) end end end minimap.dispose return ret end module ScreenPosHelper def self.pbScreenZoomX(ch) if $PokemonSystem.tilemap==2 return ((ch.screen_y - 16) - (Graphics.height / 2)) * (Draw_Tilemap::Pitch*1.0 / (Graphics.height * 25)) + 1 else return 1.0 end end def self.pbScreenZoomY(ch) if $PokemonSystem.tilemap==2 return ((ch.screen_y - 16) - (Graphics.height / 2)) * (Draw_Tilemap::Pitch*1.0 / (Graphics.height * 25)) + 1 else return 1.0 end end def self.pbScreenX(ch) ret=ch.screen_x if $PokemonSystem.tilemap==2 widthdiv2=(Graphics.width / 2) ret=widthdiv2+(ret-widthdiv2)*pbScreenZoomX(ch) end return ret end def self.pbScreenY(ch) ret=ch.screen_y if $PokemonSystem.tilemap==2 && Draw_Tilemap::Curve && Draw_Tilemap::Pitch != 0 zoomy=pbScreenZoomY(ch) oneMinusZoomY=1-zoomy ret += (8 * oneMinusZoomY * (oneMinusZoomY / (2 * ((Draw_Tilemap::Pitch*1.0 / 100) / (Graphics.height*1.0 / 16.0))) + 0.5)) end return ret end @heightcache={} def self.bmHeight(bm) h=@heightcache[bm] if !h bmap=RPG::Cache.character(bm,0) h=bmap.height @heightcache[bm]=h bmap.dispose end return h end def self.pbScreenZ(ch,height=nil) if height==nil height=0 if ch.tile_id > 0 height=32 elsif ch.character_name!="" height=bmHeight(ch.character_name)/4 end end ret=ch.screen_z(height) if $PokemonSystem.tilemap==2 ret-=(pbScreenZoomY(ch) < 0.5 ? 1000 : 0) end return ret end end ############################################### class Draw_Tilemap # This class controls a set of sprites, with different Z # values, arranged into horizontal bars StripSize = 16 Curve = true Pitch = 3 attr_accessor :tileset attr_accessor :map_data attr_accessor :flash_data attr_accessor :priorities attr_reader :autotiles attr_accessor :bitmaps attr_accessor :pitch attr_accessor :ox attr_accessor :oy attr_accessor :visible attr_reader :viewport attr_accessor :color attr_accessor :tone FlashOpacity=[100,90,80,70,80,90] #----------------------------------------------------------------------------- def initialize(viewport=nil) @tileset=nil @map_data=nil @priorities=nil @autotiles=[nil,nil,nil,nil,nil,nil,nil] @viewport=viewport @visible=true @helper=TileDrawingHelper.new(nil,@autotiles) @drawnstrips=[] @contentstrips=[] @disposed=false @bitmaps=[] @sprites=[] @ox=0 @oy=0 @tone=Tone.new(0,0,0,0) @color=Color.new(0,0,0,0) @flash_data=nil @numsprites=0 end def tileset=(value) @tileset=value @helper.tileset=value @doredraw=true end def map_data=(value) @map_data=value @doredraw=true end def flash_data=(value) @flash_data=value @doredraw=true end def priorities=(value) @priorities=value @doredraw=true end def redrawmap # Provide blank data in proper object form self.clear xsize=@map_data.xsize ysize=@map_data.ysize # Bitmaps used for each priority's drawing. Priorities 2-5 are combined. @bitmaps = [Bitmap.new(xsize*32, ysize*32+StripSize), Bitmap.new(xsize*32, ysize*32+StripSize), Bitmap.new(xsize*32, ysize*32+StripSize)] for i in @bitmaps i.clear end if @flash_data @bitmaps.push(Bitmap.new(xsize*32, ysize*32+StripSize)) end @drawnstrips.clear @contentstrips.clear # Generate blank sprites @sprites.clear @numsprites=ysize * (32 / StripSize) for i in 0...@map_data.zsize # For each layer @sprites.push([]) @contentstrips.push([]) end if @flash_data @sprites.push([]) @contentstrips.push([]) end end def update oyunchanged=false if !@flash_data.nil? && @sprites.length>0 flashindex=@sprites.length-1 for j in 0...@numsprites sprite=@sprites[flashindex][j] next if !sprite.is_a?(Sprite) sprite.opacity=FlashOpacity[(Graphics.frame_count/2) % 6] end end for s in @sprites for sprite in s next if !sprite.is_a?(Sprite) # sprite.tone=@tone # sprite.color=@color end end if @doredraw @drawnstrips=[] redrawmap @doredraw=false elsif @oldOx==@ox && @oldOy==@oy return elsif @oldOy==@oy oyunchanged=true end @oldOx=@ox @oldOy=@oy @pitch = Pitch minvalue=[0, ((Graphics.height / 2) - ((Graphics.height * 60) / @pitch) + @oy) / StripSize].max.to_i maxvalue=[@numsprites - 1,(@oy + Graphics.height) / StripSize].min.to_i return if minvalue>maxvalue for j in 0...@numsprites if j<minvalue || j>maxvalue for i in 0...@sprites.length sprite=@sprites[i][j] if sprite sprite.dispose if sprite.is_a?(Sprite) @sprites[i][j]=nil end end else drawStrip(j) end end vpy=@viewport.rect.y vpr=@viewport.rect.x+@viewport.rect.width vpb=@viewport.rect.y+@viewport.rect.height numsprites=0 for i in @sprites numsprites+=i.compact.length end for j in minvalue..maxvalue # For each strip within the visible screen, update OX/Y x=Graphics.width/2 sox=@ox+x y = (j * StripSize - @oy) zoom_x=1.0 zoom_y=1.0 unless @pitch == 0 # Apply X Zoom zoom_x = (y - Graphics.height*1.0 / 2) * (@pitch*1.0 / (Graphics.height * 25)) + 1 if Curve # Zoom Y values same as X, and compensate zoom_y = zoom_x yadd = StripSize*1.0 * (1 - zoom_y) * ((1 - zoom_y) / (2 * ((@pitch*1.0 / 100) / (Graphics.height*1.0 / (StripSize * 2)))) + 0.5) y+=yadd end end xstart=(x-sox*zoom_x) yend=(y+(StripSize*2)*zoom_y) if xstart>vpr || yend<=vpy for i in 0...@sprites.length sprite=@sprites[i][j] if sprite.is_a?(Sprite) sprite.dispose @sprites[i][j]=nil end end else for i in 0...@sprites.length sprite=@sprites[i][j] next if !sprite if sprite==true sprite=newSprite(i,j) @sprites[i][j]=sprite end sprite.visible=@visible sprite.x = x sprite.ox = sox sprite.y = y sprite.zoom_x = zoom_x sprite.zoom_y = zoom_y end end end end def clear for i in @bitmaps i.dispose end @bitmaps.clear for i in 0...@sprites.length for j in 0...@sprites[i].length @sprites[i][j].dispose if @sprites[i][j].is_a?(Sprite) end @sprites[i].clear end @sprites.clear end def dispose return if @disposed self.clear for i in 0...7 self.autotiles[i]=nil end @helper=nil @sprites=nil @bitmaps=nil @disposed = true end def disposed? return @disposed end def newSprite(i,j) sprite=Sprite.new(@viewport) sprite.bitmap=@bitmaps[i] sprite.src_rect.set(0, j * StripSize, @map_data.xsize * 32, StripSize * 2) sprite.x = Graphics.width / 2 sprite.y = -64 sprite.z = (i * 32) sprite.tone=@tone sprite.color=@color if i==@bitmaps.length-1 && !@flash_data.nil? sprite.blend_type=1 sprite.z=1 sprite.opacity=FlashOpacity[(Graphics.frame_count/2) % 6] end return sprite end def drawStrip(j) minY=(j*StripSize)/32 maxY=(j*StripSize+StripSize*2)/32 minY=0 if minY<0 minY=@map_data.ysize-1 if minY>@map_data.ysize-1 maxY=0 if maxY<0 maxY=@map_data.ysize-1 if maxY>@map_data.ysize-1 for y in minY..maxY if !@drawnstrips[y] for x in 0...@map_data.xsize draw_position(x, y) end @drawnstrips[y]=true end end for i in 0...@sprites.length # For each priority sprite=@sprites[i][j] if !sprite || (sprite!=true && sprite.disposed?) havecontent=false for y in minY..maxY havecontent=havecontent||@contentstrips[i][y] end sprite=(havecontent) ? true : nil @sprites[i][j]=sprite end end end def draw_position(x, y) for layer in 0...@map_data.zsize pos = @map_data[x, y, layer] priopos=@priorities[pos] priopos=0 if !priopos prio=(2<priopos) ? 2 : priopos @contentstrips[prio][y]=true if pos>0 @helper.bltTile(@bitmaps[prio],x*32,y*32,pos,0) end if !@flash_data.nil? lastlayer=@bitmaps.length-1 id=@flash_data[x,y,0] r=(id>>8)&15 g=(id>>4)&15 b=(id)&15 @contentstrips[lastlayer][y]=true color=Color.new(r*16,g*16,b*16) @bitmaps[lastlayer].fill_rect(x*32,y*32,32,32,color) end end end class Sprite_Character attr_accessor :character def initialize(viewport, character = nil) super(viewport) @character = character update end alias update_or :update def update update_or if $PokemonSystem.tilemap==2 self.zoom_y=ScreenPosHelper.pbScreenZoomY(@character) self.zoom_x=ScreenPosHelper.pbScreenZoomX(@character) self.x=ScreenPosHelper.pbScreenX(@character) self.y=ScreenPosHelper.pbScreenY(@character) self.z=ScreenPosHelper.pbScreenZ(@character,@ch) else self.zoom_x=1.0 self.zoom_y=1.0 end end end
RamdomMaps
[
Selecionar
] [
-
]
def floodFillInternal(table,x,y,target,fillbits,points) w=table.xsize xLeft=x xRight=x yFromOrg=y xFromOrg=x curpos=yFromOrg*w+xFromOrg begin if !fillbits[curpos] points.push([xLeft,y]) end fillbits[curpos]=true curpos-=1 xLeft-=1 end while (xLeft>=0&& table[xLeft,y]==target&& !fillbits[curpos]) xLeft+=1 curpos=yFromOrg*w+xFromOrg begin if !fillbits[curpos] points.push([xRight,y]) end fillbits[curpos]=true curpos+=1 xRight+=1 end while(xRight<table.xsize&& table[xRight,y]==target&& !fillbits[curpos]) xRight-=1 curpos=yFromOrg-w+(xLeft) for i in xLeft..xRight above=(yFromOrg-1)*w+(i) below=(yFromOrg+1)*w+(i) if(y> 0 &&table[i,y-1]==target&&!fillbits[above]) ret=floodFillInternal(table,i,y-1,target,fillbits,points) end if(y<(table.ysize-1)&&table[i,y+1]==target&&!fillbits[below]) ret=floodFillInternal(table,i,y+1,target,fillbits,points) end end end N=0x01 NE=0x02 E=0x04 SE=0x08 S=0x10 SW=0x20 W=0x40 NW=0x80 BADNEIGHBORS=[ 0, SE, NW, NE, SW, S|SW, S|SE, N|NW, N|NE, W|SW, W|NW, E|NE, E|SE, S|SW|SE, N|NW|NE, W|NW|SW, E|NE|SE ] def isBadNeighbor?(neighbor) return true if BADNEIGHBORS.any?{|i| i==neighbor } return true if (neighbor&(S|W))==(0) && (neighbor&(SW))!=0 return true if (neighbor&(N|W))==(0) && (neighbor&(NW))!=0 return true if (neighbor&(S|E))==(0) && (neighbor&(SE))!=0 return true if (neighbor&(N|E))==(0) && (neighbor&(NE))!=0 return true if (neighbor&(NW|NE))==(0) && (neighbor&(N))!=0 return true if (neighbor&(SW|SE))==(0) && (neighbor&(S))!=0 return true if (neighbor&(NW|SW))==(0) && (neighbor&(W))!=0 return true if (neighbor&(NE|SE))==(0) && (neighbor&(E))!=0 end def pbTableMoveToNeighbor(table,pointtable,value) 1000.times do x=rand(table.xsize) y=rand(table.ysize) next if table[x,y]!=0 table[x,y]=value nb=TileDrawingHelper.tableNeighbors(table,x,y) if isBadNeighbor?(nb) table[x,y]=0 next end if nb==0 && rand(100)<50 table[x,y]=0 next end pointtable[x,y]=2 break end end def pbTablePlaceValue(table,value,minNumber,minbunch) return if minNumber<=0 # Phase 1: Place _minNumber_ points on the map 1000.times do 1000.times do x=rand(table.xsize-1) y=rand(table.ysize-1) placepos=[] if table[x,y]==0 table[x,y]=value placepos.push([x,y]) end if table[x+1,y]==0 table[x+1,y]=value placepos.push([x+1,y]) end if table[x,y+1]==0 table[x,y+1]=value placepos.push([x,y+1]) end if table[x+1,y+1]==0 table[x+1,y+1]=value placepos.push([x+1,y+1]) end placed=placepos.length for pp in placepos nb=TileDrawingHelper.tableNeighbors(table,pp[0],pp[1]) if isBadNeighbor?(nb) table[pp[0],pp[1]]=0 placed-=1 end end minNumber-=placed break end break if minNumber<=0 end # Phase 2: Move all bad points badpoints=0 begin badpoints=0 pointtable=Table.new(table.xsize,table.ysize) fillbits=[] # Find all bad points with flood filling if minbunch>0 table.xsize.times{|x| table.ysize.times{|y| next if table[x,y]!=value index=y*table.xsize+x if !fillbits[index] points=[] floodFillInternal(table,x,y,value,fillbits,points) isbad=(points.length<minbunch) havebadpoints=true if isbad badpoints+=points.length if isbad for p in points pointtable[p[0],p[1]]=isbad ? 1 : 2 end end } } end # Find all inappropriately placed points pointtable.xsize.times{|x| pointtable.ysize.times{|y| next if pointtable[x,y]==1 next if table[x,y]!=value nb=TileDrawingHelper.tableNeighbors(table,x,y) if isBadNeighbor?(nb) pointtable[x,y]=1 badpoints+=1 end if nb==(0xEF) # everything but South table[x,y+1]=value end if nb==(0xBF) # everything but West table[x-1,y]=value end if nb==(0xFB) # everything but East table[x+1,y]=value end if nb==(0xFE) # everything but North table[x,y-1]=value end } } if badpoints>0 # Move all bad points to new locations pointtable.xsize.times{|x| pointtable.ysize.times{|y| next if pointtable[x,y]!=1 # skip if not a bad point pointtable[x,y]=0 table[x,y]=0 pbTableMoveToNeighbor(table,pointtable,value) } } end end while badpoints>0 end def pbGenerateMap(id,width,height,generateMapParams) # Fill table with zeros table=Table.new(width,height) table.xsize.times{|x| table.ysize.times{|y| table[x,y]=0 } } # Place autotiles on the table for i in 0...7 count=generateMapParams[i*2] sticky=generateMapParams[i*2+1] pbTablePlaceValue(table,i+1,count,sticky) end # Create map and fill it with grass map=RPG::Map.new(width,height) map.data.xsize.times{|x| map.data.ysize.times{|y| map.data[x,y,0]=384 } } # Fill map with autotiles neighbors=TileDrawingHelper::NeighborsToTiles for i in 0...map.width for j in 0...map.height if table[i,j]!=0 nb=TileDrawingHelper.tableNeighbors(table,i,j) tile=neighbors[nb] map.data[i,j,1]=tile+48*table[i,j] end end end # Save map save_data(map,sprintf("Data/Map%03d.rxdata",id)) end =begin #Usage: pbGenerateMap( 24, # Map ID 30, # Map Width 30, # Map Height [ # Map Parameters # count, sticky 20,8, # Autotile 1 30,8, # Autotile 2 75,8, # Autotile 3 250,15, # Autotile 4 0,0, # Autotile 5 0,0, # Autotile 6 0,0 # Autotile 7 ] ) =end
RamdomMaps2
[
Selecionar
] [
-
]
class DungeonMap XBORDER=7 YBORDER=5 def initialize(width,height,blankValue) @map=Table.new( width+XBORDER+XBORDER, height+YBORDER+YBORDER ) for i in 0...@map.xsize for j in 0...@map.ysize @map[i,j]=blankValue end end end def width @map.xsize-XBORDER-XBORDER end def height @map.xsize-YBORDER-YBORDER end def map return @map end def draw(x,y,value) @map[x+XBORDER,y+YBORDER]=value end def get(x,y) @map[x+XBORDER,y+YBORDER] end def getRaw(x,y) @map[x,y] end end class RoomData attr_reader :x attr_reader :y attr_reader :width,:height alias top y alias left x def id return @room end def randomPos return [ @x+rand(@width), @y+rand(@height) ] end def right return @x+@width end def bottom return @y+@height end def initialize(room,x,y,width,height) @room=room @x=x @y=y @width=width @height=height end def draw(dungeon,value) for y in 0...self.height for x in 0...self.width xx=x+self.x yy=y+self.y dungeon.draw(xx,yy,value) end end end def createUnion(otherRoom) newX=[self.x,otherRoom.x].min newY=[self.y,otherRoom.y].min newRight=[self.right,otherRoom.right].max newBottom=[self.bottom,otherRoom.bottom].max return RoomData.new(self.id, newX,newY,newRight-newX,newBottom-newY) end def intersects?(otherRoom) newX=[self.x,otherRoom.x].max newY=[self.y,otherRoom.y].max newRight=[self.right,otherRoom.right].min newBottom=[self.bottom,otherRoom.bottom].min return (newX<newRight && newY<newBottom) end CLOSENESSFACTOR=2 def closeTo?(room) return false if !room if (self.bottom-room.top).abs<=CLOSENESSFACTOR return true end if (self.top-room.bottom).abs<=CLOSENESSFACTOR return true end if (self.right-room.left).abs<=CLOSENESSFACTOR return true end if (self.left-room.right).abs<=CLOSENESSFACTOR return true end return false end end def hasRoom?(rooms,room) return false if room<0 return rooms.any? {|item| item.id==room } end def getRoom(rooms,roomID) for room in rooms return room if room.id==roomID end return nil end def saferand(x) return 0 if x<=0 return rand(x) end def createCorridor(dungeon,startRoom,endRoom) moveDirection=(rand(2)==0) nowConnected=[] currentX=startRoom[0] currentY=startRoom[1] while currentX!=endRoom[0] || currentY!=endRoom[1] dx=endRoom[0]-currentX dy=endRoom[1]-currentY if (dx!=0 && moveDirection) currentX+=dx>0 ? 1 : -1 elsif dy!=0 currentY+=dy>0 ? 1 : -1 end if dungeon.get(currentX,currentY)==1 break end if rand(10)<3 moveDirection=!moveDirection end nowConnected.push([currentX,currentY]) end for point in nowConnected dungeon.draw(point[0],point[1],1) end end def generateDungeon(mapID) if false baselinesX=[0,0,28,18,14,11,9] baselinesY=[0,0,16,10,8] # min width, min height, min rooms, max rooms, startX, startY roomlayout=[ [2,2, 7,5, 4,4, 0,0], [3,2, 7,5, 4,6, 1,0], [3,3, 7,5, 6,9, 1,0], [4,3, 7,5, 8,11, 0,0], [4,4, 6,4, 7,12, 1,0], [5,4, 5,4, 6,12, 0,0], [6,4, 5,4, 7,12, 0,0] # prevent moving/growing here ] dungeonWidth=52 dungeonHeight=28 else baselinesX=[0,0,40,26,19,15,13] baselinesY=[0,0,21,14,10] # min width, min height, min rooms, max rooms, startX, startY roomlayout=[ [2,2, 16,7, 4,4, 0,0], [3,2, 12,7, 4,6, 1,0], [3,3, 12,7, 6,9, 1,0], [4,3, 12,7, 8,11, 0,0], [4,4, 10,6, 7,12, 1,0], [5,4, 9,6, 6,12, 0,0], [6,4, 9,6, 7,12, 0,0] # prevent moving/growing here ] dungeonWidth=78 dungeonHeight=42 end # TODO: Ensure no surpassing width/height for i in 0...baselinesX.length baselinesX[i]=baselinesX[i]*3/2 end for i in 0...baselinesY.length baselinesY[i]=baselinesY[i]*3/2 end for i in 0...roomlayout.length roomlayout[i][2]=roomlayout[i][2]*3/2 roomlayout[i][3]=roomlayout[i][3]*3/2 end dungeonWidth=dungeonWidth*3/2 dungeonHeight=dungeonHeight*3/2 dungeon=DungeonMap.new(dungeonWidth,dungeonHeight,2) layout=roomlayout[saferand(roomlayout.length)] numrooms=layout[4]+saferand(layout[5]-layout[4]+1) roomPositions=[] numRoomsX=layout[0] numRoomsY=layout[1] baselineX=baselinesX[numRoomsX] baselineY=baselinesY[numRoomsY] for y in 0...numRoomsY for x in 0...numRoomsX roomPositions.push([ roomPositions.length, layout[6]+(baselinesX[numRoomsX]*x), layout[7]+(baselinesY[numRoomsY]*y) ]) end end numrooms=roomPositions.length if numrooms>roomPositions.length roomPositions.sort!{|a,b| rand(3)-1 } rooms=[] for i in 0...numrooms room=roomPositions[i] roomX=room[1]+saferand(3) roomY=room[2]+saferand(3) roomWidth=layout[2]+saferand(baselineX-layout[2]-4) roomHeight=layout[3]+saferand(baselineY-layout[3]-2) roomRight=roomX+roomWidth roomBottom=roomY+roomHeight roomX=0 if roomX<0 roomY=0 if roomY<0 roomX-=roomRight-dungeon.width if roomRight>dungeon.width roomY-=roomBottom-dungeon.height if roomBottom>dungeon.height rooms.push(RoomData.new(room[0],roomX,roomY,roomWidth,roomHeight)) end ############ ## Combine rooms if necessary for i in 0...rooms.length next if !rooms[i] for j in i+1...rooms.length if rooms[i].closeTo?(rooms[j]) rooms[i]=rooms[i].createUnion(rooms[j]) rooms[j]=nil end end end rooms.compact! ############ ## Eliminate rooms within other rooms for i in 0...rooms.length next if !rooms[i] for j in i+1...rooms.length next if !rooms[j] || !rooms[i] # If the two rooms intersect if rooms[i].intersects?(rooms[j]) sizeI=rooms[i].width*rooms[i].height sizeJ=rooms[j].width*rooms[j].height # Eliminate the smaller of the two rooms if sizeI==sizeJ rooms[i]=nil rooms[j]=nil elsif sizeI<sizeJ rooms[i]=nil else rooms[j]=nil end end end end rooms.compact! ############ ## Create corridors firstRoom=rooms.delete_at(rand(rooms.length)) newRooms=[firstRoom] firstRoom.draw(dungeon,1) while rooms.length>0 startRoom=rooms[rand(rooms.length)] endRoom=newRooms[rand(newRooms.length)] createCorridor(dungeon, startRoom.randomPos, endRoom.randomPos ) rooms.delete(startRoom) newRooms.push(startRoom) startRoom.draw(dungeon,1) end ############ ## Fill map map=RPG::Map.new( dungeon.map.xsize, dungeon.map.ysize ) map.tileset_id=6 # Fill map with autotiles neighbors=TileDrawingHelper::NeighborsToTiles for i in 0...map.width for j in 0...map.height if dungeon.map[i,j]!=0 nb=TileDrawingHelper.tableNeighbors(dungeon.map,i,j) tile=neighbors[nb] map.data[i,j,1]=tile+48*dungeon.map[i,j] end end end save_data(map,sprintf("Data/Map%03d.rxdata",mapID)) end #generateDungeon(24)
Shadow
[
Selecionar
] [
-
]
#============================================================================== # Sprite_Shadow (Sprite_Ombre ) # Based on Genzai Kawakami's shadows, dynamisme&features by Rataime, extra features Boushy # Modified by Peter O. to be compatible with Pokémon Essentials #============================================================================== CATERPILLAR_COMPATIBLE = true SHADOW_WARN = true class Sprite_Shadow < RPG::Sprite attr_accessor :character def initialize(viewport, character = nil,params=[]) super(viewport) @source=params[0] @anglemin=0 @anglemin=params[1] if params.size>1 @anglemax=0 @anglemax=params[2] if params.size>2 @self_opacity=100 @self_opacity=params[4] if params.size>4 @distancemax=350 @distancemax=params[3] if params.size>3 @character = character update end def dispose self.bitmap.dispose if self.bitmap super end def update if !in_range?(@character, @source, @distancemax) self.opacity=0 return end super if @tile_id != @character.tile_id or @character_name != @character.character_name or @character_hue != @character.character_hue @tile_id = @character.tile_id @character_name = @character.character_name @character_hue = @character.character_hue if @tile_id >= 384 self.bitmap.dispose if self.bitmap self.bitmap = RPG::Cache.tile(@character.map.tileset_name, @tile_id, @character.character_hue) self.src_rect.set(0, 0, 32, 32) @ch=32 @cw=32 self.ox = 16 self.oy = 32 else self.bitmap.dispose if self.bitmap self.bitmap = RPG::Cache.character(@character.character_name, @character.character_hue) @cw = bitmap.width / 4 @ch = bitmap.height / 4 self.ox = @cw / 2 self.oy = @ch end end self.visible = (not @character.transparent) if @tile_id == 0 sx = @character.pattern * @cw sy = (@character.direction - 2) / 2 * @ch if self.angle>90 or angle<-90 if @character.direction== 6 sy = ( 4- 2) / 2 * @ch end if @character.direction== 4 sy = ( 6- 2) / 2 * @ch end if @character.direction== 2 sy = ( 8- 2) / 2 * @ch end if @character.direction== 8 sy = ( 2- 2) / 2 * @ch end end self.src_rect.set(sx, sy, @cw, @ch) end self.x = ScreenPosHelper.pbScreenX(@character) self.y = ScreenPosHelper.pbScreenY(@character)-5 self.z = ScreenPosHelper.pbScreenZ(@character,@ch)-1 self.zoom_x = ScreenPosHelper.pbScreenZoomX(@character) self.zoom_y = ScreenPosHelper.pbScreenZoomY(@character) self.blend_type = @character.blend_type self.bush_depth = @character.bush_depth if @character.animation_id != 0 animation = $data_animations[@character.animation_id] animation(animation, true) @character.animation_id = 0 end @deltax=ScreenPosHelper.pbScreenX(@source)-self.x @deltay=ScreenPosHelper.pbScreenY(@source)-self.y self.color = Color.new(0, 0, 0) @distance = ((@deltax ** 2) + (@deltay ** 2)) self.opacity = @self_opacity*13000/((@distance*370/@distancemax)+6000) self.angle = 57.3*Math.atan2(@deltax, @deltay ) @angle_trigo=self.angle+90 if @angle_trigo<0 @angle_trigo=360+@angle_trigo end if @anglemin !=0 or @anglemax !=0 if (@angle_trigo<@anglemin or @angle_trigo>@anglemax) and @anglemin<@anglemax self.opacity=0 return end if (@angle_trigo<@anglemin and @angle_trigo>@anglemax) and @anglemin>@anglemax self.opacity=0 return end end end def in_range?(element, object, range)# From Near's Anti Lag Script, edited elemScreenX=ScreenPosHelper.pbScreenX(element) objScreenX=ScreenPosHelper.pbScreenX(object) elemScreenY=ScreenPosHelper.pbScreenY(element) objScreenY=ScreenPosHelper.pbScreenY(object) x = (elemScreenX - objScreenX) * (elemScreenX - objScreenX) y = (elemScreenY - objScreenY) * (elemScreenY - objScreenY) r = x + y if r <= (range * range) return true else return false end end end #=================================================== # ? CLASS Sprite_Character edit #=================================================== class Sprite_Character < RPG::Sprite alias shadow_initialize initialize def initialize(viewport, character = nil) super(viewport) @ombrelist=[] @character = character shadow_initialize(viewport, @character) end def setShadows(map,shadows) if character.is_a?(Game_Event) and shadows.length>0 params = XPML_read(map,"Shadow",@character,4) if params!=nil for i in 0...shadows.size @ombrelist.push(Sprite_Shadow.new( viewport, @character,shadows[i] )) end end end if character.is_a?(Game_Player) and shadows.length>0 for i in 0...shadows.size @ombrelist.push(Sprite_Shadow.new( viewport, $game_player,shadows[i] )) end end update end alias shadow_update update def update shadow_update if @ombrelist.length>0 for i in 0...@ombrelist.size @ombrelist[i].update end end end end #=================================================== # ? CLASS Game_Event edit #=================================================== class Game_Event attr_accessor :id end #=================================================== # ? CLASS Spriteset_Map edit #=================================================== class Spriteset_Map attr_accessor :shadows alias shadow_initialize initialize def initialize(map=nil) @shadows=[] warn=false map=$game_map if !map for k in map.events.keys.sort warn=true if (map.events[k].list!=nil and map.events[k].list[0].code == 108 and (map.events[k].list[0].parameters == ["s"] or map.events[k].list[0].parameters == ["o"])) params = XPML_read(map,"Shadow Source",map.events[k],4) @shadows.push([map.events[k]]+params) if params!=nil end if warn == true and SHADOW_WARN p "Warning : At least one event on this map uses the obsolete way to add shadows" end shadow_initialize(map) for sprite in @character_sprites sprite.setShadows(map,@shadows) end end end #=================================================== # ? XPML Definition, by Rataime, using ideas from Near Fantastica # # Returns nil if the markup wasn't present at all, # returns [] if there wasn't any parameters, else # returns a parameters list with "int" converted as int # eg : # begin first # begin second # param1 1 # param2 two # begin third # anything 3 # # p XPML_read("first", event_id) -> [] # p XPML_read("second", event_id) -> [1,"two"] # p XPML_read("third", event_id) -> [3] # p XPML_read("forth", event_id) -> nil #=================================================== def XPML_read(map,markup,event,max_param_number=0) parameter_list = nil return nil if !event || event.list==nil for i in 0...event.list.size if event.list[i].code == 108 and event.list[i].parameters[0].downcase == "begin "+markup.downcase parameter_list = [] if parameter_list == nil for j in i+1...event.list.size if event.list[j].code == 108 parts = event.list[j].parameters[0].split if parts.size!=1 and parts[0].downcase!="begin" if parts[1].to_i!=0 or parts[1]=="0" parameter_list.push(parts[1].to_i) else parameter_list.push(parts[1]) end else return parameter_list end else return parameter_list end return parameter_list if max_param_number!=0 and j==i+max_param_number end end end return parameter_list end
Audio
[
Selecionar
] [
-
]
class Thread def Thread.exclusive _old = Thread.critical begin Thread.critical = true return yield ensure Thread.critical = _old end end end class AudioContext attr_reader :context def initialize init = Win32API.new("audio.dll", "AudioContextInitialize", '', 'l') @context=init.call() end def dispose if @context!=0 init = Win32API.new("audio.dll", "AudioContextFree", 'l', '') init.call(context) @context=0 end end end ##################################### # Needed because RGSS doesn't call at_exit procs on exit # Exit is not called when game is reset (using F12) $AtExitProcs=[] if !$AtExitProcs def exit(code=0) for p in $AtExitProcs p.call end raise SystemExit.new(code) end def at_exit(&block) $AtExitProcs.push(Proc.new(&block)) end ##################################### module AudioState w32_LL = Win32API.new("kernel32.dll", "LoadLibrary", 'p', 'l') w32_FL = Win32API.new("kernel32.dll", "FreeLibrary", 'p', 'l') if FileTest.exist?("audio.dll") @handle = w32_LL.call("audio.dll") at_exit { w32_FL.call(@handle) } AudioContextIsActive=Win32API.new("audio.dll","AudioContextIsActive","l","l") AudioContextPlay=Win32API.new("audio.dll","AudioContextPlay","lpllll","") AudioContextStop=Win32API.new("audio.dll","AudioContextStop","l","") AudioContextFadeOut=Win32API.new("audio.dll","AudioContextFadeOut","ll","") AudioContextGetPosition=Win32API.new("audio.dll","AudioContextGetPosition","l","l") AudioContextFadeIn=Win32API.new("audio.dll","AudioContextFadeIn","ll","") AudioContextSetVolume=Win32API.new("audio.dll","AudioContextSetVolume","ll","") # AudioContextMute=Win32API.new("audio.dll","AudioContextMute","ll","") # AudioContextUnmute=Win32API.new("audio.dll","AudioContextUnmute","ll","") AudioContextSEPlay=Win32API.new("audio.dll","AudioContextSEPlay","lplll","") if !@MEContext @MEContext=AudioContext.new at_exit { @MEContext.dispose } end if !@BGMContext @BGMContext=AudioContext.new at_exit { @BGMContext.dispose } end if !@BGSContext @BGSContext=AudioContext.new at_exit { @BGSContext.dispose } end if !@SEContext @SEContext=AudioContext.new at_exit { @SEContext.dispose } end else AudioContextIsActive=nil AudioContextPlay=nil AudioContextStop=nil AudioContextFadeOut=nil AudioContextGetPosition=nil AudioContextFadeIn=nil AudioContextSetVolume=nil AudioContextSEPlay=nil end @channel=nil @bgm=nil @name="" @pitch=100 @bgmVolume=100.0 @meVolume=100.0 @bgsVolume=100.0 @seVolume=100.0 def self.setWaitingBGM(bgm,volume,pitch,position) @waitingBGM=[bgm,volume,pitch,position] end def self.bgmActive? return (AudioContextIsActive.call(@BGMContext.context)!=0) end def self.meActive? return (AudioContextIsActive.call(@MEContext.context)!=0) end def self.waitingBGM; @waitingBGM; end def self.context; @BGMContext.context; end def self.meContext; @MEContext.context; end def self.bgsContext; @BGSContext.context; end def self.seContext; @SEContext.context; end def self.system; @system; end def self.bgm; @bgm; end def self.name; @name; end def self.pitch; @pitch; end def self.volume; @volume; end def self.waitingBGM=(value); Thread.exclusive { @waitingBGM=value; } end def self.volume=(value); @volume=value; end def self.bgm=(value); @bgm=value; end def self.name=(value); @name=value; end def self.pitch=(value); @pitch=value; end end def Audio_bgm_playing? AudioState.channel!=nil end def Audio_bgm_name AudioState.name end def Audio_bgm_pitch AudioState.pitch end def Audio_bgm_play(name, volume, pitch, position = 0) volume=0 if !getPlayMusic() begin filename = canonicalize(rtpGetPath(name,[".mid",".mp3",".wma",".ogg",".wav",""])) if AudioState.meActive? AudioState.setWaitingBGM(filename,volume,pitch,position) return end AudioState::AudioContextPlay.call(AudioState.context,filename,volume,pitch,position,1) AudioState.name=filename AudioState.volume=volume AudioState.pitch=pitch rescue Hangup rescue p $!.message,$!.backtrace end end def Audio_me_play(name, volume, pitch, position = 0) volume=0 if !getPlayMusic() begin filename = canonicalize(rtpGetPath(name,[".mid",".mp3",".wma",".ogg",".wav",""])) if AudioState.bgmActive? bgmPosition=Kernel.Audio_bgm_get_position AudioState.setWaitingBGM( AudioState.name, AudioState.volume, AudioState.pitch, bgmPosition ) AudioState::AudioContextStop.call(AudioState.context) end AudioState::AudioContextPlay.call(AudioState.meContext,filename,volume,pitch,position,0) rescue p $!.message,$!.backtrace end end def Audio_me_fade(ms) AudioState::AudioContextFadeOut.call(AudioState.meContext,ms) end def Audio_me_stop() AudioState::AudioContextStop.call(AudioState.meContext) end def Audio_bgm_stop() begin AudioState::AudioContextStop.call(AudioState.context) AudioState.waitingBGM=nil AudioState.name = "" rescue p $!.message,$!.backtrace end end def Audio_bgm_get_position return AudioState::AudioContextGetPosition.call(AudioState.context) end def Audio_bgm_fade(ms) AudioState::AudioContextFadeOut.call(AudioState.context,ms.to_i) end def Audio_bgm_fadein(ms) AudioState::AudioContextFadeIn.call(AudioState.context,ms.to_i) end def Audio_bgm_get_volume return 0 if !AudioState.bgmActive? return AudioState.volume end def Audio_bgm_set_volume(volume) return if !AudioState.bgmActive? AudioState.volume = volume * 1.0 AudioState::AudioContextSetVolume.call(AudioState.context,volume.to_i) end def Audio_bgm_mute AudioState::AudioContextMute.call(AudioState.context,300) end def Audio_me_mute AudioState::AudioContextMute.call(AudioState.meContext,300) end def Audio_bgs_mute AudioState::AudioContextMute.call(AudioState.bgsContext,300) end def Audio_se_mute AudioState::AudioContextMute.call(AudioState.seContext,300) end def Audio_bgm_unmute AudioState::AudioContextUnmute.call(AudioState.context,300) end def Audio_me_unmute AudioState::AudioContextUnmute.call(AudioState.meContext,300) end def Audio_bgs_unmute AudioState::AudioContextUnmute.call(AudioState.bgsContext,300) end def Audio_se_unmute AudioState::AudioContextUnmute.call(AudioState.seContext,300) end def Audio_bgs_play(name, volume, pitch, position = 0) volume=0 if !getPlaySound() begin filename = canonicalize(rtpGetPath(name,[".mid",".mp3",".wma",".ogg",".wav",""])) AudioState::AudioContextPlay.call(AudioState.bgsContext,filename,volume,pitch,position,0) rescue p $!.message,$!.backtrace end end def Audio_bgs_fade(ms) AudioState::AudioContextFadeOut.call(AudioState.bgsContext,ms) end def Audio_bgs_stop() AudioState::AudioContextStop.call(AudioState.bgsContext) end def Audio_se_play(name, volume, pitch, position = 0) volume=0 if !getPlaySound() begin filename = canonicalize(rtpGetPath(name,[".mid",".mp3",".wma",".ogg",".wav",""])) AudioState::AudioContextSEPlay.call(AudioState.seContext,filename,volume,pitch,position) rescue p $!.message,$!.backtrace end end def Audio_se_stop() AudioState::AudioContextStop.call(AudioState.seContext) end #################################################### if FileTest.exist?("audio.dll") module Graphics if !defined?(audiomodule_update) class << self alias audiomodule_update update end end def self.update Audio.update audiomodule_update end end module Audio @@musicstate=nil @@soundstate=nil def self.update return if Graphics.frame_count%10!=0 =begin pm=getPlayMusic() ps=getPlaySound() if @@musicstate!=false && !pm @@musicstate=false Kernel.Audio_bgm_mute Kernel.Audio_me_mute elsif @@musicstate!=true && pm @@musicstate=true Kernel.Audio_bgm_unmute Kernel.Audio_me_unmute end if @@soundstate!=false && !ps @@soundstate=false Kernel.Audio_bgs_mute Kernel.Audio_se_mute elsif @@soundstate!=true && ps @@musicstate=true Kernel.Audio_bgs_unmute Kernel.Audio_se_unmute end =end if AudioState.waitingBGM && !AudioState.meActive? waitbgm=AudioState.waitingBGM AudioState.waitingBGM=nil bgm_play(waitbgm[0],waitbgm[1],waitbgm[2],waitbgm[3]) end end def self.bgm_play(name,volume=80,pitch=100,position=nil) begin if position==nil || position==0 Kernel.Audio_bgm_play(name,volume,pitch,0) else Kernel.Audio_bgm_play(name,volume,pitch,position) Kernel.Audio_bgm_fadein(500) end rescue Hangup bgm_play(name,volume,pitch,position) end end def self.bgm_fade(ms) Kernel.Audio_bgm_fade(ms) end def self.bgm_stop Kernel.Audio_bgm_stop() end def self.bgm_position ret=Kernel.Audio_bgm_get_position return ret end def self.me_play(name,volume=80,pitch=100) Kernel.Audio_me_play(name,volume,pitch,0) end def self.me_fade(ms) Kernel.Audio_me_fade(ms) end def self.me_stop Kernel.Audio_me_stop() end def self.bgs_play(name,volume=80,pitch=100) Kernel.Audio_bgs_play(name,volume,pitch,0) end def self.bgs_fade(ms) Kernel.Audio_bgs_fade(ms) end def self.bgs_stop Kernel.Audio_bgs_stop() end =begin def self.se_play(name,volume=80,pitch=100) Kernel.Audio_se_play(name,volume,pitch,0) end def self.se_stop Kernel.Audio_se_stop() end =end end class Game_System def bgm_pause(fadetime=0.0) pos=Audio.bgm_position if fadetime>0.0 bgm_fade(fadetime) end @bgm_position=pos end def bgs_pause(fadetime=0.0) if fadetime>0.0 bgs_fade(fadetime) else bgs_stop end end def bgm_unpause; @bgm_position=0; end def bgs_unpause; ; end def bgs_resume(bgm,volume=80,pitch=100); bgs_play(bgm,volume,pitch) end def bgm_resume(bgm,volume=80,pitch=100); bgm_play(bgm,volume,pitch,@bgm_position) @bgm_position=0 end def bgs_resume(bgm,volume=80,pitch=100); bgs_play(bgm,volume,pitch) end end ########### else ########### module Audio if !defined?(oldbgm_play) class << self alias oldbgm_play bgm_play end end def self.bgm_play(*arg) oldbgm_play(arg[0],arg[1]?arg[1]:80,arg[2]?arg[2]:100) end def self.bgm_position; 0; end end class Game_System def bgm_pause(fadetime=0.0) if fadetime>0.0 bgm_fade(fadetime) else bgm_stop end end def bgs_pause(fadetime=0.0) if fadetime>0.0 bgs_fade(fadetime) else bgs_stop end end def bgm_unpause; ; end def bgs_unpause; ; end def bgm_resume(*arg); bgm_play(*arg); end def bgs_resume(*arg); bgs_play(*arg); end end end
RTPandRegistry
[
Selecionar
] [
-
]
module Win32 class Registry module Constants HKEY_CLASSES_ROOT = 0x80000000 HKEY_CURRENT_USER = 0x80000001 HKEY_LOCAL_MACHINE = 0x80000002 HKEY_USERS = 0x80000003 HKEY_PERFORMANCE_DATA = 0x80000004 HKEY_PERFORMANCE_TEXT = 0x80000050 HKEY_PERFORMANCE_NLSTEXT = 0x80000060 HKEY_CURRENT_CONFIG = 0x80000005 HKEY_DYN_DATA = 0x80000006 REG_NONE = 0 REG_SZ = 1 REG_EXPAND_SZ = 2 REG_BINARY = 3 REG_DWORD = 4 REG_DWORD_LITTLE_ENDIAN = 4 REG_DWORD_BIG_ENDIAN = 5 REG_LINK = 6 REG_MULTI_SZ = 7 REG_RESOURCE_LIST = 8 REG_FULL_RESOURCE_DESCRIPTOR = 9 REG_RESOURCE_REQUIREMENTS_LIST = 10 REG_QWORD = 11 REG_QWORD_LITTLE_ENDIAN = 11 STANDARD_RIGHTS_READ = 0x00020000 STANDARD_RIGHTS_WRITE = 0x00020000 KEY_QUERY_VALUE = 0x0001 KEY_SET_VALUE = 0x0002 KEY_CREATE_SUB_KEY = 0x0004 KEY_ENUMERATE_SUB_KEYS = 0x0008 KEY_NOTIFY = 0x0010 KEY_CREATE_LINK = 0x0020 KEY_READ = STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY KEY_WRITE = STANDARD_RIGHTS_WRITE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY KEY_EXECUTE = KEY_READ KEY_ALL_ACCESS = KEY_READ | KEY_WRITE | KEY_CREATE_LINK REG_OPTION_RESERVED = 0x0000 REG_OPTION_NON_VOLATILE = 0x0000 REG_OPTION_VOLATILE = 0x0001 REG_OPTION_CREATE_LINK = 0x0002 REG_OPTION_BACKUP_RESTORE = 0x0004 REG_OPTION_OPEN_LINK = 0x0008 REG_LEGAL_OPTION = REG_OPTION_RESERVED | REG_OPTION_NON_VOLATILE | REG_OPTION_CREATE_LINK | REG_OPTION_BACKUP_RESTORE | REG_OPTION_OPEN_LINK REG_CREATED_NEW_KEY = 1 REG_OPENED_EXISTING_KEY = 2 REG_WHOLE_HIVE_VOLATILE = 0x0001 REG_REFRESH_HIVE = 0x0002 REG_NO_LAZY_FLUSH = 0x0004 REG_FORCE_RESTORE = 0x0008 MAX_KEY_LENGTH = 514 MAX_VALUE_LENGTH = 32768 end include Constants include Enumerable class Error < ::StandardError FormatMessageA=Win32API.new('kernel32.dll','FormatMessageA','LPLLPLP','L') def initialize(code) @code = code msg = "\\0" * 1024 len = FormatMessageA.call(0x1200, 0, code, 0, msg, 1024, 0) super msg[0, len].tr("\\r", '').chomp end attr_reader :code end class PredefinedKey < Registry def initialize(hkey, keyname) @hkey = hkey @parent = nil @keyname = keyname @disposition = REG_OPENED_EXISTING_KEY end def close raise Error.new(5) end def class Registry end Constants.constants.grep(/^HKEY_/) do |c| Registry.const_set c, new(Constants.const_get(c), c) end end module API [ %w/RegOpenKeyExA LPLLP L/, %w/RegCreateKeyExA LPLLLLPPP L/, %w/RegEnumValueA LLPPPPPP L/, %w/RegEnumKeyExA LLPPLLLP L/, %w/RegQueryValueExA LPLPPP L/, %w/RegSetValueExA LPLLPL L/, %w/RegFlushKey L L/, %w/RegCloseKey L L/, %w/RegQueryInfoKey LPPPPPPPPPPP L/, ].each do |fn| const_set fn[0].intern, Win32API.new('advapi32.dll', *fn) end module_function def check(result) raise Error, result, caller(2) if result != 0 end def packdw(dw) [dw].pack('V') end def unpackdw(dw) dw += [0].pack('V') dw.unpack('V')[0] end def packqw(qw) [ qw & 0xFFFFFFFF, qw >> 32 ].pack('VV') end def unpackqw(qw) qw = qw.unpack('VV') (qw[1] << 32) | qw[0] end def OpenKey(hkey, name, opt, desired) result = packdw(0) check RegOpenKeyExA.call(hkey, name, opt, desired, result) unpackdw(result) end def CreateKey(hkey, name, opt, desired) result = packdw(0) disp = packdw(0) check RegCreateKeyExA.call(hkey, name, 0, 0, opt, desired, 0, result, disp) [ unpackdw(result), unpackdw(disp) ] end def EnumValue(hkey, index) name = ' ' * Constants::MAX_KEY_LENGTH size = packdw(Constants::MAX_KEY_LENGTH) check RegEnumValueA.call(hkey, index, name, size, 0, 0, 0, 0) name[0, unpackdw(size)] end def EnumKey(hkey, index) name = ' ' * Constants::MAX_KEY_LENGTH size = packdw(Constants::MAX_KEY_LENGTH) wtime = ' ' * 8 check RegEnumKeyExA.call(hkey, index, name, size, 0, 0, 0, wtime) [ name[0, unpackdw(size)], unpackqw(wtime) ] end def QueryValue(hkey, name) type = packdw(0) size = packdw(0) check RegQueryValueExA.call(hkey, name, 0, type, 0, size) data = ' ' * unpackdw(size) check RegQueryValueExA.call(hkey, name, 0, type, data, size) [ unpackdw(type), data[0, unpackdw(size)] ] end def SetValue(hkey, name, type, data, size) check RegSetValueExA.call(hkey, name, 0, type, data, size) end def FlushKey(hkey) check RegFlushKey.call(hkey) end def CloseKey(hkey) check RegCloseKey.call(hkey) end def QueryInfoKey(hkey) subkeys = packdw(0) maxsubkeylen = packdw(0) values = packdw(0) maxvaluenamelen = packdw(0) maxvaluelen = packdw(0) secdescs = packdw(0) wtime = ' ' * 8 check RegQueryInfoKey.call(hkey, 0, 0, 0, subkeys, maxsubkeylen, 0, values, maxvaluenamelen, maxvaluelen, secdescs, wtime) [ unpackdw(subkeys), unpackdw(maxsubkeylen), unpackdw(values), unpackdw(maxvaluenamelen), unpackdw(maxvaluelen), unpackdw(secdescs), unpackqw(wtime) ] end end def self.expand_environ(str) str.gsub(/%([^%]+)%/) { ENV[$1] || $& } end @@type2name = { } %w[ REG_NONE REG_SZ REG_EXPAND_SZ REG_BINARY REG_DWORD REG_DWORD_BIG_ENDIAN REG_LINK REG_MULTI_SZ REG_RESOURCE_LIST REG_FULL_RESOURCE_DESCRIPTOR REG_RESOURCE_REQUIREMENTS_LIST REG_QWORD ].each do |type| @@type2name[Constants.const_get(type)] = type end def self.type2name(type) @@type2name[type] || type.to_s end def self.wtime2time(wtime) Time.at((wtime - 116444736000000000) / 10000000) end def self.time2wtime(time) time.to_i * 10000000 + 116444736000000000 end private_class_method :new def self.open(hkey, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED) subkey = subkey.chomp('\\\\') begin newkey = API.OpenKey(hkey.hkey, subkey, opt, desired) rescue Error return nil end obj = new(newkey, hkey, subkey, REG_OPENED_EXISTING_KEY) if block_given? begin yield obj ensure obj.close end else obj end end def self.create(hkey, subkey, desired = KEY_ALL_ACCESS, opt = 0x0000) newkey, disp = API.CreateKey(hkey.hkey, subkey, opt, desired) obj = new(newkey, hkey, subkey, disp) if block_given? begin yield obj ensure obj.close end else obj end end @@final = proc { |hkey| proc { API.CloseKey(hkey[0]) if hkey[0] } } def initialize(hkey, parent, keyname, disposition) @hkey = hkey @parent = parent @keyname = keyname @disposition = disposition @hkeyfinal = [ hkey ] ObjectSpace.define_finalizer self, @@final.call(@hkeyfinal) end attr_reader :hkey, :parent, :keyname, :disposition def created? @disposition == REG_CREATED_NEW_KEY end def open? !@hkey.nil? end def name parent = self name = @keyname while parent = parent.parent name = parent.keyname + '\\\\' + name end name end def inspect "\\#<Win32::Registry key=#{name.inspect}>" end def _dump(depth) raise TypeError, "can't dump Win32::Registry" end def open(subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED, &blk) self.class.open(self, subkey, desired, opt, &blk) end def create(subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED, &blk) self.class.create(self, subkey, desired, opt, &blk) end def close API.CloseKey(@hkey) @hkey = @parent = @keyname = nil @hkeyfinal[0] = nil end def each_value index = 0 while true begin subkey = API.EnumValue(@hkey, index) rescue Error break end begin type, data = read(subkey) rescue Error next end yield subkey, type, data index += 1 end index end alias each each_value def each_key index = 0 while true begin subkey, wtime = API.EnumKey(@hkey, index) rescue Error break end yield subkey, wtime index += 1 end index end def keys keys_ary = [] each_key { |key,| keys_ary << key } keys_ary end def read(name, *rtype) type, data = API.QueryValue(@hkey, name) unless rtype.empty? or rtype.include?(type) string = "Type mismatch (expect #{rtype.inspect} but #{type} present)" raise TypeError, string end case type when REG_SZ, REG_EXPAND_SZ [ type, data.chop ] when REG_MULTI_SZ [ type, data.split(/\\0/) ] when REG_BINARY [ type, data ] when REG_DWORD [ type, API.unpackdw(data) ] when REG_DWORD_BIG_ENDIAN [ type, data.unpack('N')[0] ] when REG_QWORD [ type, API.unpackqw(data) ] else raise TypeError, "Type #{type} is not supported." end end def [](name, *rtype) type, data = read(name, *rtype) case type when REG_SZ, REG_DWORD, REG_QWORD, REG_MULTI_SZ data when REG_EXPAND_SZ Registry.expand_environ(data) else raise TypeError, "Type #{type} is not supported." end end def read_s(name) read(name, REG_SZ)[1] end def read_s_expand(name) type, data = read(name, REG_SZ, REG_EXPAND_SZ) if type == REG_EXPAND_SZ Registry.expand_environ(data) else data end end def read_i(name) read(name, REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_QWORD)[1] end def read_bin(name) read(name, REG_BINARY)[1] end def write(name, type, data) case type when REG_SZ, REG_EXPAND_SZ data = data.to_s + "\\0" when REG_MULTI_SZ data = data.to_a.join("\\0") + "\\0\\0" when REG_BINARY data = data.to_s when REG_DWORD data = API.packdw(data.to_i) when REG_DWORD_BIG_ENDIAN data = [data.to_i].pack('N') when REG_QWORD data = API.packqw(data.to_i) else raise TypeError, "Unsupported type #{type}" end API.SetValue(@hkey, name, type, data, data.length) end def []=(name, rtype, value = nil) if value write name, rtype, value else case value = rtype when Integer write name, REG_DWORD, value when String write name, REG_SZ, value when Array write name, REG_MULTI_SZ, value else raise TypeError, "Unexpected type #{value.class}" end end value end def write_s(name, value) write name, REG_SZ, value.to_s end def write_i(name, value) write name, REG_DWORD, value.to_i end def write_bin(name, value) write name, REG_BINARY, value.to_s end def flush API.FlushKey @hkey end def info API.QueryInfoKey(@hkey) end %w[ num_keys max_key_length num_values max_value_name_length max_value_length descriptor_length wtime ].each_with_index do |s, i| eval <<-__END__ def #{s} info[#{i}] end __END__ end end end def getExistingPath(file,extensions=[]) return file if FileTest.exist?(file) if extensions for ext in extensions fullfile=file+ext return fullfile if FileTest.exist?(fullfile) end end return nil end def rtpGetDirectory(key,rtpname) rtp=Win32API.GetPrivateProfileString("Game",rtpname) return nil if !rtp || rtp=="" begin path=key.read_s(rtp) if path && path!="" return path end return nil rescue return nil end end def rtpGetPathHelper(key,rtpname,file,extensions) path=rtpGetDirectory(key,rtpname) return path ? getExistingPath(path+"\\\\"+file,extensions) : nil end def chdirRTP(rtpname) Win32::Registry.open( Win32::Registry::HKEY_LOCAL_MACHINE,"SOFTWARE\\\\Enterbrain\\\\RGSS\\\\RTP"){|key| path=rtpGetDirectory(key,rtpname) if path && path!="" if block_given? Dir.chdir(path){ yield } else Dir.chdir(path) end end } end def rtpGetPath(file,extensions=[]) path=getExistingPath(file,extensions) if !path Win32::Registry.open( Win32::Registry::HKEY_LOCAL_MACHINE,"SOFTWARE\\\\Enterbrain\\\\RGSS\\\\RTP"){|key| path=rtpGetPathHelper(key,"RTP1",file,extensions) path=rtpGetPathHelper(key,"RTP2",file,extensions) if !path path=rtpGetPathHelper(key,"RTP3",file,extensions) if !path } end return path end def getPlayMusic begin ret=true Win32::Registry.open( Win32::Registry::HKEY_CURRENT_USER,"SOFTWARE\\\\Enterbrain\\\\RGSS"){|key| ret=(key["PlayMusic"] == 1) } return ret rescue return true end end def getPlaySound begin ret=true Win32::Registry.open( Win32::Registry::HKEY_CURRENT_USER,"SOFTWARE\\\\Enterbrain\\\\RGSS"){|key| ret=(key["PlaySound"] == 1) } return ret rescue p $!.message,$!.class.name return true end end def getButtonAssign begin Win32::Registry.open( Win32::Registry::HKEY_CURRENT_USER,"SOFTWARE\\\\Enterbrain\\\\RGSS"){|key| return key.read_bin("ButtonAssign") } rescue p $!.message,$!.class.name return nil end end module FileTest Image_ext = ['.bmp', '.png', '.jpg', '.jpeg'] Audio_ext = ['.mp3', '.mid', '.midi', '.ogg', '.wav', '.wma'] def self.audio_exist?(filename) return !rtpGetPath(filename,Audio_ext).nil? end def self.image_exist?(filename) return !rtpGetPath(filename,Image_ext).nil? end end
StringIO
[
Selecionar
] [
-
]
#31931740 # # stringio.rb # # Copyright (c) 1999-2003 Minero Aoki <aamine@loveruby.net> # # This program is free software. # You can distribute/modify this program under the terms of # the GNU Lesser General Public License version 2 or later. # # Id: stringio.rb,v 1.10 2003/04/27 22:02:14 aamine Exp # class StringInput#:nodoc: include Enumerable class << self def new( str ) if block_given? begin f = super yield f ensure f.close if f end else super end end alias open new end def initialize( str ) @src = str @pos = 0 @closed = false @lineno = 0 end attr_reader :lineno def string @src end def inspect "#<#{self.class}:#{@closed ? 'closed' : 'open'},src=#{@src[0,30].inspect}>" end def close stream_check! @pos = nil @closed = true end def closed? @closed end def pos stream_check! [@pos, @src.size].min end alias tell pos def seek( offset, whence = IO::SEEK_SET ) stream_check! case whence when IO::SEEK_SET @pos = offset when IO::SEEK_CUR @pos += offset when IO::SEEK_END @pos = @src.size - offset else raise ArgumentError, "unknown seek flag: #{whence}" end @pos = 0 if @pos < 0 @pos = [@pos, @src.size + 1].min offset end def rewind stream_check! @pos = 0 end def eof? stream_check! @pos > @src.size end def each( &block ) stream_check! begin @src.each(&block) ensure @pos = 0 end end def gets stream_check! if idx = @src.index(?\\n, @pos) idx += 1 # "\\n".size line = @src[ @pos ... idx ] @pos = idx @pos += 1 if @pos == @src.size else line = @src[ @pos .. -1 ] @pos = @src.size + 1 end @lineno += 1 line end def getc stream_check! ch = @src[@pos] @pos += 1 @pos += 1 if @pos == @src.size ch end def read( len = nil ) stream_check! return read_all unless len str = @src[@pos, len] @pos += len @pos += 1 if @pos == @src.size str end alias sysread read def read_all stream_check! return nil if eof? rest = @src[@pos ... @src.size] @pos = @src.size + 1 rest end def stream_check! @closed and raise IOError, 'closed stream' end end class StringOutput#:nodoc: class << self def new( str = '' ) if block_given? begin f = super yield f ensure f.close if f end else super end end alias open new end def initialize( str = '' ) @dest = str @closed = false end def close @closed = true end def closed? @closed end def string @dest end alias value string alias to_str string def size @dest.size end alias pos size def inspect "#<#{self.class}:#{@dest ? 'open' : 'closed'},#{id}>" end def print( *args ) stream_check! raise ArgumentError, 'wrong # of argument (0 for >1)' if args.empty? args.each do |s| raise ArgumentError, 'nil not allowed' if s.nil? @dest << s.to_s end nil end def puts( *args ) stream_check! args.each do |str| @dest << (s = str.to_s) @dest << "\\n" unless s[-1] == ?\\n end @dest << "\\n" if args.empty? nil end def putc( ch ) stream_check! @dest << ch.chr nil end def printf( *args ) stream_check! @dest << sprintf(*args) nil end def write( str ) stream_check! s = str.to_s @dest << s s.size end alias syswrite write def <<( str ) stream_check! @dest << str.to_s self end private def stream_check! @closed and raise IOError, 'closed stream' end end
SpriteResize
[
Selecionar
] [
-
]
#---------------------------------------- # # Overriding Sprite, Viewport, and Plane to support resizing # By Peter O. # #---------------------------------------- module Graphics ## Nominal screen size @@width=480 @@height=320 ############## def self.width return @@width.to_i end def self.height return @@height.to_i end @@fadeoutvp=Viewport.new(0,0,640,480) @@fadeoutvp.z=0x3FFFFFFF @@fadeoutvp.color=Color.new(0,0,0,0) def self.brightness return (255-@@fadeoutvp.color.alpha) end def self.brightness=(value) value=0 if value<0 value=255 if value>255 @@fadeoutvp.color.alpha=255-value end def self.fadein(frames) return if frames<=0 curvalue=self.brightness count=(255-self.brightness) frames.times do |i| self.brightness=curvalue+(count*i/frames) self.update end end def self.wait(frames) return if frames<=0 frames.times do |i| self.update end end def self.fadeout(frames) return if frames<=0 curvalue=self.brightness count=self.brightness frames.times do |i| self.brightness=curvalue-(count*i/frames) self.update end end class << self begin x=@@haveresizescreen rescue NameError # If exception is caught, # the class variable wasn't defined yet if !method_defined?(:oldresizescreen) begin alias oldresizescreen resize_screen @@haveresizescreen=true rescue @@haveresizescreen=false end else @@haveresizescreen=false end end def haveresizescreen @@haveresizescreen end end def self.resize_screen(w,h) @@width=w @@height=h pbSetResizeFactor($ResizeFactor) end @@deletefailed=false def self.snap_to_bitmap if FileTest.exist?("./tempscreen.bmp") && @@deletefailed begin File.delete("./tempscreen.bmp") @@deletefailed=false rescue Errno::EACCES @@deletefailed=true return nil end end if FileTest.exist?("./rubyscreen.dll") takescreen=Win32API.new("rubyscreen.dll","TakeScreenshot","%w(p)","i") takescreen.call("./tempscreen.bmp") end bm=nil if FileTest.exist?("./tempscreen.bmp") bm=Bitmap.new("./tempscreen.bmp") begin File.delete("./tempscreen.bmp") @@deletefailed=false rescue Errno::EACCES @@deletefailed=true end end if bm && $ResizeOffsetX && $ResizeOffsetY && $ResizeOffsetX!=0 || $ResizeOffsetY!=0 tmpbitmap=Bitmap.new( Graphics.width*$ResizeFactor, Graphics.height*$ResizeFactor) tmpbitmap.blt(0,0,bm, Rect.new($ResizeOffsetX*$ResizeFactor, $ResizeOffsetY*$ResizeFactor, tmpbitmap.width,tmpbitmap.height)) bm.dispose bm=tmpbitmap end if bm && (bm.width<Graphics.width || bm.height<Graphics.height) newbitmap=Bitmap.new(Graphics.width,Graphics.height) newbitmap.stretch_blt(newbitmap.rect, bm,Rect.new(0,0,bm.width,bm.height)) bm.dispose bm=newbitmap end return bm end end $ResizeFactor=1.0 $ResizeFactorMul=100 $ResizeOffsetX=0 $ResizeOffsetY=0 def pbSetResizeFactor(factor) if $ResizeFactor!=factor $ResizeFactor=factor $ResizeFactorMul=(factor*100).to_i ObjectSpace.each_object(Sprite){|o| next if o.disposed? o.x=o.x o.y=o.y o.ox=o.ox o.oy=o.oy o.zoom_x=o.zoom_x o.zoom_y=o.zoom_y } ObjectSpace.each_object(Viewport){|o| begin o.rect=o.rect o.ox=o.ox o.oy=o.oy rescue RGSSError end } ObjectSpace.each_object(Plane){|o| next if o.disposed? o.zoom_x=o.zoom_x o.zoom_y=o.zoom_y } end if $ResizeBorder $ResizeBorder.refresh end begin if Graphics.haveresizescreen Graphics.oldresizescreen( (Graphics.width+$ResizeOffsetX*2)*factor, (Graphics.height+$ResizeOffsetY*2)*factor ) end Win32API.SetWindowPos( (Graphics.width+$ResizeOffsetX*2)*factor, (Graphics.height+$ResizeOffsetY*2)*factor ) rescue end end class Sprite unless @SpriteResizerMethodsAliased alias _initialize_SpriteResizer initialize alias _x_SpriteResizer x alias _y_SpriteResizer y alias _ox_SpriteResizer ox alias _oy_SpriteResizer oy alias _zoomx_SpriteResizer zoom_x alias _zoomy_SpriteResizer zoom_y alias _xeq_SpriteResizer x= alias _yeq_SpriteResizer y= alias _zoomxeq_SpriteResizer zoom_x= alias _zoomyeq_SpriteResizer zoom_y= alias _oxeq_SpriteResizer ox= alias _oyeq_SpriteResizer oy= alias _bushdeptheq_SpriteResizer bush_depth= @SpriteResizerMethodsAliased=true end def initialize(viewport=nil) _initialize_SpriteResizer(viewport) @resizedX=0 @resizedY=0 @resizedOx=0 @resizedOy=0 @resizedBushDepth=0 @resizedZoomX=1.0 @resizedZoomY=1.0 if $ResizeOffsetX!=0 && $ResizeOffsetY!=0 && !viewport _xeq_SpriteResizer($ResizeOffsetX*$ResizeFactorMul/100) _yeq_SpriteResizer($ResizeOffsetY*$ResizeFactorMul/100) end _zoomxeq_SpriteResizer(@resizedZoomX*$ResizeFactorMul/100) _zoomyeq_SpriteResizer(@resizedZoomY*$ResizeFactorMul/100) end def zoom_x return @resizedZoomX end def zoom_x=(val) value=val if $ResizeFactorMul!=100 value=(val.to_f*$ResizeFactorMul/100) if (value-0.50).abs<=0.001 value=0.50 end if (value-1.00).abs<=0.001 value=1.00 end end _zoomxeq_SpriteResizer(value) @resizedZoomX=val end def zoom_y return @resizedZoomY end def zoom_y=(val) value=val if $ResizeFactorMul!=100 value=(val.to_f*$ResizeFactorMul/100) if (value-0.50).abs<=0.001 value=0.50 end if (value-1.00).abs<=0.001 value=1.00 end end _zoomyeq_SpriteResizer(value) @resizedZoomY=val end def x return @resizedX end def x=(val) if $ResizeFactorMul!=100 offset=(self.viewport) ? 0 : $ResizeOffsetX value=((val.to_i+offset)*$ResizeFactorMul/100) _xeq_SpriteResizer(value.to_i) @resizedX=val.to_i elsif self.viewport _xeq_SpriteResizer(val) @resizedX=val else _xeq_SpriteResizer(val + $ResizeOffsetX) @resizedX=val end end def y return @resizedY end def bush_depth=(val) value=((val.to_i)*$ResizeFactorMul/100) _bushdeptheq_SpriteResizer(value.to_i) @resizedBushDepth=val.to_i end def bush_depth return @resizedBushDepth end def y=(val) if $ResizeFactorMul!=100 offset=(self.viewport) ? 0 : $ResizeOffsetY value=((val.to_i+offset)*$ResizeFactorMul/100) _yeq_SpriteResizer(value.to_i) @resizedY=val.to_i elsif self.viewport _yeq_SpriteResizer(val) @resizedY=val else _yeq_SpriteResizer(val + $ResizeOffsetY) @resizedY=val end end def ox=(val) if $ResizeFactor!=1.0 val=(val*$ResizeFactor).to_i val=(val/$ResizeFactor).to_i end @resizedOx=val _oxeq_SpriteResizer(val) end def oy=(val) if $ResizeFactor!=1.0 val=(val*$ResizeFactor).to_i val=(val/$ResizeFactor).to_i end @resizedOy=val _oyeq_SpriteResizer(val) end def ox return @resizedOx end def oy return @resizedOy end end class NotifiableRect < Rect def setNotifyProc(proc) @notifyProc=proc end def set(x,y,width,height) super @notifyProc.call(self) if @notifyProc end def x=(value) super @notifyProc.call(self) if @notifyProc end def y=(value) super @notifyProc.call(self) if @notifyProc end def width=(value) super @notifyProc.call(self) if @notifyProc end def height=(value) super @notifyProc.call(self) if @notifyProc end end class Viewport unless @SpriteResizerMethodsAliased alias _initialize_SpriteResizer initialize alias _rect_ViewportResizer rect alias _recteq_SpriteResizer rect= alias _oxeq_SpriteResizer ox= alias _oyeq_SpriteResizer oy= @SpriteResizerMethodsAliased=true end def initialize(*arg) args=arg.clone @oldrect=Rect.new(0,0,100,100) _initialize_SpriteResizer( @oldrect ) newRect=NotifiableRect.new(0,0,0,0) @resizedRectProc=Proc.new {|r| if $ResizeFactorMul==100 @oldrect.set( r.x.to_i+$ResizeOffsetX, r.y.to_i+$ResizeOffsetY, r.width.to_i, r.height.to_i ) self._recteq_SpriteResizer(@oldrect) else @oldrect.set( ((r.x+$ResizeOffsetX)*$ResizeFactorMul/100).to_i, ((r.y+$ResizeOffsetY)*$ResizeFactorMul/100).to_i, (r.width*$ResizeFactorMul/100).to_i, (r.height*$ResizeFactorMul/100).to_i ) self._recteq_SpriteResizer(@oldrect) end } newRect.setNotifyProc(@resizedRectProc) if arg.length==1 newRect.set( args[0].x,args[0].y,args[0].width,args[0].height) else newRect.set( args[0],args[1],args[2],args[3]) end @resizedRect=newRect @resizedOx=0 @resizedOy=0 end def ox return @resizedOx end def ox=(val) return if !val _oxeq_SpriteResizer((val*$ResizeFactorMul/100).to_i.to_f) @resizedOx=val end def oy return @resizedOy end def oy=(val) return if !val _oyeq_SpriteResizer((val*$ResizeFactorMul/100).to_i.to_f) @resizedOy=val end def rect return @resizedRect end def rect=(val) if val newRect=NotifiableRect.new(0,0,100,100) newRect.setNotifyProc(@resizedRectProc) newRect.set(val.x.to_i,val.y.to_i,val.width.to_i,val.height.to_i) @resizedRect=newRect end end end class Plane unless @SpriteResizerMethodsAliased alias _initialize_SpriteResizer initialize alias _zoomxeq_SpriteResizer zoom_x= alias _zoomyeq_SpriteResizer zoom_y= alias _oxeq_SpriteResizer ox= alias _oyeq_SpriteResizer oy= @SpriteResizerMethodsAliased=true end def initialize(viewport=nil) _initialize_SpriteResizer(viewport) @resizedZoomX=1.0 @resizedZoomY=1.0 @resizedOx=0 @resizedOy=0 _zoomxeq_SpriteResizer(@resizedZoomX*$ResizeFactorMul/100) _zoomyeq_SpriteResizer(@resizedZoomY*$ResizeFactorMul/100) end def ox return @resizedOx end def ox=(val) return if !val _oxeq_SpriteResizer(val*$ResizeFactorMul/100) @resizedOx=val end def oy return @resizedOy end def oy=(val) return if !val _oyeq_SpriteResizer(val*$ResizeFactorMul/100) @resizedOy=val end def zoom_x return @resizedZoomX end def zoom_x=(val) return if !val _zoomxeq_SpriteResizer(val*$ResizeFactorMul/100) @resizedZoomX=val end def zoom_y return @resizedZoomY end def zoom_y=(val) return if !val _zoomyeq_SpriteResizer(val*$ResizeFactorMul/100) @resizedZoomY=val end end ################### class ScreenBorder def initialize @maximumZ=500000 @bordername="" @sprite=Sprite.new @sprite.z=@maximumZ @defaultwidth=640 @defaultheight=480 @defaultbitmap=Bitmap.new(@defaultwidth,@defaultheight) refresh end def dispose @borderbitmap.dispose if @borderbitmap @defaultbitmap.dispose @sprite.dispose end def adjustZ(z) if z>=@maximumZ @maximumZ=z+1 @sprite.z=@maximumZ end end def bordername=(value) @bordername=value refresh end def refresh @sprite.x=-$ResizeOffsetX @sprite.y=-$ResizeOffsetY @sprite.visible=($ResizeOffsetX>0 && $ResizeOffsetY>0) @sprite.bitmap=nil if @sprite.visible if @bordername!=nil && @bordername!="" @borderbitmap.dispose if @borderbitmap @borderbitmap=RPG::Cache.picture(@bordername) @sprite.bitmap=@borderbitmap else @sprite.bitmap=@defaultbitmap end end @defaultbitmap.clear @defaultbitmap.fill_rect(0,0,@defaultwidth,$ResizeOffsetY,Color.new(0,0,0)) @defaultbitmap.fill_rect(0,0,$ResizeOffsetX,@defaultheight,Color.new(0,0,0)) @defaultbitmap.fill_rect(@defaultwidth-$ResizeOffsetX,0, $ResizeOffsetX,@defaultheight,Color.new(0,0,0)) @defaultbitmap.fill_rect(0,@defaultheight-$ResizeOffsetY, @defaultwidth,$ResizeOffsetY,Color.new(0,0,0)) end end $ResizeBorder=ScreenBorder.new def setScreenBorderName(border) if $ResizeBorder $ResizeBorder.bordername=border end end
Window
[
Selecionar
] [
-
]
class WindowCursorRect < Rect def initialize(window) @window=window @x=0 @y=0 @width=0 @height=0 end attr_reader :x,:y,:width,:height def empty needupdate=@x!=0 || @y!=0 || @width!=0 || @height!=0 if needupdate @x=0 @y=0 @width=0 @height=0 @window.width=@window.width end end def isEmpty? return @x==0 && @y==0 && @width==0 && @height==0 end def set(x,y,width,height) needupdate=@x!=x || @y!=y || @width!=width || @height!=height if needupdate @x=x @y=y @width=width @height=height @window.width=@window.width end end def height=(value) @height=value; @window.width=@window.width end def width=(value) @width=value; @window.width=@window.width end def x=(value) @x=value; @window.width=@window.width end def y=(value) @y=value; @window.width=@window.width end end class Window attr_reader :tone attr_reader :color attr_reader :blend_type attr_reader :contents_blend_type attr_reader :viewport attr_reader :contents attr_reader :ox attr_reader :oy attr_reader :x attr_reader :y attr_reader :z attr_reader :width attr_reader :active attr_reader :pause attr_reader :height attr_reader :opacity attr_reader :back_opacity attr_reader :contents_opacity attr_reader :visible attr_reader :cursor_rect attr_reader :openness attr_reader :stretch def windowskin @_windowskin end def initialize(viewport=nil) @sprites={} @spritekeys=[ "back", "corner0","side0","scroll0", "corner1","side1","scroll1", "corner2","side2","scroll2", "corner3","side3","scroll3", "cursor","contents","pause" ] @sidebitmaps=[nil,nil,nil,nil] @cursorbitmap=nil @bgbitmap=nil @viewport=viewport for i in @spritekeys @sprites[i]=Sprite.new(@viewport) end @disposed=false @tone=Tone.new(0,0,0) @color=Color.new(0,0,0,0) @blankcontents=Bitmap.new(1,1) # RGSS2 requires this @contents=@blankcontents @_windowskin=nil @rpgvx=false # Set to true to emulate RPGVX windows @x=0 @y=0 @width=0 @openness=255 @height=0 @ox=0 @oy=0 @z=0 @stretch=true @visible=true @active=true @blend_type=0 @contents_blend_type=0 @opacity=255 @back_opacity=255 @contents_opacity=255 @cursor_rect=WindowCursorRect.new(self) @cursorblink=0 @cursoropacity=255 @pause=false @pauseopacity=255 @pauseframe=0 privRefresh(true) end def dispose if !self.disposed? for i in @sprites i[1].dispose if i[1] @sprites[i[0]]=nil end for i in 0...@sidebitmaps.length @sidebitmaps[i].dispose if @sidebitmaps[i] @sidebitmaps[i]=nil end @blankcontents.dispose @cursorbitmap.dispose if @cursorbitmap @backbitmap.dispose if @backbitmap @sprites.clear @sidebitmaps.clear @_windowskin=nil @_contents=nil @disposed=true end end def openness=(value) @openness=value @openness=0 if @openness<0 @openness=255 if @openness>255 privRefresh end def stretch=(value) @stretch=value privRefresh(true) end def visible=(value) @visible=value privRefresh end def viewport=(value) @viewport=value for i in @spritekeys @sprites[i].dispose if @sprites[i].is_a?(Sprite) @sprites[i]=Sprite.new(@viewport) else @sprites[i]=nil end end privRefresh(true) end def z=(value) @z=value privRefresh end def disposed? return @disposed end def contents=(value) @contents=value privRefresh end def windowskin=(value) @_windowskin=value if value && value.is_a?(Bitmap) && !value.disposed? && value.width==128 @rpgvx=true else @rpgvx=false end privRefresh(true) end def ox=(value) @ox=value privRefresh end def active=(value) @active=value privRefresh(true) end def cursor_rect=(value) if !value @cursor_rect.empty else @cursor_rect.set(value.x,value.y,value.width,value.height) end end def oy=(value) @oy=value privRefresh end def width=(value) @width=value privRefresh(true) end def height=(value) @height=value privRefresh(true) end def pause=(value) @pause=value @pauseopacity=0 if !value privRefresh end def x=(value) @x=value privRefresh end def y=(value) @y=value privRefresh end def opacity=(value) @opacity=value @opacity=0 if @opacity<0 @opacity=255 if @opacity>255 privRefresh end def back_opacity=(value) @back_opacity=value @back_opacity=0 if @back_opacity<0 @back_opacity=255 if @back_opacity>255 privRefresh end def contents_opacity=(value) @contents_opacity=value @contents_opacity=0 if @contents_opacity<0 @contents_opacity=255 if @contents_opacity>255 privRefresh end def tone=(value) @tone=value privRefresh end def color=(value) @color=value privRefresh end def blend_type=(value) @blend_type=value privRefresh end def flash(color,duration) return if disposed? for i in @sprites i[1].flash(color,duration) end end def update return if disposed? mustchange=false if @active if @cursorblink==0 @cursoropacity-=8 @cursorblink=1 if @cursoropacity<=128 else @cursoropacity+=8 @cursorblink=0 if @cursoropacity>=255 end mustchange=true if !@cursor_rect.isEmpty? else mustchange=true if @cursoropacity!=128 @cursoropacity=128 end if @pause @pauseframe=(Graphics.frame_count / 8) % 4 @pauseopacity=[@pauseopacity+64,255].min mustchange=true end privRefresh if mustchange for i in @sprites i[1].update end end private def ensureBitmap(bitmap,dwidth,dheight) if !bitmap||bitmap.disposed?||bitmap.width<dwidth||bitmap.height<dheight bitmap.dispose if bitmap bitmap=Bitmap.new([1,dwidth].max,[1,dheight].max) end return bitmap end def tileBitmap(dstbitmap,dstrect,srcbitmap,srcrect) return if !srcbitmap || srcbitmap.disposed? left=dstrect.x top=dstrect.y y=0;loop do break unless y<dstrect.height x=0;loop do break unless x<dstrect.width dstbitmap.blt(x+left,y+top,srcbitmap,srcrect) x+=srcrect.width end y+=srcrect.height end end def privRefresh(changeBitmap=false) return if self.disposed? backopac=self.back_opacity*self.opacity/255 contopac=self.contents_opacity cursoropac=@cursoropacity*contopac/255 for i in 0...4 @sprites["corner#{i}"].bitmap=@_windowskin @sprites["scroll#{i}"].bitmap=@_windowskin end @sprites["pause"].bitmap=@_windowskin @sprites["contents"].bitmap=@contents if @_windowskin && !@_windowskin.disposed? for i in 0...4 @sprites["corner#{i}"].opacity=@opacity @sprites["corner#{i}"].tone=@tone @sprites["corner#{i}"].color=@color @sprites["corner#{i}"].blend_type=@blend_type @sprites["corner#{i}"].visible=@visible @sprites["side#{i}"].opacity=@opacity @sprites["side#{i}"].tone=@tone @sprites["side#{i}"].color=@color @sprites["side#{i}"].blend_type=@blend_type @sprites["side#{i}"].visible=@visible @sprites["scroll#{i}"].opacity=@opacity @sprites["scroll#{i}"].tone=@tone @sprites["scroll#{i}"].blend_type=@blend_type @sprites["scroll#{i}"].color=@color @sprites["scroll#{i}"].visible=@visible end for i in ["back","cursor","pause","contents"] @sprites[i].color=@color @sprites[i].tone=@tone @sprites[i].blend_type=@blend_type end @sprites["contents"].blend_type=@contents_blend_type @sprites["back"].opacity=backopac @sprites["contents"].opacity=contopac @sprites["cursor"].opacity=cursoropac @sprites["pause"].opacity=@pauseopacity @sprites["back"].visible=@visible @sprites["contents"].visible=@visible && @openness==255 @sprites["pause"].visible=@visible && @pause @sprites["cursor"].visible=@visible && @openness==255 hascontents=(@contents && !@contents.disposed?) @sprites["scroll0"].visible = @visible && hascontents && @oy > 0 @sprites["scroll1"].visible = @visible && hascontents && @ox > 0 @sprites["scroll2"].visible = @visible && hascontents && (@contents.width - @ox) > @width-32 @sprites["scroll3"].visible = @visible && hascontents && (@contents.height - @oy) > @height-32 else for i in 0...4 @sprites["corner#{i}"].visible=false @sprites["side#{i}"].visible=false @sprites["scroll#{i}"].visible=false end @sprites["contents"].visible=@visible && @openness==255 @sprites["contents"].color=@color @sprites["contents"].tone=@tone @sprites["contents"].blend_type=@contents_blend_type @sprites["contents"].opacity=contopac @sprites["back"].visible=false @sprites["pause"].visible=false @sprites["cursor"].visible=false end for i in @sprites i[1].z=@z end if @rpgvx @sprites["cursor"].z=@z#+1 # For Compatibility @sprites["contents"].z=@z#+2 # For Compatibility @sprites["pause"].z=@z#+2 # For Compatibility else @sprites["cursor"].z=@z+1 # For Compatibility @sprites["contents"].z=@z+2 # For Compatibility @sprites["pause"].z=@z+2 # For Compatibility end if @rpgvx trimX=64 trimY=0 backRect=Rect.new(0,0,64,64) blindsRect=Rect.new(0,64,64,64) else trimX=128 trimY=0 backRect=Rect.new(0,0,128,128) blindsRect=nil end @sprites["corner0"].src_rect.set(trimX,trimY+0,16,16); @sprites["corner1"].src_rect.set(trimX+48,trimY+0,16,16); @sprites["corner2"].src_rect.set(trimX,trimY+48,16,16); @sprites["corner3"].src_rect.set(trimX+48,trimY+48,16,16); @sprites["scroll0"].src_rect.set(trimX+24, trimY+16, 16, 8) # up @sprites["scroll3"].src_rect.set(trimX+24, trimY+40, 16, 8) # down @sprites["scroll1"].src_rect.set(trimX+16, trimY+24, 8, 16) # left @sprites["scroll2"].src_rect.set(trimX+40, trimY+24, 8, 16) # right cursorX=trimX cursorY=trimY+64 sideRects=[ Rect.new(trimX+16,trimY+0,32,16), Rect.new(trimX,trimY+16,16,32), Rect.new(trimX+48,trimY+16,16,32), Rect.new(trimX+16,trimY+48,32,16) ] if @width>32 && @height>32 @sprites["contents"].src_rect.set(@ox,@oy,@width-32,@height-32) else @sprites["contents"].src_rect.set(0,0,0,0) end pauseRects=[ trimX+32,trimY+64, trimX+48,trimY+64, trimX+32,trimY+80, trimX+48,trimY+80, ] pauseWidth=16 pauseHeight=16 @sprites["pause"].src_rect.set( pauseRects[@pauseframe*2], pauseRects[@pauseframe*2+1], pauseWidth,pauseHeight ) @sprites["pause"].x=@x+(@width/2)-(pauseWidth/2) @sprites["pause"].y=@y+@height-16 # 16 refers to skin margin @sprites["contents"].x=@x+16 @sprites["contents"].y=@y+16 @sprites["corner0"].x=@x @sprites["corner0"].y=@y @sprites["corner1"].x=@x+@width-16 @sprites["corner1"].y=@y @sprites["corner2"].x=@x @sprites["corner2"].y=@y+@height-16 @sprites["corner3"].x=@x+@width-16 @sprites["corner3"].y=@y+@height-16 @sprites["side0"].x=@x+16 @sprites["side0"].y=@y @sprites["side1"].x=@x @sprites["side1"].y=@y+16 @sprites["side2"].x=@x+@width-16 @sprites["side2"].y=@y+16 @sprites["side3"].x=@x+16 @sprites["side3"].y=@y+@height-16 @sprites["scroll0"].x = @x+@width / 2 - 8 @sprites["scroll0"].y = @y+8 @sprites["scroll1"].x = @x+8 @sprites["scroll1"].y = @y+@height / 2 - 8 @sprites["scroll2"].x = @x+@width - 16 @sprites["scroll2"].y = @y+@height / 2 - 8 @sprites["scroll3"].x = @x+@width / 2 - 8 @sprites["scroll3"].y = @y+@height - 16 @sprites["back"].x=@x+2 @sprites["back"].y=@y+2 @sprites["cursor"].x=@x+16+@cursor_rect.x @sprites["cursor"].y=@y+16+@cursor_rect.y if changeBitmap && @_windowskin && !@_windowskin.disposed? width=@cursor_rect.width height=@cursor_rect.height if width > 0 && height > 0 cursorrects=[ # sides Rect.new(cursorX+2, cursorY+0, 28, 2), Rect.new(cursorX+0, cursorY+2, 2, 28), Rect.new(cursorX+30, cursorY+2, 2, 28), Rect.new(cursorX+2, cursorY+30, 28, 2), # corners Rect.new(cursorX+0, cursorY+0, 2, 2), Rect.new(cursorX+30, cursorY+0, 2, 2), Rect.new(cursorX+0, cursorY+30, 2, 2), Rect.new(cursorX+30, cursorY+30, 2, 2), # back Rect.new(cursorX+2, cursorY+2, 28, 28) ] margin=2 fullmargin=4 @cursorbitmap = ensureBitmap(@cursorbitmap, width, height) @cursorbitmap.clear @sprites["cursor"].bitmap=@cursorbitmap @sprites["cursor"].src_rect.set(0,0,width,height) rect = Rect.new(margin,margin, width - fullmargin, height - fullmargin) @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[8]) @cursorbitmap.blt(0, 0, @_windowskin, cursorrects[4])# top left @cursorbitmap.blt(width-margin, 0, @_windowskin, cursorrects[5]) # top right @cursorbitmap.blt(0, height-margin, @_windowskin, cursorrects[6]) # bottom right @cursorbitmap.blt(width-margin, height-margin, @_windowskin, cursorrects[7]) # bottom left rect = Rect.new(margin, 0, width - fullmargin, margin) @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[0]) rect = Rect.new(0, margin, margin, height - fullmargin) @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[1]) rect = Rect.new(width - margin, margin, margin, height - fullmargin) @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[2]) rect = Rect.new(margin, height-margin, width - fullmargin, margin) @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[3]) else @sprites["cursor"].visible=false @sprites["cursor"].src_rect.set(0,0,0,0) end for i in 0..3 dwidth=(i==0||i==3) ? @width-32 : 16 dheight=(i==0||i==3) ? 16 : @height-32 @sidebitmaps[i]=ensureBitmap(@sidebitmaps[i],dwidth,dheight) @sprites["side#{i}"].bitmap=@sidebitmaps[i] @sprites["side#{i}"].src_rect.set(0,0,dwidth,dheight) @sidebitmaps[i].clear if sideRects[i].width>0 && sideRects[i].height>0 @sidebitmaps[i].stretch_blt(@sprites["side#{i}"].src_rect, @_windowskin,sideRects[i]) end end backwidth=@width-4 backheight=@height-4 if backwidth>0 && backheight>0 @backbitmap=ensureBitmap(@backbitmap,backwidth,backheight) @sprites["back"].bitmap=@backbitmap @sprites["back"].src_rect.set(0,0,backwidth,backheight) @backbitmap.clear if @stretch @backbitmap.stretch_blt(@sprites["back"].src_rect,@_windowskin,backRect) else tileBitmap(@backbitmap,@sprites["back"].src_rect,@_windowskin,backRect) end if blindsRect tileBitmap(@backbitmap,@sprites["back"].src_rect,@_windowskin,blindsRect) end else @sprites["back"].visible=false @sprites["back"].src_rect.set(0,0,0,0) end end if @openness!=255 opn=@openness/255.0 for k in @spritekeys sprite=@sprites[k] ratio=(@height<=0) ? 0 : (sprite.y-@y)*1.0/@height sprite.zoom_y=opn sprite.oy=0 sprite.y=(@y+(@height/2.0)+(@height*ratio*opn)-(@height/2*opn)).floor end else for k in @spritekeys sprite=@sprites[k] sprite.zoom_y=1.0 end end i=0 # Ensure Z order for k in @spritekeys sprite=@sprites[k] y=sprite.y sprite.y=i sprite.oy=(sprite.zoom_y<=0) ? 0 : (i-y)/sprite.zoom_y end end end
TilemapXP
[
Selecionar
] [
-
]
class CustomTilemapAutotiles attr_accessor :changed def initialize @changed=true @tiles=[nil,nil,nil,nil,nil,nil,nil] end def []=(i,value) @tiles[i]=value @changed=true end def [](i) return @tiles[i] end end #Console::setup_console class CustomTilemapSprite < Sprite end class CustomTilemap Animated_Autotiles_Frames = 15 Autotiles = [ [ [27, 28, 33, 34], [ 5, 28, 33, 34], [27, 6, 33, 34], [ 5, 6, 33, 34], [27, 28, 33, 12], [ 5, 28, 33, 12], [27, 6, 33, 12], [ 5, 6, 33, 12] ], [ [27, 28, 11, 34], [ 5, 28, 11, 34], [27, 6, 11, 34], [ 5, 6, 11, 34], [27, 28, 11, 12], [ 5, 28, 11, 12], [27, 6, 11, 12], [ 5, 6, 11, 12] ], [ [25, 26, 31, 32], [25, 6, 31, 32], [25, 26, 31, 12], [25, 6, 31, 12], [15, 16, 21, 22], [15, 16, 21, 12], [15, 16, 11, 22], [15, 16, 11, 12] ], [ [29, 30, 35, 36], [29, 30, 11, 36], [ 5, 30, 35, 36], [ 5, 30, 11, 36], [39, 40, 45, 46], [ 5, 40, 45, 46], [39, 6, 45, 46], [ 5, 6, 45, 46] ], [ [25, 30, 31, 36], [15, 16, 45, 46], [13, 14, 19, 20], [13, 14, 19, 12], [17, 18, 23, 24], [17, 18, 11, 24], [41, 42, 47, 48], [ 5, 42, 47, 48] ], [ [37, 38, 43, 44], [37, 6, 43, 44], [13, 18, 19, 24], [13, 14, 43, 44], [37, 42, 43, 48], [17, 18, 47, 48], [13, 18, 43, 48], [ 1, 2, 7, 8] ] ] FlashOpacity=[100,90,80,70,80,90] attr_reader :tileset attr_reader :autotiles attr_reader :map_data attr_accessor :flash_data attr_accessor :priorities attr_reader :visible attr_accessor :ox attr_accessor :oy attr_reader :viewport attr_accessor :tone attr_accessor :color def graphicsHeight return @graphicsHeight end def graphicsWidth return @graphicsWidth end def initialize(viewport) @tileset = nil # Refers to Map Tileset Name @autotiles = CustomTilemapAutotiles.new @map_data = nil # Refers to 3D Array Of Tile Settings @flash_data = nil # Refers to 3D Array of Tile Flashdata @priorities = nil # Refers to Tileset Priorities @visible = true # Refers to Tileset Visibleness @ox = 0 # Bitmap Offsets @oy = 0 # bitmap Offsets @plane = false @haveGraphicsWH=Graphics.width!=nil rescue false if @haveGraphicsWH @graphicsWidth=Graphics.width @graphicsHeight=Graphics.height else @graphicsWidth=640 @graphicsHeight=480 end @tileWidth = Game_Map::TILEWIDTH rescue 32 @tileHeight = Game_Map::TILEHEIGHT rescue 32 @tileSrcWidth = 32 @tileSrcHeight = 32 @diffsizes=(@tileWidth!=@tileSrcWidth)||(@tileHeight!=@tileSrcHeight) @tone=Tone.new(0,0,0,0) @color=Color.new(0,0,0,0) @oldtone=Tone.new(0,0,0,0) @oldcolor=Color.new(0,0,0,0) @selfviewport=Viewport.new(0,0,graphicsWidth,graphicsHeight) @viewport=viewport ? viewport : @selfviewport @tiles=[] @autotileInfo=[] @regularTileInfo=[] @oldOx=0 @oldOy=0 @oldViewportOx=0 @oldViewportOy=0 @layer0=CustomTilemapSprite.new(viewport) @layer0.visible=true @nowshown=false @layer0.bitmap=Bitmap.new([graphicsWidth+320,1].max,[graphicsHeight+320,1].max) @flash=nil @layer0.ox=0 @layer0.oy=0 @oxLayer0=0 @oyLayer0=0 @oxFlash=0 @oyFlash=0 @layer0.z=0 @priotiles=[] @priotilesfast=[] @prioautotiles=[] @autosprites=[] @framecount=[0,0,0,0,0,0,0,0] @tilesetChanged=true @flashChanged=false @firsttime=true @disposed=false @usedsprites=false @layer0clip=true @firsttimeflash=true @fullyrefreshed=false @fullyrefreshedautos=false end def disposed? return @disposed end def flash_data=(value) @flash_data=value @flashChanged=true end def update if @haveGraphicsWH @graphicsWidth=Graphics.width @graphicsHeight=Graphics.height end if @oldtone!=@tone @layer0.tone=@tone @flash.tone=@tone if @flash for sprite in @autosprites sprite.tone=@tone if sprite.is_a?(Sprite) end for sprite in @tiles sprite.tone=@tone if sprite.is_a?(Sprite) end @oldtone=@tone.clone end if @oldcolor!=@color @layer0.color=@color @flash.color=@color if @flash for sprite in @autosprites sprite.color=@color if sprite.is_a?(Sprite) end for sprite in @tiles sprite.color=@color if sprite.is_a?(Sprite) end @oldcolor=@color.clone end if @autotiles.changed refresh_autotiles repaintAutotiles end if @flashChanged refresh_flash end if @tilesetChanged refresh_tileset end if @flash @flash.opacity=FlashOpacity[(Graphics.frame_count/2) % 6] end mustrefresh=!(@oldOx==@ox && @oldOy==@oy && !@tilesetChanged && !@autotiles.changed) if @viewport.ox!=@oldViewportOx || @viewport.oy!=@oldViewportOy mustrefresh=true @oldViewportOx=@viewport.ox @oldViewportOy=@viewport.oy end if mustrefresh refresh end if (Graphics.frame_count % Animated_Autotiles_Frames == 0) || @nowshown repaintAutotiles refresh(true) end @nowshown=false @autotiles.changed=false @tilesetChanged=false end def priorities=(value) @priorities=value @tilesetChanged=true end def tileset=(value) @tileset=value @tilesetChanged=true end def shown? return false if !@visible ysize=@map_data.ysize xsize=@map_data.xsize xStart=(@ox/@tileWidth)-1 xEnd=((@ox+@viewport.rect.width)/@tileWidth)+1 yStart=(@oy/@tileHeight)-1 yEnd=((@oy+@viewport.rect.height)/@tileHeight)+1 xStart=0 if xStart<0 xStart=xsize-1 if xStart>=xsize xEnd=0 if xEnd<0 xEnd=xsize-1 if xEnd>=xsize yStart=0 if yStart<0 yStart=ysize-1 if yStart>=ysize yEnd=0 if yEnd<0 yEnd=ysize-1 if yEnd>=ysize return (xStart<xEnd && yStart<yEnd) end def dispose return if disposed? @help.dispose if @help @help=nil i=0;len=@autotileInfo.length;while i<len if @autotileInfo[i] @autotileInfo[i].dispose @autotileInfo[i]=nil end i+=1 end i=0;len=@regularTileInfo.length;while i<len if @regularTileInfo[i] @regularTileInfo[i].dispose @regularTileInfo[i]=nil end i+=1 end i=0;len=@tiles.length;while i<len @tiles[i].dispose @tiles[i]=nil i+=2 end i=0;len=@autosprites.length;while i<len @autosprites[i].dispose @autosprites[i]=nil i+=2 end if @layer0 @layer0.bitmap.dispose if !@layer0.disposed? @layer0.bitmap=nil if !@layer0.disposed? @layer0.dispose @layer0=nil end if @flash @flash.bitmap.dispose if !@flash.disposed? @flash.bitmap=nil if !@flash.disposed? @flash.dispose @flash=nil end for i in 0...7 self.autotiles[i]=nil end @tiles.clear @autosprites.clear @autotileInfo.clear @regularTileInfo.clear @tilemap=nil @tileset=nil @priorities=nil @selfviewport.dispose @selfviewport=nil @disposed=true end def bltAutotile(bitmap,x,y,id,frame) return if frame<0 autotile=@autotiles[id/48-1] return if !autotile || autotile.disposed? if autotile.height==@tileSrcHeight anim=frame*@tileSrcWidth src_rect=Rect.new(anim,0,@tileSrcWidth,@tileSrcHeight) if @diffsizes bitmap.stretch_blt(Rect.new(x,y,@tileWidth,@tileHeight),autotile,src_rect) else bitmap.blt(x,y,autotile,src_rect) end else anim=frame*3*@tileSrcWidth id%=48 tiles = Autotiles[id>>3][id&7] src=Rect.new(0,0,0,0) halfTileWidth=@tileWidth>>1 halfTileHeight=@tileHeight>>1 halfTileSrcWidth=@tileSrcWidth>>1 halfTileSrcHeight=@tileSrcHeight>>1 for i in 0...4 tile_position = tiles[i] - 1 src.set( (tile_position % 6)*halfTileSrcWidth + anim, (tile_position / 6)*halfTileSrcHeight, halfTileSrcWidth, halfTileSrcHeight) if @diffsizes bitmap.stretch_blt( Rect.new(i%2*halfTileWidth+x,i/2*halfTileHeight+y,halfTileWidth,halfTileHeight), autotile,src) else bitmap.blt(i%2*halfTileWidth+x,i/2*halfTileHeight+y, autotile, src) end end end end def autotileNumFrames(id) autotile=@autotiles[id/48-1] return 0 if !autotile || autotile.disposed? frames=1 if autotile.height==@tileHeight frames=autotile.width/@tileWidth else frames=autotile.width/(3*@tileWidth) end return frames end def autotileFrame(id) autotile=@autotiles[id/48-1] return -1 if !autotile || autotile.disposed? frames=1 if autotile.height==@tileHeight frames=autotile.width/@tileWidth else frames=autotile.width/(3*@tileWidth) end return (Graphics.frame_count/Animated_Autotiles_Frames)%frames end def repaintAutotiles for i in 0...@autotileInfo.length next if !@autotileInfo[i] frame=autotileFrame(i) bltAutotile(@autotileInfo[i],0,0,i,frame) end end def getAutotile(sprite,id) frames=@framecount[id/48-1] if frames<=1 anim=0 else anim=(Graphics.frame_count/Animated_Autotiles_Frames)%frames end return if anim<0 bitmap=@autotileInfo[id] if !bitmap bitmap=Bitmap.new(@tileWidth,@tileHeight) bltAutotile(bitmap,0,0,id,anim) @autotileInfo[id]=bitmap end if sprite.bitmap!=bitmap sprite.bitmap=bitmap end end def getRegularTile(sprite,id) if !@diffsizes if sprite.bitmap!=@tileset sprite.bitmap=@tileset end sprite.src_rect.set(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight,@tileSrcWidth,@tileSrcHeight) else bitmap=@regularTileInfo[id] if !bitmap bitmap=Bitmap.new(@tileWidth,@tileHeight) rect=Rect.new(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight,@tileSrcWidth,@tileSrcHeight) bitmap.stretch_blt(Rect.new(0,0,@tileWidth,@tileHeight),@tileset,rect) @regularTileInfo[id]=bitmap end if sprite.bitmap!=bitmap sprite.bitmap=bitmap end end end def addTile(tiles,count,xpos,ypos,id) if id>=384 if count>=tiles.length sprite=CustomTilemapSprite.new(@viewport) tiles.push(sprite,0) else sprite=tiles[count] tiles[count+1]=0 end sprite.visible=@visible sprite.x=xpos sprite.y=ypos sprite.tone=@tone sprite.color=@color getRegularTile(sprite,id) spriteZ=(@priorities[id]==0||!@priorities[id]) ? 0 : ypos+@priorities[id]*32+32 sprite.z=spriteZ count+=2 else if count>=tiles.length sprite=CustomTilemapSprite.new(@viewport) tiles.push(sprite,1) else sprite=tiles[count] tiles[count+1]=1 end sprite.visible=@visible sprite.x=xpos sprite.y=ypos sprite.tone=@tone sprite.color=@color getAutotile(sprite,id) spriteZ=(@priorities[id]==0||!@priorities[id]) ? 0 : ypos+@priorities[id]*32+32 sprite.z=spriteZ count+=2 end return count end def refresh_tileset i=0;len=@regularTileInfo.length;while i<len if @regularTileInfo[i] @regularTileInfo[i].dispose @regularTileInfo[i]=nil end i+=1 end @regularTileInfo.clear @priotiles.clear ysize=@map_data.ysize xsize=@map_data.xsize zsize=@map_data.zsize if xsize>100 || ysize>100 @fullyrefreshed=false else for z in 0...zsize for y in 0...ysize for x in 0...xsize id = @map_data[x, y, z] next if id==0 || !@priorities[id] next if @priorities[id]==0 @priotiles.push([x,y,z,id]) end end end @fullyrefreshed=true end end def refresh_flash if @flash_data && !@flash @flash=CustomTilemapSprite.new(viewport) @flash.visible=true @flash.z=1 @flash.tone=tone @flash.color=color @flash.blend_type=1 @flash.bitmap=Bitmap.new([graphicsWidth*2,1].max,[graphicsHeight*2,1].max) @firsttimeflash=true elsif !@flash_data && @flash @flash.bitmap.dispose if @flash.bitmap @flash.dispose @flash=nil @firsttimeflash=false end end def refresh_autotiles i=0;len=@autotileInfo.length;while i<len if @autotileInfo[i] @autotileInfo[i].dispose @autotileInfo[i]=nil end i+=1 end i=0;len=@autosprites.length;while i<len if @autosprites[i] @autosprites[i].dispose @autosprites[i]=nil end i+=2 end @autosprites.clear @autotileInfo.clear @prioautotiles.clear @priorect=nil @priorectautos=nil hasanimated=false for i in 0...7 numframes=autotileNumFrames(48*(i+1)) hasanimated=true if numframes>=2 @framecount[i]=numframes end if hasanimated ysize=@map_data.ysize xsize=@map_data.xsize zsize=@map_data.zsize if xsize>100 || ysize>100 @fullyrefreshedautos=false else for y in 0...ysize for x in 0...xsize haveautotile=false for z in 0...zsize id = @map_data[x, y, z] next if id==0 || id>=384 || @priorities[id]!=0 || !@priorities[id] next if @framecount[id/48-1]<2 haveautotile=true break end @prioautotiles.push([x,y]) if haveautotile end end @fullyrefreshedautos=true end else @fullyrefreshedautos=true end end def map_data=(value) @map_data=value @tilesetChanged=true end def refreshFlashSprite return if !@flash || @flash_data.nil? ptX=@ox-@oxFlash ptY=@oy-@oyFlash if !@firsttimeflash && !@usedsprites && ptX>=0 && ptX+@viewport.rect.width<=@flash.bitmap.width && ptY>=0 && ptY+@viewport.rect.height<=@flash.bitmap.height @flash.ox=0 @flash.oy=0 @flash.src_rect.set(ptX.round,ptY.round, @viewport.rect.width,@viewport.rect.height) return end width=@flash.bitmap.width height=@flash.bitmap.height bitmap=@flash.bitmap ysize=@map_data.ysize xsize=@map_data.xsize zsize=@map_data.zsize @firsttimeflash=false @oxFlash=@ox-(width>>2) @oyFlash=@oy-(height>>2) @flash.ox=0 @flash.oy=0 @flash.src_rect.set(width>>2,height>>2, @viewport.rect.width,@viewport.rect.height) @flash.bitmap.clear @oxFlash=@oxFlash.floor @oyFlash=@oyFlash.floor xStart=(@oxFlash/@tileWidth) xStart=0 if xStart<0 yStart=(@oyFlash/@tileHeight) yStart=0 if yStart<0 xEnd=xStart+(width/@tileWidth)+1 yEnd=yStart+(height/@tileHeight)+1 xEnd=xsize if xEnd>=xsize yEnd=ysize if yEnd>=ysize if xStart<xEnd && yStart<yEnd yrange=yStart...yEnd xrange=xStart...xEnd tmpcolor=Color.new(0,0,0,0) for y in yrange ypos=(y*@tileHeight)-@oyFlash for x in xrange xpos=(x*@tileWidth)-@oxFlash id = @flash_data[x, y, 0] r=(id>>8)&15 g=(id>>4)&15 b=(id)&15 tmpcolor.set(r<<4,g<<4,b<<4) bitmap.fill_rect(xpos,ypos,@tileWidth,@tileHeight,tmpcolor) end end end end def refreshLayer0(autotiles=false) if autotiles return true if !shown? end ptX=@ox-@oxLayer0 ptY=@oy-@oyLayer0 if !autotiles && !@firsttime && !@usedsprites && ptX>=0 && ptX+@viewport.rect.width<=@layer0.bitmap.width && ptY>=0 && ptY+@viewport.rect.height<=@layer0.bitmap.height if @layer0clip @layer0.ox=0 @layer0.oy=0 @layer0.src_rect.set(ptX.round,ptY.round, @viewport.rect.width,@viewport.rect.height) else @layer0.ox=ptX.round @layer0.oy=ptY.round @layer0.src_rect.set(0,0,@layer0.bitmap.width,@layer0.bitmap.height) end return true end width=@layer0.bitmap.width height=@layer0.bitmap.height bitmap=@layer0.bitmap ysize=@map_data.ysize xsize=@map_data.xsize zsize=@map_data.zsize twidth=@tileWidth theight=@tileHeight mapdata=@map_data if autotiles return true if @fullyrefreshedautos && @prioautotiles.length==0 xStart=(@oxLayer0/twidth) xStart=0 if xStart<0 yStart=(@oyLayer0/theight) yStart=0 if yStart<0 xEnd=xStart+(width/twidth)+1 yEnd=yStart+(height/theight)+1 xEnd=xsize if xEnd>xsize yEnd=ysize if yEnd>ysize return true if xStart>=xEnd || yStart>=yEnd trans=Color.new(0,0,0,0) temprect=Rect.new(0,0,0,0) tilerect=Rect.new(0,0,twidth,theight) zrange=0...zsize overallcount=0 count=0 if !@fullyrefreshedautos for y in yStart..yEnd for x in xStart..xEnd haveautotile=false for z in zrange id = mapdata[x, y, z] next if !id || id<48 || id>=384 prioid=@priorities[id] next if prioid!=0 || !prioid fcount=@framecount[id/48-1] next if !fcount || fcount<2 if !haveautotile haveautotile=true overallcount+=1 xpos=(x*twidth)-@oxLayer0 ypos=(y*theight)-@oyLayer0 bitmap.fill_rect(xpos,ypos,twidth,theight,trans) if overallcount<=2000 break end end for z in zrange id = mapdata[x,y,z] next if !id || id<48 prioid=@priorities[id] next if prioid!=0 || !prioid if overallcount>2000 xpos=(x*twidth)-@oxLayer0 ypos=(y*theight)-@oyLayer0 count=addTile(@autosprites,count,xpos,ypos,id) next elsif id>=384 temprect.set(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight,@tileSrcWidth,@tileSrcHeight) xpos=(x*twidth)-@oxLayer0 ypos=(y*theight)-@oyLayer0 if @diffsizes bitmap.stretch_blt(Rect.new(xpos,ypos,twidth,theight),@tileset,temprect) else bitmap.blt(xpos,ypos,@tileset,temprect) end else tilebitmap=@autotileInfo[id] if !tilebitmap anim=autotileFrame(id) next if anim<0 tilebitmap=Bitmap.new(twidth,theight) bltAutotile(tilebitmap,0,0,id,anim) @autotileInfo[id]=tilebitmap end xpos=(x*twidth)-@oxLayer0 ypos=(y*theight)-@oyLayer0 bitmap.blt(xpos,ypos,tilebitmap,tilerect) end end end end Graphics.frame_reset else if !@priorect || !@priorectautos || @priorect[0]!=xStart || @priorect[1]!=yStart || @priorect[2]!=xEnd || @priorect[3]!=yEnd @priorectautos=@prioautotiles.find_all{|tile| x=tile[0] y=tile[1] # "next" means "return" here next !(x<xStart||x>xEnd||y<yStart||y>yEnd) } @priorect=[xStart,yStart,xEnd,yEnd] end # echoln ["autos",@priorect,@priorectautos.length,@prioautotiles.length] for tile in @priorectautos x=tile[0] y=tile[1] overallcount+=1 xpos=(x*twidth)-@oxLayer0 ypos=(y*theight)-@oyLayer0 bitmap.fill_rect(xpos,ypos,twidth,theight,trans) z=0 while z<zsize id = mapdata[x,y,z] z+=1 next if !id || id<48 prioid=@priorities[id] next if prioid!=0 || !prioid if id>=384 temprect.set(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight,@tileSrcWidth,@tileSrcHeight) if @diffsizes bitmap.stretch_blt(Rect.new(xpos,ypos,twidth,theight),@tileset,temprect) else bitmap.blt(xpos,ypos,@tileset,temprect) end else tilebitmap=@autotileInfo[id] if !tilebitmap anim=autotileFrame(id) next if anim<0 tilebitmap=Bitmap.new(twidth,theight) bltAutotile(tilebitmap,0,0,id,anim) @autotileInfo[id]=tilebitmap end bitmap.blt(xpos,ypos,tilebitmap,tilerect) end end end Graphics.frame_reset if overallcount>500 end @usedsprites=false return true end return false if @usedsprites @firsttime=false @oxLayer0=@ox-(width>>2) @oyLayer0=@oy-(height>>2) if @layer0clip @layer0.ox=0 @layer0.oy=0 @layer0.src_rect.set(width>>2,height>>2, @viewport.rect.width,@viewport.rect.height) else @layer0.ox=(width>>2) @layer0.oy=(height>>2) end @layer0.bitmap.clear @oxLayer0=@oxLayer0.floor @oyLayer0=@oyLayer0.floor xStart=(@oxLayer0/twidth) xStart=0 if xStart<0 yStart=(@oyLayer0/theight) yStart=0 if yStart<0 xEnd=xStart+(width/twidth)+1 yEnd=yStart+(height/theight)+1 xEnd=xsize if xEnd>=xsize yEnd=ysize if yEnd>=ysize if xStart<xEnd && yStart<yEnd tmprect=Rect.new(0,0,0,0) yrange=yStart...yEnd xrange=xStart...xEnd for z in 0...zsize for y in yrange ypos=(y*theight)-@oyLayer0 for x in xrange xpos=(x*twidth)-@oxLayer0 id = mapdata[x, y, z] next if id==0 || @priorities[id]!=0 || !@priorities[id] if id>=384 tmprect.set( ((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight,@tileSrcWidth,@tileSrcHeight) if @diffsizes bitmap.stretch_blt(Rect.new(xpos,ypos,twidth,theight),@tileset,tmprect) else bitmap.blt(xpos,ypos,@tileset,tmprect) end else frames=@framecount[id/48-1] if frames<=1 frame=0 else frame=(Graphics.frame_count/Animated_Autotiles_Frames)%frames end bltAutotile(bitmap,xpos,ypos,id,frame) end end end end Graphics.frame_reset end return true end def getResizeFactor return $ResizeFactor ? $ResizeFactor : 1.0 end def ox=(val) rf=getResizeFactor if rf!=1.0 val=(val*rf).to_i val=(val/rf).to_i end wasshown=self.shown? @ox=val.floor @nowshown=(!wasshown && self.shown?) end def oy=(val) rf=getResizeFactor if rf!=1.0 val=(val*rf).to_i val=(val/rf).to_i end wasshown=self.shown? @oy=val.floor @nowshown=(!wasshown && self.shown?) end def visible=(val) wasshown=@visible @visible=val @nowshown=(!wasshown && val) end def refresh(autotiles=false) @oldOx=@ox @oldOy=@oy usesprites=false if @layer0 @layer0.visible=@visible usesprites=!refreshLayer0(autotiles) if autotiles && !usesprites return end else usesprites=true end refreshFlashSprite vpx=@viewport.rect.x vpy=@viewport.rect.y vpr=@viewport.rect.width+vpx vpb=@viewport.rect.height+vpy xsize=@map_data.xsize ysize=@map_data.ysize minX=(@ox/@tileWidth)-1 maxX=((@ox+@viewport.rect.width)/@tileWidth)+1 minY=(@oy/@tileHeight)-1 maxY=((@oy+@viewport.rect.height)/@tileHeight)+1 minX=0 if minX<0 minX=xsize-1 if minX>=xsize maxX=0 if maxX<0 maxX=xsize-1 if maxX>=xsize minY=0 if minY<0 minY=ysize-1 if minY>=ysize maxY=0 if maxY<0 maxY=ysize-1 if maxY>=ysize count=0 if minX<maxX && minY<maxY @usedsprites=usesprites || @usedsprites if @layer0 @layer0.visible=false if usesprites end if @fullyrefreshed if !@priotilesrect || !@priotilesfast || @priotilesrect[0]!=minX || @priotilesrect[1]!=minY || @priotilesrect[2]!=maxX || @priotilesrect[3]!=maxY @priotilesfast=@priotiles.find_all{|tile| x=tile[0] y=tile[1] # "next" means "return" here next !(x<minX||x>maxX||y<minY||y>maxY) } @priotilesrect=[minX,minY,maxX,maxY] end # echoln [minX,minY,maxX,maxY,@priotilesfast.length,@priotiles.length] for prio in @priotilesfast xpos=(prio[0]*@tileWidth)-@ox ypos=(prio[1]*@tileHeight)-@oy count=addTile(@tiles,count,xpos,ypos,prio[3]) end else if !@priotilesrect || !@priotilesfast || @priotilesrect[0]!=minX || @priotilesrect[1]!=minY || @priotilesrect[2]!=maxX || @priotilesrect[3]!=maxY @priotilesfast=[] for z in 0...@map_data.zsize for y in minY..maxY for x in minX..maxX id = @map_data[x, y, z] next if id==0 || !@priorities[id] next if @priorities[id]==0 @priotilesfast.push([x,y,z,id]) end end end @priotilesrect=[minX,minY,maxX,maxY] end for prio in @priotilesfast xpos=(prio[0]*@tileWidth)-@ox ypos=(prio[1]*@tileHeight)-@oy count=addTile(@tiles,count,xpos,ypos,prio[3]) end end end if count<@tiles.length bigchange=(count<=(@tiles.length*2/3)) && (@tiles.length*2/3)>25 j=count;len=@tiles.length;while j<len sprite=@tiles[j] @tiles[j+1]=-1 if bigchange sprite.dispose @tiles[j]=nil @tiles[j+1]=nil elsif !@tiles[j].disposed? sprite.visible=false if sprite.visible end j+=2 end @tiles.compact! if bigchange end end end class SynchronizedTilemapAutotilesInternal def initialize(oldat) @atdisposables=[[],[],[],[],[],[],[]] @atframes=[[],[],[],[],[],[],[]] @atframe=[-1,-1,-1,-1,-1,-1,-1] @autotiles=[] @oldat=oldat end def dispose for i in 0...7 for bitmap in @atdisposables[i] bitmap.dispose end @atdisposables[i].clear @atframes[i].clear end end def [](i) return @autotiles[i] end def []=(i,value) for frame in @atdisposables[i] frame.dispose end @atframe[i]=-1 @atframes[i].clear @atdisposables[i].clear if value && !value.disposed? if value.height==32 frames=value.width/32 for j in 0...frames @atdisposables[i][j]=Bitmap.new(32,32) @atdisposables[i][j].blt(0,0,value,Rect.new(j*32,0,32,32)) @atframes[i][j]=@atdisposables[i][j] end elsif value.height==128 frames=value.width/96 for j in 0...frames @atdisposables[i][j]=Bitmap.new(96,128) @atdisposables[i][j].blt(0,0,value,Rect.new(j*96,0,96,128)) @atframes[i][j]=@atdisposables[i][j] end else @atframes[i][0]=value end else @atframes[i][0]=value end @autotiles[i]=value sync end def sync frameused=[] for i in 0...7 frames=[1,@atframes[i].length].max frame=(Graphics.frame_count/15)%frames if frames>1 && @atframe[i]!=frame @oldat[i]=@atframes[i][frame] @atframe[i]=frame end end end end class SynchronizedTilemapAutotiles def initialize(autotiles) @autotiles=autotiles end def [](i) @autotiles[i] end def []=(i,value) @autotiles[i]=value end end class SynchronizedTilemap < Tilemap # This class derives from Tilemap just to synchronize # the tilemap animation. attr_accessor :numupdates def initialize(viewport=nil) super(viewport) @updating=true @autotiles=SynchronizedTilemapAutotilesInternal.new(self.autotiles) @autos=SynchronizedTilemapAutotiles.new(@autotiles) @updating=false end def dispose @autotiles.dispose super end def autotiles if @updating super else return @autos end end def update return if disposed? @autotiles.sync super end end
TilemapLoader
[
Selecionar
] [
-
]
class TilemapLoader def initialize(viewport) @viewport=viewport @tilemap=nil @color=Color.new(0,0,0,0) @tone=Tone.new(0,0,0,0) updateClass end def updateClass case $PokemonSystem.tilemap when 1 setClass(CustomTilemap) when 2 setClass(Draw_Tilemap) else if Tilemap.method_defined?(:passages) setClass(CustomTilemap) else setClass($ResizeFactor==1.0 ? SynchronizedTilemap : CustomTilemap) end end end def setClass(cls) newtilemap=cls.new(@viewport) if @tilemap newtilemap.tileset=@tilemap.tileset newtilemap.map_data=@tilemap.map_data newtilemap.flash_data=@tilemap.flash_data newtilemap.priorities=@tilemap.priorities newtilemap.visible=@tilemap.visible newtilemap.ox=@tilemap.ox newtilemap.oy=@tilemap.oy for i in 0...7 newtilemap.autotiles[i]=@tilemap.autotiles[i] end @tilemap.dispose @tilemap=newtilemap newtilemap.update if cls!=SynchronizedTilemap else @tilemap=newtilemap end end def tone @tilemap.tone rescue @tone end def tone=(value) @tilemap.tone=value rescue nil end def disposed? @tilemap && @tilemap.disposed? end def dispose @tilemap.dispose end def update @tilemap.update end def viewport @tilemap.viewport end def autotiles @tilemap.autotiles end def tileset @tilemap.tileset end def tileset=(v) @tilemap.tileset=v end def map_data @tilemap.map_data end def map_data=(v) @tilemap.map_data=v end def flash_data @tilemap.flash_data end def flash_data=(v) @tilemap.flash_data=v end def priorities @tilemap.priorities end def priorities=(v) @tilemap.priorities=v end def visible @tilemap.visible end def visible=(v) @tilemap.visible=v end def ox @tilemap.ox end def ox=(v) @tilemap.ox=v end def oy @tilemap.oy end def oy=(v) @tilemap.oy=v end end
TileDrawingHelper
[
Selecionar
] [
-
]
class TileDrawingHelper Autotiles = [ [ [27, 28, 33, 34], [ 5, 28, 33, 34], [27, 6, 33, 34], [ 5, 6, 33, 34], [27, 28, 33, 12], [ 5, 28, 33, 12], [27, 6, 33, 12], [ 5, 6, 33, 12] ], [ [27, 28, 11, 34], [ 5, 28, 11, 34], [27, 6, 11, 34], [ 5, 6, 11, 34], [27, 28, 11, 12], [ 5, 28, 11, 12], [27, 6, 11, 12], [ 5, 6, 11, 12] ], [ [25, 26, 31, 32], [25, 6, 31, 32], [25, 26, 31, 12], [25, 6, 31, 12], [15, 16, 21, 22], [15, 16, 21, 12], [15, 16, 11, 22], [15, 16, 11, 12] ], [ [29, 30, 35, 36], [29, 30, 11, 36], [ 5, 30, 35, 36], [ 5, 30, 11, 36], [39, 40, 45, 46], [ 5, 40, 45, 46], [39, 6, 45, 46], [ 5, 6, 45, 46] ], [ [25, 30, 31, 36], [15, 16, 45, 46], [13, 14, 19, 20], [13, 14, 19, 12], [17, 18, 23, 24], [17, 18, 11, 24], [41, 42, 47, 48], [ 5, 42, 47, 48] ], [ [37, 38, 43, 44], [37, 6, 43, 44], [13, 18, 19, 24], [13, 14, 43, 44], [37, 42, 43, 48], [17, 18, 47, 48], [13, 18, 43, 48], [ 1, 2, 7, 8] ] ] # converts neighbors returned from tableNeighbors to tile indexes NeighborsToTiles=[ 46, 44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40, 42, 32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16, 46, 44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40, 42, 32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16, 45, 39, 45, 39, 33, 31, 33, 29, 45, 39, 45, 39, 33, 31, 33, 29, 37, 27, 37, 27, 23, 15, 23, 13, 37, 27, 37, 27, 22, 11, 22, 9, 45, 39, 45, 39, 33, 31, 33, 29, 45, 39, 45, 39, 33, 31, 33, 29, 36, 26, 36, 26, 21, 7, 21, 5, 36, 26, 36, 26, 20, 3, 20, 1, 46, 44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40, 42, 32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16, 46, 44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40, 42, 32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16, 45, 38, 45, 38, 33, 30, 33, 28, 45, 38, 45, 38, 33, 30, 33, 28, 37, 25, 37, 25, 23, 14, 23, 12, 37, 25, 37, 25, 22, 10, 22, 8, 45, 38, 45, 38, 33, 30, 33, 28, 45, 38, 45, 38, 33, 30, 33, 28, 36, 24, 36, 24, 21, 6, 21, 4, 36, 24, 36, 24, 20, 2, 20, 0 ] def self.tableNeighbors(data,x,y) return 0 if x>=data.xsize || x<0 return 0 if y>=data.ysize || y<0 t=data[x,y] xp1=[x+1,data.xsize-1].min yp1=[y+1,data.ysize-1].min xm1=[x-1,0].max ym1=[y-1,0].max i=0 i|=0x01 if data[x ,ym1]==t # N i|=0x02 if data[xp1,ym1]==t # NE i|=0x04 if data[xp1,y ]==t # E i|=0x08 if data[xp1,yp1]==t # SE i|=0x10 if data[x ,yp1]==t # S i|=0x20 if data[xm1,yp1]==t # SW i|=0x40 if data[xm1,y ]==t # W i|=0x80 if data[xm1,ym1]==t # NW return i end attr_accessor :tileset attr_accessor :autotiles def initialize(tileset,autotiles) @tileset=tileset @autotiles=autotiles end def self.fromTileset(tileset) bmtileset=RPG::Cache.tileset(tileset.tileset_name) bmautotiles=[] for i in 0...7 bmautotiles.push(RPG::Cache.autotile(tileset.autotile_names[i])) end return self.new(bmtileset,bmautotiles) end def bltSmallAutotile(bitmap,x,y,cxTile,cyTile,id,frame) return if frame<0 || !@autotiles || id>=384 autotile=@autotiles[id/48-1] return if !autotile || autotile.disposed? cxTile=[cxTile/2,1].max cyTile=[cyTile/2,1].max if autotile.height==32 anim=frame*32 src_rect=Rect.new(anim,0,32,32) bitmap.stretch_blt(Rect.new(x,y,cxTile*2,cyTile*2),autotile,src_rect) else anim=frame*96 id%=48 tiles = TileDrawingHelper::Autotiles[id>>3][id&7] src=Rect.new(0,0,0,0) for i in 0...4 tile_position = tiles[i] - 1 src.set(tile_position % 6 * 16 + anim, tile_position / 6 * 16, 16, 16) bitmap.stretch_blt(Rect.new(i%2*cxTile+x,i/2*cyTile+y,cxTile,cyTile), autotile, src) end end end def bltSmallRegularTile(bitmap,x,y,cxTile,cyTile,id) return if !@tileset || id<384 || @tileset.disposed? rect=Rect.new((id - 384) % 8 * 32, (id - 384) / 8 * 32,32,32) bitmap.stretch_blt(Rect.new(x,y,cxTile,cyTile),@tileset,rect) end def bltSmallTile(bitmap,x,y,cxTile,cyTile,id,frame=0) if id>=384 bltSmallRegularTile(bitmap,x,y,cxTile,cyTile,id) elsif id>0 bltSmallAutotile(bitmap,x,y,cxTile,cyTile,id,frame) end end def bltAutotile(bitmap,x,y,id,frame) bltSmallAutotile(bitmap,x,y,32,32,id,frame) end def bltRegularTile(bitmap,x,y,id) bltSmallRegularTile(bitmap,x,y,32,32,id) end def bltTile(bitmap,x,y,id,frame=0) if id>=384 bltRegularTile(bitmap,x,y,id) elsif id>0 bltAutotile(bitmap,x,y,id,frame) end end end
PBFile
[
Selecionar
] [
-
]
module FileInputMixin def fgetb x=0 ret=0 each_byte do |i| ret=i break end return ret end def fgetw x=0 ret=0 each_byte do |i| ret|=(i<<x) x+=8 break if x==16 end return ret end def fgetdw x=0 ret=0 each_byte do |i| ret|=(i<<x) x+=8 break if x==32 end return ret end def fgetsb ret=fgetb if (ret&0x80)!=0 return ret-256 else return ret end end def xfgetb(offset) self.pos=offset return fgetb end def xfgetw(offset) self.pos=offset return fgetw end def xfgetdw(offset) self.pos=offset return fgetdw end def getOffset(index) self.binmode self.pos=0 offset=fgetdw>>3 return 0 if index>=offset self.pos=index*8 return fgetdw end def getLength(index) self.binmode self.pos=0 offset=fgetdw>>3 return 0 if index>=offset self.pos=index*8+4 return fgetdw end def readName(index) self.binmode self.pos=0 offset=fgetdw>>3 return "" if index>=offset self.pos=index<<3 offset=fgetdw length=fgetdw return "" if length==0 self.pos=offset return read(length) end end module FileOutputMixin def fputb(b) b=b&0xFF write(b.chr) end def fputw(w) 2.times do b=w&0xFF write(b.chr) w>>=8 end end def fputdw(w) 4.times do b=w&0xFF write(b.chr) w>>=8 end end end class File < IO =begin class << self alias debugopen open def open(f,m="r") debugopen("debug.txt","ab"){|file| file.write([f,m].inspect+"\\r\\n") } if block_given? debugopen(f,m) {|file| yield file } else return debugopen(f,m) end end end =end include FileInputMixin include FileOutputMixin end class StringInput include FileInputMixin def pos=(value) seek(value) end def each_byte while !eof? yield getc end end def binmode end end class StringOutput include FileOutputMixin end
PBIntl
[
Selecionar
] [
-
]
def pbAddScriptTexts(items,script) script.scan(/(?:_I)\\s*\\(\\s*\\"((?:[^\\\\\\"]*\\\\\\"?)*[^\\"]*)\\"/){|s| string=s[0] string.gsub!(/\\\\\\"/,"\\"") string.gsub!(/\\\\\\\\/,"\\\\") items.push(string) } end def pbAddRgssScriptTexts(items,script) script.scan(/(?:_INTL|_ISPRINTF)\\s*\\(\\s*\\"((?:[^\\\\\\"]*\\\\\\"?)*[^\\"]*)\\"/){|s| string=s[0] string.gsub!(/\\\\r/,"\\r") string.gsub!(/\\\\n/,"\\n") string.gsub!(/\\\\1/,"\\1") string.gsub!(/\\\\\\"/,"\\"") string.gsub!(/\\\\\\\\/,"\\\\") items.push(string) } end def pbSetTextMessages Graphics.update begin mapinfos = load_data("Data/MapInfos.rxdata") t = Time.now.to_i messages=[] texts=[] for script in $RGSS_SCRIPTS if Time.now.to_i - t >= 5 t = Time.now.to_i Graphics.update end scr=Zlib::Inflate.inflate(script[2]) pbAddRgssScriptTexts(texts,scr) end mapnames=[] for id in mapinfos.keys mapnames[id]=mapinfos[id].name end MessageTypes.setMessages(MessageTypes::MapNames,mapnames) # Must add messages since this code is shared by game system # and editor MessageTypes.addMapMessagesAsHash(0,texts) for id in mapinfos.keys if Time.now.to_i - t >= 5 t = Time.now.to_i Graphics.update end filename=sprintf("Data/Map%03d.rxdata",id) next if !pbRgssExists?(filename) map = load_data(filename) items=[] choices=[] for event in map.events.values if Time.now.to_i - t >= 5 t = Time.now.to_i Graphics.update end begin for i in 0...event.pages.size neednewline=false lastitem="" for j in 0...event.pages[i].list.size list = event.pages[i].list[j] if neednewline && list.code!=401 if lastitem!="" lastitem.gsub!(/([^\\.\\!\\?])\\s\\s+/){|m| $1+" "} items.push(lastitem) lastitem="" end neednewline=false end if list.code == 101 lastitem+="#{list.parameters[0]}" neednewline=true elsif list.code == 102 for k in 0...list.parameters[0].length choices.push(list.parameters[0][k]) end neednewline=false elsif list.code == 401 lastitem+=" #{list.parameters[0]}" neednewline=true elsif list.code == 355 || list.code==655 pbAddScriptTexts(items,list.parameters[0]) elsif list.code == 111 && list.parameters[0]==12 pbAddScriptTexts(items,list.parameters[1]) elsif list.code==209 route=list.parameters[1] for k in 0...route.list.size if route.list[k].code==45 pbAddScriptTexts(items,route.list[k].parameters[0]) end end end end if neednewline if lastitem!="" items.push(lastitem) lastitem="" end end end end end if Time.now.to_i - t >= 5 t = Time.now.to_i Graphics.update end items|=[] choices|=[] items.concat(choices) MessageTypes.setMapMessagesAsHash(id,items) if Time.now.to_i - t >= 5 t = Time.now.to_i Graphics.update end end rescue Hangup end Graphics.update end def pbEachIntlSection(file) lineno=1 re=/^\\s*\\[\\s*([^\\]]+)\\s*\\]\\s*$/ havesection=false sectionname=nil lastsection=[] file.each_line {|line| if lineno==1&&line[0]==0xEF&&line[1]==0xBB&&line[2]==0xBF line=line[3,line.length-3] end if !line[/^\\#/] && !line[/^\\s*$/] if line[re] if havesection yield lastsection,sectionname end lastsection.clear sectionname=$~[1] havesection=true else if sectionname==nil raise _INTL("Expected a section at the beginning of the file (line {1})",lineno) end lastsection.push(line.gsub(/\\s+$/,"")) end end lineno+=1 if lineno%500==0 Graphics.update end } if havesection yield lastsection,sectionname end end def pbGetText(infile) begin file=File.open(infile,"rb") rescue raise _INTL("Can't find {1}",infile) end intldat=[] begin pbEachIntlSection(file){|section,name| index=name if section.length==0 next end if !name[/^([Mm][Aa][Pp])?(\\d+)$/] raise _INTL("Invalid section name {1}",name) end ismap=$~[1] && $~[1]!="" id=$~[2].to_i itemlength=0 if section[0][/^\\d+$/] intlhash=[] itemlength=3 if ismap raise _INTL("Section {1} can't be an ordered list (section was recognized as an ordered list because its first line is a number)",name) end if section.length%3!=0 raise _INTL("Section {1}'s line count is not divisible by 3 (section was recognized as an ordered list because its first line is a number)",name) end else intlhash=OrderedHash.new itemlength=2 if section.length%2!=0 raise _INTL("Section {1} has an odd number of entries (section was recognized as a hash because its first line is not a number)",name) end end i=0;loop do break unless i<section.length if itemlength==3 if !section[i][/^\\d+$/] raise _INTL("Expected a number in section {1}, got {2} instead",name,section[i]) end key=section[i].to_i i+=1 else key=MessageTypes.denormalizeValue(section[i]) end intlhash[key]=MessageTypes.denormalizeValue(section[i+1]) i+=2 end if ismap intldat[0]=[] if !intldat[0] intldat[0][id]=intlhash else intldat[id]=intlhash end } ensure file.close end return intldat end def pbCompileText outfile=File.open("intl.dat","wb") begin intldat=pbGetText("intl.txt") Marshal.dump(intldat,outfile) rescue raise ensure outfile.close end end class OrderedHash < Hash def initialize @keys=[] super end def keys return @keys.clone end def inspect str="{" for i in 0...@keys.length str+=", " if i>0 str+=@keys[i].inspect+"=>"+self[@keys[i]].inspect end str+="}" return str end alias :to_s :inspect def []=(key,value) oldvalue=self[key] if !oldvalue && value @keys.push(key) elsif !value @keys|=[] @keys-=[key] end return super(key,value) end def self._load(string) ret=self.new keysvalues=Marshal.load(string) keys=keysvalues[0] values=keysvalues[1] for i in 0...keys.length ret[keys[i]]=values[i] end return ret end def _dump(depth=100) values=[] for key in @keys values.push(self[key]) end return Marshal.dump([@keys,values]) end end class Messages def initialize(filename=nil,delayLoad=false) @messages=nil @filename=filename if @filename && !delayLoad loadMessageFile(@filename) end end def delayedLoad if @filename && !@messages loadMessageFile(@filename) @filename=nil end end def self.stringToKey(str) if str[/[\\r\\n\\t\\1]|^\\s+|\\s+$|\\s{2,}/] key=str.clone key.gsub!(/^\\s+/,"") key.gsub!(/\\s+$/,"") key.gsub!(/\\s{2,}/," ") return key end return str end def self.normalizeValue(value) if value[/[\\r\\n\\t\\x01]|^[\\[\\]]/] ret=value.clone ret.gsub!(/\\r/,"<<r>>") ret.gsub!(/\\n/,"<<n>>") ret.gsub!(/\\t/,"<<t>>") ret.gsub!(/\\[/,"<<[>>") ret.gsub!(/\\]/,"<<]>>") ret.gsub!(/\\x01/,"<<1>>") return ret end return value end def self.denormalizeValue(value) if value[/<<[rnt1\\[\\]]>>/] ret=value.clone ret.gsub!(/<<1>>/,"\\1") ret.gsub!(/<<r>>/,"\\r") ret.gsub!(/<<n>>/,"\\n") ret.gsub!(/<<\\[>>/,"[") ret.gsub!(/<<\\]>>/,"]") ret.gsub!(/<<t>>/,"\\t") return ret end return value end def self.writeObject(f,msgs,secname,origMessages=nil) return if !msgs if msgs.is_a?(Array) f.write("[#{secname}]\\r\\n") for j in 0...msgs.length next if msgs[j]==nil || msgs[j]=="" value=Messages.normalizeValue(msgs[j]) origValue="" if origMessages origValue=Messages.normalizeValue(origMessages.get(secname,j)) else origValue=Messages.normalizeValue(MessageTypes.get(secname,j)) end f.write("#{j}\\r\\n") f.write(origValue+"\\r\\n") f.write(value+"\\r\\n") end elsif msgs.is_a?(OrderedHash) f.write("[#{secname}]\\r\\n") keys=msgs.keys for key in keys next if msgs[key]==nil || msgs[key]=="" value=Messages.normalizeValue(msgs[key]) valkey=Messages.normalizeValue(key) # key is already serialized f.write(valkey+"\\r\\n") f.write(value+"\\r\\n") end end end def messages return @messages || [] end def extract(outfile) return if !@messages origMessages=Messages.new("Data/messages.dat") File.open(outfile,"wb"){|f| f.write(0xef.chr) f.write(0xbb.chr) f.write(0xbf.chr) f.write("# To localize this text for a particular language, please\\r\\n") f.write("# translate every second line of this file.\\r\\n") if @messages[0] for i in 0...@messages[0].length msgs=@messages[0][i] Messages.writeObject(f,msgs,"Map#{i}",origMessages) end end for i in 1...@messages.length msgs=@messages[i] Messages.writeObject(f,msgs,i,origMessages) end } end def setMessages(type,array) arr=[] @messages=[] if !@messages for i in 0...array.length arr[i]=(array[i]) ? array[i] : "" end @messages[type]=arr end def self.createHash(type,array) arr=OrderedHash.new for i in 0...array.length if array[i] key=Messages.stringToKey(array[i]) arr[key]=array[i] end end return arr end def self.addToHash(type,array,hash) if !hash hash=OrderedHash.new end for i in 0...array.length if array[i] key=Messages.stringToKey(array[i]) hash[key]=array[i] end end return hash end def setMapMessagesAsHash(type,array) @messages=[] if !@messages @messages[0]=[] if !@messages[0] @messages[0][type]=Messages.createHash(type,array) end def addMapMessagesAsHash(type,array) @messages=[] if !@messages @messages[0]=[] if !@messages[0] @messages[0][type]=Messages.addToHash(type,array,@messages[0][type]) end def setMessagesAsHash(type,array) @messages=[] if !@messages @messages[type]=Messages.createHash(type,array) end def saveMessages(filename=nil) filename="Data/messages.dat" if !filename File.open(filename,"wb"){|f| Marshal.dump(@messages,f) } end def loadMessageFile(filename) begin Kernel.pbRgssOpen(filename,"rb"){|f| @messages=Marshal.load(f) } if !@messages.is_a?(Array) @messages=nil raise "Corrupted data" end return @messages rescue @messages=nil return nil end end def set(type,id,value) delayedLoad return if !@messages return if !@messages[type] @messages[type][id]=value end def get(type,id) delayedLoad return "" if !@messages return "" if !@messages[type] return "" if !@messages[type][id] return @messages[type][id] end def getFromHash(type,key) delayedLoad return key if !@messages return key if !@messages[type] id=Messages.stringToKey(key) return key if !@messages[type][id] return @messages[type][id] end def getFromMapHash(type,key) delayedLoad return key if !@messages return key if !@messages[0] return key if !@messages[0][type] id=Messages.stringToKey(key) return key if !@messages[0][type][id] return @messages[0][type][id] end end module MessageTypes Species=1 Items=2 Entries=3 Kinds=4 Moves=5 StorageCreator=6 TrainerTypes=7 TrainerNames=8 RegionNames=9 PlaceNames=10 ItemDescriptions=11 MoveDescriptions=12 Abilities=13 AbilityDescs=14 PhoneMessages=15 MapNames=16 @@messages=Messages.new @@messagesFallback=Messages.new("Data/messages.dat",true) def self.stringToKey(str) return Messages.stringToKey(str) end def self.normalizeValue(value) return Messages.normalizeValue(value) end def self.denormalizeValue(value) Messages.denormalizeValue(value) end def self.writeObject(f,msgs,secname) Messages.denormalizeValue(str) end def self.extract(outfile) @@messages.extract(outfile) end def self.setMessages(type,array) @@messages.setMessages(type,array) end def self.createHash(type,array) Messages.createHash(type,array) end def self.addMapMessagesAsHash(type,array) @@messages.addMapMessagesAsHash(type,array) end def self.setMapMessagesAsHash(type,array) @@messages.setMapMessagesAsHash(type,array) end def self.setMessagesAsHash(type,array) @@messages.setMessagesAsHash(type,array) end def self.saveMessages(filename=nil) @@messages.saveMessages(filename) end def self.loadMessageFile(filename) @@messages.loadMessageFile(filename) end def self.get(type,id) ret=@@messages.get(type,id) if ret=="" ret=@@messagesFallback.get(type,id) end return ret end def self.getOriginal(type,id) return @@messagesFallback.get(type,id) end def self.getFromHash(type,key) @@messages.getFromHash(type,key) end def self.getFromMapHash(type,key) @@messages.getFromMapHash(type,key) end end def pbLoadMessages(file) return MessageTypes.loadMessageFile(file) end def pbGetMessage(type,id) return MessageTypes.get(type,id) end def pbGetMessageFromHash(type,id) return MessageTypes.getFromHash(type,id) end # Replaces first argument with a localized version and # formats the other parameters by replacing {1}, {2}, etc. # with those placeholders. def _INTL(*arg) begin string=MessageTypes.getFromMapHash(0,arg[0]) rescue string=arg[0] end string=string.clone for i in 1...arg.length string.gsub!(/\\{#{i}\\}/,"#{arg[i]}") end return string end # Replaces first argument with a localized version and # formats the other parameters by replacing {1}, {2}, etc. # with those placeholders. # This version acts more like sprintf, supports e.g. {1:d} or {2:s} def _ISPRINTF(*arg) begin string=MessageTypes.getFromMapHash(0,arg[0]) rescue string=arg[0] end string=string.clone for i in 1...arg.length string.gsub!(/\\{#{i}\\:([^\\}]+?)\\}/){|m| next sprintf("%"+$1,arg[i]) } end return string end def _I(str) return _MAPINTL($game_map.map_id,str) end def _MAPINTL(mapid,*arg) string=MessageTypes.getFromMapHash(mapid,arg[0]) string=string.clone for i in 1...arg.length string.gsub!(/\\{#{i}\\}/,"#{arg[i]}") end return string end def _MAPISPRINTF(mapid,*arg) string=MessageTypes.getFromMapHash(mapid,arg[0]) string=string.clone for i in 1...arg.length string.gsub!(/\\{#{i}\\:([^\\}]+?)\\}/){|m| next sprintf("%"+$1,arg[i]) } end return string end
PBMove
[
Selecionar
] [
-
]
class PBMoveData attr_reader :function,:basedamage,:type,:accuracy attr_reader :totalpp,:addlEffect,:target,:priority attr_reader :flags attr_reader :contestType,:category def initializeOld(moveid) movedata=pbRgssOpen("Data/rsattacks.dat") movedata.pos=moveid*9 @function=movedata.fgetb @basedamage=movedata.fgetb @type=movedata.fgetb @accuracy=movedata.fgetb @totalpp=movedata.fgetb @addlEffect=movedata.fgetb @target=movedata.fgetb @priority=movedata.fgetsb @flags=movedata.fgetb movedata.close end def initialize(moveid) movedata=pbRgssOpen("Data/moves.dat") movedata.pos=moveid*13 @function=movedata.fgetw @basedamage=movedata.fgetb @type=movedata.fgetb @category=movedata.fgetb @accuracy=movedata.fgetb @totalpp=movedata.fgetb @addlEffect=movedata.fgetb @target=movedata.fgetw @priority=movedata.fgetsb @flags=movedata.fgetb @contestType=movedata.fgetb movedata.close end end class PBMove attr_accessor(:id) attr_accessor(:pp) attr_accessor(:ppup) attr_reader(:type) def totalpp return @totalpp+(@totalpp*@ppup/5).floor end def initialize(moveid) movedata=PBMoveData.new(moveid) @totalpp=movedata.totalpp @type=movedata.type @pp=@totalpp @id=moveid @ppup=0 end end
PBStatuses
[
Selecionar
] [
-
]
#70925035 begin class PBStatuses SLEEP=1 POISON=2 BURN=3 PARALYSIS=4 FROZEN=5 end rescue Exception if $!.is_a?(SystemExit) || "#{$!.class}"=="Reset" raise $! else end end
PBTypes
[
Selecionar
] [
-
]
class PBTypes NORMAL=0 FIGHTING=1 FLYING=2 POISON=3 GROUND=4 ROCK=5 BUG=6 GHOST=7 STEEL=8 QMARKS=9 FIRE=10 WATER=11 GRASS=12 ELECTRIC=13 PSYCHIC=14 ICE=15 DRAGON=16 DARK=17 def PBTypes.getCount # Change this number if you add a new type # This number doesn't include QMARKS return 17 end PBTypeChart=[ # Rows indicate the attack's type # Columns indicate the opponent's type # 0 - Immune # 1 - "Not very effective" # 2 - Normal # 4 - "Super effective" # When you add a new type, add a number showing effect # on opponents with that type to each line, then add a # new line showing effect on attacks with the new type # on opponents. 2,2,2,2,2,1,2,0,1,2,2,2,2,2,2,2,2, 4,2,1,1,2,4,1,0,4,2,2,2,2,1,4,2,4, 2,4,2,2,2,1,4,2,1,2,2,4,1,2,2,2,2, 2,2,2,1,1,1,2,1,0,2,2,4,2,2,2,2,2, 2,2,0,4,2,4,1,2,4,4,2,1,4,2,2,2,2, 2,1,4,2,1,2,4,2,1,4,2,2,2,2,4,2,2, 2,1,1,1,2,2,2,1,1,1,2,4,2,4,2,2,4, 0,2,2,2,2,2,2,4,1,2,2,2,2,4,2,2,1, 2,2,2,2,2,4,2,2,1,1,1,2,1,2,4,2,2, 2,2,2,2,2,1,4,2,4,1,1,4,2,2,4,1,2, 2,2,2,2,4,4,2,2,2,4,1,1,2,2,2,1,2, 2,2,1,1,4,4,1,2,1,1,4,1,2,2,2,1,2, 2,2,4,2,0,2,2,2,2,2,4,1,1,2,2,1,2, 2,4,2,4,2,2,2,2,1,2,2,2,2,1,2,2,0, 2,2,4,2,4,2,2,2,1,1,1,4,2,2,1,4,2, 2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,4,2, 2,1,2,2,2,2,2,4,1,2,2,2,2,4,2,2,1 ] def PBTypes.getName(type) # Add the names of new types at the end of # this list types=[ _INTL("NORMAL"), _INTL("FIGHTING"), _INTL("FLYING"), _INTL("POISON"), _INTL("GROUND"), _INTL("ROCK"), _INTL("BUG"), _INTL("GHOST"), _INTL("STEEL"), _INTL("???"), _INTL("FIRE"), _INTL("WATER"), _INTL("GRASS"), _INTL("ELECTRIC"), _INTL("PSYCHIC"), _INTL("ICE"), _INTL("DRAGON"), _INTL("DARK") ] return types[type] end end
PBWeather
[
Selecionar
] [
-
]
#11045744 begin class PBWeather SUNNYDAY=1 RAINDANCE=2 SANDSTORM=3 HAIL=4 end rescue Exception if $!.is_a?(SystemExit) || "#{$!.class}"=="Reset" raise $! else end end
PBExperience
[
Selecionar
] [
-
]
module PBExperience @PBExpTable=[ 0,1,8,27,64,125,216,343,512,729, 1000,1331,1728,2197,2744,3375,4096,4913,5832,6859, 8000,9261,10648,12167,13824,15625,17576,19683,21952,24389, 27000,29791,32768,35937,39304,42875,46656,50653,54872,59319, 64000,68921,74088,79507,85184,91125,97336,103823,110592,117649, 125000,132651,140608,148877,157464,166375,175616,185193,195112,205379, 216000,226981,238328,250047,262144,274625,287496,300763,314432,328509, 343000,357911,373248,389017,405224,421875,438976,456533,474552,493039, 512000,531441,551368,571787,592704,614125,636056,658503,681472,704969, 729000,753571,778688,804357,830584,857375,884736,912673,941192,970299,1000000, 0,1,15,52,122,237,406,637,942,1326, 1800,2369,3041,3822,4719,5737,6881,8155,9564,11111, 12800,14632,16610,18737,21012,23437,26012,28737,31610,34632, 37800,41111,44564,48155,51881,55737,59719,63822,68041,72369, 76800,81326,85942,90637,95406,100237,105122,110052,115015,120001, 125000,131324,137795,144410,151165,158056,165079,172229,179503,186894, 194400,202013,209728,217540,225443,233431,241496,249633,257834,267406, 276458,286328,296358,305767,316074,326531,336255,346965,357812,367807, 378880,390077,400293,411686,423190,433572,445239,457001,467489,479378, 491346,501878,513934,526049,536557,548720,560922,571333,583539,591882,600000, 0,1,4,13,32,65,112,178,276,393, 540,745,967,1230,1591,1957,2457,3046,3732,4526, 5440,6482,7666,9003,10506,12187,14060,16140,18439,20974, 23760,26811,30146,33780,37731,42017,46656,50653,55969,60505, 66560,71677,78533,84277,91998,98415,107069,114205,123863,131766, 142500,151222,163105,172697,185807,196322,210739,222231,238036,250562, 267840,281456,300293,315059,335544,351520,373744,390991,415050,433631, 459620,479600,507617,529063,559209,582187,614566,639146,673863,700115, 737280,765275,804997,834809,877201,908905,954084,987754,1035837,1071552, 1122660,1160499,1214753,1254796,1312322,1354652,1415577,1460276,1524731,1571884,1640000, 0,1,9,57,96,135,179,236,314,419, 560,742,973,1261,1612,2035,2535,3120,3798,4575, 5460,6458,7577,8825,10208,11735,13411,15244,17242,19411, 21760,24294,27021,29949,33084,36435,40007,43808,47846,52127, 56660,61450,66505,71833,77440,83335,89523,96012,102810,109923, 117360,125126,133229,141677,150476,159635,169159,179056,189334,199999, 211060,222522,234393,246681,259392,272535,286115,300140,314618,329555, 344960,360838,377197,394045,411388,429235,447591,466464,485862,505791, 526260,547274,568841,590969,613664,636935,660787,685228,710266,735907, 762160,789030,816525,844653,873420,902835,932903,963632,995030,1027103,1059860, 0,1,6,21,51,100,172,274,409,583, 800,1064,1382,1757,2195,2700,3276,3930,4665,5487, 6400,7408,8518,9733,11059,12500,14060,15746,17561,19511, 21600,23832,26214,28749,31443,34300,37324,40522,43897,47455, 51200,55136,59270,63605,68147,72900,77868,83058,88473,94119, 100000,106120,112486,119101,125971,133100,140492,148154,156089,164303, 172800,181584,190662,200037,209715,219700,229996,240610,251545,262807, 274400,286328,298598,311213,324179,337500,351180,365226,379641,394431, 409600,425152,441094,457429,474163,491300,508844,526802,545177,563975, 583200,602856,622950,643485,664467,685900,707788,730138,752953,776239,800000, 0,1,10,33,80,156,270,428,640,911, 1250,1663,2160,2746,3430,4218,5120,6141,7290,8573, 10000,11576,13310,15208,17280,19531,21970,24603,27440,30486, 33750,37238,40960,44921,49130,53593,58320,63316,68590,74148, 80000,86151,92610,99383,106480,113906,121670,129778,138240,147061, 156250,165813,175760,186096,196830,207968,219520,231491,243890,256723, 270000,283726,297910,312558,327680,343281,359370,375953,393040,410636, 428750,447388,466560,486271,506530,527343,548720,570666,593190,616298, 640000,664301,689210,714733,740880,767656,795070,823128,851840,881211, 911250,941963,973360,1005446,1038230,1071718,1105920,1140841,1176490,1212873,1250000 ] MAXLEVEL=100 =begin Erratic (600000): For levels 0-50: n**3([100-n]/50) For levels 51-68: n**3([150-n]/100) For levels 69-98: n**3(1.274-[1/50][n/3]-p(n mod 3)) where p(x) = array(0.000,0.008,0.014)[x] For levels 99-100: n**3([160-n]/100) Fluctuating (1640000): For levels 0-15: n**3([24+{(n+1)/3}]/50) For levels 16-35: n**3([14+n]/50) For levels 36-100: n**3([32+{n/2}]/50) =end def self.pbGetExpInternal(level,growth) if level>100 # Use formulas for levels greater than 100 case growth when 0 # 1000000 medium return level**3 when 1 # 600000 erratic # Different formula that causes 600000 EXP at level 100 return ( (level**3)*( (level * 6 / 10) / (100*1.0) ) ).floor when 2 # 1640000 fluctuating # Different formula that causes 1640000 EXP at level 100 rate=82 if level>100 # Slow rate with increasing level rate-=(level-100)/2 rate=40 if rate<40 end return ( (level**3)*( (level * rate / 100) / 50.0 ) ).floor when 3 # 1059860 parabolic return (6*(level**3)/5) - 15*(level**2) + 100*level - 140 when 4 # 800000 fast return ( 4*(level**3)/5 ).floor when 5 # 1250000 slow return ( 5*(level**3)/4 ).floor else return 0 end else # Refer to experience table for levels 100 and less return @PBExpTable[growth*101+level] end end def PBExperience.pbGetMaxExperience(growth) if growth>=6 || growth<0 return ArgumentError.new("The growth rate is invalid.") end return pbGetExpInternal(MAXLEVEL,growth) end def PBExperience.pbGetStartExperience(level,growth) if growth>=6 || growth<0 return ArgumentError.new("The growth rate is invalid.") end if level<0 return ArgumentError.new("The level is invalid.") end level=MAXLEVEL if level>MAXLEVEL return pbGetExpInternal(level,growth) end def PBExperience.pbAddExperience(currexp,expgain,growth) if growth>=6 || growth<0 return ArgumentError.new("The growth rate is invalid.") end exp=currexp+expgain maxexp=pbGetExpInternal(MAXLEVEL,growth) exp=maxexp if exp>maxexp return exp end def PBExperience.pbGetLevelFromExperience(exp,growth) if growth>=6 || growth<0 return ArgumentError.new("The growth rate is invalid.") end maxexp=pbGetExpInternal(MAXLEVEL,growth) exp=maxexp if exp>maxexp i=0 for j in 0..MAXLEVEL currentExp=pbGetExpInternal(i,growth) return i if exp==currentExp return i-1 if exp<currentExp i+=1 end return MAXLEVEL end end
PBEnviroment
[
Selecionar
] [
-
]
#52687037 begin class PBEnvironment None=0 Grass=1 TallGrass=2 MovingWater=3 StillWater=4 Underwater=5 Rock=6 Cave=7 Sand=8 end rescue Exception if $!.is_a?(SystemExit) || "#{$!.class}"=="Reset" raise $! else end end
PBStats
[
Selecionar
] [
-
]
#4680357 begin class PBStats ATTACK=0 DEFENSE=1 SPEED=2 SPATK=3 SPDEF=4 ACCURACY=5 EVASION=6 HP=7 end rescue Exception if $!.is_a?(SystemExit) || "#{$!.class}"=="Reset" raise $! else end end
PBEffects
[
Selecionar
] [
-
]
#64103086 begin class PBEffects Attract=0 Bide=2 BideDamage=3 Charge=5 ChoiceBand=6 Confusion=7 Counter=8 Curse=9 DefenseCurl=10 DestinyBond=11 Disable=13 Encore=15 EncoreIndex=16 EncoreMove=17 Endure=18 FlashFire=19 Flinch=20 FocusEnergy=22 FollowMe=23 FuryCutter=24 Grudge=25 HelpingHand=26 HyperBeam=27 Imprison=28 Ingrain=29 LeechSeed=30 LightScreen=31 LockOn=32 LockOnPos=33 MagicCoat=34 MeanLook=35 Mimic=37 Minimize=38 MirrorCoat=39 Mist=40 MudSport=41 MultiTurn=42 Outrage=43 PerishSong=44 Protect=45 ProtectRate=46 Pursuit=47 Rage=48 Reflect=49 Revenge=50 Rollout=51 Safeguard=52 Snatch=53 Spikes=54 Stockpile=56 Substitute=57 Taunt=58 Torment=59 Toxic=60 Transform=61 Truant=62 Uproar=63 WaterSport=64 Foresight=65 Wish=66 WishMaker=67 MirrorMove=68 Conversion2Move=69 Conversion2Type=70 DisableMove=71 TwoTurnAttack=72 MultiTurnAttack=73 Nightmare=74 Yawn=75 RecycleItem=76 BideTarget=77 MultiTurnUser=78 CounterTarget=79 MirrorCoatTarget=80 Trace=81 FutureSight=82 FutureSightMove=83 FutureSightDamage=84 FutureSightUser=85 Pinch=86 end rescue Exception if $!.is_a?(SystemExit) || "#{$!.class}"=="Reset" raise $! else end end
PBAnimation
[
Selecionar
] [
-
]
def yaxisIntersect(x1,y1,x2,y2,px,py) dx=x2-x1 dy=y2-y1 t=0.0 if(dx>0) while(px>x2) x1+=dx x2+=dx y1+=dy y2+=dy t+=1.0 end while(px<x1) x1-=dx x2-=dx y1-=dy y2-=dy t-=1.0 end tv=(px-x1)*1.0/(x2-x1) y=y1+tv*(y2-y1) return [t+tv,py-y] end if(dx<0) while(px<x2) x1+=dx x2+=dx y1+=dy y2+=dy t+=1.0 end while(px>x1) x1-=dx x2-=dx y1-=dy y2-=dy t-=1.0 end tv=(px-x2)*1.0/(x1-x2) y=y2+tv*(y1-y2) return [t+tv,py-y] end if(dx==0) return [0,py-y1] end end def repositionY(x1,y1,x2,y2,t,yDist) dx=x2-x1 dy=y2-y1 while(t<0.0) x1-=dx x2-=dx y1-=dy y2-=dy t+=1.0 end while(t>1.0) x1+=dx x2+=dx y1+=dy y2+=dy t-=1.0 end x=x1+t*1.0*(x2-x1) y=y1+t*1.0*(y2-y1) y+=yDist return [x,y] end def transformPoint( x1,y1,x2,y2, # Source line x3,y3,x4,y4, # Destination line px,py # Source point ) ret=yaxisIntersect(x1,y1,x2,y2,px,py) ret2=repositionY(x3,y3,x4,y4,ret[0],ret[1]) return ret2 end def getSpriteCenter(sprite) if !sprite || sprite.disposed? return [0,0] end if !sprite.bitmap || sprite.bitmap.disposed? return [sprite.x,sprite.y] end centerX=sprite.src_rect.width/2 centerY=sprite.src_rect.height/2 offsetX=(centerX-sprite.ox)*sprite.zoom_x offsetY=(centerY-sprite.oy)*sprite.zoom_y return [sprite.x+offsetX,sprite.y+offsetY] end class AnimFrame X=0 Y=1 ZOOMX=2 ANGLE=3 MIRROR=4 BLENDTYPE=5 VISIBLE=6 PATTERN=7 OPACITY=8 ZOOMY=11 COLORRED=12 COLORGREEN=13 COLORBLUE=14 COLORALPHA=15 TONERED=16 TONEGREEN=17 TONEBLUE=18 TONEGRAY=19 LOCKED=20 FLASHRED=21 FLASHGREEN=22 FLASHBLUE=23 FLASHALPHA=24 end class RPG::Animation def self.fromOther(otherAnim,id) ret=RPG::Animation.new ret.id=id ret.name=otherAnim.name.clone ret.animation_name=otherAnim.animation_name.clone ret.animation_hue=otherAnim.animation_hue ret.position=otherAnim.position return ret end def addSound(frame,se) timing=RPG::Animation::Timing.new timing.frame=frame timing.se=RPG::AudioFile.new(se,100) self.timings.push(timing) end def addAnimation(otherAnim,frame,x,y) # frame is zero-based if frame+otherAnim.frames.length>=self.frames.length totalframes=frame+otherAnim.frames.length+1 for i in self.frames.length...totalframes self.frames.push(RPG::Animation::Frame.new) end end self.frame_max=self.frames.length for i in 0...otherAnim.frame_max thisframe=self.frames[frame+i] otherframe=otherAnim.frames[i] cellStart=thisframe.cell_max thisframe.cell_max+=otherframe.cell_max thisframe.cell_data.resize(thisframe.cell_max,8) for j in 0...otherframe.cell_max thisframe.cell_data[cellStart+j,0]=otherframe.cell_data[j,0] thisframe.cell_data[cellStart+j,1]=otherframe.cell_data[j,1]+x thisframe.cell_data[cellStart+j,2]=otherframe.cell_data[j,2]+y thisframe.cell_data[cellStart+j,3]=otherframe.cell_data[j,3] thisframe.cell_data[cellStart+j,4]=otherframe.cell_data[j,4] thisframe.cell_data[cellStart+j,5]=otherframe.cell_data[j,5] thisframe.cell_data[cellStart+j,6]=otherframe.cell_data[j,6] thisframe.cell_data[cellStart+j,7]=otherframe.cell_data[j,7] end end for i in 0...otherAnim.timings.length timing=RPG::Animation::Timing.new othertiming=otherAnim.timings[i] timing.frame=frame+othertiming.frame timing.se=RPG::AudioFile.new( othertiming.se.name.clone, othertiming.se.volume, othertiming.se.pitch) timing.flash_scope=othertiming.flash_scope timing.flash_color=othertiming.flash_color.clone timing.flash_duration=othertiming.flash_duration timing.condition=othertiming.condition self.timings.push(timing) end self.timings.sort!{|a,b| a.frame<=>b.frame } end end def pbSpriteSetAnimFrame(sprite,frame,ineditor=false) return if !sprite if !frame sprite.visible=false sprite.src_rect=Rect.new(0,0,1,1) return end sprite.blend_type=frame[AnimFrame::BLENDTYPE] sprite.angle=frame[AnimFrame::ANGLE] sprite.mirror=frame[AnimFrame::MIRROR]>0 ? true : false sprite.opacity=frame[AnimFrame::OPACITY] sprite.visible=true if !frame[AnimFrame::VISIBLE]==1 && ineditor sprite.opacity/=2 else sprite.visible=(frame[AnimFrame::VISIBLE]==1) end pattern=frame[AnimFrame::PATTERN] if pattern>=0 sprite.zoom_x=frame[AnimFrame::ZOOMX]/100.0 sprite.zoom_y=frame[AnimFrame::ZOOMY]/100.0 if sprite.bitmap&&!sprite.bitmap.disposed? animwidth=192#sprite.bitmap.width/5 #echo(animwidth.inspect+"\\r\\n") else animwidth=192 end sprite.src_rect.set( (pattern%5)*animwidth, (pattern/5)*animwidth, animwidth,animwidth) else sprite.zoom_x=frame[AnimFrame::ZOOMX]/100.0 sprite.zoom_y=frame[AnimFrame::ZOOMY]/100.0 sprite.src_rect.set( 0,0,128,128) end sprite.color.set( frame[AnimFrame::COLORRED], frame[AnimFrame::COLORGREEN], frame[AnimFrame::COLORBLUE], frame[AnimFrame::COLORALPHA] ) sprite.tone.set( frame[AnimFrame::TONERED], frame[AnimFrame::TONEGREEN], frame[AnimFrame::TONEBLUE], frame[AnimFrame::TONEGRAY] ) sprite.ox=sprite.src_rect.width/2 sprite.oy=sprite.src_rect.height/2 sprite.x=frame[AnimFrame::X] sprite.y=frame[AnimFrame::Y] end def pbResetCel(frame) return if !frame frame[AnimFrame::ZOOMX]=100 frame[AnimFrame::ZOOMY]=100 frame[AnimFrame::BLENDTYPE]=0 frame[AnimFrame::VISIBLE]=1 frame[AnimFrame::ANGLE]=0 frame[AnimFrame::MIRROR]=0 frame[AnimFrame::OPACITY]=255 frame[AnimFrame::COLORRED]=0 frame[AnimFrame::COLORGREEN]=0 frame[AnimFrame::COLORBLUE]=0 frame[AnimFrame::COLORALPHA]=0 frame[AnimFrame::TONERED]=0 frame[AnimFrame::TONEGREEN]=0 frame[AnimFrame::TONEBLUE]=0 frame[AnimFrame::TONEGRAY]=0 end def pbCreateCel(x,y,pattern) frame=[] frame[AnimFrame::X]=x frame[AnimFrame::Y]=y frame[AnimFrame::PATTERN]=pattern frame[AnimFrame::LOCKED]=0 pbResetCel(frame) return frame end class PBAnimTiming attr_accessor :frame attr_accessor :name attr_accessor :volume attr_accessor :pitch attr_accessor :flashScope attr_accessor :flashColor attr_accessor :flashDuration def initialize @frame=0 @name="" @volume=80 @pitch=100 @flashScope=0 @flashColor=Color.new(255,255,255,255) @flashDuration=5 end def to_s return "[#{@frame}] #{name} (volume #{@volume}, pitch #{@pitch})" end end class PBAnimations < Array include Enumerable attr_reader :array attr_accessor :selected def initialize(size=1) @array=[] @selected=0 size=1 if size<1 # Always create at least one animation size.times do @array.push(PBAnimation.new) end end def length return @array.length end def each @array.each {|i| yield i } end def [](i) return @array[i] end def []=(i,value) @array[i]=value end def resize(len) startidx=@array.length endidx=len if startidx>endidx for i in endidx...startidx @array.pop end else for i in startidx...endidx @array.push(PBAnimation.new) end end self.selected=len if self.selected>=len end end def pbConvertRPGAnimation(animation) pbanim=PBAnimation.new pbanim.id=animation.id pbanim.name=animation.name pbanim.graphic=animation.animation_name pbanim.hue=animation.animation_hue yoffset=0 pbanim.position=animation.position yoffset=-64 if animation.position==0 yoffset=64 if animation.position==2 for i in 0...animation.frames.length frame=pbanim.addFrame animframe=animation.frames[i] for j in 0...animframe.cell_max data=animframe.cell_data if data[j,0]!=-1 if animation.position==3 point=transformPoint( -160,80,160,-80, 144,188,352,108, data[j,1],data[j,2] ) cel=pbCreateCel( point[0],point[1], data[j,0] ) else cel=pbCreateCel( data[j,1], data[j,2]+yoffset, data[j,0] ) end cel[AnimFrame::ZOOMX]=data[j,3] cel[AnimFrame::ZOOMY]=data[j,3] cel[AnimFrame::ANGLE]=data[j,4] cel[AnimFrame::MIRROR]=data[j,5] cel[AnimFrame::OPACITY]=data[j,6] cel[AnimFrame::BLENDTYPE]=0 frame.push(cel) else frame.push(nil) end end end for i in 0...animation.timings.length timing=animation.timings[i] newtiming=PBAnimTiming.new newtiming.frame=timing.frame newtiming.name=timing.se.name newtiming.volume=timing.se.volume newtiming.pitch=timing.se.pitch newtiming.flashScope=timing.flash_scope newtiming.flashColor=timing.flash_color.clone newtiming.flashDuration=timing.flash_duration pbanim.timing.push(newtiming) end return pbanim end class PBAnimation < Array include Enumerable attr_accessor :graphic attr_accessor :hue attr_accessor :name attr_accessor :position attr_reader :array attr_reader :timing attr_accessor :id MAXSPRITES=30 def initialize(size=1) @array=[] @timing=[] @name="" @id=-1 @graphic="" @hue=0 @scope=0 @position=3 size=1 if size<1 # Always create at least one frame size.times do addFrame end end def length return @array.length end def each @array.each {|i| yield i } end def [](i) return @array[i] end def []=(i,value) @array[i]=value end def insert(*arg) return @array.insert(*arg) end def delete_at(*arg) return @array.delete_at(*arg) end def playTiming(frame,sprite=nil) for i in @timing if i.frame==frame if i.name!="" && i.name Audio.se_play("Audio/SE/"+i.name,i.volume,i.pitch) end if sprite sprite.flash(i.flashColor,i.flashDuration*2) if i.flashScope==1 sprite.flash(nil,i.flashDuration*2) if i.flashScope==3 end end end end def resize(len) if len<@array.length @array[len,@array.length-len]=[] elsif len>@array.length (len-@array.length).times do addFrame end end end def addFrame pos=@array.length @array[pos]=[] for i in 0...PBAnimation::MAXSPRITES # maximum sprites plus user and target if i==0 @array[pos][i]=pbCreateCel(144,188,-1) # Move's user @array[pos][i][AnimFrame::LOCKED]=1 elsif i==1 @array[pos][i]=pbCreateCel(352,108,-2) # Move's target @array[pos][i][AnimFrame::LOCKED]=1 end end return @array[pos] end end module PBAnimationPlayerModule def initialize(animation,target,viewport=nil); end def dispose; end def start; end def playing?; end def update; end end class PBAnimationPlayer def initialize(animation,user,target,viewport=nil) if animation.position==3 @player=PBAnimationPlayerPosition3.new(animation,user,target,viewport) else @player=PBAnimationPlayerPositionCenter.new(animation,target,viewport) end end def dispose;@player.dispose;end def start;@player.start;end def playing?;@player.playing?;end def looping;@player.looping;end def looping=(v);@player.looping=v;end def update;@player.update;end def setLineTransform(x1,y1,x2,y2,x3,y3,x4,y4) @player.setLineTransform(x1,y1,x2,y2,x3,y3,x4,y4) end end class PBAnimationPlayerPositionCenter attr_accessor :looping MAXSPRITES=30 def initialize(animation,target,viewport=nil) @animsprites=[] @looping=false @target=target @animation=animation @animbitmap=nil @viewport=viewport @frame=-1 @srcLine=nil @dstLine=nil @haveobservers=false for i in 0...MAXSPRITES @animsprites[i]=Sprite.new(viewport) @animsprites[i].bitmap=nil @animsprites[i].visible=false end end def dispose @animbitmap.dispose if @animbitmap for i in 0...MAXSPRITES @animsprites[i].dispose end end def start @frame=0 end def playing? return @frame>=0 end def setLineTransform(x1,y1,x2,y2,x3,y3,x4,y4) end def update return if @frame<0 if (@frame>>1) >= @animation.length @frame=(@looping) ? 0 : -1 if @frame<0 @animbitmap.dispose if @animbitmap @animbitmap=nil return end end if !@animbitmap || @animbitmap.disposed? @animbitmap=BitmapCache.animation(@animation.graphic,@animation.hue) for i in 0...MAXSPRITES @animsprites[i].bitmap=@animbitmap end end if (@frame&1)==0 thisframe=@animation[@frame>>1] for i in 0...MAXSPRITES sprite=@animsprites[i] sprite.visible=false end for i in 0...thisframe.length cel=thisframe[i] next if !cel sprite=@animsprites[i] if sprite && cel[AnimFrame::PATTERN]>=0 sprite.bitmap=@animbitmap pbSpriteSetAnimFrame(sprite,cel) center=getSpriteCenter(@target) sprite.x=cel[AnimFrame::X]+center[0] sprite.y=cel[AnimFrame::Y]+center[1] end end @animation.playTiming(@frame>>1,@target) end @frame+=1 end end def isReversed(src0,src1,dst0,dst1) if src0==src1 return false elsif src0<src1 return (dst0>dst1) else return (dst0<dst1) end end class PBAnimationPlayerPosition3 attr_accessor :looping MAXSPRITES=30 def initialize(animation,user,target,viewport=nil) @animsprites=[] @user=user @looping=false @target=target @userbitmap=user.bitmap # not to be disposed @targetbitmap=target.bitmap # not to be disposed @animation=animation @animbitmap=nil @viewport=viewport @frame=-1 @srcLine=nil @dstLine=nil @haveobservers=false @animsprites[0]=user @animsprites[1]=target for i in 2...MAXSPRITES @animsprites[i]=Sprite.new(viewport) @animsprites[i].bitmap=nil @animsprites[i].visible=false end end def dispose @animbitmap.dispose if @animbitmap for i in 2...MAXSPRITES @animsprites[i].dispose end end def start @frame=0 end def setLineTransform(x1,y1,x2,y2,x3,y3,x4,y4) @srcLine=[x1,y1,x2,y2] @dstLine=[x3,y3,x4,y4] end def playing? return @frame>=0 end def update return if @frame<0 if (@frame>>1) >= @animation.length @frame=(@looping) ? 0 : -1 if @frame<0 @animbitmap.dispose if @animbitmap @animbitmap=nil return end end if !@animbitmap || @animbitmap.disposed? @animbitmap=BitmapCache.animation(@animation.graphic,@animation.hue) for i in 0...MAXSPRITES @animsprites[i].bitmap=@animbitmap end end if (@frame&1)==0 thisframe=@animation[@frame>>1] for i in 0...MAXSPRITES sprite=@animsprites[i] sprite.visible=false end for i in 0...thisframe.length cel=thisframe[i] next if !cel sprite=@animsprites[i] sprite.bitmap=@animbitmap sprite.bitmap=@userbitmap if cel[AnimFrame::PATTERN]==-1 sprite.bitmap=@targetbitmap if cel[AnimFrame::PATTERN]==-2 if sprite pbSpriteSetAnimFrame(sprite,cel) if @srcLine && @dstLine if isReversed(@srcLine[0],@srcLine[2],@dstLine[0],@dstLine[2]) && cel[AnimFrame::PATTERN]>=0 # Reverse direction sprite.mirror=!sprite.mirror end point=transformPoint( @srcLine[0],@srcLine[1], @srcLine[2],@srcLine[3], @dstLine[0],@dstLine[1], @dstLine[2],@dstLine[3], sprite.x,sprite.y) sprite.x=point[0] sprite.y=point[1] end end end @animation.playTiming(@frame>>1) end @frame+=1 end end
PBDebug
[
Selecionar
] [
-
]
module PBDebug $PBDebugExceptions=0 def PBDebug.logonerr begin yield rescue $PBDebugExceptions+=1 PBDebug.log("**Exception: #{$!.message}") pbPrintException($!) if $PBDebugExceptions>100 raise end end end @@log=[] def PBDebug.flush File.open("Data/debuglog.txt", "a+b") {|f| f.write("#{@@log}") } @@log.clear end def PBDebug.log(msg) if $DEBUG @@log.push("#{msg}\\r\\n") if @@log.length>256 PBDebug.flush end end end def PBDebug.dump(msg) if $DEBUG File.open("Data/dumplog.txt", "a+b") { |f| f.write("#{msg}\\r\\n") } end end end
BitmapCache
[
Selecionar
] [
-
]
class Hangup < Exception; end def strsplit(str,re) ret=[] tstr=str while re=~tstr ret[ret.length]=$~.pre_match tstr=$~.post_match end ret[ret.length]=tstr if ret.length return ret end def canonicalize(c) csplit=strsplit(c,/[\\/\\\\]/) pos=-1 ret=[] retstr="" for x in csplit if x=="." elsif x==".." if pos>=0 ret.delete_at(pos) pos-=1 end else ret.push(x) pos+=1 end end for i in 0...ret.length retstr+="/" if i>0 retstr+=ret[i] end return retstr end ##################################################################### class WeakRef @@id_map = {} @@id_rev_map = {} @@final = lambda{|id| __old_status = Thread.critical Thread.critical = true begin rids = @@id_map[id] if rids for rid in rids @@id_rev_map.delete(rid) end @@id_map.delete(id) end rid = @@id_rev_map[id] if rid @@id_rev_map.delete(id) @@id_map[rid].delete(id) @@id_map.delete(rid) if @@id_map[rid].empty? end ensure Thread.critical = __old_status end } # Create a new WeakRef from +orig+. def initialize(orig) __setobj__(orig) end def __getobj__ unless @@id_rev_map[self.__id__] == @__id return nil end begin ObjectSpace._id2ref(@__id) rescue RangeError return nil end end def __setobj__(obj) @__id = obj.__id__ __old_status = Thread.critical begin Thread.critical = true unless @@id_rev_map.key?(self) ObjectSpace.define_finalizer obj, @@final ObjectSpace.define_finalizer self, @@final end @@id_map[@__id] = [] unless @@id_map[@__id] ensure Thread.critical = __old_status end @@id_map[@__id].push self.__id__ @@id_rev_map[self.__id__] = @__id end # Returns true if the referenced object still exists, and false if it has # been garbage collected. def weakref_alive? @@id_rev_map[self.__id__] == @__id end end class WeakHashtable include Enumerable def initialize @hash={} end def clear @hash.clear end def delete(value) @hash.delete(value) end def include?(value) @hash.include?(value) end def each @hash.each {|i| yield i } end def keys @hash.keys end def values @hash.values end def [](key) o=@hash[key] return o if !o if o.weakref_alive? o=o.__getobj__ else @hash.delete(key) o=nil end return o end def []=(key,o) if o!=nil o=WeakRef.new(o) end @hash[key]=o end end module RPG module Cache @cache = WeakHashtable.new def self.fromCache(i) return nil if !@cache.include?(i) obj=@cache[i] return nil if obj && obj.disposed? return obj end def self.debug File.open("bitmapcache2.txt","wb"){|f| for i in @cache.keys k=fromCache(i) if !k f.write("#{i} (nil)\\r\\n") elsif k.disposed? f.write("#{i} (disposed)\\r\\n") else f.write("#{i} (#{k.refcount}, #{k.width}x#{k.height})\\r\\n") end end } end def self.load_bitmap(folder_name, filename, hue = 0) cached=true path = folder_name + filename.to_s path=canonicalize(path) objPath=fromCache(path) if !objPath if rand(10) == 0 for i in @cache.keys obj=fromCache(i) if !obj @cache.delete(i) end end end if filename != "" begin bm = BitmapWrapper.new(path) rescue Hangup begin bm = BitmapWrapper.new(path) rescue bm = BitmapWrapper.new(32, 32) raise _INTL("Failed to load bitmap: {1}",path) end rescue bm = BitmapWrapper.new(32, 32) raise _INTL("Failed to load bitmap: {1}",path) end else bm = BitmapWrapper.new(32, 32) end objPath=bm @cache[path]=objPath cached=false end if hue == 0 objPath.addRef if cached return objPath else key = [path, hue] objKey=fromCache(key) if !objKey bitmap= objPath.clone bitmap.hue_change(hue) bitmap.resetRef objKey=bitmap @cache[key]=objKey else objKey.addRef end return objKey end end def self.animation(filename, hue) self.load_bitmap("Graphics/Animations/", filename, hue) end def self.autotile(filename) self.load_bitmap("Graphics/Autotiles/", filename) end def self.battleback(filename) self.load_bitmap("Graphics/Battlebacks/", filename) end def self.battler(filename, hue) self.load_bitmap("Graphics/Battlers/", filename, hue) end def self.character(filename, hue) self.load_bitmap("Graphics/Characters/", filename, hue) end def self.fog(filename, hue) self.load_bitmap("Graphics/Fogs/", filename, hue) end def self.gameover(filename) self.load_bitmap("Graphics/Gameovers/", filename) end def self.icon(filename) self.load_bitmap("Graphics/Icons/", filename) end def self.panorama(filename, hue) self.load_bitmap("Graphics/Panoramas/", filename, hue) end def self.picture(filename) self.load_bitmap("Graphics/Pictures/", filename) end def self.tileset(filename) self.load_bitmap("Graphics/Tilesets/", filename) end def self.title(filename) self.load_bitmap("Graphics/Titles/", filename) end def self.windowskin(filename) self.load_bitmap("Graphics/Windowskins/", filename) end def self.tile(filename, tile_id, hue) key = [filename, tile_id, hue] objKey=fromCache(key) if !objKey bitmap=BitmapWrapper.new(32, 32) x = (tile_id - 384) % 8 * 32 y = (tile_id - 384) / 8 * 32 rect = Rect.new(x, y, 32, 32) tileset = self.tileset(filename) bitmap.blt(0, 0, tileset, rect) tileset.dispose bitmap.hue_change(hue) objKey=bitmap @cache[key]=objKey else objKey.addRef end objKey end def self.clear @cache = {} GC.start end end end =begin A safer version of RPG::Cache, this module loads bitmaps that keep an internal reference count. Each call to dispose decrements the reference count and the bitmap is freed when the reference count reaches 0. =end class BitmapWrapper < Bitmap attr_reader :refcount attr_reader :key def dispose return if self.disposed? @refcount-=1 if @refcount==0 super end end def initialize(*arg) super @key="" @refcount=1 end def key=(value) @key=value end def resetRef @refcount=1 end def addRef @refcount+=1 end end module BitmapCache @cache = WeakHashtable.new def self.fromCache(i) return nil if !@cache.include?(i) obj=@cache[i] return nil if obj && obj.disposed? return obj end def self.debug File.open("bitmapcache2.txt","wb"){|f| for i in @cache.keys k=fromCache(i) if !k f.write("#{i} (nil)\\r\\n") elsif k.disposed? f.write("#{i} (disposed)\\r\\n") else f.write("#{i} (#{k.refcount}, #{k.width}x#{k.height})\\r\\n") end end } end def self.load_bitmap(path, hue = 0) cached=true path=canonicalize(path) objPath=fromCache(path) if !objPath if rand(10) == 0 for i in @cache.keys obj=fromCache(i) if !obj @cache.delete(i) end end end begin bm = BitmapWrapper.new(path) rescue Hangup begin bm = BitmapWrapper.new(path) rescue raise _INTL("Failed to load bitmap: {1}",path) end rescue raise _INTL("Failed to load bitmap: {1}",path) end objPath=bm @cache[path]=objPath cached=false end if hue == 0 objPath.addRef if cached return objPath else key = [path, hue] objKey=fromCache(key) if !objKey bitmap= objPath.clone bitmap.hue_change(hue) bitmap.resetRef objKey=bitmap @cache[key]=objKey else objKey.addRef end return objKey end end def self.animation(filename, hue) self.load_bitmap("Graphics/Animations/"+filename, hue) end def self.autotile(filename) self.load_bitmap("Graphics/Autotiles/"+ filename) end def self.battleback(filename) self.load_bitmap("Graphics/Battlebacks/"+ filename) end def self.battler(filename, hue) self.load_bitmap("Graphics/Battlers/"+ filename, hue) end def self.character(filename, hue) self.load_bitmap("Graphics/Characters/"+ filename, hue) end def self.fog(filename, hue) self.load_bitmap("Graphics/Fogs/"+ filename, hue) end def self.gameover(filename) self.load_bitmap("Graphics/Gameovers/"+ filename) end def self.icon(filename) self.load_bitmap("Graphics/Icons/"+ filename) end def self.panorama(filename, hue) self.load_bitmap("Graphics/Panoramas/"+ filename, hue) end def self.picture(filename) self.load_bitmap("Graphics/Pictures/"+ filename) end def self.tileset(filename) self.load_bitmap("Graphics/Tilesets/"+ filename) end def self.title(filename) self.load_bitmap("Graphics/Titles/"+ filename) end def self.windowskin(filename) self.load_bitmap("Graphics/Windowskins/"+ filename) end def self.tile(filename, tile_id, hue) key = [filename, tile_id, hue] objKey=fromCache(key) if !objKey bitmap=BitmapWrapper.new(32, 32) x = (tile_id - 384) % 8 * 32 y = (tile_id - 384) / 8 * 32 rect = Rect.new(x, y, 32, 32) tileset = self.tileset(filename) bitmap.blt(0, 0, tileset, rect) tileset.dispose bitmap.hue_change(hue) objKey=bitmap @cache[key]=objKey else objKey.addRef end objKey end def self.clear @cache = {} GC.start end end
DrawText
[
Selecionar
] [
-
]
def getLineBrokenChunks(bitmap,value,width,dims,plain=false) x=0 y=0 textheight=0 ret=[] if dims dims[0]=0 dims[1]=0 end re=/<c=([^>]+)>/ reNoMatch=/<c=[^>]+>/ return ret if !bitmap || bitmap.disposed? || width<=0 textmsg=value.clone lines=0 color=Font.default_color while ((c = textmsg.slice!(/\\n|(\\S*([ \\r\\t\\f]?))/)) != nil) break if c=="" ccheck=c if ccheck=="\\n" x=0 y+=(textheight==0) ? bitmap.text_size("X").height : textheight textheight=0 next end if ccheck[/</] && !plain textcols=[] ccheck.scan(re){ textcols.push(RgbToColor($1)) } words=ccheck.split(reNoMatch) # must have no matches because split can include match else textcols=[] words=[ccheck] end for i in 0...words.length word=words[i] if word && word!="" textSize=bitmap.text_size(word) textwidth=textSize.width if x>0 && x+textwidth>=width-2 x=0 y+=32 # (textheight==0) ? bitmap.text_size("X").height : textheight textheight=0 end textheight=32 # [textheight,textSize.height].max ret.push([word,x,y,textwidth,textheight,color]) x+=textwidth dims[0]=x if dims && dims[0]<x end if textcols[i] color=textcols[i] end end end dims[1]=y+textheight if dims return ret end def renderLineBrokenChunks(bitmap,xDst,yDst,normtext,maxheight=0) for i in 0...normtext.length width=normtext[i][3] textx=normtext[i][1]+xDst texty=normtext[i][2]+yDst if maxheight==0 || normtext[i][2]<maxheight bitmap.font.color=normtext[i][5] bitmap.draw_text(textx,texty,width+2,normtext[i][4],normtext[i][0]) end end end def renderLineBrokenChunksWithShadow(bitmap,xDst,yDst,normtext,maxheight,baseColor,shadowColor) for i in 0...normtext.length width=normtext[i][3] textx=normtext[i][1]+xDst texty=normtext[i][2]+yDst if maxheight==0 || normtext[i][2]<maxheight height=normtext[i][4] text=normtext[i][0] bitmap.font.color=shadowColor bitmap.draw_text(textx+2,texty,width+2,height,text) bitmap.draw_text(textx,texty+2,width+2,height,text) bitmap.draw_text(textx+2,texty+2,width+2,height,text) bitmap.font.color=baseColor bitmap.draw_text(textx,texty,width+2,height,text) end end end def shadowctag(base,shadow) return sprintf("<c2=%s%s>",colorToRgb16(base),colorToRgb16(shadow)) end def colorToRgb16(color) ret=(color.red.to_i>>3) ret|=((color.green.to_i>>3)<<5) ret|=((color.blue.to_i>>3)<<10) return sprintf("%04X",ret) end def ctag(color) ret=(color.red.to_i<<24) ret|=((color.green.to_i)<<16) ret|=((color.blue.to_i)<<8) ret|=((color.alpha.to_i)) return sprintf("<c=%08X>",ret) end def RgbToColor(param) baseint=param.to_i(16) if param.length==8 # 32-bit hex return Color.new( (baseint>>24)&0xFF, (baseint>>16)&0xFF, (baseint>>8)&0xFF, (baseint)&0xFF ) elsif param.length==6 # 24-bit hex return Color.new( (baseint>>16)&0xFF, (baseint>>8)&0xFF, (baseint)&0xFF ) elsif param.length==4 # 16-bit hex return Color.new( ((baseint)&0x1F)<<3, ((baseint>>5)&0x1F)<<3, ((baseint>>10)&0x1F)<<3 ) elsif param.length==1 # Color number i=param.to_i return Font.default_color if i>=8 return [ Color.new(255, 255, 255, 255), Color.new(128, 128, 255, 255), Color.new(255, 128, 128, 255), Color.new(128, 255, 128, 255), Color.new(128, 255, 255, 255), Color.new(255, 128, 255, 255), Color.new(255, 255, 128, 255), Color.new(192, 192, 192, 255) ][i] else return Font.default_color end end def shadowctagFromRgb(param) color=RgbToColor(param) shadow=nil isdark=(color.red+color.green+color.blue)/3 < 128 if isdark shadow=Color.new(color.red+64,color.green+64,color.blue+64) else shadow=Color.new(color.red-64,color.green-64,color.blue-64) end return shadowctag(color,shadow) end def shadowctagFromColor(color) shadow=nil isdark=(color.red+color.green+color.blue)/3 < 128 if isdark shadow=Color.new(color.red+64,color.green+64,color.blue+64) else shadow=Color.new(color.red-64,color.green-64,color.blue-64) end return shadowctag(color,shadow) end def Rgb16ToColor(param) baseint=param.to_i(16) return Color.new( ((baseint)&0x1F)<<3, ((baseint>>5)&0x1F)<<3, ((baseint>>10)&0x1F)<<3 ) end def getLastParam(array,default) i=array.length-1 while i>=0 return array[i] if array[i] i-=1 end return default end =begin Formats a string of text and returns an array containing a list of formatted characters. Parameters: bitmap: Source bitmap. Will be used to determine the default font of the text. xDst: X coordinate of the text's top left corner. yDst: Y coordinate of the text's top left corner. widthDst: Width of the text. Used to determine line breaks. heightDst: Height of the text. If -1, there is no height restriction. If 1 or greater, any characters exceeding the height are removed from the returned list. newLineBreaks: If true, newline characters will be treated as line breaks. The default is true. Return Values: A list of formatted characters. Returns an empty array if _bitmap_ is nil or disposed, or if _widthDst_ is 0 or less or _heightDst_ is 0. Formatting Specification: This function uses the following syntax when formatting the text. <b> ... </b> - Formats the text in bold. <i> ... </i> - Formats the text in italics. <u> ... </u> - Underlines the text. <s> ... </s> - Draws a strikeout line over the text. <r> - Right-aligns the text until the next line break. <br> - Causes a line break. <c=X> ... </c> - Color specification. A total of four formats are supported: RRGGBBAA, RRGGBB, 16-bit RGB, and Window_Base color numbers. <c2=X> ... </c2> - Color specification where the first half is the base color and the second half is the shadow color. 16-bit RGB is supported. <fn=X> ... </fn> - Formats the text in the specified font, or Arial if the font doesn't exist. <fs=X> ... </fs> - Changes the font size to X. <ac> ... </ac> - Centers the text. Causes line breaks before and after the text. <al> ... </al> - Left-aligns the text. Causes line breaks before and after the text. <ar> ... </ar> - Right-aligns the text. Causes line breaks before and after the text. <icon=X> - Displays the icon X (in Graphics/Icons/). In addition, the syntax supports the following: ' - Converted to "'". < - Converted to "<". > - Converted to ">". & - Converted to "&". " - Converted to double quotation mark. To draw the characters, pass the returned array to the _drawFormattedChars_ function. =end def isWaitChar(x) return (x=="\\1" || x=="\\2") end FORMATREGEXP=/<(\\/?)([Cc]|[Cc][2]|[Ff][Nn]|[Bb][Rr]|[Ff][Ss]|[Ii]|[Bb]|[Uu]|[Ss]|[Ii][Cc][Oo][Nn]|[Ii][Mm][Gg]|[Aa][Cc]|[Aa][Rr]|[Aa][Ll]|[Rr])(\\s*\\=\\s*([^>]*))?>/ def toUnformattedText(text) text2=text.gsub(FORMATREGEXP,"") text2.gsub!(/</,"<") text2.gsub!(/>/,">") text2.gsub!(/'/,"'") text2.gsub!(/"/,"\\"") text2.gsub!(/&/,"&") return text2 end def unformattedTextLength(text) return toUnformattedText(text).scan(/./m).length end def getFormattedTextForDims( bitmap,xDst,yDst,widthDst,heightDst, text,lineheight,newlineBreaks=true, explicitBreaksOnly=false) text2=text.gsub(/<(\\/?)([Cc]|[Cc][2]|[Uu]|[Ss])(\\s*\\=\\s*([^>]*))?>/,"") if newlineBreaks text2.gsub!(/<(\\/?)([Bb][Rr])(\\s*\\=\\s*([^>]*))?>/,"\\n") end return getFormattedText( bitmap,xDst,yDst,widthDst,heightDst, text2,lineheight,newlineBreaks, explicitBreaksOnly) end def getFormattedTextFast( bitmap,xDst,yDst,widthDst,heightDst, text,lineheight,newlineBreaks=true, explicitBreaksOnly=false) numchars=0 x=y=0 characters=[] charactersInternal=[] textchunks=[] controls=[] charsonline=0 textchunks.push(text) text=textchunks.join("") textchars=text.scan(/./m) lastword=[0,0] # position of last word hadspace=false hadnonspace=false bold=bitmap.font.bold italic=bitmap.font.italic colorclone=bitmap.font.color havenl=false position=0;while position<textchars.length nextline=0 yStart=0 xStart=0 width=isWaitChar(textchars[position]) ? 0 : bitmap.text_size(textchars[position]).width nextline.times do havenl=true characters.push(["\\n",x,y*lineheight+yDst,0,lineheight, false,false,false,colorclone,nil,false,false,"",8,position]) y+=1; x=0; lastword=[characters.length,x] hadspace=false hadnonspace=false end if textchars[position]=="\\n" if newlineBreaks # treat newline as break if nextline==0 havenl=true characters.push(["\\n",x,y*lineheight+yDst,0,lineheight, false,false,false,colorclone,nil,false,false,"",8,position]) y+=1 x=0 end hadspace=true hadnonspace=false position+=1 next else # treat newline as space textchars[position]=" " end end isspace=(textchars[position][/\\s/]||isWaitChar(textchars[position])) ? true : false if hadspace && !isspace # set last word to here lastword[0]=characters.length lastword[1]=x hadspace=false hadnonspace=true elsif isspace hadspace=true end textx=x+xStart texty=(lineheight*y)+yDst+yStart oldx=x # Push character, textx will be calculated later if heightDst<0 || yStart<heightDst havenl=true if isWaitChar(textchars[position]) characters.push([ textchars[position], x+xStart,texty+yStart,width+2,lineheight, false, bold,italic, colorclone,nil, false,false, bitmap.font.name,bitmap.font.size,position]) end x+=width if !explicitBreaksOnly && x+2>widthDst && lastword[1]!=0 && (!hadnonspace || !hadspace) havenl=true characters.insert(lastword[0],["\\n",x,y*lineheight+yDst,0,lineheight, false,false,false,colorclone,nil,false,false,"",8,position]) lastword[0]+=1 y+=1 x=0 for i in lastword[0]...characters.length characters[i][2]+=lineheight charwidth=characters[i][3]-2 characters[i][1]=x x+=charwidth end lastword[1]=0 end position+=1 end # Count total number of lines numlines=(x==0 && y>0) ? y-1 : y realtext=(newlineBreaks) ? text : text.gsub(/\\n/," ") if numlines==2 && !explicitBreaksOnly && !realtext[/\\n/] && realtext.length>=50 # Set half to middle of text (known to contain no formatting) half=realtext.length/2 leftSearch=0 rightSearch=0 # Search left for a space i=half; while i>=0 if realtext[i,1][/\\s/]||isWaitChar(realtext[i]) # found a space break end leftSearch+=1 i-=1 end # Search right for a space i=half; while i<realtext.length if realtext[i,1][/\\s/]||isWaitChar(realtext[i]) # found a space break end rightSearch+=1 i+=1 end # Move half left or right whichever is closer trialHalf=half+((leftSearch<rightSearch) ? -leftSearch : rightSearch) if trialHalf!=0 && trialHalf!=realtext.length # Insert newline and re-call this function (force newlineBreaksOnly) newText=realtext.clone newText.insert(trialHalf,"\\n") return getFormattedTextFast(bitmap,xDst,yDst, widthDst,heightDst,newText,lineheight,true, explicitBreaksOnly) end end # Eliminate spaces before newlines and pause character if havenl firstspace=-1 for i in 0...characters.length if characters[i][5]!=false # If not a character firstspace=-1 elsif (characters[i][0]=="\\n" || isWaitChar(characters[i][0])) && firstspace>=0 for j in firstspace...i characters[j]=nil end firstspace=-1 elsif characters[i][0][/[ \\r\\t]/] if firstspace<0 firstspace=i end else firstspace=-1 end end if firstspace>0 for j in firstspace...characters.length characters[j]=nil end end characters.compact! end for i in 0...characters.length characters[i][1]=xDst+characters[i][1] end # Remove all characters with Y # greater or equal to _heightDst_ if heightDst>=0 for i in 0...characters.length if characters[i][2]>=texty+heightDst characters[i]=nil end end characters.compact! end return characters end def getFormattedText( bitmap,xDst,yDst,widthDst,heightDst, text,lineheight,newlineBreaks=true, explicitBreaksOnly=false) if !bitmap||bitmap.disposed?||widthDst<=0||heightDst==0||text.length==0 return [] end textchunks=[] controls=[] oldtext=text while text[FORMATREGEXP] textchunks.push($~.pre_match) if $~[3] controls.push([$~[2].downcase,$~[4],-1,$~[1]=="/" ? true : false]) else controls.push([$~[2].downcase,"",-1,$~[1]=="/" ? true : false]) end text=$~.post_match end if controls.length==0 return getFormattedTextFast( bitmap,xDst,yDst,widthDst,heightDst, text,lineheight,newlineBreaks, explicitBreaksOnly) end numchars=0 x=y=0 characters=[] charactersInternal=[] charsonline=0 realtext=nil if !explicitBreaksOnly && textchunks.join("").length==0 # All commands occurred at the beginning of the text string realtext=(newlineBreaks) ? text : text.gsub(/\\n/," ") realtextStart=oldtext[0,oldtext.length-realtext.length] realtextHalf=text.length/2 end textchunks.push(text) for chunk in textchunks chunk.gsub!(/</,"<") chunk.gsub!(/>/,">") chunk.gsub!(/'/,"'") chunk.gsub!(/"/,"\\"") chunk.gsub!(/&/,"&") end textlen=0 for i in 0...controls.length textlen+=textchunks[i].scan(/./m).length controls[i][2]=textlen end text=textchunks.join("") textchars=text.scan(/./m) colorstack=[] boldcount=0 italiccount=0 underlinecount=0 strikecount=0 rightalign=0 oldfont=bitmap.font.clone defaultfontname=bitmap.font.name.clone defaultfontsize=bitmap.font.size fontname=defaultfontname fontsize=defaultfontsize fontnamestack=[] fontsizestack=[] defaultcolors=[oldfont.color.clone,nil] if defaultfontname.is_a?(Array) defaultfontname.push("Arial") else defaultfontname=[defaultfontname,"Arial"] end alignstack=[] lastword=[0,0] # position of last word hadspace=false hadnonspace=false havenl=false position=0;while position<textchars.length nextline=0 graphic=nil graphicX=0 graphicY=0 graphicWidth=nil graphicHeight=nil graphicRect=nil for i in 0...controls.length if controls[i] && controls[i][2]==position control=controls[i][0] param=controls[i][1] endtag=controls[i][3] if control=="c" if endtag colorstack.pop else color=RgbToColor(param) colorstack.push([color,nil]) end elsif control=="c2" if endtag colorstack.pop else base=Rgb16ToColor(param[0,4]) shadow=Rgb16ToColor(param[4,4]) colorstack.push([base,shadow]) end elsif control=="b" boldcount-=1 if endtag boldcount+=1 if !endtag elsif control=="i" italiccount-=1 if endtag italiccount+=1 if !endtag elsif control=="u" underlinecount-=1 if endtag underlinecount+=1 if !endtag elsif control=="s" strikecount-=1 if endtag strikecount+=1 if !endtag elsif control=="fs" # Font size if endtag fontsizestack.pop else fontsizestack.push(param.sub(/\\s+$/,"").to_i) end fontsize=getLastParam(fontsizestack,defaultfontsize) bitmap.font.size=fontsize elsif control=="fn" # Font name if endtag fontnamestack.pop else fontnamestack.push([param.sub(/\\s+$/,""),"Arial"]) end fontname=getLastParam(fontnamestack,defaultfontname) bitmap.font.name=fontname elsif control=="ar" # Right align if !endtag alignstack.push(1) nextline=1 if x>0 && nextline==0 else alignstack.pop; nextline=1 if x>0 && nextline==0 end elsif control=="al" # Left align if !endtag alignstack.push(0) nextline=1 if x>0 && nextline==0 else alignstack.pop; nextline=1 if x>0 && nextline==0 end elsif control=="ac" # Center align if !endtag alignstack.push(2) nextline=1 if x>0 && nextline==0 else alignstack.pop; nextline=1 if x>0 && nextline==0 end elsif control=="icon" # Icon if !endtag param=param.sub(/\\s+$/,"") graphic="Graphics/Icons/#{param}" controls[i]=nil break end elsif control=="img" # Icon if !endtag param=param.sub(/\\s+$/,"") param=param.split("|") graphic=param[0] if param.length>1 graphicX=param[1].to_i graphicY=param[2].to_i graphicWidth=param[3].to_i graphicHeight=param[4].to_i end controls[i]=nil break end elsif control=="br" # Line break if !endtag nextline+=1 end elsif control=="r" # Right align this line if !endtag x=0 rightalign=1;lastword=[characters.length,x] end end controls[i]=nil end end bitmap.font.bold=(boldcount>0) bitmap.font.italic=(italiccount>0) if graphic if !graphicWidth tempgraphic=Bitmap.new(graphic) graphicWidth=tempgraphic.width graphicHeight=tempgraphic.height tempgraphic.dispose end width=graphicWidth+8 xStart=4 yStart=[(lineheight/2)-(graphicHeight/2),0].max graphicRect=Rect.new(graphicX,graphicY,graphicWidth,graphicHeight) else yStart=0 xStart=0 width=isWaitChar(textchars[position]) ? 0 : bitmap.text_size(textchars[position]).width end if rightalign==1 && nextline==0 alignment=1 else alignment=getLastParam(alignstack,0) end nextline.times do havenl=true characters.push(["\\n",x,y*lineheight+yDst,0,lineheight, false,false,false,defaultcolors[0],defaultcolors[1],false,false,"",8,position,nil]) charactersInternal.push([alignment,y,0]) y+=1; x=0; rightalign=0; lastword=[characters.length,x] hadspace=false hadnonspace=false end if textchars[position]=="\\n" if newlineBreaks if nextline==0 havenl=true characters.push(["\\n",x,y*lineheight+yDst,0,lineheight, false,false,false,defaultcolors[0],defaultcolors[1],false,false,"",8,position,nil]) charactersInternal.push([alignment,y,0]) y+=1 x=0 end rightalign=0 hadspace=true hadnonspace=false position+=1 next else textchars[position]=" " if !graphic width=bitmap.text_size(textchars[position]).width end end end isspace=(textchars[position][/\\s/]||isWaitChar(textchars[position])) ? true : false if hadspace && !isspace # set last word to here lastword[0]=characters.length lastword[1]=x hadspace=false hadnonspace=true elsif isspace hadspace=true end textx=x+xStart texty=(lineheight*y)+yDst+yStart colors=getLastParam(colorstack,defaultcolors) oldx=x # Push character, textx will be calculated later if heightDst<0 || texty<heightDst havenl=true if !graphic && isWaitChar(textchars[position]) extraspace=(!graphic && italiccount>0) ? 2+(width/2) : 2 characters.push([ graphic ? graphic : textchars[position], x+xStart,texty,width+extraspace,lineheight, graphic ? true : false, (boldcount>0),(italiccount>0),colors[0],colors[1], (underlinecount>0),(strikecount>0),fontname,fontsize,position,graphicRect]) charactersInternal.push([alignment,y,xStart,textchars[position],extraspace]) end x+=width if !explicitBreaksOnly && x+2>widthDst && lastword[1]!=0 && (!hadnonspace || !hadspace) havenl=true characters.insert(lastword[0],["\\n",x,y*lineheight+yDst,0,lineheight, false,false,false,defaultcolors[0],defaultcolors[1],false,false,"",8,position,nil]) charactersInternal.insert(lastword[0],[alignment,y,0]) lastword[0]+=1 y+=1 x=0 for i in lastword[0]...characters.length characters[i][2]+=lineheight charactersInternal[i][1]+=1 extraspace=(charactersInternal[i][4]) ? charactersInternal[i][4] : 0 charwidth=characters[i][3]-extraspace characters[i][1]=x+charactersInternal[i][2] x+=charwidth end lastword[1]=0 end position+=1 if !graphic end # Count total number of lines numlines=(x==0 && y>0) ? y : y+1 if numlines==2 && realtext && !realtext[/\\n/] && realtext.length>=50 # Set half to middle of text (known to contain no formatting) half=realtext.length/2 leftSearch=0 rightSearch=0 # Search left for a space i=half; while i>=0 if realtext[i,1][/\\s/]||isWaitChar(realtext[i,1]) # found a space break end leftSearch+=1 i-=1 end # Search right for a space i=half; while i<realtext.length if realtext[i,1][/\\s/]||isWaitChar(realtext[i,1]) # found a space break end rightSearch+=1 i+=1 end # Move half left or right whichever is closer trialHalf=half+((rightSearch<leftSearch) ? rightSearch : -leftSearch) if trialHalf!=0 && trialHalf!=realtext.length # Insert newline and re-call this function (force newlineBreaksOnly) newText=realtext.clone if isWaitChar(newText[trialHalf,1]) # insert after wait character newText.insert(trialHalf+1,"\\n") else # remove spaces after newline newText.insert(trialHalf,"\\n") newText.gsub!(/\\n\\s+/,"\\n") end return getFormattedText(bitmap,xDst,yDst, widthDst,heightDst, realtextStart+newText, lineheight,true, explicitBreaksOnly) end end if havenl # Eliminate spaces before newlines and pause character firstspace=-1 for i in 0...characters.length if characters[i][5]!=false # If not a character firstspace=-1 elsif (characters[i][0]=="\\n" || isWaitChar(characters[i][0])) && firstspace>=0 for j in firstspace...i characters[j]=nil charactersInternal[j]=nil end firstspace=-1 elsif characters[i][0][/[ \\r\\t]/] if firstspace<0 firstspace=i end else firstspace=-1 end end if firstspace>0 for j in firstspace...characters.length characters[j]=nil charactersInternal[j]=nil end end characters.compact! charactersInternal.compact! end # Calculate Xs based on alignment # First, find all text runs with # the same alignment on the same line totalwidth=0 widthblocks=[] lastalign=0 lasty=0 runstart=0 for i in 0...characters.length c=characters[i] if i>0 && (charactersInternal[i][0]!=lastalign || charactersInternal[i][1]!=lasty) # Found end of run widthblocks.push([runstart,i,lastalign,totalwidth]) runstart=i totalwidth=0 end lastalign=charactersInternal[i][0] lasty=charactersInternal[i][1] extraspace=(charactersInternal[i][4]) ? charactersInternal[i][4] : 0 totalwidth+=c[3]-extraspace end widthblocks.push([runstart,characters.length,lastalign,totalwidth]) # Now, based on the text runs found, # recalculate Xs for block in widthblocks next if block[0]>=block[1] for i in block[0]...block[1] case block[2] when 1;characters[i][1]=xDst+(widthDst-block[3]-4)+characters[i][1] when 2;characters[i][1]=xDst+((widthDst/2)-(block[3]/2))+characters[i][1] else;characters[i][1]=xDst+characters[i][1] end end end # Remove all characters with Y # greater or equal to _heightDst_ if heightDst>=0 for i in 0...characters.length if characters[i][2]>=texty+heightDst characters[i]=nil end end characters.compact! end bitmap.font=oldfont return characters end def drawBitmapBuffer(chars) width=1 height=1 for ch in chars chx=ch[1]+ch[3] chy=ch[2]+ch[4] width=chx if width<chx height=chy if height<chy end buffer=Bitmap.new(width,height) drawFormattedChars(buffer,chars) return buffer end def drawSingleFormattedChar(bitmap,ch) if ch[5] # If a graphic graphic=Bitmap.new(ch[0]) graphicRect=ch[15] bitmap.blt(ch[1], ch[2], graphic,graphicRect,ch[8].alpha) graphic.dispose else if bitmap.font.size!=ch[13] bitmap.font.size=ch[13] end if ch[0]!="\\n" && ch[0]!="\\r" && ch[0]!=" " && !isWaitChar(ch[0]) if bitmap.font.bold!=ch[6] bitmap.font.bold=ch[6] end if bitmap.font.italic!=ch[7] bitmap.font.italic=ch[7] end if bitmap.font.name!=ch[12] bitmap.font.name=ch[12] end if ch[9] # shadow bitmap.font.color=ch[9] bitmap.draw_text(ch[1]+2,ch[2],ch[3]+2,ch[4],ch[0]) bitmap.draw_text(ch[1],ch[2]+2,ch[3]+2,ch[4],ch[0]) bitmap.draw_text(ch[1]+2,ch[2]+2,ch[3]+2,ch[4],ch[0]) end if bitmap.font.color!=ch[8] bitmap.font.color=ch[8] end bitmap.draw_text(ch[1],ch[2],ch[3],ch[4],ch[0]) else if bitmap.font.color!=ch[8] bitmap.font.color=ch[8] end end if ch[10] # underline bitmap.fill_rect(ch[1],ch[2]+ch[4]-[(ch[4]-bitmap.font.size)/2,0].max-2, ch[3]-2,2,ch[8]) end if ch[11] # strikeout bitmap.fill_rect(ch[1],ch[2]+(ch[4]/2),ch[3]-2,2,ch[8]) end end end def drawFormattedChars(bitmap,chars) if chars.length==0||!bitmap||bitmap.disposed? return end oldfont=bitmap.font.clone for ch in chars drawSingleFormattedChar(bitmap,ch) end bitmap.font=oldfont end def drawTextTable(bitmap,x,y,totalWidth,rowHeight,columnWidthPercents,table) yPos=y for i in 0...table.length row=table[i] xPos=x for j in 0...row.length cell=row[j] cellwidth=columnWidthPercents[j]*totalWidth/100 chars=getFormattedText( bitmap,xPos,yPos,cellwidth,-1,cell,rowHeight) drawFormattedChars(bitmap,chars) xPos+=cellwidth end yPos+=rowHeight end end def drawTextEx(bitmap,x,y,width,numlines,text,baseColor,shadowColor) normtext=getLineBrokenChunks(bitmap,text,width,nil,true) renderLineBrokenChunksWithShadow(bitmap,x,y,normtext,numlines*32,baseColor,shadowColor) end def fmtescape(text) if text[/[&<>]/] text2=text.gsub(/&/,"&") text2.gsub!(/</,"<") text2.gsub!(/>/,">") return text2 end return text end def coloredToFormattedText(text,baseColor=nil,shadowColor=nil) base=!baseColor ? Color.new(12*8,12*8,12*8) : baseColor.clone shadow=!shadowColor ? Color.new(26*8,26*8,25*8) : shadowColor.clone text2=text.gsub(/&/,"&") text2.gsub!(/</,"<") text2.gsub!(/>/,">") text2.gsub!(/\\\\\\[([A-Fa-f0-9]{8,8})\\]/){ "<c2="+$1+">" } text2="<c2="+colorToRgb16(base)+colorToRgb16(shadow)+">"+text2 text2.gsub!(/\\\\\\\\/,"\\\\") return text2 end def drawColoredTextEx(bitmap,x,y,width,text,baseColor=nil,shadowColor=nil) chars=getFormattedText(bitmap,x,y,width,-1,coloredToFormattedText(text),32) drawFormattedChars(bitmap,chars) end def drawFormattedTextOnWindow(window,text) chars=getFormattedText( window.contents,0,0,window.width-32,window.height-32,text,32) drawFormattedChars(window.contents,chars) end
Transitions
[
Selecionar
] [
-
]
module Graphics @@transition=nil STOP_WHILE_TRANSITION = true unless defined?(transition_KGC_SpecialTransition) class << Graphics alias transition_KGC_SpecialTransition transition end class << Graphics alias update_KGC_SpecialTransition update end end def self.transition(duration = 8, filename = "", vague = 20) if judge_special_transition(duration,filename) duration = 0 filename="" end begin transition_KGC_SpecialTransition(duration, filename, vague) rescue Exception if filename!="" transition_KGC_SpecialTransition(duration, "", vague) end end if STOP_WHILE_TRANSITION && !@_interrupt_transition while @@transition && !@@transition.disposed? update end end end def self.update update_KGC_SpecialTransition =begin if Graphics.frame_count%40==0 count=0 ObjectSpace.each_object(Object) {|o| count+=1 } echo("Objects: #{count}\\r\\n") end =end if @@transition && !@@transition.disposed? @@transition.update end if @@transition && @@transition.disposed? @@transition=nil end end def self.judge_special_transition(duration,filename) ret=true if @_interrupt_transition return false end if @@transition && !@@transition.disposed? @@transition.dispose @@transition=nil end dc=File.basename(filename).downcase if dc=="splash" @@transition=SplashTransition.new(duration) elsif dc=="random_stripe_v" @@transition=RandomStripeTransition.new(duration,0) elsif dc=="random_stripe_h" @@transition=RandomStripeTransition.new(duration,1) elsif dc=="rotatingpieces" @@transition=ShrinkingPieces.new(duration,true) elsif dc=="shrinkingpieces" @@transition=ShrinkingPieces.new(duration,false) elsif dc=="scrolldown" @@transition=ScrollScreen.new(duration,2) elsif dc=="scrollleft" @@transition=ScrollScreen.new(duration,4) elsif dc=="scrollright" @@transition=ScrollScreen.new(duration,6) elsif dc=="scrollup" @@transition=ScrollScreen.new(duration,8) elsif dc=="scrolldownright" @@transition=ScrollScreen.new(duration,3) elsif dc=="scrolldownleft" @@transition=ScrollScreen.new(duration,1) elsif dc=="scrollupleft" @@transition=ScrollScreen.new(duration,7) elsif dc=="scrollupright" @@transition=ScrollScreen.new(duration,9) elsif dc=="breakingglass" @@transition=BreakingGlass.new(duration) elsif dc=="mosaic" @@transition=MosaicTransition.new(duration) elsif dc=="zoomin" @@transition=ZoomInTransition.new(duration) else ret=false end Graphics.frame_reset if ret return ret end end class BreakingGlass def initialize(numframes) @disposed=false @numframes=numframes @opacitychange=(numframes<=0) ? 255 : 255.0/numframes cx=6 cy=5 @bitmap=Graphics.snap_to_bitmap if !@bitmap @disposed=true return end width=@bitmap.width/cx height=@bitmap.height/cy @numtiles=cx*cy @sprites=[] @offset=[] @y=[] for i in 0...@numtiles @sprites[i]=Sprite.new @sprites[i].z=100000 @sprites[i].bitmap=@bitmap @sprites[i].x=width*(i%cx) @sprites[i].y=height*(i/cx) @sprites[i].src_rect.set( @sprites[i].x,@sprites[i].y,width,height) @offset[i]=(rand(100)+1)*3.0/100.0 @y[i]=@sprites[i].y end end def disposed? @disposed end def dispose if !disposed? @bitmap.dispose for i in 0...@numtiles @sprites[i].visible=false @sprites[i].dispose end @sprites.clear @disposed=true end end def update return if disposed? continue=false for i in 0...@numtiles @sprites[i].opacity-=@opacitychange @y[i]+=@offset[i] @sprites[i].y=@y[i] continue=true if @sprites[i].opacity>0 end self.dispose if !continue end end class ShrinkingPieces def initialize(numframes,rotation) @disposed=false @rotation=rotation @numframes=numframes @opacitychange=(numframes<=0) ? 255 : 255.0/numframes cx=6 cy=5 @bitmap=Graphics.snap_to_bitmap if !@bitmap @disposed=true return end width=@bitmap.width/cx height=@bitmap.height/cy @numtiles=cx*cy @sprites=[] for i in 0...@numtiles @sprites[i]=Sprite.new @sprites[i].z=200000 @sprites[i].bitmap=@bitmap @sprites[i].ox=width/2 @sprites[i].oy=height/2 @sprites[i].x=width*(i%cx)+@sprites[i].ox @sprites[i].y=height*(i/cx)+@sprites[i].oy @sprites[i].src_rect.set( width*(i%cx),height*(i/cx),width,height) end end def disposed? @disposed end def dispose if !disposed? @bitmap.dispose for i in 0...@numtiles @sprites[i].visible=false @sprites[i].dispose end @sprites.clear @disposed=true end end def update return if disposed? continue=false for i in 0...@numtiles @sprites[i].opacity-=@opacitychange if @rotation @sprites[i].angle+=40 @sprites[i].angle%=360 end @sprites[i].zoom_x=@sprites[i].opacity/255.0 @sprites[i].zoom_y=@sprites[i].opacity/255.0 continue=true if @sprites[i].opacity>0 end self.dispose if !continue end end class SplashTransition SPLASH_SIZE=32 def initialize(numframes,vague=9.6) @duration=numframes @numframes=numframes @splash_dir = [] @disposed=false if @numframes<=0 @disposed=true return end @buffer=Graphics.snap_to_bitmap if !@buffer @disposed=true return end @sprite = RPG::Sprite.new @sprite.bitmap = Bitmap.new(Graphics.width, Graphics.height) @sprite.z = 200000 size = SPLASH_SIZE size = [size,1].max cells = Graphics.width*Graphics.height / (size ** 2) rows = Graphics.width / size rect = Rect.new(0, 0, size, size) mag = 40.0 / @numframes cells.times { |i| rect.x = i % rows * size rect.y = i / rows * size x = rect.x / size - (rows >> 1) y = rect.y / size - ((cells / rows) >> 1) r = Math.sqrt(x ** 2 + y ** 2) / vague @splash_dir[i] = [] if r != 0 @splash_dir[i][0] = x / r @splash_dir[i][1] = y / r else @splash_dir[i][0] = x != 0 ? (x * 1.5) : (pmrand * vague) @splash_dir[i][1] = y != 0 ? (y * 1.5) : (pmrand * vague) end @splash_dir[i][0] += (rand - 0.5) * vague @splash_dir[i][1] += (rand - 0.5) * vague @splash_dir[i][0] *= mag @splash_dir[i][1] *= mag } @sprite.bitmap.blt(0, 0,@buffer,@buffer.rect) end def disposed?; @disposed; end def dispose return if disposed? @buffer.dispose if @buffer @buffer=nil @sprite.visible=false @sprite.bitmap.dispose @sprite.dispose @disposed=true end def update return if disposed? if @duration==0 dispose else size = SPLASH_SIZE cells = Graphics.width*Graphics.height / (size ** 2) rows = Graphics.width / size rect = Rect.new(0, 0, size, size) buffer = @buffer sprite = @sprite phase = @numframes - @duration sprite.bitmap.clear cells.times { |i| rect.x = i % rows * size rect.y = i / rows * size dx = rect.x + @splash_dir[i][0] * phase dy = rect.y + @splash_dir[i][1] * phase sprite.bitmap.blt(dx, dy, buffer, rect) } sprite.opacity = 384 * @duration / @numframes @duration-=1 end end private def pmrand return (rand(2) == 0 ? 1 : -1) end end class RandomStripeTransition RAND_STRIPE_SIZE=2 def initialize(numframes,direction) @duration=numframes @numframes=numframes @disposed=false if @numframes<=0 @disposed=true return end @buffer=Graphics.snap_to_bitmap if !@buffer @disposed=true return end @sprite = RPG::Sprite.new @sprite.bitmap = Bitmap.new(Graphics.width,Graphics.height) @sprite.z = 200000 ########## @direction=direction size = RAND_STRIPE_SIZE bands = (@direction == 0 ? Graphics.width : Graphics.height) / size @rand_stripe_deleted = [] @rand_stripe_deleted_count = 0 ary = (0...bands).to_a @rand_stripe_index_array = ary.sort_by { rand } ########## @sprite.bitmap.blt(0, 0,@buffer,@buffer.rect) end def disposed?; @disposed; end def dispose return if disposed? @buffer.dispose if @buffer @buffer=nil @sprite.visible=false @sprite.bitmap.dispose @sprite.dispose @disposed=true end def update return if disposed? if @duration==0 dispose else dir = @direction size = RAND_STRIPE_SIZE bands = (dir == 0 ? Graphics.width : Graphics.height) / size rect = Rect.new(0, 0, (dir == 0 ? size : Graphics.width), (dir == 0 ? Graphics.height : size)) buffer = @buffer sprite = @sprite phase = @numframes - @duration count = (bands - bands * @duration / @numframes) - @rand_stripe_deleted_count while count > 0 @rand_stripe_deleted[@rand_stripe_index_array.pop] = true @rand_stripe_deleted_count += 1 count -= 1 end sprite.bitmap.clear bands.to_i.times { |i| unless @rand_stripe_deleted[i] if dir == 0 rect.x = i * size sprite.bitmap.blt(rect.x, 0, buffer, rect) else rect.y = i * size sprite.bitmap.blt(0, rect.y, buffer, rect) end end } @duration-=1 end end end class ZoomInTransition def initialize(numframes) @duration=numframes @numframes=numframes @disposed=false if @numframes<=0 @disposed=true return end @buffer=Graphics.snap_to_bitmap if !@buffer @disposed=true return end @width=@buffer.width @height=@buffer.height @sprite = RPG::Sprite.new @sprite.bitmap = @buffer @sprite.ox=@width/2 @sprite.oy=@height/2 @sprite.x=@width/2 @sprite.y=@height/2 @sprite.z = 200000 end def disposed?; @disposed; end def dispose return if disposed? @buffer.dispose if @buffer @buffer=nil @sprite.dispose if @sprite @disposed=true end def update return if disposed? if @duration==0 dispose else @sprite.zoom_x+=0.2 @sprite.zoom_y+=0.2 @sprite.opacity=(@duration-1)*255/@numframes @duration-=1 end end end class ScrollScreen def initialize(numframes,direction) @duration=numframes @numframes=numframes @dir=direction @disposed=false if @numframes<=0 @disposed=true return end @buffer=Graphics.snap_to_bitmap if !@buffer @disposed=true return end @width=@buffer.width @height=@buffer.height @sprite = RPG::Sprite.new @sprite.bitmap = @buffer @sprite.z = 200000 end def disposed?; @disposed; end def dispose return if disposed? @buffer.dispose if @buffer @buffer=nil @sprite.dispose if @sprite @disposed=true end def update return if disposed? if @duration==0 dispose else case @dir when 1 # down left @sprite.y+=(@buffer.height/@numframes) @sprite.x-=(@buffer.width/@numframes) when 2 # down @sprite.y+=(@buffer.height/@numframes) when 3 # down right @sprite.y+=(@buffer.height/@numframes) @sprite.x+=(@buffer.width/@numframes) when 4 # left @sprite.x-=(@buffer.width/@numframes) when 6 # right @sprite.x+=(@buffer.width/@numframes) when 7 # up left @sprite.y-=(@buffer.height/@numframes) @sprite.x-=(@buffer.width/@numframes) when 8 # up @sprite.y-=(@buffer.height/@numframes) when 9 # up right @sprite.y-=(@buffer.height/@numframes) @sprite.x+=(@buffer.width/@numframes) end @duration-=1 end end end class MosaicTransition def initialize(numframes) @duration=numframes @numframes=numframes @disposed=false if @numframes<=0 @disposed=true return end @buffer=Graphics.snap_to_bitmap if !@buffer @disposed=true return end @width=@buffer.width @height=@buffer.height @sprite = RPG::Sprite.new @sprite.bitmap = @buffer @sprite.z = 200000 @bitmapclone=@buffer.clone @bitmapclone2=@buffer.clone end def disposed?; @disposed; end def dispose return if disposed? @buffer.dispose if @buffer @buffer=nil @sprite.dispose if @sprite @disposed=true end def update return if disposed? if @duration==0 dispose else @bitmapclone2.stretch_blt( Rect.new(0,0,@buffer.width*@duration/@numframes, @buffer.height*@duration/@numframes),@bitmapclone, Rect.new(0,0,@buffer.width,@buffer.height)) @buffer.stretch_blt( Rect.new(0,0,@buffer.width,@buffer.height),@bitmapclone2, Rect.new(0,0,@buffer.width*@duration/@numframes, @buffer.height*@duration/@numframes)) @duration-=1 end end end
SpriteWindow
[
Selecionar
] [
-
]
############################# ############################# module MessageConfig FontName="Pokemon Emerald" # in Graphics/Windowskins/ TextSkinName="frlgtextskin.png" # full path to file ChoiceSkinName="skin1.png" WindowOpacity=255 end LIGHTTEXTBASE=Color.new(31*8,31*8,31*8) LIGHTTEXTSHADOW=Color.new(23*8,23*8,23*8) DARKTEXTBASE=Color.new(12*8,12*8,12*8) DARKTEXTSHADOW=Color.new(26*8,26*8,25*8) # 0 = Pause cursor is displayed at end of text # 1 = Pause cursor is displayed at bottom right # 2 = Pause cursor is displayed at lower middle side CURSORMODE=0 ############################# ############################# module GifLibrary @@loadlib=Win32API.new("Kernel32.dll","LoadLibrary",'p','') if FileTest.exist?("gif.dll") PngDll=@@loadlib.call("gif.dll") GifToPngFiles=Win32API.new("gif.dll","GifToPngFiles",'pp','l') GifToPngFilesInMemory=Win32API.new("gif.dll","GifToPngFilesInMemory",'plp','l') CopyDataString=Win32API.new("gif.dll","CopyDataString",'lpl','l') FreeDataString=Win32API.new("gif.dll","FreeDataString",'l','') else PngDll=nil end def self.getDataFromResult(result) datasize=CopyDataString.call(result,"",0) ret=nil if datasize!=0 data="0"*datasize CopyDataString.call(result,data,datasize) ret=data.unpack("V*") end FreeDataString.call(result) return ret end end class AnimatedBitmap def initialize(file,hue=0) if file[/^\\[(\\d+)\\]/] @bitmap=PngAnimatedBitmap.new(file,hue) else @bitmap=GifBitmap.new(file,hue) end end def [](index); @bitmap[index]; end def length; @bitmap.length; end def each; @bitmap.each { yield }; end def bitmap; @bitmap.bitmap; end def currentIndex; @bitmap.currentIndex; end def frameDelay; @bitmap.frameDelay; end def totalFrames; @bitmap.totalFrames; end def disposed?; @bitmap.disposed?; end def update; @bitmap.update; end def dispose; @bitmap.dispose; end end class PngAnimatedBitmap # Creates an animated bitmap from a PNG file. def initialize(file,hue=0) @frames=[] @currentFrame=0 @framecount=0 panorama=BitmapCache.load_bitmap(file,hue) if file[/^\\[(\\d+)\\]/] # File has a frame count numFrames=$1.to_i if numFrames<=0 raise "Invalid frame count in #{file}" end if panorama.width % numFrames != 0 raise "Bitmap's width (#{panorama.width}) is not divisible by frame count: #{file}" end subWidth=panorama.width/numFrames for i in 0...numFrames subBitmap=Bitmap.new(subWidth,panorama.height) subBitmap.blt(0,0,panorama,Rect.new(subWidth*i,0,subWidth,panorama.height)) @frames.push(subBitmap) end panorama.dispose else @frames=[panorama] self.bitmap=@frames[0] end end def [](index) return @frames[index] end def bitmap @gifbitmaps[@currentFrame] end def currentIndex @currentFrame end def frameDelay(index) return 10 end def length @frames.length end def each @frames.each { yield } end def totalFrames 10*@frames.length end def disposed? @disposed end def update return if disposed? if @frames.length>1 @framecount+=1 if @framecount>=10 @framecount=0 @currentFrame+=1 @currentFrame%=@frames.length end end end def dispose for i in @frames i.dispose end @disposed=true end end class GifBitmap # Creates a bitmap from a GIF file with the specified # optional viewport. Can also load non-animated bitmaps. def initialize(file,hue=0) @gifbitmaps=[] @gifdelays=[] @totalframes=0 @framecount=0 @currentIndex=0 @disposed=false bitmap=nil filestring=pbGetFileString(file) filestring=pbGetFileString(file+".gif") if !filestring filestring=pbGetFileString(file+".png") if !filestring filestring=pbGetFileString(file+".jpg") if !filestring filestring=pbGetFileString(file+".bmp") if !filestring if filestring && filestring[0]!=0x47 begin bitmap=BitmapCache.load_bitmap(file) rescue bitmap=nil end end if bitmap # Have a regular non-animated bitmap @totalframes=1 @framecount=0 @gifbitmaps=[bitmap] @gifdelays=[1] else if filestring && GifLibrary::PngDll result=GifLibrary::GifToPngFilesInMemory.call(filestring,filestring.length,File.basename(file)) else result=0 end if result>0 @gifdelays=GifLibrary.getDataFromResult(result) @totalframes=@gifdelays.pop for i in 0...@gifdelays.length @gifdelays[i]=[@gifdelays[i],1].max bmfile=sprintf("%s%d.png",File.basename(file),i); if FileTest.exist?(bmfile) @gifbitmaps.push(Bitmap.new(bmfile)) File.delete(bmfile) else @gifbitmaps.push(Bitmap.new(32,32)) end end end if @gifbitmaps.length==0 @gifbitmaps=[Bitmap.new(32,32)] @gifdelays=[1] end end end def [](index) return @gifbitmaps[index] end def bitmap @gifbitmaps[@currentIndex] end def currentIndex @currentIndex end def frameDelay(index) return @gifdelay[index]/2 # Due to frame count being incremented by 2 end def length @gifbitmaps.length end def each @gifbitmaps.each { yield } end def totalFrames @totalframes/2 # Due to frame count being incremented by 2 end def disposed? @disposed end def width @gifbitmaps.length==0 ? 0 : @gifbitmaps[0].width end def height @gifbitmaps.length==0 ? 0 : @gifbitmaps[0].height end # This function must be called in order to animate # the GIF image. def update return if disposed? if @gifbitmaps.length>0 @framecount+=2 @framecount=@totalframes<=0 ? 0 : @framecount%@totalframes frametoshow=0 for i in 0...@gifdelays.length frametoshow=i if @gifdelays[i]<=@framecount end @currentIndex=frametoshow end end def dispose for i in @gifbitmaps i.dispose end @disposed=true end end class GifSprite # Creates a sprite from a GIF file with the specified # optional viewport. Can also load non-animated bitmaps. # 'File' can be nil. def initialize(file=nil,viewport=nil) @sprite=SpriteWrapper.new(viewport) if file @bitmap=AnimatedBitmap.new(file) @sprite.bitmap=@bitmap.bitmap end end def [](index); @bitmap[index]; end def length; @bitmap.length; end def each; @bitmap.each { yield }; end def currentIndex; @bitmap.currentIndex; end def frameDelay; @bitmap.frameDelay; end def totalFrames; @bitmap.totalFrames; end def setBitmap(file) @bitmap.dispose if @bitmap @bitmap=AnimatedBitmap.new(file) @sprite.bitmap=@bitmap.bitmap end def bitmap @sprite.bitmap end def bitmap=(value) @sprite.bitmap=value end def disposed? @sprite.disposed? end def width @bitmap.bitmap.width end def height @bitmap.bitmap.height end # This function must be called in order to animate # the GIF image. def update @bitmap.update @sprite.update if @sprite.bitmap!=@bitmap.bitmap oldsrc=@sprite.src_rect ? @sprite.src_rect.clone : nil @sprite.bitmap=@bitmap.bitmap @sprite.src_rect=oldsrc if oldsrc end end def dispose @bitmap.dispose @sprite.dispose end def flash(*arg); sprite.flash(*arg); end %w[ x y z ox oy visible zoom_x zoom_y angle mirror bush_depth opacity blend_type color tone src_rect viewport ].each do |s| eval <<-__END__ def #{s}; @sprite.#{s}; end def #{s}=(value); @sprite.#{s}=value; end __END__ end end ############################# ############################# def pbGetSystemFrame return $PokemonSystem ? $PokemonSystem.frame : 0 end def pbGetSystemFont return $PokemonSystem ? $PokemonSystem.font : 0 end def pbGetSystemTextSpeed return $PokemonSystem ? $PokemonSystem.textspeed : ((Graphics.frame_rate>40) ? 2 : 3) end def pbSetSystemTextSpeed(speed) $PokemonSystem.textspeed=speed if $PokemonSystem end def pbGetDecisionSE if $data_system && $data_system.respond_to?("decision_se") && $data_system.decision_se.name!="" return "Audio/SE/"+$data_system.decision_se.name elsif $data_system && $data_system.respond_to?("sounds") && $data_system.sounds[1] && $data_system.sounds[1].name!="" return "Audio/SE/"+$data_system.sounds[1].name else return "Audio/SE/Choose.wav" end end $VersionStyles=[ [MessageConfig::FontName], ["Pokemon RS"], ["Pokemon FireLeaf"], ["Pokemon DP"], ["Pokemon RS Intl"] ] $TextFrames=[ "Graphics/Windowskins/"+MessageConfig::ChoiceSkinName, "Graphics/Windowskins/skin2.png", "Graphics/Windowskins/skin3.png", "Graphics/Windowskins/skin4.png", "Graphics/Windowskins/skin5.png", "Graphics/Windowskins/skin6.png", "Graphics/Windowskins/skin7.png", "Graphics/Windowskins/skin8.png", "Graphics/Windowskins/skin9.png", "Graphics/Windowskins/skin10.png", "Graphics/Windowskins/skin11.png", "Graphics/Windowskins/skin12.png", "Graphics/Windowskins/skin13.png", "Graphics/Windowskins/skin14.png", "Graphics/Windowskins/skin15.png", "Graphics/Windowskins/skin16.png", "Graphics/Windowskins/skin17.png", "Graphics/Windowskins/skin18.png", "Graphics/Windowskins/skin19.png", "Graphics/Windowskins/skin20.png", "Graphics/Windowskins/skin21.png", "Graphics/Windowskins/skin22.png", "Graphics/Windowskins/skin23.png", "Graphics/Windowskins/skin24.png", "Graphics/Windowskins/skin25.png", "Graphics/Windowskins/skin26.png", "Graphics/Windowskins/skin27.png", "Graphics/Windowskins/skin28.png", "Graphics/Windowskins/textbox0.png", "Graphics/Windowskins/textbox1.png", "Graphics/Windowskins/textbox2.png", "Graphics/Windowskins/textbox3.png", "Graphics/Windowskins/textbox4.png" ] $SpeechFrames=[ nil, # Default text skin, leave as nil "rstextskin", "frlgtextskin", "emtextskin", "textbox0", "textbox1", "textbox2", "textbox3", "textbox4", "textbox5", "textbox6", "textbox7", "textbox8", "textbox9", "textbox10", "textbox11", "textbox12", "textbox13", "textbox14", "textbox15", "textbox16", "textbox17", "textbox18", "textbox19" ] ######################### def pbDrawShadow(bitmap,x,y,width,height,string) bitmap.draw_text(x+2,y,width,height,string) bitmap.draw_text(x,y+2,width,height,string) bitmap.draw_text(x+2,y+2,width,height,string) end def pbCopyBitmap(dstbm,srcbm,x,y,opacity=255) rc=Rect.new(0,0,srcbm.width,srcbm.height) dstbm.blt(x,y,srcbm,rc,opacity) end def using(window) begin yield if block_given? ensure window.dispose end end def pbBottomRight(window) window.x=Graphics.width-window.width window.y=Graphics.height-window.height end def pbBottomLeft(window) window.x=0 window.y=Graphics.height-window.height end def pbBottomLeftLines(window,lines,width=nil) window.x=0 window.width=width ? width : Graphics.width window.height=32+lines*32 window.y=Graphics.height-window.height end def pbDisposed?(x) if x.is_a?(Viewport) begin x.rect=x.rect rescue return true end return false else return x.disposed? end end def getDefaultTextColors(windowskin) if !windowskin || windowskin.disposed? || windowskin.width!=128 || windowskin.height!=128 if isDarkWindowskin(windowskin) return [LIGHTTEXTBASE,LIGHTTEXTSHADOW] # White else return [DARKTEXTBASE,DARKTEXTSHADOW] # Dark gray end else # VX windowskin color=windowskin.get_pixel(64, 96) shadow=nil isdark=(color.red+color.green+color.blue)/3 < 128 if isdark shadow=Color.new(color.red+64,color.green+64,color.blue+64) else shadow=Color.new(color.red-64,color.green-64,color.blue-64) end return [color,shadow] end end def pbDoEnsureBitmap(bitmap,dwidth,dheight) if !bitmap||bitmap.disposed?||bitmap.width<dwidth||bitmap.height<dheight oldfont=(bitmap && !bitmap.disposed?) ? bitmap.font : nil bitmap.dispose if bitmap bitmap=Bitmap.new([1,dwidth].max,[1,dheight].max) if !oldfont pbSetSystemFont(bitmap) else bitmap.font=oldfont end if bitmap.font && bitmap.font.respond_to?("shadow") bitmap.font.shadow=false end end return bitmap end def pbUpdateSpriteHash(windows) for i in windows window=i[1] if window if window.is_a?(Sprite) || window.is_a?(Window) window.update if !pbDisposed?(window) elsif window.is_a?(Plane) begin i[1].update if !window.disposed? rescue NoMethodError end end end end end def pbDisposeSpriteHash(sprites) for i in sprites sprite=i[1] if sprite && !pbDisposed?(sprite) if sprite.is_a?(Sprite) || sprite.is_a?(Plane) sprite.bitmap.dispose if sprite.bitmap && !sprite.bitmap.disposed? end sprite.dispose end sprites[i[0]]=nil end sprites.clear end def pbDisposeSprite(sprites,id) sprite=sprites[id] if sprite && !pbDisposed?(sprite) if sprite.is_a?(Sprite) || sprite.is_a?(Plane) sprite.bitmap.dispose if sprite.bitmap && !sprite.bitmap.disposed? end sprite.dispose end sprites[id]=nil end def pbDrawTextPositions(bitmap,textpos) for i in textpos textsize=bitmap.text_size(i[0]) x=i[1] y=i[2] if i[3]==true || i[3]==1 # right align x-=textsize.width if i[3] elsif i[3]==2 # centered x-=(textsize.width/2) if i[3] end if i[5] bitmap.font.color=i[5] pbDrawShadow(bitmap,x,y,textsize.width,textsize.height,i[0]) end bitmap.font.color=i[4] bitmap.draw_text(x,y,textsize.width,textsize.height,i[0]) end end def pbDrawImagePositions(bitmap,textpos) for i in textpos srcbitmap=BitmapCache.load_bitmap(i[0]) x=i[1] y=i[2] srcx=i[3] srcy=i[4] width=i[5]>=0 ? i[5] : srcbitmap.width height=i[6]>=0 ? i[6] : srcbitmap.height srcrect=Rect.new(srcx,srcy,width,height) bitmap.blt(x,y,srcbitmap,srcrect) srcbitmap.dispose end end class Game_Temp attr_accessor :fadestate def fadestate return @fadestate ? @fadestate : 0 end end def pbPushFade if $game_temp $game_temp.fadestate=[$game_temp.fadestate+1,0].max end end def pbPopFade if $game_temp $game_temp.fadestate=[$game_temp.fadestate-1,0].max end end def pbIsFaded? if $game_temp return $game_temp.fadestate>0 else return false end end =begin pbFadeOutIn(z) { block } Fades out the screen before a block is run and fades it back in after the block exits. z indicates the z-coordinate of the viewport used for this effect =end def pbFadeOutIn(z) col=Color.new(0,0,0,0) viewport=Viewport.new(0,0,Graphics.width,Graphics.height) viewport.z=z for j in 0..17 col.set(0,0,0,j*15) viewport.color=col Graphics.update Input.update end pbPushFade yield if block_given? pbPopFade for j in 0..17 col.set(0,0,0,(17-j)*15) viewport.color=col Graphics.update Input.update end viewport.dispose end def pbFadeOutAndHide(sprites) visiblesprites={} for j in 0..26 yield if block_given? for i in sprites next if !i[1] next if pbDisposed?(i[1]) if i[1].is_a?(Sprite) || i[1].is_a?(Window) i[1].update elsif i[1].is_a?(Plane) begin i[1].update rescue NoMethodError end end next if pbDisposed?(i[1]) i[1].color.red=0 i[1].color.green=0 i[1].color.blue=0 i[1].color.alpha=j*10 i[1].color=i[1].color end Graphics.update Input.update end for i in sprites next if !i[1] next if pbDisposed?(i[1]) visiblesprites[i[0]]=true if i[1].visible i[1].visible=false end return visiblesprites end def pbFadeInAndShow(sprites,visiblesprites=nil) if visiblesprites for i in visiblesprites if i[1] && sprites[i[0]] && !pbDisposed?(sprites[i[0]]) sprites[i[0]].visible=true end end end for j in 0..26 yield if block_given? for i in sprites next if !i[1] next if pbDisposed?(i[1]) if i[1].is_a?(Sprite) || i[1].is_a?(Window) i[1].update elsif i[1].is_a?(Plane) begin i[1].update rescue NoMethodError end end next if pbDisposed?(i[1]) i[1].color.red=0 i[1].color.green=0 i[1].color.blue=0 i[1].color.alpha=((26-j)*10) next if pbDisposed?(i[1]) i[1].color=i[1].color end Graphics.update Input.update end end def pbHaveString(x) ret=pbGetFileString(x) return (ret!=nil && ret!="") end def pbHaveBitmap(x) return BitmapCache.load_bitmap(x) rescue nil end def pbTryString(x) return pbHaveString(x) ? x : nil end def pbTryBitmap(x) return pbHaveBitmap(x) ? x : nil end def pbResolveBitmap(x) return nil if !x noext=x.gsub(/\\.(bmp|png|gif|jpg|jpeg)$/,"") filename=pbTryBitmap(x) filename=pbTryBitmap("#{noext}.png") if !filename filename=pbTryString("#{x}.gif") if !filename filename=pbTryString("#{noext}.gif") if !filename filename=pbTryBitmap("#{noext}.jpg") if !filename filename=pbTryBitmap("#{noext}.jpeg") if !filename filename=pbTryBitmap("#{noext}.bmp") if !filename return filename end def addBackgroundPlane(sprites,planename,background,viewport=nil) sprites[planename]=AnimatedPlane.new(viewport) bitmapName=pbResolveBitmap("Graphics/Pictures/#{background}") if bitmapName==nil # Plane should exist in any case sprites[planename].bitmap=nil sprites[planename].visible=false else sprites[planename].setBitmap(bitmapName) for spr in sprites.values if spr.is_a?(Window) spr.windowskin=nil end end end end def addBackgroundOrColoredPlane(sprites,planename,background,color,viewport=nil) bitmapName=pbResolveBitmap("Graphics/Pictures/#{background}") if bitmapName==nil # Plane should exist in any case sprites[planename]=ColoredPlane.new(color,@viewport) else sprites[planename]=AnimatedPlane.new(viewport) sprites[planename].setBitmap(bitmapName) for spr in sprites.values if spr.is_a?(Window) spr.windowskin=nil end end end end def pbSetSystemFont(bitmap) bitmap.font.name=[$VersionStyles[pbGetSystemFont][0],"Arial Narrow","Arial"] if pbGetSystemFont==2 bitmap.font.size=29 else bitmap.font.size=31 end end def pbSetSmallFont(bitmap) bitmap.font.name=["Pokemon Emerald Small","Arial Narrow","Arial"] bitmap.font.size=25 end def pbSetNarrowFont(bitmap) bitmap.font.name=["Pokemon Emerald Narrow","Arial Narrow","Arial"] bitmap.font.size=31 end ######################################################################### =begin SpriteWrapper is a class based on Sprite which wraps Sprite's properties. =end class SpriteWrapper < Sprite def initialize(viewport=nil) @sprite=Sprite.new(viewport) end def dispose @sprite.dispose end def disposed? return @sprite.disposed? end def viewport return @sprite.viewport end def flash(color,duration) return @sprite.flash(color,duration) end def update return @sprite.update end def x @sprite.x end def x=(value) @sprite.x=value end def y @sprite.y end def y=(value) @sprite.y=value end def bitmap @sprite.bitmap end def bitmap=(value) @sprite.bitmap=value end def src_rect @sprite.src_rect end def src_rect=(value) @sprite.src_rect=value end def visible @sprite.visible end def visible=(value) @sprite.visible=value end def z @sprite.z end def z=(value) @sprite.z=value end def ox @sprite.ox end def ox=(value) @sprite.ox=value end def oy @sprite.oy end def oy=(value) @sprite.oy=value end def zoom_x @sprite.zoom_x end def zoom_x=(value) @sprite.zoom_x=value end def zoom_y @sprite.zoom_y end def zoom_y=(value) @sprite.zoom_y=value end def angle @sprite.angle end def angle=(value) @sprite.angle=value end def mirror @sprite.mirror end def mirror=(value) @sprite.mirror=value end def bush_depth @sprite.bush_depth end def bush_depth=(value) @sprite.bush_depth=value end def opacity @sprite.opacity end def opacity=(value) @sprite.opacity=value end def blend_type @sprite.blend_type end def blend_type=(value) @sprite.blend_type=value end def color @sprite.color end def color=(value) @sprite.color=value end def tone @sprite.tone end def tone=(value) @sprite.tone=value end def viewport=(value) return if self.viewport==value bitmap=@sprite.bitmap src_rect=@sprite.src_rect visible=@sprite.visible x=@sprite.x y=@sprite.y z=@sprite.z ox=@sprite.ox oy=@sprite.oy zoom_x=@sprite.zoom_x zoom_y=@sprite.zoom_y angle=@sprite.angle mirror=@sprite.mirror bush_depth=@sprite.bush_depth opacity=@sprite.opacity blend_type=@sprite.blend_type color=@sprite.color tone=@sprite.tone @sprite.dispose @sprite=Sprite.new(value) @sprite.bitmap=bitmap @sprite.src_rect=src_rect @sprite.visible=visible @sprite.x=x @sprite.y=y @sprite.z=z @sprite.ox=ox @sprite.oy=oy @sprite.zoom_x=zoom_x @sprite.zoom_y=zoom_y @sprite.angle=angle @sprite.mirror=mirror @sprite.bush_depth=bush_depth @sprite.opacity=opacity @sprite.blend_type=blend_type @sprite.color=color @sprite.tone=tone end end ######################################################################### module ::Marshal class << self if !@oldloadAliased alias oldload load @oldloadAliased=true end def neverload return @@neverload end @@neverload=false def neverload=(value) @@neverload=value end def load(port,*arg) if @@neverload if port.is_a?(IO) return port.read else return port end end oldpos=port.pos if port.is_a?(IO) begin oldload(port,*arg) rescue if port.is_a?(IO) port.pos=oldpos return port.read else return port end end end end end def pbRgssExists?(filename) filename=canonicalize(filename) if FileTest.exist?("./Game.rgssad") return pbGetFileString(filename)!=nil else return FileTest.exist?(filename) end end def pbRgssOpen(file,mode=nil) file=canonicalize(file) Marshal.neverload=true begin str=load_data(file) ensure Marshal.neverload=false end if block_given? StringInput.open(str){|f| yield f } return nil else return StringInput.open(str) end end def pbGetFileString(file) file=canonicalize(file) Marshal.neverload=true str=nil begin str=load_data(file) rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, RGSSError str=nil ensure Marshal.neverload=false end return str end =begin SpriteWindow is a class based on Window which emulates Window's functionality. This class is necessary in order to change the viewport of windows (with viewport=) and to make windows fade in and out (with tone=). =end class SpriteWindowCursorRect < Rect def initialize(window) @window=window @x=0 @y=0 @width=0 @height=0 end attr_reader :x,:y,:width,:height def empty needupdate=@x!=0 || @y!=0 || @width!=0 || @height!=0 if needupdate @x=0 @y=0 @width=0 @height=0 @window.width=@window.width end end def isEmpty? return @x==0 && @y==0 && @width==0 && @height==0 end def set(x,y,width,height) needupdate=@x!=x || @y!=y || @width!=width || @height!=height if needupdate @x=x @y=y @width=width @height=height @window.width=@window.width end end def height=(value) @height=value; @window.width=@window.width end def width=(value) @width=value; @window.width=@window.width end def x=(value) @x=value; @window.width=@window.width end def y=(value) @y=value; @window.width=@window.width end end class SpriteWindow < Window attr_reader :tone attr_reader :color attr_reader :viewport attr_reader :contents attr_reader :ox attr_reader :oy attr_reader :x attr_reader :y attr_reader :z attr_reader :width attr_reader :active attr_reader :pause attr_reader :height attr_reader :opacity attr_reader :back_opacity attr_reader :contents_opacity attr_reader :visible attr_reader :cursor_rect attr_reader :contents_blend_type attr_reader :blend_type attr_reader :openness def windowskin @_windowskin end def initialize(viewport=nil) @sprites={} @spritekeys=[ "back", "corner0","side0","scroll0", "corner1","side1","scroll1", "corner2","side2","scroll2", "corner3","side3","scroll3", "cursor","contents","pause" ] @viewport=viewport @sidebitmaps=[nil,nil,nil,nil] @cursorbitmap=nil @bgbitmap=nil for i in @spritekeys @sprites[i]=Sprite.new(@viewport) end @disposed=false @tone=Tone.new(0,0,0) @color=Color.new(0,0,0,0) @blankcontents=Bitmap.new(1,1) # RGSS2 requires this @contents=@blankcontents @_windowskin=nil @rpgvx=false @compat=true @x=0 @y=0 @width=0 @height=0 @ox=0 @oy=0 @z=0 @stretch=true @visible=true @active=true @openness=255 @opacity=255 @back_opacity=255 @blend_type=0 @contents_blend_type=0 @contents_opacity=255 @cursor_rect=SpriteWindowCursorRect.new(self) @cursorblink=0 @cursoropacity=255 @pause=false @pauseframe=0 @flash=0 @pauseopacity=0 @skinformat=0 @skinrect=Rect.new(0,0,0,0) @trim=[16,16,16,16] privRefresh(true) end def dispose if !self.disposed? for i in @sprites i[1].dispose if i[1] @sprites[i[0]]=nil end for i in 0...@sidebitmaps.length @sidebitmaps[i].dispose if @sidebitmaps[i] @sidebitmaps[i]=nil end @blankcontents.dispose @cursorbitmap.dispose if @cursorbitmap @backbitmap.dispose if @backbitmap @sprites.clear @sidebitmaps.clear @_windowskin=nil @_contents=nil @disposed=true end end def stretch=(value) @stretch=value privRefresh(true) end def visible=(value) @visible=value privRefresh end def viewport=(value) @viewport=value for i in @spritekeys @sprites[i].dispose if @sprites[i] end for i in @spritekeys if @sprites[i].is_a?(Sprite) @sprites[i]=Sprite.new(@viewport) else @sprites[i]=nil end end privRefresh(true) end def z=(value) @z=value privRefresh end def disposed? return @disposed end def contents=(value) if @contents!=value @contents=value privRefresh if @visible end end def ox=(value) if @ox!=value @ox=value privRefresh if @visible end end def oy=(value) if @oy!=value @oy=value privRefresh if @visible end end def active=(value) @active=value privRefresh(true) end def cursor_rect=(value) if !value @cursor_rect.empty else @cursor_rect.set(value.x,value.y,value.width,value.height) end end def openness=(value) @openness=value @openness=0 if @openness<0 @openness=255 if @openness>255 privRefresh end def width=(value) @width=value privRefresh(true) end def height=(value) @height=value privRefresh(true) end def pause=(value) @pause=value @pauseopacity=0 if !value privRefresh if @visible end def x=(value) @x=value privRefresh if @visible end def y=(value) @y=value privRefresh if @visible end def opacity=(value) @opacity=value @opacity=0 if @opacity<0 @opacity=255 if @opacity>255 privRefresh if @visible end def back_opacity=(value) @back_opacity=value @back_opacity=0 if @back_opacity<0 @back_opacity=255 if @back_opacity>255 privRefresh if @visible end def contents_opacity=(value) @contents_opacity=value @contents_opacity=0 if @contents_opacity<0 @contents_opacity=255 if @contents_opacity>255 privRefresh if @visible end def tone=(value) @tone=value privRefresh if @visible end def color=(value) @color=value privRefresh if @visible end def blend_type=(value) @blend_type=value privRefresh if @visible end def flash(color,duration) return if disposed? @flash=duration+1 for i in @sprites i[1].flash(color,duration) end end def update return if disposed? mustchange=false if @active if @cursorblink==0 @cursoropacity-=8 @cursorblink=1 if @cursoropacity<=128 else @cursoropacity+=8 @cursorblink=0 if @cursoropacity>=255 end privRefreshCursor else @cursoropacity=128 privRefreshCursor end if @pause oldpauseframe=@pauseframe oldpauseopacity=@pauseopacity @pauseframe=(Graphics.frame_count / 8) % 4 @pauseopacity=[@pauseopacity+64,255].min mustchange=@pauseframe!=oldpauseframe || @pauseopacity!=oldpauseopacity end privRefresh if mustchange if @flash>0 for i in @sprites.values i.update end @flash-=1 end end ############# attr_reader :skinformat attr_reader :skinrect def loadSkinFile(file) begin data=load_data(file).split("\\n") # Body = X, Y, width, height of body rectangle within windowskin bodyRE=/[Bb]ody\\s*=\\s*(\\-?\\d+)\\s*,\\s*(\\-?\\d+)\\s*,\\s*(\\-?\\d+)\\s*,\\s*(\\-?\\d+)\\s*/ # Trim = X, Y, width, height of trim rectangle within windowskin trimRE=/[Tt]rim\\s*=\\s*(\\-?\\d+)\\s*,\\s*(\\-?\\d+)\\s*,\\s*(\\-?\\d+)\\s*,\\s*(\\-?\\d+)\\s*/ for line in data if line[bodyRE] @skinrect.set($~[1].to_i,$~[2].to_i,$~[3].to_i,$~[4].to_i) end if line[trimRE] @trim=[$~[1].to_i,$~[2].to_i,$~[3].to_i,$~[4].to_i] end end privRefresh(true) rescue Errno::ENOENT # ignore rescue raise end end def windowskin=(value) @_windowskin=value if @skinformat==1 @rpgvx=false @skinrect.set(16,16,16,16) @trim=[16,16,16,16] if @_windowskin && !@_windowskin.disposed? @skinrect.set((@_windowskin.width-16)/2,(@_windowskin.height-16)/2,16,16) @trim=[@skinrect.x,@skinrect.y,@skinrect.x,@skinrect.y] end else if value && value.is_a?(Bitmap) && !value.disposed? && value.width==128 @rpgvx=true else @rpgvx=false end @trim=[16,16,16,16] end privRefresh(true) end def skinrect=(value) @skinrect=value privRefresh end def skinformat=(value) @skinformat=value privRefresh(true) end def borderX return 32 if !@trim || skinformat==0 if @_windowskin && !@_windowskin.disposed? return @trim[0]+(@_windowskin.width-@trim[2]-@trim[0]) end return 32 end def borderY return 32 if !@trim || skinformat==0 if @_windowskin && !@_windowskin.disposed? return @trim[1]+(@_windowskin.height-@trim[3]-@trim[1]) end return 32 end def startX return !@trim || skinformat==0 ? 16 : @trim[0] end def startY return !@trim || skinformat==0 ? 16 : @trim[1] end def endX return !@trim || skinformat==0 ? 16 : @trim[2] end def endY return !@trim || skinformat==0 ? 16 : @trim[3] end def startX=(value) @trim[0]=value privRefresh end def startY=(value) @trim[1]=value privRefresh end def endX=(value) @trim[2]=value privRefresh end def endY=(value) @trim[3]=value privRefresh end ############# private def ensureBitmap(bitmap,dwidth,dheight) if !bitmap||bitmap.disposed?||bitmap.width<dwidth||bitmap.height<dheight bitmap.dispose if bitmap bitmap=Bitmap.new([1,dwidth].max,[1,dheight].max) end return bitmap end def tileBitmap(dstbitmap,dstrect,srcbitmap,srcrect) return if !srcbitmap || srcbitmap.disposed? left=dstrect.x top=dstrect.y y=0;loop do break unless y<dstrect.height x=0;loop do break unless x<dstrect.width dstbitmap.blt(x+left,y+top,srcbitmap,srcrect) x+=srcrect.width end y+=srcrect.height end end def privRefreshCursor contopac=self.contents_opacity cursoropac=@cursoropacity*contopac/255 @sprites["cursor"].opacity=cursoropac end def privRefresh(changeBitmap=false) return if self.disposed? backopac=self.back_opacity*self.opacity/255 contopac=self.contents_opacity cursoropac=@cursoropacity*contopac/255 haveskin=@_windowskin && !@_windowskin.disposed? for i in 0...4 @sprites["corner#{i}"].bitmap=@_windowskin @sprites["scroll#{i}"].bitmap=@_windowskin end @sprites["pause"].bitmap=@_windowskin @sprites["contents"].bitmap=@contents if haveskin for i in 0...4 @sprites["corner#{i}"].opacity=@opacity @sprites["corner#{i}"].tone=@tone @sprites["corner#{i}"].color=@color @sprites["corner#{i}"].visible=@visible @sprites["corner#{i}"].blend_type=@blend_type @sprites["side#{i}"].opacity=@opacity @sprites["side#{i}"].tone=@tone @sprites["side#{i}"].color=@color @sprites["side#{i}"].blend_type=@blend_type @sprites["side#{i}"].visible=@visible @sprites["scroll#{i}"].opacity=@opacity @sprites["scroll#{i}"].tone=@tone @sprites["scroll#{i}"].color=@color @sprites["scroll#{i}"].visible=@visible @sprites["scroll#{i}"].blend_type=@blend_type end for i in ["back","cursor","pause","contents"] @sprites[i].color=@color @sprites[i].tone=@tone @sprites[i].blend_type=@blend_type end @sprites["contents"].blend_type=@contents_blend_type @sprites["back"].opacity=backopac @sprites["contents"].opacity=contopac @sprites["cursor"].opacity=cursoropac @sprites["pause"].opacity=@pauseopacity supported=(@skinformat==0) hascontents=(@contents && !@contents.disposed?) @sprites["back"].visible=@visible @sprites["contents"].visible=@visible && @openness==255 @sprites["pause"].visible=supported && @visible && @pause @sprites["cursor"].visible=supported && @visible && @openness==255 @sprites["scroll0"].visible = false @sprites["scroll1"].visible = false @sprites["scroll2"].visible = false @sprites["scroll3"].visible = false else for i in 0...4 @sprites["corner#{i}"].visible=false @sprites["side#{i}"].visible=false @sprites["scroll#{i}"].visible=false end @sprites["contents"].visible=@visible && @openness==255 @sprites["contents"].color=@color @sprites["contents"].tone=@tone @sprites["contents"].blend_type=@contents_blend_type @sprites["contents"].opacity=contopac @sprites["back"].visible=false @sprites["pause"].visible=false @sprites["cursor"].visible=false end for i in @spritekeys @sprites[i].z=@z end if @compat && @skinformat==0 # Compatibility Mode @sprites["cursor"].z=@z+1 @sprites["contents"].z=@z+2 @sprites["pause"].z=@z+2 end if @skinformat==0 startX=16 startY=16 endX=16 endY=16 trimStartX=16 trimStartY=16 trimWidth=32 trimHeight=32 if @rpgvx trimX=64 trimY=0 backRect=Rect.new(0,0,64,64) blindsRect=Rect.new(0,64,64,64) else trimX=128 trimY=0 backRect=Rect.new(0,0,128,128) blindsRect=nil end if @_windowskin && !@_windowskin.disposed? @sprites["corner0"].src_rect.set(trimX,trimY+0,16,16); @sprites["corner1"].src_rect.set(trimX+48,trimY+0,16,16); @sprites["corner2"].src_rect.set(trimX,trimY+48,16,16); @sprites["corner3"].src_rect.set(trimX+48,trimY+48,16,16); @sprites["scroll0"].src_rect.set(trimX+24, trimY+16, 16, 8) # up @sprites["scroll3"].src_rect.set(trimX+24, trimY+40, 16, 8) # down @sprites["scroll1"].src_rect.set(trimX+16, trimY+24, 8, 16) # left @sprites["scroll2"].src_rect.set(trimX+40, trimY+24, 8, 16) # right cursorX=trimX cursorY=trimY+64 sideRects=[ Rect.new(trimX+16,trimY+0,32,16), Rect.new(trimX,trimY+16,16,32), Rect.new(trimX+48,trimY+16,16,32), Rect.new(trimX+16,trimY+48,32,16) ] pauseRects=[ trimX+32,trimY+64, trimX+48,trimY+64, trimX+32,trimY+80, trimX+48,trimY+80, ] pauseWidth=16 pauseHeight=16 @sprites["pause"].src_rect.set( pauseRects[@pauseframe*2], pauseRects[@pauseframe*2+1], pauseWidth,pauseHeight ) end else trimStartX=@trim[0] trimStartY=@trim[1] trimWidth=@trim[0]+(@skinrect.width-@trim[2]+@trim[0]) trimHeight=@trim[1]+(@skinrect.height-@trim[3]+@trim[1]) if @_windowskin && !@_windowskin.disposed? # width of left end of window startX=@skinrect.x # width of top end of window startY=@skinrect.y backWidth=@skinrect.width backHeight=@skinrect.height cx=@skinrect.x+@skinrect.width # right side of BODY rect cy=@skinrect.y+@skinrect.height # bottom side of BODY rect # width of right end of window endX=(!@_windowskin || @_windowskin.disposed?) ? @skinrect.x : @_windowskin.width-cx # height of bottom end of window endY=(!@_windowskin || @_windowskin.disposed?) ? @skinrect.y : @_windowskin.height-cy @sprites["corner0"].src_rect.set(0,0,startX,startY); @sprites["corner1"].src_rect.set(cx,0,endX,startY); @sprites["corner2"].src_rect.set(0,cy,startX,endY); @sprites["corner3"].src_rect.set(cx,cy,endX,endY); backRect=Rect.new(@skinrect.x,@skinrect.y, @skinrect.width,@skinrect.height); blindsRect=nil sideRects=[ Rect.new(startX,0,@skinrect.width,startY), # side0 (top) Rect.new(0,startY,startX,@skinrect.height), # side1 (left) Rect.new(cx,startY,endX,@skinrect.height), # side2 (right) Rect.new(startX,cy,@skinrect.width,endY) # side3 (bottom) ] end end if @width>trimWidth && @height>trimHeight @sprites["contents"].src_rect.set(@ox,@oy,@width-trimWidth,@height-trimHeight) else @sprites["contents"].src_rect.set(0,0,0,0) end @sprites["contents"].x=@x+trimStartX @sprites["contents"].y=@y+trimStartY if @compat && @skinformat==0 # Compatibility mode =begin if @skinformat==0 && @_windowskin && !@_windowskin.disposed? && @contents && !@contents.disposed? @sprites["scroll0"].visible = @visible && hascontents && @oy > 0 @sprites["scroll1"].visible = @visible && hascontents && @ox > 0 @sprites["scroll2"].visible = @visible && (@contents.width - @ox) > @width-trimWidth @sprites["scroll3"].visible = @visible && (@contents.height - @oy) > @height-trimHeight end =end end if @_windowskin && !@_windowskin.disposed? backTrimX=startX+endX backTrimY=startX+endX borderX=startX+endX borderY=startY+endY @sprites["corner0"].x=@x @sprites["corner0"].y=@y @sprites["corner1"].x=@x+@width-endX @sprites["corner1"].y=@y @sprites["corner2"].x=@x @sprites["corner2"].y=@y+@height-endY @sprites["corner3"].x=@x+@width-endX @sprites["corner3"].y=@y+@height-endY @sprites["side0"].x=@x+startX @sprites["side0"].y=@y @sprites["side1"].x=@x @sprites["side1"].y=@y+startY @sprites["side2"].x=@x+@width-endX @sprites["side2"].y=@y+startY @sprites["side3"].x=@x+startX @sprites["side3"].y=@y+@height-endY @sprites["scroll0"].x = @x+@width / 2 - 8 @sprites["scroll0"].y = @y+8 @sprites["scroll1"].x = @x+8 @sprites["scroll1"].y = @y+@height / 2 - 8 @sprites["scroll2"].x = @x+@width - 16 @sprites["scroll2"].y = @y+@height / 2 - 8 @sprites["scroll3"].x = @x+@width / 2 - 8 @sprites["scroll3"].y = @y+@height - 16 @sprites["cursor"].x=@x+startX+@cursor_rect.x @sprites["cursor"].y=@y+startY+@cursor_rect.y if @compat && @skinformat==0 # Compatibility mode @sprites["back"].x=@x+2 @sprites["back"].y=@y+2 else @sprites["back"].x=@x+startX @sprites["back"].y=@y+startY end end if changeBitmap && @_windowskin && !@_windowskin.disposed? if @skinformat==0 @sprites["cursor"].x=@x+startX+@cursor_rect.x @sprites["cursor"].y=@y+startY+@cursor_rect.y width=@cursor_rect.width height=@cursor_rect.height if width > 0 && height > 0 cursorrects=[ # sides Rect.new(cursorX+2, cursorY+0, 28, 2), Rect.new(cursorX+0, cursorY+2, 2, 28), Rect.new(cursorX+30, cursorY+2, 2, 28), Rect.new(cursorX+2, cursorY+30, 28, 2), # corners Rect.new(cursorX+0, cursorY+0, 2, 2), Rect.new(cursorX+30, cursorY+0, 2, 2), Rect.new(cursorX+0, cursorY+30, 2, 2), Rect.new(cursorX+30, cursorY+30, 2, 2), # back Rect.new(cursorX+2, cursorY+2, 28, 28) ] margin=2 fullmargin=4 @cursorbitmap = ensureBitmap(@cursorbitmap, width, height) @cursorbitmap.clear @sprites["cursor"].bitmap=@cursorbitmap @sprites["cursor"].src_rect.set(0,0,width,height) rect = Rect.new(margin,margin, width - fullmargin, height - fullmargin) @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[8]) @cursorbitmap.blt(0, 0, @_windowskin, cursorrects[4])# top left @cursorbitmap.blt(width-margin, 0, @_windowskin, cursorrects[5]) # top right @cursorbitmap.blt(0, height-margin, @_windowskin, cursorrects[6]) # bottom right @cursorbitmap.blt(width-margin, height-margin, @_windowskin, cursorrects[7]) # bottom left rect = Rect.new(margin, 0, width - fullmargin, margin) @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[0]) rect = Rect.new(0, margin, margin, height - fullmargin) @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[1]) rect = Rect.new(width - margin, margin, margin, height - fullmargin) @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[2]) rect = Rect.new(margin, height-margin, width - fullmargin, margin) @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[3]) else @sprites["cursor"].visible=false @sprites["cursor"].src_rect.set(0,0,0,0) end end for i in 0..3 case i when 0 dwidth=@width-startX-endX dheight=startY when 1 dwidth=startX dheight=@height-startY-endY when 2 dwidth=endX dheight=@height-startY-endY when 3 dwidth=@width-startX-endX dheight=endY end @sidebitmaps[i]=ensureBitmap(@sidebitmaps[i],dwidth,dheight) @sprites["side#{i}"].bitmap=@sidebitmaps[i] @sprites["side#{i}"].src_rect.set(0,0,dwidth,dheight) @sidebitmaps[i].clear if sideRects[i].width>0 && sideRects[i].height>0 if @compat && @skinformat==0 # Compatibility mode @sidebitmaps[i].stretch_blt(@sprites["side#{i}"].src_rect, @_windowskin,sideRects[i]) else tileBitmap(@sidebitmaps[i],@sprites["side#{i}"].src_rect, @_windowskin,sideRects[i]) end end end if @compat && @skinformat==0 # Compatibility mode backwidth=@width-4 backheight=@height-4 else backwidth=@width-borderX backheight=@height-borderY end if backwidth>0 && backheight>0 @backbitmap=ensureBitmap(@backbitmap,backwidth,backheight) @sprites["back"].bitmap=@backbitmap @sprites["back"].src_rect.set(0,0,backwidth,backheight) @backbitmap.clear if @stretch @backbitmap.stretch_blt(@sprites["back"].src_rect,@_windowskin,backRect) else tileBitmap(@backbitmap,@sprites["back"].src_rect,@_windowskin,backRect) end if blindsRect tileBitmap(@backbitmap,@sprites["back"].src_rect,@_windowskin,blindsRect) end else @sprites["back"].visible=false @sprites["back"].src_rect.set(0,0,0,0) end end if @openness!=255 opn=@openness/255.0 for k in @spritekeys sprite=@sprites[k] ratio=(@height<=0) ? 0 : (sprite.y-@y)*1.0/@height sprite.zoom_y=opn sprite.oy=0 sprite.y=(@y+(@height/2.0)+(@height*ratio*opn)-(@height/2*opn)).floor oldbitmap=sprite.bitmap oldsrcrect=sprite.src_rect.clone end else for k in @spritekeys sprite=@sprites[k] sprite.zoom_y=1.0 end end i=0 # Ensure Z order for k in @spritekeys sprite=@sprites[k] y=sprite.y sprite.y=i sprite.oy=(sprite.zoom_y<=0) ? 0 : (i-y)/sprite.zoom_y end end end class SpriteWindow_Base < SpriteWindow TEXTPADDING=4 # In pixels def initialize(x, y, width, height) super() self.x = x self.y = y self.width = width self.height = height self.z = 100 @curframe=pbGetSystemFrame @curfont=pbGetSystemFont @sysframe=BitmapCache.load_bitmap($TextFrames[pbGetSystemFrame]) @customskin=nil __setWindowskin(@sysframe) end def __setWindowskin(skin) if skin && (skin.width==192 && skin.height==128) || # RPGXP Windowskin (skin.width==128 && skin.height==128) # RPGVX Windowskin self.skinformat=0 else self.skinformat=1 end self.windowskin=skin end def setSkin(skin) @customskin.dispose if @customskin @customskin=BitmapCache.load_bitmap(skin) __setWindowskin(@customskin) end def setSystemFrame @customskin.dispose if @customskin __setWindowskin(@sysframe) end def update super if @curframe!=pbGetSystemFrame @curframe=pbGetSystemFrame if @sysframe && !@customskin @sysframe.dispose if @sysframe @sysframe=BitmapCache.load_bitmap($TextFrames[pbGetSystemFrame]) __setWindowskin(@sysframe) end begin refresh rescue NoMethodError end end if @curfont!=pbGetSystemFont @curfont=pbGetSystemFont if self.contents && !self.contents.disposed? pbSetSystemFont(self.contents) end begin refresh rescue NoMethodError end end end def dispose self.contents.dispose if self.contents @sysframe.dispose @customskin.dispose if @customskin super end end class SpriteWindow_Selectable < SpriteWindow_Base attr_reader :index def initialize(x, y, width, height) super(x, y, width, height) @item_max = 1 @column_max = 1 @virtualOy=0 @index = -1 end def index=(index) if @index!=index @index = index update_cursor_rect end end def count return @item_max end def row_max return ((@item_max + @column_max - 1) / @column_max).to_i end def top_row return (@virtualOy / 32).to_i end def update_cursor_rect priv_update_cursor_rect end def top_row=(row) if row > row_max - 1 row = row_max - 1 end if row < 0 # NOTE: The two comparison checks must be reversed since row_max can be 0 row = 0 end @virtualOy = row * 32 end def page_row_max return priv_page_row_max.to_i end def page_item_max return priv_page_item_max.to_i end def itemRect(item) if item<0 || item>=@item_max return Rect.new(0,0,0,0) else cursor_width = (self.width-self.borderX) / @column_max x = self.index % @column_max * (cursor_width + 32) y = self.index / @column_max * 32 - @virtualOy return Rect.new(x, y, cursor_width, 32) end end def update super if self.active and @item_max > 0 and @index >= 0 if Input.repeat?(Input::DOWN) if (@column_max == 1 and Input.trigger?(Input::DOWN)) or @index < @item_max - @column_max Audio.se_play(pbGetDecisionSE) @index = (@index + @column_max) % @item_max update_cursor_rect end end if Input.repeat?(Input::UP) if (@column_max == 1 and Input.trigger?(Input::UP)) or @index >= @column_max Audio.se_play(pbGetDecisionSE) @index = (@index - @column_max + @item_max) % @item_max update_cursor_rect end end if Input.repeat?(Input::RIGHT) if @column_max >= 2 and @index < @item_max - 1 Audio.se_play(pbGetDecisionSE) @index += 1 update_cursor_rect end end if Input.repeat?(Input::LEFT) if @column_max >= 2 and @index > 0 Audio.se_play(pbGetDecisionSE) @index -= 1 update_cursor_rect end end if Input.repeat?(Input::R) if self.top_row + (self.page_row_max - 1) < (self.row_max - 1) Audio.se_play(pbGetDecisionSE) @index = [self.index + self.page_item_max, @item_max - 1].min self.top_row += self.page_row_max update_cursor_rect end end if Input.repeat?(Input::L) if self.top_row > 0 Audio.se_play(pbGetDecisionSE) @index = [self.index - self.page_item_max, 0].max self.top_row -= self.page_row_max update_cursor_rect end end end end private def priv_page_row_max return (self.height - self.borderX) / 32 end def priv_page_item_max return (self.height - self.borderX) / 32 * @column_max end def priv_update_cursor_rect if @index < 0 # self.cursor_rect.empty self.refresh return end row = @index / @column_max if row < self.top_row self.top_row = row dorefresh=true end if row > self.top_row + (self.page_row_max - 1) self.top_row = row - (self.page_row_max - 1) dorefresh=true end cursor_width = (self.width-self.borderX) / @column_max x = self.index % @column_max * (cursor_width + 32) y = self.index / @column_max * 32 - @virtualOy # self.cursor_rect.set(x, y, cursor_width, 32) self.refresh if dorefresh end end class Window_CommandPokemon < SpriteWindow_Selectable attr_reader :baseColor attr_reader :shadowColor attr_reader :commands def getAutoDims(commands,dims,width=nil) windowheight=commands.length*32 windowheight=1 if windowheight<1 windowheight=Graphics.height-32 if windowheight>Graphics.height-32 windowheight+=self.borderY if !width || width<0 width=0 tmpbitmap=Bitmap.new(1,1) pbSetSystemFont(tmpbitmap) for i in commands width=[width,tmpbitmap.text_size(i).width].max end width+=64 tmpbitmap.dispose else width=[33,width].max end dims[0]=width dims[1]=windowheight end def initialize(commands,width=nil) @starting=true @commands=commands dims=[] getAutoDims(commands,dims,width) super(0,0,dims[0],dims[1]) @item_max=commands.length @selarrow=BitmapCache.load_bitmap("Graphics/Pictures/selarrow.png") self.active=true colors=getDefaultTextColors(self.windowskin) @baseColor=colors[0] @shadowColor=colors[1] self.index=0 refresh @starting=false end def self.newWithSize(commands,x,y,width,height,viewport=nil) ret=self.new(commands,width) ret.x=x ret.y=y ret.width=width ret.height=height ret.viewport=viewport return ret end def self.newEmpty(x,y,width,height,viewport=nil) ret=self.new([],width) ret.x=x ret.y=y ret.width=width ret.height=height ret.viewport=viewport return ret end def index=(value) super refresh if !@starting end def commands=(value) @commands=value @item_max=commands.length self.update_cursor_rect self.refresh end def width=(value) super if !@starting self.index=self.index self.update_cursor_rect end end def height=(value) super if !@starting self.index=self.index self.update_cursor_rect end end def resizeToFit(commands) dims=[] getAutoDims(commands,dims) self.width=dims[0] self.height=dims[1] end def dispose @selarrow.dispose super end def baseColor=(value) @baseColor=value refresh end def shadowColor=(value) @shadowColor=value refresh end def refresh dwidth=self.width-self.borderX dheight=self.height-self.borderY self.contents=pbDoEnsureBitmap(self.contents,dwidth,dheight) if @starting pbSetSystemFont(self.contents) end self.contents.clear contentsWidth=self.contents.width ypos=0 firstcmd=self.top_row lastcmd=[self.top_row+self.page_row_max,@commands.length].min for i in firstcmd...lastcmd if i<self.top_row || i>self.top_row+self.page_row_max next end self.contents.blt(0,ypos,@selarrow,@selarrow.rect) if self.index==i self.contents.font.color=self.shadowColor pbDrawShadow(self.contents,16,ypos,contentsWidth,32,@commands[i]) self.contents.font.color=self.baseColor self.contents.draw_text(16,ypos,contentsWidth,32,@commands[i]) ypos+=32 end end def update oldindex=self.index super refresh if self.index!=oldindex end end class Window_AdvancedCommandPokemon < SpriteWindow_Selectable attr_reader :baseColor attr_reader :shadowColor attr_reader :commands def textWidth(bitmap,text) dims=[nil,0] chars=getFormattedText(bitmap,0,0,Graphics.width,-1,text,32,true,true) for ch in chars dims[0]=dims[0] ? [dims[0],ch[1]].min : ch[1] dims[1]=[dims[1],ch[1]+ch[3]].max end dims[0]=0 if !dims[0] return dims[1]-dims[0] end def getAutoDims(commands,dims,width=nil) windowheight=commands.length*32 windowheight=1 if windowheight<1 windowheight=Graphics.height-32 if windowheight>Graphics.height-32 windowheight+=self.borderY if !width || width<0 width=0 tmpbitmap=Bitmap.new(1,1) pbSetSystemFont(tmpbitmap) for i in commands width=[width,textWidth(tmpbitmap,i)].max end width+=64 tmpbitmap.dispose else width=[33,width].max end dims[0]=width dims[1]=windowheight end def initialize(commands,width=nil) @starting=true @commands=commands dims=[] getAutoDims(commands,dims,width) super(0,0,dims[0],dims[1]) @item_max=commands.length @selarrow=BitmapCache.load_bitmap("Graphics/Pictures/selarrow.png") self.active=true colors=getDefaultTextColors(self.windowskin) @baseColor=colors[0] @shadowColor=colors[1] self.index=0 refresh @starting=false end def self.newEmpty(x,y,width,height,viewport=nil) ret=self.new([],width) ret.x=x ret.y=y ret.width=width ret.height=height ret.viewport=viewport return ret end def index=(value) super refresh if !@starting end def commands=(value) @commands=value @item_max=commands.length self.update_cursor_rect self.refresh end def width=(value) oldvalue=self.width super if !@starting && oldvalue!=value self.index=self.index self.update_cursor_rect end end def height=(value) oldvalue=self.height super if !@starting && oldvalue!=value self.index=self.index self.update_cursor_rect end end def resizeToFit(text,maxwidth=-1) dims=resizeToFitInternal(text,maxwidth) self.width=dims[0]+self.borderX+SpriteWindow_Base::TEXTPADDING self.height=dims[1]+self.borderY end def resizeToFit(commands) dims=[] getAutoDims(commands,dims) self.width=dims[0] self.height=dims[1] end def dispose @selarrow.dispose super end def baseColor=(value) @baseColor=value refresh end def shadowColor=(value) @shadowColor=value refresh end def refresh dwidth=self.width-self.borderX dheight=self.height-self.borderY self.contents=pbDoEnsureBitmap(self.contents,dwidth,dheight) self.contents.clear contentsWidth=self.contents.width ypos=0 firstcmd=self.top_row lastcmd=[self.top_row+self.page_row_max,@commands.length].min preamble=shadowctag(@baseColor,@shadowColor) for i in firstcmd...lastcmd if i<self.top_row || i>self.top_row+self.page_row_max next end self.contents.blt(0,ypos,@selarrow,@selarrow.rect) if self.index==i chars=getFormattedText( self.contents,16,ypos,contentsWidth,32,preamble+@commands[i],32,true,true) drawFormattedChars(self.contents,chars) ypos+=32 end end def update oldindex=self.index super refresh if self.index!=oldindex end end # Represents a single-line scrolling window. class Window_SingleLineScroll < SpriteWindow_Base attr_reader :text attr_reader :baseColor attr_reader :shadowColor # Letter-by-letter mode. This mode is not supported # in this class. attr_accessor :letterbyletter def text=(value) oldDisplay=@displaytext @text=value @displaytext=value.gsub(/\\n/," ").gsub(/[\\r\\0\\1]/,"") if oldDisplay!=@displaytext @frame=0 self.ox=0 end refresh end def baseColor=(value) @baseColor=value refresh end def shadowColor=(value) @shadowColor=value refresh end def initialize(text) super(0,0,33,33) self.contents=Bitmap.new(1,1) pbSetSystemFont(self.contents) @text=text @displaytext=text.gsub(/\\n/," ").gsub(/[\\r\\0\\1]/,"") @letterbyletter=false # Not supported in this class colors=getDefaultTextColors(self.windowskin) @baseColor=colors[0] @shadowColor=colors[1] @frame=0 @textwidth=0 resizeToFit(text) end def self.newWithSize(text,x,y,width,height,viewport=nil) ret=self.new(text) ret.x=x ret.y=y ret.width=width ret.height=height ret.viewport=viewport ret.refresh return ret end def resizeToFitInternal(text,maxwidth) # maxwidth is maximum acceptable window width dims=[0,0] cwidth=maxwidth<0 ? Graphics.width : maxwidth displaytext=text.gsub(/\\n/," ").gsub(/[\\r\\0\\1]/,"") getLineBrokenChunks(self.contents,text,cwidth-self.borderX-SpriteWindow_Base::TEXTPADDING,dims,true) return dims end def resizeToFit(text,maxwidth=-1) # maxwidth is maximum acceptable window width displaytext=text.gsub(/\\n/," ").gsub(/[\\r\\0\\1]/,"") dims=resizeToFitInternal(text,maxwidth) self.width=dims[0]+self.borderX+SpriteWindow_Base::TEXTPADDING self.height=dims[1]+self.borderY refresh end def resizeHeightToFit(text,width=-1) displaytext=text.gsub(/\\n/," ").gsub(/[\\r\\0\\1]/,"") dims=resizeToFitInternal(text,width) self.width=width<0 ? Graphics.width : width self.height=dims[1]+self.borderY refresh end def refresh dims=[0,0] getLineBrokenChunks(self.contents,@displaytext,0x7FFFFFFF,dims,true) @textwidth=dims[0]+SpriteWindow_Base::TEXTPADDING self.contents=pbDoEnsureBitmap(self.contents,@textwidth,32) self.contents.clear drawTextEx(self.contents,0,0,self.contents.width-SpriteWindow_Base::TEXTPADDING,0, @displaytext,@baseColor,@shadowColor) end def update super if @frame<60 @frame+=1 elsif self.width-self.borderX < @textwidth self.ox+=2 if self.ox>=@textwidth+8 self.ox=0 @frame=0 end end end end # Represents a window with no formatting capabilities. Its # text color can be set, though, and line breaks are supported, # but the text is generally unformatted. class Window_UnformattedTextPokemon < SpriteWindow_Base attr_reader :text attr_reader :baseColor attr_reader :shadowColor # Letter-by-letter mode. This mode is not supported # in this class. attr_accessor :letterbyletter def text=(value) @text=value refresh end def baseColor=(value) @baseColor=value refresh end def shadowColor=(value) @shadowColor=value refresh end def initialize(text) super(0,0,33,33) self.contents=Bitmap.new(1,1) pbSetSystemFont(self.contents) @text=text @letterbyletter=false # Not supported in this class colors=getDefaultTextColors(self.windowskin) @baseColor=colors[0] @shadowColor=colors[1] resizeToFit(text) end def self.newWithSize(text,x,y,width,height,viewport=nil) ret=self.new(text) ret.x=x ret.y=y ret.width=width ret.height=height ret.viewport=viewport ret.refresh return ret end def resizeToFitInternal(text,maxwidth) # maxwidth is maximum acceptable window width dims=[0,0] cwidth=maxwidth<0 ? Graphics.width : maxwidth getLineBrokenChunks(self.contents,text,cwidth-self.borderX-SpriteWindow_Base::TEXTPADDING,dims,true) return dims end def resizeToFit(text,maxwidth=-1) # maxwidth is maximum acceptable window width dims=resizeToFitInternal(text,maxwidth) self.width=dims[0]+self.borderX+SpriteWindow_Base::TEXTPADDING self.height=dims[1]+self.borderY refresh end def resizeHeightToFit(text,width=-1) # width is current window width dims=resizeToFitInternal(text,width) self.width=width<0 ? Graphics.width : width self.height=dims[1]+self.borderY refresh end def refresh self.contents=pbDoEnsureBitmap(self.contents,self.width-self.borderX,self.height-self.borderY) self.contents.clear drawTextEx(self.contents,0,0,self.contents.width,0, @text.gsub(/\\r/,""),@baseColor,@shadowColor) end end class Window_AdvancedTextPokemon < SpriteWindow_Base attr_reader :text attr_reader :baseColor attr_reader :shadowColor attr_accessor :letterbyletter def text=(value) setText(value) end def textspeed @frameskip end def textspeed=(value) @frameskip=value end def setText(value) @curchar=0 @drawncurchar=-1 @lastDrawnChar=-1 oldtext=@text @text=value @textlength=unformattedTextLength(value) @scrollstate=0 @scrollY=0 @linesdrawn=0 @realframes=0 @textchars=[] width=1 height=1 numlines=0 visiblelines=(self.height-self.borderY)/32 if value.length==0 @fmtchars=[] @bitmapwidth=width @bitmapheight=height @numtextchars=0 else if !@letterbyletter @fmtchars=getFormattedText(self.contents,0,0, self.width-self.borderX-SpriteWindow_Base::TEXTPADDING,-1, shadowctag(@baseColor,@shadowColor)+value,32,true) for ch in @fmtchars chx=ch[1]+ch[3] chy=ch[2]+ch[4] width=chx if width<chx height=chy if height<chy @textchars.push(ch[5] ? "" : ch[0]) end else @fmtchars=[] fmt=getFormattedText(self.contents,0,0, self.width-self.borderX-SpriteWindow_Base::TEXTPADDING,-1, shadowctag(@baseColor,@shadowColor)+value,32,true) for ch in fmt chx=ch[1]+ch[3] chy=ch[2]+ch[4] width=chx if width<chx height=chy if height<chy if !ch[5] && ch[0]=="\\n" && @letterbyletter numlines+=1 if numlines>=visiblelines fclone=ch.clone fclone[0]="\\1" @fmtchars.push(fclone) @textchars.push("\\1") end end # Don't add newline characters, since they # can slow down letter-by-letter display if ch[5] || (ch[0]!="\\r") @fmtchars.push(ch) @textchars.push(ch[5] ? "" : ch[0]) end end fmt.clear end @bitmapwidth=width @bitmapheight=height @numtextchars=@textchars.length end stopPause @displaying=@letterbyletter @needclear=true @nodraw=@letterbyletter refresh end def baseColor=(value) @baseColor=value refresh end def shadowColor=(value) @shadowColor=value refresh end def busy? return @displaying end def pausing? return @pausing && @displaying end def resume if !busy? self.stopPause return true end if @pausing @pausing=false self.stopPause return false else return true end end def dispose return if disposed? @pausesprite.dispose if @pausesprite @pausesprite=nil super end attr_reader :cursorMode def cursorMode=(value) @cursorMode=value moveCursor end def moveCursor if @pausesprite cursor=@cursorMode cursor=2 if cursor==0 && !@endOfText case cursor when 0 # End of text @pausesprite.x=self.x+self.startX+@endOfText.x+@endOfText.width-2 @pausesprite.y=self.y+self.startY+@endOfText.y-@scrollY when 1 # Lower right pauseWidth=@pausesprite.bitmap ? @pausesprite.framewidth : 16 pauseHeight=@pausesprite.bitmap ? @pausesprite.frameheight : 16 @pausesprite.x=self.x+self.width-(20*2)+(pauseWidth/2) @pausesprite.y=self.y+self.height-(28*2)+(pauseHeight/2) when 2 # Lower middle pauseWidth=@pausesprite.bitmap ? @pausesprite.framewidth : 16 pauseHeight=@pausesprite.bitmap ? @pausesprite.frameheight : 16 @pausesprite.x=self.x+(self.width/2)-(pauseWidth/2) @pausesprite.y=self.y+self.height-(18*2)+(pauseHeight/2) end end end def initialize(text) @cursorMode=CURSORMODE @endOfText=nil @scrollstate=0 @realframes=0 @scrollY=0 @nodraw=false @linesdrawn=0 @bufferbitmap=nil @letterbyletter=false @starting=true @displaying=false @lastDrawnChar=-1 @fmtchars=[] @frameskip=[3,2,1,-2][pbGetSystemTextSpeed] super(0,0,33,33) @pausesprite=nil @text="" self.contents=Bitmap.new(1,1) pbSetSystemFont(self.contents) self.resizeToFit(text,Graphics.width) colors=getDefaultTextColors(self.windowskin) @baseColor=colors[0] @shadowColor=colors[1] self.text=text @starting=false end def self.newWithSize(text,x,y,width,height,viewport=nil) ret=self.new(text) ret.x=x ret.y=y ret.width=width ret.height=height ret.viewport=viewport return ret end def width=(value) super if !@starting self.text=self.text end end def height=(value) super if !@starting self.text=self.text end end def resizeToFitInternal(text,maxwidth) dims=[0,0] cwidth=maxwidth<0 ? Graphics.width : maxwidth chars=getFormattedTextForDims( self.contents,0,0,cwidth-self.borderX-2-6,-1,text,32,true) for ch in chars dims[0]=[dims[0],ch[1]+ch[3]].max dims[1]=[dims[1],ch[2]+ch[4]].max end return dims end def resizeToFit2(text,maxwidth,maxheight) dims=resizeToFitInternal(text,maxwidth) oldstarting=@starting @starting=true self.width=[dims[0]+self.borderX+SpriteWindow_Base::TEXTPADDING,maxwidth].min self.height=[dims[1]+self.borderY,maxheight].min @starting=oldstarting self.text=self.text end def resizeToFit(text,maxwidth=-1) dims=resizeToFitInternal(text,maxwidth) oldstarting=@starting @starting=true self.width=dims[0]+self.borderX+SpriteWindow_Base::TEXTPADDING self.height=dims[1]+self.borderY @starting=oldstarting self.text=self.text end def resizeHeightToFit(text,width=-1) dims=resizeToFitInternal(text,width) oldstarting=@starting @starting=true self.width=width<0 ? Graphics.width : width self.height=dims[1]+self.borderY @starting=oldstarting self.text=self.text end def refresh oldcontents=self.contents self.contents=pbDoEnsureBitmap(oldcontents,@bitmapwidth,@bitmapheight) self.oy=@scrollY numchars=@numtextchars startchar=0 numchars=[@curchar,@numtextchars].min if self.letterbyletter if busy? && @drawncurchar==@curchar && @scrollstate==0 return end if !self.letterbyletter || !oldcontents.equal?(self.contents) @drawncurchar=-1 @needclear=true end if @needclear self.contents.clear @needclear=false end if @nodraw @nodraw=false return end maxX=self.width-self.borderX maxY=self.height-self.borderY for i in @drawncurchar+1..numchars next if i>=@fmtchars.length if !self.letterbyletter next if @fmtchars[i][1]>=maxX next if @fmtchars[i][2]>=maxY end drawSingleFormattedChar(self.contents,@fmtchars[i]) @lastDrawnChar=i end if numchars>0 && numchars!=@numtextchars && @textchars[numchars]=="\\1" fch=@fmtchars[numchars-1] if fch rcdst=Rect.new(fch[1],fch[2],fch[3],fch[4]) @endOfText=rcdst allocPause moveCursor() end end @drawncurchar=@curchar end def maxPosition pos=0 for ch in @fmtchars # index after the last character's index pos=ch[14]+1 if pos<ch[14]+1 end return pos end def position if @lastDrawnChar<0 return 0 elsif @lastDrawnChar>=@fmtchars.length return @numtextchars else # index after the last character's index return @fmtchars[@lastDrawnChar][14]+1 end end def update super if @pausesprite && @pausesprite.visible @pausesprite.update end if busy? refresh curcharskip=@frameskip<0 ? @frameskip.abs : 1 visiblelines=(self.height-self.borderY)/32 if @textchars[@curchar]=="\\1" if !@pausing @realframes+=1 if @realframes>=@frameskip || @frameskip<0 curcharSkip(curcharskip) @realframes=0 end end elsif @textchars[@curchar]=="\\n" if @linesdrawn>=visiblelines-1 if @scrollstate<32 @scrollstate+=8 @scrollY+=8 end if @scrollstate>=32 @realframes+=1 if @realframes>=@frameskip || @frameskip<0 curcharSkip(curcharskip) @linesdrawn+=1 @scrollstate=0 @realframes=0 end end else @realframes+=1 if @realframes>=@frameskip || @frameskip<0 curcharSkip(curcharskip) @linesdrawn+=1 @realframes=0 end end elsif @curchar<=@numtextchars @realframes+=1 if @realframes>=@frameskip || @frameskip<0 curcharSkip(curcharskip) @realframes=0 end if @textchars[@curchar]=="\\1" @pausing=true if @curchar<@numtextchars-1 self.startPause refresh end else @displaying=false @scrollstate=0 @scrollY=0 @linesdrawn=0 end end end def allocPause if !@pausesprite @pausesprite=AnimatedSprite.create("Graphics/Pictures/pause.png",4,3) @pausesprite.z=100000 @pausesprite.visible=false end end def startPause allocPause @pausesprite.visible=true @pausesprite.frame=0 @pausesprite.start end def stopPause if @pausesprite @pausesprite.stop @pausesprite.visible=false end end private def curcharSkip(skip) skip.times do @curchar+=1 break if @textchars[@curchar]=="\\n" || # newline @textchars[@curchar]=="\\1" || # pause @textchars[@curchar]=="\\2" || # letter-by-letter break @textchars[@curchar]==nil end end end class Window_InputNumberPokemon < SpriteWindow_Base attr_reader :number attr_reader :sign def initialize(digits_max) @digits_max=digits_max @number=0 @sign=false @negative=false super(0,0,digits_max*24+40,64) colors=getDefaultTextColors(self.windowskin) @baseColor=colors[0] @shadowColor=colors[1] @selarrow=BitmapCache.load_bitmap("Graphics/Pictures/selarrow.png") @index=digits_max-1 refresh end def number @number*(@sign && @negative ? -1 : 1) end def sign=(value) @sign=value self.width=@digits_max*24+40+(@sign ? 24 : 0) @index=(@digits_max-1)+(@sign ? 1 : 0) refresh end def dispose @selarrow.dispose super end def number=(value) value=0 if !value.is_a?(Numeric) if @sign @number = [value, 10 ** @digits_max - 1].min else @number = [[value, 0].max, 10 ** @digits_max - 1].min end refresh end def refresh self.contents=pbDoEnsureBitmap(self.contents,self.width-32,self.height-32) pbSetSystemFont(self.contents) self.contents.clear s=sprintf("%0*d",@digits_max,@number.abs) x=0 if @sign textHelper(0,0,@negative ? "-" : "+",0) end for i in 0...@digits_max index=i+(@sign ? 1 : 0) textHelper(index*24,0,s[i,1],index) end end def update super digits=@digits_max+(@sign ? 1 : 0) if Input.repeat?(Input::UP) or Input.repeat?(Input::DOWN) Audio.se_play(pbGetDecisionSE) if @index==0 && @sign @negative=!@negative else place = 10 ** (digits - 1 - @index) n = @number / place % 10 @number -= n*place if Input.repeat?(Input::UP) n = (n + 1) % 10 elsif Input.repeat?(Input::DOWN) n = (n + 9) % 10 end @number += n*place end refresh elsif Input.repeat?(Input::RIGHT) if digits >= 2 Audio.se_play(pbGetDecisionSE) @index = (@index + 1) % digits refresh end elsif Input.repeat?(Input::LEFT) if digits >= 2 Audio.se_play(pbGetDecisionSE) @index = (@index + digits - 1) % digits refresh end end end private def textHelper(x,y,text,i) textwidth=self.contents.text_size(text).width self.contents.font.color=@shadowColor pbDrawShadow(self.contents,x+(12-textwidth/2),y, textwidth+4, 32, text) self.contents.font.color=@baseColor self.contents.draw_text(x+(12-textwidth/2),y, textwidth+4, 32, text) if @index==i self.contents.fill_rect(x+(12-textwidth/2),y+30,textwidth,2,Color.new(0,0,0)) end end end class AnimatedSprite < SpriteWrapper attr_reader :frame attr_reader :framewidth attr_reader :frameheight attr_reader :framecount attr_reader :animname def initializeLong(animname,framecount,framewidth,frameheight,frameskip) @animname=animname @realframes=0 @frameskip=[1,frameskip].max raise _INTL("Frame width is 0") if framewidth==0 raise _INTL("Frame height is 0") if frameheight==0 begin @animbitmap=BitmapCache.load_bitmap(animname) rescue @animbitmap=Bitmap.new(framewidth,frameheight) end if @animbitmap.width%framewidth!=0 raise _INTL("Bitmap's width ({1}) is not a multiple of frame width ({2}) [Bitmap={3}]",@animbitmap.width,framewidth,animname) end if @animbitmap.height%frameheight!=0 raise _INTL("Bitmap's height ({1}) is not a multiple of frame height ({2}) [Bitmap={3}]",@animbitmap.height,frameheight,animname) end @framecount=framecount @framewidth=framewidth @frameheight=frameheight @framesperrow=@animbitmap.width/@framewidth @playing=false self.bitmap=@animbitmap self.src_rect.width=@framewidth self.src_rect.height=@frameheight self.frame=0 end # Shorter version of AnimationSprite. All frames # are placed on a single row of the bitmap, so that # the width and height need not be defined beforehand def initializeShort(animname,framecount,frameskip) @animname=animname @realframes=0 @frameskip=[1,frameskip].max begin @animbitmap=BitmapCache.load_bitmap(animname) rescue @animbitmap=Bitmap.new(framecount*4,32) end if @animbitmap.width%framecount!=0 raise _INTL("Bitmap's width ({1}) is not a multiple of frame count ({2}) [Bitmap={3}]",@animbitmap.width,framewidth,animname) end @framecount=framecount @framewidth=@animbitmap.width/@framecount @frameheight=@animbitmap.height @framesperrow=framecount @playing=false self.bitmap=@animbitmap self.src_rect.width=@framewidth self.src_rect.height=@frameheight self.frame=0 end def initialize(*args) if args.length==1 super(args[0][3]) initializeShort(args[0][0],args[0][1],args[0][2]) else super(args[5]) initializeLong(args[0],args[1],args[2],args[3],args[4]) end end def self.create(animname,framecount,frameskip,viewport=nil) return self.new([animname,framecount,frameskip,viewport]) end def dispose return if disposed? @animbitmap.dispose @animbitmap=nil super end def playing? return @playing end def frame=(value) @frame=value @realframes=0 self.src_rect.x=@frame%@framesperrow*@framewidth self.src_rect.y=@frame/@framesperrow*@frameheight end def start @playing=true @realframes=0 end alias play start def stop @playing=false end def update super if @playing @realframes+=1 if @realframes==@frameskip @realframes=0 self.frame+=1 self.frame%=self.framecount end end end end class ColoredPlane < Plane def initialize(color,viewport=nil) super(viewport) self.bitmap=Bitmap.new(32,32) setPlaneColor(color) end def dispose self.bitmap.dispose if self.bitmap super end def update; end def setPlaneColor(value) self.bitmap.fill_rect(0,0,self.bitmap.width,self.bitmap.height,value) end end #A simple sprite class that displays an icon. class IconSprite < SpriteWrapper attr_reader :name def initialize(x,y,viewport=nil) super(viewport) self.bitmap=nil self.x=x self.y=y @name="" end def dispose self.bitmap.dispose if self.bitmap super end # Sets the icon's filename. Alias for setBitmap. def name=(value) setBitmap(value) end # Sets the icon's filename. def setBitmap(file) @name=file self.bitmap.dispose if self.bitmap if @name!="" self.bitmap=BitmapCache.load_bitmap(file) else self.bitmap=nil end end end class IconWindow < SpriteWindow_Base def initialize(x,y,width,height,viewport=nil) super(x,y,width,height) self.viewport=viewport self.contents=nil end def dispose self.contents.dispose if self.contents super end def clearBitmap self.contents.clear if self.contents && !self.contents.disposed? end def setBitmap(file) iconbitmap=(!file||file.length==0) ? Bitmap.new(32,32) : BitmapCache.load_bitmap(file) dwidth=iconbitmap.width dheight=iconbitmap.height if !self.contents || self.contents.disposed? || self.contents.height<dheight || self.contents.width<dwidth self.contents.dispose if self.contents self.contents=Bitmap.new([1,dwidth].max,[1,dheight].max) end self.contents.clear self.contents.blt(0,0,iconbitmap, Rect.new(0,0,iconbitmap.width,iconbitmap.height)) iconbitmap.dispose end end class AnimatedPlane < Plane def initialize(viewport=nil) super(viewport) @bitmap=nil end def dispose clearBitmaps() super end def update if @bitmap @bitmap.update self.bitmap=@bitmap.bitmap end end def clearBitmaps @bitmap.dispose if @bitmap @bitmap=nil self.bitmap=nil if !self.disposed? end def setPanorama(file, hue=0) clearBitmaps() return if file==nil @bitmap=AnimatedBitmap.new("Graphics/Panoramas/"+file,hue) end def setFog(file, hue=0) clearBitmaps() return if file==nil @bitmap=AnimatedBitmap.new("Graphics/Fogs/"+file,hue) end def setBitmap(file, hue=0) clearBitmaps() return if file==nil @bitmap=AnimatedBitmap.new(file,hue) end end =begin Accepts bitmaps and paths to bitmap files in its constructor =end class PictureWindow < SpriteWindow_Base def initialize(file) super(0,0,32,32) @iconbitmap=nil self.contents=nil setBitmapPriv(file) end def dispose self.contents.dispose if self.contents @iconbitmap.dispose if @iconbitmap && @disposeBitmap super end def clearBitmap self.contents.clear if self.contents && !self.contents.disposed? @iconbitmap.dispose if @iconbitmap && @disposeBitmap @iconbitmap=nil end def setBitmap(file) setBitmapPriv(file) end def setBitmapPriv(file) @iconbitmap.dispose if @iconbitmap && @disposeBitmap @disposeBitmap=!file.is_a?(Bitmap) @iconbitmap=file.is_a?(Bitmap) ? file : BitmapCache.load_bitmap(file) if !@iconbitmap self.contents.clear if self.contents && !self.contents.disposed? self.width=64 self.height=64 return end dwidth=@iconbitmap.width dheight=@iconbitmap.height if !self.contents || self.contents.disposed? || self.contents.height<dheight || self.contents.width<dwidth self.contents.dispose if self.contents self.contents=Bitmap.new([1,dwidth].max,[1,dheight].max) end self.contents.clear self.contents.blt(0,0,@iconbitmap, Rect.new(0,0,@iconbitmap.width,@iconbitmap.height)) self.width=@iconbitmap.width+32 self.height=@iconbitmap.height+32 @iconbitmap.dispose end end module UpDownArrowMixin def initUpDownArrow @uparrow=AnimatedSprite.create("Graphics/Pictures/uparrow.png",8,2,self.viewport) @downarrow=AnimatedSprite.create("Graphics/Pictures/downarrow.png",8,2,self.viewport) @uparrow.z=99998 @downarrow.z=99998 @uparrow.visible=false @downarrow.visible=false @uparrow.play @downarrow.play end def dispose @uparrow.dispose @downarrow.dispose super end def viewport=(value) super @uparrow.viewport=self.viewport @downarrow.viewport=self.viewport end def color=(value) super @uparrow.color=value @downarrow.color=value end def update super @uparrow.x=self.x+(self.width/2)-(@uparrow.framewidth/2) @downarrow.x=self.x+(self.width/2)-(@downarrow.framewidth/2) @uparrow.y=self.y @downarrow.y=self.y+self.height-@downarrow.frameheight @uparrow.visible=self.visible && self.active && (self.top_row!=0 && @item_max > self.page_item_max) @downarrow.visible=self.visible && self.active && (self.top_row+self.page_item_max<@item_max && @item_max > self.page_item_max) @uparrow.z=self.z+1 @downarrow.z=self.z+1 @uparrow.viewport=self.viewport @downarrow.viewport=self.viewport @uparrow.update @downarrow.update end end class SpriteWindow_SelectableEx < SpriteWindow_Selectable include UpDownArrowMixin def initialize(*arg) super(*arg) initUpDownArrow end end class Window_CommandPokemonEx < Window_CommandPokemon include UpDownArrowMixin def initialize(*arg) super(*arg) initUpDownArrow end end
EventScene
[
Selecionar
] [
-
]
def getCubicPoint(src,t) x0=src[0].x; y0=src[0].y; cx0=src[1].x; cy0=src[1].y; cx1=src[2].x; cy1=src[2].y; x1=src[3].x; y1=src[3].y; x1=cx1+(x1-cx1)*t; y1=cy1+(y1-cy1)*t; x0=x0+(cx0-x0)*t; y0=y0+(cy0-y0)*t; cx0=cx0+(cx1-cx0)*t; cy0=cy0+(cy1-cy0)*t; cx1=cx0+(x1-cx0)*t; cy1=cy0+(y1-cy0)*t; cx0=x0+(cx0-x0)*t; cy0=y0+(cy0-y0)*t; cx=cx0+(cx1-cx0)*t; cy=cy0+(cy1-cy0)*t; return [cx,cy] end def getCubicPoint2(src,t) x0=src[0]; y0=src[1]; cx0=src[2]; cy0=src[3]; cx1=src[4]; cy1=src[5]; x1=src[6]; y1=src[7]; x1=cx1+(x1-cx1)*t; y1=cy1+(y1-cy1)*t; x0=x0+(cx0-x0)*t; y0=y0+(cy0-y0)*t; cx0=cx0+(cx1-cx0)*t; cy0=cy0+(cy1-cy0)*t; cx1=cx0+(x1-cx0)*t; cy1=cy0+(y1-cy0)*t; cx0=x0+(cx0-x0)*t; cy0=y0+(cy0-y0)*t; cx=cx0+(cx1-cx0)*t; cy=cy0+(cy1-cy0)*t; return [cx,cy] end class PictureEx attr_reader :number # picture number attr_accessor :name # file name attr_accessor :origin # starting point attr_accessor :x # x-coordinate attr_accessor :y # y-coordinate attr_accessor :zoom_x # x directional zoom rate attr_accessor :zoom_y # y directional zoom rate attr_accessor :opacity # opacity level attr_accessor :blend_type # blend method attr_reader :tone # color tone attr_reader :color attr_accessor :angle # rotation angle attr_accessor :visible class Processes XY=0 Zoom=1 Opacity=2 BlendType=3 Tone=4 Color=5 Visible=6 SE=7 Angle=8 Origin=9 Name=10 Curve=11 end def callback(cb) if cb.is_a?(Proc) proc.call(self) elsif cb.is_a?(Array) cb[0].method(cb[1]).call(self) elsif cb.is_a?(Method) cb.call(self) end end 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 = 0 @processes=[] @tone = Tone.new(0, 0, 0, 0) @color = Color.new(0, 0, 0, 0) @tone_duration = 0 @angle = 0 @rotate_speed = 0 @bitmap=0 @visible=true end def name=(value) @name=value end def running? return @processes.length>0 end def totalDuration ret=0 for process in @processes dur=process[1]+process[2] ret=dur if dur>ret end return ret end def adjustPosition(xOffset,yOffset) for process in @processes if process[0]==Processes::XY process[3]+=xOffset process[4]+=yOffset process[5]+=xOffset process[6]+=yOffset end end end def generateCurve(duration, delay, curve, cb=nil) duration=1 if duration<=0 step=1.0/duration lastX=curve[0] lastY=curve[1] t=0.0 for i in 0..duration point=getCubicPoint2(curve,t) cbref=(i==duration) ? cb : nil @processes.push([Processes::XY,1,delay+i,lastX,lastY,point[0],point[1],cbref]) lastX=point[0] lastY=point[1] t+=step end end def moveCurve(duration, delay, x1, y1, x2, y2, x3, y3, cb=nil) delay=self.totalDuration if delay<0 if duration==0 && delay==0 @x=x3 @y=y3 callback(cb) elsif delay==0 generateCurve(duration,delay,[@x,@y,x1,y1,x2,y2,x3,y3],cb) else @processes.push([Processes::Curve,duration,delay,[@x,@y,x1,y1,x2,y2,x3,y3],cb]) end end def move(duration, delay, origin, x, y, zoom_x, zoom_y, opacity, blend_type) @duration = duration moveOrigin(duration,delay,origin) moveXY(duration,delay,x,y) moveZoomXY(duration,delay,zoom_x,zoom_y) moveOpacity(duration,delay,opacity) moveBlendType(duration,delay,blend_type) end def moveZoomXY(duration, delay, zoom_x,zoom_y,cb=nil) delay=self.totalDuration if delay<0 if duration==0 && delay==0 @zoom_x=zoom_x @zoom_y=zoom_y callback(cb) else @processes.push([Processes::Zoom,duration,delay,@zoom_x,@zoom_y,zoom_x,zoom_y,cb]) end end def moveName(delay,name,cb=nil) delay=self.totalDuration if delay<0 @processes.push([Processes::Name,0,delay,name,cb]) end def moveSE(delay,sefile,cb=nil) delay=self.totalDuration if delay<0 @processes.push([Processes::SE,0,delay,sefile,cb]) end def moveOrigin(delay,origin,cb=nil) delay=self.totalDuration if delay<0 @processes.push([Processes::Origin,0,delay,origin,cb]) end def moveZoom(duration,delay,zoom,cb=nil) moveZoomXY(duration,delay,zoom,zoom,cb) end def moveOpacity(duration,delay,opacity,cb=nil) delay=self.totalDuration if delay<0 if duration==0 && delay==0 @opacity=opacity callback(cb) else @processes.push([Processes::Opacity,duration,delay,@opacity,opacity,cb]) end end def moveDelta(duration,delay,x,y,cb=nil) delay=self.totalDuration if delay<0 if duration==0 && delay==0 @x+=x @y+=y callback(cb) else @processes.push([Processes::XY,duration,delay,@x,@y,@x+x,@y+y,cb]) end end def moveXY(duration,delay,x,y,cb=nil) delay=self.totalDuration if delay<0 if duration==0 && delay==0 @x=x @y=y callback(cb) else @processes.push([Processes::XY,duration,delay,@x,@y,x,y,cb]) end end def moveBlendType(duration,delay,blend,cb=nil) delay=self.totalDuration if delay<0 if duration==0 && delay==0 @blend_type=blend callback(cb) else @processes.push([Processes::BlendType,duration,delay,@blend_type,blend,cb]) end end def moveVisible(delay,visible,cb=nil) delay=self.totalDuration if delay<0 @processes.push([Processes::Visible,0,delay,visible,cb]) end def rotate(speed) @rotate_speed = speed end def moveAngle(duration,delay,angle,cb=nil) delay=self.totalDuration if delay<0 if duration==0 && delay==0 @angle=angle callback(cb) else @processes.push([Processes::Angle,duration,delay,@angle,angle,cb]) end end def moveTone(duration, delay,tone, cb=nil) delay=self.totalDuration if delay<0 target = tone ? tone.clone : Tone.new(0,0,0,0) if duration==0 && delay==0 @tone.set(target.red,target.green,target.blue,target.gray) else @processes.push([Processes::Tone,duration,delay,@tone.clone,target.clone,cb]) end end def moveColor(duration, delay, tone, cb=nil) delay=self.totalDuration if delay<0 target = tone ? tone.clone : Color.new(0,0,0,0) if duration==0 && delay==0 @color.set(target.red,target.green,target.blue,target.alpha) else @processes.push([Processes::Color,duration,delay,@color.clone,target.clone,cb]) end end def erase self.name = "" end def update i=0;while i<@processes.length process=@processes[i] d=process[1] cb=nil # decrease delay if process[2]>0 process[2]-=1 if process[2]<=0 # set initial values case process[0] when Processes::XY process[3]=@x process[4]=@y when Processes::Zoom process[3]=@zoom_x process[4]=@zoom_y when Processes::Opacity process[3]=@opacity when Processes::BlendType process[3]=@blend_type when Processes::Tone process[3]=@tone.clone when Processes::Color process[3]=@color.clone when Processes::Angle process[3]=@angle when Processes::Curve process[3][0]=@x process[3][1]=@y generateCurve(process[1],0,process[3],process[4]) @processes[i]=nil i+=1 next end else i+=1 next end end if process[1]<1 process[1]=1 d=1 end case process[0] when Processes::XY process[3] = (process[3] * (d - 1) + process[5]) / d process[4] = (process[4] * (d - 1) + process[6]) / d @x=process[3] @y=process[4] cb=process[7] when Processes::Zoom process[3] = (process[3] * (d - 1) + process[5]) / d process[4] = (process[4] * (d - 1) + process[6]) / d @zoom_x=process[3] @zoom_y=process[4] cb=process[7] when Processes::Opacity process[3] = (process[3] * (d - 1) + process[4]) / d @opacity=process[3] cb=process[5] when Processes::BlendType process[3] = (process[3] * (d - 1) + process[4]) / d @blend_type=process[3] cb=process[5] when Processes::Tone process[3].red = (process[3].red * (d - 1) + process[4].red) / d process[3].green = (process[3].green * (d - 1) + process[4].green) / d process[3].blue = (process[3].blue * (d - 1) + process[4].blue) / d process[3].gray = (process[3].gray * (d - 1) + process[4].gray) / d @tone.set(process[3].red,process[3].green,process[3].blue,process[3].gray) cb=process[5] when Processes::Color process[3].red = (process[3].red * (d - 1) + process[4].red) / d process[3].green = (process[3].green * (d - 1) + process[4].green) / d process[3].blue = (process[3].blue * (d - 1) + process[4].blue) / d process[3].alpha = (process[3].alpha * (d - 1) + process[4].alpha) / d @color.set(process[3].red,process[3].green,process[3].blue,process[3].alpha) cb=process[5] when Processes::Visible @visible=process[3] if process[1]==1 cb=process[4] when Processes::SE Audio.se_play(process[3]) if process[1]==1 cb=process[4] when Processes::Name @name=process[3] if process[1]==1 cb=process[4] when Processes::Origin @origin=process[3] if process[1]==1 cb=process[4] when Processes::Angle process[3] = (process[3] * (d - 1) + process[4]) / d @angle=process[3] cb=process[5] end # decrease duration process[1]-=1 if process[1]<=0 callback(cb) if cb @processes[i]=nil end i+=1 end @processes.compact! if @rotate_speed != 0 @angle += @rotate_speed / 2.0 while @angle < 0 @angle += 360 end @angle %= 360 end end end def setPictureIconSprite(sprite,picture) if sprite.name != picture.name sprite.name = picture.name end setPictureSprite(sprite,picture) end def setPictureSprite(sprite,picture) sprite.visible = picture.visible # Set transfer starting point case picture.origin when PictureOrigin::TopLeft, PictureOrigin::Top, PictureOrigin::TopRight sprite.oy=0 when PictureOrigin::Left, PictureOrigin::Center, PictureOrigin::Right sprite.oy=(sprite.bitmap && !sprite.bitmap.disposed?) ? sprite.bitmap.height/2 : 0 when PictureOrigin::BottomLeft, PictureOrigin::Bottom, PictureOrigin::BottomRight sprite.oy=(sprite.bitmap && !sprite.bitmap.disposed?) ? sprite.bitmap.height : 0 end case picture.origin when PictureOrigin::TopLeft, PictureOrigin::Left, PictureOrigin::BottomLeft sprite.ox=0 when PictureOrigin::Top, PictureOrigin::Center, PictureOrigin::Bottom sprite.ox=(sprite.bitmap && !sprite.bitmap.disposed?) ? sprite.bitmap.width/2 : 0 when PictureOrigin::TopRight, PictureOrigin::Right, PictureOrigin::BottomRight sprite.ox=(sprite.bitmap && !sprite.bitmap.disposed?) ? sprite.bitmap.width : 0 end # Set sprite coordinates sprite.x = picture.x sprite.y = picture.y sprite.z = picture.number # Set zoom rate, opacity level, and blend method sprite.zoom_x = picture.zoom_x / 100.0 sprite.zoom_y = picture.zoom_y / 100.0 sprite.opacity = picture.opacity sprite.blend_type = picture.blend_type # Set rotation angle and color tone angle = picture.angle sprite.tone = picture.tone sprite.color = picture.color while angle < 0 angle += 360 end angle %= 360 sprite.angle=angle end class PictureOrigin TopLeft=0 Center=1 TopRight=2 BottomLeft=3 LowerLeft=3 BottomRight=4 LowerRight=4 Top=5 Bottom=6 Left=7 Right=8 end def pbTextBitmap(text,maxwidth=480) dims=[] tmp=Bitmap.new(maxwidth,Graphics.height) pbSetSystemFont(tmp) drawColoredTextEx(tmp,0,0,maxwidth,text) return tmp end class PictureSprite < SpriteWrapper def initialize(viewport, picture) super(viewport) @picture = picture @pictureBitmap = nil @customBitmap = nil update end def setCustomBitmap(bitmap) @customBitmap.dispose if @customBitmap @customBitmap=bitmap end def dispose @pictureBitmap.dispose if @pictureBitmap @customBitmap.dispose if @customBitmap super end def update super # If picture file name is different from current one if @customBitmap && @picture.name=="" self.bitmap=@customBitmap elsif @picture_name != @picture.name # Remember file name to instance variables @picture_name = @picture.name # If file name is not empty if @picture_name != "" # Get picture graphic @pictureBitmap.dispose if self.bitmap @pictureBitmap = BitmapCache.load_bitmap(@picture_name) else @pictureBitmap.dispose if self.bitmap @pictureBitmap=nil self.visible = false return end self.bitmap=@pictureBitmap elsif @picture_name == "" # Set sprite to invisible self.visible = false return end # Set sprite to visible self.visible = true # Set transfer starting point case @picture.origin when PictureOrigin::TopLeft, PictureOrigin::Top, PictureOrigin::TopRight self.oy=0 when PictureOrigin::Left, PictureOrigin::Center, PictureOrigin::Right self.oy=self.bitmap.height/2 when PictureOrigin::BottomLeft, PictureOrigin::Bottom, PictureOrigin::BottomRight self.oy=self.bitmap.height end case @picture.origin when PictureOrigin::TopLeft, PictureOrigin::Left, PictureOrigin::BottomLeft self.ox=0 when PictureOrigin::Top, PictureOrigin::Center, PictureOrigin::Bottom self.ox=self.bitmap.width/2 when PictureOrigin::TopRight, PictureOrigin::Right, PictureOrigin::BottomRight self.ox=self.bitmap.width end # Set sprite coordinates self.x = @picture.x self.y = @picture.y self.z = @picture.number # Set zoom rate, opacity level, and blend method self.zoom_x = @picture.zoom_x / 100.0 self.zoom_y = @picture.zoom_y / 100.0 self.opacity = @picture.opacity self.blend_type = @picture.blend_type # Set rotation angle and color tone angle = @picture.angle self.tone = @picture.tone while angle < 0 angle += 360 end angle %= 360 if @picture.angle!=0 echo([angle,@picture.angle]+"\\r\\n") end self.angle=angle end end # Defines an event that procedures can subscribe # to. class Event def initialize @callbacks=[] end # Sets an event handler for this event and removes # all other event handlers. def set(method) @callbacks.clear @callbacks.push(method) end # Removes an event handler procedure from # the event. def -(method) for i in 0...@callbacks.length if @callbacks[i]==method @callbacks.delete_at(i) break end end return self end # Adds an event handler procedure from # the event. def +(method) for i in 0...@callbacks.length if @callbacks[i]==method return self end end @callbacks.push(method) return self end # Clears the event of event handlers. def clear @callbacks.clear end # Triggers the event and calls all its event # handlers. Normally called only # by the code where the event occurred. # The first argument is the sender of the event, # the second argument contains the event's parameters. def trigger(*arg) arglist=arg[1,arg.length] for callback in @callbacks callback.call(arg[0],arglist) end end end class EventScene attr_accessor :onCTrigger,:onBTrigger def initialize(viewport=nil) @viewport=viewport @onCTrigger=Event.new @onBTrigger=Event.new @pictures=[] @picturesprites=[] @usersprites=[] @disposed=false end def main while !disposed? update end end def disposed? return @disposed end def dispose return if disposed? for sprite in @picturesprites sprite.dispose end for sprite in @usersprites sprite.dispose end @onCTrigger.clear @onBTrigger.clear @pictures.clear @picturesprites.clear @usersprites.clear @disposed=true end def addBitmap(x,y,bitmap) num=@pictures.length picture=PictureEx.new(num) picture.moveXY(0,0,x,y) @pictures[num]=picture @picturesprites[num]=PictureSprite.new(@viewport,picture) @picturesprites[num].setCustomBitmap(bitmap) return picture end def addLabel(x,y,width,text) addBitmap(x,y,pbTextBitmap(text,width)) end def addImage(x,y,name) num=@pictures.length picture=PictureEx.new(num) picture.name=name picture.moveXY(0,0,x,y) @pictures[num]=picture @picturesprites[num]=PictureSprite.new(@viewport,picture) return picture end def getPicture(num) return @pictures[num] end def wait(frames) frames.times { update } end def pictureWait(extraframes=0) loop do hasRunning=false for pic in @pictures hasRunning=true if pic.running? end if hasRunning update else break end end extraframes.times { update } end def addUserSprite(sprite) @usersprites.push(sprite) end def update return if disposed? Graphics.update Input.update for picture in @pictures picture.update end for sprite in @picturesprites sprite.update end for sprite in @usersprites if sprite && !sprite.disposed? sprite.update if sprite.is_a?(Sprite) end end if Input.trigger?(Input::C) @onCTrigger.trigger(self) end if Input.trigger?(Input::B) @onBTrigger.trigger(self) end end end class ButtonEventScene < EventScene def initialize(viewport=nil) super Graphics.freeze addUserSprite(ColoredPlane.new(Color.new(24,24,248),viewport)) @labels=[ addLabel(52*2,24,Graphics.width*3/4,_INTL("Moves the main character. Also used to choose various data headings.")), addLabel(52*2,(24+48)*2,Graphics.width*3/4,_INTL("Used to confirm a choice, check things, and talk to people.")), addLabel(52*2,(24+48+32)*2,Graphics.width*3/4,_INTL("Used to exit, cancel a choice or mode, and open the menu.")), addLabel(52*2,24,360,_INTL("Use this key to use a registered item.")), addLabel(52*2,(24+64)*2,Graphics.width*3/4,_INTL("As you advance in the game, you can use this key to run while moving.")) ] @keys=[ addImage(26*2,24,"Graphics/Pictures/arrowkeys.png"), addImage(26*2,(24+48)*2,"Graphics/Pictures/ckey.png"), addImage(26*2,(24+48+32)*2,"Graphics/Pictures/xkey.png"), addImage(26*2,24,"Graphics/Pictures/f5key.png"), addImage(26*2,(24+64)*2,"Graphics/Pictures/zkey.png") ] for key in @keys key.origin=PictureOrigin::Top end for i in [3,4] @labels[i].moveOpacity(0,0,0) @keys[i].moveOpacity(0,0,0) end update Graphics.transition(20) onCTrigger.set(method(:pbOnScreen1)) end def pbOnScreen1(scene,args) onCTrigger.clear for i in [0,1,2] @labels[i].moveOpacity(20,0,0) @keys[i].moveOpacity(20,0,0) end for i in [3,4] @labels[i].moveOpacity(20,30,255) @keys[i].moveOpacity(20,30,255) end pictureWait onCTrigger.set(method(:pbOnScreen2)) end def pbOnScreen2(scene,args) Graphics.freeze scene.dispose Graphics.transition(20) end end def pbEventScreen(cls) pbFadeOutIn(99999){ viewport=Viewport.new(0,0,480,320) viewport.z=99999 PBDebug.logonerr { cls.new(viewport).main } viewport.dispose } end
PokeBattle_ActiveSide
[
Selecionar
] [
-
]
#5687956 begin class PokeBattle_ActiveSide attr_accessor :effects def initialize @effects=[] @effects[PBEffects::Reflect]=0 @effects[PBEffects::LightScreen]=0 @effects[PBEffects::Mist]=0 @effects[PBEffects::Safeguard]=0 @effects[PBEffects::Spikes]=0 end end rescue Exception if $!.is_a?(SystemExit) || "#{$!.class}"=="Reset" raise $! else end end
PokeBattle_Battler
[
Selecionar
] [
-
]
class PokeBattle_Battler attr_reader :battle attr_reader :totalhp attr_reader :pokemon attr_reader :name attr_reader :index attr_reader :fainted attr_reader :pokemonIndex attr_reader :usingsubmove attr_accessor :lastAttacker attr_accessor :turncount attr_accessor :effects attr_accessor :type1 attr_accessor :type2 attr_accessor :ability attr_accessor :level attr_accessor :species attr_accessor :attack attr_accessor :defense attr_accessor :speed attr_accessor :spatk attr_accessor :iv attr_accessor :spdef attr_accessor :participants attr_accessor :happiness attr_accessor :stages attr_accessor :moves attr_accessor :lastHPLost attr_accessor :lastMoveUsed attr_accessor :lastMoveUsedSketch attr_accessor :lastMoveCalled attr_accessor :currentMove attr_accessor :damagestate ### -- complex accessors def gender return @pokemon.gender if @pokemon return 2 end def nature return @pokemon.nature if @pokemon return 0 end def happiness return @pokemon.happiness if @pokemon return 0 end attr_reader :level def level=(value) @level=value @pokemon.level=value if @pokemon end attr_reader :status def status=(value) @status=value @pokemon.status=value if @pokemon if value!=PBStatuses::POISON @effects[PBEffects::Toxic]=0 end if value!=PBStatuses::POISON && value!=PBStatuses::SLEEP @statusCount=0 @pokemon.statusCount=0 if @pokemon end end attr_reader :statusCount def statusCount=(value) @statusCount=value @pokemon.statusCount=value if @pokemon end attr_reader :hp def hp=(value) @hp=value @pokemon.hp=value if @pokemon end attr_reader :item def item=(value) @item=value @pokemon.item=value if @pokemon end def hpzone return 2 if hp<=(totalhp/4).floor # red [31,11,7],[21,8,9] (bottom,top) return 1 if hp<=(totalhp/2).floor # orange [31,28,7],[25,21,1] return 0 # green [14,31,21],[11,26,16] end ### -- end complex accessors def initialize(btl,index) @battle=btl @hp=0 @fainted=true @usingsubmove=false @totalhp=0 @index=index @effects=[] @stages=[] @damagestate=PokeBattle_DamageState.new pbInitBlank pbInitEffects(false) pbInitPermanentEffects end def pbHasType?(type) if type1==type||type2==type return true end return false end def pbUpdate if @pokemon @hp=@pokemon.hp @totalhp=@pokemon.totalhp @attack=@pokemon.attack @defense=@pokemon.defense @speed=@pokemon.speed @spatk=@pokemon.spatk @spdef=@pokemon.spdef @level=@pokemon.level end end def pbInitPokemon(pkmn,pkmnIndex) if pkmn.egg? raise _INTL("An egg can't be an active Pokémon") end @name=pkmn.name @hp=pkmn.hp @pokemonIndex=pkmnIndex @type1=pkmn.type1 @type2=pkmn.type2 @totalhp=pkmn.totalhp @item=pkmn.item @ability=pkmn.ability @level=pkmn.level @species=pkmn.species @attack=pkmn.attack @defense=pkmn.defense @speed=pkmn.speed @iv=[] @iv[0]=pkmn.iv[0] @iv[1]=pkmn.iv[1] @iv[2]=pkmn.iv[2] @iv[3]=pkmn.iv[3] @iv[4]=pkmn.iv[4] @iv[5]=pkmn.iv[5] @spatk=pkmn.spatk @spdef=pkmn.spdef @happiness=pkmn.happiness @status=pkmn.status @statusCount=pkmn.statusCount @pokemon=pkmn @participants=[] # participants will earn Exp. Points if this battler is defeated @moves=[ PokeBattle_Move.pbFromPBMove(@battle,pkmn.moves[0]), PokeBattle_Move.pbFromPBMove(@battle,pkmn.moves[1]), PokeBattle_Move.pbFromPBMove(@battle,pkmn.moves[2]), PokeBattle_Move.pbFromPBMove(@battle,pkmn.moves[3]) ] end def pbInitBlank @name="" @hp=0 @type1=0 @type2=0 @totalhp=0 @item=0 @ability=0 @level=0 @species=0 @attack=0 @defense=0 @speed=0 @spatk=0 @spdef=0 @happiness=0 @status=0 @statusCount=0 @pokemon=nil @pokemonIndex=-1 @participants=[] @moves=[nil,nil,nil,nil] @iv=[0,0,0,0,0,0] end def pbInitPermanentEffects # These effects are retained even if a Pokémon is replaced @effects[PBEffects::Wish]=0 @effects[PBEffects::WishMaker]=-1 @effects[PBEffects::RecycleItem]=0 @effects[PBEffects::FutureSight]=0 @effects[PBEffects::FutureSightMove]=0 @effects[PBEffects::FutureSightDamage]=0 @effects[PBEffects::FutureSightUser]=-1 end def pbInitEffects(batonpass) if !batonpass # These effects are retained if Baton Pass is used @stages[PBStats::ATTACK]=0 @stages[PBStats::DEFENSE]=0 @stages[PBStats::SPEED]=0 @stages[PBStats::SPATK]=0 @stages[PBStats::SPDEF]=0 @stages[PBStats::EVASION]=0 @stages[PBStats::ACCURACY]=0 @effects[PBEffects::Confusion]=0 @effects[PBEffects::Substitute]=0 @effects[PBEffects::FocusEnergy]=false @effects[PBEffects::Curse]=false @effects[PBEffects::LockOnPos]=-1 @effects[PBEffects::LockOn]=0 for i in 0..3 next if !@battle.battlers[i] if @battle.battlers[i].effects[PBEffects::LockOnPos]==@index && @battle.battlers[i].effects[PBEffects::LockOn]>0 @battle.battlers[i].effects[PBEffects::LockOn]=0 @battle.battlers[i].effects[PBEffects::LockOnPos]=-1 end end @effects[PBEffects::Ingrain]=false @effects[PBEffects::PerishSong]=0 @effects[PBEffects::LeechSeed]=-1 @effects[PBEffects::WaterSport]=false @effects[PBEffects::MudSport]=false @effects[PBEffects::MeanLook]=-1 for i in 0..3 next if !@battle.battlers[i] if @battle.battlers[i].effects[PBEffects::MeanLook]==@index @battle.battlers[i].effects[PBEffects::MeanLook]=-1 end end else if @effects[PBEffects::LockOn] && @effects[PBEffects::LockOn]>0 @effects[PBEffects::LockOn]=2 else @effects[PBEffects::LockOn]=0 end end @fainted=false @damagestate.reset @turncount=0 @lastAttacker=-1 @effects[PBEffects::Pinch]=false @effects[PBEffects::Trace]=false @effects[PBEffects::MirrorMove]=0 pbOpposing1.effects[PBEffects::MirrorMove]=0 if pbOpposing1 pbOpposing2.effects[PBEffects::MirrorMove]=0 if pbOpposing2 @effects[PBEffects::Conversion2Move]=0 @effects[PBEffects::Conversion2Type]=0 @effects[PBEffects::Toxic]=0 @effects[PBEffects::Nightmare]=false @effects[PBEffects::Encore]=0 @effects[PBEffects::EncoreMove]=0 @effects[PBEffects::EncoreIndex]=0 @effects[PBEffects::Attract]=-1 @effects[PBEffects::MultiTurnUser]=-1 for i in 0..3 next if !@battle.battlers[i] if @battle.battlers[i].effects[PBEffects::Attract]==@index @battle.battlers[i].effects[PBEffects::Attract]=-1 end end @effects[PBEffects::MultiTurn]=0 @effects[PBEffects::MultiTurnUser]=-1 for i in 0..3 next if !@battle.battlers[i] if @battle.battlers[i].effects[PBEffects::MultiTurnUser]==@index @battle.battlers[i].effects[PBEffects::MultiTurn]=0 @battle.battlers[i].effects[PBEffects::MultiTurnUser]=-1 end end @effects[PBEffects::Transform]=false @effects[PBEffects::MultiTurn]=0 @effects[PBEffects::Yawn]=0 @effects[PBEffects::MultiTurnAttack]=0 @effects[PBEffects::Outrage]=0 @effects[PBEffects::Foresight]=false @effects[PBEffects::HyperBeam]=0 @effects[PBEffects::DestinyBond]=false @effects[PBEffects::Grudge]=false @effects[PBEffects::Truant]=false @effects[PBEffects::Flinch]=false @effects[PBEffects::Taunt]=0 @effects[PBEffects::Transform]=false @lastMoveUsed=0 @lastMoveUsedSketch=0 @lastMoveCalled=0 @effects[PBEffects::Pursuit]=false @effects[PBEffects::Revenge]=0 @effects[PBEffects::Bide]=0 @effects[PBEffects::BideDamage]=0 @effects[PBEffects::Stockpile]=0 @effects[PBEffects::Protect]=false @effects[PBEffects::ProtectRate]=0 @effects[PBEffects::Endure]=false @effects[PBEffects::HelpingHand]=false @effects[PBEffects::Charge]=0 @lastHPLost=0 @lastAttacker=-1 @effects[PBEffects::Counter]=-1 @effects[PBEffects::MirrorCoat]=-1 @effects[PBEffects::CounterTarget]=-1 @effects[PBEffects::MirrorCoatTarget]=-1 @effects[PBEffects::TwoTurnAttack]=0 @effects[PBEffects::Rollout]=0 @effects[PBEffects::DefenseCurl]=false @effects[PBEffects::MagicCoat]=false @effects[PBEffects::Snatch]=false @effects[PBEffects::FollowMe]=false @effects[PBEffects::Rage]=false @effects[PBEffects::Minimize]=false @effects[PBEffects::FuryCutter]=0 @effects[PBEffects::Imprison]=false @effects[PBEffects::ChoiceBand]=0 @effects[PBEffects::Uproar]=0 @effects[PBEffects::Torment]=false @effects[PBEffects::Disable]=0 @effects[PBEffects::DisableMove]=0 end def pbInitialize(pkmn,index,batonpass) if @hp>0 && @pokemon && self.ability==PBAbilities::NATURALCURE self.status=0 end pbInitPokemon(pkmn,index) pbInitEffects(batonpass) end def pbThis if @battle.pbIsOpposing?(@index) if @battle.opponent return _INTL("Foe {1}",@name) else return _INTL("Wild {1}",@name) end else return _INTL("{1}",@name) end end def pbSpeed stagemul=[10,10,10,10,10,10,10,15,20,25,30,35,40] stagediv=[40,35,30,25,20,15,10,10,10,10,10,10,10] speed=@speed stage=@stages[PBStats::SPEED]+6 speed=(speed*stagemul[stage]/stagediv[stage]).floor if @battle.pbWeather==PBWeather::RAINDANCE && self.ability==PBAbilities::SWIFTSWIM speed=speed*2 end if @battle.pbWeather==PBWeather::SUNNYDAY && self.ability==PBAbilities::CHLOROPHYLL speed=speed*2 end if @item==PBItems::MACHOBRACE speed=(speed/2).floor end if self.status==PBStatuses::PARALYSIS speed=(speed/4).floor end # Dynamo Badge (index 2, internal battles only) if @battle.internalbattle if @battle.pbPlayer.badges[2] && @battle.pbOwnedByPlayer?(@index) speed=(speed*1.1).floor end end return speed end def pbReduceHP(amt) if amt>=self.hp amt=self.hp elsif amt<=0 && self.hp!=0 amt=1 end oldhp=self.hp self.hp-=amt raise _INTL("HP less than 0") if self.hp<0 raise _INTL("HP greater than total HP") if self.hp>@totalhp @battle.scene.pbHPChanged(self,oldhp) if amt>0 return amt end def pbRecoverHP(amt) if self.hp+amt>@totalhp amt=@totalhp-self.hp elsif amt<=0 && self.hp!=@totalhp amt=1 end oldhp=self.hp self.hp+=amt raise _INTL("HP less than 0") if self.hp<0 raise _INTL("HP greater than total HP") if self.hp>@totalhp @battle.scene.pbHPChanged(self,oldhp) if amt>0 return amt end # Returns the data structure for this battler's side def pbOwnSide return @battle.sides[index&1] # Player: 0 and 2; Foe: 1 and 3 end # Returns the data structure for the opposing Pokémon's side def pbOpposingSide return @battle.sides[(index&1)^1] # Player: 1 and 3; Foe: 0 and 2 end # Returns whether the position belongs to the opposing Pokémon's side def pbIsOpposing?(i) return (@index&1)!=(i&1) end # Returns the battler's partner def pbPartner return @battle.battlers[(@index&1)|((@index&2)^2)] end # Returns the battler's first opposing Pokémon def pbOpposing1 return @battle.battlers[((@index&1)^1)] end # Returns the battler's second opposing Pokémon def pbOpposing2 return @battle.battlers[((@index&1)^1)+2] end def pbOppositeOpposing return @battle.battlers[(@index^1)] end # Update Pokémon who will gain EXP if this battler is defeated def pbUpdateParticipants return if hp<=0 # can't update if already fainted if @battle.pbIsOpposing?(@index) found1=false found2=false for i in @participants found1=true if i==pbOpposing1.pokemonIndex found2=true if i==pbOpposing2.pokemonIndex end if !found1&& pbOpposing1.hp>0 @participants[@participants.length]=pbOpposing1.pokemonIndex end if !found2&& pbOpposing2.hp>0 @participants[@participants.length]=pbOpposing2.pokemonIndex end end end def pbReset @pokemon=nil self.hp=0 pbInitEffects(false) # reset status self.status=0 self.statusCount=0 @fainted=true # reset choice @battle.choices[@index]=[0,0,nil,-1] return true end def pbFaint if self.hp>0 PBDebug.log("!!!***Can't faint with HP greater than 0") return true end if @fainted # PBDebug.log("!!!***Can't faint if already fainted") return true end @battle.scene.pbFainted(self) pbInitEffects(false) # reset status self.status=0 self.statusCount=0 @fainted=true # reset choice @battle.choices[@index]=[0,0,nil,-1] @battle.pbDisplayPaused(_INTL("{1} fainted!",pbThis)) if @battle.pbAllFainted?(@battle.party1) @battle.decision=2 return false end return true end def pbUseItem(item) @battle.pbDisplay(_INTL("Items can't be used now.")) end def pbTrace(onactive) if ability==PBAbilities::TRACE && hp>0 return if hp<=0 return if !@effects[PBEffects::Trace] && !onactive choices=[] for i in 0..3 if pbIsOpposing?(i) choices[choices.length]=i if @battle.battlers[i].ability>0 end end if choices==0 @effects[PBEffects::Trace]=true else choice=choices[@battle.pbRandom(choices.length)] battlername=@battle.battlers[choice].pbThis battlerability=@battle.battlers[choice].ability @ability=battlerability abilityname=PBAbilities.getName(battlerability) @battle.pbDisplay(_INTL("{1} traced {2}'s {3}!",pbThis,battlername,abilityname)) @effects[PBEffects::Trace]=false end end end def pbForecast if ability==PBAbilities::FORECAST && isConst?(species,PBSpecies,:CASTFORM) && hp>0 && !@battle.pbCheckGlobalAbility(PBAbilities::CLOUDNINE) && !@battle.pbCheckGlobalAbility(PBAbilities::AIRLOCK) weather=@battle.pbWeather if weather==PBWeather::SUNNYDAY && !pbHasType?(PBTypes::FIRE) @type1=PBTypes::FIRE @type2=PBTypes::FIRE @battle.pbDisplay(_INTL("{1} transformed!",pbThis)) elsif weather==PBWeather::RAINDANCE && !pbHasType?(PBTypes::WATER) @type1=PBTypes::WATER @type2=PBTypes::WATER @battle.pbDisplay(_INTL("{1} transformed!",pbThis)) elsif weather==PBWeather::HAIL && !pbHasType?(PBTypes::ICE) @type1=PBTypes::ICE @type2=PBTypes::ICE @battle.pbDisplay(_INTL("{1} transformed!",pbThis)) elsif (weather==0 || weather==PBWeather::SANDSTORM) && !pbHasType?(PBTypes::NORMAL) @type1=PBTypes::NORMAL @type2=PBTypes::NORMAL @battle.pbDisplay(_INTL("{1} transformed!",pbThis)) end end end def pbAbilityCureCheck return if hp<=0 while self.ability==PBAbilities::LIMBER && self.status==PBStatuses::PARALYSIS @battle.pbDisplay(_INTL("{1}'s Limber cured its paralysis problem!",pbThis)) self.status=0 end while self.ability==PBAbilities::OBLIVIOUS && @effects[PBEffects::Attract]>=0 @battle.pbDisplay(_INTL("{1}'s Oblivious cured its love problem!",pbThis)) @effects[PBEffects::Attract]=-1 end while self.ability==PBAbilities::VITALSPIRIT &&self.status==PBStatuses::SLEEP @battle.pbDisplay(_INTL("{1}'s Vital Spirit cured its sleep problem!",pbThis)) self.status=0 end while self.ability==PBAbilities::INSOMNIA && self.status==PBStatuses::SLEEP @battle.pbDisplay(_INTL("{1}'s Insomnia cured its sleep problem!",pbThis)) self.status=0 end while self.ability==PBAbilities::IMMUNITY && self.status==PBStatuses::POISON @battle.pbDisplay(_INTL("{1}'s Immunity cured its poison problem!",pbThis)) self.status=0 end while self.ability==PBAbilities::OWNTEMPO && @effects[PBEffects::Confusion]>0 @battle.pbDisplay(_INTL("{1}'s Own Tempo cured its confusion problem!",pbThis)) @effects[PBEffects::Confusion]=0 end while self.ability==PBAbilities::MAGMAARMOR && self.status==PBStatuses::FROZEN @battle.pbDisplay(_INTL("{1}'s Magma Armor cured its ice problem!",pbThis)) self.status=0 end while self.ability==PBAbilities::WATERVEIL && self.status==PBStatuses::BURN @battle.pbDisplay(_INTL("{1}'s Water Veil cured its burn problem!",pbThis)) self.status=0 end end def pbConfusionBerry(id,flavor,message1,message2) if self.item==id && self.hp<=(self.totalhp/2).floor pbRecoverHP((self.totalhp/8).floor) @battle.pbDisplay(message1) if (self.nature%5) == flavor && (self.nature/5).floor != (self.nature%5) @battle.pbDisplay(message2) if @effects[PBEffects::Confusion]==0 && self.ability!=PBAbilities::OWNTEMPO @effects[PBEffects::Confusion]=2+@battle.pbRandom(4) @battle.pbCommonAnimation("Confusion",self,nil) @battle.pbDisplay(_INTL("{1} became confused!",pbThis)) end end @effects[PBEffects::RecycleItem]=self.item self.item=0 end end def pbStatIncreasingBerry(id,stat,message) if self.item==id && self.hp<=(self.totalhp/4).floor && !self.pbTooHigh?(stat) @stages[stat]+=1 @battle.pbDisplay(message) @effects[PBEffects::RecycleItem]=self.item self.item=0 end end def pbBerryCureCheck(hpcure=false) return if hp<=0 itemname=(self.item==0) ? "" : PBItems.getName(self.item) if hpcure && self.item==PBItems::BERRYJUICE && self.hp<=(self.totalhp/2).floor @battle.pbDisplay(_INTL("{1}'s {2} restored health!",pbThis,itemname)) self.pbRecoverHP(20) @effects[PBEffects::RecycleItem]=self.item self.item=0 end if hpcure && self.item==PBItems::ORANBERRY && self.hp<=(self.totalhp/2).floor @battle.pbDisplay(_INTL("{1}'s {2} restored health!",pbThis,itemname)) self.pbRecoverHP(10) @effects[PBEffects::RecycleItem]=self.item self.item=0 end if hpcure && self.item==PBItems::SITRUSBERRY && self.hp<=(self.totalhp/2).floor @battle.pbDisplay(_INTL("{1}'s {2} restored health!",pbThis,itemname)) self.pbRecoverHP(30) @effects[PBEffects::RecycleItem]=self.item self.item=0 end while self.item==PBItems::CHERIBERRY && status==PBStatuses::PARALYSIS @battle.pbDisplay(_INTL("{1}'s {2} cured its paralysis problem!",pbThis,itemname)) self.status=0 @effects[PBEffects::RecycleItem]=self.item self.item=0 end while self.item==PBItems::CHESTOBERRY && status==PBStatuses::SLEEP @battle.pbDisplay(_INTL("{1}'s {2} cured its sleep problem!",pbThis,itemname)) self.status=0 @effects[PBEffects::RecycleItem]=self.item self.item=0 end while self.item==PBItems::PECHABERRY && status==PBStatuses::POISON @battle.pbDisplay(_INTL("{1}'s {2} cured its poison problem!",pbThis,itemname)) self.status=0 @effects[PBEffects::RecycleItem]=self.item self.item=0 end while self.item==PBItems::RAWSTBERRY && status==PBStatuses::BURN @battle.pbDisplay(_INTL("{1}'s {2} cured its burn problem!",pbThis,itemname)) self.status=0 @effects[PBEffects::RecycleItem]=self.item self.item=0 end while self.item==PBItems::ASPEARBERRY && status==PBStatuses::FROZEN @battle.pbDisplay(_INTL("{1}'s {2} cured its ice problem!",pbThis,itemname)) self.status=0 @effects[PBEffects::RecycleItem]=self.item self.item=0 end if hpcure && self.item==PBItems::LEPPABERRY for i in 0...@pokemon.moves.length pokemove=@pokemon.moves[i] battlermove=self.moves[i] if pokemove.pp==0 movename=PBMoves.getName(pokemove.id); pokemove.pp=10 pokemove.pp=pokemove.totalpp if pokemove.pp>pokemove.totalpp battlermove.pp=pokemove.pp @battle.pbDisplay(_INTL("{1}'s {2} restored {3}'s PP!",pbThis,itemname,movename)) @effects[PBEffects::RecycleItem]=self.item self.item=0 break end end end while self.item==PBItems::PERSIMBERRY && @effects[PBEffects::Confusion]>0 @battle.pbDisplay(_INTL("{1}'s {2} cured its confusion problem!",pbThis,itemname)) @effects[PBEffects::Confusion]=0 @effects[PBEffects::RecycleItem]=self.item self.item=0 end while self.item==PBItems::LUMBERRY && (status>0||@effects[PBEffects::Confusion]>0) if @effects[PBEffects::Confusion]>0 @battle.pbDisplay(_INTL("{1}'s {2} cured its confusion problem!",pbThis,itemname)) else case status when PBStatuses::PARALYSIS @battle.pbDisplay(_INTL("{1}'s {2} cured its paralysis problem!",pbThis,itemname)) when PBStatuses::SLEEP @battle.pbDisplay(_INTL("{1}'s {2} cured its sleep problem!",pbThis,itemname)) when PBStatuses::POISON @battle.pbDisplay(_INTL("{1}'s {2} cured its poison problem!",pbThis,itemname)) when PBStatuses::BURN @battle.pbDisplay(_INTL("{1}'s {2} cured its burn problem!",pbThis,itemname)) when PBStatuses::FROZEN @battle.pbDisplay(_INTL("{1}'s {2} cured its frozen problem!",pbThis,itemname)) end end self.status=0 @effects[PBEffects::Confusion]=0 @effects[PBEffects::RecycleItem]=self.item self.item=0 end if hpcure pbConfusionBerry(PBItems::FIGYBERRY,0, _INTL("{1}'s {2} restored health!",pbThis,itemname), _INTL("For {1}, the {2} was too spicy!",pbThis,itemname)) pbConfusionBerry(PBItems::WIKIBERRY,3, _INTL("{1}'s {2} restored health!",pbThis,itemname), _INTL("For {1}, the {2} was too dry!",pbThis,itemname)) pbConfusionBerry(PBItems::MAGOBERRY,2, _INTL("{1}'s {2} restored health!",pbThis,itemname), _INTL("For {1}, the {2} was too sweet!",pbThis,itemname)) pbConfusionBerry(PBItems::AGUAVBERRY,4, _INTL("{1}'s {2} restored health!",pbThis,itemname), _INTL("For {1}, the {2} was too bitter!",pbThis,itemname)) pbConfusionBerry(PBItems::IAPAPABERRY,1, _INTL("{1}'s {2} restored health!",pbThis,itemname), _INTL("For {1}, the {2} was too sour!",pbThis,itemname)) pbStatIncreasingBerry(PBItems::LIECHIBERRY,PBStats::ATTACK, _INTL("Using its {1}, the Attack of {2} rose!",itemname,pbThis)) pbStatIncreasingBerry(PBItems::GANLONBERRY,PBStats::DEFENSE, _INTL("Using its {1}, the Defense of {2} rose!",itemname,pbThis)) pbStatIncreasingBerry(PBItems::SALACBERRY,PBStats::SPEED, _INTL("Using its {1}, the Speed of {2} rose!",itemname,pbThis)) pbStatIncreasingBerry(PBItems::PETAYABERRY,PBStats::SPATK, _INTL("Using its {1}, the Special Attack of {2} rose!",itemname,pbThis)) pbStatIncreasingBerry(PBItems::APICOTBERRY,PBStats::SPDEF, _INTL("Using its {1}, the Special Defense of {2} rose!",itemname,pbThis)) end if hpcure && self.item==PBItems::LANSATBERRY && self.hp<=(self.totalhp/4).floor && !@effects[PBEffects::FocusEnergy] @battle.pbDisplay(_INTL("{1} used its {2} to get pumped!",pbThis,itemname)) @effects[PBEffects::FocusEnergy]=true @effects[PBEffects::RecycleItem]=self.item self.item=0 end if hpcure && self.item==PBItems::STARFBERRY && self.hp<=(self.totalhp/4).floor stats=[] messages=[ _INTL("Using {1}, the Attack of {2} sharply rose!",itemname,pbThis), _INTL("Using {1}, the Defense of {2} sharply rose!",itemname,pbThis), _INTL("Using {1}, the Speed of {2} sharply rose!",itemname,pbThis), _INTL("Using {1}, the Special Attack of {2} sharply rose!",itemname,pbThis), _INTL("Using {1}, the Special Defense of {2} sharply rose!",itemname,pbThis) ] for i in 0...5 stats[stats.length]=i if !pbTooHigh?(i) end if stats.length>0 stat=stats[@battle.pbRandom(stats.length)] @stages[stat]+=2 @stages[stat]=6 if @stages[stat]>6 @battle.pbDisplay(messages[stat]) @effects[PBEffects::RecycleItem]=self.item self.item=0 end end if self.item==PBItems::WHITEHERB while true reducedstats=0 for i in 0..6 reducedstats+=1 if @stages[i]<0 end break if reducedstats==0 for i in 0..6 @stages[i]=0 if @stages[i]<0 end @battle.pbDisplay(_INTL("{1}'s {2} restored its status!",pbThis,itemname)) @effects[PBEffects::RecycleItem]=self.item self.item=0 end end while self.item==PBItems::MENTALHERB && @effects[PBEffects::Attract]>=0 @battle.pbDisplay(_INTL("{1}'s {2} cured its love problem!",pbThis,itemname)) @effects[PBEffects::Attract]=-1 @effects[PBEffects::RecycleItem]=self.item self.item=0 end if hpcure && self.item==PBItems::LEFTOVERS && self.hp!=self.totalhp pbRecoverHP((self.totalhp/16).floor) @battle.pbDisplay(_INTL("{1}'s {2} restored its HP a little!",pbThis,itemname)) end end def pbAddTarget(targets,target) if target.hp>0 targets[targets.length]=target return true end return false end def pbRandomTarget(targets) choices=[] pbAddTarget(choices,pbOpposing1) pbAddTarget(choices,pbOpposing2) if choices.length>0 pbAddTarget(targets,choices[@battle.pbRandom(choices.length)]) end end def pbConfusionDamage self.damagestate.reset confmove=PokeBattle_Confusion.new(@battle,nil) confmove.pbEffect(self,self) pbFaint if self.hp<=0 end def pbSetPP(move,pp) move.pp=pp #Not effects[PBEffects::Mimic], since Mimic can't copy Mimic if move.id==move.thismove.id && !@effects[PBEffects::Transform] move.thismove.pp=pp end end def pbReducePP(move) #TODO: Pressure if @effects[PBEffects::TwoTurnAttack]>0 || @effects[PBEffects::Bide]>0 || @effects[PBEffects::Outrage]>0 || @effects[PBEffects::Rollout]>0 || @effects[PBEffects::HyperBeam]>0 || @effects[PBEffects::Uproar]>0 # No need to reduce PP if two-turn attack return true end if move.pp<0 # No need to reduce PP for special calls of moves return true end if move.pp==0 return false end if move.pp>0 pbSetPP(move,move.pp-1) end return true end def pbReducePPOther(move) pbSetPP(move,move.pp-1) if move.pp>0 end def pbFindUser(choice,targets) priority=@battle.pbPriority move=choice[2] target=choice[3] #Normally, the user is self user=self #Targets in normal cases if move.target==0x00 if target>=0 targetBattler=@battle.battlers[target] if !pbIsOpposing?(targetBattler.index) if !pbAddTarget(targets,targetBattler) pbAddTarget(targets,pbOpposing2) if !pbAddTarget(targets,pbOpposing1) end else pbAddTarget(targets,targetBattler.pbPartner) if !pbAddTarget(targets,targetBattler) end else pbRandomTarget(targets) end elsif move.target==0x04 pbRandomTarget(targets) elsif move.target==0x08 # Just pbOpposing1 because partner is determined late pbAddTarget(targets,pbOpposing2) if !pbAddTarget(targets,pbOpposing1) elsif move.target==0x20 for i in 0..3 # not ordered by priority if i!=@index pbAddTarget(targets,@battle.battlers[i]) end end else move.pbAddTarget(targets,self) end return user end def pbChangeUser(thismove,user) priority=@battle.pbPriority # Change user to user of Snatch if (thismove.flags&0x08)!=0 # flag d: Snatch for i in priority if i.effects[PBEffects::Snatch] @battle.pbDisplay(_INTL("{1} Snatched {2}'s move!",i.pbThis,user.pbThis)) i.effects[PBEffects::Snatch]=false target=user user=i # Snatch's PP is reduced if old user has Pressure userchoice=@battle.choices[user.index][1] if target.ability==PBAbilities::PRESSURE && userchoice>=0 pressuremove=user.moves[userchoice] pbSetPP(pressuremove,pressuremove.pp-1) if pressuremove.pp>0 end end end end return user end def pbChangeTarget(thismove,userandtarget,targets) priority=@battle.pbPriority changeeffect=0 user=userandtarget[0] target=userandtarget[1] # LightningRod here, considers Hidden Power as Normal if thismove.type==PBTypes::ELECTRIC && targets.length>0 && target.ability!=PBAbilities::LIGHTNINGROD # all damaging Electric attacks have a target of "single non-user" for i in priority # use Pokémon earliest in priority next if !pbIsOpposing?(i.index) if i.ability==PBAbilities::LIGHTNINGROD target=i# X's LightningRod took the attack! changeeffect=1 break end end end # Change target to user of Follow Me (overrides Magic Coat # because check for Magic Coat below uses this target) if thismove.target==0 # target is a single non-user for i in priority # use Pokémon latest in priority next if !pbIsOpposing?(i.index) if i.effects[PBEffects::FollowMe] #change target to this target=i end end end # TODO: Pressure here is incorrect if Magic Coat redirects target if target.ability==PBAbilities::PRESSURE pbReducePP(thismove) # Reduce PP end # Change user to user of Snatch if (thismove.flags&0x08)!=0 # flag d: Snatch for i in priority if i.effects[PBEffects::Snatch] @battle.pbDisplay(_INTL("{1} Snatched {2}'s move!",i.pbThis,user.pbThis)) i.effects[PBEffects::Snatch]=false target=user user=i # Snatch's PP is reduced if old user has Pressure userchoice=@battle.choices[user.index][1] if target.ability==PBAbilities::PRESSURE && userchoice>=0 pressuremove=user.moves[userchoice] pbSetPP(pressuremove,pressuremove.pp-1) if pressuremove.pp>0 end end end end userandtarget[0]=user userandtarget[1]=target if target.ability==PBAbilities::SOUNDPROOF && #Heal Bell/Perish Song handled elsewhere (thismove.id==PBMoves::GROWL|| thismove.id==PBMoves::HYPERVOICE|| thismove.id==PBMoves::SUPERSONIC|| thismove.id==PBMoves::ROAR|| thismove.id==PBMoves::GRASSWHISTLE|| thismove.id==PBMoves::METALSOUND|| thismove.id==PBMoves::SING|| thismove.id==PBMoves::SCREECH|| thismove.id==PBMoves::UPROAR|| thismove.id==PBMoves::SNORE) @battle.pbDisplay(_INTL("{1}'s Soundproof blocks {2}!",target.pbThis,thismove.name)) return false end if (thismove.flags&0x04)!=0 && target.effects[PBEffects::MagicCoat] # flag c: Magic Coat # switch user and target changeeffect=2 target.effects[PBEffects::MagicCoat]=false tmp=user user=target target=tmp # Magic Coat's PP is reduced if old user has Pressure userchoice=@battle.choices[user.index][1] if target.ability==PBAbilities::PRESSURE && userchoice>=0 pressuremove=user.moves[userchoice] pbSetPP(pressuremove,pressuremove.pp-1) if pressuremove.pp>0 end end if changeeffect==1 @battle.pbDisplay(_INTL("{1}'s LightningRod took the move!",target.pbThis)) elsif changeeffect==2 # Target refers to the move's old user @battle.pbDisplay(_INTL("{1}'s {2} was bounced back by Magic Coat!",target.pbThis,thismove.name)) end userandtarget[0]=user userandtarget[1]=target return true end def pbObedienceCheck?(choice) if choice[0]!=1 return true end if @battle.pbOwnedByPlayer?(@index) && @battle.internalbattle badgelevel=10 badgelevel=30 if @battle.pbPlayer.badges[1] badgelevel=50 if @battle.pbPlayer.badges[3] badgelevel=70 if @battle.pbPlayer.badges[5] badgelevel=100 if @battle.pbPlayer.badges[7] move=choice[2] if @pokemon.isForeign?(@battle.pbPlayer) && @level>badgelevel a=((@level+badgelevel)*@battle.pbRandom(256)/255).floor return true if a<badgelevel @effects[PBEffects::Rage]=false if self.status==PBStatuses::SLEEP && (move.function==0x5C || # SNORE move.function==0x61) # SLEEP TALK @battle.pbDisplay(_INTL("{1} ignored orders while asleep!",pbThis)) return false end b=((@level+badgelevel)*@battle.pbRandom(256)/255).floor if b<badgelevel if !@battle.pbCanShowFightMenu?(@index) return false end othermoves=[] for i in 0..3 next if i==choice[1] othermoves[othermoves.length]=i if @battle.pbCanChooseMove?(@index,i,false) end if othermoves.length>0 @battle.pbDisplay(_INTL("{1} used a different move instead!",pbThis)) newchoice=othermoves[@battle.pbRandom(othermoves.length)] choice[1]=newchoice choice[2]=@moves[newchoice] choice[3]=-1 end return true elsif self.status!=PBStatuses::SLEEP c=@level-b r=@battle.pbRandom(256) if r<c && pbCanSleep?(false,true) pbSleep @battle.pbDisplay(_INTL("{1} took a nap!",pbThis)) return false end r-=c if r<c @battle.pbDisplay(_INTL("It hurt itself from its confusion!")) pbConfusionDamage else message=@battle.pbRandom(4) @battle.pbDisplay(_INTL("{1} ignored orders!",pbThis)) if message==0 @battle.pbDisplay(_INTL("{1} turned away!",pbThis)) if message==1 @battle.pbDisplay(_INTL("{1} is loafing around!",pbThis)) if message==2 @battle.pbDisplay(_INTL("{1} pretended not to notice!",pbThis)) if message==3 end return false end end return true else return true end end def pbSuccessCheck(thismove,user,target,accuracy=true) if user.effects[PBEffects::TwoTurnAttack]>0 PBDebug.log("[Using two-turn attack]") return true end # TODO: "Before Protect" applies to Counter/Mirror Coat if (target.status!=PBStatuses::SLEEP || target.effects[PBEffects::Substitute]>0) && thismove.function==0x08 # DREAM EATER @battle.pbDisplay(_INTL("{1} wasn't affected!",target.pbThis)) return false end if thismove.function==0xA8 # MEMENTO if target.pbTooLow?(PBStats::ATTACK) && target.pbTooLow?(PBStats::SPATK) @battle.pbDisplay(_INTL("But it failed!")) return false end user.hp=0 end if thismove.function==0xA1 && user.effects[PBEffects::Stockpile]==0 # SPIT UP @battle.pbDisplay(_INTL("But it failed to spit up a thing!")) return false end if target.effects[PBEffects::Protect] && (thismove.flags & 0x02) # flag b: Protect/Detect @battle.pbDisplay(_INTL("{1} protected itself!",target.pbThis)) return false end if thismove.function==0x51 # RAGE @effects[PBEffects::Rage]=true end # TODO: Mind Reader/Lock-On # --Sketch/FutureSight/PsychUp work even on Fly/Bounce/Dive/Dig if thismove.pbMoveFailed(user,target) #TODO:Applies to Snore/Fake Out @battle.pbDisplay(_INTL("But it failed!")) return false end if thismove.basedamage>0 && thismove.function!=0x9A && # BEAT UP thismove.id!=PBMoves::STRUGGLE && thismove.function!=0x94 # FUTURE SIGHT type=thismove.pbType(thismove.type,user,target) typemod=thismove.pbTypeModifier(type,target) if target.ability==PBAbilities::LEVITATE && type==PBTypes::GROUND @battle.pbDisplay(_INTL("{1} makes Ground moves miss with Levitate!",target.pbThis)); return false end if target.ability==PBAbilities::WONDERGUARD && typemod<=4 @battle.pbDisplay(_INTL("{1} avoided damage with Wonder Guard!",target.pbThis)); return false end if typemod==0 @battle.pbDisplay(_INTL("It doesn't affect\\r\\n{1}...",target.pbThis)); return false end end if accuracy if target.effects[PBEffects::LockOn]>0 && target.effects[PBEffects::LockOnPos]==user.index return true end miss=false if target.effects[PBEffects::TwoTurnAttack]==PBMoves::DIG miss=true unless thismove.id==PBMoves::EARTHQUAKE|| thismove.id==PBMoves::FISSURE|| thismove.id==PBMoves::MAGNITUDE end if target.effects[PBEffects::TwoTurnAttack]==PBMoves::DIVE miss=true unless thismove.id==PBMoves::SURF|| thismove.id==PBMoves::WHIRLPOOL end if target.effects[PBEffects::TwoTurnAttack]==PBMoves::FLY || target.effects[PBEffects::TwoTurnAttack]==PBMoves::BOUNCE miss=true unless thismove.id==PBMoves::GUST|| thismove.id==PBMoves::THUNDER|| thismove.id==PBMoves::TWISTER|| thismove.id==PBMoves::SKYUPPERCUT end if miss || !thismove.pbAccuracyCheck(user,target)#Includes Counter/Mirror Coat if thismove.target==0x08||thismove.target==0x20 # All opposing Pokémon or all non-users @battle.pbDisplay(_INTL("{1}\\r\\navoided the attack!",target.pbThis)) elsif thismove.function==0x54 # LEECH SEED @battle.pbDisplay(_INTL("{1}\\r\\nevaded the attack!",target.pbThis)) else @battle.pbDisplay(_INTL("{1}'s\\r\\nattack missed!",user.pbThis)) end return false end end return true end def pbProcessBeatUp(thismove,user,target) #TODO: Actually ignores Wonder Guard effect unless it really misses numhits=0 if !pbSuccessCheck(thismove,user,target,true) return end party=@battle.pbParty(@index) # NOTE: Considers both parties in multi battles for i in 0...party.length if party[i] && party[i].hp>0 && party[i].status!=0 && !party[i].egg? thisname=@battle.pbThisEx(@index,i) @battle.pbDisplayBrief(_INTL("{1}'s attack!",thisname)); thismove.pbSetThisPkmn(party[i]) pbProcessNonMultiHitMove(thismove,user,target,true) numhits+=1 end end if numhits==0 @battle.pbDisplay(_INTL("But it failed!")); return end end def pbUpdateTargetedMove(thismove,user) # TODO: Snatch, moves that use other moves if (thismove.target==0x00||thismove.target==0x01|| thismove.target==0x04||thismove.target==0x02) && thismove.flags&0x10 && !user.usingsubmove @effects[PBEffects::MirrorMove]=thismove.id end # TODO: All targeting cases # Two-turn attacks, Magic Coat, Future Sight, Counter/MirrorCoat/Bide handled @effects[PBEffects::Conversion2Move]=thismove.id @effects[PBEffects::Conversion2Type]=thismove.pbType(thismove.type,user,self) end def pbProcessNonMultiHitMove(thismove,user,target,nocheck=false) if !nocheck && !pbSuccessCheck(thismove,user,target,true) if thismove.function==0x2D # JUMP KICK #TODO: Not shown if message is "It doesn't affect XXX..." @battle.pbDisplay(_INTL("{1} kept going and crashed!",user.pbThis)) damage=thismove.pbCalcDamage(user,target) if damage>0 if target.effects[PBEffects::Substitute]>0 if target.effects[PBEffects::Endure] || target.damagestate.focusband damage=target.hp-1 if damage>=target.hp end end damage=(damage/2).floor damage=[damage,(target.hp/2).floor].min @battle.scene.pbDamageAnimation(user,0) user.pbReduceHP(damage) end user.pbFaint if user.hp<=0 end user.effects[PBEffects::Rollout]=0 if thismove.function==0x75 # ROLLOUT user.effects[PBEffects::FuryCutter]=0 if thismove.function==0x77 # FURY CUTTER user.effects[PBEffects::Stockpile]=0 if thismove.function==0xA1 # SPIT UP target.effects[PBEffects::Conversion2Move]=-1 target.effects[PBEffects::Conversion2Type]=0 return else if thismove.function==0x75 # ROLLOUT user.effects[PBEffects::Rollout]=5 if user.effects[PBEffects::Rollout]==0 user.effects[PBEffects::Rollout]-=1 user.currentMove=thismove.id end if thismove.function==0x77 # FURY CUTTER user.effects[PBEffects::FuryCutter]+=1 if user.effects[PBEffects::FuryCutter]<5 end end damage=thismove.pbEffect(user,target)# Recoil/drain, etc. are applied here if user.hp<=0 && thismove.function!=0x07 # SELFDESTRUCT user.pbFaint#no return end # Additional effect if target.damagestate.calcdamage>0 && target.ability!=PBAbilities::SHIELDDUST addleffect=thismove.addlEffect if user.ability==PBAbilities::SERENEGRACE addleffect*=2 end if @battle.pbRandom(100)<addleffect thismove.pbAdditionalEffect(user,target) end # if @battle.pbRandom(100)<addleffect # thismove.pbAdditionalEffect2(user,target) # end if user.item==PBItems::KINGSROCK&& (thismove.flags&0x20)!=0 && @battle.pbRandom(10)==0 # flag f: King's Rock if target.ability!=PBAbilities::INNERFOCUS && target.effects[PBEffects::Substitute]==0 target.effects[PBEffects::Flinch]=true end end end # Rage if target.hp>0 && target.effects[PBEffects::Rage] && target.pbIsOpposing?(user.index) && damage>0 # TODO: Apparently triggers if opposing Pokémon uses Future Sight after a Future Sight attack if !target.pbTooHigh?(PBStats::ATTACK) target.stages[PBStats::ATTACK]+=1 @battle.pbDisplay(_INTL("{1}'s Rage is building!",target.pbThis)) end end # Defrost if thismove.pbType(thismove.type,user,target)==PBTypes::FIRE && thismove.function!=0x87 && # HIDDEN POWER target.status==PBStatuses::FROZEN && target.hp>0 && damage>0 @battle.pbDisplay(_INTL("{1} was defrosted!",target.pbThis)) target.status=0 end # Grudge if target.effects[PBEffects::Grudge] && target.hp<=0 && user.hp>0 @battle.pbDisplay(_INTL("{1}'s {2} lost all PP due to the Grudge!",user.pbThis,thismove.name)) thismove.pp=0 end # Destiny Bond if thismove.function!=0x9A && # BEAT UP target.effects[PBEffects::DestinyBond] && target.hp<=0 && user.hp>0 @battle.pbDisplay(_INTL("{1} took {2} with it!",target.pbThis,user.pbThis)) user.pbReduceHP(user.hp) user.pbFaint#no return end # Opponent faints if 0 HP if target.hp<=0 target.pbFaint#no return end # Ability effects @battle.pbAbilityEffect(thismove,user,target,damage) for j in 0..3 @battle.battlers[j].pbBerryCureCheck end # Shell Bell if user.item==PBItems::SHELLBELL && damage > 0 && user.hp>0 hpgain=user.pbRecoverHP((damage/8).floor) if hpgain>0 @battle.pbDisplay(_INTL("{1}'s Shell Bell restored its HP a little!",user.pbThis)) end end target.pbUpdateTargetedMove(thismove,user) end def pbProcessMultiHitMove(thismove,user,target,numhits) # Includes Triple Kick realnumhits=0 for i in 0...numhits if !pbSuccessCheck(thismove,user,target,i==0||thismove.function==0x68) # TRIPLE KICK target.effects[PBEffects::Conversion2Move]=-1 target.effects[PBEffects::Conversion2Type]=0 return end realnumhits+=1 damage=thismove.pbEffect(user,target)# Recoil/drain, etc. are applied here return if target.damagestate.calcdamage<=0 # Critical hit message if target.damagestate.critical @battle.pbDisplay(_INTL("A critical hit!")) end # Rage if target.hp>0 && target.effects[PBEffects::Rage] && target.pbIsOpposing?(user.index) && damage>0 if !target.pbTooHigh?(PBStats::ATTACK) target.stages[PBStats::ATTACK]+=1 @battle.pbDisplay(_INTL("{1}'s Rage is building!",target.pbThis)) end end # Ability effects @battle.pbAbilityEffect(thismove,user,target,damage) # Berry check (maybe just called by ability effect, since only necessary Berries are checked) for j in 0..3 @battle.battlers[j].pbBerryCureCheck end # Shell Bell if user.item==PBItems::SHELLBELL && damage > 0 && user.hp>0 hpgain=user.pbRecoverHP((damage/8).floor) if hpgain>0 @battle.pbDisplay(_INTL("{1}'s Shell Bell restored its HP a little!",user.pbThis)) end end #Endure if target.damagestate.endured @battle.pbDisplay(_INTL("{1} endured the hit!",target.pbThis)) break end target.pbUpdateTargetedMove(thismove,user) break if target.hp<=0 end # Focus Band if target.damagestate.focusbandused @battle.pbDisplay(_INTL("{1} hung on using its Focus Band!",target.pbThis)) end # Type effectiveness if target.damagestate.typemod>=1&&target.damagestate.typemod<4 @battle.pbDisplay(_INTL("It's not very effective...")) end if target.damagestate.typemod>4 @battle.pbDisplay(_INTL("It's super effective!")) end # Number of hits @battle.pbDisplay(_INTL("Hit {1} time(s)!",realnumhits)) # Opponent faints if 0 HP if target.hp<=0 target.pbFaint#no return end # Additional effect if target.ability!=PBAbilities::SHIELDDUST addleffect=thismove.addlEffect if user.ability==PBAbilities::SERENEGRACE addleffect*=2 end if @battle.pbRandom(100)<addleffect thismove.pbAdditionalEffect(user,target) end if user.item==PBItems::KINGSROCK&& (thismove.flags&0x20)!=0 && @battle.pbRandom(10)==0 # flag f: King's Rock if target.ability!=PBAbilities::INNERFOCUS && target.effects[PBEffects::Substitute]==0 target.effects[PBEffects::Flinch]=true end end end # TODO: If Poison Point, etc. triggered above, user's Synchronize somehow triggers here # even if condition is removed before now [true except for Triple Kick] # Berry check for j in 0..3 @battle.battlers[j].pbBerryCureCheck end target.pbUpdateTargetedMove(thismove,user) end def pbUseMoveSimple(moveid,index=-1) choice=[] choice[0]=1 choice[1]=index choice[2]=PokeBattle_Move.pbFromPBMove(@battle,PBMove.new(moveid)) choice[2].pp=-1 choice[3]=-1 if index>=0 @battle.choices[@index][1]=index end @usingsubmove=true ret=pbUseMove(choice) @usingsubmove=false return ret end def pbUseMove(choice) if choice[0]!=1# if move was not chosen return false end thismove=choice[2] if thismove.pbTwoTurnAttack(self) # Beginning use of two-turn attack @effects[PBEffects::TwoTurnAttack]=thismove.id @currentMove=thismove.id else @effects[PBEffects::TwoTurnAttack]=0 # Cancel use of two-turn attack case thismove.pbDisplayUseMessage(self) when 2 # Continuing Bide self.lastMoveUsed=-1 self.lastMoveCalled=-1 return true when 1 # Starting Bide self.lastMoveUsedSketch=thismove.id self.lastMoveUsed=thismove.id self.lastMoveCalled=thismove.id return true when -1 # Focus Punch self.lastMoveUsed=thismove.id self.lastMoveCalled=thismove.id return false end end targets=[] user=pbFindUser(choice,targets) selffaint=(thismove.function==0x07) # SELFDESTRUCT if !thismove.pbOnStartUse(user) # Used by Magnitude/Selfdestruct/etc. user.lastMoveUsedSketch=thismove.id user.lastMoveUsed=thismove.id user.lastMoveCalled=thismove.id return false end if targets.length==0 user=pbChangeUser(thismove,user) PBDebug.logonerr{ thismove.pbEffect(user,nil) } else i=0; loop do break if i>=targets.length userandtarget=[user,targets[i]] success=pbChangeTarget(thismove,userandtarget,targets) user=userandtarget[0] target=userandtarget[1] if i==0 && thismove.target==0x08 # Add partner to list of targets pbAddTarget(targets,target.pbPartner) end if !success i+=1 next end numhits=thismove.pbNumHits target.damagestate.reset if target.item==PBItems::FOCUSBAND && @battle.pbRandom(10)==0 #Works even if it's a Future Sight attack target.damagestate.focusband=true end if thismove.function==0x9A # BEATUP pbProcessBeatUp(thismove,user,target) elsif thismove.pbIsMultiHit pbProcessMultiHitMove(thismove,user,target,numhits) else pbProcessNonMultiHitMove(thismove,user,target) end i+=1 end end # TODO: lastMoveUsed is not to be updated on nested calls if thismove.function==0x52|| # MIMIC thismove.function==0x5F|| # SKETCH thismove.function==0x39 # TRANSFORM user.lastMoveUsedSketch=-1 user.lastMoveUsed=-1 else if @effects[PBEffects::TwoTurnAttack]==0 user.lastMoveUsedSketch=thismove.id end user.lastMoveUsed=thismove.id end user.lastMoveCalled=thismove.id if selffaint user.hp=0 user.pbFaint#no return end @battle.pbGainEXP return true end def pbBeginTurn(choice) @effects[PBEffects::DestinyBond]=false @effects[PBEffects::Grudge]=false if @effects[PBEffects::Encore]>0 && @moves[@effects[PBEffects::EncoreIndex]].id!=@effects[PBEffects::EncoreMove] PBDebug.log("[Resetting Encore effect]") @effects[PBEffects::Encore]=0 @effects[PBEffects::EncoreIndex]=0 @effects[PBEffects::EncoreMove]=0 end if self.ability!=PBAbilities::SOUNDPROOF && self.status==PBStatuses::SLEEP for i in 0..3 if @battle.battlers[i].effects[PBEffects::Uproar]>0 self.effects[PBEffects::Nightmare]=false @battle.pbDisplay(_INTL("{1} woke up in the uproar!",pbThis)) self.status=0 end end end end def pbEndTurn(choice) @effects[PBEffects::Conversion2Move]=0 @effects[PBEffects::Conversion2Type]=0 if @effects[PBEffects::ChoiceBand]<0 && @lastMoveUsed>=0 && @hp>0 && @item==PBItems::CHOICEBAND @effects[PBEffects::ChoiceBand]=@lastMoveUsed end @battle.synchronize[0]=-1 @battle.synchronize[1]=-1 @battle.synchronize[2]=0 for i in 0..3 @battle.battlers[i].pbAbilityCureCheck end for i in 0..3 @battle.battlers[i].pbBerryCureCheck end for i in 0..3 @battle.battlers[i].pbTrace(false) end for i in 0..3 @battle.battlers[i].pbForecast end for i in 0..3 @battle.battlers[i].pbBerryCureCheck end end def pbTryUseMove(choice) if choice[0]!=1# if move was not chosen return false end if @effects[PBEffects::TwoTurnAttack]>0 || @effects[PBEffects::Outrage]>0|| @effects[PBEffects::HyperBeam]>0|| @effects[PBEffects::Bide]>0|| @effects[PBEffects::Rollout]>0|| @effects[PBEffects::Uproar]>0 choice[2]=PokeBattle_Move.pbFromPBMove(@battle,PBMove.new(@currentMove)) elsif @effects[PBEffects::Encore]>0 if @battle.pbCanShowCommands?(@index)&& @battle.pbCanChooseMove?(@index,@effects[PBEffects::EncoreIndex],false) PBDebug.log("[Using Encore move]") choice[1]=@effects[PBEffects::EncoreIndex] choice[2]=@moves[@effects[PBEffects::EncoreIndex]] choice[3]=-1 # No target chosen end end thismove=choice[2] pbBeginTurn(choice) if !pbObedienceCheck?(choice) return false end if self.status==PBStatuses::SLEEP if self.ability==PBAbilities::EARLYBIRD self.statusCount-=2 else self.statusCount-=1 end if self.statusCount<=0 self.effects[PBEffects::Nightmare]=false @battle.pbDisplay(_INTL("{1} woke up!",pbThis)) self.status=0 else @battle.pbDisplay(_INTL("{1} is fast asleep.",pbThis)) @battle.pbCommonAnimation("Sleep",self,nil) if thismove.function!=0x5C && # SNORE thismove.function!=0x61 # SLEEP TALK return false end end end if self.status==PBStatuses::FROZEN if @battle.pbRandom(10)==0 @battle.pbDisplay(_INTL("{1} was defrosted!",pbThis)) self.status=0 elsif thismove.function!=0x7D # FLAME WHEEL @battle.pbDisplay(_INTL("{1} is frozen solid!",pbThis)) @battle.pbCommonAnimation("Frozen",self,nil) return false end end if choice[1]==-2 # Battle Palace @battle.pbDisplay(_INTL("{1} appears incapable of using its power!",pbThis)) return false end if @effects[PBEffects::HyperBeam]>0 @battle.pbDisplay(_INTL("{1} must recharge!",pbThis)) return false end # TODO: Torment message goes here if self.ability==PBAbilities::TRUANT && @effects[PBEffects::Truant] @battle.pbDisplay(_INTL("{1} is loafing around!",pbThis)) return false end if @effects[PBEffects::Flinch] # No Inner Focus check here @battle.pbDisplay(_INTL("{1} flinched!",pbThis)) @effects[PBEffects::Flinch]=false return false end if @effects[PBEffects::Disable]>0 && thismove.id==@effects[PBEffects::DisableMove] @battle.pbDisplayPaused(_INTL("{1}'s {2} is disabled!",pbThis,thismove.name)) return false end if @effects[PBEffects::Taunt] > 0 && thismove.basedamage == 0 @battle.pbDisplayPaused(_INTL("{1} can't use {2} after the Taunt!",pbThis,thismove.name)) return false end if pbOpposing1.effects[PBEffects::Imprison] if thismove.id==pbOpposing1.moves[0].id || thismove.id==pbOpposing1.moves[1].id || thismove.id==pbOpposing1.moves[2].id || thismove.id==pbOpposing1.moves[3].id @battle.pbDisplayPaused(_INTL("{1} can't use the sealed {2}!",pbThis,thismove.name)) PBDebug.log("[#{pbOpposing1.pbThis} has: #{pbOpposing1.moves[0].id}, #{pbOpposing1.moves[1].id},#{pbOpposing1.moves[2].id} #{pbOpposing1.moves[3].id}]") return false end end if pbOpposing2.effects[PBEffects::Imprison] if thismove.id==pbOpposing2.moves[0].id || thismove.id==pbOpposing2.moves[1].id || thismove.id==pbOpposing2.moves[2].id || thismove.id==pbOpposing2.moves[3].id @battle.pbDisplayPaused(_INTL("{1} can't use the sealed {2}!",pbThis,thismove.name)) PBDebug.log("[#{pbOpposing2.pbThis} has: #{pbOpposing2.moves[0].id}, #{pbOpposing2.moves[1].id},#{pbOpposing2.moves[2].id} #{pbOpposing2.moves[3].id}]") return false end end if @effects[PBEffects::Confusion] > 0 @effects[PBEffects::Confusion]-=1 if @effects[PBEffects::Confusion]==0 @battle.pbDisplay(_INTL("{1} snapped out of confusion!",pbThis)) else @battle.pbDisplay(_INTL("{1} is confused!",pbThis)) @battle.pbCommonAnimation("Confusion",self,nil) if @battle.pbRandom(2) == 0 @battle.pbDisplay(_INTL("It hurt itself from its confusion!")) pbConfusionDamage return false end end end if self.status==PBStatuses::PARALYSIS if @battle.pbRandom(4) == 0 @battle.pbDisplay(_INTL("{1} is paralyzed! It can't move!",pbThis)) @battle.pbCommonAnimation("Paralysis",self,nil) return false end end if @effects[PBEffects::Attract]>=0 other=@battle.battlers[@effects[PBEffects::Attract]] @battle.pbDisplay(_INTL("{1} is in love with {2}!",pbThis,other.pbThis)) if @battle.pbRandom(2) == 0 @battle.pbDisplay(_INTL("{1} is immobilized by love!",pbThis)) return false end end if status==PBStatuses::FROZEN && thismove.function==0x7D # FLAME WHEEL @battle.pbDisplay(_INTL("{1} was defrosted by {2}!",pbThis,thismove.name)) status=0 end return true end def pbCancelMoves # Cancel two-turn attack # Note: Hyper Beam effect is not canceled here @effects[PBEffects::TwoTurnAttack]=0 if @effects[PBEffects::TwoTurnAttack]>0 # Cancel current move (for Thrash, etc.) @currentMove=0 @effects[PBEffects::Bide]=0 @effects[PBEffects::Outrage]=0 @effects[PBEffects::Uproar]=0 @effects[PBEffects::Rollout]=0 @effects[PBEffects::FuryCutter]=0 end def pbProcessTurn(choice) if choice[0]!=1 # Clean up effects that end at battler's turn pbBeginTurn(choice) pbEndTurn(choice) return end # turn is skipped if Pursuit was used during switch if @effects[PBEffects::Pursuit] @effects[PBEffects::Pursuit]=false pbCancelMoves pbEndTurn(choice) @battle.pbSwitch return false end ret=pbTryUseMove(choice) if !ret self.lastMoveUsed=-1 self.lastMoveCalled=-1 pbCancelMoves @battle.pbGainEXP pbEndTurn(choice) @battle.pbSwitch return false end thismove=choice[2] if !pbReducePP(thismove) @battle.pbDisplay(_INTL("{1} used\\r\\n{2}!",pbThis,thismove.name)) @battle.pbDisplay(_INTL("But there was no PP left for the move!")) self.lastMoveUsedSketch=thismove.id self.lastMoveUsed=-1 self.lastMoveCalled=-1 pbEndTurn(choice) @battle.pbSwitch return false end ret=0 # @battle.pbDisplayPaused("Before: [#{@lastMoveUsedSketch},#{@lastMoveUsed},#{@lastMoveCalled}]") PBDebug.logonerr{ ret=pbUseMove(choice) } # @battle.pbDisplayPaused("After: [#{@lastMoveUsedSketch},#{@lastMoveUsed},#{@lastMoveCalled}]") pbEndTurn(choice) @battle.pbSwitch return ret end end
PokeBattle_Move
[
Selecionar
] [
-
]
class PokeBattle_Move attr_accessor(:id) attr_reader(:name) attr_reader(:battle) attr_reader(:accuracy) attr_reader(:basedamage) attr_reader(:addlEffect) attr_reader(:type) attr_reader(:function) attr_reader(:target) attr_reader(:flags) attr_reader(:thismove) attr_accessor(:pp) attr_accessor(:totalpp) attr_reader(:priority) ################################ # Constants ################################ NOTYPE = 0x01 IGNOREPKMNTYPES = 0x02 NOWEIGHTING = 0x04 NOCRITICAL = 0x08 NOREFLECT = 0x10 ################################ def totalpp return @thismove.totalpp if @thismove end def to_int return @id end def ppzone return 3 if pp==0 # red [28,3,0], [30,27,19] return 2 if pp<=(totalpp/4).floor # orange [31,16,0],[31,29,14] return 1 if pp<=(totalpp/2).floor # yellow [26,24,0],[31,30,17] return 0 # black [9,9,9],[27,27,27] end ####################################### ####################################### def initialize(battle,move) @id=move.id @battle=battle # get data on the move movedata=PBMoveData.new(id) @function=movedata.function @basedamage=movedata.basedamage @type=movedata.type @accuracy=movedata.accuracy @pp=move.pp # can be changed with Mimic/Transform @addlEffect=movedata.addlEffect @target=movedata.target @priority=movedata.priority @flags=movedata.flags @thismove=move @category=movedata.category # get the move's name @name=PBMoves.getName(id) end USECATEGORY=true def pbIsPhysical?(type) if USECATEGORY return @category==0 else return (type<9) end end def pbIsSpecial?(type) if USECATEGORY return @category==1 else return (type>=9) end end def pbTypeModifier(type,opponent) return 4 if type<0 atype=type # attack type otype1=opponent.type1 otype2=opponent.type2 atype=atype-1 if atype>=10 otype1=otype1-1 if otype1>=10 otype2=otype2-1 if otype2>=10 mod1=PBTypes::PBTypeChart[atype*PBTypes.getCount+otype1] mod2=(otype1==otype2) ? 2 : PBTypes::PBTypeChart[atype*PBTypes.getCount+otype2] if opponent.effects[PBEffects::Foresight] mod1=2 if otype1==PBTypes::GHOST && (atype==PBTypes::NORMAL || atype==PBTypes::FIGHTING) mod2=2 if otype2==PBTypes::GHOST && (atype==PBTypes::NORMAL || atype==PBTypes::FIGHTING) end return mod1*mod2 end def pbAccuracyCheck(attacker,opponent) if (@flags&0x10)==0 # flag e: Accuracy check return true end accuracy=@accuracy stagemul=[33,36,43,50,60,75,100,133,166,200,250,266,300] #One-hit KO accuracy handled elsewhere if @battle.pbWeather==PBWeather::RAINDANCE && @id==PBMoves::THUNDER return true end if @battle.pbWeather==PBWeather::SUNNYDAY && @id==PBMoves::THUNDER accuracy=50 end evasion=opponent.effects[PBEffects::Foresight] ? 0 : opponent.stages[PBStats::EVASION] stage=attacker.stages[PBStats::ACCURACY]-evasion stage=-6 if stage<-6 stage=6 if stage>6 accuracy=(accuracy*stagemul[stage+6]/100).floor accuracy=(accuracy*1.3).floor if attacker.ability==PBAbilities::COMPOUNDEYES if @battle.pbWeather==PBWeather::SANDSTORM && opponent.ability==PBAbilities::SANDVEIL accuracy=(accuracy*4/5).floor end realtype=pbType(@type,attacker,opponent) if attacker.ability==PBAbilities::HUSTLE && pbIsPhysical?(realtype) accuracy=(accuracy*4/5).floor end if opponent.item==PBItems::BRIGHTPOWDER accuracy=(accuracy*90/100).floor end if opponent.item==PBItems::LAXINCENSE accuracy=(accuracy*95/100).floor end return 1+@battle.pbRandom(100)<accuracy end def pbTypeModMessages(type,opponent) return 4 if type<0 if opponent.ability==PBAbilities::FLASHFIRE && type==PBTypes::FIRE && opponent.status!=PBStatuses::FROZEN if !opponent.effects[PBEffects::FlashFire] @battle.pbDisplay(_INTL("{1}'s Flash Fire raised its Fire power!",opponent.pbThis)) opponent.effects[PBEffects::FlashFire]=true else @battle.pbDisplay(_INTL("{1}'s Flash Fire made {2} ineffective!",opponent.pbThis,self.name)) end return 0 end if (opponent.ability==PBAbilities::WATERABSORB && type==PBTypes::WATER)|| (opponent.ability==PBAbilities::VOLTABSORB && type==PBTypes::ELECTRIC) hpgain=(opponent.hp/4).floor hpgain=opponent.pbRecoverHP(hpgain) abilityname=PBAbilities.getName(opponent.ability) if hpgain==0 @battle.pbDisplay(_INTL("{1}'s {2} made {3} useless!",opponent.pbThis,abilityname,@name)) else @battle.pbDisplay(_INTL("{1}'s {2} restored its HP!",opponent.pbThis,abilityname)) end return 0 end typemod=pbTypeModifier(type,opponent) if typemod==0 @battle.pbDisplay(_INTL("It doesn't affect {1}...",opponent.pbThis)); end return typemod end def pbTargetsAll?(attacker) if @target==0x08 # All opposing Pokémon # TODO: should apply even if partner faints during an attack return attacker.pbOpposing1.hp>0 && attacker.pbOpposing2.hp>0 end return false end def pbIsCritical?(attacker,opponent) if opponent.ability==PBAbilities::SHELLARMOR|| opponent.ability==PBAbilities::BATTLEARMOR return false end c=0 ratios=[16,8,4,3,2] c=c+2 if attacker.effects[PBEffects::FocusEnergy] if @function==0x2B || @function==0x4B || @function==0xC8 || @function==0xD1 c=c+1 end if isConst?(attacker.species,PBSpecies,:CHANSEY) && attacker.item==PBItems::LUCKYPUNCH c=c+2 end if isConst?(attacker.species,PBSpecies,:FARFETCHD) && attacker.item==PBItems::STICK c=c+2 end c=c+1 if attacker.item==PBItems::SCOPELENS c=4 if c>4 return @battle.pbRandom(ratios[c])==0 end def pbCalcDamage(attacker,opponent,options=0) opponent.damagestate.critical=false opponent.damagestate.typemod=0 opponent.damagestate.calcdamage=0 opponent.damagestate.hplost=0 if @basedamage==0 return 0 end if (options&NOCRITICAL)==0 opponent.damagestate.critical=pbIsCritical?(attacker,opponent) end stagemul=[10,10,10,10,10,10,10,15,20,25,30,35,40] stagediv=[40,35,30,25,20,15,10,10,10,10,10,10,10] basedmg=@basedamage basedmg=pbBaseDamage(basedmg,attacker,opponent) if (options&NOTYPE)==0 type=@type type=pbType(type,attacker,opponent) else type=-1 # Will be treated as physical end atk=attacker.attack defense=opponent.defense spatk=attacker.spatk spdef=opponent.spdef #Gym Badges (internal battles only) if @battle.internalbattle # Stone Badge (index 0) if @battle.pbPlayer.badges[0] && @battle.pbOwnedByPlayer?(attacker.index) atk=(atk*1.1).floor end # Balance Badge (index 4) if @battle.pbPlayer.badges[4] && @battle.pbOwnedByPlayer?(opponent.index) defense=(defense*1.1).floor end # Mind Badge (index 6) if @battle.pbPlayer.badges[6] && @battle.pbOwnedByPlayer?(attacker.index) spatk=(spatk*1.1).floor end if @battle.pbPlayer.badges[6] && @battle.pbOwnedByPlayer?(opponent.index) spdef=(spdef*1.1).floor end end #Stat Stages atkstage=attacker.stages[PBStats::ATTACK]+6 spatkstage=attacker.stages[PBStats::SPATK]+6 defstage=opponent.stages[PBStats::DEFENSE]+6 spdefstage=opponent.stages[PBStats::SPDEF]+6 if opponent.damagestate.critical atkstage=6 if atkstage>6 spatkstage=6 if spatkstage>6 defstage=6 if defstage<6 spdefstage=6 if spdefstage<6 end atk=(atk*stagemul[atkstage]/stagediv[atkstage]).floor spatk=(spatk*stagemul[spatkstage]/stagediv[spatkstage]).floor defense=(defense*stagemul[defstage]/stagediv[defstage]).floor spdef=(spdef*stagemul[spdefstage]/stagediv[spdefstage]).floor if opponent.ability==PBAbilities::MARVELSCALE&&opponent.status>0 defense=(defense*1.5).floor end if @id==PBMoves::SELFDESTRUCT&&@id==PBMoves::EXPLOSION defense=(defense/2).floor end if isConst?(opponent.species,PBSpecies,:CLAMPERL)&&opponent.item==PBItems::DEEPSEASCALE spdef*=2 end if (isConst?(opponent.species,PBSpecies,:LATIOS)|| isConst?(opponent.species,PBSpecies,:LATIAS))&& opponent.item==PBItems::SOULDEW spdef*=2 #except in Battle Tower/Battle Frontier end if (isConst?(opponent.species,PBSpecies,:LATIOS)|| isConst?(opponent.species,PBSpecies,:LATIAS))&& attacker.item==PBItems::SOULDEW spatk*=2 #except in Battle Tower/Battle Frontier end if isConst?(opponent.species,PBSpecies,:DITTO)&&opponent.item==PBItems::METALPOWDER defense*=2 end # Type boosting items modatk=(atk*1.1).floor modspatk=(spatk*1.1).floor atk=modatk if attacker.item==PBItems::SILKSCARF && type==PBTypes::NORMAL atk=modatk if attacker.item==PBItems::BLACKBELT && type==PBTypes::FIGHTING atk=modatk if attacker.item==PBItems::SHARPBEAK && type==PBTypes::FLYING atk=modatk if attacker.item==PBItems::POISONBARB && type==PBTypes::POISON atk=modatk if attacker.item==PBItems::SOFTSAND && type==PBTypes::GROUND atk=modatk if attacker.item==PBItems::HARDSTONE && type==PBTypes::ROCK atk=modatk if attacker.item==PBItems::SILVERPOWDER && type==PBTypes::BUG atk=modatk if attacker.item==PBItems::SPELLTAG && type==PBTypes::GHOST atk=modatk if attacker.item==PBItems::METALCOAT && type==PBTypes::STEEL spatk=modspatk if attacker.item==PBItems::CHARCOAL && type==PBTypes::FIRE spatk=modspatk if attacker.item==PBItems::MYSTICWATER && type==PBTypes::WATER spatk=modspatk if attacker.item==PBItems::MIRACLESEED && type==PBTypes::GRASS spatk=modspatk if attacker.item==PBItems::MAGNET && type==PBTypes::ELECTRIC spatk=modspatk if attacker.item==PBItems::TWISTEDSPOON && type==PBTypes::PSYCHIC spatk=modspatk if attacker.item==PBItems::NEVERMELTICE && type==PBTypes::ICE spatk=modspatk if attacker.item==PBItems::DRAGONFANG && type==PBTypes::DRAGON spatk=modspatk if attacker.item==PBItems::BLACKGLASSES && type==PBTypes::DARK if attacker.item==PBItems::SEAINCENSE&&type==PBTypes::WATER spatk=(spatk*1.05).floor end atk=(atk*1.5).floor if attacker.item==PBItems::CHOICEBAND if isConst?(attacker.species,PBSpecies,:CLAMPERL)&&attacker.item==PBItems::DEEPSEATOOTH spatk*=2 end if isConst?(attacker.species,PBSpecies,:PIKACHU)&&attacker.item==PBItems::LIGHTBALL spatk*=2 end if (isConst?(attacker.species,PBSpecies,:CUBONE)|| isConst?(attacker.species,PBSpecies,:MAROWAK))&& attacker.item==PBItems::THICKCLUB atk*=2 end atk*=2 if attacker.ability==PBAbilities::HUGEPOWER atk*=2 if attacker.ability==PBAbilities::PUREPOWER atk=(atk*1.5).floor if attacker.ability==PBAbilities::HUSTLE if attacker.ability==PBAbilities::GUTS && attacker.status>0 atk=(atk*1.5).floor end if attacker.ability==PBAbilities::PLUS && @battle.pbCheckGlobalAbility(PBAbilities::MINUS) spatk=(spatk*1.5).floor end if attacker.ability==PBAbilities::MINUS && @battle.pbCheckGlobalAbility(PBAbilities::PLUS) spatk=(spatk*1.5).floor end if attacker.ability==PBAbilities::FLASHFIRE && attacker.effects[PBEffects::FlashFire] && type==PBTypes::FIRE basedmg=(basedmg*1.5).floor end if attacker.hp<=(attacker.hp/3).floor modbasedmg=(basedmg*1.5).floor basedmg=modbasedmg if attacker.ability==PBAbilities::OVERGROW&&type==PBTypes::GRASS basedmg=modbasedmg if attacker.ability==PBAbilities::BLAZE&&type==PBTypes::FIRE basedmg=modbasedmg if attacker.ability==PBAbilities::TORRENT&&type==PBTypes::WATER basedmg=modbasedmg if attacker.ability==PBAbilities::SWARM&&type==PBTypes::BUG end if type==PBTypes::ELECTRIC for i in 0..3 if @battle.battlers[i].effects[PBEffects::MudSport] basedmg=(basedmg/2).floor break #Not cumulative end end end if type==PBTypes::FIRE for i in 0..3 if @battle.battlers[i].effects[PBEffects::WaterSport] basedmg=(basedmg/2).floor break #Not cumulative end end end if opponent.ability==PBAbilities::THICKFAT && (type==PBTypes::ICE||type==PBTypes::FIRE) atk>>=1 end #Damage formula if type>=0 && pbIsSpecial?(type) atk=spatk defense=spdef end defense=1 if defense<1 atk=1 if atk<1 damage=(((2*attacker.level/5+2).floor*atk*basedmg/defense).floor/50).floor if pbTargetsAll?(attacker) damage>>=1 end #Weather weather=@battle.pbWeather if weather==PBWeather::SUNNYDAY if type==PBTypes::FIRE damage*=2 elsif type==PBTypes::WATER damage>>=1 end end if weather==PBWeather::RAINDANCE if type==PBTypes::FIRE damage>>=1 elsif type==PBTypes::WATER damage=(damage*2) end end if weather==PBWeather::SANDSTORM|| weather==PBWeather::HAIL|| weather==PBWeather::RAINDANCE if @id==PBMoves::SOLARBEAM damage>>=1 end end damage+=2 if (options&IGNOREPKMNTYPES)==0 #Same Type Attack Bonus if attacker.pbHasType?(type) damage=(damage*1.5).floor end #Type Effectiveness typemod=pbTypeModMessages(type,opponent) damage=(damage*typemod/4).floor opponent.damagestate.typemod=typemod if typemod==0 opponent.damagestate.calcdamage=0 return 0 end else opponent.damagestate.typemod=4 end damage=pbModifyDamage(damage,attacker,opponent) # Helping Hand if attacker.effects[PBEffects::HelpingHand] damage=(damage*1.5).floor end # Burns if attacker.status == PBStatuses::BURN && attacker.ability != PBAbilities::GUTS && @id != PBMoves::FACADE damage=(damage/2).floor end # Charge if attacker.effects[PBEffects::Charge] > 0&& type==PBTypes::ELECTRIC damage=(damage*1.5).floor end if !opponent.damagestate.critical && (options&NOREFLECT)==0 #Reflect oppside=opponent.pbOwnSide if oppside.effects[PBEffects::Reflect] > 0 if opponent.pbPartner.hp>0 # if opponent has a partner [TODO: should apply even if partner faints during an attack] damage=(damage*2/3).floor else damage=(damage/2).floor end end #Light Screen if oppside.effects[PBEffects::LightScreen] > 0 if opponent.pbPartner.hp>0 # if opponent has a partner [TODO: should apply even if partner faints during an attack] damage=(damage*2/3).floor else damage=(damage/2).floor end end end #Damage weighting if (options&NOWEIGHTING)==0 random=85+@battle.pbRandom(16) damage=(damage*random/100).floor end if opponent.damagestate.critical damage*=2 end damage=1 if damage<1 ########## if false if attacker.index==0 return opponent.hp end if opponent.index==0 return 0 end end ########## opponent.damagestate.calcdamage=damage return damage end def pbModifyDamage(damage,attacker,opponent) return damage end def pbReduceHPDamage(damage,attacker,opponent) endure=false if opponent.effects[PBEffects::Substitute] > 0 && (!attacker || attacker.index!=opponent.index) damage=opponent.effects[PBEffects::Substitute] if damage>opponent.effects[PBEffects::Substitute] opponent.effects[PBEffects::Substitute]-=damage opponent.damagestate.substitute=true @battle.scene.pbDamageAnimation(opponent,0) @battle.pbDisplayPaused(_INTL("The substitute took damage for {1}!",opponent.name)) if opponent.effects[PBEffects::Substitute]<=0 opponent.effects[PBEffects::Substitute]=0 @battle.pbDisplayPaused(_INTL("{1}'s substitute faded!",opponent.name)) end opponent.damagestate.hplost=damage damage=0 else if damage>=opponent.hp damage=opponent.hp if opponent.effects[PBEffects::Endure] damage=damage-1 opponent.damagestate.endured=true elsif opponent.damagestate.focusband opponent.damagestate.focusbandused=true damage=damage-1 elsif @id==PBMoves::FALSESWIPE damage=damage-1 end damage=0 if damage<0 end oldhp=opponent.hp opponent.hp-=damage effectiveness=0 if opponent.damagestate.typemod<4 effectiveness=1 # "Not very effective" elsif opponent.damagestate.typemod>4 effectiveness=2 # "Super effective" end @battle.scene.pbDamageAnimation(opponent,effectiveness) @battle.scene.pbHPChanged(opponent,oldhp) opponent.damagestate.hplost=damage end return damage end def pbEffectMessages(opponent) return if pbIsMultiHit if opponent.damagestate.critical @battle.pbDisplay(_INTL("A critical hit!")) end if opponent.damagestate.endured @battle.pbDisplay(_INTL("{1} endured the hit!",opponent.name)) elsif opponent.damagestate.focusbandused @battle.pbDisplay(_INTL("{1} hung on using its Focus Band!",opponent.name)) end if opponent.damagestate.typemod>=1&&opponent.damagestate.typemod<4 @battle.pbDisplay(_INTL("It's not very effective...")) end if opponent.damagestate.typemod>4 @battle.pbDisplay(_INTL("It's super effective!")) end end def pbEffectFixedDamage(damage,attacker,opponent) type=@type type=pbType(type,attacker,opponent) typemod=pbTypeModMessages(type,opponent) opponent.damagestate.critical=false opponent.damagestate.typemod=0 opponent.damagestate.calcdamage=0 opponent.damagestate.hplost=0 if typemod!=0 opponent.damagestate.calcdamage=damage opponent.damagestate.typemod=4 @battle.pbAnimation(@id,attacker,opponent) damage=1 if damage<1 # HP reduced can't be less than 1 damage=pbReduceHPDamage(damage,attacker,opponent) pbEffectMessages(opponent) pbOnDamageLost(damage,attacker,opponent) return damage end return 0 end def pbOnDamageLost(damage,attacker,opponent) #Used by Counter/Mirror Coat/Revenge/Focus Punch/Bide type=@type type=pbType(type,attacker,opponent) if opponent.effects[PBEffects::Bide] opponent.effects[PBEffects::BideDamage]+=damage opponent.effects[PBEffects::BideTarget]=attacker.index end type=PBTypes::NORMAL if @id==PBMoves::HIDDENPOWER if pbIsPhysical?(type) opponent.effects[PBEffects::Counter]=damage opponent.effects[PBEffects::CounterTarget]=attacker.index end if pbIsSpecial?(type) opponent.effects[PBEffects::MirrorCoat]=damage opponent.effects[PBEffects::MirrorCoatTarget]=attacker.index end opponent.lastHPLost=damage # for Revenge/Focus Punch opponent.lastAttacker=attacker.index # for Revenge end def pbSuccessCheck(attacker,opponent,numtargets) end def pbEffect(attacker,opponent) return 0 if !opponent damage=pbCalcDamage(attacker,opponent) if opponent.damagestate.typemod!=0 @battle.pbAnimation(@id,attacker,opponent) end damage=pbReduceHPDamage(damage,attacker,opponent) pbEffectMessages(opponent) pbOnDamageLost(damage,attacker,opponent) return damage #HP lost by opponent due to attack end def pbDisplayUseMessage(attacker) # Return values: # -1 if the attack should exit as a failure # 1 if the attack should exit as a success # 0 if the attack should proceed its effect @battle.pbDisplayBrief(_INTL("{1} used\\r\\n{2}!",attacker.pbThis,name)); return 0 end def pbAddTarget(targets,attacker) end def pbTwoTurnAttack(attacker) return false end def pbOnStartUse(attacker) return true end def pbType(type,attacker,opponent) return type end def pbBaseDamage(basedmg,attacker,opponent) return basedmg end def pbNumHits return 1 end def pbMoveFailed(attacker,opponent) # Called to determine whether the move failed return false end def pbIsMultiHit #not the same as pbNumHits>1 return false end def pbAdditionalEffect(attacker,opponent) end def pbAdditionalEffect2(attacker,opponent) end =begin Generates a PokeBattle_Move object based on the move's ID =end def PokeBattle_Move.pbFromPBMove(battle,move) move=PBMove.new(0) if !move movedata=PBMoveData.new(move.id) return eval(sprintf("PokeBattle_Move_%02X.new(battle,move)",movedata.function)) end end
PokeBattle_Pokemon
[
Selecionar
] [
-
]
=begin This class stores data on each Pokémon. Refer to $Trainer.party for an array of each Pokémon in the Trainer's current party. =end def nextUtf8(str,index) utf8tbl = [ [0x00,0x7F,0 ,0 ,0x7F,0], [0xC2,0xDF,0x80,0xBF,0x1F,1], [0xE0,0xE0,0xA0,0xBF,0x0F,2], [0xE1,0xEF,0x80,0xBF,0x0F,2], [0xF0,0xF0,0x90,0xBF,0x07,3], [0xF1,0xF3,0x80,0xBF,0x07,3], [0xF4,0xF4,0x80,0x8F,0x07,3], [0 ,0 ,0 ,0 ,0 ,0] ] length=str.length if index==length return -1 end b1=str[index] index+=1 return b1 if b1<0x80 row=0 ret=0 while (utf8tbl[row][4]&&((b1<utf8tbl[row][0])||(b1>utf8tbl[row][1]))) row+=1 end utfrow=utf8tbl[row] if utfrow[4]==0 return -1 end ret=(b1&utfrow[4]) if utfrow[5]==0 return ret end trail=str[index,utfrow[5]] index+=utfrow[5] if trail.length!=utfrow[5] return -1 end utfrow[5].times do |i| tbyte=trail[i] if i==0 if(tbyte<utfrow[2]||tbyte>utfrow[3]) return -1 end else if(tbyte<0x80||tbyte>0xBF) return -1 end end ret=(ret<<6)|(tbyte&0x3F) end return ret end class PokeBattle_Pokemon attr_reader(:totalhp) # Total HP attr_reader(:attack) # Current Attack stat attr_reader(:defense) # Current Defense stat attr_reader(:speed) # Current Speed stat attr_reader(:spatk) # Current Special Attack stat attr_reader(:spdef) # Current Special Defense stat attr_accessor(:iv) # Individual Values attr_accessor(:species) # Species attr_accessor(:personalID) # Personal ID attr_accessor(:abilityflag) # Ability flag attr_accessor(:trainerID) # Trainer ID attr_accessor(:hp) # Current HP attr_accessor(:pokerus) # Three states: Not infected, infected, cured attr_accessor(:pokerusTime) # Time infected by Pokerus attr_accessor(:item) # Held item attr_accessor(:ot) # Original Trainer name attr_accessor(:name) # Nickname attr_accessor(:exp) # Current experience points attr_accessor(:happiness) # Current happiness attr_accessor(:status) # Status problem (PBStatuses) attr_accessor(:statusCount) # Sleep count/Toxic flag attr_accessor(:ev) # Effort Values attr_accessor(:eggsteps) # Steps to hatch egg, 0 if Pokémon is not an egg attr_accessor(:moves) # Moves (PBMove) attr_accessor(:ballused) # Ball used attr_accessor(:mail) # Mail def nature return @personalID%25 end def unownShape d=@personalID&3 d|=((@personalID>>8)&3)<<2 d|=((@personalID>>16)&3)<<4 d|=((@personalID>>24)&3)<<6 return "ABCDEFGHIJKLMNOPQRSTUVWXYZ!?"[d%28,1] end def pbToInternal(idx) return idx if idx<=251 || idx>386 idx-=252 indexes=[ 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 304, 305, 309, 310, 392, 393, 394, 311, 312, 306, 307, 364, 365, 366, 301, 302, 303, 370, 371, 372, 335, 336, 350, 320, 315, 316, 322, 355, 382, 383, 384, 356, 357, 337, 338, 353, 354, 386, 387, 363, 367, 368, 330, 331, 313, 314, 339, 340, 321, 351, 352, 308, 332, 333, 334, 344, 345, 358, 359, 380, 379, 348, 349, 323, 324, 326, 327, 318, 319, 388, 389, 390, 391, 328, 329, 385, 317, 377, 378, 361, 362, 369, 411, 376, 360, 346, 347, 341, 342, 343, 373, 374, 375, 381, 325, 395, 396, 397, 398, 399, 400, 401, 402, 403, 407, 408, 404, 405, 406, 409, 410 ] return indexes[idx] end def getBytes ret=[@personalID,@trainerID].pack("V*") namechars=@name.scan(/./m) otchars=@ot.scan(/./m) for i in 0...10 ret+=(i>=namechars.length) ? 0xFF.chr : toRSChar(namechars[i]) end ret+=[2,2].pack("CC") # Font, sanity byte for i in 0...7 ret+=(i>=otchars.length) ? 0xFF.chr : toRSChar(otchars[i]) end ret+=[0].pack("C") # Markings structA=[pbToInternal(@species),@item,@exp, @moves[0].ppup|(@moves[1].ppup<<2)|(@moves[2].ppup<<4)|(@moves[3].ppup<<6), @eggsteps==0 ? @happiness : (@eggsteps>>8),0,0].pack("vvVCCCC") structB=[ @moves[0].id,@moves[1].id,@moves[2].id,@moves[3].id, @moves[0].pp,@moves[1].pp,@moves[2].pp,@moves[3].pp ].pack("vvvvCCCC") structC=[ @ev[0],@ev[1],@ev[2],@ev[3],@ev[4],@ev[5], 0,0,0,0,0,0 ].pack("C*") iv=@iv[0]|(@iv[1]<<5)|(@iv[2]<<10)|(@iv[3]<<15)|(@iv[4]<<20)|(@iv[5]<<25) iv|=0x80000000 if @abilityflag==1 iv|=0x40000000 if @eggsteps>0 pokerus=[0,1,0x10][@pokerus] fromballused= [0,3,5,2,1,6,7,8,9,10,11,12] ballused=@ballused && @ballused<fromballused.length ? fromballused[@ballused] : 0 structD=[ pokerus,0,0,ballused<<3,iv,0 ].pack("CCCCVV") structs=[structA,structB,structC,structD] ordering=[ 0,1,2,3,0,1,3,2,0,2,1,3,0,2,3,1,0,3,1,2,0,3,2,1, 1,0,2,3,1,0,3,2,1,2,0,3,1,2,3,0,1,3,0,2,1,3,2,0, 2,0,1,3,2,0,3,1,2,1,0,3,2,1,3,0,2,3,0,1,2,3,1,0, 3,0,1,2,3,0,2,1,3,1,0,2,3,1,2,0,3,2,0,1,3,2,1,0 ] o=@personalID%24 neworder=[ structs[ordering[o*4]], structs[ordering[o*4+1]], structs[ordering[o*4+2]], structs[ordering[o*4+3]] ] checksum=0 xor=@personalID^@trainerID for i in 0...4 struct=neworder[i].unpack("v*") for j in 0...6 checksum+=struct[j] checksum&=0xFFFF end struct2=neworder[i].unpack("V*") for j in 0...3 struct2[j]^=xor end neworder[i]=struct2.pack("V*") end ret+=[checksum,0].pack("vv") ret+=neworder[0] ret+=neworder[1] ret+=neworder[2] ret+=neworder[3] return ret end def genCodes(file) words=getBytes.unpack("V*") offset=0x20300a4 File.open(file,"wb"){|f| for word in words f.write(sprintf("%08X:%08X\\r\\n",offset,word)) offset+=4 end } end def ability abil=@abilityflag ? @abilityflag : 0 dexdata=pbOpenDexData pbDexDataOffset(dexdata,@species,29) ret1=dexdata.fgetb ret2=dexdata.fgetb ret=ret1 if abil==1 ret=ret2 if ret2==0 @abilityflag=0 ret=ret1 end end dexdata.close return ret end def gender dexdata=pbOpenDexData pbDexDataOffset(dexdata,@species,18) genderbyte=dexdata.fgetb dexdata.close case genderbyte when 255 return 2 # genderless when 254 return 1 # always female else lowbyte=@personalID&0xFF return (lowbyte<genderbyte) ? 1 : 0 end end def setGender(female) dexdata=pbOpenDexData pbDexDataOffset(dexdata,@species,18) genderbyte=dexdata.fgetb dexdata.close case genderbyte when 255 return false # genderless when 254 return female # always female when 0 return !female # always male else lowbyte=@personalID&0xFF return true if (lowbyte<genderbyte)==female loop do value=rand(256) if female==(value<genderbyte) @personalID&=~0xFF @personalID|=value calcStats return true end end end end def level=(value) if value<1 || value>PBExperience::MAXLEVEL raise ArgumentError.new(_INTL("The level number ({1}) is invalid.",value)) end @exp=PBExperience.pbGetStartExperience(value,self.growthrate) end def level return PBExperience.pbGetLevelFromExperience(@exp,self.growthrate) end def egg? return @eggsteps>0 end def isForeign?(trainer) return @trainerID!=trainer.id || @ot!=trainer.name end def isShiny? a=@personalID^@trainerID b=a&0xFFFF c=(a>>16)&0xFFFF d=b^c return (d<8) end def makeShiny rnd=rand(65536) rnd|=(rnd<<16) rnd|=rand(8) @personalID=rnd^@trainerID calcStats end def calcHP(base,level,iv,ev) return 1 if base==1 return ((base*2+iv+(ev>>2)).floor*level/100).floor+level+10 end def calcStat(base,level,iv,ev,pv) return ((((base*2+iv+(ev>>2))*level/100).floor+5)*pv/100).floor end def growthrate dexdata=pbOpenDexData pbDexDataOffset(dexdata,@species,20) ret=dexdata.fgetb dexdata.close return ret end def type1 dexdata=pbOpenDexData pbDexDataOffset(dexdata,@species,8) ret=dexdata.fgetb dexdata.close return ret end def type2 dexdata=pbOpenDexData pbDexDataOffset(dexdata,@species,9) ret=dexdata.fgetb dexdata.close return ret end def heal return if egg? @hp=@totalhp @status=0 @statusCount=0 for i in 0..3 @moves[i].pp=@moves[i].totalpp end end def calcStats nature=self.nature stats=[] pvalues=[100,100,100,100,100] nd5=(nature/5).floor nm5=(nature%5).floor if nd5!=nm5 pvalues[nd5]=110 pvalues[nm5]=90 end dexdata=pbOpenDexData level=self.level pbDexDataOffset(dexdata,@species,10) for i in 0..5 base=dexdata.fgetb if i==0 stats[i]=calcHP(base,level,@iv[i],@ev[i]) else stats[i]=calcStat(base,level,@iv[i],@ev[i],pvalues[i-1]) end end dexdata.close diff=@totalhp-@hp @totalhp=stats[0] if @hp>0 @hp=@totalhp-diff @hp=1 if @hp<=0 @hp=@totalhp if @hp>@totalhp end @attack=stats[1] @defense=stats[2] @speed=stats[3] @spatk=stats[4] @spdef=stats[5] end def initialize(species,level,player=nil) @ev=[0,0,0,0,0,0] if species<1||species>PBSpecies.getCount raise ArgumentError.new(_INTL("The species number (no. {1} of {2}) is invalid.", species,PBSpecies.getCount)) return nil end @species=species # Individual Values @hp=1 @totalhp=1 @iv=[] @abilityflag=rand(2) self.level=level dexdata=pbOpenDexData pbDexDataOffset(dexdata,@species,19) @happiness=dexdata.fgetb pbDexDataOffset(dexdata,@species,29) ability1=dexdata.fgetb ability2=dexdata.fgetb dexdata.close @iv[0]=rand(32) @iv[1]=rand(32) @iv[2]=rand(32) @iv[3]=rand(32) @iv[4]=rand(32) @iv[5]=rand(32) @personalID=rand(256) @personalID|=rand(256)<<8 @personalID|=rand(256)<<16 @personalID|=rand(256)<<24 @name=PBSpecies.getName(@species) calcStats @hp=@totalhp @eggsteps=0 @status=0 @statusCount=0 @item=0 @pokerusTime=0 @ballused=0 atkdata=pbRgssOpen("Data/attacksRS.dat","rb") offset=atkdata.getOffset(species-1) length=atkdata.getLength(species-1)>>1 atkdata.pos=offset # Generating move list movelist=[] for i in 0..length-1 alevel=atkdata.fgetw move=atkdata.fgetw if alevel<=level movelist[movelist.length]=move end end atkdata.close movelist|=[] # Remove duplicates # Use the last 4 items in the move list listend=movelist.length-4 listend=0 if listend<0 j=0 @pokerus=0 @mail=nil @moves=[] for i in listend..listend+3 moveid=(i>=movelist.length) ? 0 : movelist[i] @moves[j]=PBMove.new(moveid) j+=1 end if player @trainerID=player.id @ot=player.name else @trainerID=0 @ot="" end end end
PokeBattle_ActualScene
[
Selecionar
] [
-
]
=begin - def pbChooseNewEnemy(index,party) Use this method to choose a new Pokémon for the enemy The enemy's party is guaranteed to have at least one choosable member. index - Index to the battler to be replaced (use e.g. @battle.battlers[index] to access the battler) party - Enemy's party - def pbWildBattleSuccess This method is called when the player wins a wild Pokémon battle. This method can change the battle's music for example. - def pbTrainerBattleSuccess This method is called when the player wins a Trainer battle. This method can change the battle's music for example. - def pbFainted(pkmn) This method is called whenever a Pokémon faints. pkmn - PokeBattle_Battler object indicating the Pokémon that fainted - def pbChooseEnemyCommand(index) Use this method to choose a command for the enemy. index - Index of enemy battler (use e.g. @battle.battlers[index] to access the battler) - def pbCommandMenu(index) Use this method to display the list of commands and choose a command for the player. index - Index of battler (use e.g. @battle.battlers[index] to access the battler) Return values: 0 - Fight 1 - Pokémon 2 - Bag 3 - Run =end ################################################ class Window_CommandMenuInner < SpriteWindow_Base attr_reader :index def index=(value) @index=value refresh end def setTexts(value) @choice1=value[1] @choice2=value[2] @choice3=value[3] @choice4=value[4] refresh end def initialize super(Graphics.width-240,Graphics.height-96,240,96) self.contents=Bitmap.new(self.width-32,self.height-32) pbSetSystemFont(self.contents) @choice1="" @choice2="" @choice3="" @choice4="" @selarrow=BitmapCache.load_bitmap("Graphics/Pictures/selarrow.png") @index=0 @menuBaseColor=PokeBattle_Scene::MENUBASECOLOR @menuShadowColor=PokeBattle_Scene::MENUSHADOWCOLOR refresh end def dispose @selarrow.dispose super end def refresh self.contents.clear pbCopyBitmap(self.contents,@selarrow,4,0) if @index==0 pbCopyBitmap(self.contents,@selarrow,116,0) if @index==1 pbCopyBitmap(self.contents,@selarrow,4,32) if @index==2 pbCopyBitmap(self.contents,@selarrow,116,32) if @index==3 self.contents.font.color=@menuShadowColor pbDrawShadow(self.contents,20,0,96,32,@choice1) pbDrawShadow(self.contents,20,32,96,32,@choice2) pbDrawShadow(self.contents,132,0,96,32,@choice3) pbDrawShadow(self.contents,132,32,96,32,@choice4) self.contents.font.color=@menuBaseColor self.contents.draw_text(20,0,96,32,@choice1) self.contents.draw_text(20,32,96,32,@choice2) self.contents.draw_text(132,0,96,32,@choice3) self.contents.draw_text(132,32,96,32,@choice4) end end class TwoColumnWindow < SpriteWindow_Base attr_reader :index def index=(value) @index=value refresh end def setChoices(array) @choices[0]=array[0] @choices[1]=array[1] @choices[2]=array[2] @choices[3]=array[3] refresh end def initialize(x,y,width,height,viewport=nil) super(x,y,width,height) self.viewport=viewport @choices=["","","",""] self.contents=Bitmap.new(self.width-32,self.height-32) pbSetNarrowFont(self.contents) @selarrow=BitmapCache.load_bitmap("Graphics/Pictures/selarrow.png") @index=0 @menuBaseColor=PokeBattle_Scene::MENUBASECOLOR @menuShadowColor=PokeBattle_Scene::MENUSHADOWCOLOR refresh end def dispose @selarrow.dispose super end def refresh self.contents.clear pbCopyBitmap(self.contents,@selarrow,0,0) if @index==0 pbCopyBitmap(self.contents,@selarrow,144,0) if @index==1 pbCopyBitmap(self.contents,@selarrow,0,32) if @index==2 pbCopyBitmap(self.contents,@selarrow,144,32) if @index==3 self.contents.font.color=@menuShadowColor pbDrawShadow(self.contents,16,0,128,32,@choices[0]) pbDrawShadow(self.contents,160,0,128,32,@choices[1]) pbDrawShadow(self.contents,16,32,128,32,@choices[2]) pbDrawShadow(self.contents,160,32,128,32,@choices[3]) self.contents.font.color=@menuBaseColor self.contents.draw_text(16,0,128,32,@choices[0]) self.contents.draw_text(160,0,128,32,@choices[1]) self.contents.draw_text(16,32,128,32,@choices[2]) self.contents.draw_text(160,32,128,32,@choices[3]) end end class CommandMenuDisplay def initialize(viewport=nil) @display=nil if PokeBattle_Scene::USECOMMANDBOX @display=Sprite.new(viewport) @display.bitmap=BitmapCache.load_bitmap("Graphics/Pictures/commandbox.png") @display.x=0 @display.y=Graphics.height-96 end @window=Window_CommandMenuInner.new @window.viewport=viewport @msgbox=Window_UnformattedTextPokemon.newWithSize( "",4,Graphics.height-96, Graphics.width-@window.width-4, 96,viewport) @msgbox.baseColor=PokeBattle_Scene::MESSAGEBASECOLOR @msgbox.shadowColor=PokeBattle_Scene::MESSAGESHADOWCOLOR @msgbox.windowskin=nil if PokeBattle_Scene::USECOMMANDBOX @window.opacity=0 end @title="" end def index; @window.index; end def index=(value); @window.index=value; end def setTexts(value) @msgbox.text=value[0] @window.setTexts(value) end def visible; @window.visible; end def visible=(value) @window.visible=value @msgbox.visible=value @display.visible=value if @display end def x; @window.x; end def x=(value) @window.x=value @msgbox.x=value @display.x=value if @display end def y; @window.y; end def y=(value) @window.y=value @msgbox.y=value @display.y=value if @display end def oy; @window.oy; end def oy=(value) @window.oy=value @msgbox.oy=value @display.oy=value if @display end def color; @window.color; end def color=(value) @window.color=value @msgbox.color=value @display.color=value if @display end def ox; @window.ox; end def ox=(value) @window.ox=value @msgbox.ox=value @display.ox=value if @display end def z; @window.z; end def z=(value) @window.z=value @msgbox.z=value @display.z=value if @display end def disposed? return @msgbox.disposed? || @window.disposed? end def dispose return if disposed? @msgbox.dispose @window.dispose @display.dispose if @display @display.bitmap.dispose if @display && @display.bitmap end def update @msgbox.update @window.update @display.update if @display end def refresh @msgbox.refresh @window.refresh end end class FightMenuDisplay attr_reader :battler attr_reader :index def battler=(value) @battler=value refresh end def setIndex(value) if @battler && @battler.moves[value].id!=0 @index=value @window.index=value refresh end end def visible; @window.visible; end def visible=(value) @window.visible=value @info.visible=value @display.visible=value if @display end def x; @window.x; end def x=(value) @window.x=value @info.x=value @display.x=value if @display end def y; @window.y; end def y=(value) @window.y=value @info.y=value @display.y=value if @display end def oy; @window.oy; end def oy=(value) @window.oy=value @info.oy=value @display.oy=value if @display end def color; @window.color; end def color=(value) @window.color=value @info.color=value @display.color=value if @display end def ox; @window.ox; end def ox=(value) @window.ox=value @info.ox=value @display.ox=value if @display end def z; @window.z; end def z=(value) @window.z=value @info.z=value @display.z=value if @display end def disposed? return @info.disposed? || @window.disposed? end def dispose return if disposed? @info.dispose @display.dispose if @display @display.bitmap.dispose if @display && @display.bitmap @window.dispose end def update @info.update @window.update @display.update if @display end def initialize(battler,viewport=nil) @display=nil if PokeBattle_Scene::USEFIGHTBOX @display=Sprite.new(viewport) @display.bitmap=BitmapCache.load_bitmap("Graphics/Pictures/fightbox.png") @display.x=0 @display.y=Graphics.height-96 end @window=TwoColumnWindow.new(0,Graphics.height-96,320,96,viewport) @info=Window_AdvancedTextPokemon.newWithSize( "",320,Graphics.height-96,Graphics.width-320,96,viewport) @ctag=shadowctag(PokeBattle_Scene::MENUBASECOLOR, PokeBattle_Scene::MENUSHADOWCOLOR) if PokeBattle_Scene::USEFIGHTBOX @window.opacity=0 @info.opacity=0 end @battler=battler @index=0 refresh end def refresh return if !@battler @window.setChoices([ @battler.moves[0].name, @battler.moves[1].name, @battler.moves[2].name, @battler.moves[3].name ]) selmove=@battler.moves[@index] movetype=PBTypes.getName(selmove.type) pbSetNarrowFont(@info.contents) @info.text=_ISPRINTF("{1:s}PP: {2: 2d}/{3: 2d}<br>TYPE/{4:s}", @ctag,selmove.pp,selmove.totalpp,movetype) end end def pbSpriteSetCenter(sprite,cx,cy) if !sprite.bitmap sprite.x=cx sprite.y=cy return end realwidth=sprite.bitmap.width*sprite.zoom_x realheight=sprite.bitmap.height*sprite.zoom_y sprite.x=cx-(realwidth/2) sprite.y=cy-(realheight/2) end class PokemonSprite < RPG::Sprite attr_accessor :selected def initialize(doublebattle,index,viewport=nil) super(viewport) @selected=0 @frame=0 @index=index @updating=false @doublebattle=doublebattle @index=index @spriteX=0 @spriteY=0 @spriteVisible=false self.bitmap=nil self.visible=false end def visible=(value) @spriteVisible=value if !@updating super end def x=(value) @spriteX=value if !@updating super end def y=(value) @spriteY=value if !@updating super end def update @frame+=1 @updating=true if ((@frame/9).floor&1)==1 && @selected==1 # When choosing commands for this Pokémon self.x=@spriteX self.y=@spriteY+2 self.visible=@spriteVisible elsif @selected==2 # When targeted or damaged self.x=@spriteX self.y=@spriteY self.visible=(@frame%10<7) elsif self.x=@spriteX self.y=@spriteY self.visible=@spriteVisible end @updating=false end end class SafariDataBox < SpriteWrapper attr_accessor :selected attr_reader :appearing def initialize(battle,viewport=nil) super(viewport) @selected=0 @battle=battle @databox=BitmapCache.load_bitmap("Graphics/Pictures/safariPlayerBox.png") @spriteX=254 @spriteY=148+(Graphics.height-320) @spritebaseY=0 @spritebaseX=16 @appearing=false @contents=Bitmap.new(@databox.width,@databox.height) self.bitmap=@contents self.visible=false self.z=2 refresh end def appear refresh self.visible=true self.opacity=255 self.x=@spriteX+320 self.y=@spriteY @appearing=true end def refresh self.bitmap.clear self.bitmap.blt(0,0,@databox,Rect.new(0,0,@databox.width,@databox.height)) pbSetSmallFont(self.bitmap) textpos=[] base=PokeBattle_Scene::BOXTEXTBASECOLOR shadow=PokeBattle_Scene::BOXTEXTSHADOWCOLOR textpos.push([_INTL("SAFARI BALLS"),@spritebaseX+14,@spritebaseY+6,false,base,shadow]) textpos.push([_INTL("Left: {1}",@battle.ballcount),@spritebaseX+170,@spritebaseY+40, true,base,shadow]) pbDrawTextPositions(self.bitmap,textpos) end def update super if @appearing self.x-=8 @appearing=false if self.x<=@spriteX self.y=@spriteY return end self.x=@spriteX self.y=@spriteY end end class PokemonDataBox < SpriteWrapper attr_reader :battler attr_accessor :selected attr_accessor :appearing attr_reader :animatingHP attr_reader :animatingEXP def initialize(battler,doublebattle,viewport=nil) super(viewport) @explevel=0 @battler=battler @spritebaseY=0 @selected=0 @frame=0 @showhp=false @showexp=false @appearing=false @animatingHP=false @currenthp=0 @endhp=0 @expflash=0 @statusCX=64 @statusY=28 if (@battler.index&1)==0 # if player's Pokémon @spritebaseX=16 else @spritebaseX=0 end yoffset=(Graphics.height-320) if doublebattle case @battler.index when 0 @databox=BitmapCache.load_bitmap("Graphics/Pictures/doublePlayerBox.png") @spriteX=256 @spriteY=124+yoffset when 1 @databox=BitmapCache.load_bitmap("Graphics/Pictures/doubleEnemyBox.png") @spriteX=26 @spriteY=10+yoffset @spritebaseX=0 @spritebaseY=0 when 2 @databox=BitmapCache.load_bitmap("Graphics/Pictures/doublePlayerBox.png") @spriteX=280 @spriteY=174+yoffset when 3 @databox=BitmapCache.load_bitmap("Graphics/Pictures/doubleEnemyBox.png") @spriteX=2 @spriteY=60+yoffset end else case @battler.index when 0 @databox=BitmapCache.load_bitmap("Graphics/Pictures/singlePlayerBox.png") @spriteX=254 @spriteY=148+yoffset @showhp=true @showexp=true @statusCX=40 @statusY=44 when 1 @databox=BitmapCache.load_bitmap("Graphics/Pictures/singleEnemyBox.png") @spriteX=26 @spriteY=32+yoffset end end @statuses=BitmapCache.load_bitmap(_INTL("Graphics/Pictures/boxstatuses.png")) @contents=Bitmap.new(@databox.width,@databox.height) self.bitmap=@contents self.visible=false self.z=2 refreshExpLevel refresh end def dispose @statuses.dispose @databox.dispose @contents.dispose super end def refreshExpLevel if !@battler.pokemon @explevel=0 else growthrate=@battler.pokemon.growthrate startexp=PBExperience.pbGetStartExperience(@battler.pokemon.level,growthrate) endexp=PBExperience.pbGetStartExperience(@battler.pokemon.level+1,growthrate) if startexp==endexp @explevel=0 else @explevel=(@battler.pokemon.exp-startexp)*PokeBattle_Scene::EXPGAUGESIZE/(endexp-startexp) end end end def exp return @animatingEXP ? @currentexp : @explevel end def hp return @animatingHP ? @currenthp : @battler.hp end def animateHP(oldhp,newhp) @currenthp=oldhp @endhp=newhp @animatingHP=true end def animateEXP(oldexp,newexp) @currentexp=oldexp @endexp=newexp @animatingEXP=true end def appear refreshExpLevel refresh self.visible=true self.opacity=255 if (@battler.index&1)==0 # if player's Pokémon self.x=@spriteX+320 else self.x=@spriteX-320 end self.y=@spriteY @appearing=true end def refresh self.bitmap.clear return if !@battler.pokemon self.bitmap.blt(0,0,@databox,Rect.new(0,0,@databox.width,@databox.height)) pbSetSmallFont(self.bitmap) hpstring=_ISPRINTF("{1: 2d}/{2: 2d}",self.hp,@battler.totalhp) textpos=[] base=PokeBattle_Scene::BOXTEXTBASECOLOR shadow=PokeBattle_Scene::BOXTEXTSHADOWCOLOR genderX=self.bitmap.text_size(@battler.name).width genderX+=@spritebaseX+14 textpos.push([@battler.name,@spritebaseX+14,@spritebaseY+6,false,base,shadow]) if @battler.gender==0 # Male textpos.push([_INTL("♂"),genderX,@spritebaseY+6,false,Color.new(8*8,25*8,31*8),shadow]) elsif @battler.gender==1 # Female textpos.push([_INTL("♀"),genderX,@spritebaseY+6,false,Color.new(31*8,19*8,18*8),shadow]) end textpos.push([_INTL("Lv{1}",@battler.level),@spritebaseX+170,@spritebaseY+6,true,base,shadow]) if @showhp textpos.push([hpstring,@spritebaseX+170,@spritebaseY+40,true,base,shadow]) end pbDrawTextPositions(self.bitmap,textpos) if @battler.status>0 self.bitmap.blt(@spritebaseX+14,@spritebaseY+@statusY,@statuses, Rect.new(0,(@battler.status-1)*16,@statusCX,16)) end hpGaugeSize=PokeBattle_Scene::HPGAUGESIZE hpgauge=@battler.totalhp==0 ? 0 : (self.hp*hpGaugeSize/@battler.totalhp) hpgauge=1 if hpgauge==0 && self.hp>0 hpzone=0 hpzone=1 if self.hp<=(@battler.totalhp/2).floor hpzone=2 if self.hp<=(@battler.totalhp/4).floor hpcolors=[ PokeBattle_Scene::HPCOLORSHADOW1, PokeBattle_Scene::HPCOLORBASE1, PokeBattle_Scene::HPCOLORSHADOW2, PokeBattle_Scene::HPCOLORBASE2, PokeBattle_Scene::HPCOLORSHADOW3, PokeBattle_Scene::HPCOLORBASE3 ] # fill with HP color hpGaugeX=PokeBattle_Scene::HPGAUGE_X hpGaugeY=PokeBattle_Scene::HPGAUGE_Y expGaugeX=PokeBattle_Scene::EXPGAUGE_X expGaugeY=PokeBattle_Scene::EXPGAUGE_Y self.bitmap.fill_rect(@spritebaseX+hpGaugeX,@spritebaseY+hpGaugeY,hpgauge,2,hpcolors[hpzone*2]) self.bitmap.fill_rect(@spritebaseX+hpGaugeX,@spritebaseY+hpGaugeY+2,hpgauge,2,hpcolors[hpzone*2+1]) # fill with black self.bitmap.fill_rect(@spritebaseX+hpGaugeX+hpgauge,@spritebaseY+hpGaugeY,hpGaugeSize-hpgauge,2,PokeBattle_Scene::HPCOLORSHADOW4) self.bitmap.fill_rect(@spritebaseX+hpGaugeX+hpgauge,@spritebaseY+hpGaugeY+2,hpGaugeSize-hpgauge,2,PokeBattle_Scene::HPCOLORBASE4) if @showexp # fill with EXP color self.bitmap.fill_rect(@spritebaseX+expGaugeX,@spritebaseY+expGaugeY,self.exp,4,PokeBattle_Scene::EXPCOLOR) end end def update super @frame+=1 if @animatingHP if @currenthp<@endhp @currenthp+=1 elsif @currenthp>@endhp @currenthp-=1 end refresh @animatingHP=false if @currenthp==@endhp end if @animatingEXP if !@showexp @currentexp=@endexp elsif @currentexp<@endexp @currentexp+=1 elsif @currentexp>@endexp @currentexp-=1 end refresh if @currentexp==@endexp if @currentexp==PokeBattle_Scene::EXPGAUGESIZE if @expflash==0 Audio.se_play("Audio/SE/expfull.wav") self.flash(Color.new(64,200,248),8) @expflash=8 else @expflash-=1 if @expflash==0 @animatingEXP=false refreshExpLevel end end else @animatingEXP=false end end end if @appearing if (@battler.index&1)==0 # if player's Pokémon self.x-=8 @appearing=false if self.x<=@spriteX else self.x+=8 @appearing=false if self.x>=@spriteX end self.y=@spriteY return end if ((@frame/10).floor&1)==1 && @selected==1 # When choosing commands for this Pokémon self.x=@spriteX self.y=@spriteY+2 elsif ((@frame/5).floor&1)==1 && @selected==2 # When targeted or damaged self.x=@spriteX self.y=@spriteY+2 else self.x=@spriteX self.y=@spriteY end end end class PokeballSendOutAnimation SPRITESTEPS=10 STARTZOOM=0.125 def initialize(sprite,spritehash,pkmn,doublebattle) @disposed=false @pokeballopen=BitmapCache.load_bitmap("Graphics/Pictures/pokeballopen.png") @pokeballclosed=BitmapCache.load_bitmap("Graphics/Pictures/pokeball.png") @pokemonsprite=sprite @pokemonsprite.visible=false @pokemonsprite.color=Color.new(31*8,22*8,30*8) @pokeballsprite=Sprite.new(sprite.viewport) if doublebattle @spritex=pkmn.index==1 ? 400 : 304 @spritey=pkmn.index==1 ? 96+24 : 96+24 else @spritex=344 @spritey=112 end @spritey+=(Graphics.height-320) @spritehash=spritehash @pokeballsprite.x=@spritex-8 @pokeballsprite.y=@spritey-8 @pkmn=pkmn metrics=load_data("Data/metrics.dat") factor=metrics[1][pkmn.species] # enemy Y factor-=metrics[2][pkmn.species] # altitude (affects shadows) halfY=(sprite.bitmap && !sprite.bitmap.disposed?) ? sprite.bitmap.height/2 : 64 @endspritey=factor*2+halfY # from center @endspritey+=(Graphics.height-320) @shadowY=@spritey+16 # from top @shadowX=@spritex+32 # from left @endspritey+=16 if !doublebattle @endspritey+=16 if doublebattle && pkmn.index==1 @stepspritey=(@spritey-@endspritey) @zoomstep=(1.0-STARTZOOM)/SPRITESTEPS @pokeballsprite.bitmap=@pokeballclosed @animdone=false @frame=0 end def disposed? return @disposed end def animdone? return @animdone end def dispose return if disposed? @pokeballclosed.dispose @pokeballopen.dispose @pokeballsprite.dispose @disposed=true end def update return if disposed? @frame+=1 if @frame==2 Audio.se_play("Audio/SE/recall.wav") @pokeballsprite.bitmap=@pokeballopen end if @frame==4 @pokemonsprite.visible=true @pokemonsprite.zoom_x=STARTZOOM @pokemonsprite.zoom_y=STARTZOOM pbSpriteSetCenter(@pokemonsprite,@spritex,@spritey) pbPlayCry(@pkmn.pokemon ? @pkmn.pokemon : @pkmn.species) end if @frame==8 @pokeballsprite.visible=false end if @frame>8 && @frame<=16 color=Color.new(248,248,248,256-(16-@frame)*32) @spritehash["enemybase"].color=color @spritehash["playerbase"].color=color @spritehash["battlebg"].color=color end if @frame>16 && @frame<=24 color=Color.new(248,248,248,(24-@frame)*32) @pokemonsprite.color.alpha=(24-@frame)*32 @spritehash["enemybase"].color=color @spritehash["playerbase"].color=color @spritehash["battlebg"].color=color end if @frame>5 && @pokemonsprite.zoom_x<1.0 @pokemonsprite.zoom_x+=@zoomstep @pokemonsprite.zoom_y+=@zoomstep @pokemonsprite.zoom_x=1.0 if @pokemonsprite.zoom_x > 1.0 @pokemonsprite.zoom_y=1.0 if @pokemonsprite.zoom_y > 1.0 currentY=@spritey-(@stepspritey*@pokemonsprite.zoom_y) pbSpriteSetCenter(@pokemonsprite,@spritex,currentY) end if @pokemonsprite.color.alpha<=0 && @pokemonsprite.zoom_x>=1.0 @animdone=true end end end def pokeballThrow(ball,shakes,targetBattler) balltype=@battle.pbGetBallType(ball) ball0=sprintf("Graphics/Pictures/ball%02d_0.png",balltype) ball1=sprintf("Graphics/Pictures/ball%02d_1.png",balltype) ball2=sprintf("Graphics/Pictures/ball%02d_2.png",balltype) # sprites spriteBall=IconSprite.new(0,0,@viewport) spriteBall.visible=false spritePoke=@sprites["pokemon#{targetBattler}"] # pictures pictureBall=PictureEx.new(0) picturePoke=PictureEx.new(0) pokeball=[360,32] dims=[spritePoke.x,spritePoke.y] center=getSpriteCenter(@sprites["pokemon#{targetBattler}"]) # starting positions pictureBall.moveVisible(1,true) pictureBall.moveName(1,ball0) pictureBall.moveOrigin(1,PictureOrigin::Center) pictureBall.moveXY(0,1,83,103) picturePoke.moveVisible(1,true) picturePoke.moveOrigin(1,PictureOrigin::Center) picturePoke.moveXY(0,1,center[0],center[1]) # directives picturePoke.moveSE(1,"Audio/SE/throw.wav") pictureBall.moveCurve(20,1,233,47,314,33,360,32) delay=pictureBall.totalDuration+2 picturePoke.moveColor(10,delay,Color.new(31*8,22*8,30*8)) delay=picturePoke.totalDuration picturePoke.moveSE(delay,"Audio/SE/recall.wav") pictureBall.moveName(delay,ball1) pictureBall.moveName(delay+4,ball2) picturePoke.moveZoom(15,delay,0) picturePoke.moveXY(15,delay,pokeball[0],pokeball[1]) picturePoke.moveSE(delay+10,"Audio/SE/jumptoball.wav") picturePoke.moveVisible(delay+15,false) pictureBall.moveName(picturePoke.totalDuration+2,ball0) delay=picturePoke.totalDuration+6 pictureBall.moveXY(15,delay,pokeball[0],128) pictureBall.moveSE(pictureBall.totalDuration,"Audio/SE/balldrop.wav") pictureBall.moveXY(8,pictureBall.totalDuration+2,pokeball[0],80) pictureBall.moveXY(7,pictureBall.totalDuration+2,pokeball[0],128) pictureBall.moveSE(pictureBall.totalDuration,"Audio/SE/balldrop.wav") pictureBall.moveXY(6,pictureBall.totalDuration+2,pokeball[0],96) pictureBall.moveXY(5,pictureBall.totalDuration+2,pokeball[0],128) pictureBall.moveSE(pictureBall.totalDuration,"Audio/SE/balldrop.wav") pictureBall.moveXY(4,pictureBall.totalDuration+2,pokeball[0],112) pictureBall.moveXY(3,pictureBall.totalDuration+2,pokeball[0],128) pictureBall.moveSE(pictureBall.totalDuration,"Audio/SE/balldrop.wav") picturePoke.moveXY(0,pictureBall.totalDuration,pokeball[0],128) delay=pictureBall.totalDuration+18 if shakes==0 [shakes,3].min.times do delay=pictureBall.totalDuration+18 pictureBall.moveSE(delay,"Audio/SE/ballshake.wav") pictureBall.moveXY(4,delay,pokeball[0]-8,128) pictureBall.moveAngle(4,delay,20) # positive means counterclockwise delay=pictureBall.totalDuration pictureBall.moveXY(8,delay,pokeball[0]+8,128) pictureBall.moveAngle(8,delay,-20) # negative means clockwise delay=pictureBall.totalDuration pictureBall.moveXY(4,delay,pokeball[0],128) pictureBall.moveAngle(4,delay,0) end if shakes<4 picturePoke.moveSE(delay,"Audio/SE/recall.wav") pictureBall.moveName(delay,ball1) pictureBall.moveName(delay+4,ball2) pictureBall.moveVisible(delay+10,false) picturePoke.moveVisible(delay,true) picturePoke.moveZoom(15,delay,100) picturePoke.moveXY(15,delay,center[0],center[1]) delay=picturePoke.totalDuration picturePoke.moveColor(10,delay,Color.new(31*8,22*8,30*8,0)) end picturePoke.moveOrigin(picturePoke.totalDuration,PictureOrigin::TopLeft) picturePoke.moveXY(0,picturePoke.totalDuration,dims[0],dims[1]) loop do pictureBall.update picturePoke.update setPictureIconSprite(spriteBall,pictureBall) setPictureSprite(spritePoke,picturePoke) pbGraphicsUpdate pbInputUpdate break if !pictureBall.running? && !picturePoke.running? end spriteBall.dispose end class PokeballPlayerSendOutAnimation # Ball curve: 8,52; 22,44; 52, 96 # Player: Color.new(16*8,23*8,30*8) SPRITESTEPS=10 STARTZOOM=0.125 def initialize(sprite,spritehash,pkmn,doublebattle) @disposed=false @pokemonsprite=sprite @pkmn=pkmn @pokemonsprite.visible=false @pokemonsprite.color=Color.new(16*8,23*8,30*8) @spritehash=spritehash if doublebattle @spritex=pkmn.index==0 ? 64 : 180 @spritey=pkmn.index==0 ? 96 : 112 else @spritex=128 @spritey=96 end @spritey+=(Graphics.height-320) metrics=load_data("Data/metrics.dat") # metrics[0] is player Y array @spritey+=(metrics[0][pkmn.species])*2 @spritey+=128 @animdone=false @frame=0 end def disposed? return @disposed end def animdone? return @animdone end def dispose return if disposed? @disposed=true end def update return if disposed? @frame+=1 if @frame==4 @pokemonsprite.visible=true @pokemonsprite.zoom_x=STARTZOOM @pokemonsprite.zoom_y=STARTZOOM Audio.se_play("Audio/SE/recall.wav") pbSpriteSetCenter(@pokemonsprite,@spritex,@spritey) pbPlayCry(@pkmn.pokemon ? @pkmn.pokemon : @pkmn.species) end if @frame>8 && @frame<=16 color=Color.new(248,248,248,256-(16-@frame)*32) @spritehash["enemybase"].color=color @spritehash["playerbase"].color=color @spritehash["battlebg"].color=color end if @frame>16 && @frame<=24 color=Color.new(248,248,248,(24-@frame)*32) @pokemonsprite.color.alpha=(24-@frame)*32 @spritehash["enemybase"].color=color @spritehash["playerbase"].color=color @spritehash["battlebg"].color=color end if @frame>5 && @pokemonsprite.zoom_x<1.0 @pokemonsprite.zoom_x+=0.1 @pokemonsprite.zoom_y+=0.1 @pokemonsprite.zoom_x=1.0 if @pokemonsprite.zoom_x > 1.0 @pokemonsprite.zoom_y=1.0 if @pokemonsprite.zoom_y > 1.0 halfY=(@pokemonsprite.bitmap && !@pokemonsprite.bitmap.disposed?) ? @pokemonsprite.bitmap.height/2 : 64 currentY=@spritey-(halfY*@pokemonsprite.zoom_y) pbSpriteSetCenter(@pokemonsprite,@spritex,currentY) end if @pokemonsprite.color.alpha<=0 && @pokemonsprite.zoom_x>=1.0 @animdone=true end end end class TrainerFadeAnimation def initialize(sprites) @frame=0 @sprites=sprites @animdone=false end def animdone? return @animdone end def update return if @animdone @frame+=1 @sprites["trainer"].x+=8 @sprites["trainer2"].x+=8 if @sprites["trainer2"] @sprites["partybase1"].x+=8 @sprites["partybase1"].opacity-=12 for i in 0...6 @sprites["enemy#{i}"].opacity-=12 @sprites["enemy#{i}"].x+=8 if @frame>=i*4 end @animdone=true if @sprites["trainer"].x>=480 && ( !@sprites["trainer2"]||@sprites["trainer2"].x>=480) end end class PlayerFadeAnimation def initialize(sprites) @frame=0 @sprites=sprites @animdone=false end def animdone? return @animdone end def update return if @animdone @frame+=1 @sprites["player"].x-=8 @sprites["playerB"].x-=8 if @sprites["playerB"] @sprites["partybase2"].x-=8 @sprites["partybase2"].opacity-=12 for i in 0...6 if @sprites["player#{i}"] @sprites["player#{i}"].opacity-=12 @sprites["player#{i}"].x-=8 if @frame>=i*4 end end pa=@sprites["player"] pb=@sprites["playerB"] pawidth=128 pbwidth=128 if (pa && pa.bitmap && !pa.bitmap.disposed?) if pa.bitmap.height<pa.bitmap.width numframes=pa.bitmap.width/pa.bitmap.height # Number of frames pawidth=pa.bitmap.width/numframes # Width per frame @sprites["player"].src_rect.x=pawidth*1 if @frame>0 @sprites["player"].src_rect.x=pawidth*2 if @frame>8 @sprites["player"].src_rect.x=pawidth*3 if @frame>11 @sprites["player"].src_rect.width=pawidth else pawidth=pa.bitmap.width @sprites["player"].src_rect.x=0 @sprites["player"].src_rect.width=pawidth end end if (pb && pb.bitmap && !pb.bitmap.disposed?) if pb.bitmap.height<pb.bitmap.width numframes=pb.bitmap.width/pb.bitmap.height # Number of frames pbwidth=pb.bitmap.width/numframes # Width per frame @sprites["playerB"].src_rect.x=pbwidth*1 if @frame>0 @sprites["playerB"].src_rect.x=pbwidth*2 if @frame>8 @sprites["playerB"].src_rect.x=pbwidth*3 if @frame>11 @sprites["playerB"].src_rect.width=pbwidth else pbwidth=pb.bitmap.width @sprites["playerB"].src_rect.x=0 @sprites["playerB"].src_rect.width=pbwidth end end if pb @animdone=true if pb.x<=-pbwidth else @animdone=true if pa.x<=-pawidth end end end #################################################### class PokeBattle_Scene USECOMMANDBOX=false # If true, expects a file named Graphics/Pictures/commandbox.png USEFIGHTBOX=false # If true, expects a file named Graphics/Pictures/fightbox.png MESSAGEBASECOLOR=Color.new(248,248,248) MESSAGESHADOWCOLOR=Color.new(104,88,112) MENUBASECOLOR=Color.new(72,72,72) MENUSHADOWCOLOR=Color.new(208,208,208) BOXTEXTBASECOLOR=Color.new(64,64,64) BOXTEXTSHADOWCOLOR=Color.new(216,208,176) EXPCOLOR=Color.new(64,200,248) # Green HP color HPCOLORBASE1=Color.new(14*8,31*8,21*8) HPCOLORSHADOW1=Color.new(11*8,26*8,16*8) # Orange HP color HPCOLORBASE2=Color.new(31*8,28*8,7*8) HPCOLORSHADOW2=Color.new(25*8,21*8,1*8) # Red HP color HPCOLORBASE3=Color.new(31*8,11*8,7*8) HPCOLORSHADOW3=Color.new(21*8,8*8,9*8) # Blank HP color HPCOLORBASE4=Color.new(0,0,0) HPCOLORSHADOW4=Color.new(0,0,0) # Position of HP gauge HPGAUGE_X=78 HPGAUGE_Y=34 # Position of EXP gauge EXPGAUGE_X=46 EXPGAUGE_Y=66 # Size of gauges EXPGAUGESIZE=128 HPGAUGESIZE=96 BLANK=0 MESSAGEBOX=1 COMMANDBOX=2 FIGHTBOX=3 attr_accessor :abortable def initialize @battle=nil @lastcmd=[0,0,0,0] @lastmove=[0,0,0,0] @pkmnwindows=[nil,nil,nil,nil] @sprites={} @battlestart=true @messagemode=false @abortable=false @aborted=false end def pbGraphicsUpdate partyAnimationUpdate @sprites["battlebg"].update if @sprites["battlebg"].respond_to?("update") Graphics.update end def pbInputUpdate Input.update if Input.trigger?(Input::B) && @abortable && !@aborted @aborted=true @battle.pbAbort end end def pbShowWindow(windowtype) @sprites["messagebox"].visible=(windowtype==MESSAGEBOX||windowtype==COMMANDBOX||windowtype==FIGHTBOX|| windowtype==BLANK) @sprites["messagewindow"].visible=(windowtype==MESSAGEBOX) @sprites["commandwindow"].visible=(windowtype==COMMANDBOX) @sprites["fightwindow"].visible=(windowtype==FIGHTBOX) end def pbSetMessageMode(mode) @messagemode=mode msgwindow=@sprites["messagewindow"] if mode # Within Pokémon command msgwindow.baseColor=MENUBASECOLOR msgwindow.shadowColor=MENUSHADOWCOLOR msgwindow.windowskin=@spriteskin msgwindow.x=0 msgwindow.width=Graphics.width msgwindow.height=96 msgwindow.y=Graphics.height-msgwindow.height else msgwindow.baseColor=MESSAGEBASECOLOR msgwindow.shadowColor=MESSAGESHADOWCOLOR msgwindow.windowskin=nil msgwindow.x=16 msgwindow.width=Graphics.width-32 msgwindow.height=96 msgwindow.y=Graphics.height-msgwindow.height end end def pbWaitMessage if @briefmessage pbShowWindow(MESSAGEBOX) cw=@sprites["messagewindow"] 60.times do pbGraphicsUpdate pbInputUpdate end cw.text="" cw.visible=false @briefmessage=false end end def pbDisplayMessage(msg,brief=false) pbWaitMessage pbRefresh pbShowWindow(MESSAGEBOX) cw=@sprites["messagewindow"] cw.text=msg i=0 loop do pbGraphicsUpdate pbInputUpdate cw.update if i==60 cw.text="" cw.visible=false return end if Input.trigger?(Input::C) || @abortable if cw.pausing? Audio.se_play(pbGetDecisionSE) if !@abortable cw.resume end end if !cw.busy? if brief @briefmessage=true return end i+=1 end end end def pbDisplayPausedMessage(msg) pbWaitMessage pbRefresh pbShowWindow(MESSAGEBOX) if @messagemode @switchscreen.pbDisplay(msg) return end cw=@sprites["messagewindow"] cw.text=_ISPRINTF("{1:s}\\1",msg) loop do pbGraphicsUpdate pbInputUpdate if Input.trigger?(Input::C) || @abortable if cw.busy? Audio.se_play(pbGetDecisionSE) if cw.pausing? && !@abortable cw.resume else cw.text="" Audio.se_play(pbGetDecisionSE) cw.visible=false if @messagemode return end end cw.update end end def pbDisplayConfirmMessage(msg) pbWaitMessage pbRefresh pbShowWindow(MESSAGEBOX) dw=@sprites["messagewindow"] dw.text=msg commands=[_INTL("YES"),_INTL("NO")] cw = Window_CommandPokemon.new(commands) cw.x=Graphics.width-cw.width cw.y=Graphics.height-cw.height-dw.height cw.index=0 cw.viewport=@viewport pbRefresh loop do cw.visible=!dw.busy? pbGraphicsUpdate pbInputUpdate pbFrameUpdate(cw) dw.update if Input.trigger?(Input::B) if dw.busy? Audio.se_play(pbGetDecisionSE)if dw.pausing? dw.resume else cw.dispose dw.text="" return false end end if Input.trigger?(Input::C) if dw.busy? Audio.se_play(pbGetDecisionSE)if dw.pausing? dw.resume else cw.dispose dw.text="" return (cw.index==0)?true:false end end end end def pbFrameUpdate(cw) cw.update if cw for i in 0..3 if @sprites["battler#{i}"] @sprites["battler#{i}"].update end if @sprites["pokemon#{i}"] @sprites["pokemon#{i}"].update end end end def pbRefresh for i in 0..3 if @sprites["battler#{i}"] @sprites["battler#{i}"].refresh end end end def pbAddSprite(id,x,y,filename,viewport) sprite=GifSprite.new(nil,viewport) if filename sprite.setBitmap(filename) rescue sprite.bitmap=nil end sprite.x=x sprite.y=y sprite.zoom_x=1.0 sprite.zoom_y=1.0 sprite.visible=true @sprites[id]=sprite return sprite end def pbAddPlane(id,filename,viewport) sprite=AnimatedPlane.new(viewport) if filename sprite.setBitmap(filename) end @sprites[id]=sprite return sprite end def pbDisposeSprites pbDisposeSpriteHash(@sprites) end def pbBeginCommandPhase # Called whenever a new round begins. @battlestart=false end def pbShowOpponent(index) if @battle.opponent if @battle.opponent.is_a?(Array) trainerfile=sprintf("Graphics/Characters/trainer%03d.png",@battle.opponent[index].trainertype) else trainerfile=sprintf("Graphics/Characters/trainer%03d.png",@battle.opponent.trainertype) end else trainerfile="Graphics/Pictures/trfront.png" end pbAddSprite("trainer",Graphics.width,16+@yoffset,trainerfile,@viewport) if @sprites["trainer"].bitmap @sprites["trainer"].y-=@sprites["trainer"].bitmap.height-128 end 20.times do pbGraphicsUpdate pbInputUpdate @sprites["trainer"].x-=6 end end def pbHideOpponent 20.times do pbGraphicsUpdate pbInputUpdate @sprites["trainer"].x+=6 end end def pbShowHelp(text) @sprites["helpwindow"].resizeToFit(text,Graphics.width) @sprites["helpwindow"].y=0 @sprites["helpwindow"].x=0 @sprites["helpwindow"].text=text @sprites["helpwindow"].visible=true end def pbHideHelp @sprites["helpwindow"].visible=false end def pbBackdrop outdoor=false if $game_map && pbGetMetadata($game_map.map_id,MetadataOutdoor) outdoor=true end case @battle.environment when PBEnvironment::Grass id=1 when PBEnvironment::TallGrass id=2 when PBEnvironment::MovingWater id=3 when PBEnvironment::StillWater id=4 when PBEnvironment::Underwater id=5 when PBEnvironment::Rock id=7 when PBEnvironment::Cave id=8 when PBEnvironment::Sand id=9 else id=(outdoor) ? 0 : 6 end if $PokemonGlobal.nextBattleBack id=$PokemonGlobal.nextBattleBack end battlebg="Graphics/Pictures/battlebg#{id}.png" enemybase="Graphics/Pictures/enemybase#{id}.png" playerbase="Graphics/Pictures/playerbase#{id}.png" if true # !$game_temp.background_bitmap.respond_to?("radial_blur") pbAddPlane("battlebg",battlebg,@viewport) else source = $game_temp.background_bitmap bitmap = Bitmap.new(Graphics.width+32,Graphics.height) bitmap.stretch_blt(bitmap.rect, source, source.rect) bitmap.radial_blur(90, 12) @sprites["battlebg"] = Sprite.new(@viewport) @sprites["battlebg"].bitmap = bitmap @sprites["battlebg"].x = -16 @sprites["battlebg"].y = 0 @sprites["battlebg"].wave_amp = 8 @sprites["battlebg"].wave_length = 240 @sprites["battlebg"].wave_speed = 120 end pbAddSprite("enemybase",-256,96+@yoffset,enemybase,@viewport) # ends at (224,96) pbAddSprite("playerbase",Graphics.width,192+@yoffset,playerbase,@viewport) # ends at (0,192) @sprites["enemybase"].z=-1 # For compatibility with RGSS2 @sprites["playerbase"].z=-1 # For compatibility with RGSS2 @sprites["battlebg"].z=-1 # For compatibility with RGSS2 =begin if outdoor tone = $HourlyTones[Time.now.hour] @sprites["battlebg"].tone=tone @sprites["enemybase"].tone=tone @sprites["playerbase"].tone=tone end =end end def inPartyAnimation? return @enablePartyAnim && @partyAnimPhase<4 end def partyAnimationUpdate return if !inPartyAnimation? if @partyAnimPhase==0 @sprites["partybase1"].x+=16 @sprites["partybase2"].x-=16 @partyAnimPhase=1 if @sprites["partybase1"].x+@sprites["partybase1"].bitmap.width>=208 return end if @partyAnimPhase==1 @enemyendpos=152 @playerendpos=312 @partyAnimPhase=2 @partyAnimI=0 end if @partyAnimPhase==2 if @partyAnimI>=6 @partyAnimPhase=4 return end if @partyAnimI>=@battle.party2.length || !@battle.party2[@partyAnimI] pbAddSprite("enemy#{@partyAnimI}",-28,64+@yoffset,"Graphics/Pictures/ballempty.png",@viewport) elsif @battle.party2[@partyAnimI].hp<=0 || @battle.party2[@partyAnimI].status>0 || @battle.party2[@partyAnimI].egg? pbAddSprite("enemy#{@partyAnimI}",-28,64+@yoffset,"Graphics/Pictures/ballfainted.png",@viewport) else pbAddSprite("enemy#{@partyAnimI}",-28,64+@yoffset,"Graphics/Pictures/ballnormal.png",@viewport) end if @partyAnimI==@battle.party1.length || !@battle.party1[@partyAnimI] pbAddSprite("player#{@partyAnimI}",492,176+@yoffset,"Graphics/Pictures/ballempty.png",@viewport) elsif @battle.party1[@partyAnimI].hp<=0 || @battle.party1[@partyAnimI].status>0 || @battle.party1[@partyAnimI].egg? pbAddSprite("player#{@partyAnimI}",492,176+@yoffset,"Graphics/Pictures/ballfainted.png",@viewport) else pbAddSprite("player#{@partyAnimI}",492,176+@yoffset,"Graphics/Pictures/ballnormal.png",@viewport) end @partyAnimPhase=3 end if @partyAnimPhase==3 @sprites["enemy#{@partyAnimI}"].x+=20 @sprites["player#{@partyAnimI}"].x-=20 if @sprites["enemy#{@partyAnimI}"].x>=@enemyendpos @partyAnimPhase=2 @partyAnimI+=1 @enemyendpos-=20 @playerendpos+=20 end end end def pbStartBattle(battle) # Called whenever the battle begins @battle=battle @lastcmd=[0,0,0,0] @lastmove=[0,0,0,0] @sprites.clear @sprites.clear @viewport=Viewport.new(0,Graphics.height/2,Graphics.width,0) @viewport.z=99999 @battleboxvp=Viewport.new(0,0,Graphics.width,Graphics.height) @battleboxvp.z=99999 @msgviewport=Viewport.new(0,Graphics.height/2,Graphics.width,0) @msgviewport.z=100001 @showingplayer=true @showingenemy=true @yoffset=(Graphics.height-320) @spriteskin=Bitmap.new($TextFrames[$PokemonSystem.frame]) pbBackdrop pbAddSprite("partybase1",-400,80+@yoffset,"Graphics/Pictures/pbarrow.png",@viewport) pbAddSprite("partybase2",480,192+@yoffset,"Graphics/Pictures/pbarrow.png",@viewport) @sprites["partybase2"].mirror=true @sprites["partybase1"].visible=false @sprites["partybase2"].visible=false if @battle.opponent if @battle.opponent.is_a?(Array) trainerfile=sprintf("Graphics/Characters/trainer%03d.png",@battle.opponent[0].trainertype) pbAddSprite("trainer",-144,16+@yoffset,trainerfile,@viewport) trainerfile=sprintf("Graphics/Characters/trainer%03d.png",@battle.opponent[1].trainertype) pbAddSprite("trainer2",-240,16+@yoffset,trainerfile,@viewport) else trainerfile=sprintf("Graphics/Characters/trainer%03d.png",@battle.opponent.trainertype) pbAddSprite("trainer",-192,16+@yoffset,trainerfile,@viewport) end else trainerfile="Graphics/Pictures/trfront.png" pbAddSprite("trainer",-192,16+@yoffset,trainerfile,@viewport) end if @sprites["trainer"].bitmap @sprites["trainer"].y-=@sprites["trainer"].bitmap.height-128 end if @sprites["trainer2"] && @sprites["trainer2"].bitmap @sprites["trainer2"].y-=@sprites["trainer2"].bitmap.height-128 end @sprites["pokemon0"]=PokemonSprite.new(battle.doublebattle,0,@viewport) @sprites["pokemon1"]=PokemonSprite.new(battle.doublebattle,1,@viewport) if battle.doublebattle @sprites["pokemon3"]=PokemonSprite.new(battle.doublebattle,3,@viewport) @sprites["pokemon2"]=PokemonSprite.new(battle.doublebattle,2,@viewport) end @sprites["battler0"]=PokemonDataBox.new(battle.battlers[0],battle.doublebattle,@viewport) @sprites["battler1"]=PokemonDataBox.new(battle.battlers[1],battle.doublebattle,@viewport) if battle.doublebattle @sprites["battler2"]=PokemonDataBox.new(battle.battlers[2],battle.doublebattle,@viewport) @sprites["battler3"]=PokemonDataBox.new(battle.battlers[3],battle.doublebattle,@viewport) end if @battle.player.is_a?(Array) trainerfile=sprintf("Graphics/Pictures/trback%03d.png",@battle.player[0].trainertype) pbAddSprite("player",576-48,96+@yoffset,trainerfile,@viewport) trainerfile=sprintf("Graphics/Pictures/trback%03d.png",@battle.player[1].trainertype) pbAddSprite("playerB",576+48,96+@yoffset,trainerfile,@viewport) if @sprites["player"].bitmap if @sprites["player"].bitmap.width>@sprites["player"].bitmap.height @sprites["player"].src_rect.x=0 @sprites["player"].src_rect.width=@sprites["player"].bitmap.width/4 end end if @sprites["playerB"].bitmap if @sprites["playerB"].bitmap.width>@sprites["playerB"].bitmap.height @sprites["playerB"].src_rect.x=0 @sprites["playerB"].src_rect.width=@sprites["playerB"].bitmap.width/4 end end else trainerfile=sprintf("Graphics/Pictures/trback%03d.png",@battle.player.trainertype) pbAddSprite("player",576,96+@yoffset,trainerfile,@viewport) if @sprites["player"].bitmap if @sprites["player"].bitmap.width>@sprites["player"].bitmap.height @sprites["player"].src_rect.x=0 @sprites["player"].src_rect.width=@sprites["player"].bitmap.width/4 end end end pbAddSprite("messagebox",0,Graphics.height-96,"Graphics/Pictures/messagebox.png",@viewport) @sprites["helpwindow"]=Window_UnformattedTextPokemon.newWithSize("",0,0,32,32,@viewport) @sprites["helpwindow"].visible=false @sprites["messagewindow"]=Window_AdvancedTextPokemon.new("") @sprites["commandwindow"]=CommandMenuDisplay.new(@viewport) @sprites["fightwindow"]=FightMenuDisplay.new(nil,@viewport) @sprites["messagewindow"].letterbyletter=true @sprites["messagewindow"].viewport=@viewport @sprites["messagebox"].z=50 @sprites["messagewindow"].z=100 @sprites["commandwindow"].z=100 @sprites["fightwindow"].z=100 pbShowWindow(MESSAGEBOX) pbSetMessageMode(false) trainersprite1=@sprites["trainer"] trainersprite2=@sprites["trainer2"] if !@battle.opponent @sprites["trainer"].visible=false if @battle.party2.length>=1 @sprites["pokemon1"].color=Color.new(0,0,0,128) @sprites["pokemon1"].bitmap=pbLoadPokemonBitmap(@battle.party2[0],false) @sprites["pokemon1"].x=-192 # ends at 144*2 species=@battle.party2[0].species metrics=load_data("Data/metrics.dat") factor=metrics[1][species] # enemy Y factor-=metrics[2][species] # altitude (affects shadows) @sprites["pokemon1"].y=factor*2+16+@yoffset @sprites["pokemon1"].visible=true pbPositionPokemonSprite( @sprites["pokemon1"], @sprites["pokemon1"].x, @sprites["pokemon1"].y ) trainersprite1=@sprites["pokemon1"] end if @battle.party2.length==2 @sprites["pokemon1"].color=Color.new(0,0,0,160) @sprites["pokemon3"].color=Color.new(0,0,0,160) @sprites["pokemon1"].x=-144 @sprites["pokemon1"].y+=8 @sprites["pokemon3"].bitmap=pbLoadPokemonBitmap(@battle.party2[1],false) @sprites["pokemon3"].x=-240 species=@battle.party2[1].species metrics=load_data("Data/metrics.dat") factor=metrics[1][species] # enemy Y factor-=metrics[2][species] # altitude (affects shadows) @sprites["pokemon3"].y=factor*2+8+@yoffset @sprites["pokemon3"].visible=true pbPositionPokemonSprite( @sprites["pokemon3"], @sprites["pokemon3"].x, @sprites["pokemon3"].y ) trainersprite2=@sprites["pokemon3"] end end loop do if @viewport.rect.y>Graphics.height/4 @viewport.rect.y-=2 @viewport.rect.height+=4 elsif @viewport.rect.y>0 @viewport.rect.y-=4 @viewport.rect.height+=8 end for i in @sprites i[1].ox=@viewport.rect.x i[1].oy=@viewport.rect.y end @sprites["enemybase"].x+=4 @sprites["playerbase"].x-=4 trainersprite1.x+=4 trainersprite2.x+=4 if trainersprite2 @sprites["player"].x-=4 @sprites["playerB"].x-=4 if @sprites["playerB"] pbGraphicsUpdate pbInputUpdate break if @sprites["enemybase"].x>=224 end # Show shiny animation if !@battle.opponent pkmnwav=sprintf("Audio/SE/%03dCry",@battle.party2[0].species) Audio.se_play(pkmnwav,90,100) rescue nil if @battle.party2[0].isShiny? pbCommonAnimation("Shiny",@battle.battlers[1],nil) end if @battle.party2.length==2 if @battle.party2[1].isShiny? pbCommonAnimation("Shiny",@battle.battlers[3],nil) end end end if @battle.opponent @enablePartyAnim=true @partyAnimPhase=0 @sprites["partybase1"].visible=true @sprites["partybase2"].visible=true else @sprites["battler1"].appear @sprites["battler3"].appear if @battle.party2.length==2 appearing=true begin pbGraphicsUpdate pbInputUpdate @sprites["battler1"].update appearing=@sprites["battler1"].appearing @sprites["pokemon1"].color.alpha-=16 @sprites["pokemon1"].color=@sprites["pokemon1"].color if @battle.party2.length==2 @sprites["battler3"].update @sprites["pokemon3"].color.alpha-=16 @sprites["pokemon3"].color=@sprites["pokemon3"].color appearing=(appearing||@sprites["battler3"].appearing) end end while appearing end end def pbEndBattle(result) @abortable=false pbShowWindow(BLANK) # Fade out all sprites $game_system.bgm_fade(1.0) pbFadeOutAndHide(@sprites) @spriteskin.dispose pbDisposeSprites end def pbRecall(battlerindex) @briefmessage=false if @battle.pbIsOpposing?(battlerindex) else spritePoke=@sprites["pokemon#{battlerindex}"] picturePoke=PictureEx.new(0) dims=[spritePoke.x,spritePoke.y] center=getSpriteCenter(spritePoke) # starting positions picturePoke.moveVisible(1,true) picturePoke.moveOrigin(1,PictureOrigin::Center) picturePoke.moveXY(0,1,center[0],center[1]) # directives picturePoke.moveColor(10,1,Color.new(16*8,23*8,30*8)) delay=picturePoke.totalDuration picturePoke.moveSE(delay,"Audio/SE/recall.wav") picturePoke.moveZoom(15,delay,0) picturePoke.moveXY(15,delay,center[0],Graphics.height-80) picturePoke.moveVisible(picturePoke.totalDuration,false) picturePoke.moveColor(0,picturePoke.totalDuration,Color.new(0,0,0,0)) picturePoke.moveOrigin(picturePoke.totalDuration,PictureOrigin::TopLeft) loop do picturePoke.update setPictureSprite(spritePoke,picturePoke) pbGraphicsUpdate pbInputUpdate break if !picturePoke.running? end end end def pbTrainerSendOut(battlerindex,pkmn) @briefmessage=false fadeanim=nil while inPartyAnimation?; end if @showingenemy fadeanim=TrainerFadeAnimation.new(@sprites) end frame=0 if @sprites["pokemon#{battlerindex}"].bitmap @sprites["pokemon#{battlerindex}"].bitmap.dispose end @sprites["pokemon#{battlerindex}"].bitmap=pbLoadPokemonBitmap(pkmn,false) sendout=PokeballSendOutAnimation.new(@sprites["pokemon#{battlerindex}"], @sprites,@battle.battlers[battlerindex],@battle.doublebattle) loop do pbGraphicsUpdate pbInputUpdate fadeanim.update if fadeanim frame+=1 if frame==1 @sprites["battler#{battlerindex}"].appear end if frame>=10 sendout.update end @sprites["battler#{battlerindex}"].update break if (!fadeanim || fadeanim.animdone?) && sendout.animdone? && !@sprites["battler#{battlerindex}"].appearing end if @battle.battlers[battlerindex].pokemon.isShiny? pbCommonAnimation("Shiny",@battle.battlers[battlerindex],nil) end sendout.dispose if @showingenemy @showingenemy=false pbDisposeSprite(@sprites,"trainer") pbDisposeSprite(@sprites,"partybase1") for i in 0...6 pbDisposeSprite(@sprites,"enemy#{i}") end end pbRefresh end def pbSendOut(battlerindex,pkmn) while inPartyAnimation?; end balltype=pkmn.ballused ballbitmap=sprintf("Graphics/Pictures/ball%02d_0.png",balltype) pictureBall=PictureEx.new(0) delay=1 pictureBall.moveVisible(delay,true) pictureBall.moveName(delay,ballbitmap) pictureBall.moveOrigin(delay,PictureOrigin::Center) # Setting the ball's movement path path=[[111, 164], [113, 154], [115, 145], [118, 136], [122, 128], [130, 124], [137, 129], [140, 138], [142, 147], [143, 156], [144, 166], [145, 175], [145, 185], [146, 194], [146, 203], [146, 213], [147, 222], [147, 232], [147, 241], [147, 250]] spriteBall=IconSprite.new(0,0,@viewport) spriteBall.visible=false angle=0 for coord in path delay=pictureBall.totalDuration pictureBall.moveAngle(0,delay,angle) pictureBall.moveXY(1,delay,coord[0],coord[1]) angle+=80 angle%=360 end pictureBall.adjustPosition(0,Graphics.height-320) @sprites["battler#{battlerindex}"].visible=false @briefmessage=false fadeanim=nil if @showingplayer fadeanim=PlayerFadeAnimation.new(@sprites) end frame=0 if @sprites["pokemon#{battlerindex}"].bitmap @sprites["pokemon#{battlerindex}"].bitmap.dispose end @sprites["pokemon#{battlerindex}"].bitmap=pbLoadPokemonBitmap(pkmn,true) sendout=PokeballPlayerSendOutAnimation.new(@sprites["pokemon#{battlerindex}"], @sprites,@battle.battlers[battlerindex],@battle.doublebattle) loop do fadeanim.update if fadeanim frame+=1 if frame>1 && !pictureBall.running? && !@sprites["battler#{battlerindex}"].appearing @sprites["battler#{battlerindex}"].appear end if frame>=3 && !pictureBall.running? sendout.update end if (frame>=10 || !fadeanim) && pictureBall.running? pictureBall.update setPictureIconSprite(spriteBall,pictureBall) end @sprites["battler#{battlerindex}"].update pbGraphicsUpdate pbInputUpdate break if (!fadeanim || fadeanim.animdone?) && sendout.animdone? && !@sprites["battler#{battlerindex}"].appearing end spriteBall.dispose sendout.dispose if @battle.battlers[battlerindex].pokemon.isShiny? pbCommonAnimation("Shiny",@battle.battlers[battlerindex],nil) end if @showingplayer @showingplayer=false pbDisposeSprite(@sprites,"player") pbDisposeSprite(@sprites,"partybase2") for i in 0...6 pbDisposeSprite(@sprites,"player#{i}") end end pbRefresh end def pbTrainerWithdraw(battle,pkmn) pbRefresh end def pbWithdraw(battle,pkmn) pbRefresh end def pbForgetMove(pokemon,moveToLearn) # Called whenever a Pokémon should forget a move. It # should return -1 if the selection is canceled, or 0 to 3 # to indicate the move to forget. The function should not # allow HM moves to be forgotten. ret=-1 pbFadeOutIn(99999){ scene=PokemonSummaryScene.new screen=PokemonSummary.new(scene) ret=screen.pbStartForgetScreen([pokemon],0,moveToLearn) } return ret end def pbBeginAttackPhase pbSelectBattler(-1) end def pbSafariStart @briefmessage=false @sprites["battler0"]=SafariDataBox.new(@battle,@viewport) @sprites["battler0"].appear loop do @sprites["battler0"].update pbGraphicsUpdate pbInputUpdate break if !@sprites["battler0"].appearing end pbRefresh end def pbCommandMenuEx(index,texts) pbShowWindow(COMMANDBOX) cw2=@sprites["commandwindow"] cw2.setTexts(texts) cw2.index=[0,2,1,3][@lastcmd[index]] pbSelectBattler(index) pbRefresh loop do pbGraphicsUpdate pbInputUpdate pbFrameUpdate(cw2) if Input.trigger?(Input::C) ret=[0,2,1,3][cw2.index] Audio.se_play(pbGetDecisionSE) @lastcmd[index]=ret return ret end nextindex=pbNextIndex(cw2.index) if cw2.index!=nextindex Audio.se_play(pbGetDecisionSE) cw2.index=nextindex end end end def pbSafariCommandMenu(index) pbCommandMenuEx(index,[ _INTL("What will\\n{1} throw?",@battle.pbPlayer.name), _INTL("BALL"), _INTL("ROCK"), _INTL("BAIT"), _INTL("RUN") ]) end def pbCommandMenu(index) # Use this method to display the list of commands. # Return values: # 0 - Fight # 1 - Pokémon # 2 - Bag # 3 - Run pbCommandMenuEx(index,[ _INTL("What will\\n{1} do?",@battle.battlers[index].name), _INTL("FIGHT"), _INTL("POKéMON"), _INTL("BAG"), _INTL("RUN") ]) end def pbMoveString(move) ret=_INTL("{1}",move.name) typename=PBTypes.getName(move.type) if move.id>0 ret+=_INTL(" ({1}) PP: {2}/{3}",typename,move.pp,move.totalpp) end return ret end def pbNameEntry(helptext) return pbEnterText(helptext,0,10) end def pbFightMenu(index) # Use this method to display the list of moves for a Pokémon pbShowWindow(FIGHTBOX) cw = @sprites["fightwindow"] battler=@battle.battlers[index] cw.battler=battler lastIndex=@lastmove[index] if battler.moves[lastIndex].id!=0 cw.setIndex(lastIndex) else cw.setIndex(0) end pbSelectBattler(index) pbRefresh loop do pbGraphicsUpdate pbInputUpdate pbFrameUpdate(cw) if Input.trigger?(Input::B) @lastmove[index]=cw.index Audio.se_play(pbGetDecisionSE) return -1 end if Input.trigger?(Input::C) ret=cw.index Audio.se_play(pbGetDecisionSE) @lastmove[index]=ret return ret end nextindex=pbNextIndex(cw.index) if cw.index!=nextindex Audio.se_play(pbGetDecisionSE) cw.setIndex(nextindex) end end end def pbItemMenu(index) # Use this method to display the inventory # The return value is the item chosen, or 0 if the choice was canceled. ret=0 endscene=true oldsprites=pbFadeOutAndHide(@sprites) itemscene=PokemonBag_Scene.new itemscene.pbStartScene($PokemonBag) loop do item=itemscene.pbChooseItem break if item==0 usetype=$ItemData[item][ITEMBATTLEUSE] cmdUse=-1 commands=[] if usetype==0 commands[commands.length]=_INTL("CANCEL") else commands[cmdUse=commands.length]=_INTL("USE") commands[commands.length]=_INTL("CANCEL") end itemname=PBItems.getName(item) command=itemscene.pbShowCommands(_INTL("{1} is selected.",itemname),commands) if cmdUse>=0 && command==cmdUse if usetype==1 pkmnlist=PokemonScreen_Scene.new pkmnscreen=PokemonScreen.new(pkmnlist,@battle.party1) itemscene.pbEndScene pkmnlist.pbStartScene(@battle.party1,_INTL("Use on which Pokémon?")) pkmnid=pkmnlist.pbChoosePokemon if pkmnid>=0 && @battle.pbUseItemOnPokemon(item,pkmnid,pkmnscreen) pkmnscreen.pbRefresh pkmnlist.pbEndScene ret=item endscene=false break end pkmnlist.pbEndScene itemscene.pbStartScene($PokemonBag) elsif usetype==2 if @battle.pbUseItemOnBattler(item,index,itemscene) ret=item break end end end end if ret!=0 && $ItemData[ret][ITEMBATTLEUSE]!=3 # Delete the item just used from stock $PokemonBag.pbDeleteItem(ret) end itemscene.pbEndScene if endscene for i in 0..4 if @sprites["battler#{i}"] @sprites["battler#{i}"].refresh end end pbFadeInAndShow(@sprites,oldsprites) return ret end def pbSelectBattler(index,selectmode=1) numwindows=@battle.doublebattle ? 4 : 2 for i in 0...numwindows sprite=@sprites["battler#{i}"] sprite.selected=(i==index) ? selectmode : 0 sprite=@sprites["pokemon#{i}"] sprite.selected=(i==index) ? selectmode : 0 end end def pbFirstTarget(index) for i in 0..3 if i!=index && @battle.battlers[i].hp>0 && @battle.battlers[index].pbIsOpposing?(i) return i end end return -1 end def pbNextIndex(curindex) if Input.trigger?(Input::LEFT) && (curindex&1)==1 return curindex-1 elsif Input.trigger?(Input::RIGHT) && (curindex&1)==0 return curindex+1 elsif Input.trigger?(Input::UP) && (curindex&2)==2 return curindex-2 elsif Input.trigger?(Input::DOWN) && (curindex&2)==0 return curindex+2 end return curindex end def pbUpdateSelected(index) numwindows=@battle.doublebattle ? 4 : 2 for i in 0...numwindows if i==index @sprites["battler#{i}"].selected=2 @sprites["pokemon#{i}"].selected=2 else @sprites["battler#{i}"].selected=0 @sprites["pokemon#{i}"].selected=0 end @sprites["battler#{i}"].update @sprites["pokemon#{i}"].update end end def pbChooseTarget(index) # Use this method to make the player choose a target # for certain moves in double battles. pbShowWindow(FIGHTBOX) curwindow=pbFirstTarget(index) if curwindow==-1 raise RuntimeError.new(_INTL("No targets somehow...")) end loop do pbGraphicsUpdate pbInputUpdate pbUpdateSelected(curwindow) if Input.trigger?(Input::C) pbUpdateSelected(-1) return curwindow end if Input.trigger?(Input::B) pbUpdateSelected(-1) return -1 end if curwindow>=0 if Input.trigger?(Input::RIGHT) || Input.trigger?(Input::DOWN) loop do newcurwindow=3 if curwindow==0 newcurwindow=1 if curwindow==3 newcurwindow=2 if curwindow==1 newcurwindow=0 if curwindow==2 curwindow=newcurwindow next if curwindow==index break if @battle.battlers[curwindow].hp>0 end elsif Input.trigger?(Input::LEFT) || Input.trigger?(Input::UP) loop do newcurwindow=2 if curwindow==0 newcurwindow=1 if curwindow==2 newcurwindow=3 if curwindow==1 newcurwindow=0 if curwindow==3 curwindow=newcurwindow next if curwindow==index break if @battle.battlers[curwindow].hp>0 end end end end end def pbSwitch(index,lax,cancancel) party=@battle.pbParty(index) inactives=[1,1,1,1,1,1] partypos=[] switchsprites={} activecmd=0 ret=-1 numactive=(@doublebattle)?2:1 pbShowWindow(BLANK) pbSetMessageMode(true) # Fade out and hide all sprites visiblesprites=pbFadeOutAndHide(@sprites) battler=@battle.battlers[0] activecmd=0 if battler.index==index inactives[battler.pokemonIndex]=0 partypos[0]=battler.pokemonIndex if @battle.doublebattle && !@battle.fullparty1 battler=@battle.battlers[2] activecmd=1 if battler.index==index inactives[battler.pokemonIndex]=0 partypos[1]=battler.pokemonIndex end # Add all non-active Pokémon for i in 0...6 partypos[partypos.length]=i if inactives[i]==1 end modparty=[] for i in 0...6 modparty.push(party[partypos[i]]) end scene=PokemonScreen_Scene.new @switchscreen=PokemonScreen.new(scene,modparty) @switchscreen.pbStartScene(_INTL("Choose a Pokémon."), @battle.doublebattle && !@battle.fullparty1) loop do scene.pbSetHelpText(_INTL("Choose a Pokémon.")) activecmd=@switchscreen.pbChoosePokemon if cancancel && activecmd==-1 ret=-1 break end if activecmd>=0 commands=[] cmdShift=-1 cmdSummary=-1 pkmnindex=partypos[activecmd] commands[cmdShift=commands.length]=_INTL("SHIFT") if !party[pkmnindex].egg? commands[cmdSummary=commands.length]=_INTL("SUMMARY") commands[commands.length]=_INTL("CANCEL") command=scene.pbShowCommands(_INTL("Do what with {1}?",party[pkmnindex].name),commands) if cmdShift>=0 && command==cmdShift canswitch=lax ? @battle.pbCanSwitchLax?(index,pkmnindex,true) : @battle.pbCanSwitch?(index,pkmnindex,true) if canswitch ret=pkmnindex break end elsif cmdSummary>=0 && command==cmdSummary scene.pbSummary(activecmd) end end end @switchscreen.pbEndScene @switchscreen=nil pbSetMessageMode(false) # back to main battle screen pbFadeInAndShow(@sprites,visiblesprites) return ret end def pbDamageAnimation(pkmn,effectiveness) pkmnsprite=@sprites["pokemon#{pkmn.index}"] sprite=@sprites["battler#{pkmn.index}"] oldvisible=sprite.visible sprite.selected=2 @briefmessage=false 6.times do pbGraphicsUpdate pbInputUpdate end case effectiveness when 0 Audio.se_play("Audio/SE/normaldamage.wav") when 1 Audio.se_play("Audio/SE/notverydamage.wav") when 2 Audio.se_play("Audio/SE/superdamage.wav") end 8.times do pkmnsprite.visible=!pkmnsprite.visible 4.times do pbGraphicsUpdate pbInputUpdate sprite.update end end sprite.selected=0 sprite.visible=oldvisible end def pbHPChanged(pkmn,oldhp) # This method is called whenever a Pokémon's HP changes. # Used to animate the HP bar. @briefmessage=false hpchange=pkmn.hp-oldhp if hpchange<0 hpchange=-hpchange PBDebug.log("[#{pkmn.pbThis} lost #{hpchange} HP, now has #{pkmn.hp} HP]") if @battle.debug else PBDebug.log("[#{pkmn.pbThis} gained #{hpchange} HP, now has #{pkmn.hp} HP]") if @battle.debug end sprite=@sprites["battler#{pkmn.index}"] sprite.animateHP(oldhp,pkmn.hp) while sprite.animatingHP pbGraphicsUpdate pbInputUpdate sprite.update end end def pbFainted(pkmn) # This method is called whenever a Pokémon faints pbPlayCry(pkmn.pokemon) 30.times do pbGraphicsUpdate pbInputUpdate end pkmnsprite=@sprites["pokemon#{pkmn.index}"] pkmnsprite.visible=false if @battle.pbIsOpposing?(pkmn.index) tempvp=Viewport.new(0,0,480,144+@yoffset) else tempvp=Viewport.new(0,0,480,224+@yoffset) end tempvp.z=@viewport.z tempsprite=Sprite.new(tempvp) tempsprite.x=pkmnsprite.x tempsprite.y=pkmnsprite.y tempsprite.bitmap=pkmnsprite.bitmap tempsprite.visible=true Audio.se_play("Audio/SE/faint.wav") 16.times do tempsprite.y+=8 pbGraphicsUpdate pbInputUpdate end tempsprite.dispose tempvp.dispose 8.times do @sprites["battler#{pkmn.index}"].opacity=32 pbGraphicsUpdate pbInputUpdate end @sprites["battler#{pkmn.index}"].visible=false end def pbChooseEnemyCommand(index) # Use this method to choose a command for the enemy. if !@battle.pbCanShowFightMenu?(index) @battle.pbAutoChooseMove(index) return end return if @battle.pbEnemyShouldUseItem?(index) return if @battle.pbEnemyShouldWithdraw?(index) return if @battle.pbAutoFightMenu(index) @battle.pbChooseMoves(index) end def pbChooseNewEnemy(index,party) # Use this method to choose a new Pokémon for the enemy # The enemy's party is guaranteed to have at least one choosable member. for i in 0..party.length-1 return i if @battle.pbCanSwitchLax?(index,i,false) end return -1 end def pbWildBattleSuccess # This method is called when the player wins a wild Pokémon battle. # This method can change the battle's music for example. $game_system.bgm_play(pbGetWildVictoryME()) end def pbTrainerBattleSuccess # This method is called when the player wins a Trainer battle. # This method can change the battle's music for example. if @battle.opponent.is_a?(Array) opp=@battle.opponent[0] else opp=@battle.opponent end $game_system.bgm_play(pbGetTrainerVictoryME(opp)) end def pbEXPBar(pokemon,battler,startexp,endexp,tempexp1,tempexp2) if battler @sprites["battler#{battler.index}"].refreshExpLevel exprange=(endexp-startexp) startexplevel=0 endexplevel=0 if exprange!=0 startexplevel=(tempexp1-startexp)*128/exprange endexplevel=(tempexp2-startexp)*128/exprange end @sprites["battler#{battler.index}"].animateEXP(startexplevel,endexplevel) while @sprites["battler#{battler.index}"].animatingEXP pbGraphicsUpdate pbInputUpdate @sprites["battler#{battler.index}"].update end end end def pbShowPokedex(species) pbFadeOutIn(99999){ scene=PokemonPokedexScene.new screen=PokemonPokedex.new(scene) screen.pbDexEntry(species) } end def pbFindAnimation(moveid) begin move2anim=load_data("Data/move2anim.dat") anim=move2anim[0][moveid] return anim if anim anim=move2anim[0][PBMoves::TACKLE] return anim if anim rescue return nil end end def pbCommonAnimation(animname,attacker,opponent,side=true) animations=load_data("Data/PkmnAnimations.rxdata") for i in 0...animations.length if animations[i] && animations[i].name=="Common:"+animname pbAnimationCore(animations[i],attacker,opponent,side) return end end end def pbAnimation(moveid,attacker,opponent,side=true) animid=pbFindAnimation(moveid) return if !animid animations=load_data("Data/PkmnAnimations.rxdata") pbAnimationCore(animations[animid],attacker,opponent,side) end def pbAnimationCore(animation,attacker,opponent,side=true) if !attacker || !animation return end @briefmessage=false user=(attacker) ? @sprites["pokemon#{attacker.index}"] : nil target=(opponent) ? @sprites["pokemon#{opponent.index}"] : nil olduserx=user.x oldusery=user.y oldtargetx=target ? target.x : 0 oldtargety=target ? target.y : 0 if !target animplayer=PBAnimationPlayer.new( animation,user,user,@viewport ) userwidth=(!user.bitmap || user.bitmap.disposed?) ? 128 : user.bitmap.width userheight=(!user.bitmap || user.bitmap.disposed?) ? 128 : user.bitmap.height animplayer.setLineTransform( 144,188,352,108, user.x+(userwidth/2), user.y+(userheight/2), user.x+(userwidth/2), user.y+(userheight/2) ) else animplayer=PBAnimationPlayer.new( animation,user,target,@viewport ) userwidth=(!user.bitmap || user.bitmap.disposed?) ? 128 : user.bitmap.width targetwidth=(!target.bitmap || target.bitmap.disposed?) ? 128 : target.bitmap.width userheight=(!user.bitmap || user.bitmap.disposed?) ? 128 : user.bitmap.height targetheight=(!target.bitmap || target.bitmap.disposed?) ? 128 : target.bitmap.height animplayer.setLineTransform( 144,188,352,108, user.x+(userwidth/2), user.y+(userheight/2), target.x+(targetwidth/2), target.y+(targetheight/2) ) end animplayer.start while animplayer.playing? animplayer.update pbGraphicsUpdate pbInputUpdate end user.ox=0 user.oy=0 target.ox=0 if target target.oy=0 if target user.x=olduserx user.y=oldusery target.x=oldtargetx if target target.y=oldtargety if target animplayer.dispose end def pbLevelUp(pokemon,battler,oldtotalhp,oldattack, olddefense,oldspeed,oldspatk,oldspdef) pbTopRightWindow(_INTL("MaxHP: +{1}\\r\\nATTACK: +{2}\\r\\nDEFENSE: +{3}\\r\\nSP. ATK: +{4}\\r\\nSP. DEF: +{5}\\r\\nSPEED: +{6}", pokemon.totalhp-oldtotalhp, pokemon.attack-oldattack, pokemon.defense-olddefense, pokemon.spatk-oldspatk, pokemon.spdef-oldspdef, pokemon.speed-oldspeed )) pbTopRightWindow(_INTL("MaxHP: {1}\\r\\nATTACK: {2}\\r\\nDEFENSE: {3}\\r\\nSP. ATK: {4}\\r\\nSP. DEF: {5}\\r\\nSPEED: {6}", pokemon.totalhp,pokemon.attack,pokemon.defense,pokemon.speed,pokemon.spatk,pokemon.spdef)) end def pbThrowAndDeflect(ball,targetBattler) end def pbThrow(ball,shakes,targetBattler) @briefmessage=false pokeballThrow(ball,shakes,targetBattler) end def pbThrowSuccess if !@opponent @briefmessage=false $game_system.bgm_play("../ME/PkmRS-Caught.mid") frames=(3.5*Graphics.frame_rate).to_i frames.times do pbGraphicsUpdate pbInputUpdate end end end end
PokeBattle_DamageState
[
Selecionar
] [
-
]
class PokeBattle_DamageState attr_accessor :hplost # HP lost by opponent, including life points lost by Substitute attr_accessor :critical # Critical hit flag attr_accessor :focusband # Focus Band possible attr_accessor :focusbandused # Focus Band actually used attr_accessor :calcdamage # Calculated damage attr_accessor :endured # Damage was endured attr_accessor :typemod # Type effectiveness attr_accessor :substitute # A Substitute took the damage def reset @hplost=0 @critical=false @calcdamage=0 @focusband=false @focusbandused=false @endured=false @typemod=0 @substitute=false end def initialize reset end end
PokeBattle_Battle
[
Selecionar
] [
-
]
def pbGetBallType(ball) balls=[ :POKeBALL, :GREATBALL, :SAFARIBALL, :ULTRABALL, :MASTERBALL, :NETBALL, :DIVEBALL, :NESTBALL, :REPEATBALL, :TIMERBALL, :LUXURYBALL, :PREMIERBALL ] balltypes=[] for i in 0...balls.length if hasConst?(PBItems,balls[i]) value=PBItems.const_get(balls[i]) balltypes[value]=i end end balltype=balltypes[ball] balltype=0 if !balltype return balltype end module PokeBattle_BattleCommon def pbStorePokemon(pokemon) if pbDisplayConfirm(_INTL("Would you like to give a nickname to {1}?",pokemon.name)) species=PBSpecies.getName(pokemon.species) nickname=@scene.pbNameEntry(_INTL("{1}'s nickname?",species)) pokemon.name=nickname if nickname!="" end if self.pbPlayer.party.length<6 self.pbPlayer.party[self.pbPlayer.party.length]=pokemon else oldcurbox=$PokemonStorage.currentBox storedbox=$PokemonStorage.pbStoreCaught(pokemon) if storedbox<0 pbDisplayPaused(_INTL("Can't catch any more...")) else curboxname=$PokemonStorage[oldcurbox].name boxname=$PokemonStorage[storedbox].name creator=nil if $PokemonGlobal.seenStorageCreator creator=pbGetStorageCreator end if storedbox!=oldcurbox if creator pbDisplayPaused(_INTL("Box \\"{1}\\" on {2}'s PC was full.",curboxname,creator)) else pbDisplayPaused(_INTL("Box \\"{1}\\" on someone's PC was full.",curboxname)) end pbDisplayPaused(_INTL("{1} was transferred to box \\"{2}.\\"",pokemon.name,boxname)) else if creator pbDisplayPaused(_INTL("{1} was transferred to {2}'s PC.",pokemon.name,creator)) else pbDisplayPaused(_INTL("{1} was transferred to someone's PC.",pokemon.name)) end pbDisplayPaused(_INTL("It was stored in box \\"{1}.\\"",boxname)) end end end end def pbThrowPokeBall(ball,rareness=nil) if pbIsSnagBall?(ball) pbSnagPokeBall(ball,rareness) return end itemname=PBItems.getName(ball) pbDisplayBrief(_INTL("{1} threw one {2}!",self.pbPlayer.name,itemname)) if @opponent @scene.pbThrowAndDeflect(ball,1) pbDisplay(_INTL("The Trainer blocked the Ball! Don't be a thief!")) else battler=self.battlers[1] if battler.hp<=0 battler=battler.pbPartner end if battler.hp<=0 pbDisplay(_INTL("But there was no target...")) return end pokemon=battler.pokemon species=pokemon.species if !rareness dexdata=pbOpenDexData pbDexDataOffset(dexdata,species,16) rareness=dexdata.fgetb # Get rareness from dexdata file dexdata.close end a=battler.totalhp b=battler.hp case ball when PBItems::GREATBALL rareness=(rareness*3/2).floor when PBItems::SAFARIBALL rareness=(rareness*3/2).floor when PBItems::ULTRABALL rareness*=2 when PBItems::NETBALL rareness*=3 if battler.pbHasType?(PBTypes::BUG) || battler.pbHasType?(PBTypes::WATER) when PBItems::DIVEBALL rareness=(rareness*7/2).floor if @environment==PBEnvironment::Underwater when PBItems::TIMERBALL if @turncount>30 rareness*=4 else rareness=rareness*(@turncount+10)/10 end when PBItems::REPEATBALL rareness*=3 if self.pbPlayer.owned[battler.species] when PBItems::NESTBALL if battler.level<30 rareness*=(40-battler.level)/10 end end x=(((a*3-b*2)*rareness)/(a*3)).floor if battler.status==PBStatuses::SLEEP|| battler.status==PBStatuses::FROZEN x*=2 elsif battler.status!=0 x=(x*3/2).floor end shakes=0 if x>255 || ball==PBItems::MASTERBALL shakes=4 else x=1 if x==0 y = 0x000FFFF0 / (Math.sqrt(Math.sqrt( 0x00FF0000/x ) ) ) shakes+=1 if pbRandom(65536)<y shakes+=1 if pbRandom(65536)<y shakes+=1 if pbRandom(65536)<y shakes+=1 if pbRandom(65536)<y end @scene.pbThrow(ball,shakes,battler.index) case shakes when 0 pbDisplay(_INTL("Oh no! The Pokémon broke free!")) when 1 pbDisplay(_INTL("Aww... it appeared to be caught!")) when 2 pbDisplay(_INTL("Aargh! Almost had it!")) when 3 pbDisplay(_INTL("Shoot! It was so close, too!")) when 4 pbDisplayBrief(_INTL("Gotcha! {1} was caught!",pokemon.name)) @scene.pbThrowSuccess @decision=4 if isConst?(ball,PBItems,:LUXURYBALL) pokemon.happiness=200 end pokemon.ballused=pbGetBallType(ball) if !self.pbPlayer.owned[species] pbDisplayPaused(_INTL("{1}'s data was added to the Pokédex.",pokemon.name)) self.pbPlayer.owned[species]=true @scene.pbShowPokedex(species) end pbStorePokemon(pokemon) end end end def pbSnagPokeBall(ball,rareness=nil) itemname=PBItems.getName(ball) pbDisplayBrief(_INTL("{1} threw one {2}!",self.pbPlayer.name,itemname)) battler=self.battlers[1] if battler.hp<=0 battler=battler.pbPartner end if battler.hp<=0 pbDisplay(_INTL("But there was no target...")) return end pokemon=battler.pokemon species=pokemon.species if !rareness dexdata=pbOpenDexData pbDexDataOffset(dexdata,species,16) rareness=dexdata.fgetb # Get rareness from dexdata file dexdata.close end a=battler.totalhp b=battler.hp case ball when PBItems::GREATBALL rareness=(rareness*3/2).floor when PBItems::SAFARIBALL rareness=(rareness*3/2).floor when PBItems::ULTRABALL rareness*=2 when PBItems::NETBALL rareness*=3 if battler.pbHasType?(PBTypes::BUG) || battler.pbHasType?(PBTypes::WATER) when PBItems::DIVEBALL rareness=(rareness*7/2).floor if @environment==PBEnvironment::Underwater when PBItems::TIMERBALL if @turncount>30 rareness*=4 else rareness=rareness*(@turncount+10)/10 end when PBItems::REPEATBALL rareness*=3 if self.pbPlayer.owned[battler.species] when PBItems::NESTBALL if battler.level<30 rareness*=(40-battler.level)/10 end end x=(((a*3-b*2)*rareness)/(a*3)).floor if battler.status==PBStatuses::SLEEP|| battler.status==PBStatuses::FROZEN x*=2 elsif battler.status!=0 x=(x*3/2).floor end shakes=0 if x>255 || ball==PBItems::MASTERBALL shakes=4 else x=1 if x==0 y = 0x000FFFF0 / (Math.sqrt(Math.sqrt( 0x00FF0000/x ) ) ) shakes+=1 if pbRandom(65536)<y shakes+=1 if pbRandom(65536)<y shakes+=1 if pbRandom(65536)<y shakes+=1 if pbRandom(65536)<y end @scene.pbThrow(ball,shakes,battler.index) case shakes when 0 pbDisplay(_INTL("Oh no! The Pokémon broke free!")) when 1 pbDisplay(_INTL("Aww... it appeared to be caught!")) when 2 pbDisplay(_INTL("Aargh! Almost had it!")) when 3 pbDisplay(_INTL("Shoot! It was so close, too!")) when 4 pbDisplayBrief(_INTL("Gotcha! {1} was caught!",pokemon.name)) @scene.pbThrowSuccess if @opponent pbRemoveFromParty(battler.index,battler.pokemonIndex) # No need to add to player's party, happens in pbStorePokemon battler.pbReset else @decision=4 end pokemon.ot=$Trainer.name pokemon.trainerID=$Trainer.id if isConst?(ball,PBItems,:LUXURYBALL) pokemon.happiness=200 end pokemon.ballused=pbGetBallType(ball) if !self.pbPlayer.owned[species] pbDisplayPaused(_INTL("{1}'s data was added to the Pokédex.",pokemon.name)) self.pbPlayer.owned[species]=true @scene.pbShowPokedex(species) end pbStorePokemon(pokemon) end end end class PokeBattle_Battle attr_reader(:scene) # Scene object for this battle attr_accessor(:decision) # Decision: 0=undecided; 1=win; 2=loss; 3=escaped; 4=caught attr_reader(:battlers) # Currently active Pokémon attr_reader(:sides) # Effects common to each side of a battle attr_reader(:party1) # Player's Pokémon party attr_reader(:party2) # Foe's Pokémon party attr_accessor(:choices) # Choices made by each Pokémon this round attr_accessor(:internalbattle) # Internal battle flag attr_reader(:player) # Player trainer attr_reader(:opponent) # Opponent trainer attr_accessor(:endspeech) # Speech by opponent when player wins attr_accessor(:endspeech2) # Speech by opponent when player wins attr_accessor(:endspeechwin) # Speech by opponent when opponent wins attr_accessor(:endspeechwin2) # Speech by opponent when opponent wins attr_accessor(:doublebattle) # Double battle flag attr_accessor(:weather) # Current weather, custom methods should use pbWeather instead attr_accessor(:shiftStyle) # Shift/Set "battle style" option attr_accessor(:battlescene) # "Battle scene" option attr_accessor(:moneygained) # Money gained in battle by using Pay Day attr_accessor(:synchronize) # Synchronize state attr_accessor(:items) # Items held by opponents attr_accessor(:weatherduration) # Duration of current weather, or -1 if indefinite attr_accessor(:environment) # Battle surroundings attr_reader(:switching) # True if during the switching phase of the round attr_accessor(:fullparty1) # True if player's party's max size is 6 instead of 3 attr_accessor(:fullparty2) # True if opponent's party's max size is 6 instead of 3 attr_accessor(:debug) # Debug flag attr_accessor(:cantescape) # True if can't escape attr_reader(:phase) # Phase of the round. include PokeBattle_BattleCommon class BattleAbortedException < Exception; end def pbAbort raise BattleAbortedException.new("Battle aborted") end def initialize(scene,p1,p2,player,opponent) @scene=scene @party1=p1 @party2=p2 if opponent && player.is_a?(Array) && player.length==0 player=player[0] end if opponent && opponent.is_a?(Array) && opponent.length==0 opponent=opponent[0] end @player=player # PokeBattle_Trainer object @opponent=opponent # PokeBattle_Trainer object @environment=PBEnvironment::None # Environment for battle (ex. Tall grass, caves, still water...) @weatherduration=0 @decision=0 @battlers=[] @sides=[] @priority=[] @participants=[] @switching=false @items=nil @synchronize=[-1,-1,0] @internalbattle=true @usepriority=false @shiftStyle=true @battlescene=true @fullparty1=false @fullparty2=false @struggle=PokeBattle_Move.pbFromPBMove(self,PBMove.new(PBMoves::STRUGGLE)) @struggle.pp=-1 @debug=false @debugupdate=0 @endspeech="" @endspeech2="" @endspeechwin="" @endspeechwin2="" @doublebattle=false @runCommand=0 @moneygained=0 @turncount=0 @choices=[ [0,0,nil,-1],[0,0,nil,-1],[0,0,nil,-1],[0,0,nil,-1] ] if p1.length==0 raise ArgumentError.new(_INTL("Party 1 has no Pokémon.")) return end if p2.length==0 raise ArgumentError.new(_INTL("Party 2 has no Pokémon.")) return end if p2.length>2 && !opponent raise ArgumentError.new(_INTL("Wild battles with more than two Pokémon are not allowed.")) return end sides[0]=PokeBattle_ActiveSide.new # player's side sides[1]=PokeBattle_ActiveSide.new # foe's side for i in 0..3 battlers[i]=PokeBattle_Battler.new(self,i) end @decision=0 @opponent=opponent @weather=0 end def pbIsOpposing?(index) return (index%2)==1 end def pbIsDoubleBattler?(index) return (index>=2) end def pbParty(index) return pbIsOpposing?(index) ? party2 : party1 end def pbThisEx(battlerindex,pokemonindex) party=pbParty(battlerindex) if pbIsOpposing?(battlerindex) if @opponent return _INTL("Foe {1}",party[pokemonindex].name) else return _INTL("Wild {1}",party[pokemonindex].name) end else return _INTL("{1}",party[pokemonindex].name) end end def pbFindNextUnfainted(party,start,finish=-1) finish=party.length if finish<0 for i in start...finish next if !party[i] if party[i].hp>0 && !party[i].egg? return i end end return -1 end def pbOwnedByPlayer?(index) return false if pbIsOpposing?(index) return false if @player.is_a?(Array) && index==2 return true end def pbSecondPartyBegin(battlerIndex) if pbIsOpposing?(battlerIndex) return @fullparty2 ? 6 : 3 else return @fullparty1 ? 6 : 3 end end def pbRemoveFromParty(battlerIndex,partyIndex) party=pbParty(battlerIndex) side=(pbIsOpposing?(battlerIndex)) ? @opponent : @player party[partyIndex]=nil if !side || !side.is_a?(Array) # Wild or single opponent party.compact! else j=0 for i in 0...pbSecondPartyBegin(battlerIndex) if party[i] party[j]=party[i] j+=1 end end j=pbSecondPartyBegin(battlerIndex) for i in pbSecondPartyBegin(battlerIndex)...party.length if party[i] party[j]=party[i] j+=1 end end end end def pbAddToPlayerParty(pokemon) party=pbParty(0) for i in 0...party.length if pbIsOwner?(0,i) && !party[i] party[i]=pokemon end end end def pbIsOwner?(battlerIndex,partyIndex) secondParty=pbSecondPartyBegin(battlerIndex) if !pbIsOpposing?(battlerIndex) if !@player || !@player.is_a?(Array) return true end return (battlerIndex==0) ? partyIndex<secondParty : partyIndex>=secondParty else if !@opponent || !@opponent.is_a?(Array) return true end return (battlerIndex==1) ? partyIndex<secondParty : partyIndex>=secondParty end end def pbPartyGetOwner(battlerIndex,partyIndex) secondParty=pbSecondPartyBegin(battlerIndex) if !pbIsOpposing?(battlerIndex) if !@player || !@player.is_a?(Array) return @player end return (partyIndex<secondParty) ? @player[0] : @player[1] else if !@opponent || !@opponent.is_a?(Array) return @opponent end return (partyIndex<secondParty) ? @opponent[0] : @opponent[1] end end def pbGetOwner(battlerIndex) if pbIsOpposing?(battlerIndex) if @opponent.is_a?(Array) return (battlerIndex==1) ? @opponent[0] : @opponent[1] else return @opponent end else if @player.is_a?(Array) return (battlerIndex==0) ? @player[0] : @player[1] else return @player end end end def pbGetOwnerPartner(battlerIndex) if pbIsOpposing?(battlerIndex) if @opponent.is_a?(Array) return (battlerIndex==1) ? @opponent[1] : @opponent[0] else return @opponent end else if @player.is_a?(Array) return (battlerIndex==0) ? @player[1] : @player[0] else return @player end end end def pbPlayer if @player.is_a?(Array) return @player[0] else return @player end end def pbGetOwnerItems(battlerIndex) return [] if !@items if pbIsOpposing?(battlerIndex) if @opponent.is_a?(Array) return (battlerIndex==1) ? @items[0] : @items[1] else return @items end else return [] end end def pbStartBattle begin pbStartBattleCore rescue BattleAbortedException @decision=0 @scene.pbEndBattle(@decision) end return @decision end MAXPARTYSIZE=6 def pbStartBattleCore if !@fullparty1 && @party1.length>MAXPARTYSIZE raise ArgumentError.new(_INTL("Party 1 has more than six Pokémon.")) end if !@fullparty2 && @party2.length>MAXPARTYSIZE raise ArgumentError.new(_INTL("Party 2 has more than six Pokémon.")) end if !@opponent # # Initialize wild Pokémon # if @party2.length==1 if @doublebattle raise _INTL("Only two wild Pokémon are allowed in double battles") end wildpoke=@party2[0] self.pbPlayer.seen[wildpoke.species]=true @battlers[1].pbInitialize(wildpoke,0,false) @scene.pbStartBattle(self) pbDisplayPaused(_INTL("Wild {1} appeared!",wildpoke.name)) elsif @party2.length==2 if !@doublebattle raise _INTL("Only one wild Pokémon is allowed in single battles") end @battlers[1].pbInitialize(@party2[0],0,false) @battlers[3].pbInitialize(@party2[1],0,false) self.pbPlayer.seen[@party2[0].species]=true self.pbPlayer.seen[@party2[1].species]=true @scene.pbStartBattle(self) pbDisplayPaused(_INTL("Wild {1} and\\r\\n{2} appeared!", @party2[0].name,@party2[1].name)) else raise _INTL("Only one or two wild Pokémon are allowed") end elsif @doublebattle # # Initialize opponents in double battles # if @opponent.is_a?(Array) if @opponent.length==1 @opponent=@opponent[0] elsif @opponent.length!=2 raise _INTL("Opponents with zero or more than two people are not allowed") end end if @player.is_a?(Array) if @player.length==1 @player=@player[0] elsif @player.length!=2 raise _INTL("Player trainers with zero or more than two people are not allowed") end end @scene.pbStartBattle(self) if @opponent.is_a?(Array) pbDisplayPaused(_INTL("{1} and {2} want to battle!",@opponent[0].fullname,@opponent[1].fullname)) sendout1=pbFindNextUnfainted(@party2,0,pbSecondPartyBegin(1)) raise _INTL("Opponent 1 has no unfainted Pokémon") if sendout1<0 sendout2=pbFindNextUnfainted(@party2,pbSecondPartyBegin(1)) raise _INTL("Opponent 2 has no unfainted Pokémon") if sendout2<0 pbDisplay(_INTL("{1} sent\\r\\nout {2}!",@opponent[0].fullname,@party2[sendout1].name)) pbDisplayBrief(_INTL("{1} sent\\r\\nout {2}!",@opponent[1].fullname,@party2[sendout2].name)) else pbDisplayPaused(_INTL("{1}\\r\\nwould like to battle!",@opponent.fullname)) sendout1=pbFindNextUnfainted(@party2,0) sendout2=pbFindNextUnfainted(@party2,sendout1+1) if sendout1<0 || sendout2<0 raise _INTL("Opponent doesn't have two unfainted Pokémon") end pbDisplayBrief(_INTL("{1} sent\\r\\nout {2} and {3}!",@opponent.fullname,@party2[sendout1].name,@party2[sendout2].name)) end self.pbPlayer.seen[@party2[sendout1].species]=true self.pbPlayer.seen[@party2[sendout2].species]=true @battlers[1].pbInitialize(@party2[sendout1],sendout1,false) @battlers[3].pbInitialize(@party2[sendout2],sendout2,false) @scene.pbTrainerSendOut(1,@party2[sendout1]) @scene.pbTrainerSendOut(3,@party2[sendout2]) else # # Initialize opponent in single battles # sendout=pbFindNextUnfainted(@party2,0) if sendout<0 raise _INTL("Trainer has no unfainted Pokémon") end if @opponent.is_a?(Array) raise _INTL("Opponent trainer must be only one person in single battles") if @opponent.length!=1 @opponent=@opponent[0] end if @player.is_a?(Array) raise _INTL("Player trainer must be only one person in single battles") if @player.length!=1 @player=@player[0] end trainerpoke=@party2[0] @scene.pbStartBattle(self) pbDisplayPaused(_INTL("{1}\\r\\nwould like to battle!",@opponent.fullname)) pbDisplayBrief(_INTL("{1} sent\\r\\nout {2}!",@opponent.fullname,trainerpoke.name)) self.pbPlayer.seen[trainerpoke.species]=true @battlers[1].pbInitialize(trainerpoke,sendout,false) @scene.pbTrainerSendOut(1,trainerpoke) end # # Initialize players in double battles # if @doublebattle if @player.is_a?(Array) sendout1=pbFindNextUnfainted(@party1,0,pbSecondPartyBegin(0)) raise _INTL("Player 1 has no unfainted Pokémon") if sendout1<0 sendout2=pbFindNextUnfainted(@party1,pbSecondPartyBegin(0)) raise _INTL("Player 2 has no unfainted Pokémon") if sendout2<0 pbDisplayBrief(_INTL("{1} sent\\r\\nout {2}! Go! {3}!",@player[1].fullname,@party1[sendout2].name,@party1[sendout1].name)) self.pbPlayer.seen[@party1[sendout1].species]=true self.pbPlayer.seen[@party1[sendout2].species]=true else sendout1=pbFindNextUnfainted(@party1,0) sendout2=pbFindNextUnfainted(@party1,sendout1+1) if sendout1<0 || sendout2<0 raise _INTL("Player doesn't have two unfainted Pokémon") end pbDisplayBrief(_INTL("Go! {1} and {2}!",@party1[sendout1].name,@party1[sendout2].name)) end @battlers[0].pbInitialize(@party1[sendout1],sendout1,false) @battlers[2].pbInitialize(@party1[sendout2],sendout2,false) @scene.pbSendOut(0,@party1[sendout1]) @scene.pbSendOut(2,@party1[sendout2]) else # # Initialize player in single battles # sendout=pbFindNextUnfainted(@party1,0) if sendout<0 raise _INTL("Player has no unfainted Pokémon") end playerpoke=@party1[sendout] pbDisplayBrief(_INTL("Go! {1}!",playerpoke.name)) @battlers[0].pbInitialize(playerpoke,sendout,false) @scene.pbSendOut(0,playerpoke) end # # Initialize battle # if @weather==PBWeather::SUNNYDAY pbDisplay(_INTL("The sunlight is harsh.")) elsif @weather==PBWeather::RAINDANCE pbDisplay(_INTL("It is raining.")) elsif @weather==PBWeather::SANDSTORM pbDisplay(_INTL("A sandstorm is raging.")) elsif @weather==PBWeather::HAIL pbDisplay(_INTL("Hail is falling.")) end # Abilities pbOnActiveAll # Now begin the battle loop @turncount=0 loop do if @debug if @turncount>=200 @decision=-1 PBDebug.log("***[Undecided after 200 rounds]") pbAbort break end if $PBDebugExceptions>=50 @decision=-1 PBDebug.log("***[Battle aborted]") pbAbort break end PBDebug.log("***Round #{@turncount+1}") end PBDebug.logonerr{ pbCommandPhase } break if @decision>0 PBDebug.logonerr{ pbAttackPhase } break if @decision>0 PBDebug.logonerr{ pbEndOfRoundPhase } break if @decision>0 @turncount+=1 end case @decision when 1 #win if @opponent @scene.pbTrainerBattleSuccess if @opponent.is_a?(Array) pbDisplayPaused(_INTL("{1} and {2} were defeated!",@opponent[0].fullname,@opponent[1].fullname)) else pbDisplayPaused(_INTL("Player defeated\\r\\n{1}!",@opponent.fullname)) end @scene.pbShowOpponent(0) pbDisplayPaused(@endspeech.gsub(/\\\\[Pp][Nn]/,self.pbPlayer.name)) if @opponent.is_a?(Array) @scene.pbHideOpponent @scene.pbShowOpponent(1) pbDisplayPaused(@endspeech2.gsub(/\\\\[Pp][Nn]/,self.pbPlayer.name)) end if @internalbattle maxlevel=0 for i in @party2 next if !i maxlevel=i.level if maxlevel<i.level end if @opponent.is_a?(Array) maxlevel*=@opponent[0].moneyEarned+@opponent[1].moneyEarned else maxlevel*=@opponent.moneyEarned end # If a participant is holding Amulet Coin, money earned is doubled for i in 0...@party1.length if @participants[i] && @party1[i].hp>0 && !@party1[i].egg? && @party1[i].item==PBItems::AMULETCOIN maxlevel*=2 break end end self.pbPlayer.money+=maxlevel self.pbPlayer.money=999999 if self.pbPlayer.money>999999 if maxlevel>0 pbDisplayPaused(_INTL("{1} got ${2}\\r\\nfor winning!",self.pbPlayer.name,maxlevel)) end end end if @internalbattle && @moneygained>0 pbDisplayPaused(_INTL("{1} picked up ${2}!",self.pbPlayer.name,moneygained)) self.pbPlayer.money+=moneygained self.pbPlayer.money=999999 if self.pbPlayer.money>999999 end when 2 #lose if @internalbattle pbDisplayPaused(_INTL("{1} is out of usable Pokémon!",self.pbPlayer.name)) moneylost=pbMaxLevel(@party1) multiplier=[8,16,24,32,48,64,80,100,120] moneylost*=multiplier[[8,self.pbPlayer.numbadges].min] moneylost=self.pbPlayer.money if moneylost>self.pbPlayer.money self.pbPlayer.money-=moneylost if @opponent if @opponent.is_a?(Array) pbDisplayPaused(_INTL("Player lost against {1} and {2}!",@opponent[0].fullname,@opponent[1].fullname)) else pbDisplayPaused(_INTL("Player lost against\\r\\n{1}!",@opponent.fullname)) end if moneylost>0 pbDisplayPaused(_INTL("{1} paid ${2}\\r\\nas the prize money...",self.pbPlayer.name,moneylost)) pbDisplayPaused(_INTL("...")) end else if moneylost>0 pbDisplayPaused(_INTL("{1} panicked and lost\\r\\n${2}...",self.pbPlayer.name,moneylost)) pbDisplayPaused(_INTL("...")) end end pbDisplayPaused(_INTL("{1} whited out!",self.pbPlayer.name)) else @scene.pbShowOpponent(0) pbDisplayPaused(@endspeechwin.gsub(/\\\\[Pp][Nn]/,self.pbPlayer.name)) if @opponent.is_a?(Array) @scene.pbHideOpponent @scene.pbShowOpponent(1) pbDisplayPaused(@endspeechwin2.gsub(/\\\\[Pp][Nn]/,self.pbPlayer.name)) end end end @scene.pbEndBattle(@decision) return @decision end def pbMaxLevel(party) lv=0 for i in party next if !i lv=i.level if lv<i.level end return lv end def pbCheckGlobalAbility(a) for i in 0..3 # in order from own first, opposing first, own second, opposing second if @battlers[i].ability==a return @battlers[i] end end return nil end def pbWeather for i in 0..3 if @battlers[i].ability==PBAbilities::CLOUDNINE||@battlers[i].ability==PBAbilities::AIRLOCK return 0 end end return @weather end def pbRun(idxPokemon,duringBattle=false) thispkmn=@battlers[idxPokemon] if(pbIsOpposing?(idxPokemon)) if @opponent return 0 else pbDisplay(_INTL("{1} fled!",thispkmn.pbThis)) @decision=3 end end if @opponent if $DEBUG && Input.press?(Input::CTRL) if pbDisplayConfirm(_INTL("Treat this battle as a win?")) @decision=1 return 1 elsif pbDisplayConfirm(_INTL("Treat this battle as a loss?")) @decision=2 return 1 end elsif @internalbattle pbDisplayPaused(_INTL("No! There's no running from a Trainer battle!")) elsif pbDisplayConfirm(_INTL("Would you like to forfeit the match and quit now?")) pbDisplay(_INTL("{1} forfeited the match!",player.name)) @decision=3 return 1 end return 0 end if $DEBUG && Input.press?(Input::CTRL) pbDisplayPaused(_INTL("Got away safely!")) @decision=3 return 1 end if @cantescape pbDisplayPaused(_INTL("Can't escape!")) return 0 end if thispkmn.item==PBItems::SMOKEBALL if duringBattle pbDisplayPaused(_INTL("Got away safely!")) else pbDisplayPaused(_INTL("{1} fled using its Smoke Ball!",thispkmn.pbThis)) end @decision=3 return 1 end if thispkmn.ability==PBAbilities::RUNAWAY if duringBattle pbDisplayPaused(_INTL("Got away safely!")) else pbDisplayPaused(_INTL("{1} fled using Run Away!",thispkmn.pbThis)) end @decision=3 return 1 end if !duringBattle&&!pbCanSwitch?(idxPokemon,-1,false) # TODO: Use real messages pbDisplayPaused(_INTL("Can't escape!")) return 0 end # Note: not pbSpeed, because using unmodified Speed speedPlayer=@battlers[idxPokemon].speed opposing=@battlers[idxPokemon].pbOppositeOpposing if opposing.hp<=0 opposing=opposing.pbPartner end if opposing.hp>0 speedEnemy=opposing.speed if speedPlayer>speedEnemy rate=256 else speedEnemy=1 if speedEnemy<=0 rate=speedPlayer*128/speedEnemy rate+=@runCommand*30 rate&=0xFF end else rate=256 end ret=1 if pbAIRandom(256)<rate pbDisplayPaused(_INTL("Got away safely!")) @decision=3 else pbDisplayPaused(_INTL("Can't escape!")) ret=-1 end if !duringBattle @runCommand+=1 end return ret end def pbRegisterMove(idxPokemon,idxMove) thispkmn=@battlers[idxPokemon] # printRetry("pbRegisterMove #{idxPokemon} #{idxMove}") thismove=thispkmn.moves[idxMove] if !pbCanChooseMove?(idxPokemon,idxMove,1) return false end @choices[idxPokemon][0]=1 # Move @choices[idxPokemon][1]=idxMove # Index of move @choices[idxPokemon][2]=thismove # Move object @choices[idxPokemon][3]=-1 # No target chosen return true end def pbCanChooseMove?(idxPokemon,idxMove,showMessages) thispkmn=@battlers[idxPokemon] thismove=thispkmn.moves[idxMove] opp1=thispkmn.pbOpposing1 opp2=thispkmn.pbOpposing2 if !thismove||thismove.id==0 return false end if thismove.pp<=0 if showMessages pbDisplayPaused(_INTL("There's no PP left for this move!")) end return false end if thispkmn.effects[PBEffects::ChoiceBand]!=0 && thismove.id!=thispkmn.effects[PBEffects::ChoiceBand]&& thispkmn.item.id==PBItems::CHOICEBAND if showMessages pbDisplayPaused(_INTL("{1} allows it to use only {2}!",thispkmn.pbThis,thispkmn.effects[PBEffects::ChoiceBand].name)) end return false end if opp1.effects[PBEffects::Imprison] if thismove.id==opp1.moves[0].id || thismove.id==opp1.moves[1].id || thismove.id==opp1.moves[2].id || thismove.id==opp1.moves[3].id if showMessages pbDisplayPaused(_INTL("{1} can't use the sealed {2}!",thispkmn.pbThis,thismove.name)) end PBDebug.log("[CanChoose][#{opp1.pbThis} has: #{opp1.moves[0].name}, #{opp1.moves[1].name},#{opp1.moves[2].name},#{opp1.moves[3].name}]") return false end end if opp2.effects[PBEffects::Imprison] if thismove.id==opp2.moves[0].id || thismove.id==opp2.moves[1].id || thismove.id==opp2.moves[2].id || thismove.id==opp2.moves[3].id if showMessages pbDisplayPaused(_INTL("{1} can't use the sealed {2}!",thispkmn.pbThis,thismove.name)) end PBDebug.log("[CanChoose][#{opp2.pbThis} has: #{opp2.moves[0].name}, #{opp2.moves[1].name},#{opp2.moves[2].name},#{opp2.moves[3].name}]") return false end end if thispkmn.effects[PBEffects::Taunt] > 0 && thismove.basedamage == 0 if showMessages pbDisplayPaused(_INTL("{1} can't use {2} after the Taunt!",thispkmn.pbThis,thismove.name)) end return false end if thispkmn.effects[PBEffects::Torment] if thismove.id==thispkmn.lastMoveUsed if showMessages pbDisplayPaused(_INTL("{1} can't use the same move in a row due to the Torment!",thispkmn.pbThis)) end return false end end if thismove.id==thispkmn.effects[PBEffects::DisableMove] if showMessages pbDisplayPaused(_INTL("{1}'s {2} is disabled!",thispkmn.pbThis,thismove.name)) end return false end if thispkmn.effects[PBEffects::Encore]>0 && idxMove!=thispkmn.effects[PBEffects::EncoreIndex] return false end return true end def pbAutoChooseMove(idxPokemon,showMessages=true) thispkmn=@battlers[idxPokemon] if thispkmn.hp<=0 @choices[idxPokemon][0]=0 @choices[idxPokemon][1]=0 @choices[idxPokemon][2]=nil return end if thispkmn.effects[PBEffects::Encore] > 0 && pbCanChooseMove?(idxPokemon,thispkmn.effects[PBEffects::EncoreIndex],false) PBDebug.log("[Auto choosing Encore move...]") @choices[idxPokemon][0]=1 # Move @choices[idxPokemon][1]=thispkmn.effects[PBEffects::EncoreIndex] # Index of move @choices[idxPokemon][2]=@battlers[idxPokemon].moves[thispkmn.effects[PBEffects::EncoreIndex]] @choices[idxPokemon][3]=-1 else if !pbIsOpposing?(idxPokemon) pbDisplayPaused(_INTL("{1} has no moves left!",thispkmn.name)) if showMessages end @choices[idxPokemon][0]=1 # Move @choices[idxPokemon][1]=-1 # Index of move @choices[idxPokemon][2]=@struggle @choices[idxPokemon][3]=-1 end end def pbOnActiveAll for i in 0..3 # update participants in battles (unfainted participants will earn EXP even if they faint in between) if pbIsOpposing?(i) @battlers[i].pbUpdateParticipants end end @usepriority=false priority=pbPriority for i in priority if i.ability==PBAbilities::DRIZZLE && i.hp>0 @weather=PBWeather::RAINDANCE @weatherduration=-1 pbDisplay(_INTL("{1}'s Drizzle made it rain!",i.pbThis)) end if i.ability==PBAbilities::SANDSTREAM && i.hp>0 @weather=PBWeather::SANDSTORM @weatherduration=-1 pbDisplay(_INTL("{1}'s Sand Stream whipped up a sandstorm!",i.pbThis)) end if i.ability==PBAbilities::DROUGHT && i.hp>0 @weather=PBWeather::SUNNYDAY @weatherduration=-1 pbDisplay(_INTL("{1}'s Drought intensified the sun's rays!",i.pbThis)) end end # Intimidate for i in 0..3 pkmn=@battlers[i] next if pkmn.hp<=0 for j in 0..3 if pkmn.ability==PBAbilities::INTIMIDATE && pkmn.pbIsOpposing?(j) @battlers[j].pbReduceAttackStatStageIntimidate(pkmn) end end end # Trace for i in 0..3 @battlers[i].pbTrace(true) end # Forecast for i in 0..3 pkmn=@battlers[i] next if pkmn.hp<=0 @battlers[i].pbForecast end end def pbOnActiveOne(pkmn) if pkmn.hp<=0 return false end for i in 0..3 # update participants in battles (unfainted participants will earn EXP even if they faint in between) if pbIsOpposing?(i) @battlers[i].pbUpdateParticipants end end if pkmn.pbOwnSide.effects[PBEffects::Spikes] > 0 if pkmn.ability!=PBAbilities::LEVITATE && !pkmn.pbHasType?(PBTypes::FLYING) spikesdiv=[0,8,6,4] pkmn.pbReduceHP(pkmn.hp/spikesdiv[pkmn.pbOwnSide.effects[PBEffects::Spikes]]) pbDisplayPaused(_INTL("{1} is hurt by Spikes!",pkmn.pbThis)) end end if pkmn.hp<=0 pkmn.pbFaint end for i in 0..3 @battlers[i].pbAbilityCureCheck end if pkmn.hp<=0 pbGainEXP pbSwitch return false end if pkmn.ability==PBAbilities::DRIZZLE && pkmn.hp>0 @weather=PBWeather::RAINDANCE @weatherduration=-1 pbDisplay(_INTL("{1}'s Drizzle made it rain!",pkmn.pbThis)) end if pkmn.ability==PBAbilities::SANDSTREAM && pkmn.hp>0 @weather=PBWeather::SANDSTORM @weatherduration=-1 pbDisplay(_INTL("{1}'s Sand Stream whipped up a sandstorm!",pkmn.pbThis)) end if pkmn.ability==PBAbilities::DROUGHT && pkmn.hp>0 @weather=PBWeather::SUNNYDAY @weatherduration=-1 pbDisplay(_INTL("{1}'s Drought intensified the sun's rays!",pkmn.pbThis)) end if pkmn.ability==PBAbilities::INTIMIDATE && pkmn.hp>0 for i in 0..3 if pkmn.pbIsOpposing?(i) @battlers[i].pbReduceAttackStatStageIntimidate(pkmn) end end end pkmn.pbTrace(true) if pkmn.ability==PBAbilities::SPEEDBOOST && pkmn.hp>0 end for i in 0..3 pkmn.pbForecast end pkmn.pbBerryCureCheck return true end def pbCanShowCommands?(idxPokemon) thispkmn=@battlers[idxPokemon] if thispkmn.hp<=0 return false end return false if thispkmn.effects[PBEffects::TwoTurnAttack]>0 return false if thispkmn.effects[PBEffects::HyperBeam]>0 return false if thispkmn.effects[PBEffects::Rollout]>0 return false if thispkmn.effects[PBEffects::Outrage]>0 return false if thispkmn.effects[PBEffects::Uproar]>0 return false if thispkmn.effects[PBEffects::Bide]>0 return true end def pbCanShowFightMenu?(idxPokemon) thispkmn=@battlers[idxPokemon] if !pbCanShowCommands?(idxPokemon) return false end # No moves that can be chosen if !pbCanChooseMove?(idxPokemon,0,false)&& !pbCanChooseMove?(idxPokemon,1,false)&& !pbCanChooseMove?(idxPokemon,2,false)&& !pbCanChooseMove?(idxPokemon,3,false) return false end # Encore encore=thispkmn.effects[PBEffects::Encore] if thispkmn.effects[PBEffects::Encore]>0 return false end return true end def pbCanSwitchLax?(idxPokemon,pkmnidxTo,showMessages) thispkmn=@battlers[idxPokemon] if pkmnidxTo>=0 party=pbParty(idxPokemon) if pkmnidxTo>=party.length return false end if !party[pkmnidxTo] return false end if party[pkmnidxTo].egg? pbDisplayPaused(_INTL("An Egg can't battle!")) if showMessages return false end if !pbIsOwner?(idxPokemon,pkmnidxTo) owner=pbPartyGetOwner(idxPokemon,pkmnidxTo) pbDisplayPaused(_INTL("You can't switch {1}'s Pokémon with one of yours!",owner.name)) if showMessages return false end if party[pkmnidxTo].hp<=0 pbDisplayPaused(_INTL("{1} has no energy left to battle!",party[pkmnidxTo].name)) if showMessages return false end if @battlers[idxPokemon].pokemonIndex==pkmnidxTo pbDisplayPaused(_INTL("{1} is already in battle!",party[pkmnidxTo].name)) if showMessages return false end if @battlers[idxPokemon].pbPartner.pokemonIndex==pkmnidxTo pbDisplayPaused(_INTL("{1} is already in battle!",party[pkmnidxTo].name)) if showMessages return false end end return true end def pbCanSwitch?(idxPokemon,pkmnidxTo,showMessages) thispkmn=@battlers[idxPokemon] # Multi-Turn Attacks/Mean Look if !pbCanSwitchLax?(idxPokemon,pkmnidxTo,showMessages) return false end isOpposing=pbIsOpposing?(idxPokemon) party=pbParty(idxPokemon) for i in 0..3 next if isOpposing!=pbIsOpposing?(i) if choices[i][0]==2&&choices[i][1]==pkmnidxTo pbDisplayPaused(_INTL("{1} has already been selected.",party[pkmnidxTo].name)) if showMessages return false end end if thispkmn.effects[PBEffects::MultiTurn]>0 || thispkmn.effects[PBEffects::MeanLook]>=0 pbDisplayPaused(_INTL("{1} can't be switched out!",thispkmn.pbThis)) if showMessages return false end # Ingrain if thispkmn.effects[PBEffects::Ingrain] pbDisplayPaused(_INTL("{1} can't be switched out!",thispkmn.pbThis)) if showMessages return false end opp1=thispkmn.pbOpposing1 opp2=thispkmn.pbOpposing2 opp=nil if thispkmn.pbHasType?(PBTypes::STEEL) opp=opp1 if opp1.ability==PBAbilities::MAGNETPULL opp=opp2 if opp2.ability==PBAbilities::MAGNETPULL end if !thispkmn.pbHasType?(PBTypes::FLYING) && thispkmn.ability!=PBAbilities::LEVITATE opp=opp1 if opp1.ability==PBAbilities::ARENATRAP opp=opp2 if opp2.ability==PBAbilities::ARENATRAP end opp=opp1 if opp1.ability==PBAbilities::SHADOWTAG opp=opp2 if opp2.ability==PBAbilities::SHADOWTAG if opp abilityname=PBAbilities.getName(opp.ability) pbDisplayPaused(_INTL("{1}'s {2} prevents switching!",opp.pbThis,abilityname)) if showMessages return false end return true end def pbRegisterSwitch(idxPokemon,idxOther) thispkmn=@battlers[idxPokemon] if !pbCanSwitch?(idxPokemon,idxOther,false) return false else @choices[idxPokemon][0]=2 # Pokémon @choices[idxPokemon][1]=idxOther # Pokémon to switch to @choices[idxPokemon][2]=nil return true end end =begin Uses an item on a Pokémon in the player's party. =end def pbUseItemOnPokemon(item,pkmnIndex,scene) pokemon=@party1[pkmnIndex] battler=nil if pokemon.egg? scene.pbDisplay(_INTL("It won't have any effect.")) return false end for i in 0...3 if !pbIsOpposing?(i) && @battlers[i].pokemonIndex==pkmnIndex battler=@battlers[i] end end case item when PBItems::POTION return pbBattleHPItem(pokemon, battler,20,scene) when PBItems::CHERIBERRY, PBItems::PARLYZHEAL if pokemon.hp<=0 || pokemon.status!=PBStatuses::PARALYSIS scene.pbDisplay(_INTL("It won't have any effect.")) return false else scene.pbDisplay(_INTL("{1} was cured of paralysis.",pokemon.name)) pokemon.status=0 battler.status=0 if battler return true end when PBItems::CHESTOBERRY, PBItems::AWAKENING, PBItems::BLUEFLUTE if pokemon.hp<=0 || pokemon.status!=PBStatuses::SLEEP scene.pbDisplay(_INTL("It won't have any effect.")) return false else scene.pbDisplay(_INTL("{1} woke up.",pokemon.name)) pokemon.status=0 battler.status=0 if battler return true end when PBItems::PECHABERRY, PBItems::ANTIDOTE if pokemon.hp<=0 || pokemon.status!=PBStatuses::POISON scene.pbDisplay(_INTL("It won't have any effect.")) return false else scene.pbDisplay(_INTL("{1} was cured of its poisoning.",pokemon.name)) pokemon.status=0 battler.status=0 if battler return true end when PBItems::RAWSTBERRY, PBItems::BURNHEAL if pokemon.hp<=0 || pokemon.status!=PBStatuses::BURN scene.pbDisplay(_INTL("It won't have any effect.")) return false else scene.pbDisplay(_INTL("{1}'s burn was healed.",pokemon.name)) pokemon.status=0 battler.status=0 if battler return true end when PBItems::ASPEARBERRY, PBItems::ICEHEAL if pokemon.hp<=0 || pokemon.status!=PBStatuses::FROZEN scene.pbDisplay(_INTL("It won't have any effect.")) return false else scene.pbDisplay(_INTL("{1} was thawed out.",pokemon.name)) pokemon.status=0 battler.status=0 if battler return true end when PBItems::FULLRESTORE if pokemon.hp<=0 || (pokemon.status==0 && pokemon.hp==pokemon.totalhp && (!battler || battler.effects[PBEffects::Confusion]==0)) scene.pbDisplay(_INTL("It won't have any effect.")) return false else hpgain=pbItemRestoreHP(pokemon,pokemon.totalhp-pokemon.hp) battler.hp=pokemon.hp if battler pokemon.status=0 battler.status=0 if battler battler.effects[PBEffects::Confusion]=0 if battler if hpgain>0 scene.pbDisplay(_INTL("{1}'s HP was restored by {2} points.",pokemon.name,hpgain)) else scene.pbDisplay(_INTL("{1} became healthy.",pokemon.name)) end return true end when PBItems::MAXPOTION return pbBattleHPItem(pokemon, battler,pokemon.totalhp-pokemon.hp,scene) when PBItems::HYPERPOTION return pbBattleHPItem(pokemon, battler,200,scene) when PBItems::SUPERPOTION return pbBattleHPItem(pokemon, battler,50,scene) when PBItems::ORANBERRY return pbBattleHPItem(pokemon, battler,10,scene) when PBItems::BERRYJUICE return pbBattleHPItem(pokemon, battler,20,scene) when PBItems::SITRUSBERRY return pbBattleHPItem(pokemon, battler,30,scene) when PBItems::FULLHEAL, PBItems::LUMBERRY, PBItems::LAVACOOKIE if pokemon.hp<=0 || (pokemon.status==0 && (!battler || battler.effects[PBEffects::Confusion]==0)) scene.pbDisplay(_INTL("It won't have any effect.")) return false else pokemon.status=0 battler.status=0 if battler battler.effects[PBEffects::Confusion]=0 if battler scene.pbDisplay(_INTL("{1} became healthy.",pokemon.name)) return true end when PBItems::REVIVE if pokemon.hp>0 scene.pbDisplay(_INTL("It won't have any effect.")) return false else pokemon.status=0 pokemon.hp=(pokemon.totalhp/2).floor battler.pbInitialize(pokemon,pkmnindex,false) if battler scene.pbDisplay(_INTL("{1} regained health.",pokemon.name)) return true end when PBItems::MAXREVIVE if pokemon.hp>0 scene.pbDisplay(_INTL("It won't have any effect.")) return false else pokemon.status=0 pokemon.hp=pokemon.totalhp battler.pbInitialize(pokemon,pkmnindex,false) if battler scene.pbDisplay(_INTL("{1} regained health.",pokemon.name)) return true end when PBItems::FRESHWATER return pbBattleHPItem(pokemon, battler,50,scene) when PBItems::SODAPOP return pbBattleHPItem(pokemon, battler,60,scene) when PBItems::LEMONADE return pbBattleHPItem(pokemon, battler,80,scene) when PBItems::MOOMOOMILK return pbBattleHPItem(pokemon, battler,100,scene) when PBItems::ENERGYPOWDER if pbBattleHPItem(pokemon, battler,50,scene) pokemon.happiness-=5 # TODO: Don't know actual amount pokemon.happiness=0 if pokemon.happiness<0 return true end return false when PBItems::ENERGYROOT if pbBattleHPItem(pokemon, battler,200,scene) pokemon.happiness-=5 # TODO: Don't know actual amount pokemon.happiness=0 if pokemon.happiness<0 return true end return false when PBItems::HEALPOWDER if pokemon.hp<=0 || (pokemon.status==0 && (!battler || battler.effects[PBEffects::Confusion]==0)) scene.pbDisplay(_INTL("It won't have any effect.")) return false else pokemon.status=0 battler.status=0 if battler battler.effects[PBEffects::Confusion]=0 if battler scene.pbDisplay(_INTL("{1} became healthy.",pokemon.name)) pokemon.happiness-=5 # TODO: Don't know actual amount pokemon.happiness=0 if pokemon.happiness<0 return true end when PBItems::REVIVALHERB if pokemon.hp>0 scene.pbDisplay(_INTL("It won't have any effect.")) return false else pokemon.status=0 pokemon.hp=pokemon.totalhp scene.pbDisplay(_INTL("{1} regained health.",pokemon.name)) pokemon.happiness-=5 # TODO: Don't know actual amount pokemon.happiness=0 if pokemon.happiness<0 battler.pbInitialize(pokemon,pkmnindex,false) if battler return true end when PBItems::LEPPABERRY, PBItems::ETHER move=scene.pbChooseMove(pokemon,_INTL("Restore which move?")) if move>=0 if pbBattleRestorePP(pokemon,battler,move,10)==0 scene.pbDisplay(_INTL("It won't have any effect.")) return false else scene.pbDisplay(_INTL("PP was restored.")) return true end end return false when PBItems::MAXETHER move=scene.pbChooseMove(pokemon,_INTL("Restore which move?")) if move>=0 if pbBattleRestorePP(pokemon,battler,move,pokemon.moves[move].totalpp-pokemon.moves[move].pp)==0 scene.pbDisplay(_INTL("It won't have any effect.")) return false else scene.pbDisplay(_INTL("PP was restored.")) return true end end return false when PBItems::ELIXIR pprestored=0 for i in 0...pokemon.moves.length pprestored+=pbBattleRestorePP(pokemon,battler,i,10) end if pprestored==0 scene.pbDisplay(_INTL("It won't have any effect.")) return false else scene.pbDisplay(_INTL("PP was restored.")) return true end when PBItems::MAXELIXIR pprestored=0 for i in 0...pokemon.moves.length pprestored+=pbBattleRestorePP(pokemon,battler,i,pokemon.moves[i].totalpp-pokemon.moves[i].pp) end if pprestored==0 scene.pbDisplay(_INTL("It won't have any effect.")) return false else scene.pbDisplay(_INTL("PP was restored.")) return true end when PBItems::REDFLUTE if battler && battler.effects[PBEffects::Attract]>=0 battler.effects[PBEffects::Attract]=-1 scene.pbDisplay(_INTL("{1} got over its infatuation.",pokemon.name)) return true # :consumed: else scene.pbDisplay(_INTL("It won't have any effect.")) return false end when PBItems::YELLOWFLUTE, PBItems::PERSIMBERRY if battler && battler.effects[PBEffects::Confusion]>0 battler.effects[PBEffects::Confusion]=0 scene.pbDisplay(_INTL("{1} snapped out of confusion.",pokemon.name)) return true # :consumed: else scene.pbDisplay(_INTL("It won't have any effect.")) return false end else return ItemHandlers.triggerBattleUseOnPokemon(item,pokemon,battler,scene) end end =begin Uses an item on an active Pokémon. =end def pbUseItemOnBattler(item,index,scene) battler=@battlers[index] if $ItemData[item][ITEMPOCKET]==2 # Any Ball if !@opponent && @battlers[1].hp>0 && @battlers[3].hp>0 scene.pbDisplay(_INTL("It's no good! It's impossible to aim when there are two Pokémon!")) return false end if self.pbPlayer.party.length==6 && $PokemonStorage.full? scene.pbDisplay(_INTL("There is no room left in the PC!")) return false end return true end case item when PBItems::GUARDSPEC if battler.pbOwnSide.effects[PBEffects::Mist]>0 scene.pbDisplay(_INTL("It won't have any effect.")) return false else battler.pbOwnSide.effects[PBEffects::Mist]=5 scene.pbDisplay(_INTL("Ally became shrouded in Mist!")) return true end when PBItems::DIREHIT if battler.effects[PBEffects::FocusEnergy] scene.pbDisplay(_INTL("It won't have any effect.")) return false else battler.effects[PBEffects::FocusEnergy]=true scene.pbDisplay(_INTL("{1} is getting pumped!",battler.pbThis)) return true end when PBItems::XATTACK if battler.pbTooHigh?(PBStats::ATTACK) scene.pbDisplay(_INTL("It won't have any effect.")) return false else battler.stages[PBStats::ATTACK]+=1 scene.pbDisplay(_INTL("{1}'s Attack rose!",battler.pbThis)) return true end when PBItems::XDEFEND if battler.pbTooHigh?(PBStats::DEFENSE) scene.pbDisplay(_INTL("It won't have any effect.")) return false else battler.stages[PBStats::DEFENSE]+=1 scene.pbDisplay(_INTL("{1}'s Defense rose!",battler.pbThis)) return true end when PBItems::XSPEED if battler.pbTooHigh?(PBStats::SPEED) scene.pbDisplay(_INTL("It won't have any effect.")) return false else battler.stages[PBStats::SPEED]+=1 scene.pbDisplay(_INTL("{1}'s Speed rose!",battler.pbThis)) return true end when PBItems::XACCURACY if battler.pbTooHigh?(PBStats::ACCURACY) scene.pbDisplay(_INTL("It won't have any effect.")) return false else battler.stages[PBStats::ACCURACY]+=1 scene.pbDisplay(_INTL("{1}'s accuracy rose!",battler.pbThis)) return true end when PBItems::XSPECIAL if battler.pbTooHigh?(PBStats::SPATK) scene.pbDisplay(_INTL("It won't have any effect.")) return false else battler.stages[PBStats::SPATK]+=1 scene.pbDisplay(_INTL("{1}'s Special Attack rose!",battler.pbThis)) return true end when PBItems::POKeDOLL, PBItems::FLUFFYTAIL if @opponent scene.pbDisplay(_INTL("Can't use that here.")) return false else playername=self.pbPlayer.name itemname=PBItems.getName(item) scene.pbDisplay(_INTL("{1} used the {2}.",playername,itemname)) return true end else return ItemHandlers.triggerBattleUseOnBattler(item,battler,scene) end return false end def pbRegisterItem(idxPokemon,idxItem) thispkmn=@battlers[idxPokemon] @choices[idxPokemon][0]=3 # item @choices[idxPokemon][1]=idxItem # item used @choices[idxPokemon][2]=nil if idxItem==PBItems::POKeDOLL||idxItem==PBItems::FLUFFYTAIL @decision=3 pbDisplayPaused(_INTL("Got away safely!")) elsif $ItemData[idxItem][ITEMPOCKET]==2 # Any Ball pbThrowPokeBall(idxItem) end return true end def pbEnemyItemToUse(index) return 0 if !@internalbattle items=pbGetOwnerItems(index) return 0 if !items hashpitem=false battler=@battlers[index] return 0 if battler.hp<=0 for i in items if i==PBItems::POTION || i==PBItems::SUPERPOTION || i==PBItems::HYPERPOTION || i==PBItems::MAXPOTION || i==PBItems::FULLRESTORE hashpitem=true end end for i in items case i when PBItems::POTION, PBItems::SUPERPOTION, PBItems::HYPERPOTION, PBItems::MAXPOTION return i if battler.hp<=(battler.totalhp/4).floor return i if battler.hp<=(battler.totalhp/2).floor && (pbAIRandom(10)<2) when PBItems::FULLRESTORE return i if battler.hp<=(battler.totalhp/4).floor return i if battler.hp<=(battler.totalhp/2).floor && (pbAIRandom(10)<2) return i if battler.hp<=(battler.totalhp*2/3).floor && (battler.status>0 || battler.effects[PBEffects::Confusion]>0) && (pbAIRandom(10)<2) when PBItems::FULLHEAL return i if !hashpitem && (battler.status>0 || battler.effects[PBEffects::Confusion]>0) when PBItems::XATTACK return i if !battler.pbTooHigh?(PBStats::ATTACK) when PBItems::XDEFEND return i if !battler.pbTooHigh?(PBStats::DEFENSE) when PBItems::XSPEED return i if !battler.pbTooHigh?(PBStats::SPEED) when PBItems::XSPECIAL return i if !battler.pbTooHigh?(PBStats::SPATK) when PBItems::XACCURACY return i if !battler.pbTooHigh?(PBStats::ACCURACY) end end return 0 end def pbEnemyShouldUseItem?(index) item=pbEnemyItemToUse(index) if item>0 pbRegisterItem(index,item) return true end return false end def pbEnemyUseItem(item,battler) items=pbGetOwnerItems(battler.index) return if !items opponent=pbGetOwner(battler.index) for i in 0...items.length if items[i]==item items.delete_at(i) break end end itemname=PBItems.getName(item) pbDisplayBrief(_INTL("{1} used the\\r\\n{2}!",opponent.fullname,itemname)) case item when PBItems::POTION battler.pbRecoverHP(20) pbDisplayBrief(_INTL("{1} regained health!",battler.pbThis)) when PBItems::SUPERPOTION battler.pbRecoverHP(50) pbDisplayBrief(_INTL("{1} regained health!",battler.pbThis)) when PBItems::HYPERPOTION battler.pbRecoverHP(200) pbDisplayBrief(_INTL("{1} regained health!",battler.pbThis)) when PBItems::MAXPOTION battler.pbRecoverHP(battler.totalhp-battler.hp) pbDisplayBrief(_INTL("{1} regained health!",battler.pbThis)) when PBItems::XATTACK if !battler.pbTooHigh?(PBStats::ATTACK) battler.stages[PBStats::ATTACK]+=1 pbCommonAnimation("StatUp",battler,nil) pbDisplayBrief(_INTL("{1}'s Attack rose!",battler.pbThis)) end when PBItems::XDEFEND if !battler.pbTooHigh?(PBStats::DEFENSE) battler.stages[PBStats::DEFENSE]+=1 pbCommonAnimation("StatUp",battler,nil) pbDisplayBrief(_INTL("{1}'s Defense rose!",battler.pbThis)) end when PBItems::XSPEED if !battler.pbTooHigh?(PBStats::SPEED) battler.stages[PBStats::SPEED]+=1 pbCommonAnimation("StatUp",battler,nil) pbDisplayBrief(_INTL("{1}'s Speed rose!",battler.pbThis)) end when PBItems::XSPECIAL if !battler.pbTooHigh?(PBStats::SPATK) battler.stages[PBStats::SPATK]+=1 pbCommonAnimation("StatUp",battler,nil) pbDisplayBrief(_INTL("{1}'s Special Attack rose!",battler.pbThis)) end when PBItems::XACCURACY if !battler.pbTooHigh?(PBStats::ACCURACY) battler.stages[PBStats::ACCURACY]+=1 pbCommonAnimation("StatUp",battler,nil) pbDisplayBrief(_INTL("{1}'s accuracy rose!",battler.pbThis)) end when PBItems::FULLRESTORE fullhp=(battler.hp==battler.totalhp) battler.pbRecoverHP(battler.totalhp-battler.hp) battler.status=0 battler.effects[PBEffects::Confusion]=0 if fullhp pbDisplayBrief(_INTL("{1} became healthy!",battler.pbThis)) else pbDisplayBrief(_INTL("{1} regained health!",battler.pbThis)) end when PBItems::FULLHEAL battler.status=0 battler.effects[PBEffects::Confusion]=0 pbDisplayBrief(_INTL("{1} became healthy!",battler.pbThis)) end end def pbRegisterTarget(idxPokemon,idxTarget) thispkmn=@battlers[idxPokemon] @choices[idxPokemon][3]=idxTarget return true end def pbAIRandom(x) return rand(x) end def pbRandom(x) return rand(x) end def pbPriority if @usepriority # use stored priority if round isn't over yet return @priority end speeds=[] quickclaw=[] priorities=[] temp=[] @priority.clear maxpri=0 minpri=0 # Calculate each Pokémon's speed speeds[0]=@battlers[0].pbSpeed speeds[1]=@battlers[1].pbSpeed speeds[2]=@battlers[2].pbSpeed speeds[3]=@battlers[3].pbSpeed quickclaw[0]=@battlers[0].item==PBItems::QUICKCLAW quickclaw[1]=@battlers[1].item==PBItems::QUICKCLAW quickclaw[2]=@battlers[2].item==PBItems::QUICKCLAW quickclaw[3]=@battlers[3].item==PBItems::QUICKCLAW # Find the maximum and minimum priority for i in 0..3 # For this function, switching and using items # is the same as using a move with a priority of 0 pri=(@choices[i][0]!=1)?0:@choices[i][2].priority priorities[i]=pri if i==0 maxpri=pri minpri=pri else maxpri=pri if maxpri<pri minpri=pri if minpri>pri end end # Find and order all moves with the same priority curpri=maxpri loop do temp.clear for j in 0..3 if priorities[j]==curpri temp[temp.length]=j end end # Sort by speed if temp.length==1 @priority[@priority.length]=@battlers[temp[0]] else n=temp.length usequickclaw=(pbRandom(5)==0) for m in 0..n-2 for i in m+1..n-1 if quickclaw[temp[i]] && usequickclaw cmp=(quickclaw[temp[i-1]]) ? 0 : -1 #Rank higher if without Quick Claw, or equal if with it elsif quickclaw[temp[i-1]] && usequickclaw cmp=1 # Rank lower elsif speeds[temp[i]]!=speeds[temp[i-1]] cmp=(speeds[temp[i]]>speeds[temp[i-1]]) ? -1 : 1 #Rank higher to higher-speed battler else cmp=0 end if cmp<0 # put higher-speed Pokémon first swaptmp=temp[i] temp[i]=temp[i-1] temp[i-1]=swaptmp elsif cmp==0 # swap at random if speeds are equal if pbRandom(2)==0 swaptmp=temp[i] temp[i]=temp[i-1] temp[i-1]=swaptmp end end end end #Now add the temp array to priority for i in temp @priority[@priority.length]=@battlers[i] end end curpri-=1 break unless curpri>=minpri end =begin prioind=[ @priority[0].index, @priority[1].index, @priority[2] ? @priority[2].index : -1, @priority[3] ? @priority[3].index : -1 ] print("#{speeds.inspect} #{prioind.inspect}") =end @usepriority=true return @priority end def pbAllFainted?(party) allfainted=true for i in party next if !i if i.hp>0 && !i.egg? allfainted=false break end end return allfainted end def pbAbilityEffect(move,user,target,damage) # Static if (move.flags&0x01)!=0 && damage>0 if target.ability==PBAbilities::STATIC && self.pbRandom(10)<3 && user.pbCanParalyze?(false) user.pbParalyze(target) pbDisplay(_INTL("{1}'s {2} paralyzed {3}! It may be unable to move!",target.pbThis, PBAbilities.getName(target.ability),user.pbThis)) end if target.ability==PBAbilities::POISONPOINT && self.pbRandom(10)<3 && user.pbCanPoison?(false) user.pbPoison(target) pbDisplay(_INTL("{1}'s {2} poisoned {3}!",target.pbThis, PBAbilities.getName(target.ability),user.pbThis)) end if target.ability==PBAbilities::FLAMEBODY && self.pbRandom(10)<3 && user.pbCanBurn?(false) user.pbBurn(target) pbDisplay(_INTL("{1}'s {2} burned {3}!",target.pbThis, PBAbilities.getName(target.ability),user.pbThis)) end if target.ability==PBAbilities::EFFECTSPORE && self.pbRandom(10)==0 rnd=self.pbRandom(3) if rnd==0 && user.pbCanPoison?(false) user.pbPoison(target) pbDisplay(_INTL("{1}'s {2} poisoned {3}!",target.pbThis, PBAbilities.getName(target.ability),user.pbThis)) elsif rnd==1 && user.pbCanSleep?(false) user.pbSleep pbDisplay(_INTL("{1}'s {2} made {3} sleep!",target.pbThis, PBAbilities.getName(target.ability),user.pbThis)) elsif rnd==2 && user.pbCanParalyze?(false) user.pbParalyze(target) pbDisplay(_INTL("{1}'s {2} paralyzed {3}! It may be unable to move!",target.pbThis, PBAbilities.getName(target.ability),user.pbThis)) end end if target.ability==PBAbilities::CUTECHARM && self.pbRandom(10)<3 if user.ability!=PBAbilities::OBLIVIOUS && ((user.gender==1&&target.gender==0) || (user.gender==0&&target.gender==1)) && user.effects[PBEffects::Attract]<0 && user.hp>0 user.effects[PBEffects::Attract]=target.index pbDisplay(_INTL("{1}'s {2} infatuated {3}!",target.pbThis, PBAbilities.getName(target.ability),user.pbThis)) end end if target.ability==PBAbilities::ROUGHSKIN && user.hp>0 user.pbReduceHP((user.totalhp/16).floor) pbDisplay(_INTL("{1}'s {2} hurt {3}!",target.pbThis, PBAbilities.getName(target.ability),user.pbThis)) end end type=move.pbType(move.type,user,target) if target.ability==PBAbilities::COLORCHANGE && target.hp>0 && damage>0 && type!=PBTypes::QMARKS && !target.pbHasType?(type) target.type1=type target.type2=type pbDisplay(_INTL("{1}'s {2} made it the {3} type!",target.pbThis, PBAbilities.getName(target.ability), PBTypes.getName(type))) end user.pbAbilityCureCheck target.pbAbilityCureCheck # Synchronize here s=@synchronize[0] t=@synchronize[1] # PBDebug.log("[synchronize: #{@synchronize.inspect}]") if s>=0 && t>=0 && @battlers[s].ability==PBAbilities::SYNCHRONIZE && @synchronize[2]>0 # see [2024281]&0xF0, [202420C] sbattler=@battlers[s] tbattler=@battlers[t] if @synchronize[2]==PBStatuses::POISON && tbattler.pbCanPoisonSynchronize?(sbattler) tbattler.pbPoison(sbattler) pbDisplay(_INTL("{1}'s {2} poisoned {3}!",sbattler.pbThis, PBAbilities.getName(sbattler.ability),tbattler.pbThis)) elsif @synchronize[2]==PBStatuses::BURN && tbattler.pbCanBurnSynchronize?(sbattler) tbattler.pbBurn(sbattler) pbDisplay(_INTL("{1}'s {2} burned {3}!",sbattler.pbThis, PBAbilities.getName(sbattler.ability),tbattler.pbThis)) elsif @synchronize[2]==PBStatuses::PARALYSIS && tbattler.pbCanParalyzeSynchronize?(sbattler) tbattler.pbParalyze(sbattler) pbDisplay(_INTL("{1}'s {2} paralyzed {3}! It may be unable to move!",sbattler.pbThis, PBAbilities.getName(sbattler.ability),tbattler.pbThis)) end end end def pbFindPlayerBattler(pkmnIndex) battler=nil for k in 0..3 if !pbIsOpposing?(k) && @battlers[k].pokemonIndex==pkmnIndex battler=@battlers[k] break end end return battler end def pbLearnMove(pkmnIndex,move) pokemon=@party1[pkmnIndex] return if !pokemon pkmnname=pokemon.name battler=pbFindPlayerBattler(pkmnIndex) movename=PBMoves.getName(move) for i in 0..3 if pokemon.moves[i].id==move return end if pokemon.moves[i].id==0 pokemon.moves[i]=PBMove.new(move) battler.moves[i]=PokeBattle_Move.pbFromPBMove(self,pokemon.moves[i]) if battler pbDisplayPaused(_INTL("{1} learned {2}!",pkmnname,movename)) return end end loop do pbDisplayPaused(_INTL("{1} wants to learn {2}.",pkmnname,movename)) #Replaces current/total PP pbDisplayPaused(_INTL("But, {1} can't learn more than four moves.",pkmnname)) if pbDisplayConfirm(_INTL("Delete a move to make room for {1}?",movename)) pbDisplayPaused(_INTL("Which move should be forgotten?")) forgetmove=@scene.pbForgetMove(pokemon,move) if forgetmove >=0 oldmovename=PBMoves.getName(pokemon.moves[forgetmove].id) pokemon.moves[forgetmove]=PBMove.new(move)#Replaces current/total PP battler.moves[forgetmove]=PokeBattle_Move.pbFromPBMove(self,pokemon.moves[forgetmove]) if battler pbDisplayPaused(_INTL("1, 2, and... ... ...")) pbDisplayPaused(_INTL("Poof!")) pbDisplayPaused(_INTL("{1} forgot {2}.",pkmnname,oldmovename)) pbDisplayPaused(_INTL("And...")) pbDisplayPaused(_INTL("{1} learned {2}!",pkmnname,movename)) return elsif pbDisplayConfirm(_INTL("Should {1} stop learning {2}?",pkmnname,movename)) pbDisplayPaused(_INTL("{1} did not learn {2}.",pkmnname,movename)) return end elsif pbDisplayConfirm(_INTL("Should {1} stop learning {2}?",pkmnname,movename)) pbDisplayPaused(_INTL("{1} did not learn {2}.",pkmnname,movename)) return end end end def pbGainEXP return if !@internalbattle successbegin=true for i in 0..3 # Not ordered by priority if !@doublebattle && pbIsDoubleBattler?(i) @battlers[i].participants=[] next end if pbIsOpposing?(i) && @battlers[i].participants.length>0 && @battlers[i].hp<=0 dexdata=pbOpenDexData battlerSpecies=@battlers[i].species # Current species, not original species; also using R/S base EXP pbDexDataOffset(dexdata,battlerSpecies,17) baseexp=dexdata.fgetb level=@battlers[i].level dexdata.close # First count the number of participants partic=0 expshare=0 for j in @battlers[i].participants @participants[j]=true # Add participant to global list end for j in @battlers[i].participants next if !@party1[j] || !pbIsOwner?(0,j) partic+=1 if @party1[j].hp>0 && !@party1[j].egg? end for j in 0..@party1.length-1 next if !@party1[j] || !pbIsOwner?(0,j) expshare+=1 if @party1[j].hp>0 && !@party1[j].egg? && @party1[j].item==PBItems::EXPSHARE end # Now calculate EXP for the participants if partic>0 if !@opponent && successbegin && pbAllFainted?(@party2) @scene.pbWildBattleSuccess successbegin=false end for j in 0..@party1.length-1 thispoke=@party1[j] next if !@party1[j] || !pbIsOwner?(0,j) ispartic=0 level=@battlers[i].level haveexpshare=(thispoke.item==PBItems::EXPSHARE) ? 1 : 0 for k in @battlers[i].participants ispartic=1 if k==j end if thispoke.hp>0 && !thispoke.egg? exp=0 if expshare>0 exp=((level*baseexp/7).floor/2).floor exp=(exp/partic).floor*ispartic+(exp/expshare).floor*haveexpshare elsif ispartic==1 exp=((level*baseexp/7).floor/partic).floor end exp=(exp*3/2).floor if @opponent exp=(exp*3/2).floor if thispoke.trainerID!=self.pbPlayer.id exp=(exp*3/2).floor if thispoke.item==PBItems::LUCKYEGG growthrate=thispoke.growthrate newexp=PBExperience.pbAddExperience(thispoke.exp,exp,growthrate) exp=newexp-thispoke.exp; if exp > 0 if thispoke.trainerID!=self.pbPlayer.id pbDisplayPaused(_INTL("{1} gained a boosted\\r\\n{2} Exp. Points!",thispoke.name,exp)) else pbDisplayPaused(_INTL("{1} gained\\r\\n{2} Exp. Points!",thispoke.name,exp)) end #Gain effort value points, using RS effort values totalev=0 for k in 0..5 totalev+=thispoke.ev[k] end dexdata=pbOpenDexData pbDexDataOffset(dexdata,battlerSpecies,23) for k in 0..5 evgain=dexdata.fgetb if thispoke.item==PBItems::MACHOBRACE evgain*=2 end if thispoke.pokerus > 0 evgain*=2 end if evgain>0 # Can't exceed overall limit if totalev+evgain>510 # Bug Fix: must use "-=" instead of "=" evgain-=totalev+evgain-510 end # Can't exceed stat limit if thispoke.ev[k]+evgain>255 # Bug Fix: must use "-=" instead of "=" evgain-=thispoke.ev[k]+evgain-255 end # Add EV gain thispoke.ev[k]+=evgain if thispoke.ev[k]>255 print "Single-stat EV limit 255 exceeded.\\r\\nStat: #{k} EV gain: #{evgain} EVs: #{thispoke.ev.inspect}" thispoke.ev[k]=255 end totalev+=evgain if totalev>510 print "EV limit 510 exceeded.\\r\\nTotal EVs: #{totalev} EV gain: #{evgain} EVs: #{thispoke.ev.inspect}" end end end newlevel=PBExperience.pbGetLevelFromExperience(newexp,growthrate) tempexp=0 curlevel=thispoke.level thisPokeSpecies=thispoke.species if newlevel<curlevel debuginfo="#{thispoke.name}: #{thispoke.level}/#{newlevel} | #{thispoke.exp}/#{newexp} | gain: #{exp}" raise RuntimeError.new( _INTL("The new level ({1}) is less than the Pokémon's\\r\\ncurrent level ({2}), which shouldn't happen.\\r\\n[Debug: {3}]", newlevel,curlevel,debuginfo)) return end tempexp1=thispoke.exp tempexp2=0 # Find battler battler=pbFindPlayerBattler(j) loop do #EXP Bar animation startexp=PBExperience.pbGetStartExperience(curlevel,growthrate) endexp=PBExperience.pbGetStartExperience(curlevel+1,growthrate) tempexp2=(endexp<newexp) ? endexp : newexp thispoke.exp=tempexp2 @scene.pbEXPBar(thispoke,battler,startexp,endexp,tempexp1,tempexp2) tempexp1=tempexp2 curlevel+=1 break if curlevel>newlevel oldtotalhp=thispoke.totalhp oldattack=thispoke.attack olddefense=thispoke.defense oldspeed=thispoke.speed oldspatk=thispoke.spatk oldspdef=thispoke.spdef thispoke.calcStats battler.pbUpdate if battler @scene.pbRefresh pbDisplayPaused(_INTL("{1} grew to Level {2}!",thispoke.name,curlevel)) @scene.pbLevelUp(thispoke,battler,oldtotalhp,oldattack, olddefense,oldspeed,oldspatk,oldspdef) # Finding all moves learned at this level atkdata=pbRgssOpen("Data/attacksRS.dat","rb") offset=atkdata.getOffset(thisPokeSpecies-1) length=atkdata.getLength(thisPokeSpecies-1)>>1 atkdata.pos=offset for k in 0..length-1 atklevel=atkdata.fgetw move=atkdata.fgetw if atklevel==thispoke.level # Learned a new move pbLearnMove(j,move) end end atkdata.close end end end end end # Now clear the participants array @battlers[i].participants=[] end end end def pbCanChooseNonActive?(index) party=pbParty(index) for i in 0..party.length-1 return true if pbCanSwitchLax?(index,i,false) end return false end def pbSwitchInBetween(index,lax,cancancel) if !pbOwnedByPlayer?(index) return @scene.pbChooseNewEnemy(index,pbParty(index)) else return pbSwitchPlayer(index,lax,cancancel) end end def pbSwitch return if @decision>0 if pbAllFainted?(@party1) @decision=2 return end if pbAllFainted?(@party2) @decision=1 return end firstbattlerhp=@battlers[0].hp for index in 0..3 i=@battlers[index] next if !@doublebattle && pbIsDoubleBattler?(index) next if i.hp>0 next if !pbCanChooseNonActive?(index) if !pbOwnedByPlayer?(index) if @opponent newenemy=pbSwitchInBetween(index,false,false) opponent=pbGetOwner(index) if !@doublebattle && firstbattlerhp>0 && @shiftStyle && @opponent && @internalbattle && pbCanChooseNonActive?(0) && pbIsOpposing?(index) pbDisplayPaused(_INTL("{1} is about to send in {2}.",opponent.fullname,@party2[newenemy].name)) if pbDisplayConfirm(_INTL("Will {1} change Pokémon?",self.pbPlayer.name)) newpoke=pbSwitchPlayer(0,true,true) if newpoke>=0 pbDisplayBrief(_INTL("{1}, that's enough! Come back!",@battlers[0].name)) pbRecallAndReplace(0,newpoke) end end end pbRecallAndReplace(index,newenemy) end elsif @opponent newpoke=pbSwitchInBetween(index,true,false) pbRecallAndReplace(index,newpoke) else switch=false if !pbDisplayConfirm(_INTL("Use next Pokémon?")) switch=(pbRun(index,true)<=0) else switch=true end if switch newpoke=pbSwitchInBetween(index,true,false) pbRecallAndReplace(index,newpoke) end end end end def pbRecallAndReplace(index,newpoke,batonpass=false) if @battlers[index].hp>0 @scene.pbRecall(index) end return pbReplace(index,newpoke,batonpass) end def pbReplace(index,newpoke,batonpass=false) party=pbParty(index) if pbOwnedByPlayer?(index) pbDisplayBrief(_INTL("Go! {1}!",party[newpoke].name)) @battlers[index].pbInitialize(party[newpoke],newpoke,batonpass); @scene.pbSendOut(index,party[newpoke]) else owner=pbGetOwner(index) pbDisplayBrief(_INTL("{1} sent\\r\\nout {2}!",owner.fullname,party[newpoke].name)) @battlers[index].pbInitialize(party[newpoke],newpoke,batonpass); pbPlayer.seen[party[newpoke].species]=true if pbIsOpposing?(index) @scene.pbTrainerSendOut(index,party[newpoke]) else @scene.pbSendOut(index,party[newpoke]) end end return pbOnActiveOne(@battlers[index]) end def pbSwitchPlayer(index,lax,cancancel) if @debug return @scene.pbChooseNewEnemy(index,pbParty(index)) else return @scene.pbSwitch(index,lax,cancancel) end end def pbDebugUpdate @debugupdate+=1 if @debugupdate==30 # Graphics.update @debugupdate=0 end end def pbDisplayPaused(msg) if @debug pbDebugUpdate PBDebug.log(msg) else @scene.pbDisplayPausedMessage(msg) end end def pbDisplay(msg) if @debug pbDebugUpdate PBDebug.log(msg) else @scene.pbDisplayMessage(msg) end end def pbDisplayBrief(msg) if @debug pbDebugUpdate PBDebug.log(msg) else @scene.pbDisplayMessage(msg,true) end end def pbDisplayConfirm(msg) if @debug pbDebugUpdate PBDebug.log(msg) return true else return @scene.pbDisplayConfirmMessage(msg) end end def pbCommonAnimation(name,attacker,opponent,side=true) if @battlescene @scene.pbCommonAnimation(name,attacker,opponent,side) end end def pbAnimation(move,attacker,opponent,side=true) if @battlescene @scene.pbAnimation(move,attacker,opponent,side) end end def pbAutoFightMenu(i) return false end def pbItemMenu(i) return @scene.pbItemMenu(i) end def pbCommandMenu(i) return @scene.pbCommandMenu(i) end def pbCommandPhase @scene.pbBeginCommandPhase for i in 0..3 # Reset choices if commands can be shown if pbCanShowCommands?(i) @choices[i][0]=0 @choices[i][1]=0 @choices[i][2]=nil @choices[i][3]=-1 else battler=@battlers[i] PBDebug.log("[reusing commands for #{battler.pbThis}]") unless !@doublebattle && pbIsDoubleBattler?(i) end end for i in 0..3 next if !@doublebattle && pbIsDoubleBattler?(i) break if @decision!=0 if !pbOwnedByPlayer?(i) || @debug if @battlers[i].hp>0 && pbCanShowCommands?(i) @scene.pbChooseEnemyCommand(i) end else commandDone=false commandEnd=false if pbCanShowCommands?(i) loop do cmd=pbCommandMenu(i) if cmd==0 # Fight if pbCanShowFightMenu?(i) commandDone=true if pbAutoFightMenu(i) until commandDone index=@scene.pbFightMenu(i) break if index<0 next if !pbRegisterMove(i,index) if @doublebattle thismove=@battlers[i].moves[index]; target=thismove.target if thismove.function==0x6D && # CURSE !@battlers[i].pbHasType?(PBTypes::GHOST) target=0x10 end if target==0x00 # single non-user target=@scene.pbChooseTarget(i) next if target<0 pbRegisterTarget(i,target) end end commandDone=true end else pbAutoChooseMove(i) commandDone=true end elsif cmd==1 # Pokémon pkmn=pbSwitchPlayer(i,false,true) if pkmn>=0 commandDone=true if pbRegisterSwitch(i,pkmn) end elsif cmd==2 # Bag if !@internalbattle if pbOwnedByPlayer?(i) pbDisplay(_INTL("Items can't be used here.")) end else item=pbItemMenu(i) if item>0 pbRegisterItem(i,item) commandDone=true end end elsif cmd==3 # Run run=pbRun(i) if run > 0 commandDone=true return elsif run < 0 commandDone=true end end break if commandDone end # end command loop end # end CanShowCommands end end end def pbChoseMove?(i,move) return false if @battlers[i].hp<=0 if @choices[i][0]==1&&@choices[i][1]>=0 choice=@choices[i][1] return @battlers[i].moves[choice].id==move end return false end def pbAttackPhase @scene.pbBeginAttackPhase for i in 0..3 # in order from own first, opposing first, own second, opposing second if pbChoseMove?(i,PBMoves::FOCUSPUNCH) if @battlers[i].status!=PBStatuses::SLEEP&& (@battlers[i].ability!=PBAbilities::TRUANT ||!@battlers[i].effects[PBEffects::Truant]) pbDisplay(_INTL("{1} is tightening its focus!",@battlers[i].pbThis)) end end end for i in 0..3 if pbIsOpposing?(i) && @choices[i][0]==3 pbEnemyUseItem(@choices[i][1],@battlers[i]) end end for i in 0..3 if @battlers[i].hp>0 @battlers[i].turncount+=1 end end for i in 0..3 if !pbChoseMove?(i,PBMoves::RAGE) @battlers[i].effects[PBEffects::Rage]=false end end @switching=true for i in 0..3 # in order from own first, opposing first, own second, opposing second if @choices[i][0]==2 index=@choices[i][1]# party position of Pokémon to switch to if !pbOwnedByPlayer?(i) owner=pbGetOwner(i) pbDisplayBrief(_INTL("{1} withdrew {2}!",owner.fullname,battlers[i].name)); else pbDisplayBrief(_INTL("{1}, that's enough!\\r\\nCome back!",battlers[i].name)); end for j in 3..0 # in order from opposing second, opposing first next if !@battlers[i].pbIsOpposing?(j) # if Pursuit and this target ("i") was chosen if pbChoseMove?(j,PBMoves::PURSUIT) && @choices[j][3]==i if @battlers[j].status!=PBStatuses::SLEEP&& @battlers[j].status!=PBStatuses::FROZEN&& (@battlers[j].ability!=PBAbilities::TRUANT ||!@battlers[j].effects[PBEffects::Truant]) @battlers[j].pbUseMove(@choices[i]) @battlers[i].effects[PBEffects::Pursuit]=true #UseMove calls pbGainEXP as appropriate @switching=false return if @decision>0 end end break if @battlers[i].hp<=0 end if !pbRecallAndReplace(i,index) # If a forced switch somehow occurs here in single battles # the attack phase now ends if !@doublebattle @switching=false return end end end end @switching=false # calculate priority at this time @usepriority=false # recalculate priority priority=pbPriority for i in priority i.pbProcessTurn(@choices[i.index]) return if @decision>0 end end def pbEndOfRoundPhase for i in 0..3 @battlers[i].effects[PBEffects::Protect]=false @battlers[i].effects[PBEffects::Endure]=false @battlers[i].effects[PBEffects::HyperBeam]-=1 if @battlers[i].effects[PBEffects::HyperBeam]>0 end @usepriority=false # recalculate priority priority=pbPriority #Reflect for i in 0..1 if sides[i].effects[PBEffects::Reflect] > 0 sides[i].effects[PBEffects::Reflect]-=1 if sides[i].effects[PBEffects::Reflect]==0 pbDisplay(_INTL("Ally's Reflect faded!")) if i==0 pbDisplay(_INTL("Foe's Reflect faded!")) if i==1 end end end #Light Screen for i in 0..1 if sides[i].effects[PBEffects::LightScreen] > 0 sides[i].effects[PBEffects::LightScreen]-=1 if sides[i].effects[PBEffects::LightScreen]==0 pbDisplay(_INTL("Ally's Light Screen faded!")) if i==0 pbDisplay(_INTL("Foe's Light Screen faded!")) if i==1 end end end #Mist for i in 0..1 if sides[i].effects[PBEffects::Mist] > 0 sides[i].effects[PBEffects::Mist]-=1 if sides[i].effects[PBEffects::Mist]==0 pbDisplay(_INTL("Ally's Mist faded!")) if i==0 pbDisplay(_INTL("Foe's Mist faded!")) if i==1 end end end #Safeguard for i in 0..1 if sides[i].effects[PBEffects::Safeguard] > 0 sides[i].effects[PBEffects::Safeguard]-=1 if sides[i].effects[PBEffects::Safeguard]==0 pbDisplay(_INTL("Ally's party is no longer protected by Safeguard!")) if i==0 pbDisplay(_INTL("Foe's party is no longer protected by Safeguard!")) if i==1 end end end #Wish for i in priority if i.effects[PBEffects::Wish]>0 i.effects[PBEffects::Wish]-=1 if i.effects[PBEffects::Wish]==0 && i.hp>0 wishmaker=pbThisEx(i.index,i.effects[PBEffects::WishMaker]) pbDisplay(_INTL("{1}'s Wish came true!",wishmaker)) hpgain=i.pbRecoverHP((i.totalhp/2).floor) if hpgain==0 pbDisplay(_INTL("{1}'s HP is full!",i.pbThis)) else pbDisplay(_INTL("{1} regained health!",i.pbThis)) end end end end #Weather if @weather==PBWeather::RAINDANCE @weatherduration=@weatherduration-1 if @weatherduration>0 if @weatherduration==0 pbDisplay(_INTL("The rain stopped.")) @weather=0 else pbDisplay(_INTL("Rain continues to fall.")); end end if @weather==PBWeather::SANDSTORM @weatherduration=@weatherduration-1 if @weatherduration>0 if @weatherduration==0 pbDisplay(_INTL("The sandstorm subsided.")) @weather=0 else pbDisplay(_INTL("The sandstorm rages.")); if pbWeather==PBWeather::SANDSTORM for i in priority next if i.hp<=0 if i.ability!=PBAbilities::SANDVEIL && !i.pbHasType?(PBTypes::GROUND)&& !i.pbHasType?(PBTypes::ROCK)&& !i.pbHasType?(PBTypes::STEEL)&& i.effects[PBEffects::TwoTurnAttack]!=PBMoves::DIG&& i.effects[PBEffects::TwoTurnAttack]!=PBMoves::DIVE pbDisplay(_INTL("{1} was buffeted by the sandstorm!",i.pbThis)) @scene.pbDamageAnimation(i,0) i.pbReduceHP(i.totalhp/16) if i.hp<=0 return if !i.pbFaint end end end end end end if @weather==PBWeather::SUNNYDAY @weatherduration=@weatherduration-1 if @weatherduration>0 if @weatherduration==0 pbDisplay(_INTL("The sunlight faded.")) @weather=0 else pbDisplay(_INTL("The sunlight is strong.")); end end if @weather==PBWeather::HAIL @weatherduration=@weatherduration-1 if @weatherduration>0 if @weatherduration==0 pbDisplay(_INTL("The hail stopped.")) @weather=0 else pbDisplay(_INTL("Hail continues to fall.")); if pbWeather==PBWeather::HAIL for i in priority next if i.hp<=0 if !i.pbHasType?(PBTypes::ICE)&& i.effects[PBEffects::TwoTurnAttack]!=PBMoves::DIG&& i.effects[PBEffects::TwoTurnAttack]!=PBMoves::DIVE pbDisplay(_INTL("{1} was pelted by hail!",i.pbThis)) @scene.pbDamageAnimation(i,0) i.pbReduceHP(i.totalhp/16) if i.hp<=0 return if !i.pbFaint end end end end end end # Ingrain for i in priority # No switching during process next if i.hp<=0 if i.effects[PBEffects::Ingrain] hpgain=i.pbRecoverHP(i.totalhp/16) pbDisplay(_INTL("{1} absorbed nutrients with its roots!",i.pbThis)) if hpgain>0 end # Rain Dish if pbWeather==PBWeather::RAINDANCE && i.ability==PBAbilities::RAINDISH hpgain=i.pbRecoverHP(i.totalhp/16) pbDisplay(_INTL("{1}'s Rain Dish restored its HP a little!",i.pbThis)) if hpgain>0 end # Speed Boost # A Pokémon's turncount is 0 if it became active after the beginning of a round if i.turncount>0 && i.ability==PBAbilities::SPEEDBOOST if !i.pbTooHigh?(PBStats::SPEED) i.stages[PBStats::SPEED]+=1 pbCommonAnimation("StatUp",i,nil) pbDisplay(_INTL("{1}'s Speed Boost raised its Speed!",i.pbThis)) end end # Truant if i.turncount>0 && i.ability==PBAbilities::TRUANT i.effects[PBEffects::Truant]=!i.effects[PBEffects::Truant] end # Shed Skin if i.ability==PBAbilities::SHEDSKIN if pbRandom(10)<3 && i.status>0 case i.status when PBStatuses::SLEEP pbDisplay(_INTL("{1}'s Shed Skin cured its sleep problem!",i.pbThis)) when PBStatuses::FROZEN pbDisplay(_INTL("{1}'s Shed Skin cured its ice problem!",i.pbThis)) when PBStatuses::BURN pbDisplay(_INTL("{1}'s Shed Skin cured its burn problem!",i.pbThis)) when PBStatuses::POISON pbDisplay(_INTL("{1}'s Shed Skin cured its poison problem!",i.pbThis)) when PBStatuses::PARALYSIS pbDisplay(_INTL("{1}'s Shed Skin cured its paralysis problem!",i.pbThis)) end i.status=0 i.statusCount=0 end end # Berry check i.pbBerryCureCheck(true) # Leech Seed if i.effects[PBEffects::LeechSeed]>=0 recipient=@battlers[i.effects[PBEffects::LeechSeed]] if recipient.hp>0 hploss=i.pbReduceHP((i.totalhp/8).floor) if i.ability==PBAbilities::LIQUIDOOZE recipient.pbReduceHP(hploss) pbDisplay(_INTL("It sucked up the liquid ooze!")) else recipient.pbRecoverHP(hploss) pbDisplay(_INTL("{1}'s health is sapped by Leech Seed!",i.pbThis)) end i.pbFaint if i.hp<=0 recipient.pbFaint if recipient.hp<=0 end end return if @decision>0 next if i.hp<=0 # Poison/Toxic/Burn if i.status==PBStatuses::POISON pbDisplay(_INTL("{1} is hurt by poison!",i.pbThis)) pbCommonAnimation("Poison",i,nil) if i.statusCount==0 i.pbReduceHP((i.totalhp/8).floor) else i.effects[PBEffects::Toxic]+=1 i.effects[PBEffects::Toxic]=[15,i.effects[PBEffects::Toxic]].min i.pbReduceHP((i.totalhp/16).floor*i.effects[PBEffects::Toxic]) end end if i.hp<=0 return if !i.pbFaint next end if i.status==PBStatuses::BURN pbDisplay(_INTL("{1} is hurt by its burn!",i.pbThis)) pbCommonAnimation("Burn",i,nil) i.pbReduceHP((i.totalhp/8).floor) end if i.hp<=0 return if !i.pbFaint next end # Nightmare if i.effects[PBEffects::Nightmare] if i.status==PBStatuses::SLEEP pbDisplay(_INTL("{1} is locked in a nightmare!",i.pbThis)) i.pbReduceHP((i.totalhp/4).floor) else i.effects[PBEffects::Nightmare]=false end end if i.hp<=0 return if !i.pbFaint next end # Curse if i.effects[PBEffects::Curse] pbDisplay(_INTL("{1} is afflicted by the Curse!",i.pbThis)) i.pbReduceHP((i.totalhp/4).floor) end if i.hp<=0 return if !i.pbFaint next end # Multi-turn attacks if i.effects[PBEffects::MultiTurn]>0 i.effects[PBEffects::MultiTurn]-=1 movename=PBMoves.getName(i.effects[PBEffects::MultiTurnAttack]) if i.effects[PBEffects::MultiTurn]==0 pbDisplay(_INTL("{1} was freed from {2}!",i.pbThis,movename)) else pbDisplay(_INTL("{1} is hurt by {2}!",i.pbThis,movename)) i.pbReduceHP((i.totalhp/16).floor) end end if i.hp<=0 return if !i.pbFaint next end # Uproar if i.effects[PBEffects::Uproar]>0 for j in priority if j.hp>0 && j.status==PBStatuses::SLEEP && j.ability!=PBAbilities::SOUNDPROOF pbDisplay(_INTL("{1} woke up in the uproar!",j.pbThis)) j.effects[PBEffects::Nightmare]=false j.status=0 j.statusCount=0 end end i.effects[PBEffects::Uproar]-=1 if i.effects[PBEffects::Uproar]==0 pbDisplay(_INTL("{1} calmed down.",i.pbThis)) else pbDisplay(_INTL("{1} is making an uproar!",i.pbThis)) end end # Outrage if i.effects[PBEffects::Outrage]>0 i.effects[PBEffects::Outrage]-=1 if i.effects[PBEffects::Outrage]==0 && i.ability!=PBAbilities::OWNTEMPO && i.effects[PBEffects::Confusion]<=0 i.effects[PBEffects::Confusion]=2+pbRandom(4) pbCommonAnimation("Confusion",i,nil) pbDisplay(_INTL("{1} became confused due to fatigue!",i.pbThis)) end end # Disable if i.effects[PBEffects::Disable]>0 i.effects[PBEffects::Disable]-=1 if i.effects[PBEffects::Disable]==0 i.effects[PBEffects::DisableMove]=0 pbDisplay(_INTL("{1} is disabled no more!",i.pbThis)) end end # Encore if i.effects[PBEffects::Encore]>0 # PBDebug.log("[Battler: #{i.pbThis}]") # PBDebug.log("[Encore=#{i.effects[PBEffects::Encore]}]") # PBDebug.log("[EncoreIndex=#{i.effects[PBEffects::EncoreIndex]}]") # PBDebug.log("[EncoreMove=#{i.effects[PBEffects::EncoreMove]}]") # PBDebug.log("[CurrentMove=#{i.moves[i.effects[PBEffects::EncoreIndex]].id}]") if i.moves[i.effects[PBEffects::EncoreIndex]].id!=i.effects[PBEffects::EncoreMove] i.effects[PBEffects::Encore]=0 i.effects[PBEffects::EncoreIndex]=0 i.effects[PBEffects::EncoreMove]=0 else i.effects[PBEffects::Encore]-=1 if i.effects[PBEffects::Encore]==0 || i.moves[i.effects[PBEffects::EncoreIndex]].pp==0 i.effects[PBEffects::Encore]=0 pbDisplay(_INTL("{1}'s encore ended!",i.pbThis)) end end end # Taunt/Lock-on/Mind Reader if i.effects[PBEffects::LockOn]>0 i.effects[PBEffects::LockOn]-=1 if i.effects[PBEffects::LockOn]==0 i.effects[PBEffects::LockOnPos]=-1 end end i.effects[PBEffects::Taunt]-=1 if i.effects[PBEffects::Taunt]>0 i.effects[PBEffects::Charge]-=1 if i.effects[PBEffects::Charge]>0 # Yawn if i.effects[PBEffects::Yawn]>0 i.effects[PBEffects::Yawn]-=1 if i.effects[PBEffects::Yawn]==0&&i.pbCanSleepYawn? i.pbSleep pbDisplay(_INTL("{1} fell asleep!",i.pbThis)) end end # Berry/Herb i.pbBerryCureCheck(false) end pbGainEXP pbSwitch for i in 0..3 @battlers[i].pbTrace(false) end for i in 0..3 @battlers[i].pbForecast end #Future Sight for i in battlers # not priority if i.hp>0 && i.effects[PBEffects::FutureSight]>0 i.effects[PBEffects::FutureSight]-=1 if i.effects[PBEffects::FutureSight]==0 move=PokeBattle_Move.pbFromPBMove(self,PBMove.new(i.effects[PBEffects::FutureSightMove])) pbDisplay(_INTL("{1} took the {2} attack!",i.pbThis,move.name)) moveuser=@battlers[i.effects[PBEffects::FutureSightUser]] if i.hp<=0 || move.pbAccuracyCheck(moveuser,i) damage=((i.effects[PBEffects::FutureSightDamage]*85)/100).floor damage=1 if damage<1 i.damagestate.reset if i.item==PBItems::FOCUSBAND && pbRandom(10)==0 i.damagestate.focusband=true end move.pbReduceHPDamage(damage,nil,i) else pbDisplay(_INTL("But it failed!")) end i.effects[PBEffects::FutureSight]=0 i.effects[PBEffects::FutureSightMove]=0 i.effects[PBEffects::FutureSightDamage]=0 i.effects[PBEffects::FutureSightUser]=-1 if i.hp<=0 i.pbFaint # no return pbGainEXP pbSwitch end end end end #Perish Song for i in priority if i.hp>0 && i.effects[PBEffects::PerishSong]>0 i.effects[PBEffects::PerishSong]-=1 pbDisplay(_INTL("{1}'s Perish count fell to {2}!",i.pbThis,i.effects[PBEffects::PerishSong])) if i.effects[PBEffects::PerishSong]==0 i.pbReduceHP(i.hp) i.pbFaint # no return pbGainEXP pbSwitch end end end for i in 0..3 @battlers[i].effects[PBEffects::Protect]=false @battlers[i].effects[PBEffects::Endure]=false end for i in 0..3 @battlers[i].effects[PBEffects::Flinch]=false @battlers[i].effects[PBEffects::FollowMe]=false @battlers[i].effects[PBEffects::HelpingHand]=false @battlers[i].effects[PBEffects::MagicCoat]=false @battlers[i].effects[PBEffects::Snatch]=false @battlers[i].lastHPLost=0 @battlers[i].lastAttacker=-1 @battlers[i].effects[PBEffects::Counter]=-1 @battlers[i].effects[PBEffects::MirrorCoat]=-1 @battlers[i].effects[PBEffects::CounterTarget]=-1 @battlers[i].effects[PBEffects::MirrorCoatTarget]=-1 end pbSwitch # invalidate stored priority @usepriority=false end end
PokeBattle_AI
[
Selecionar
] [
-
]
class PokeBattle_Battle def pbTypeModifier(type,opponent) return 4 if type<0 atype=type otype1=opponent.type1 otype2=opponent.type2 atype=atype-1 if atype>=10 otype1=otype1-1 if otype1>=10 otype2=otype2-1 if otype2>=10 mod1=PBTypes::PBTypeChart[atype*PBTypes.getCount+otype1] mod2=(otype1==otype2) ? 2 : PBTypes::PBTypeChart[atype*PBTypes.getCount+otype2] if opponent.effects[PBEffects::Foresight] mod1=2 if otype1==PBTypes::GHOST && (atype==PBTypes::NORMAL || atype==PBTypes::FIGHTING) mod2=2 if otype2==PBTypes::GHOST && (atype==PBTypes::NORMAL || atype==PBTypes::FIGHTING) end return mod1*mod2 end def pbGetMoveScore(move,attacker,opponent) score=100 case move.function when 0x00 score+=20 if opponent.effects[PBEffects::TwoTurnAttack]==PBMoves::DIVE when 0x01 if opponent.status!=0 score-=80 elsif opponent.effects[PBEffects::Yawn]>0 score-=60 elsif !opponent.pbCanSleep?(false) score-=40 end when 0x02 score-=10 if opponent.status==PBStatuses::POISON when 0x03 score-=20 if opponent.ability==PBAbilities::LIQUIDOOZE when 0x04 score-=10 if opponent.status==PBStatuses::BURN score-=40 if opponent.pbHasType?(PBTypes::FIRE) when 0x05 score-=10 if opponent.status==PBStatuses::FROZEN when 0x06 score-=10 if opponent.status==PBStatuses::PARALYSIS when 0x07 score-=40 if opponent.ability==PBAbilities::DAMP score+=50 score-=(attacker.hp*100/attacker.totalhp) when 0x08 score-=80 if opponent.status!=PBStatuses::SLEEP score-=20 if opponent.ability==PBAbilities::LIQUIDOOZE when 0x0A score-=(attacker.stages[PBStats::ATTACK]*10) when 0x0B score-=(attacker.stages[PBStats::DEFENSE]*10) when 0x0D score-=(attacker.stages[PBStats::SPATK]*10) when 0x10 score-=(attacker.stages[PBStats::EVASION]*10) when 0x11 score+=10 when 0x12 score+=(opponent.stages[PBStats::ATTACK]*10) when 0x13 score+=(opponent.stages[PBStats::DEFENSE]*10) when 0x14 score+=(opponent.stages[PBStats::SPEED]*10) when 0x17 score+=(opponent.stages[PBStats::ACCURACY]*10) when 0x18 score+=(opponent.stages[PBStats::EVASION]*10) when 0x19 stages=0 for i in 0..3 battler=@battlers[i] stages+=battler.stages[PBStats::ATTACK] stages+=battler.stages[PBStats::DEFENSE] stages+=battler.stages[PBStats::SPEED] stages+=battler.stages[PBStats::SPATK] stages+=battler.stages[PBStats::SPDEF] stages+=battler.stages[PBStats::EVASION] stages+=battler.stages[PBStats::ACCURACY] end score-=70 if stages==0 when 0x1B score-=20 if attacker.effects[PBEffects::Confusion]>0 when 0x1C party=pbParty(opponent.index) for i in 0...party.length choices[choices.length]=i if pbCanSwitchLax?(opponent.index,i,false) end score-=90 if choices.length==0 when 0x1F score-=10 if opponent.ability==PBAbilities::INNERFOCUS when 0x20 if attacker.hp==attacker.totalhp score-=80 else score+=50 score-=(attacker.hp*100/attacker.totalhp) end when 0x21 score-=80 if opponent.status!=0 score-=90 if opponent.pbHasType?(PBTypes::POISON) || opponent.pbHasType?(PBTypes::STEEL) when 0x23 score-=80 if attacker.pbOwnSide.effects[PBEffects::LightScreen]>0 when 0x24 score-=10 if opponent.status==PBStatuses::BURN score-=10 if opponent.status==PBStatuses::FROZEN score-=10 if opponent.status==PBStatuses::PARALYSIS when 0x25 if attacker.hp==attacker.totalhp || attacker.status==PBStatuses::SLEEP score-=80 else score+=50 score-=(attacker.hp*100/attacker.totalhp) score+=30 if attacker.status!=0 end when 0x26 score-=80 if attacker.level<opponent.level when 0x28 score-=50 score+=(opponent.hp*100/opponent.totalhp) when 0x29 score+=50 if opponent.hp<=40 when 0x2A score-=30 if opponent.effects[PBEffects::MultiTurn]>0 when 0x2B score+=40 if attacker.effects[PBEffects::FocusEnergy] when 0x2D score+=10*(attacker.stages[PBStats::ACCURACY]-opponent.stages[PBStats::EVASION]) when 0x2E score-=80 if attacker.pbOwnSide.effects[PBEffects::Mist]>0 when 0x2F score-=80 if attacker.effects[PBEffects::FocusEnergy] when 0x30 score-=25 score+=(attacker.hp*50/attacker.totalhp) when 0x31 score-=80 if opponent.effects[PBEffects::Confusion]>0 when 0x32 score-=(attacker.stages[PBStats::ATTACK]*20) when 0x33 score-=(attacker.stages[PBStats::DEFENSE]*20) when 0x34 score-=(attacker.stages[PBStats::SPEED]*20) when 0x35 score-=(attacker.stages[PBStats::SPATK]*20) when 0x36 score-=(attacker.stages[PBStats::SPDEF]*20) when 0x3A score+=(opponent.stages[PBStats::ATTACK]*20) when 0x3B score+=(attacker.stages[PBStats::DEFENSE]*20) when 0x3C score+=(attacker.stages[PBStats::SPEED]*20) when 0x3E score+=(attacker.stages[PBStats::SPDEF]*20) when 0x41 score-=80 if attacker.pbOwnSide.effects[PBEffects::Reflect]>0 when 0x42 score-=80 if opponent.status!=0 score-=90 if opponent.pbHasType?(PBTypes::POISON) || opponent.pbHasType?(PBTypes::STEEL) when 0x43 score-=80 if opponent.status!=0 when 0x44 score-=10 if opponent.stages[PBStats::ATTACK]<0 when 0x45 score-=10 if opponent.stages[PBStats::DEFENSE]<0 when 0x46 score-=10 if opponent.stages[PBStats::SPEED]<0 when 0x47 score-=10 if opponent.stages[PBStats::SPATK]<0 when 0x48 score-=10 if opponent.stages[PBStats::SPDEF]<0 when 0x49 score-=10 if opponent.stages[PBStats::ACCURACY]<0 when 0x4B score+=20 if attacker.effects[PBEffects::FocusEnergy] when 0x4C score-=10 if opponent.effects[PBEffects::Confusion]>0 when 0x4D score-=10 if opponent.status!=0 when 0x4E score+=10 when 0x4F score-=80 if attacker.effects[PBEffects::Substitute]>0 || attacker.hp<=(attacker.totalhp/4) when 0x51 score+=25 if attacker.effects[PBEffects::Rage] when 0x54 score-=80 if opponent.effects[PBEffects::LeechSeed]>=0 when 0x55 score-=100 when 0x56 score-=80 if opponent.effects[PBEffects::Disable]>0 when 0x57 score+=50 if opponent.hp<=attacker.level when 0x58 score+=20 if opponent.hp<=attacker.level when 0x5A score-=80 if opponent.effects[PBEffects::Encore]>0 when 0x5B score+=30 if attacker.hp>opponent.hp when 0x5C score-=80 if attacker.status!=PBStatuses::SLEEP score+=70 if attacker.status==PBStatuses::SLEEP when 0x5E score-=80 if opponent.effects[PBEffects::LockOn]>0 when 0x61 score-=80 if attacker.status!=PBStatuses::SLEEP score+=70 if attacker.status==PBStatuses::SLEEP when 0x62 score+=50 score-=(attacker.hp*100/attacker.totalhp) when 0x63 score+=50 score-=(attacker.hp*100/attacker.totalhp) when 0x65 score-=25 score+=(opponent.hp*50/opponent.totalhp) when 0x66 party=pbParty(opponent.index) statuses=0 for i in 0...party.length statuses+=1 if party[i] && party[i].status!=0 end score-=80 if statuses==0 when 0x67 score+=15 when 0x69 score-=20 if attacker.item!=0 when 0x6A score-=80 if opponent.effects[PBEffects::MeanLook]>=0 when 0x6B score-=80 if opponent.status!=PBStatuses::SLEEP when 0x6C score-=(attacker.stages[PBStats::EVASION]*10) when 0x6D if attacker.pbHasType?(PBTypes::GHOST) score-=40 if attacker.hp<=(attacker.totalhp/2) score-=70 if opponent.effects[PBEffects::Curse] else avg=(attacker.stages[PBStats::SPEED]*10) avg-=(attacker.stages[PBStats::ATTACK]*10) avg-=(attacker.stages[PBStats::DEFENSE]*10) score+=avg/3 end when 0x6F score-=(attacker.effects[PBEffects::ProtectRate]*10) when 0x70 score-=80 if attacker.pbOpposingSide.effects[PBEffects::Spikes]>=3 when 0x72 score-=80 if opponent.effects[PBEffects::PerishSong]>0 when 0x73 score-=80 if @weather==PBWeather::SANDSTORM when 0x74 score-=(attacker.effects[PBEffects::ProtectRate]*10) when 0x76 if opponent.effects[PBEffects::Confusion]>0 score-=90 elsif opponent.stages[PBStats::ATTACK]<0 score+=30 end when 0x78 agender=attacker.gender ogender=opponent.gender if agender==2||ogender==2||agender==ogender score-=80 elsif opponent.effects[PBEffects::Attract]>=0 score-=90 end when 0x79 damage=(attacker.happiness*10/25).floor damage/=2 score+=damage-25 when 0x7B damage=((255-attacker.happiness)*10/25).floor damage/=2 score+=damage-25 when 0x7C score-=80 if attacker.pbOwnSide.effects[PBEffects::Safeguard]>0 when 0x7D score+=70 if attacker.status==PBStatuses::FROZEN when 0x7F score-=80 if !pbCanChooseNonActive?(attacker.index) when 0x81 score+=10 if attacker.effects[PBEffects::MultiTurn]>0 score+=10 if attacker.effects[PBEffects::LeechSeed]>=0 score+=20 if attacker.pbOwnSide.effects[PBEffects::Spikes]>0 when 0x82 score+=50 if opponent.hp<=20 when 0x84, 0x85, 0x86 if attacker.hp==attacker.totalhp score-=80 else score+=30 if pbWeather==PBWeather::SUNNYDAY score-=30 if pbWeather==PBWeather::RAINDANCE score-=30 if pbWeather==PBWeather::SANDSTORM score-=30 if pbWeather==PBWeather::HAIL score+=50 score-=(attacker.hp*100/attacker.totalhp) end when 0x88 score-=80 if weather==PBWeather::RAINDANCE when 0x89 score-=80 if weather==PBWeather::SUNNYDAY when 0x8A score+=20 if (attacker.stages[PBStats::DEFENSE]<0) when 0x8B score+=20 if (attacker.stages[PBStats::ATTACK]<0) when 0x8C score+=10 if (attacker.stages[PBStats::ATTACK]<0) score+=10 if (attacker.stages[PBStats::DEFENSE]<0) score+=10 if (attacker.stages[PBStats::SPEED]<0) score+=10 if (attacker.stages[PBStats::SPATK]<0) score+=10 if (attacker.stages[PBStats::SPDEF]<0) when 0x8E if attacker.hp<=attacker.totalhp/2 || attacker.pbTooHigh?(PBStats::ATTACK) score-=100 end when 0x8F equal=true for i in 0...7 score+=10 if opponent.stages[i]>attacker.stages[i] score-=10 if opponent.stages[i]<attacker.stages[i] equal=false if opponent.stages[i]!=attacker.stages[i] end score-=80 if equal when 0x91 score+=10 if attacker.stages[PBStats::DEFENSE]<0 when 0x94 score-=80 if opponent.effects[PBEffects::FutureSight]>0 when 0x96 score+=40 if opponent.effects[PBEffects::Minimize] when 0x97 score+=30 if pbWeather==PBWeather::SUNNYDAY score-=30 if pbWeather==PBWeather::RAINDANCE score-=30 if pbWeather==PBWeather::SANDSTORM score-=30 if pbWeather==PBWeather::HAIL when 0x98 score-=50 if pbWeather==PBWeather::SUNNYDAY score+=30 if pbWeather==PBWeather::RAINDANCE when 0x99 score-=100 if @opponent when 0x9C score-=(attacker.stages[PBStats::DEFENSE]*10) when 0x9E score-=80 if attacker.turncount>=1 when 0xA0 if attacker.effects[PBEffects::Stockpile]>=3 score-=80 end when 0xA1 score-=80 if attacker.effects[PBEffects::Stockpile]==0 when 0xA2 score-=80 if attacker.effects[PBEffects::Stockpile]==0 || attacker.hp==attacker.totalhp when 0xA4 score-=80 if @weather==PBWeather::HAIL when 0xA5 score-=80 if opponent.effects[PBEffects::Torment] when 0xA6 if opponent.effects[PBEffects::Confusion]>0 score-=90 elsif opponent.stages[PBStats::SPATK]<0 score+=30 end when 0xA7 score-=80 if opponent.status!=0 score-=90 if opponent.pbHasType?(PBTypes::FIRE) when 0xA8 avg=(opponent.stages[PBStats::ATTACK]*10) avg+=(opponent.stages[PBStats::SPATK]*10) score+=avg score+=50 score-=(attacker.hp*100/attacker.totalhp) when 0xA9 score+=30 if attacker.status==PBStatuses::POISON score+=30 if attacker.status==PBStatuses::BURN score+=30 if attacker.status==PBStatuses::PARALYSIS when 0xAB score+=10 if opponent.status==PBStatuses::PARALYSIS when 0xAC score-=80 if attacker.pbPartner.hp==0 when 0xAE found=false for i in 0...4 if attacker.moves[i].type==PBTypes::ELECTRIC found=true break end end score-=80 if !found when 0xAF score-=80 if opponent.effects[PBEffects::Taunt]>0 when 0xB0 score-=80 if attacker.pbPartner.hp==0 when 0xB1 score-=80 if attacker.item==0 && opponent.item==0 when 0xB2 score-=80 if opponent.ability==PBAbilities::WONDERGUARD when 0xB3 score-=80 if attacker.effects[PBEffects::Wish]>0 when 0xB5 score-=80 if attacker.effects[PBEffects::Ingrain] when 0xB6 avg=(attacker.stages[PBStats::ATTACK]*10) avg+=(attacker.stages[PBStats::DEFENSE]*10) score+=avg/2 when 0xB8 score-=80 if attacker.effects[PBEffects::RecycleItem]==0 || attacker.item!=0 when 0xBA score+=30 if attacker.pbOpposingSide.effects[PBEffects::Reflect]>0 score+=30 if attacker.pbOpposingSide.effects[PBEffects::LightScreen]>0 when 0xBB if opponent.status!=0 score-=80 elsif opponent.effects[PBEffects::Yawn]>0 score-=80 elsif !opponent.pbCanSleep?(false) score-=40 end when 0xBC score-=20 if opponent.item==0 score+=20 if opponent.item!=0 when 0xBD score-=80 if attacker.hp>=opponent.hp when 0xBE score-=50 score+=(attacker.hp*100/attacker.totalhp) when 0xBF if opponent.ability==PBAbilities::WONDERGUARD || attacker.ability==PBAbilities::WONDERGUARD score-=80 end when 0xC0 score-=80 if attacker.effects[PBEffects::Imprison] when 0xC1 score-=80 if attacker.status==0 when 0xC6 score-=25 score+=(attacker.hp*50/attacker.totalhp) when 0xC7 score-=80 if attacker.effects[PBEffects::Confusion]>0 when 0xC8 score+=20 if attacker.effects[PBEffects::FocusEnergy] score-=20 if opponent.status==PBStatuses::BURN when 0xC9 score-=80 if attacker.effects[PBEffects::MudSport] when 0xCA score-=20 if opponent.status==PBStatuses::POISON when 0xCB score+=30 if pbWeather!=0 when 0xCC score+=(attacker.stages[PBStats::SPATK]*10) when 0xCD avg=(opponent.stages[PBStats::ATTACK]*10) avg+=(opponent.stages[PBStats::DEFENSE]*10) score+=avg/2 when 0xCE avg=-(attacker.stages[PBStats::DEFENSE]*10) avg-=(attacker.stages[PBStats::SPDEF]*10) score+=avg/2 when 0xD0 avg=-(attacker.stages[PBStats::ATTACK]*10) avg-=(attacker.stages[PBStats::DEFENSE]*10) score+=avg/2 when 0xD1 score+=20 if attacker.effects[PBEffects::FocusEnergy] score-=20 if opponent.status==PBStatuses::POISON when 0xD2 score-=80 if attacker.effects[PBEffects::WaterSport] when 0xD3 avg=-(attacker.stages[PBStats::SPATK]*10) avg-=(attacker.stages[PBStats::SPDEF]*10) score+=avg/2 when 0xD4 avg=-(attacker.stages[PBStats::ATTACK]*10) avg-=(attacker.stages[PBStats::SPEED]*10) score+=avg/2 end if move.basedamage>0 typemod=pbTypeModifier(move.type,opponent) if typemod==0 score-=80 else score-=20 if typemod==1 score-=10 if typemod==2 score+=35 if typemod==8 score+=60 if typemod==16 score+=25 if attacker.pbHasType?(move.type) if attacker.effects[PBEffects::Charge]>0 score+=20 if move.type==PBTypes::ELECTRIC end end score+=(move.basedamage/5)-10 else score-=10 end return score end def pbEnemyShouldWithdraw?(index) shouldswitch=false typecheck=false movetype=-1 if !@doublebattle && @opponent money=@opponent.moneyEarned if money>=70 # Experienced trainers only opponent=@battlers[index].pbOppositeOpposing if opponent.lastMoveUsed>0 && (opponent.level-@battlers[index].level).abs<=6 move=PBMoveData.new(opponent.lastMoveUsed) typemod=pbTypeModifier(move.type,@battlers[index]) movetype=move.type if move.basedamage>70 && typemod>4 shouldswitch=pbAIRandom(100)<30 movetype=move.type elsif move.basedamage>50 && typemod>4 shouldswitch=pbAIRandom(100)<20 movetype=move.type end end end end if !pbCanChooseMove?(index,0,false) && !pbCanChooseMove?(index,1,false) && !pbCanChooseMove?(index,2,false) && !pbCanChooseMove?(index,3,false) && @battlers[index].turncount && @battlers[index].turncount>5 shouldswitch=true end if @battlers[index].effects[PBEffects::PerishSong]==1 shouldswitch=true end if shouldswitch list=[] party=pbParty(index) for i in 0...party.length if pbCanSwitch?(index,i,false) if movetype>=0 && pbTypeModifier(movetype,@battlers[index])==0 && pbAIRandom(100)<80 list.unshift(i) elsif movetype>=0 && pbTypeModifier(movetype,@battlers[index])<4 && pbAIRandom(100)<55 list.unshift(i) else list.push(i) end end end if list.length>0 pbRegisterSwitch(index,list[0]) return true end end return false end def pbChooseMoves(index) attacker=@battlers[index] scores=[0,0,0,0] choices=[] totalscore=0 target=-1 if !@opponent && pbIsOpposing?(index) # If wild battle for i in 0...4 if pbCanChooseMove?(index,i,false) scores[i]=100 choices.push(i) totalscore+=100 end end else opponent=attacker.pbOppositeOpposing if @doublebattle otheropp=opponent.pbPartner scores1=[0,0,0,0] scores2=[0,0,0,0] maxscore1=0 maxscore2=0 totalscore1=0 totalscore2=0 for i in 0...4 if pbCanChooseMove?(index,i,false) scores1[i]=pbGetMoveScore(attacker.moves[i],attacker,opponent) scores2[i]=pbGetMoveScore(attacker.moves[i],attacker,otheropp) choices.push(i) end scores1[i]=0 if scores1[i]<0 scores2[i]=0 if scores2[i]<0 maxscore1=[scores1[i],maxscore1].max maxscore2=[scores2[i],maxscore2].max totalscore1+=scores1[i] totalscore2+=scores2[i] end usescore1weight=5 if maxscore1==maxscore2 if totalscore1==totalscore2 usescore1weight=5 else usescore1weight=(totalscore1>totalscore2) ? 7 : 3 end else usescore1weight=(maxscore1>maxscore2) ? 7 : 3 end if pbAIRandom(10)<usescore1weight target=opponent.index scores=scores1 totalscore=totalscore1 else target=otheropp.index scores=scores2 totalscore=totalscore2 end else for i in 0...4 if pbCanChooseMove?(index,i,false) scores[i]=pbGetMoveScore(attacker.moves[i],attacker,opponent) choices.push(i) end scores[i]=0 if scores[i]<0 totalscore+=scores[i] end end end maxscore=scores[0] maxscore=scores[1] if maxscore<scores[1] maxscore=scores[2] if maxscore<scores[2] maxscore=scores[3] if maxscore<scores[3] if maxscore==0 # If all scores are 0 or less choose a move at random if choices.length>0 pbRegisterMove(index,choices[pbAIRandom(choices.length)]) else pbAutoChooseMove(index) end else randnum=pbAIRandom(totalscore) cumtotal=0 for i in 0...4 if scores[i]>0 cumtotal+=scores[i] if randnum<cumtotal pbRegisterMove(index,i) break end end end end if @doublebattle && target>=0 pbRegisterTarget(index,target) end end end
PokeBattle_Trainer
[
Selecionar
] [
-
]
class PokeBattle_Trainer ########## # Trainer's initial money INITIALMONEY=2000 ########## attr_reader(:name) attr_accessor(:id) attr_accessor(:trainertype) attr_accessor(:badges) attr_accessor(:seen) attr_accessor(:money) attr_accessor(:owned) attr_accessor(:party) attr_accessor(:pokedex) # Whether the Pokédex was obtained attr_accessor(:pokegear) def trainerTypeName # Name of this trainer type begin ret="" pbRgssOpen("Data/trainernames.dat","rb"){|f| trainernames=Marshal.load(f) raise _INTL("Bad trainer type") if !trainernames[@trainertype] ret=trainernames[@trainertype][2] raise _INTL("Blank trainer type") if !ret||ret.length==0 } return ret rescue PBDebug.logonerr { raise } return _INTL("PKMN Trainer") end end def moneyEarned # Money won when trainer is defeated begin ret=0 pbRgssOpen("Data/trainernames.dat","rb"){|f| trainernames=Marshal.load(f) raise _INTL("Bad trainer type") if !trainernames[@trainertype] ret=trainernames[@trainertype][3] } return ret rescue return 30 end end def pokemonCount ret=0 for i in 0...@party.length ret+=1 if @party[i] && !@party[i].egg? end return ret end def ablePokemonCount ret=0 for i in 0...@party.length ret+=1 if @party[i] && !@party[i].egg? && @party[i].hp>0 end return ret end def fullname return _INTL("{1} {2}",self.trainerTypeName,@name) end def numbadges # Number of badges ret=0 for i in 0...@badges.length ret+=1 if @badges[i] end return ret end def publicID(id) # Portion of the ID which is visible on the Trainer Card return id&0xFFFF end def pokedexSeen # Number of Pokémon seen ret=0 for i in 0..PBSpecies.getCount ret+=1 if @seen[i] end return ret end def pokedexOwned # Number of Pokémon owned ret=0 for i in 0..PBSpecies.getCount ret+=1 if @owned[i] end return ret end def setForeignID(other) @id=other.getForeignID end def getForeignID # Random ID other than this Trainer's ID fid=0 loop do fid=rand(256) fid|=rand(256)<<8 fid|=rand(256)<<16 fid|=rand(256)<<24 break if fid!=@id end return fid end def initialize(name,trainertype) @name=name @trainertype=trainertype @id=rand(256) @id|=rand(256)<<8 @id|=rand(256)<<16 @id|=rand(256)<<24 @seen=[] @owned=[] @badges=[] @pokedex=false @pokegear=false for i in 0..PBSpecies.getCount @seen[i]=false @owned[i]=false end for i in 0..7 @badges[i]=false end @money=INITIALMONEY @party=[] end end
PokeBattle_Effects
[
Selecionar
] [
-
]
class PokeBattle_Battler def pbTooLow?(stat) return @stages[stat]<=-6 end def pbTooHigh?(stat) return @stages[stat]>=6 end def pbCanPoison?(showMessages) return false if hp<=0 if pbHasType?(PBTypes::POISON) || pbHasType?(PBTypes::STEEL) @battle.pbDisplay(_INTL("It doesn't affect {1}...",pbThis)) if showMessages return false end if status==PBStatuses::POISON @battle.pbDisplay(_INTL("{1} is already poisoned.",pbThis)) if showMessages return false end if self.status!=0 @battle.pbDisplay(_INTL("But it failed!")) if showMessages return false end if self.ability==PBAbilities::IMMUNITY @battle.pbDisplay(_INTL("{1}'s Immunity prevents poisoning!",pbThis)) if showMessages return false end if @effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("But it failed!")) if showMessages return false end if pbOwnSide.effects[PBEffects::Safeguard]>0 @battle.pbDisplay(_INTL("{1}'s party is protected by Safeguard!",pbThis)) if showMessages return false end return true end def pbPoison(attacker,toxic=false) self.status=PBStatuses::POISON if toxic self.statusCount=1 self.effects[PBEffects::Toxic]=0 else self.statusCount=0 end @battle.synchronize[0]=self.index @battle.synchronize[1]=attacker.index @battle.synchronize[2]=PBStatuses::POISON @battle.pbCommonAnimation("Poison",attacker,self) end def pbBurn(attacker) self.status=PBStatuses::BURN self.statusCount=0 @battle.synchronize[0]=self.index @battle.synchronize[1]=attacker.index @battle.synchronize[2]=PBStatuses::BURN @battle.pbCommonAnimation("Burn",attacker,self) end def pbParalyze(attacker) self.status=PBStatuses::PARALYSIS self.statusCount=0 @battle.synchronize[0]=self.index @battle.synchronize[1]=attacker.index @battle.synchronize[2]=PBStatuses::PARALYSIS @battle.pbCommonAnimation("Paralysis",attacker,self) end def pbSleep(duration=-1) self.status=PBStatuses::SLEEP if duration>0 self.statusCount=duration else self.statusCount=2+@battle.pbRandom(6) end pbCancelMoves @battle.pbCommonAnimation("Sleep",self,nil) end def pbFreeze self.status=PBStatuses::FROZEN self.statusCount=0 pbCancelMoves @battle.pbCommonAnimation("Frozen",self,nil) end def pbConfuseSelf if @effects[PBEffects::Confusion]==0 && effects[PBEffects::Ability]!=PBAbilities::OWNTEMPO @effects[PBEffects::Confusion]=2+@battle.pbRandom(4) @battle.pbCommonAnimation("Confusion",self,nil) @battle.pbDisplay(_INTL("{1} became confused!",pbThis)) end end def pbCanPoisonSynchronize?(opponent) return false if hp<=0 if pbHasType?(PBTypes::POISON) || pbHasType?(PBTypes::STEEL) @battle.pbDisplay(_INTL("{1}'s {2} had no effect on {3}!",opponent.pbThis, PBAbilities.getName(opponent.ability),pbThis)) return false end if self.status!=0 return false end if opponent.ability==PBAbilities::IMMUNITY @battle.pbDisplay(_INTL("{1}'s {2} prevents {3}'s {4} from working!", pbThis,PBAbilities.getName(self.ability), opponent.pbThis,PBAbilities.getName(opponent.ability) )) return false end return true end def pbCanSleepYawn? if ability!=PBAbilities::SOUNDPROOF for i in 0..3 if @battle.battlers[i].effects[PBEffects::Uproar]>0 return false end end end if ability==PBAbilities::VITALSPIRIT || ability==PBAbilities::INSOMNIA return false end if status!=0 return false end return true end def pbCanSleep?(showMessages,selfsleep=false) return false if hp<=0 if !selfsleep && effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("But it failed!")) if showMessages return false end if status==PBStatuses::SLEEP @battle.pbDisplay(_INTL("{1} is already asleep!",pbThis)) if showMessages return false end if ability!=PBAbilities::SOUNDPROOF for i in 0..3 if @battle.battlers[i].effects[PBEffects::Uproar]>0 @battle.pbDisplay(_INTL("But the Uproar kept {1} awake!",pbThis)) if showMessages return false end end end if self.ability==PBAbilities::VITALSPIRIT || self.ability==PBAbilities::INSOMNIA abilityname=PBAbilities.getName(self.ability) @battle.pbDisplay(_INTL("{1} stayed awake using its {2}!",pbThis,abilityname)) if showMessages return false end if !selfsleep && status!=0 @battle.pbDisplay(_INTL("But it failed!")) if showMessages return false end if !selfsleep && pbOwnSide.effects[PBEffects::Safeguard]>0 @battle.pbDisplay(_INTL("{1}'s party is protected by Safeguard!",pbThis)) if showMessages return false end return true end def pbCanParalyze?(showMessages) return false if hp<=0 if self.ability==PBAbilities::LIMBER @battle.pbDisplay(_INTL("{1}'s Limber prevents paralysis!",pbThis)) if showMessages return false end if @effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("But it failed!")) if showMessages return false end if status==PBStatuses::PARALYSIS @battle.pbDisplay(_INTL("{1} is already paralyzed!",pbThis)) if showMessages return false end if self.status!=0 @battle.pbDisplay(_INTL("But it failed!")) if showMessages return false end if pbOwnSide.effects[PBEffects::Safeguard]>0 @battle.pbDisplay(_INTL("{1}'s party is protected by Safeguard!",pbThis)) if showMessages return false end return true end def pbCanParalyzeSynchronize?(opponent) if opponent.ability==PBAbilities::LIMBER @battle.pbDisplay(_INTL("{1}'s Limber prevents {2}'s Synchronize from working!",pbThis,opponent.pbThis)) return false end if self.status!=0 return false end return true end def pbCanFreeze?(showMessages) return false if hp<=0 if @battle.pbWeather==PBWeather::SUNNYDAY|| status!=0|| ability==PBAbilities::MAGMAARMOR|| pbOwnSide.effects[PBEffects::Safeguard]>0|| effects[PBEffects::Substitute]>0|| pbHasType?(PBTypes::ICE) return false end return true end def pbCanConfuse?(showMessages) return false if hp<=0 if effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("But it failed!")) if showMessages return false end if ability==PBAbilities::OWNTEMPO @battle.pbDisplay(_INTL("{1}'s Own Tempo prevents confusion!",pbThis)) if showMessages return false end if pbOwnSide.effects[PBEffects::Safeguard]>0 @battle.pbDisplay(_INTL("{1}'s party is protected by Safeguard!",pbThis)) if showMessages return false end if effects[PBEffects::Confusion]>0 @battle.pbDisplay(_INTL("{1} is already confused!",pbThis)) if showMessages return false end return true end def pbCanBurn?(showMessages) if hp<=0 return false end if self.status==PBStatuses::BURN @battle.pbDisplay(_INTL("{1} already has a burn.",pbThis)) if showMessages return false end if pbHasType?(PBTypes::FIRE) @battle.pbDisplay(_INTL("It doesn't affect {1}...",pbThis)) if showMessages return false end if self.status!=0 @battle.pbDisplay(_INTL("But it failed!")) if showMessages return false end if @effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("But it failed!")) if showMessages return false end if self.ability==PBAbilities::WATERVEIL @battle.pbDisplay(_INTL("{1}'s Water Veil prevents burns!",pbThis)) if showMessages return false end if pbOwnSide.effects[PBEffects::Safeguard]>0 @battle.pbDisplay(_INTL("{1}'s party is protected by Safeguard!",pbThis)) if showMessages return false end return true end def pbCanBurnFromFireMove?(move,showMessages) if hp<=0 return false end if self.status==PBStatuses::BURN @battle.pbDisplay(_INTL("{1} already has a burn.",pbThis)) if showMessages return false end if pbHasType?(PBTypes::FIRE) @battle.pbDisplay(_INTL("It doesn't affect {1}...",pbThis)) if showMessages return false end if self.status!=0 @battle.pbDisplay(_INTL("But it failed!")) if showMessages return false end if @effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("But it failed!")) if showMessages return false end if self.ability==PBAbilities::FLASHFIRE && move.type==PBTypes::FIRE if !@effects[PBEffects::FlashFire] @battle.pbDisplay(_INTL("{1}'s Flash Fire raised its Fire power!",@pbThis)) @effects[PBEffects::FlashFire]=true else @battle.pbDisplay(_INTL("{1}'s Flash Fire made {2} ineffective!",@pbThis,move.name)) end return false end if self.ability==PBAbilities::WATERVEIL @battle.pbDisplay(_INTL("{1}'s Water Veil prevents burns!",pbThis)) if showMessages return false end if pbOwnSide.effects[PBEffects::Safeguard]>0 @battle.pbDisplay(_INTL("{1}'s party is protected by Safeguard!",pbThis)) if showMessages return false end return true end def pbCanBurnSynchronize?(opponent) return false if hp<=0 if pbHasType?(PBTypes::FIRE) @battle.pbDisplay(_INTL("{1}'s Synchronize had no effect on {2}!",opponent.pbThis,pbThis)) return false end if self.status!=0 return false end if ability==PBAbilities::WATERVEIL @battle.pbDisplay(_INTL("{1}'s {2} prevents {3}'s {4} from working!", pbThis,PBAbilities.getName(self.ability), opponent.pbThis,PBAbilities.getName(opponent.ability) )) return false end return true end def pbCanReduceStatStage?(stat,showMessages) if hp<=0 return false end if effects[PBEffects::Substitute]>0 # Note: Not used if move is Tickle @battle.pbDisplay(_INTL("But it failed!")) if showMessages return false end if pbOwnSide.effects[PBEffects::Mist]>0 @battle.pbDisplay(_INTL("{1} is protected by Mist!",pbThis)) if showMessages return false end if ability==PBAbilities::CLEARBODY||ability==PBAbilities::WHITESMOKE abilityname=PBAbilities.getName(ability) @battle.pbDisplay(_INTL("{1}'s {2} prevents stat loss!",pbThis,abilityname)) if showMessages return false end if stat==PBStats::ATTACK && ability==PBAbilities::HYPERCUTTER abilityname=PBAbilities.getName(ability) @battle.pbDisplay(_INTL("{1}'s {2} prevents Attack loss!",pbThis,abilityname)) if showMessages return false end if stat==PBStats::ACCURACY && ability==PBAbilities::KEENEYE abilityname=PBAbilities.getName(ability) @battle.pbDisplay(_INTL("{1}'s {2} prevents Accuracy loss!",pbThis,abilityname)) if showMessages return false end return true end def pbReduceStat(stat,increment,showMessages,moveid=nil,attacker=nil) # Note: Not used if attack is Tickle arrStatTexts=[ _INTL("{1}'s Attack fell!"), _INTL("{1}'s Defense fell!"), _INTL("{1}'s Speed fell!"), _INTL("{1}'s Special Attack fell!"), _INTL("{1}'s Special Defense fell!"), _INTL("{1}'s accuracy fell!"), _INTL("{1}'s evasiveness fell!"), _INTL("{1}'s Attack harshly fell!"), _INTL("{1}'s Defense harshly fell!"), _INTL("{1}'s Speed harshly fell!"), _INTL("{1}'s Special Attack harshly fell!"), _INTL("{1}'s Special Defense harshly fell!"), _INTL("{1}'s accuracy harshly fell!"), _INTL("{1}'s evasiveness harshly fell!"), _INTL("{1}'s Attack won't go lower!"), _INTL("{1}'s Defense won't go lower!"), _INTL("{1}'s Speed won't go lower!"), _INTL("{1}'s Special Attack won't go lower!"), _INTL("{1}'s Special Defense won't go lower!"), _INTL("{1}'s accuracy won't go lower!"), _INTL("{1}'s evasiveness won't go lower!"), ] if pbCanReduceStatStage?(stat,showMessages) if pbTooLow?(stat) @battle.pbDisplay(arrStatTexts[14+stat].gsub(/\\{1\\}/){pbThis}) if showMessages return false else @stages[stat]-=increment @stages[stat]=-6 if @stages[stat]<-6 if moveid @battle.pbAnimation(moveid,attacker,self) end @battle.pbCommonAnimation("StatDown",attacker,self) if increment==2 @battle.pbDisplay(arrStatTexts[7+stat].gsub(/\\{1\\}/){pbThis}) else @battle.pbDisplay(arrStatTexts[stat].gsub(/\\{1\\}/){pbThis}) end return true end end return false end def pbReduceAttackStatStageIntimidate(opponent) if hp<=0 return false end if effects[PBEffects::Substitute]>0 return false end if ability==PBAbilities::CLEARBODY||ability==PBAbilities::WHITESMOKE||ability==PBAbilities::HYPERCUTTER abilityname=PBAbilities.getName(ability) oppabilityname=PBAbilities.getName(opponent.ability) @battle.pbDisplay(_INTL("{1}'s {2} prevented {3}'s {4} from working!",pbThis,abilityname,opponent.pbThis,oppabilityname)) return false end if pbOwnSide.effects[PBEffects::Mist]>0 @battle.pbDisplay(_INTL("{1} is protected by Mist!",pbThis)) return false end if @stages[PBStats::ATTACK]>-6 @stages[PBStats::ATTACK]-=1 oppabilityname=PBAbilities.getName(opponent.ability) @battle.pbCommonAnimation("StatDown",opponent,self) @battle.pbDisplay(_INTL("{1}'s {2} cuts {3}'s Attack!",opponent.pbThis,oppabilityname,pbThis)) return true end return false end end
PokeBattle_Confusion
[
Selecionar
] [
-
]
=begin Pseudomove for confusion damage. =end class PokeBattle_Confusion < PokeBattle_Move def initialize(battle,move) @battle=battle @basedamage=40 @type=-1 @accuracy=100 @pp=-1 @addlEffect=0 @target=0 @priority=0 @flags=0 @thismove=move @name="" @id=0 end def pbIsPhysical?(type) return true end def pbIsSpecial?(type) return false end def pbCalcDamage(attacker,opponent) return super(attacker,opponent, PokeBattle_Move::NOCRITICAL|PokeBattle_Move::NOREFLECT|PokeBattle_Move::NOTYPE) end end
PokeBattle_BattlePalace
[
Selecionar
] [
-
]
class PokeBattle_BattlePalace < PokeBattle_Battle @@BattlePalaceUsualTable=[ 61,7,32, 20,25,55, 70,15,15, 38,31,31, 20,70,10, 30,20,50, 56,22,22, 25,15,60, 69,6,25, 35,10,55, 62,10,28, 58,37,5, 34,11,55, 35,5,60, 56,22,22, 35,45,20, 44,50,6, 56,22,22, 30,58,12, 30,13,57, 40,50,10, 18,70,12, 88,6,6, 42,50,8, 56,22,22 ] @@BattlePalacePinchTable=[ 61, 7,32, 84, 8, 8, 32,60, 8, 70,15,15, 70,22, 8, 32,58,10, 56,22,22, 75,15,10, 28,55,17, 29, 6,65, 30,20,50, 88, 6, 6, 29,11,60, 35,60, 5, 56,22,22, 34,60, 6, 34, 6,60, 56,22,22, 30,58,12, 27, 6,67, 25,62,13, 90, 5, 5, 22,20,58, 42, 5,53, 56,22,22 ] def initialize(*arg) super @justswitched=[false,false,false,false] end def pbMoveCategory(move) if move.target==0x10 || move.id==PBMoves::BIDE return 1 elsif move.basedamage==0 || move.id==PBMoves::COUNTER || move.id==PBMoves::MIRRORCOAT return 2 else return 0 end end def pbCanChooseMovePartial?(idxPokemon,idxMove) # Different implementation of pbCanChooseMove, ignores Imprison/Torment/Taunt/Disable/Encore thispkmn=@battlers[idxPokemon] thismove=thispkmn.moves[idxMove] if !thismove||thismove.id==0 return false end if thismove.pp<=0 return false end if thispkmn.effects[PBEffects::ChoiceBand]!=0 && thismove.id!=thispkmn.effects[PBEffects::ChoiceBand]&& thispkmn.item.id==PBItems::CHOICEBAND return false end # though incorrect, just for convenience (actually checks Torment later) if thispkmn.effects[PBEffects::Torment] if thismove.id==thispkmn.lastMoveUsed return false end end return true end def pbPinchChange(idxPokemon) thispkmn=@battlers[idxPokemon] if !thispkmn.effects[PBEffects::Pinch] && thispkmn.status!=PBStatuses::SLEEP && thispkmn.hp<=(thispkmn.totalhp/2).floor nature=thispkmn.nature thispkmn.effects[PBEffects::Pinch]=true if nature==PBNatures::QUIET|| nature==PBNatures::BASHFUL|| nature==PBNatures::NAIVE|| nature==PBNatures::QUIRKY|| nature==PBNatures::HARDY|| nature==PBNatures::DOCILE|| nature==PBNatures::SERIOUS pbDisplay(_INTL("{1} is eager for more!",thispkmn.pbThis)) end if nature==PBNatures::CAREFUL|| nature==PBNatures::RASH|| nature==PBNatures::LAX|| nature==PBNatures::SASSY|| nature==PBNatures::MILD|| nature==PBNatures::TIMID pbDisplay(_INTL("{1} began growling deeply!",thispkmn.pbThis)) end if nature==PBNatures::GENTLE|| nature==PBNatures::ADAMANT|| nature==PBNatures::HASTY|| nature==PBNatures::LONELY|| nature==PBNatures::RELAXED|| nature==PBNatures::NAUGHTY pbDisplay(_INTL("A glint appears in {1}'s eyes!",thispkmn.pbThis)) end if nature==PBNatures::JOLLY|| nature==PBNatures::BOLD|| nature==PBNatures::BRAVE|| nature==PBNatures::CALM|| nature==PBNatures::IMPISH|| nature==PBNatures::MODEST pbDisplay(_INTL("{1} is getting into position!",thispkmn.pbThis)) end end end def pbEnemyShouldWithdraw?(index) shouldswitch=false if @battlers[index].effects[PBEffects::PerishSong]==1 shouldswitch=true else hppercent=@battlers[index].hp*100/@battlers[index].totalhp percents=[] maxindex=-1 maxpercent=0 factor=0 party=pbParty(index) for i in 0...party.length if pbCanSwitch?(index,i,false) percents[i]=party[i].hp*100/party[i].totalhp if percents[i]>maxpercent maxindex=i maxpercent=percents[i] end else percents[i]=0 end end if hppercent<50 factor=(maxpercent<hppercent) ? 20 : 40 end if hppercent<25 factor=(maxpercent<hppercent) ? 30 : 50 end if @battlers[index].status==PBStatuses::BURN || @battlers[index].status==PBStatuses::POISON factor+=10 end if @battlers[index].status==PBStatuses::PARALYSIS factor+=15 end if @battlers[index].status==PBStatuses::FROZEN || @battlers[index].status==PBStatuses::SLEEP factor+=20 end if @justswitched[index] factor-=40 factor=0 if factor<0 end shouldswitch=(pbAIRandom(100)<factor) if shouldswitch && maxindex>=0 pbRegisterSwitch(index,maxindex) return true end end @justswitched[index]=shouldswitch if shouldswitch party=pbParty(index) for i in 0...party.length if pbCanSwitch?(index,i,false) pbRegisterSwitch(index,i) return true end end end return false end def pbRegisterMove(idxPokemon,idxMove) thispkmn=@battlers[idxPokemon] if idxMove==-2 @choices[idxPokemon][0]=1 # Move @choices[idxPokemon][1]=-2 # "Incapable of using its power..." @choices[idxPokemon][2]=@struggle @choices[idxPokemon][3]=-1 else @choices[idxPokemon][0]=1 # Move @choices[idxPokemon][1]=idxMove # Index of move @choices[idxPokemon][2]=thispkmn.moves[idxMove] # Move object @choices[idxPokemon][3]=-1 # No target chosen end end def pbAutoFightMenu(idxPokemon) thispkmn=@battlers[idxPokemon] nature=thispkmn.nature randnum=pbAIRandom(100) category=0 atkpercent=0 defpercent=0 if !thispkmn.effects[PBEffects::Pinch] atkpercent=@@BattlePalaceUsualTable[nature*3] defpercent=atkpercent+@@BattlePalaceUsualTable[nature*3+1] else atkpercent=@@BattlePalacePinchTable[nature*3] defpercent=atkpercent+@@BattlePalacePinchTable[nature*3+1] end if randnum<atkpercent category=0 elsif randnum<defpercent category=1 else category=2 end moves=[] for i in 0...thispkmn.moves.length next if !pbCanChooseMovePartial?(idxPokemon,i) if pbMoveCategory(thispkmn.moves[i])==category moves[moves.length]=i end end if moves.length==0 # No moves of selected category pbRegisterMove(idxPokemon,-2) else chosenmove=moves[pbAIRandom(moves.length)] pbRegisterMove(idxPokemon,chosenmove) end return true end def pbEndOfRoundPhase super return if @decision!=0 for i in 0..3 if @battlers[i].hp>0 pbPinchChange(i) end end end end class PokeBattle_Move_Blitz < PokeBattle_Move # Maps keys to numbers. KEYHASH={ :A=>0x41,:B=>0x42,:C=>0x43,:D=>0x44, :E=>0x45,:F=>0x46,:G=>0x47,:H=>0x48, :I=>0x49,:J=>0x4a,:K=>0x4b,:L=>0x4c, :M=>0x4D,:N=>0x4e,:O=>0x4f,:P=>0x50, :Q=>0x51,:R=>0x52,:S=>0x53,:T=>0x54, :U=>0x55,:V=>0x56,:W=>0x57,:X=>0x58, :Y=>0x59,:Z=>0x5a,:NUM_0=>0x30,:NUM_1=>0x31, :NUM_2=>0x32,:NUM_3=>0x33,:NUM_4=>0x34,:NUM_5=>0x35, :NUM_6=>0x36,:NUM_7=>0x37,:NUM_8=>0x38,:NUM_9=>0x39, :UP=>0x26,:DOWN=>0x28,:LEFT=>0x25,:RIGHT=>0x27, :SPACE=>0x20,:ENTER=>0x0D,:TAB=>0x09 } # Calls the blitz function def pbDisplayUseMessage(attacker) ret=super if @battle.pbOwnedByPlayer?(attacker.index) @time=@battle.scene.pbBlitz(@keys) if @time<0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end else @time=@battle.pbRandom(30)*@keys.length end return ret end # Calculates the base damage based on the time # it took to input the key combination. The shorter # the time, the greater the damage. def pbBaseDamage(basedmg,attacker,opponent) return 10 if !@time || @time<0 timeAverage=@time/[1,@keys.length].max return 10 if timeAverage>30 return 20 if timeAverage>25 return 40 if timeAverage>20 return 60 if timeAverage>16 return 80 if timeAverage>12 return 100 if timeAverage>8 return 150 if timeAverage>4 return 200 end def self.triggerKeyState(key) # -1: no keys pressed; 0: wrong key pressed; 1: correct key pressed correctKey=(KEYHASH[key]) ? KEYHASH[key] : 0x20 # check wrong keys first for i in KEYHASH.values if i!=correctKey return 0 if Input.triggerex?(i) end end # then check correct key return (Input.triggerex?(correctKey)) ? 1 : -1 end def self.getKey(key) return (KEYHASH[key]) ? KEYHASH[key] : 0x20 end end # Fire Blitz class PokeBattle_Move_110 < PokeBattle_Move_Blitz def initialize(battle,move) super @keys=[:A,:B,:UP,:DOWN] end end # Ice Blitz class PokeBattle_Move_111 < PokeBattle_Move_Blitz def initialize(battle,move) super @keys=[:X,:W,:LEFT,:RIGHT] end end # ThunderBlitz class PokeBattle_Move_112 < PokeBattle_Move_Blitz def initialize(battle,move) super @keys=[:Z,:Q,:P,:M] end end # Time Attack class PokeBattle_Move_113 < PokeBattle_Move def pbOnStartUse(attacker) totalsec = Graphics.frame_count / Graphics.frame_rate min = totalsec / 60 % 60 time = min % 10 # Get the ones digit of the current playtime minutes @calcbasedamage=[10,20,40,50,60, 70,80,100,150,200][time] return true end def pbBaseDamage(basedmg,attacker,opponent) return @calcbasedamage end end # Chatter class PokeBattle_Move_10B < PokeBattle_Move def pbEffect(attacker, opponent) if opponent.ability==PBAbilities::SOUNDPROOF @battle.pbDisplay(_INTL("{1}'s {2} blocks {3}!",i.pbThis,PBAbilities.getName(opponent.ability),name)) return -1 end @battle.scene.pbChatter(attacker, opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0 && attacker.species==PBSpecies::CHATOT && !attacker.effects[PBEffects::Transform] && attacker.pokemon && opponent.ability!=PBAbilities::SHIELDDUST && opponent.hp>0 chance=1 if attacker.pokemon.chatter chance=attacker.pokemon.chatter.intensity*30/127 chance+=1 end if rand(100)<chance && opponent.canConfuse?(false) @battle.pbAnimation(@id,attacker,opponent) opponent.effects[PBEffects::Confusion]=2+@battle.pbRandom(4) @battle.pbDisplay(_INTL("{1} became confused!",opponent.pbThis)) end end return ret end end class PokeBattle_Scene def pbChatter(attacker,opponent) if attacker.pokemon pbPlayCry(attacker.pokemon,90,100) end Graphics.frame_rate.times do Graphics.update Input.update end end # Processes the blitz function with the array of keys. Each key will # display after 30 frames. If no keys were pressed after all keys are # shown, or if all keys pressed were wrong, the move fails. If an # incorrect key was pressed, a time penalty of 30 frames will be added. # For blitz moves, the shorter the time, the greater the damage. def pbBlitz(keys) @briefmessage=false blitzwindow=Window_AdvancedTextPokemon.newWithSize("",0,Graphics.height-96-64,Graphics.width*2/3,64) blitzwindow.z=100001 keystates=[0,0,0,0] start=Graphics.frame_count time=0 penalty=0 blitzCount=0 blitzCurrent=0 shownTime=0 failures=0 loop do Graphics.update Input.update blitzwindow.update needRefresh=false if shownTime%30 == 0 blitzCount+=1 needRefresh=true if blitzCount>keys.length Audio.se_play("Audio/SE/buzzer.wav") penalty=0 time=-1 break end end keyState=PokeBattle_Move_Blitz.triggerKeyState(keys[blitzCurrent]) if keyState>=0 # Either correct or incorrect if keyState==1 # Correct Audio.se_play(pbGetDecisionSE) keystates[blitzCurrent]=1 else # Incorrect Audio.se_play("Audio/SE/buzzer.wav") keystates[blitzCurrent]=2 penalty+=30 failures+=1 end blitzCurrent+=1 if blitzCurrent>=keys.length if failures==keys.length time=-1 penalty=0 end break end shownTime=0 blitzCount=blitzCurrent+1 if blitzCount<blitzCurrent+1 needRefresh=true end if needRefresh newtext="" for i in 0...blitzCount newtext+=" " if i>0 if keystates[i]==1 #Correct newtext+="<c2=06644bd2>"+keys[i].to_s+"</c2>" elsif keystates[i]==2 # Incorrect newtext+="<c2=043c3aff>"+keys[i].to_s+"</c2>" else newtext+=keys[i].to_s end end blitzwindow.text=newtext end time+=1 shownTime+=1 end blitzwindow.dispose return time+penalty end end
PokeBattle_BattleArena
[
Selecionar
] [
-
]
#42846537 begin class PokeBattle_BattleArena < PokeBattle_Battle def initialize(*arg) super @battlerschanged=true @mind=[0,0] @skill=[0,0] @starthp=[0,0] @count=0 @partyindexes=[0,0] end def pbCanSwitchLax?(idxPokemon,pkmnidxTo,showMessages) return false end def pbSwitch return if @decision>0 if pbAllFainted?(@party1) @decision=2 return end if pbAllFainted?(@party2) @decision=1 return end if @battlers[0].hp==0 @partyindexes[0]+=1 newpoke=@partyindexes[0] pbDisplayBrief(_INTL("Go! {1}!",@party1[newpoke].name)) @battlers[0].pbInitialize(@party1[newpoke],newpoke,false); @scene.pbSendOut(0,@party1[newpoke]) pbOnActiveOne(@battlers[0]) end if @battlers[1].hp==0 @partyindexes[1]+=1 newenemy=@partyindexes[1] pbDisplayBrief(_INTL("{1} sent out {2}!",@opponent.fullname,@party2[newenemy].name)) @battlers[1].pbInitialize(@party2[newenemy],newenemy,false); @scene.pbTrainerSendOut(1,@party2[newenemy]) pbOnActiveOne(@battlers[1]) end end def pbOnActiveAll @battlerschanged=true @mind[0]=0 @mind[1]=0 @skill[0]=0 @skill[1]=0 @starthp[0]=battlers[0].hp @starthp[1]=battlers[1].hp @count=0 return super end def pbOnActiveOne(*arg) @battlerschanged=true @mind[0]=0 @mind[1]=0 @skill[0]=0 @skill[1]=0 @starthp[0]=battlers[0].hp @starthp[1]=battlers[1].hp @count=0 return super end def pbMindScore(move) if move.id==PBMoves::PROTECT|| move.id==PBMoves::DETECT|| move.id==PBMoves::ENDURE|| move.id==PBMoves::FAKEOUT return -1 end if move.id==PBMoves::COUNTER|| move.id==PBMoves::MIRRORCOAT|| move.id==PBMoves::BIDE return 0 end if move.basedamage==0 return 0 else return 1 end end def pbCommandPhase if @battlerschanged pbDisplay(_INTL("REFEREE: {1} VS {2}! Commence battling!",@battlers[0].name,@battlers[1].name)) @battlerschanged=false @count=0 end super return if @decision!=0 # Update mind rating (asserting that a move was chosen) # TODO: Actually done at Pokémon's turn for i in 0..1 if @choices[i][2] @mind[i]+=pbMindScore(@choices[i][2]) end end end def pbEndOfRoundPhase super return if @decision!=0 @count+=1 if @count==3 points=[0,0] @battlers[0].pbCancelMoves @battlers[1].pbCancelMoves pbDisplay(_INTL("REFEREE: That's it! We will now go to judging to determine the winner!")) if !self.debug pbDisplayPaused(_INTL("REFEREE: Judging category 1, Mind! The Pokémon showing the most guts!")) if !self.debug if @mind[0]==@mind[1] points[0]+=1 points[1]+=1 elsif @mind[0]>@mind[1] points[0]+=2 else points[1]+=2 end pbDisplayPaused(_INTL("{1}: {2}\\n{3}: {4}",@battlers[0].pbThis,points[0],@battlers[1].pbThis,points[1])) pbDisplayPaused(_INTL("REFEREE: Judging category 2, Skill! The Pokémon using moves the best!")) if !self.debug # TODO: Skill rating not determined yet if @skill[0]==@skill[1] points[0]+=1 points[1]+=1 elsif @skill[0]>@skill[1] points[0]+=2 else points[1]+=2 end pbDisplayPaused(_INTL("{1}: {2}\\n{3}: {4}",@battlers[0].pbThis,points[0],@battlers[1].pbThis,points[1])) pbDisplayPaused(_INTL("REFEREE: Judging category 3, Body! The Pokémon with the most vitality!")) if !self.debug body=[0,0] body[0]=((@battlers[0].hp*100)/@starthp[0]).floor body[1]=((@battlers[1].hp*100)/@starthp[1]).floor if body[0]==body[1] points[0]+=1 points[1]+=1 elsif body[0]>body[1] points[0]+=2 else points[1]+=2 end pbDisplayPaused(_INTL("{1}: {2}\\n{3}: {4}",@battlers[0].pbThis,points[0],@battlers[1].pbThis,points[1])) if points[0]==points[1] pbDisplayPaused(_INTL("REFEREE: Judgment: {1} to {2}! We have a draw!",points[0],points[1])) if !self.debug pbDisplay(_INTL("{1} tied the opponent {2} in a referee's decision!",@battlers[0].name,@battlers[1].name)) if !self.debug @battlers[0].hp=0 @battlers[0].pbFaint @battlers[1].hp=0 @battlers[1].pbFaint elsif points[0]>points[1] pbDisplayPaused(_INTL("REFEREE: Judgment: {1} to {2}! The winner is {3}'s {4}!",points[0],points[1],@player.name,@battlers[0].name)) if !self.debug pbDisplay(_INTL("{1} defeated the opponent {2} in a referee's decision!",@battlers[0].name,@battlers[1].name)) if !self.debug @battlers[1].hp=0 @battlers[1].pbFaint else pbDisplayPaused(_INTL("REFEREE: Judgment: {1} to {2}! The winner is {3}!",points[0],points[1],@battlers[1].pbThis)) if !self.debug pbDisplay(_INTL("{1} lost to the opponent {2} in a referee's decision!",@battlers[0].name,@battlers[1].name)) if !self.debug @battlers[0].hp=0 @battlers[0].pbFaint end pbGainEXP pbSwitch end end end rescue Exception if $!.is_a?(SystemExit) || "#{$!.class}"=="Reset" raise $! else end end
PokeBattle_BattleEffects
[
Selecionar
] [
-
]
class PokeBattle_Move_00 < PokeBattle_Move def pbBaseDamage(basedmg,attacker,opponent) if @id==PBMoves::SURF&& opponent.effects[PBEffects::TwoTurnAttack]==PBMoves::DIVE return basedmg*2 end return basedmg end end class PokeBattle_Move_01 < PokeBattle_Move def pbEffect(attacker,opponent) if opponent.pbCanSleep?(true) @battle.pbAnimation(@id,attacker,opponent) opponent.pbSleep @battle.pbDisplay(_INTL("{1} went to sleep!",opponent.pbThis)) return 0 end return -1 end end class PokeBattle_Move_02 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if !opponent.pbCanPoison?(false) return false end opponent.pbPoison(attacker) @battle.pbDisplay(_INTL("{1} became poisoned!",opponent.pbThis)) return true end end class PokeBattle_Move_03 < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0 hpgain=(opponent.damagestate.hplost/2).floor if opponent.ability==PBAbilities::LIQUIDOOZE attacker.pbReduceHP(hpgain) @battle.pbDisplay(_INTL("It sucked up the liquid ooze!")) else attacker.pbRecoverHP(hpgain) @battle.pbDisplay(_INTL("{1} had its energy drained!",opponent.pbThis)) end end return ret end end class PokeBattle_Move_04 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if !opponent.pbCanBurn?(false) return false end opponent.pbBurn(attacker) @battle.pbDisplay(_INTL("{1} was burned!",opponent.pbThis)) return true end end class PokeBattle_Move_05 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if opponent.pbCanFreeze?(false) opponent.pbFreeze @battle.pbDisplay(_INTL("{1} was frozen solid!",opponent.pbThis)) return true end return false end end class PokeBattle_Move_06 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if !opponent.pbCanParalyze?(false) return false end opponent.pbParalyze(attacker) @battle.pbDisplay(_INTL("{1} was paralyzed! It may be unable to move!",opponent.pbThis)) return true end end class PokeBattle_Move_07 < PokeBattle_Move def pbOnStartUse(attacker) bearer=@battle.pbCheckGlobalAbility(PBAbilities::DAMP) if bearer @battle.pbDisplay(_INTL("{1}'s Damp prevents {2} from using {3}!",bearer.pbThis,attacker.pbThis,@name)) return false else attacker.hp=0 @battle.pbAnimation(@id,attacker,nil) return true end end end class PokeBattle_Move_08 < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0 hpgain=(opponent.damagestate.hplost/2).floor attacker.pbRecoverHP(hpgain) @battle.pbDisplay(_INTL("{1}'s dream was eaten!",opponent.pbThis)) return ret end end end class PokeBattle_Move_09 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.effects[PBEffects::MirrorMove]<=0 @battle.pbDisplay(_INTL("The Mirror Move failed!")) return -1 end attacker.pbUseMoveSimple(attacker.effects[PBEffects::MirrorMove]) return 0 end end class PokeBattle_Move_0A < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbTooHigh?(PBStats::ATTACK) @battle.pbDisplay(_INTL("{1}'s Attack won't go higher!",attacker.pbThis)) return -1 else @battle.pbAnimation(@id,attacker,nil) attacker.stages[PBStats::ATTACK]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Attack rose!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_0B < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbTooHigh?(PBStats::DEFENSE) @battle.pbDisplay(_INTL("{1}'s Defense won't go higher!",attacker.pbThis)) return -1 else @battle.pbAnimation(@id,attacker,nil) attacker.stages[PBStats::DEFENSE]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Defense rose!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_0C < PokeBattle_Move # No moves with this function code end class PokeBattle_Move_0D < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbTooHigh?(PBStats::SPATK) @battle.pbDisplay(_INTL("{1}'s Special Attack won't go higher!",attacker.pbThis)) return -1 else @battle.pbAnimation(@id,attacker,nil) attacker.stages[PBStats::SPATK]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Special Attack rose!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_0E < PokeBattle_Move #No moves with this function code end class PokeBattle_Move_0F < PokeBattle_Move # No moves with this function code end class PokeBattle_Move_10 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbTooHigh?(PBStats::EVASION) @battle.pbDisplay(_INTL("{1}'s evasiveness won't go higher!",attacker.pbThis)) return -1 else @battle.pbAnimation(@id,attacker,nil) attacker.stages[PBStats::EVASION]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s evasiveness rose!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_11 < PokeBattle_Move def pbAccuracyCheck(attacker,opponent) return true end end class PokeBattle_Move_12 < PokeBattle_Move def pbEffect(attacker,opponent) return opponent.pbReduceStat(PBStats::ATTACK,1,true,@id,attacker) ? -1 : 0 end end class PokeBattle_Move_13 < PokeBattle_Move def pbEffect(attacker,opponent) return opponent.pbReduceStat(PBStats::DEFENSE,1,true,@id,attacker) ? -1 : 0 end end class PokeBattle_Move_14 < PokeBattle_Move def pbEffect(attacker,opponent) return opponent.pbReduceStat(PBStats::SPEED,1,true,@id,attacker) ? -1 : 0 end end class PokeBattle_Move_15 < PokeBattle_Move #No moves with this function code end class PokeBattle_Move_16 < PokeBattle_Move #No moves with this function code end class PokeBattle_Move_17 < PokeBattle_Move def pbEffect(attacker,opponent) return opponent.pbReduceStat(PBStats::ACCURACY,1,true,@id,attacker) ? -1 : 0 end end class PokeBattle_Move_18 < PokeBattle_Move def pbEffect(attacker,opponent) return opponent.pbReduceStat(PBStats::EVASION,1,true,@id,attacker) ? -1 : 0 end end class PokeBattle_Move_19 < PokeBattle_Move def pbEffect(attacker,opponent) for i in 0..3 @battle.battlers[i].stages[PBStats::ATTACK]=0 @battle.battlers[i].stages[PBStats::DEFENSE]=0 @battle.battlers[i].stages[PBStats::SPEED]=0 @battle.battlers[i].stages[PBStats::SPATK]=0 @battle.battlers[i].stages[PBStats::SPDEF]=0 @battle.battlers[i].stages[PBStats::ACCURACY]=0 @battle.battlers[i].stages[PBStats::EVASION]=0 end @battle.pbAnimation(@id,attacker,nil) @battle.pbDisplay(_INTL("All stat changes were eliminated!")) return 0 end end class PokeBattle_Move_1A < PokeBattle_Move def pbDisplayUseMessage(attacker) if attacker.effects[PBEffects::Bide]==0 @battle.pbDisplay(_INTL("{1} used\\r\\n{2}!",attacker.pbThis,name)) attacker.effects[PBEffects::Bide]=2+@battle.pbRandom(2) attacker.effects[PBEffects::BideDamage]=0 attacker.effects[PBEffects::BideTarget]=-1 attacker.currentMove=@id @battle.pbAnimation(@id,attacker,nil) return 1 else attacker.effects[PBEffects::Bide]-=1 if attacker.effects[PBEffects::Bide]==0 @battle.pbDisplay(_INTL("{1} unleashed energy!",attacker.pbThis)) return 0 else @battle.pbDisplay(_INTL("{1} is storing energy!",attacker.pbThis)) return 2 end end end def pbAddTarget(targets,attacker) if attacker.effects[PBEffects::BideTarget]>=0 if !attacker.pbAddTarget(targets, @battle.battlers[attacker.effects[PBEffects::BideTarget]]) attacker.pbRandomTarget(targets) end end end def pbEffect(attacker,opponent) if attacker.effects[PBEffects::BideDamage]==0 || !opponent @battle.pbDisplay(_INTL("But it failed!")) return -1 end ret=pbEffectFixedDamage(attacker.effects[PBEffects::BideDamage]*2,attacker,opponent) attacker.effects[PBEffects::BideDamage]=0 return ret end end class PokeBattle_Move_1B < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0 && attacker.effects[PBEffects::Outrage]==0 && attacker.status!=PBStatuses::SLEEP #TODO: Not likely what actually happens, but good enough attacker.effects[PBEffects::Outrage]=2+@battle.pbRandom(2) attacker.currentMove=@id elsif pbTypeModifier(@type,opponent)==0 # Cancel effect if attack is ineffective attacker.effects[PBEffects::Outrage]=0 end return ret end end class PokeBattle_Move_1C < PokeBattle_Move def pbEffect(attacker,opponent) if opponent.ability==PBAbilities::SUCTIONCUPS @battle.pbDisplay(_INTL("{1} anchors itself with Suction Cups!",opponent.pbThis)) return -1 end if opponent.effects[PBEffects::Ingrain] @battle.pbDisplay(_INTL("{1} anchored itself with its roots!",opponent.pbThis)) return -1 end if !@battle.opponent x=@battle.pbRandom(256) varA=((x*(attacker.level+opponent.level)/256).floor+1) varB=(opponent.level/4).floor if varA<=varB @battle.pbDisplay(_INTL("But it failed!")) return -1 end @battle.decision=3 # Set decision to escaped return 0 else choices=[] party=@battle.pbParty(opponent.index) for i in 0..party.length-1 choices[choices.length]=i if @battle.pbCanSwitchLax?(opponent.index,i,false) end if choices.length==0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end newpoke=choices[@battle.pbRandom(choices.length)] @battle.pbAnimation(@id,attacker,opponent) opponent.pbInitialize(party[newpoke],newpoke,false) if !@battle.pbOwnedByPlayer?(opponent.index) @battle.pbPlayer.seen[party[newpoke].species]=true @battle.scene.pbTrainerSendOut(opponent.index,party[newpoke]) else @battle.scene.pbSendOut(opponent.index,party[newpoke]) end @battle.pbDisplay(_INTL("{1} was dragged out!",opponent.pbThis)) @battle.pbOnActiveOne(opponent) return 0 end end end class PokeBattle_Move_1D < PokeBattle_Move def pbNumHits hits=[2,2,2,3,3,3,4,5] return hits[@battle.pbRandom(8)] end def pbIsMultiHit return true end end class PokeBattle_Move_1E < PokeBattle_Move def pbEffect(attacker,opponent) types=[] for i in attacker.moves next if attacker.pbHasType?(i.type) next if i.type==PBTypes::QMARKS found=false for j in types if i.type==j found=true break end end types[types.length]=i.type if !found end if types.length==0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end @battle.pbAnimation(@id,attacker,nil) thistype=types[@battle.pbRandom(types.length)] attacker.type1=thistype attacker.type2=thistype typename=PBTypes.getName(thistype) @battle.pbDisplay(_INTL("{1} transformed into the {2} type!",attacker.pbThis,typename)) end end class PokeBattle_Move_1F < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if opponent.ability!=PBAbilities::INNERFOCUS && opponent.effects[PBEffects::Substitute]==0 opponent.effects[PBEffects::Flinch]=true end end end class PokeBattle_Move_20 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.hp==attacker.totalhp @battle.pbDisplay(_INTL("{1}'s HP is full!",attacker.pbThis)) return -1 else @battle.pbAnimation(@id,attacker,nil) hpgain=(attacker.totalhp/2).floor attacker.pbRecoverHP(hpgain) @battle.pbDisplay(_INTL("{1} regained health!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_21 < PokeBattle_Move def pbEffect(attacker,opponent) if !opponent.pbCanPoison?(true) return 0 end @battle.pbAnimation(@id,attacker,opponent) opponent.pbPoison(attacker,true) @battle.pbDisplay(_INTL("{1} is badly poisoned!",opponent.pbThis)) return 0 end end class PokeBattle_Move_22 < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0 && !opponent.damagestate.substitute if @battle.pbOwnedByPlayer?(attacker.index) @battle.moneygained+=5*attacker.level @battle.moneygained=999999 if @battle.moneygained>999999 end @battle.pbDisplay(_INTL("Coins scattered everywhere!")) end return ret end end class PokeBattle_Move_23 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbOwnSide.effects[PBEffects::LightScreen]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 else attacker.pbOwnSide.effects[PBEffects::LightScreen]=5 @battle.pbAnimation(@id,attacker,nil,true) if !@battle.pbIsOpposing?(attacker.index) @battle.pbDisplay(_INTL("Ally's Light Screen raised Special Defense!")) else @battle.pbDisplay(_INTL("Foe's Light Screen raised Special Defense!")) end end end end class PokeBattle_Move_24 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) rnd=@battle.pbRandom(3) case rnd when 0 return false if !opponent.pbCanBurn?(false) opponent.pbBurn(attacker) @battle.pbDisplay(_INTL("{1} was burned!",opponent.pbThis)) when 1 return false if !opponent.pbCanFreeze?(false) opponent.pbFreeze @battle.pbDisplay(_INTL("{1} was frozen solid!",opponent.pbThis)) when 2 return false if !opponent.pbCanParalyze?(false) opponent.pbParalyze(attacker) @battle.pbDisplay(_INTL("{1} is paralyzed! It may be unable to move!",opponent.pbThis)) end return true end end class PokeBattle_Move_25 < PokeBattle_Move def pbEffect(attacker,opponent) return -1 if !attacker.pbCanSleep?(true,true) if attacker.hp==attacker.totalhp @battle.pbDisplay(_INTL("{1}'s HP is full!",attacker.pbThis)) return -1 end if attacker.status>0 @battle.pbDisplay(_INTL("{1} slept and became healthy!",attacker.pbThis)) else @battle.pbDisplay(_INTL("{1} went to sleep!",attacker.pbThis)) end attacker.pbSleep(3) attacker.pbRecoverHP(attacker.totalhp-attacker.hp) @battle.pbDisplay(_INTL("{1} regained health!",attacker.pbThis)) return 0 end end class PokeBattle_Move_26 < PokeBattle_Move def pbEffect(attacker,opponent) damage=pbEffectFixedDamage(opponent.hp,attacker,opponent) if opponent.hp<=0 @battle.pbDisplay(_INTL("It's a one-hit KO!")) end return damage end def pbAccuracyCheck(attacker,opponent) accuracy=@accuracy if opponent.ability==PBAbilities::STURDY @battle.pbDisplay(_INTL("{1} was protected by Sturdy!",opponent.pbThis)) return false end if opponent.level > attacker.level @battle.pbDisplay(_INTL("{1} is unaffected!",opponent.pbThis)) return false end accuracy=accuracy+attacker.level-opponent.level accuracy=100 if accuracy>100 return 1+@battle.pbRandom(100)<accuracy end end class PokeBattle_Move_27 < PokeBattle_Move def pbTwoTurnAttack(attacker) @razorWindStart=true return attacker.effects[PBEffects::TwoTurnAttack]==0 end def pbEffect(attacker,opponent) if attacker.effects[PBEffects::TwoTurnAttack]>0 if @razorWindStart @battle.pbAnimation(@id,attacker,nil) @battle.pbDisplay(_INTL("{1} whipped up a whirlwind!",attacker.pbThis)) @razorWindStart=false end return 0 else return super end end end class PokeBattle_Move_28 < PokeBattle_Move def pbEffect(attacker,opponent) return pbEffectFixedDamage((opponent.hp/2).floor,attacker,opponent) end end class PokeBattle_Move_29 < PokeBattle_Move def pbEffect(attacker,opponent) return pbEffectFixedDamage(40,attacker,opponent) end end class PokeBattle_Move_2A < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0 && !opponent.damagestate.substitute && opponent.hp>0 if opponent.effects[PBEffects::MultiTurn]==0 opponent.effects[PBEffects::MultiTurn]=3+@battle.pbRandom(4) opponent.effects[PBEffects::MultiTurnUser]=attacker.index opponent.effects[PBEffects::MultiTurnAttack]=@id case @id when PBMoves::BIND @battle.pbDisplay(_INTL("{1} was squeezed by {2}'s Bind!",opponent.pbThis,attacker.pbThis)) when PBMoves::WHIRLPOOL @battle.pbDisplay(_INTL("{1} was trapped in the vortex!",opponent.pbThis)) when PBMoves::FIRESPIN @battle.pbDisplay(_INTL("{1} was trapped in the vortex!",opponent.pbThis)) when PBMoves::SANDTOMB @battle.pbDisplay(_INTL("{1} was trapped by Sand Tomb!",opponent.pbThis)) when PBMoves::WRAP @battle.pbDisplay(_INTL("{1} was wrapped by {2}!",opponent.pbThis,attacker.pbThis)) when PBMoves::CLAMP @battle.pbDisplay(_INTL("{1} clamped {2}!",attacker.pbThis,opponent.pbThis)) else @battle.pbDisplay(_INTL("{1} was trapped in the vortex!",opponent.pbThis)) end end end return ret end def pbBaseDamage(basedmg,attacker,opponent) if @id==PBMoves::WHIRLPOOL&& opponent.effects[PBEffects::TwoTurnAttack]==PBMoves::DIVE return basedmg*2 end return basedmg end end class PokeBattle_Move_2B < PokeBattle_Move # Intentionally blank, handled by superclass end class PokeBattle_Move_2C < PokeBattle_Move def pbIsMultiHit return true end def pbNumHits return 2 end end class PokeBattle_Move_2D < PokeBattle_Move # Intentionally blank, handled in Battler class end class PokeBattle_Move_2E < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbOwnSide.effects[PBEffects::Mist]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end attacker.pbOwnSide.effects[PBEffects::Mist]=5 @battle.pbAnimation(@id,attacker,nil,true) if !@battle.pbIsOpposing?(attacker.index) @battle.pbDisplay(_INTL("Ally became shrouded in Mist!")) else @battle.pbDisplay(_INTL("Foe became shrouded in Mist!")) end return 0 end end class PokeBattle_Move_2F < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.effects[PBEffects::FocusEnergy] @battle.pbDisplay(_INTL("But it failed!")) return -1 else attacker.effects[PBEffects::FocusEnergy]=true @battle.pbAnimation(@id,attacker,nil,true) @battle.pbDisplay(_INTL("{1} is getting pumped!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_30 < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0 if attacker.ability!=PBAbilities::ROCKHEAD || @id==PBMoves::STRUGGLE attacker.pbReduceHP((opponent.damagestate.hplost/4).floor) @battle.pbDisplay(_INTL("{1} is hit with recoil!",attacker.pbThis)) end end return ret end def pbCalcDamage(attacker,opponent) if @id==PBMoves::STRUGGLE return super(attacker,opponent,PokeBattle_Move::IGNOREPKMNTYPES) else return super end end end class PokeBattle_Move_31 < PokeBattle_Move def pbEffect(attacker,opponent) if opponent.pbCanConfuse?(true) @battle.pbAnimation(@id,attacker,opponent) opponent.effects[PBEffects::Confusion]=2+@battle.pbRandom(4) @battle.pbDisplay(_INTL("{1} became confused!",opponent.pbThis)) return 0 end return -1 end end class PokeBattle_Move_32 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbTooHigh?(PBStats::ATTACK) @battle.pbDisplay(_INTL("{1}'s Attack won't go higher!",attacker.pbThis)) return -1 else attacker.stages[PBStats::ATTACK]+=2 attacker.stages[PBStats::ATTACK]=6 if attacker.stages[PBStats::ATTACK]>6 @battle.pbAnimation(@id,attacker,nil) @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Attack sharply rose!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_33 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbTooHigh?(PBStats::DEFENSE) @battle.pbDisplay(_INTL("{1}'s Defense won't go higher!",attacker.pbThis)) return -1 else attacker.stages[PBStats::DEFENSE]+=2 attacker.stages[PBStats::DEFENSE]=6 if attacker.stages[PBStats::DEFENSE]>6 @battle.pbAnimation(@id,attacker,nil) @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Defense sharply rose!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_34 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbTooHigh?(PBStats::SPEED) @battle.pbDisplay(_INTL("{1}'s Speed won't go higher!",attacker.pbThis)) return -1 else attacker.stages[PBStats::SPEED]+=2 attacker.stages[PBStats::SPEED]=6 if attacker.stages[PBStats::SPEED]>6 @battle.pbAnimation(@id,attacker,nil) @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Speed sharply rose!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_35 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbTooHigh?(PBStats::SPATK) @battle.pbDisplay(_INTL("{1}'s Special Attack won't go higher!",attacker.pbThis)) return -1 else attacker.stages[PBStats::SPATK]+=2 attacker.stages[PBStats::SPATK]=6 if attacker.stages[PBStats::SPATK]>6 @battle.pbAnimation(@id,attacker,nil) @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Special Attack sharply rose!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_36 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbTooHigh?(PBStats::SPDEF) @battle.pbDisplay(_INTL("{1}'s Special Defense won't go higher!",attacker.pbThis)) return -1 else attacker.stages[PBStats::SPDEF]+=2 attacker.stages[PBStats::SPDEF]=6 if attacker.stages[PBStats::SPDEF]>6 @battle.pbAnimation(@id,attacker,nil) @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Special Defense sharply rose!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_37 < PokeBattle_Move # No moves with this function code end class PokeBattle_Move_38 < PokeBattle_Move # No moves with this function code end class PokeBattle_Move_39 < PokeBattle_Move def pbEffect(attacker,opponent) if opponent.effects[PBEffects::Transform]|| opponent.effects[PBEffects::TwoTurnAttack]==PBMoves::FLY|| opponent.effects[PBEffects::TwoTurnAttack]==PBMoves::DIG|| opponent.effects[PBEffects::TwoTurnAttack]==PBMoves::DIVE|| opponent.effects[PBEffects::TwoTurnAttack]==PBMoves::BOUNCE @battle.pbDisplay(_INTL("But it failed!")) return -1 else attacker.effects[PBEffects::Transform]=true @battle.pbAnimation(@id,attacker,opponent) oldpbthis=attacker.pbThis attacker.species=opponent.species attacker.attack=opponent.attack attacker.defense=opponent.defense attacker.speed=opponent.speed attacker.spatk=opponent.spatk attacker.spdef=opponent.spdef attacker.type1=opponent.type1 attacker.type2=opponent.type2 attacker.ability=opponent.ability for i in 0..6 attacker.stages[i]=opponent.stages[i] end for i in 0..5 attacker.iv[i]=opponent.iv[i] end for i in 0..3 attacker.moves[i]=PokeBattle_Move.pbFromPBMove( @battle,PBMove.new(opponent.moves[i].id)) attacker.moves[i].pp=5 end speciesname=PBSpecies.getName(opponent.species) @battle.pbDisplay(_INTL("{1} transformed into {2}!",oldpbthis,speciesname)) return 0 end end end class PokeBattle_Move_3A < PokeBattle_Move def pbEffect(attacker,opponent) return opponent.pbReduceStat(PBStats::ATTACK,2,true,@id,attacker) ? -1 : 0 end end class PokeBattle_Move_3B < PokeBattle_Move def pbEffect(attacker,opponent) return opponent.pbReduceStat(PBStats::DEFENSE,2,true,@id,attacker) ? -1 : 0 end end class PokeBattle_Move_3C < PokeBattle_Move def pbEffect(attacker,opponent) return opponent.pbReduceStat(PBStats::SPEED,2,true,@id,attacker) ? -1 : 0 end end class PokeBattle_Move_3D < PokeBattle_Move #No moves with this function code end class PokeBattle_Move_3E < PokeBattle_Move def pbEffect(attacker,opponent) return opponent.pbReduceStat(PBStats::SPDEF,2,true,@id,attacker) ? -1 : 0 end end class PokeBattle_Move_3F < PokeBattle_Move #No moves with this function code end class PokeBattle_Move_40 < PokeBattle_Move #No moves with this function code end class PokeBattle_Move_41 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbOwnSide.effects[PBEffects::Reflect]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 else attacker.pbOwnSide.effects[PBEffects::Reflect]=5 @battle.pbAnimation(@id,attacker,nil,true) if !@battle.pbIsOpposing?(attacker.index) @battle.pbDisplay(_INTL("Ally's Reflect raised Defense!")) else @battle.pbDisplay(_INTL("Foe's Reflect raised Defense!")) end end end end class PokeBattle_Move_42 < PokeBattle_Move def pbEffect(attacker,opponent) if !opponent.pbCanPoison?(true) return 0 end @battle.pbAnimation(@id,attacker,opponent) opponent.pbPoison(attacker) @battle.pbDisplay(_INTL("{1} was poisoned!",opponent.pbThis)) return 0 end end class PokeBattle_Move_43 < PokeBattle_Move def pbEffect(attacker,opponent) typemod=pbTypeModifier(@type,opponent) if typemod==0 @battle.pbDisplay(_INTL("It doesn't affect {1}...",opponent.pbThis)) return -1 end if !opponent.pbCanParalyze?(true) return -1 end @battle.pbAnimation(@id,attacker,opponent) opponent.pbParalyze(attacker) @battle.pbDisplay(_INTL("{1} is paralyzed! It may be unable to move!",opponent.pbThis)) return 0 end end class PokeBattle_Move_44 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) return opponent.pbReduceStat(PBStats::ATTACK,1,false) end end class PokeBattle_Move_45 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) return opponent.pbReduceStat(PBStats::DEFENSE,1,false) end end class PokeBattle_Move_46 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) return opponent.pbReduceStat(PBStats::SPEED,1,false) end end class PokeBattle_Move_47 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) return opponent.pbReduceStat(PBStats::SPATK,1,false) end end class PokeBattle_Move_48 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) return opponent.pbReduceStat(PBStats::SPDEF,1,false) end end class PokeBattle_Move_49 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) return opponent.pbReduceStat(PBStats::ACCURACY,1,false) end end class PokeBattle_Move_4A < PokeBattle_Move #No moves with this function code end class PokeBattle_Move_4B < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if opponent.ability!=PBAbilities::INNERFOCUS && opponent.effects[PBEffects::Substitute]==0 opponent.effects[PBEffects::Flinch]=true end end def pbTwoTurnAttack(attacker) return attacker.effects[PBEffects::TwoTurnAttack]==0 end def pbEffect(attacker,opponent) if attacker.effects[PBEffects::TwoTurnAttack]>0 @battle.pbAnimation(@id,attacker,nil) @battle.pbDisplay(_INTL("{1} is glowing!",attacker.pbThis)) return 0 end return super end end class PokeBattle_Move_4C < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if opponent.pbCanConfuse?(true) opponent.effects[PBEffects::Confusion]=2+@battle.pbRandom(4) @battle.pbCommonAnimation("Confusion",attacker,opponent) @battle.pbDisplay(_INTL("{1} became confused!",opponent.pbThis)) return true end return false end end class PokeBattle_Move_4D < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if !opponent.pbCanPoison?(false) return false end opponent.pbPoison(attacker) @battle.pbDisplay(_INTL("{1} was poisoned!",opponent.pbThis)) return true end def pbIsMultiHit return true end def pbNumHits return 2 end end class PokeBattle_Move_4E < PokeBattle_Move def pbAccuracyCheck(attacker,opponent) return true end end class PokeBattle_Move_4F < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("{1} already has a Substitute!",attacker.pbThis)) return -1 end sublife=(attacker.totalhp/4).floor if sublife==0||attacker.hp<=sublife @battle.pbDisplay(_INTL("It was too weak to make a Substitute!")) return -1 end @battle.pbAnimation(@id,attacker,nil) attacker.pbReduceHP(sublife) attacker.effects[PBEffects::MultiTurn]=0 attacker.effects[PBEffects::MultiTurnAttack]=0 attacker.effects[PBEffects::Substitute]=sublife @battle.pbDisplay(_INTL("{1} made a Substitute!",attacker.pbThis)) return 0 end end class PokeBattle_Move_50 < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0 attacker.effects[PBEffects::HyperBeam]=2 attacker.currentMove=@id end return ret end end class PokeBattle_Move_51 < PokeBattle_Move #Handled in Battler class end class PokeBattle_Move_52 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.effects[PBEffects::Transform] || opponent.effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end if opponent.lastMoveUsed<=0|| opponent.lastMoveUsed==PBMoves::METRONOME|| opponent.lastMoveUsed==PBMoves::MIMIC|| opponent.lastMoveUsed==PBMoves::STRUGGLE|| opponent.lastMoveUsed==PBMoves::SKETCH @battle.pbDisplay(_INTL("But it failed!")) return -1 end for i in attacker.moves if i.id==opponent.lastMoveUsed @battle.pbDisplay(_INTL("But it failed!")) return -1 end end #TODO: May be unsatisfactory (Sleep Talk/Mimic, etc.), #Mimic's position is considered @battle.pbAnimation(@id,attacker,opponent) for i in 0..attacker.moves.length-1 if attacker.moves[i].id==@id attacker.moves[i]=PokeBattle_Move.pbFromPBMove( @battle,PBMove.new(opponent.lastMoveUsed)) attacker.moves[i].pp=5 movename=PBMoves.getName(opponent.lastMoveUsed) @battle.pbDisplay(_INTL("{1} learned {2}!",attacker.pbThis,movename)) return 0 end end @battle.pbDisplay(_INTL("But it failed!")) return -1 end end class PokeBattle_Move_53 < PokeBattle_Move def pbEffect(attacker,opponent) blacklist=[ PBMoves::METRONOME, PBMoves::STRUGGLE, PBMoves::SKETCH, PBMoves::MIMIC, PBMoves::COUNTER, PBMoves::MIRRORCOAT, PBMoves::PROTECT, PBMoves::DETECT, PBMoves::ENDURE, PBMoves::DESTINYBOND, PBMoves::SLEEPTALK, PBMoves::THIEF, PBMoves::FOLLOWME, PBMoves::SNATCH, PBMoves::HELPINGHAND, PBMoves::COVET, PBMoves::TRICK, PBMoves::FOCUSPUNCH ] loop do move=@battle.pbRandom(354)+1 found=false for i in blacklist if move==i found=true break end end if !found attacker.pbUseMoveSimple(move) break end end return 0 end end class PokeBattle_Move_54 < PokeBattle_Move def pbEffect(attacker,opponent) if opponent.effects[PBEffects::LeechSeed]>=0 || opponent.effects[PBEffects::Substitute]>0 # TODO: Same message upon Protect or miss @battle.pbDisplay(_INTL("{1} evaded the attack!",opponent.pbThis)) return -1 end if opponent.pbHasType?(PBTypes::GRASS) @battle.pbDisplay(_INTL("It doesn't affect {1}...",opponent.pbThis)) return -1 end @battle.pbAnimation(@id,attacker,opponent) opponent.effects[PBEffects::LeechSeed]=attacker.index @battle.pbDisplay(_INTL("{1} was seeded!",opponent.pbThis)) return 0 end end class PokeBattle_Move_55 < PokeBattle_Move def pbEffect(attacker,opponent) @battle.pbAnimation(@id,attacker,nil) @battle.pbDisplay(_INTL("But nothing happened!")) return 0 end end class PokeBattle_Move_56 < PokeBattle_Move def pbEffect(attacker,opponent) if opponent.effects[PBEffects::Disable]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end for i in opponent.moves if i.id==opponent.lastMoveUsed && i.id>0 && i.pp>0 @battle.pbAnimation(@id,attacker,opponent) opponent.effects[PBEffects::Disable]=2+@battle.pbRandom(4) opponent.effects[PBEffects::DisableMove]=opponent.lastMoveUsed @battle.pbDisplay(_INTL("{1}'s {2} was disabled!",opponent.pbThis,i.name)) return 0 end end @battle.pbDisplay(_INTL("But it failed!")) return -1 end end class PokeBattle_Move_57 < PokeBattle_Move def pbEffect(attacker,opponent) return pbEffectFixedDamage(attacker.level,attacker,opponent) end end class PokeBattle_Move_58 < PokeBattle_Move def pbEffect(attacker,opponent) rnd=@battle.pbRandom(11) dmg=((attacker.level)*(rnd*10+50)/100).floor return pbEffectFixedDamage(dmg,attacker,opponent) end end class PokeBattle_Move_59 < PokeBattle_Move def pbAddTarget(targets,attacker) if attacker.effects[PBEffects::CounterTarget]>=0 && attacker.pbIsOpposing?(attacker.effects[PBEffects::CounterTarget]) if !attacker.pbAddTarget(targets, @battle.battlers[attacker.effects[PBEffects::CounterTarget]]) attacker.pbRandomTarget(targets) end end end def pbEffect(attacker,opponent) if attacker.effects[PBEffects::Counter]==0||!opponent @battle.pbDisplay(_INTL("But it failed!")) return -1 end ret=pbEffectFixedDamage(attacker.effects[PBEffects::Counter]*2,attacker,opponent) return ret end end class PokeBattle_Move_5A < PokeBattle_Move def pbEffect(attacker,opponent) if opponent.effects[PBEffects::Encore]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end if opponent.lastMoveUsed<=0|| opponent.lastMoveUsed==PBMoves::STRUGGLE|| opponent.lastMoveUsed==PBMoves::ENCORE|| opponent.lastMoveUsed==PBMoves::MIRRORMOVE @battle.pbDisplay(_INTL("But it failed!")) return -1 end for i in 0..3 if opponent.lastMoveUsed==opponent.moves[i].id && opponent.moves[i].pp>0 opponent.effects[PBEffects::Encore]=3+@battle.pbRandom(4) opponent.effects[PBEffects::EncoreIndex]=i opponent.effects[PBEffects::EncoreMove]=opponent.moves[i].id # PBDebug.log(sprintf("lastMoveUsed=[%02X], lastMoveCalled=[%02X]", # opponent.lastMoveUsed,opponent.lastMoveCalled)) @battle.pbAnimation(@id,attacker,opponent) @battle.pbDisplay(_INTL("{1} got an encore!",opponent.pbThis)) return 0 end end @battle.pbDisplay(_INTL("But it failed!")) return -1 end end class PokeBattle_Move_5B < PokeBattle_Move def pbEffect(attacker,opponent) if opponent.effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end oldahp=attacker.hp oldohp=opponent.hp avghp=((opponent.hp+attacker.hp)/2).floor attackerhp=avghp opponenthp=avghp attackerhp=attacker.totalhp if attackerhp>attacker.totalhp opponenthp=opponent.totalhp if opponenthp>opponent.totalhp attacker.hp=attackerhp opponent.hp=opponenthp @battle.pbAnimation(@id,attacker,opponent) @battle.scene.pbHPChanged(attacker,oldahp) @battle.scene.pbHPChanged(opponent,oldohp) @battle.pbDisplay(_INTL("The battlers shared their pain!")) return 0 end end class PokeBattle_Move_5C < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if opponent.ability!=PBAbilities::INNERFOCUS && opponent.effects[PBEffects::Substitute]==0 opponent.effects[PBEffects::Flinch]=true end end def pbMoveFailed(attacker,opponent) return (attacker.status!=PBStatuses::SLEEP) end end class PokeBattle_Move_5D < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.effects[PBEffects::Conversion2Move]<=0|| attacker.effects[PBEffects::Conversion2Type]==9|| attacker.effects[PBEffects::Conversion2Type]<0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end types=[] atype=attacker.effects[PBEffects::Conversion2Type] atype-=1 if atype>=10 atype*=17 for i in 0...17 next if i==9 # type _INTL("???") otype=i otype=i-1 if otype>=10 types[types.length]=i if PBTypes::PBTypeChart[atype+otype]<2 end ctype=types[@battle.pbRandom(types.length)] attacker.type1=ctype attacker.type2=ctype @battle.pbAnimation(@id,attacker,nil) typename=PBTypes.getName(ctype) @battle.pbDisplay(_INTL("{1} transformed into the {2} type!",attacker.pbThis,typename)) return 0 end end class PokeBattle_Move_5E < PokeBattle_Move def pbEffect(attacker,opponent) opponent.effects[PBEffects::LockOn]=2 opponent.effects[PBEffects::LockOnPos]=attacker.index @battle.pbAnimation(@id,attacker,opponent) @battle.pbDisplay(_INTL("{1} took aim at {2}!",attacker.pbThis,opponent.pbThis)) return 0 end end class PokeBattle_Move_5F < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.effects[PBEffects::Transform] || opponent.effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end if opponent.lastMoveUsedSketch<=0|| opponent.lastMoveUsedSketch==PBMoves::STRUGGLE|| opponent.lastMoveUsedSketch==PBMoves::SKETCH @battle.pbDisplay(_INTL("But it failed!")) return -1 end for i in attacker.moves if i.id==opponent.lastMoveUsedSketch @battle.pbDisplay(_INTL("But it failed!")) return -1 end end #TODO: May be unsatisfactory (Sleep Talk/Sketch, etc.), #Sketch's position is considered for i in 0..attacker.moves.length-1 if attacker.moves[i].id==@id newmove=PBMove.new(opponent.lastMoveUsedSketch) attacker.moves[i]=PokeBattle_Move.pbFromPBMove( @battle,newmove) party=@battle.pbParty(attacker.index) party[attacker.pokemonIndex].moves[i]=newmove movename=PBMoves.getName(opponent.lastMoveUsedSketch) @battle.pbAnimation(@id,attacker,opponent) @battle.pbDisplay(_INTL("{1} Sketched {2}!",attacker.pbThis,movename)) return 0 end end @battle.pbDisplay(_INTL("But it failed!")) return -1 end end class PokeBattle_Move_60 < PokeBattle_Move # No moves with this function code end class PokeBattle_Move_61 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.status!=PBStatuses::SLEEP @battle.pbDisplay(_INTL("But it failed!")) return -1 end blacklist=[ 0, PBMoves::BIDE, PBMoves::SLEEPTALK, PBMoves::ASSIST, PBMoves::MIRRORMOVE, PBMoves::METRONOME, PBMoves::FOCUSPUNCH, PBMoves::UPROAR, # Two-turn attacks PBMoves::RAZORWIND, PBMoves::SKYATTACK, PBMoves::SKULLBASH, PBMoves::SOLARBEAM, PBMoves::DIG, PBMoves::FLY, PBMoves::DIVE, PBMoves::BOUNCE ] choices=[] for i in 0..3 found=false for j in 0...blacklist.length found=true if blacklist[i]==attacker.moves[i].id end next if found choices[choices.length]=i if @battle.pbCanChooseMove?(attacker.index,i,false) end if choices.length==0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end @battle.pbAnimation(@id,attacker,nil) choice=choices[@battle.pbRandom(choices.length)] attacker.pbUseMoveSimple(attacker.moves[choice].id,choice) return 0 end end class PokeBattle_Move_62 < PokeBattle_Move def pbEffect(attacker,opponent) attacker.effects[PBEffects::DestinyBond]=true @battle.pbAnimation(@id,attacker,nil,true) @battle.pbDisplay(_INTL("{1} is trying to take its foe with it!",attacker.pbThis)) return 0 end end class PokeBattle_Move_63 < PokeBattle_Move def pbBaseDamage(basedmg,attacker,opponent) n=(attacker.hp*48/attacker.totalhp).floor basedmg=20 basedmg=40 if n<33 basedmg=80 if n<17 basedmg=100 if n<10 basedmg=150 if n<5 basedmg=200 if n<2 return basedmg end end class PokeBattle_Move_64 < PokeBattle_Move def pbEffect(attacker,opponent) for i in opponent.moves if i.id==opponent.lastMoveUsed && i.id>0 && i.pp>1 reduction=2+@battle.pbRandom(4) reduction=i.pp if reduction>i.pp i.pp-=reduction @battle.pbAnimation(@id,attacker,opponent) @battle.pbDisplay(_INTL("Reduced {1}'s {2} by {3}!",opponent.pbThis,i.name,reduction)) return 0 end end @battle.pbDisplay(_INTL("But it failed!")) return -1 end end class PokeBattle_Move_65 < PokeBattle_Move #Intentionally blank, handled in superclass end class PokeBattle_Move_66 < PokeBattle_Move def pbEffect(attacker,opponent) @battle.pbAnimation(@id,attacker,nil) if @id==PBMoves::AROMATHERAPY @battle.pbDisplay(_INTL("A soothing aroma wafted through the area!")) else @battle.pbDisplay(_INTL("A bell chimed!")) end activepkmn=[] for i in @battle.battlers next if attacker.pbIsOpposing?(i.index) activepkmn[activepkmn.length]=i.pokemonIndex if @id==PBMoves::HEALBELL @battle.pbDisplay(_INTL("{1}'s {2} blocks {3}!",i.pbThis,PBAbilities.getName(i.ability),name)) else i.status=0 end end party=@battle.pbParty(attacker.index) # NOTE: Considers both parties in multi battles for i in 0...party.length found=false for j in activepkmn if j==i found=true break end end next if found next if !party[i] || party[i].egg? if @id!=PBMoves::HEALBELL || party[i].ability!=PBAbilities::SOUNDPROOF party[i].status=0 party[i].statusCount=0 end end end end class PokeBattle_Move_67 < PokeBattle_Move #Intentionally blank, handled in superclass end class PokeBattle_Move_68 < PokeBattle_Move def pbOnStartUse(attacker) @calcbasedmg=@basedamage return true end def pbBaseDamage(basedmg,attacker,opponent) damage=@calcbasedmg @calcbasedmg+=basedmg return damage end def pbNumHits return 3 end def pbIsMultiHit return true end end class PokeBattle_Move_69 < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0&& !opponent.damagestate.substitute && opponent.item!=0 if opponent.ability==PBAbilities::STICKYHOLD abilityname=PBAbilities.getName(opponent.ability) @battle.pbDisplay(_INTL("{1}'s {2} made {3} ineffective!",opponent.pbThis,abilityname,@name)) elsif attacker.item==0 itemname=PBItems.getName(opponent.item) attacker.item=opponent.item opponent.item=0 @battle.pbDisplay(_INTL("{1} stole {2}'s {3}!",attacker.pbThis,opponent.pbThis,itemname)) end end return ret end end class PokeBattle_Move_6A < PokeBattle_Move def pbEffect(attacker,opponent) if opponent.effects[PBEffects::MeanLook]>=0 || opponent.effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 else opponent.effects[PBEffects::MeanLook]=attacker.index @battle.pbAnimation(@id,attacker,opponent) @battle.pbDisplay(_INTL("{1} can't escape now!",opponent.pbThis)) return 0 end end end class PokeBattle_Move_6B < PokeBattle_Move def pbEffect(attacker,opponent) if opponent.status!=PBStatuses::SLEEP || opponent.effects[PBEffects::Nightmare] || opponent.effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end @battle.pbAnimation(@id,attacker,opponent) opponent.effects[PBEffects::Nightmare]=true @battle.pbDisplay(_INTL("{1} fell into a nightmare!",opponent.pbThis)) return 0 end end class PokeBattle_Move_6C < PokeBattle_Move def pbEffect(attacker,opponent) attacker.effects[PBEffects::Minimize]=true if attacker.pbTooHigh?(PBStats::EVASION) @battle.pbDisplay(_INTL("{1}'s evasiveness won't go higher!",attacker.pbThis)) return -1 else attacker.stages[PBStats::EVASION]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s evasiveness rose!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_6D < PokeBattle_Move def pbEffect(attacker,opponent) failed=false if !attacker.pbHasType?(PBTypes::GHOST) lowerspeed=!attacker.pbTooLow?(PBStats::SPEED) raiseatk=!attacker.pbTooHigh?(PBStats::ATTACK) raisedef=!attacker.pbTooHigh?(PBStats::DEFENSE) if !lowerspeed&&!raiseatk&&!raisedef failed=true else @battle.pbAnimation(@id,attacker,nil) if lowerspeed attacker.stages[PBStats::SPEED]-=1 @battle.pbCommonAnimation("StatDown",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Speed fell!",attacker.pbThis)) else @battle.pbDisplay(_INTL("{1}'s Speed won't go lower!",attacker.pbThis)) end if raiseatk attacker.stages[PBStats::ATTACK]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Attack rose!",attacker.pbThis)) else @battle.pbDisplay(_INTL("{1}'s Attack won't go higher!",attacker.pbThis)) end if raisedef attacker.stages[PBStats::DEFENSE]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Defense rose!",attacker.pbThis)) else @battle.pbDisplay(_INTL("{1}'s Defense won't go higher!",attacker.pbThis)) end end else if opponent.effects[PBEffects::Curse] || opponent.effects[PBEffects::Substitute]>0 failed=true else @battle.pbAnimation(@id,attacker,opponent) attacker.pbReduceHP((attacker.totalhp/2).floor) opponent.effects[PBEffects::Curse]=true @battle.pbDisplay(_INTL("{1} cut its own HP and laid a curse on {2}!",attacker.pbThis,opponent.pbThis)) end end if failed @battle.pbDisplay(_INTL("But it failed!")) end return failed ? -1 : 0 end end class PokeBattle_Move_6E < PokeBattle_Move # No moves with this function code end class PokeBattle_Move_6F < PokeBattle_Move def pbEffect(attacker,opponent) successrates=[65535,32767,16383,8191] if attacker.lastMoveCalled!=PBMoves::PROTECT&& attacker.lastMoveCalled!=PBMoves::DETECT&& attacker.lastMoveCalled!=PBMoves::ENDURE attacker.effects[PBEffects::ProtectRate]=0 end #TODO: Fails if attack strikes last if attacker.effects[PBEffects::ProtectRate]<4 && @battle.pbRandom(65536)<=successrates[attacker.effects[PBEffects::ProtectRate]] attacker.effects[PBEffects::Protect]=true attacker.effects[PBEffects::ProtectRate]+=1 @battle.pbAnimation(@id,attacker,nil) @battle.pbDisplay(_INTL("{1} protected itself!",attacker.pbThis)) return 0 else attacker.effects[PBEffects::ProtectRate]=0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end end end class PokeBattle_Move_70 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbOpposingSide.effects[PBEffects::Spikes]>=3 @battle.pbDisplay(_INTL("But it failed!")) return -1 else @battle.pbAnimation(@id,attacker,nil,true) attacker.pbOpposingSide.effects[PBEffects::Spikes]+=1 @battle.pbDisplay(_INTL("Spikes were scattered all around the opponent's side!")) return 0 end end end class PokeBattle_Move_71 < PokeBattle_Move def pbEffect(attacker,opponent) opponent.effects[PBEffects::Foresight]=true @battle.pbAnimation(@id,attacker,opponent) @battle.pbDisplay(_INTL("{1} identified {2}!",attacker.pbThis,opponent.pbThis)) return 0 end end class PokeBattle_Move_72 < PokeBattle_Move def pbEffect(attacker,opponent) failed=true for i in 0..3 if @battle.battlers[i].effects[PBEffects::PerishSong]==0 && @battle.battlers[i].ability!=PBAbilities::SOUNDPROOF failed=false end end if failed @battle.pbDisplay(_INTL("But it failed!")) return -1 end @battle.pbAnimation(@id,nil,nil) @battle.pbDisplay(_INTL("All affected Pokémon will faint in three turns!")) for i in 0..3 if @battle.battlers[i].effects[PBEffects::PerishSong]==0 if @battle.battlers[i].ability==PBAbilities::SOUNDPROOF @battle.pbDisplay(_INTL("{1}'s Soundproof blocks {2}!",@battle.battlers[i].pbThis,name)) else @battle.battlers[i].effects[PBEffects::PerishSong]=4 end end end return 0 end end class PokeBattle_Move_73 < PokeBattle_Move def pbEffect(attacker,opponent) if @battle.weather==PBWeather::SANDSTORM @battle.pbDisplay(_INTL("But it failed!")) return -1 else @battle.weather=PBWeather::SANDSTORM @battle.weatherduration=5 @battle.pbDisplay(_INTL("A sandstorm brewed!")) return 0 end end end class PokeBattle_Move_74 < PokeBattle_Move def pbEffect(attacker,opponent) #TODO: Fails if attack strikes last successrates=[65535,32767,16383,8191] if attacker.lastMoveCalled!=PBMoves::PROTECT&& attacker.lastMoveCalled!=PBMoves::DETECT&& attacker.lastMoveCalled!=PBMoves::ENDURE attacker.effects[PBEffects::ProtectRate]=0 end if attacker.effects[PBEffects::ProtectRate]<4 && @battle.pbRandom(65536)<=successrates[attacker.effects[PBEffects::ProtectRate]] attacker.effects[PBEffects::Endure]=true attacker.effects[PBEffects::ProtectRate]+=1 @battle.pbAnimation(@id,attacker,nil) @battle.pbDisplay(_INTL("{1} braced itself!",attacker.pbThis)) return 0 else attacker.effects[PBEffects::ProtectRate]=0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end end end class PokeBattle_Move_75 < PokeBattle_Move def pbBaseDamage(basedmg,attacker,opponent) shift=(4-attacker.effects[PBEffects::Rollout]) # from 0 through 4, 0 is most powerful shift+=1 if attacker.effects[PBEffects::DefenseCurl] basedmg<<=shift return basedmg end end class PokeBattle_Move_76 < PokeBattle_Move def pbEffect(attacker,opponent) ret=-1 if opponent.effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("{1}'s attack missed!",attacker.pbThis)) return -1 end @battle.pbAnimation(@id,attacker,opponent) if !opponent.pbTooHigh?(PBStats::ATTACK) opponent.stages[PBStats::ATTACK]+=2 opponent.stages[PBStats::ATTACK]=6 if opponent.stages[PBStats::ATTACK]>6 @battle.pbCommonAnimation("StatUp",attacker,opponent) @battle.pbDisplay(_INTL("{1}'s Attack sharply rose!",opponent.pbThis)) ret=0 end if opponent.effects[PBEffects::Confusion]==0 && opponent.pbCanConfuse?(true) opponent.effects[PBEffects::Confusion]=2+@battle.pbRandom(4) @battle.pbCommonAnimation("Confusion",attacker,opponent) @battle.pbDisplay(_INTL("{1} became confused!",opponent.pbThis)) ret=0 end return ret end end class PokeBattle_Move_77 < PokeBattle_Move def pbBaseDamage(basedmg,attacker,opponent) basedmg<<=(attacker.effects[PBEffects::FuryCutter]-1) # effects[PBEffects::FuryCutter] can be 1 to 5 return basedmg end end class PokeBattle_Move_78 < PokeBattle_Move def pbEffect(attacker,opponent) if opponent.ability==PBAbilities::OBLIVIOUS @battle.pbDisplay(_INTL("{1}'s Oblivious prevents romance!",opponent.pbThis)) return -1 end if opponent.effects[PBEffects::Attract]>=0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end agender=attacker.gender ogender=opponent.gender if agender==2||ogender==2||agender==ogender @battle.pbDisplay(_INTL("But it failed!")) return -1 end opponent.effects[PBEffects::Attract]=attacker.index @battle.pbAnimation(@id,attacker,opponent) @battle.pbDisplay(_INTL("{1} fell in love!",opponent.pbThis)) return 0 end end class PokeBattle_Move_79 < PokeBattle_Move def pbBaseDamage(damage,attacker,opponent) return (attacker.happiness*10/25).floor end end class PokeBattle_Move_7A < PokeBattle_Move @calcbasedmg=0 def pbEffect(attacker,opponent) random=@battle.pbRandom(256) basedmg=0 if random<52 if opponent.hp==opponent.totalhp @battle.pbDisplay(_INTL("{1}'s HP is full!",opponent.pbThis)) else @battle.pbAnimation(@id,attacker,opponent) opponent.pbRecoverHP((opponent.totalhp/4).floor) @battle.pbDisplay(_INTL("{1} regained health!",opponent.pbThis)) end return 0 elsif random<154 @calcbasedmg=40 elsif random<240 @calcbasedmg=80 else @calcbasedmg=120 end # TODO: Immunity check is currently handled earlier return super(attacker,opponent) end def pbBaseDamage(basedmg,attacker,opponent) return @calcbasedmg end end class PokeBattle_Move_7B < PokeBattle_Move def pbBaseDamage(damage,attacker,opponent) return ((255-attacker.happiness)*10/25).floor end end class PokeBattle_Move_7C < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbOwnSide.effects[PBEffects::Safeguard]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end attacker.pbOwnSide.effects[PBEffects::Safeguard]=5 @battle.pbAnimation(@id,attacker,nil,true) if !@battle.pbIsOpposing?(attacker.index) @battle.pbDisplay(_INTL("The ally's party is covered by a veil!")) else @battle.pbDisplay(_INTL("The foe's party is covered by a veil!")) end return 0 end end class PokeBattle_Move_7D < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if !opponent.pbCanBurn?(false) return false end opponent.pbBurn(attacker) @battle.pbDisplay(_INTL("{1} was burned!",opponent.pbThis)) return true end end class PokeBattle_Move_7E < PokeBattle_Move def pbOnStartUse(attacker) basedmg=[10,30,50,70,90,110,150] magnitudes=[ 0, 1,1, 2,2,2,2, 3,3,3,3,3,3, 4,4,4,4, 5,5, 6 ] magni=magnitudes[@battle.pbRandom(20)] base=basedmg[magni] magni+=4 @battle.pbDisplay(_INTL("Magnitude {1}!",magni)) @calcbasedmg=base return true end def pbBaseDamage(basedmg,attacker,opponent) if opponent.effects[PBEffects::TwoTurnAttack]==PBMoves::DIG return @calcbasedmg*2 end return @calcbasedmg end end class PokeBattle_Move_7F < PokeBattle_Move def pbEffect(attacker,opponent) if !@battle.pbCanChooseNonActive?(attacker.index) @battle.pbDisplay(_INTL("But it failed!")) return -1 end newpoke=0 @battle.pbAnimation(@id,attacker,nil) newpoke=@battle.pbSwitchInBetween(attacker.index,true,false) @battle.pbReplace(attacker.index,newpoke,true) return 0 end end class PokeBattle_Move_80 < PokeBattle_Move def pbModifyDamage(damage,attacker,opponent) damage*=2 if @battle.switching return damage end end class PokeBattle_Move_81 < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) return ret if opponent.damagestate.calcdamage<=0 if attacker.effects[PBEffects::MultiTurn]>0 mtuser=@battle.battlers[attacker.effects[PBEffects::MultiTurnUser]] mtattack=PBMoves.getName(attacker.effects[PBEffects::MultiTurnAttack]) @battle.pbDisplay(_INTL("{1} got free of {2}'s {3}!",attacker.pbThis,mtuser.pbThis,mtattack)) attacker.effects[PBEffects::MultiTurn]=-1 attacker.effects[PBEffects::MultiTurnUser]=-1 attacker.effects[PBEffects::MultiTurnAttack]=0 end if attacker.effects[PBEffects::LeechSeed]>=0 attacker.effects[PBEffects::LeechSeed]=-1 @battle.pbDisplay(_INTL("{1} shed Leech Seed!",attacker.pbThis)) end if attacker.pbOwnSide.effects[PBEffects::Spikes]>0 attacker.pbOwnSide.effects[PBEffects::Spikes]=0 @battle.pbDisplay(_INTL("{1} blew away Spikes!",attacker.pbThis)) end return ret end end class PokeBattle_Move_82 < PokeBattle_Move def pbEffect(attacker,opponent) return pbEffectFixedDamage(20,attacker,opponent) end end class PokeBattle_Move_83 < PokeBattle_Move # No moves with this function code end class PokeBattle_Move_84 < PokeBattle_Move def pbEffect(attacker,opponent) hpgain=0 if @battle.pbWeather==PBWeather::SUNNYDAY hpgain=(attacker.totalhp*2/3).floor elsif @battle.pbWeather!=0 hpgain=(attacker.totalhp/4).floor else hpgain=(attacker.totalhp/2).floor end if attacker.hp==attacker.totalhp @battle.pbDisplay(_INTL("{1}'s HP is full!",attacker.pbThis)) return -1 else @battle.pbAnimation(@id,attacker,nil) attacker.pbRecoverHP(hpgain) @battle.pbDisplay(_INTL("{1} regained health!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_85 < PokeBattle_Move def pbEffect(attacker,opponent) hpgain=0 if @battle.pbWeather==PBWeather::SUNNYDAY hpgain=(attacker.totalhp*2/3).floor elsif @battle.pbWeather!=0 hpgain=(attacker.totalhp/4).floor else hpgain=(attacker.totalhp/2).floor end if attacker.hp==attacker.totalhp @battle.pbDisplay(_INTL("{1}'s HP is full!",attacker.pbThis)) return -1 else @battle.pbAnimation(@id,attacker,nil) attacker.pbRecoverHP(hpgain) @battle.pbDisplay(_INTL("{1} regained health!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_86 < PokeBattle_Move def pbEffect(attacker,opponent) hpgain=0 if @battle.pbWeather==PBWeather::SUNNYDAY hpgain=(attacker.totalhp*2/3).floor elsif @battle.pbWeather!=0 hpgain=(attacker.totalhp/4).floor else hpgain=(attacker.totalhp/2).floor end if attacker.hp==attacker.totalhp @battle.pbDisplay(_INTL("{1}'s HP is full!",attacker.pbThis)) return -1 else @battle.pbAnimation(@id,attacker,nil) attacker.pbRecoverHP(hpgain) @battle.pbDisplay(_INTL("{1} regained health!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_87 < PokeBattle_Move def pbType(type,attacker,opponent) type=0 type|=(attacker.iv[0]&1) type|=(attacker.iv[1]&1)<<1 type|=(attacker.iv[2]&1)<<2 type|=(attacker.iv[3]&1)<<3 type|=(attacker.iv[4]&1)<<4 type|=(attacker.iv[5]&1)<<5 type=(type*15/63).floor if type<8 return type+1 else return type+2 end end def pbBaseDamage(basedmg,attacker,opponent) base=0 base|=(attacker.iv[0]&2)>>1 base|=(attacker.iv[1]&2) base|=(attacker.iv[2]&2)<<1 base|=(attacker.iv[3]&2)<<2 base|=(attacker.iv[4]&2)<<3 base|=(attacker.iv[5]&2)<<4 base=(base*40/63).floor+30 return base end end class PokeBattle_Move_88 < PokeBattle_Move def pbEffect(attacker,opponent) if @battle.weather==PBWeather::RAINDANCE @battle.pbDisplay(_INTL("But it failed!")) return -1 else @battle.weather=PBWeather::RAINDANCE @battle.weatherduration=5 @battle.pbDisplay(_INTL("It started to rain!")) return 0 end end end class PokeBattle_Move_89 < PokeBattle_Move def pbEffect(attacker,opponent) if @battle.weather==PBWeather::SUNNYDAY @battle.pbDisplay(_INTL("But it failed!")) return -1 else @battle.weather=PBWeather::SUNNYDAY @battle.weatherduration=5 @battle.pbDisplay(_INTL("The sunlight got bright!")) return 0 end end end class PokeBattle_Move_8A < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if !attacker.pbTooHigh?(PBStats::DEFENSE) attacker.stages[PBStats::DEFENSE]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Defense rose!",attacker.pbThis)) end return true end end class PokeBattle_Move_8B < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if !attacker.pbTooHigh?(PBStats::ATTACK) attacker.stages[PBStats::ATTACK]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Attack rose!",attacker.pbThis)) end return true end end class PokeBattle_Move_8C < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) haveanim=false if !attacker.pbTooHigh?(PBStats::ATTACK) attacker.stages[PBStats::ATTACK]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) if !haveanim; haveanim=true @battle.pbDisplay(_INTL("{1}'s Attack rose!",attacker.pbThis)) end if !attacker.pbTooHigh?(PBStats::DEFENSE) attacker.stages[PBStats::DEFENSE]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) if !haveanim; haveanim=true @battle.pbDisplay(_INTL("{1}'s Defense rose!",attacker.pbThis)) end if !attacker.pbTooHigh?(PBStats::SPEED) attacker.stages[PBStats::SPEED]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) if !haveanim; haveanim=true @battle.pbDisplay(_INTL("{1}'s Speed rose!",attacker.pbThis)) end if !attacker.pbTooHigh?(PBStats::SPATK) attacker.stages[PBStats::SPATK]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) if !haveanim; haveanim=true @battle.pbDisplay(_INTL("{1}'s Special Attack rose!",attacker.pbThis)) end if !attacker.pbTooHigh?(PBStats::SPDEF) attacker.stages[PBStats::SPDEF]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) if !haveanim; haveanim=true @battle.pbDisplay(_INTL("{1}'s Special Defense rose!",attacker.pbThis)) end return true end end class PokeBattle_Move_8D < PokeBattle_Move # No moves with this function code end class PokeBattle_Move_8E < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.hp<=(attacker.totalhp/2).floor @battle.pbDisplay(_INTL("But it failed!")) return -1 end if attacker.pbTooHigh?(PBStats::ATTACK) @battle.pbDisplay(_INTL("But it failed!")) return -1 end @battle.pbAnimation(@id,attacker,nil) attacker.pbReduceHP((attacker.totalhp/2).floor) attacker.stages[PBStats::ATTACK]=6 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1} cut its own HP and maximized Attack!",attacker.pbThis)) return 0 end end class PokeBattle_Move_8F < PokeBattle_Move def pbEffect(attacker,opponent) for i in 0..6 attacker.stages[i]=opponent.stages[i] end @battle.pbAnimation(@id,attacker,opponent) @battle.pbDisplay(_INTL("{1} copied {2}'s stat changes!",attacker.pbThis,opponent.pbThis)) return 0 end end class PokeBattle_Move_90 < PokeBattle_Move def pbAddTarget(targets,attacker) if attacker.effects[PBEffects::MirrorCoatTarget]>=0 && attacker.pbIsOpposing?(attacker.effects[PBEffects::MirrorCoatTarget]) if !attacker.pbAddTarget(targets, @battle.battlers[attacker.effects[PBEffects::MirrorCoatTarget]]) attacker.pbRandomTarget(targets) end end end def pbEffect(attacker,opponent) if attacker.effects[PBEffects::MirrorCoat]==0||!opponent @battle.pbDisplay(_INTL("But it failed!")) return -1 end ret=pbEffectFixedDamage(attacker.effects[PBEffects::MirrorCoat]*2,attacker,opponent) return ret end end class PokeBattle_Move_91 < PokeBattle_Move def pbTwoTurnAttack(attacker) return attacker.effects[PBEffects::TwoTurnAttack]==0 end def pbEffect(attacker,opponent) if attacker.effects[PBEffects::TwoTurnAttack]>0 @battle.pbAnimation(@id,attacker,nil) @battle.pbDisplay(_INTL("{1} lowered its head!",attacker.pbThis)) if !attacker.pbTooHigh?(PBStats::DEFENSE) attacker.stages[PBStats::DEFENSE]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Defense rose!",attacker.pbThis)) end return 0 end return super end end class PokeBattle_Move_92 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if opponent.ability!=PBAbilities::INNERFOCUS && opponent.effects[PBEffects::Substitute]==0 opponent.effects[PBEffects::Flinch]=true end end def pbBaseDamage(damage,attacker,opponent) if opponent.effects[PBEffects::TwoTurnAttack]==PBMoves::FLY|| opponent.effects[PBEffects::TwoTurnAttack]==PBMoves::BOUNCE damage*=2 end return damage end end class PokeBattle_Move_93 < PokeBattle_Move def pbBaseDamage(basedmg,attacker,opponent) if opponent.effects[PBEffects::TwoTurnAttack]==PBMoves::DIG return basedmg*2 end return basedmg end end class PokeBattle_Move_94 < PokeBattle_Move def pbEffect(attacker,opponent) #TODO: Should ignore Wonder Guard/immunity if opponent.effects[PBEffects::FutureSight]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 else damage=pbCalcDamage(attacker,opponent, PokeBattle_Move::NOCRITICAL|PokeBattle_Move::NOWEIGHTING|PokeBattle_Move::IGNOREPKMNTYPES ) @battle.pbAnimation(@id,attacker,nil) opponent.effects[PBEffects::FutureSight]=3 opponent.effects[PBEffects::FutureSightDamage]=damage opponent.effects[PBEffects::FutureSightMove]=@id opponent.effects[PBEffects::FutureSightUser]=attacker.index if @id==PBMoves::FUTURESIGHT @battle.pbDisplay(_INTL("{1} foresaw an attack!",attacker.pbThis)) else @battle.pbDisplay(_INTL("{1} chose Doom Desire as its destiny!",attacker.pbThis)) end return 0 end end end class PokeBattle_Move_95 < PokeBattle_Move def pbBaseDamage(basedmg,attacker,opponent) if opponent.effects[PBEffects::TwoTurnAttack]==PBMoves::FLY || opponent.effects[PBEffects::TwoTurnAttack]==PBMoves::BOUNCE return basedmg*2 end return basedmg end end class PokeBattle_Move_96 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if opponent.ability!=PBAbilities::INNERFOCUS && opponent.effects[PBEffects::Substitute]==0 opponent.effects[PBEffects::Flinch]=true end end def pbModifyDamage(damage,attacker,opponent) if opponent.effects[PBEffects::Minimize] damage*=2 end return damage end end class PokeBattle_Move_97 < PokeBattle_Move def pbTwoTurnAttack(attacker) return attacker.effects[PBEffects::TwoTurnAttack]==0 end def pbEffect(attacker,opponent) if attacker.effects[PBEffects::TwoTurnAttack]>0 && @battle.pbWeather!=PBWeather::SUNNYDAY @battle.pbAnimation(@id,attacker,nil) @battle.pbDisplay(_INTL("{1} took in sunlight!",attacker.pbThis)) return 0 end return super end end class PokeBattle_Move_98 < PokeBattle_Move #Accuracy handled in main pbAccuracyCheck def pbAdditionalEffect(attacker,opponent) if !opponent.pbCanParalyze?(false) return false end opponent.pbParalyze(attacker) @battle.pbDisplay(_INTL("{1} was paralyzed! It may be unable to move!",opponent.pbThis)) return true end end class PokeBattle_Move_99 < PokeBattle_Move def pbEffect(attacker,opponent) if @battle.opponent @battle.pbDisplay(_INTL("But it failed!")) return -1 elsif attacker.item==PBItems::SMOKEBALL|| attacker.ability==PBAbilities::RUNAWAY|| @battle.pbCanSwitch?(attacker.index,-1,false) @battle.pbAnimation(@id,attacker,nil) @battle.pbDisplay(_INTL("{1} fled from battle!",attacker.pbThis)) @battle.decision=3 return 0 else @battle.pbDisplay(_INTL("But it failed!")) return -1 end end end class PokeBattle_Move_9A < PokeBattle_Move def pbSetThisPkmn(thispkmn) @thispkmn=thispkmn end def pbCalcDamage(attacker,opponent) opponent.damagestate.critical=pbIsCritical?(attacker,opponent) opponent.damagestate.typemod=4 opponent.damagestate.hplost=0 basedmg=@basedamage dexdata=pbOpenDexData pbDexDataOffset(dexdata,attacker.species,11) # Base Attack of attacker atk=dexdata.fgetb pbDexDataOffset(dexdata,opponent.species,12) # Base Defense of opponent defense=dexdata.fgetb dexdata.close damage=(((2*@thispkmn.level/5+2).floor*atk*basedmg/defense).floor/50).floor if attacker.effects[PBEffects::HelpingHand] damage=(damage*1.5).floor end #Damage weighting random=85+@battle.pbRandom(16) damage=(damage*random/100).floor if opponent.damagestate.critical damage*=2 end opponent.damagestate.calcdamage=damage return damage end end class PokeBattle_Move_9B < PokeBattle_Move def pbTwoTurnAttack(attacker) return attacker.effects[PBEffects::TwoTurnAttack]==0 end def pbAdditionalEffect(attacker,opponent) if !opponent.pbCanParalyze?(false) return false end opponent.pbParalyze(attacker) @battle.pbDisplay(_INTL("{1} was paralyzed! It may be unable to move!",opponent.pbThis)) return true end def pbEffect(attacker,opponent) if attacker.effects[PBEffects::TwoTurnAttack]>0 @battle.pbAnimation(@id,attacker,nil) case @id when PBMoves::DIG @battle.pbDisplay(_INTL("{1} dug a hole!",attacker.pbThis)) when PBMoves::FLY @battle.pbDisplay(_INTL("{1} flew up high!",attacker.pbThis)) when PBMoves::DIVE @battle.pbDisplay(_INTL("{1} hid underwater!",attacker.pbThis)) when PBMoves::BOUNCE @battle.pbDisplay(_INTL("{1} sprang up!",attacker.pbThis)) end return 0 end return super end end class PokeBattle_Move_9C < PokeBattle_Move def pbEffect(attacker,opponent) attacker.effects[PBEffects::DefenseCurl]=true if attacker.pbTooHigh?(PBStats::DEFENSE) @battle.pbDisplay(_INTL("{1}'s Defense won't go higher!",attacker.pbThis)) return -1 else attacker.stages[PBStats::DEFENSE]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Defense rose!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_9D < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.hp==attacker.totalhp @battle.pbDisplay(_INTL("{1}'s HP is full!",attacker.pbThis)) return -1 else @battle.pbAnimation(@id,attacker,nil) attacker.pbRecoverHP((attacker.totalhp/2).floor) @battle.pbDisplay(_INTL("{1} regained health!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_9E < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0 && !opponent.damagestate.substitute && opponent.hp>0 if opponent.ability==PBAbilities::INNERFOCUS @battle.pbDisplay(_INTL("{1}'s Inner Focus prevents flinching!",opponent.pbThis)) return ret elsif opponent.ability!=PBAbilities::SHIELDDUST opponent.effects[PBEffects::Flinch]=true end end return ret end def pbMoveFailed(attacker,opponent) return (attacker.turncount!=1) end end class PokeBattle_Move_9F < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0 if attacker.effects[PBEffects::Uproar]==0 attacker.effects[PBEffects::Uproar]=2+@battle.pbRandom(4) @battle.pbDisplay(_INTL("{1} caused an uproar!",attacker.pbThis)) attacker.currentMove=@id end end return ret end end class PokeBattle_Move_A0 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.effects[PBEffects::Stockpile]>=3 @battle.pbDisplay(_INTL("{1} can't stockpile any more!",attacker.pbThis)) return -1 else attacker.effects[PBEffects::Stockpile]+=1 @battle.pbAnimation(@id,attacker,nil) @battle.pbDisplay(_INTL("{1} stockpiled {2}!",attacker.pbThis,attacker.effects[PBEffects::Stockpile])) return 0 end end end class PokeBattle_Move_A1 < PokeBattle_Move def pbEffect(attacker,opponent) ret=super attacker.effects[PBEffects::Stockpile]=0 return ret end def pbModifyDamage(damage,attacker,opponent) return damage*attacker.effects[PBEffects::Stockpile] end def pbCalcDamage(attacker,opponent) return super(attacker,opponent, PokeBattle_Move::NOCRITICAL|PokeBattle_Move::NOWEIGHTING) end end class PokeBattle_Move_A2 < PokeBattle_Move def pbEffect(attacker,opponent) hpgain=0 case attacker.effects[PBEffects::Stockpile] when 0 @battle.pbDisplay(_INTL("But it failed to swallow a thing!")) return -1 when 1 hpgain=(attacker.totalhp/4).floor when 2 hpgain=(attacker.totalhp/2).floor when 3 hpgain=attacker.totalhp end attacker.effects[PBEffects::Stockpile]=0 if attacker.hp==attacker.totalhp @battle.pbDisplay(_INTL("{1}'s HP is full!",attacker.pbThis)) return -1 else @battle.pbAnimation(@id,attacker,opponent) attacker.pbRecoverHP(hpgain) @battle.pbDisplay(_INTL("{1} regained health!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_A3 < PokeBattle_Move #No moves with this function code end class PokeBattle_Move_A4 < PokeBattle_Move def pbEffect(attacker,opponent) if @battle.weather==PBWeather::HAIL @battle.pbDisplay(_INTL("But it failed!")) return -1 else @battle.weather=PBWeather::HAIL @battle.weatherduration=5 @battle.pbDisplay(_INTL("It started to hail!")) return 0 end end end class PokeBattle_Move_A5 < PokeBattle_Move def pbEffect(attacker,opponent) if opponent.effects[PBEffects::Torment] @battle.pbDisplay(_INTL("But it failed!")) return -1 else opponent.effects[PBEffects::Torment]=true @battle.pbAnimation(@id,attacker,opponent) @battle.pbDisplay(_INTL("{1} was subjected to Torment!",opponent.pbThis)) return 0 end end end class PokeBattle_Move_A6 < PokeBattle_Move def pbEffect(attacker,opponent) ret=-1 if opponent.effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("{1}'s attack missed!",attacker.pbThis)) return -1 end @battle.pbAnimation(@id,attacker,opponent) if !opponent.pbTooHigh?(PBStats::SPATK) opponent.stages[PBStats::SPATK]+=1 @battle.pbCommonAnimation("StatUp",attacker,opponent) @battle.pbDisplay(_INTL("{1}'s Special Attack rose!",opponent.pbThis)) ret=0 end if opponent.effects[PBEffects::Confusion]==0 && opponent.pbCanConfuse?(true) opponent.effects[PBEffects::Confusion]=2+@battle.pbRandom(4) @battle.pbCommonAnimation("Confusion",attacker,opponent) @battle.pbDisplay(_INTL("{1} became confused!",opponent.pbThis)) ret=0 end return ret end end class PokeBattle_Move_A7 < PokeBattle_Move def pbEffect(attacker,opponent) if !opponent.pbCanBurnFromFireMove?(self,true) return -1 end opponent.pbBurn(attacker) @battle.pbDisplay(_INTL("{1} was burned!",opponent.pbThis)) return 0 end end class PokeBattle_Move_A8 < PokeBattle_Move def pbEffect(attacker,opponent) @battle.pbAnimation(@id,attacker,opponent) if opponent.effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("But it had no effect!")) return -1 end if opponent.pbOwnSide.effects[PBEffects::Mist]>0 @battle.pbDisplay(_INTL("{1} is protected by Mist!",opponent.pbThis)) return -1 end if opponent.ability==PBAbilities::CLEARBODY||opponent.ability==PBAbilities::WHITESMOKE abilityname=PBAbilities.getName(opponent.ability) @battle.pbDisplay(_INTL("{1}'s {2} prevents stat loss!",opponent.pbThis,abilityname)) return -1 end fail=-1 if opponent.ability==PBAbilities::HYPERCUTTER abilityname=PBAbilities.getName(opponent.ability) @battle.pbDisplay(_INTL("{1}'s {2} prevents Attack loss!",opponent.pbThis,abilityname)) elsif opponent.pbTooLow?(PBStats::ATTACK) @battle.pbDisplay(_INTL("{1}'s Attack won't go lower!",opponent.pbThis)) else opponent.stages[PBStats::ATTACK]-=1 @battle.pbCommonAnimation("StatDown",attacker,opponent) if fail==-1 @battle.pbDisplay(_INTL("{1}'s Attack fell!",opponent.pbThis)) fail=0 end if opponent.pbTooLow?(PBStats::SPATK) @battle.pbDisplay(_INTL("{1}'s Special Attack won't go lower!",opponent.pbThis)) else opponent.stages[PBStats::SPATK]-=1 @battle.pbCommonAnimation("StatDown",attacker,opponent) if fail==-1 @battle.pbDisplay(_INTL("{1}'s Special Attack fell!",opponent.pbThis)) fail=0 end return fail end end class PokeBattle_Move_A9 < PokeBattle_Move def pbModifyDamage(damage,attacker,opponent) if attacker.status==PBStatuses::BURN && attacker.status==PBStatuses::POISON && attacker.status==PBStatuses::PARALYSIS return damage*2 end return damage end end class PokeBattle_Move_AA < PokeBattle_Move def pbDisplayUseMessage(attacker) if attacker.lastHPLost > 0 @battle.pbDisplay(_INTL("{1} lost its focus and couldn't move!",attacker.pbThis)); return -1 else return super end end end class PokeBattle_Move_AB < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0 && !opponent.damagestate.substitute && opponent.status==PBStatuses::PARALYSIS opponent.status=0 @battle.pbDisplay(_INTL("{1} was healed of paralysis!",opponent.pbThis)) end return ret end def pbModifyDamage(damage,attacker,opponent) if opponent.status==PBStatuses::PARALYSIS && opponent.effects[PBEffects::Substitute]==0 return damage*2 end return damage end end class PokeBattle_Move_AC < PokeBattle_Move def pbEffect(attacker,opponent) attacker.effects[PBEffects::FollowMe]=true @battle.pbDisplay(_INTL("{1} became the center of attention!",attacker.pbThis)) return 0 end end class PokeBattle_Move_AD < PokeBattle_Move def pbEffect(attacker,opponent) move=PBMoves::SWIFT case @battle.environment when PBEnvironment::None move=PBMoves::SWIFT when PBEnvironment::Grass move=PBMoves::STUNSPORE when PBEnvironment::TallGrass move=PBMoves::RAZORLEAF when PBEnvironment::MovingWater move=PBMoves::SURF when PBEnvironment::StillWater move=PBMoves::BUBBLEBEAM when PBEnvironment::Underwater move=PBMoves::HYDROPUMP when PBEnvironment::Rock move=PBMoves::ROCKSLIDE when PBEnvironment::Cave move=PBMoves::SHADOWBALL when PBEnvironment::Sand move=PBMoves::EARTHQUAKE end thismovename=PBMoves.getName(@id) movename=PBMoves.getName(move) @battle.pbDisplay(_INTL("{1} turned into {2}!",thismovename,movename)) attacker.pbUseMoveSimple(move) return 0 end end class PokeBattle_Move_AE < PokeBattle_Move def pbEffect(attacker,opponent) attacker.effects[PBEffects::Charge]=2 @battle.pbAnimation(@id,attacker,nil) @battle.pbDisplay(_INTL("{1} began charging power!",attacker.pbThis)) return 0 end end class PokeBattle_Move_AF < PokeBattle_Move def pbEffect(attacker,opponent) if opponent.effects[PBEffects::Taunt]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 else opponent.effects[PBEffects::Taunt]=2 @battle.pbAnimation(@id,attacker,opponent) @battle.pbDisplay(_INTL("{1} fell for the Taunt!",opponent.pbThis)) return 0 end end end class PokeBattle_Move_B0 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbPartner.hp>0 && !attacker.pbPartner.effects[PBEffects::HelpingHand] attacker.pbPartner.effects[PBEffects::HelpingHand]=true @battle.pbAnimation(@id,attacker,attacker.pbPartner) @battle.pbDisplay(_INTL("{1} is ready to help {2}!",attacker.pbThis,attacker.pbPartner.pbThis)) return 0 else @battle.pbDisplay(_INTL("But it failed!")) return -1 end end end class PokeBattle_Move_B1 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.effects[PBEffects::Substitute]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end if attacker.item==PBItems::ENIGMABERRY|| opponent.item==PBItems::ENIGMABERRY @battle.pbDisplay(_INTL("But it failed!")) return -1 end if attacker.item==0&& opponent.item==0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end if opponent.ability==PBAbilities::STICKYHOLD abilityname=PBAbilities.getName(opponent.ability) @battle.pbDisplay(_INTL("{1}'s {2} made {3} ineffective!",opponent.pbThis,abilityname,name)) return -1 end @battle.pbAnimation(@id,attacker,opponent) oldoppitem=opponent.item oldattitem=attacker.item oldoppitemname=PBItems.getName(oldoppitem) oldattitemname=PBItems.getName(oldattitem) tmpitem=attacker.item attacker.item=opponent.item opponent.item=tmpitem @battle.pbDisplay(_INTL("{1} switched items with its opponent!",attacker.pbThis)) if oldoppitem>0 && oldattitem>0 @battle.pbDisplayPaused(_INTL("{1} obtained {2}.",attacker.pbThis,oldoppitemname)) @battle.pbDisplay(_INTL("{1} obtained {2}.",opponent.pbThis,oldattitemname)) else @battle.pbDisplay(_INTL("{1} obtained {2}.",attacker.pbThis,oldoppitemname)) if oldoppitem>0 @battle.pbDisplay(_INTL("{1} obtained {2}.",opponent.pbThis,oldattitemname)) if oldattitem>0 end return 0 end end class PokeBattle_Move_B2 < PokeBattle_Move def pbEffect(attacker,opponent) if opponent.ability==PBAbilities::WONDERGUARD || opponent.ability==0 @battle.pbDisplay(_INTL("But it failed!")) return -0 end @battle.pbAnimation(@id,attacker,opponent) attacker.ability=opponent.ability abilityname=PBAbilities.getName(opponent.ability) @battle.pbDisplay(_INTL("{1} copied {2}'s {3}!",attacker.pbThis,opponent.pbThis,abilityname)) return 0 end end class PokeBattle_Move_B3 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.effects[PBEffects::Wish]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end @battle.pbAnimation(@id,attacker,nil) attacker.effects[PBEffects::Wish]=2 attacker.effects[PBEffects::WishMaker]=attacker.pokemonIndex return 0 end end class PokeBattle_Move_B4 < PokeBattle_Move def pbEffect(attacker,opponent) moves=[] blacklist=[ 0, PBMoves::SLEEPTALK, PBMoves::ASSIST, PBMoves::MIRRORMOVE, PBMoves::METRONOME, PBMoves::STRUGGLE, PBMoves::SKETCH, PBMoves::MIMIC, PBMoves::COUNTER, PBMoves::MIRRORCOAT, PBMoves::PROTECT, PBMoves::DETECT, PBMoves::ENDURE, PBMoves::DESTINYBOND, PBMoves::THIEF, PBMoves::FOLLOWME, PBMoves::SNATCH, PBMoves::HELPINGHAND, PBMoves::COVET, PBMoves::TRICK, PBMoves::FOCUSPUNCH ] party=@battle.pbParty(attacker.index) # NOTE: pbParty is common to both allies in multi battles for i in 0...party.length if i!=attacker.pokemonIndex && party[i] && !party[i].egg? for j in party[i].moves found=false for k in blacklist if j.id==k found=true break end end moves[moves.length]=j.id if !found end end end if moves.length==0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end @battle.pbAnimation(@id,attacker,nil) move=moves[@battle.pbRandom(moves.length)] attacker.pbUseMoveSimple(move) return 0 end end class PokeBattle_Move_B5 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.effects[PBEffects::Ingrain] @battle.pbDisplay(_INTL("But it failed!")) return -1 else @battle.pbAnimation(@id,attacker,nil) attacker.effects[PBEffects::Ingrain]=true @battle.pbDisplay(_INTL("{1} planted its roots!",attacker.pbThis)) return 0 end end end class PokeBattle_Move_B6 < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0 if !attacker.pbTooLow?(PBStats::ATTACK) attacker.stages[PBStats::ATTACK]-=1 @battle.pbCommonAnimation("StatDown",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Attack fell!",attacker.pbThis)) end if !attacker.pbTooLow?(PBStats::DEFENSE) attacker.stages[PBStats::DEFENSE]-=1 @battle.pbCommonAnimation("StatDown",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Defense fell!",attacker.pbThis)) end end return ret end end class PokeBattle_Move_B7 < PokeBattle_Move def pbEffect(attacker,opponent) @battle.pbAnimation(@id,attacker,nil) attacker.effects[PBEffects::MagicCoat]=true @battle.pbDisplay(_INTL("{1} shrouded itself in Magic Coat!",attacker.pbThis)) return 0 end end class PokeBattle_Move_B8 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.effects[PBEffects::RecycleItem]==0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end @battle.pbAnimation(@id,attacker,nil) attacker.item=attacker.effects[PBEffects::RecycleItem] itemname=PBItems.getName(attacker.effects[PBEffects::RecycleItem]) @battle.pbDisplay(_INTL("{1} found one {2}!",attacker.pbThis,itemname)) attacker.effects[PBEffects::RecycleItem]=0 return 0 end end class PokeBattle_Move_B9 < PokeBattle_Move def pbModifyDamage(damage,attacker,opponent) if attacker.lastHPLost>0 && attacker.lastAttacker==opponent.index damage*=2 end return damage end end class PokeBattle_Move_BA < PokeBattle_Move def pbEffect(attacker,opponent) reflect=false if attacker.pbOpposingSide.effects[PBEffects::Reflect]>0||attacker.pbOpposingSide.effects[PBEffects::LightScreen]>0 attacker.pbOpposingSide.effects[PBEffects::Reflect]=0 attacker.pbOpposingSide.effects[PBEffects::LightScreen]=0 @battle.pbAnimation(@id,attacker,opponent) @battle.pbDisplay(_INTL("The wall shattered!")) # TODO: Actually handled earlier end ret=super(attacker,opponent) return ret end end class PokeBattle_Move_BB < PokeBattle_Move def pbEffect(attacker,opponent) if !opponent.pbCanSleep?(true) return -1 end if opponent.effects[PBEffects::Yawn]>0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end @battle.pbAnimation(@id,attacker,opponent) opponent.effects[PBEffects::Yawn]=2 @battle.pbDisplay(_INTL("{1} made {2} drowsy!",attacker.pbThis,opponent.pbThis)) return 0 end end class PokeBattle_Move_BC < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0&& !opponent.damagestate.substitute && opponent.hp>0 && opponent.item!=0 if opponent.ability==PBAbilities::STICKYHOLD abilityname=PBAbilities.getName(opponent.ability) @battle.pbDisplay(_INTL("{1}'s {2} made {3} ineffective!",opponent.pbThis,abilityname,@name)) else itemname=PBItems.getName(opponent.item) opponent.item=0 @battle.pbDisplay(_INTL("{1} knocked off {2}'s {3}!",attacker.pbThis,opponent.pbThis,itemname)) end end return ret end end class PokeBattle_Move_BD < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.hp>=opponent.hp @battle.pbDisplay(_INTL("But it failed!")) return -1 else return pbEffectFixedDamage(opponent.hp-attacker.hp,attacker,opponent) end end end class PokeBattle_Move_BE < PokeBattle_Move def pbOnStartUse(attacker) damage=(attacker.hp*150/attacker.totalhp).floor damage=1 if damage<1 @calcbasedmg=damage return true end def pbBaseDamage(damage,attacker,opponent) return @calcbasedmg end end class PokeBattle_Move_BF < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.ability==0&&opponent.ability==0 @battle.pbDisplay(_INTL("But it failed!")) return -1 end if attacker.ability==PBAbilities::WONDERGUARD|| opponent.ability==PBAbilities::WONDERGUARD @battle.pbDisplay(_INTL("But it failed!")) return -1 end @battle.pbAnimation(@id,attacker,opponent) tmp=attacker.ability attacker.ability=opponent.ability opponent.ability=tmp @battle.pbDisplay(_INTL("{1} swapped abilities with its opponent!",attacker.pbThis)) return 0 end end class PokeBattle_Move_C0 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.effects[PBEffects::Imprison] @battle.pbDisplay(_INTL("But it failed!")) return -1 end found=false for i in attacker.moves next if i.id==0 for j in attacker.pbOpposing1.moves found=true if j.id==i.id end for j in attacker.pbOpposing2.moves found=true if j.id==i.id end end if !found @battle.pbDisplay(_INTL("But it failed!")) return -1 end @battle.pbAnimation(@id,attacker,nil,true) attacker.effects[PBEffects::Imprison]=true @battle.pbDisplay(_INTL("{1} sealed the opponent's move(s)!",attacker.pbThis)) return 0 end end class PokeBattle_Move_C1 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.status!=PBStatuses::BURN && attacker.status!=PBStatuses::POISON && attacker.status!=PBStatuses::PARALYSIS @battle.pbDisplay(_INTL("But it failed!")) else @battle.pbAnimation(@id,attacker,nil) attacker.status=0 attacker.statusCount=0 @battle.pbDisplay(_INTL("{1}'s status returned to normal!",attacker.pbThis)) end end end class PokeBattle_Move_C2 < PokeBattle_Move def pbEffect(attacker,opponent) @battle.pbAnimation(@id,attacker,nil) attacker.effects[PBEffects::Grudge]=true @battle.pbDisplay(_INTL("{1} wants the opponent to bear a grudge!",attacker.pbThis)) return 0 end end class PokeBattle_Move_C3 < PokeBattle_Move def pbEffect(attacker,opponent) # TODO: Fails if attacker is last in priority attacker.effects[PBEffects::Snatch]=true @battle.pbAnimation(@id,attacker,nil) if @battle.doublebattle @battle.pbDisplay(_INTL("{1} waits for a target to make a move!",attacker.pbThis)) else @battle.pbDisplay(_INTL("{1} waits for its foe to make a move!",attacker.pbThis)) end return 0 end end class PokeBattle_Move_C4 < PokeBattle_Move def pbBaseDamage(basedmg,attacker,opponent) dexdata=pbOpenDexData pbDexDataOffset(dexdata,opponent.species,35) weight=dexdata.fgetw dexdata.close basedmg=20 basedmg=40 if weight>=100 basedmg=60 if weight>=250 basedmg=80 if weight>=500 basedmg=100 if weight>=1000 basedmg=120 if weight>=2000 return basedmg end end class PokeBattle_Move_C5 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) case @battle.environment when PBEnvironment::None return false if !opponent.pbCanParalyze?(false) opponent.pbParalyze(attacker) @battle.pbDisplay(_INTL("{1} is paralyzed! It may be unable to move!",opponent.pbThis)) when PBEnvironment::Grass return false if !opponent.pbCanPoison?(false) opponent.pbPoison(attacker) @battle.pbDisplay(_INTL("{1} was poisoned!",opponent.pbThis)) when PBEnvironment::TallGrass return false if !opponent.pbCanSleep?(false) opponent.pbSleep @battle.pbDisplay(_INTL("{1} went to sleep!",opponent.pbThis)) when PBEnvironment::MovingWater return false if !opponent.pbReduceStat(PBStats::ATTACK,1,false) @battle.pbDisplay(_INTL("{1}'s Attack fell!",opponent.pbThis)) when PBEnvironment::StillWater return false if !opponent.pbReduceStat(PBStats::SPEED,1,false) @battle.pbDisplay(_INTL("{1}'s Speed fell!",opponent.pbThis)) when PBEnvironment::Underwater return false if !opponent.pbReduceStat(PBStats::DEFENSE,1,false) @battle.pbDisplay(_INTL("{1}'s Defense fell!",opponent.pbThis)) when PBEnvironment::Cave return false if opponent.ability==PBAbilities::INNERFOCUS || opponent.effects[PBEffects::Substitute]>0 opponent.effects[PBEffects::Flinch]=true when PBEnvironment::Rock return false if !opponent.pbCanConfuse?(false) opponent.effects[PBEffects::Confusion]=2+@battle.pbRandom(4) @battle.pbCommonAnimation("Confusion",attacker,opponent) @battle.pbDisplay(_INTL("{1} became confused!",opponent.pbThis)) when PBEnvironment::Sand return false if !opponent.pbReduceStat(PBStats::ACCURACY,1,false) @battle.pbDisplay(_INTL("{1}'s accuracy fell!",opponent.pbThis)) else return false end return true end end class PokeBattle_Move_C6 < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0 if attacker.ability!=PBAbilities::ROCKHEAD attacker.pbReduceHP((opponent.damagestate.hplost/3).floor) @battle.pbDisplay(_INTL("{1} is hit with recoil!",attacker.pbThis)) end end return ret end end class PokeBattle_Move_C7 < PokeBattle_Move def pbEffect(attacker,opponent) if opponent.pbCanConfuse?(true) @battle.pbAnimation(@id,attacker,opponent) opponent.effects[PBEffects::Confusion]=2+@battle.pbRandom(4) @battle.pbCommonAnimation("Confusion",attacker,opponent) @battle.pbDisplay(_INTL("{1} became confused!",opponent.pbThis)) return 0 end return -1 end end class PokeBattle_Move_C8 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if !opponent.pbCanBurn?(false) return false end opponent.pbBurn(attacker) @battle.pbDisplay(_INTL("{1} was burned!",opponent.pbThis)) return true end end class PokeBattle_Move_C9 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.effects[PBEffects::MudSport] @battle.pbDisplay(_INTL("But it failed!")) return -1 else @battle.pbAnimation(@id,attacker,nil) attacker.effects[PBEffects::MudSport]=true @battle.pbDisplay(_INTL("Electricity's power was weakened!")) return 0 end end end class PokeBattle_Move_CA < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if !opponent.pbCanPoison?(false) return false end opponent.pbPoison(attacker,true) @battle.pbDisplay(_INTL("{1} is badly poisoned!",opponent.pbThis)) return true end end class PokeBattle_Move_CB < PokeBattle_Move def pbType(type,attacker,opponent) weather=@battle.pbWeather type=PBTypes::NORMAL type=PBTypes::FIRE if weather==PBWeather::SUNNYDAY type=PBTypes::WATER if weather==PBWeather::RAINDANCE type=PBTypes::ROCK if weather==PBWeather::SANDSTORM type=PBTypes::ICE if weather==PBWeather::HAIL return type end def pbModifyDamage(damage,attacker,opponent) damage*=2 if @battle.pbWeather!=0 return damage end end class PokeBattle_Move_CC < PokeBattle_Move def pbEffect(attacker,opponent) ret=super(attacker,opponent) if opponent.damagestate.calcdamage>0 && !attacker.pbTooLow?(PBStats::SPATK) attacker.stages[PBStats::SPATK]-=2 attacker.stages[PBStats::SPATK]=-6 if attacker.stages[PBStats::SPATK]<-6 @battle.pbCommonAnimation("StatDown",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Special Attack fell!",attacker.pbThis)) end return ret end end class PokeBattle_Move_CD < PokeBattle_Move def pbEffect(attacker,opponent) @battle.pbAnimation(@id,attacker,opponent) if opponent.pbTooLow?(PBStats::ATTACK) && opponent.pbTooLow?(PBStats::DEFENSE) @battle.pbDisplay(_INTL("{1}'s stats won't go lower!",opponent.pbThis)) return -1 end if opponent.pbOwnSide.effects[PBEffects::Mist]>0 @battle.pbDisplay(_INTL("{1} is protected by Mist!",opponent.pbThis)) return -1 end if opponent.ability==PBAbilities::CLEARBODY||opponent.ability==PBAbilities::WHITESMOKE abilityname=PBAbilities.getName(opponent.ability) @battle.pbDisplay(_INTL("{1}'s {2} prevents stat loss!",opponent.pbThis,abilityname)) return -1 end fail=-1 if opponent.ability==PBAbilities::HYPERCUTTER abilityname=PBAbilities.getName(opponent.ability) @battle.pbDisplay(_INTL("{1}'s {2} prevents Attack loss!",opponent.pbThis,abilityname)) elsif opponent.pbTooLow?(PBStats::ATTACK) @battle.pbDisplay(_INTL("{1}'s Attack won't go lower!",opponent.pbThis)) else opponent.stages[PBStats::ATTACK]-=1 @battle.pbCommonAnimation("StatDown",attacker,opponent) @battle.pbDisplay(_INTL("{1}'s Attack fell!",opponent.pbThis)) fail=0 end if opponent.pbTooLow?(PBStats::DEFENSE) @battle.pbDisplay(_INTL("{1}'s Defense won't go lower!",opponent.pbThis)) else opponent.stages[PBStats::DEFENSE]-=1 @battle.pbCommonAnimation("StatDown",attacker,opponent) @battle.pbDisplay(_INTL("{1}'s Defense fell!",opponent.pbThis)) fail=0 end return fail end end class PokeBattle_Move_CE < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbTooHigh?(PBStats::DEFENSE) && attacker.pbTooHigh?(PBStats::SPDEF) @battle.pbDisplay(_INTL("{1}'s stats won't go higher!",attacker.pbThis)) return -1 end @battle.pbAnimation(@id,attacker,nil) @battle.pbCommonAnimation("StatUp",attacker,nil) if !attacker.pbTooHigh?(PBStats::DEFENSE) attacker.stages[PBStats::DEFENSE]+=1 @battle.pbDisplay(_INTL("{1}'s Defense rose!",attacker.pbThis)) end if !attacker.pbTooHigh?(PBStats::SPDEF) attacker.stages[PBStats::SPDEF]+=1 @battle.pbDisplay(_INTL("{1}'s Special Defense rose!",attacker.pbThis)) end return 0 end end class PokeBattle_Move_CF < PokeBattle_Move # Handled in Battler class end class PokeBattle_Move_D0 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbTooHigh?(PBStats::ATTACK) && attacker.pbTooHigh?(PBStats::DEFENSE) @battle.pbDisplay(_INTL("{1}'s stats won't go higher!",attacker.pbThis)) return -1 end @battle.pbAnimation(@id,attacker,nil) @battle.pbCommonAnimation("StatUp",attacker,nil) if !attacker.pbTooHigh?(PBStats::ATTACK) attacker.stages[PBStats::ATTACK]+=1 @battle.pbDisplay(_INTL("{1}'s Attack rose!",attacker.pbThis)) end if !attacker.pbTooHigh?(PBStats::DEFENSE) attacker.stages[PBStats::DEFENSE]+=1 @battle.pbDisplay(_INTL("{1}'s Defense rose!",attacker.pbThis)) end return 0 end end class PokeBattle_Move_D1 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) if !opponent.pbCanPoison?(false) return false end opponent.pbPoison(attacker) @battle.pbDisplay(_INTL("{1} was poisoned!",opponent.pbThis)) return true end end class PokeBattle_Move_D2 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.effects[PBEffects::WaterSport] @battle.pbDisplay(_INTL("But it failed!")) return -1 else @battle.pbAnimation(@id,attacker,nil) attacker.effects[PBEffects::WaterSport]=true @battle.pbDisplay(_INTL("Fire's power was weakened!")) return 0 end end end class PokeBattle_Move_D3 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbTooHigh?(PBStats::SPATK) && attacker.pbTooHigh?(PBStats::SPDEF) @battle.pbDisplay(_INTL("{1}'s stats won't go higher!",attacker.pbThis)) return -1 end @battle.pbAnimation(@id,attacker,nil) if !attacker.pbTooHigh?(PBStats::SPATK) attacker.stages[PBStats::SPATK]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Special Attack rose!",attacker.pbThis)) end if !attacker.pbTooHigh?(PBStats::SPDEF) attacker.stages[PBStats::SPDEF]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Special Defense rose!",attacker.pbThis)) end return 0 end end class PokeBattle_Move_D4 < PokeBattle_Move def pbEffect(attacker,opponent) if attacker.pbTooHigh?(PBStats::ATTACK) && attacker.pbTooHigh?(PBStats::SPEED) @battle.pbDisplay(_INTL("{1}'s stats won't go higher!",attacker.pbThis)) return -1 end @battle.pbAnimation(@id,attacker,nil) if !attacker.pbTooHigh?(PBStats::ATTACK) attacker.stages[PBStats::ATTACK]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Attack rose!",attacker.pbThis)) end if !attacker.pbTooHigh?(PBStats::SPEED) attacker.stages[PBStats::SPEED]+=1 @battle.pbCommonAnimation("StatUp",attacker,nil) @battle.pbDisplay(_INTL("{1}'s Speed rose!",attacker.pbThis)) end return 0 end end class PokeBattle_Move_D5 < PokeBattle_Move def pbEffect(attacker,opponent) envtypes=[ PBTypes::NORMAL, PBTypes::GRASS, PBTypes::GRASS, PBTypes::WATER, PBTypes::WATER, PBTypes::WATER, PBTypes::ROCK, PBTypes::ROCK, PBTypes::GROUND ] type=envtypes[@battle.environment] if attacker.pbHasType?(type) @battle.pbDisplay(_INTL("But it failed!")) return -1 else attacker.type1=type attacker.type2=type typename=PBTypes.getName(type) @battle.pbAnimation(@id,attacker,nil) @battle.pbDisplay(_INTL("{1} transformed into the {2} type!",attacker.pbThis,typename)) return 0 end end end
PokeBattle_BattleRecord
[
Selecionar
] [
-
]
module PokeBattle_RecordedBattleModule attr_reader :randomnums attr_reader :rounds module Commands Fight=0 Bag=1 Pokémon=2 Run=3 end def initialize(*arg) @randomnumbers=[] @rounds=[] @switches=[] @roundindex=-1 @properties={} super(*arg) end def pbGetBattleType return 0 # Battle Tower end def pbGetTrainerInfo(trainer) return nil if !trainer if trainer.is_a?(Array) return [ [trainer[0].trainertype,trainer[0].name.clone,trainer[0].id,trainer[0].badges.clone], [trainer[1].trainertype,trainer[1].name.clone,trainer[1].id,trainer[0].badges.clone] ] else return [ [trainer.trainertype,trainer.name.clone,trainer.id,trainer.badges.clone] ] end end def pbStartBattle @properties={} @properties["internalbattle"]=@internalbattle @properties["player"]=pbGetTrainerInfo(@player) @properties["opponent"]=pbGetTrainerInfo(@opponent) @properties["party1"]=Marshal.dump(@party1) @properties["party2"]=Marshal.dump(@party2) @properties["endspeech"]=@endspeech ? @endspeech : "" @properties["endspeech2"]=@endspeech2 ? @endspeech2 : "" @properties["endspeechwin"]=@endspeechwin ? @endspeechwin : "" @properties["endspeechwin2"]=@endspeechwin2 ? @endspeechwin2 : "" @properties["doublebattle"]=@doublebattle @properties["weather"]=@weather @properties["weatherduration"]=@weatherduration @properties["cantescape"]=@cantescape @properties["shiftStyle"]=@shiftStyle @properties["battlescene"]=@battlescene @properties["items"]=Marshal.dump(@items) @properties["environment"]=@environment super end def pbDumpRecord return Marshal.dump([pbGetBattleType,@properties,@rounds,@randomnumbers,@switches]) end def pbSwitchInBetween(i1,i2,i3) ret=super @switches.push(ret) return ret end def pbRegisterMove(i1,i2) if super @rounds[@roundindex][i1]=[Commands::Fight,i2] return true end return false end def pbRun(i1,duringBattle=false) ret=super @rounds[@roundindex][i1]=[Commands::Run,@decision] return ret end def pbRegisterTarget(i1,i2) ret=super @rounds[@roundindex][i1][2]=i2 return ret end def pbAutoChooseMove(i1,showMessages=true) ret=super(i1,showMessages) @rounds[@roundindex][i1]=[Commands::Fight,-1] return ret end def pbRegisterSwitch(i1,i2) if super @rounds[@roundindex][i1]=[Commands::Pokémon,i2] return true end return false end def pbRegisterItem(i1,i2) if super @rounds[@roundindex][i1]=[Commands::Item,i2] return true end return false end def pbCommandPhase @roundindex+=1 @rounds[@roundindex]=[[],[],[],[]] super end def pbRandom(num) ret=super(num) @randomnumbers.push(ret) return ret end end module BattlePlayerHelper def self.pbGetOpponent(battle) return self.pbCreateTrainerInfo(battle[1]["opponent"]) end def self.pbGetBattleBGM(battle) return self.pbGetTrainerBattleBGM(self.pbGetOpponent(battle)) end def self.pbCreateTrainerInfo(trainer) return nil if !trainer if trainer.length>1 ret=[] ret[0]=PokeBattle_Trainer.new(trainer[0][1],trainer[0][0]) ret[0].id=trainer[0][2] ret[0].badges=trainer[0][3] ret[1]=PokeBattle_Trainer.new(trainer[1][1],trainer[1][0]) ret[1].id=trainer[1][2] ret[1].badges=trainer[1][3] return ret else ret=PokeBattle_Trainer.new(trainer[0][1],trainer[0][0]) ret.id=trainer[0][2] ret.badges=trainer[0][3] return ret end end end module PokeBattle_BattlePlayerModule module Commands Fight=0 Bag=1 Pokémon=2 Run=3 end def initialize(scene,battle) @battletype=battle[0] @properties=battle[1] @rounds=battle[2] @randomnums=battle[3] @switches=battle[4] @roundindex=-1 @randomindex=0 @switchindex=0 super(scene, Marshal.restore(StringInput.new(@properties["party1"])), Marshal.restore(StringInput.new(@properties["party2"])), BattlePlayerHelper.pbCreateTrainerInfo(@properties["player"]), BattlePlayerHelper.pbCreateTrainerInfo(@properties["opponent"]) ) end def pbStartBattle @internalbattle=@properties["internalbattle"] @endspeech=@properties["endspeech"] @endspeech2=@properties["endspeech2"] @endspeechwin=@properties["endspeechwin"] @endspeechwin2=@properties["endspeechwin2"] @doublebattle=@properties["doublebattle"] @weather=@properties["weather"] @weatherduration=@properties["weatherduration"] @cantescape=@properties["cantescape"] @shiftStyle=@properties["shiftStyle"] @battlescene=@properties["battlescene"] @items=Marshal.restore(StringInput.new(@properties["items"])) @environment=@properties["environment"] super end def pbSwitchInBetween(i1,i2,i3) ret=@switches[@switchindex] @switchindex+=1 return ret end def pbRandom(num) ret=@randomnums[@randomindex] @randomindex+=1 return ret end def pbDisplayPaused(str) pbDisplay(str) end def pbCommandPhase @roundindex+=1 for i in 0...4 next if @rounds[@roundindex][i].length==0 @choices[i][0]=0 @choices[i][1]=0 @choices[i][2]=nil @choices[i][3]=-1 case @rounds[@roundindex][i][0] when Commands::Fight if @rounds[@roundindex][i][1]==-1 pbAutoChooseMove(i,false) else pbRegisterMove(i,@rounds[@roundindex][i][1]) end if @rounds[@roundindex][i][2] pbRegisterTarget(i,@rounds[@roundindex][i][2]) end when Commands::Pokémon pbRegisterSwitch(i,@rounds[@roundindex][i][1]) when Commands::Bag pbRegisterItem(i,@rounds[@roundindex][i][1]) when Commands::Run @decision=@rounds[@roundindex][i][1] end end end end class PokeBattle_RecordedBattle < PokeBattle_Battle def pbGetBattleType return 0 end include PokeBattle_RecordedBattleModule end class PokeBattle_RecordedBattlePalace < PokeBattle_BattlePalace def pbGetBattleType return 1 end include PokeBattle_RecordedBattleModule end class PokeBattle_RecordedBattleArena < PokeBattle_BattleArena def pbGetBattleType return 2 end include PokeBattle_RecordedBattleModule end class PokeBattle_BattlePlayer < PokeBattle_Battle include PokeBattle_BattlePlayerModule end class PokeBattle_BattlePalacePlayer < PokeBattle_BattlePalace include PokeBattle_BattlePlayerModule end class PokeBattle_BattleArenaPlayer < PokeBattle_BattleArena include PokeBattle_BattlePlayerModule end
PokeBattle_Scene
[
Selecionar
] [
-
]
def pbPokemonString(pkmn) if pkmn.is_a?(PokeBattle_Battler) && !pkmn.pokemon return "" end status="" if pkmn.hp<=0 status=" [FNT]" else case pkmn.status when PBStatuses::SLEEP status=" [SLP]" when PBStatuses::FROZEN status=" [FRZ]" when PBStatuses::BURN status=" [BRN]" when PBStatuses::PARALYSIS status=" [PAR]" when PBStatuses::POISON status=" [PSN]" end end return "#{pkmn.name} (Lv. #{pkmn.level})#{status} HP: #{pkmn.hp}/#{pkmn.totalhp}" end class Window_Pokemon < SpriteWindow_Base attr_reader :highlighted def highlighted=(value) @highlighted=value refresh end def initialize(battler) @battler=battler @highlighted=false @highlightOpacity=255 @highlightIncr=-2 super(0,0,480,64) self.contents=Bitmap.new(self.width-32,self.height-32) refresh end def update if @highlighted @highlightIncr=-5 if @highlightOpacity>=255 @highlightIncr=5 if @highlightOpacity<=160 self.opacity=@highlightOpacity self.contents_opacity=@highlightOpacity @highlightOpacity+=@highlightIncr elsif self.opacity!=255 || self.contents_opacity!=255 self.opacity=255 self.contents_opacity=255 end super end def refresh self.contents.clear self.contents.font.color = Color.new(0,0,0) str=pbPokemonString(@battler) self.contents.draw_text(0, 0, self.width-32, 32, str, 0) end end class Window_SimpleText < SpriteWindow_Base attr_reader :text attr_reader :lines def text=(value) @text=value refresh end def initialize(text,lines) @text=text @lines=lines @lines=1 if @lines<1 super(0,0,480,32+(@lines*32)) self.contents=Bitmap.new(self.width-32,self.height-32) refresh end def refresh self.contents.clear self.contents.font.color = Color.new(0,0,0) textmsg=@text.clone x=y=0 while ((c = textmsg.slice!(/\\S*\\s?/m)) != nil) break if c=="" textwidth=self.contents.text_size(c).width if c=="\\n" # Add 1 to y y += 1 x = 0 next end if x>0 && x+textwidth>=self.contents.width # Add 1 to y y += 1 x = 0 end # Draw text self.contents.draw_text(4 + x, 32 * y, textwidth, 32, c) # Add x to drawn text width x += textwidth end end end class PokeBattle_DebugScene def initialize @battle=nil @lastcmd=[0,0,0,0] @lastmove=[0,0,0,0] @pkmnwindows=[nil,nil,nil,nil] end def pbDisplayMessage(msg) pbRefresh cw = Window_SimpleText.new(msg,4) cw.y=256 i=0 loop do Graphics.update Input.update cw.update if i==80 cw.dispose return end if Input.trigger?(Input::C) cw.dispose return end i+=1 end end def pbDisplayPausedMessage(msg) cw = Window_SimpleText.new(msg,4) cw.y=256 cw.pause=true loop do Graphics.update Input.update cw.update if Input.trigger?(Input::C) cw.dispose return end end end def pbDisplayConfirmMessage(msg) dw = Window_SimpleText.new(msg,4) dw.y=256 commands=["YES","NO"] cw = Window_Command.new(96, commands) cw.x=384 cw.y=160 cw.index=0 pbRefresh loop do Graphics.update Input.update pbFrameUpdate(cw) if Input.trigger?(Input::B) cw.dispose dw.dispose return false end if Input.trigger?(Input::C) cw.dispose dw.dispose return (cw.index==0)?true:false end end end def pbFrameUpdate(cw) cw.update if cw for i in 0..3 @pkmnwindows[i].update if @pkmnwindows[i] end # @exceptwindow.text="Exceptions: #{$PBDebugExceptions}" # @exceptwindow.update end def pbRefresh for i in 0..3 @pkmnwindows[i].refresh if @pkmnwindows[i] end # @exceptwindow.refresh end def pbBeginCommandPhase # Called whenever a new round begins. end def pbStartBattle(battle) # Called whenever the battle begins @battle=battle @lastcmd=[0,0,0,0] @lastmove=[0,0,0,0] numwindows=battle.doublebattle ? 4 : 2 for i in 0...numwindows @pkmnwindows[i]=Window_Pokemon.new(@battle.battlers[i]) @pkmnwindows[i].y=i*64 end # @exceptwindow=Window_SimpleText.new("Exceptions: 0",1) # @exceptwindow.x=0 # @exceptwindow.y=416 end def pbEndBattle(result) for i in 0..3 @pkmnwindows[i].dispose if @pkmnwindows[i] end # @exceptwindow.dispose end def pbTrainerSendOut(battle,pkmn) pbRefresh end def pbSendOut(battle,pkmn) pbRefresh end def pbTrainerWithdraw(battle,pkmn) pbRefresh end def pbWithdraw(battle,pkmn) pbRefresh end def pbForgetMove(pkmn,move) # Called whenever a Pokémon should forget a move. It # should return -1 if the selection is canceled, or 0 to 3 # to indicate the move to forget. The function should not # allow HM moves to be forgotten. return 0 end def pbBeginAttackPhase end def pbCommandMenu(index) # Use this method to display the list of commands. # Return values: # 0 - Fight # 1 - Pokémon # 2 - Bag # 3 - Run commands=["FIGHT","POKéMON","BAG","RUN"] cw = Window_Command.new(192, commands) cw.x=0 cw.y=256 cw.index=@lastcmd[index] pbRefresh loop do Graphics.update Input.update pbFrameUpdate(cw) if Input.trigger?(Input::C) ret=cw.index cw.dispose @lastcmd[index]=ret return ret end end end def pbPokemonString(pkmn) status="" if pkmn.hp<=0 status=" [FNT]" else case pkmn.status when PBStatuses::SLEEP status=" [SLP]" when PBStatuses::FROZEN status=" [FRZ]" when PBStatuses::BURN status=" [BRN]" when PBStatuses::PARALYSIS status=" [PAR]" when PBStatuses::POISON status=" [PSN]" end end return "#{pkmn.name} (Lv. #{pkmn.level})#{status} HP: #{pkmn.hp}/#{pkmn.totalhp}" end def pbMoveString(move) ret="#{move.name}" typename=PBTypes.getName(move.type) if move.id>0 ret+=" (#{typename}) PP: #{move.pp}/#{move.totalpp}" end return ret end def pbFightMenu(index) # Use this method to display the list of moves for a Pokémon moves=@battle.battlers[index].moves commands=[ pbMoveString(moves[0]), pbMoveString(moves[1]), pbMoveString(moves[2]), pbMoveString(moves[3]) ] cw = Window_Command.new(480, commands) cw.x=0 cw.y=256 cw.index=@lastmove[index] pbRefresh loop do Graphics.update Input.update pbFrameUpdate(cw) if Input.trigger?(Input::B) @lastmove[index]=cw.index cw.dispose return -1 end if Input.trigger?(Input::C) ret=cw.index @lastmove[index]=ret cw.dispose return ret end end end def pbItemMenu(index) # Use this method to display the inventory # The return value is the item chosen, or 0 if the choice was canceled. pbDisplayMessage("Items can't be used here.") return -1 end def pbFirstTarget(index) for i in 0..3 if i!=index && @battle.battlers[i].hp>0 return i end end return -1 end def pbNextTarget(cur,index) return -1 if cur>=3 for i in cur+1..3 if i!=index && @battle.battlers[i].hp>0 return i end end return -1 end def pbPrevTarget(cur,index) return -1 if cur<=0 ret=-1 for i in 0..cur-1 if i!=index && @battle.battlers[i].hp>0 ret=i end end return ret end def pbChooseTarget(index) # Use this method to make the player choose a target # for certain moves in double battles. curwindow=pbFirstTarget(index) if curwindow==-1 raise RuntimeError.new("No targets somehow...") end numwindows=@battle.doublebattle ? 4 : 2 for i in 0...numwindows @pkmnwindows[i].highlighted=(i==curwindow) end pbRefresh loop do Graphics.update Input.update pbFrameUpdate(nil) if Input.trigger?(Input::DOWN) newwindow=pbNextTarget(curwindow,index) if newwindow>=0 curwindow=newwindow for i in 0...numwindows @pkmnwindows[i].highlighted=(i==curwindow) end end end if Input.trigger?(Input::UP) newwindow=pbPrevTarget(curwindow,index) if newwindow>=0 curwindow=newwindow for i in 0...numwindows @pkmnwindows[i].highlighted=(i==curwindow) end end end if Input.trigger?(Input::B) for i in 0...numwindows @pkmnwindows[i].highlighted=false @pkmnwindows[i].update end return -1 end if Input.trigger?(Input::C) for i in 0...numwindows @pkmnwindows[i].highlighted=false @pkmnwindows[i].update end return curwindow end end end def pbSwitch(index,lax,cancancel) party=@battle.pbParty(index) commands=[] inactives=[1,1,1,1,1,1] partypos=[] activecmd=0 numactive=(@doublebattle)?2:1 battler=@battle.battlers[0] commands[commands.length]=pbPokemonString(party[battler.pokemonIndex]) activecmd=0 if battler.index==index inactives[battler.pokemonIndex]=0 partypos[partypos.length]=battler.pokemonIndex if @battle.doublebattle battler=@battle.battlers[2] commands[commands.length]=pbPokemonString(party[battler.pokemonIndex]) activecmd=1 if battler.index==index inactives[battler.pokemonIndex]=0 partypos[partypos.length]=battler.pokemonIndex end for i in 0..party.length-1 if inactives[i]==1 commands[commands.length]=pbPokemonString(party[i]) partypos[partypos.length]=i end end for i in 0..3 @pkmnwindows[i].visible=false if @pkmnwindows[i] end cw = Window_Command.new(480, commands) cw.x=0 cw.y=0 cw.index=activecmd pbRefresh ret=0 loop do Graphics.update Input.update pbFrameUpdate(cw) if cancancel && Input.trigger?(Input::B) ret=-1 cw.dispose break end if Input.trigger?(Input::C) pkmnindex=partypos[cw.index] canswitch=lax ? @battle.pbCanSwitchLax?(index,pkmnindex,true) : @battle.pbCanSwitch?(index,pkmnindex,true) if canswitch ret=pkmnindex cw.dispose break end end end for i in 0..3 @pkmnwindows[i].visible=true if @pkmnwindows[i] end return ret end def pbHPChanged(pkmn,oldhp) # This method is called whenever a Pokémon's HP changes. # Used to animate the HP bar. hpchange=pkmn.hp-oldhp if hpchange<0 hpchange=-hpchange PBDebug.log("[#{pkmn.pbThis} lost #{hpchange} HP, now has #{pkmn.hp} HP]") else PBDebug.log("[#{pkmn.pbThis} gained #{hpchange} HP, now has #{pkmn.hp} HP]") end pbRefresh end def pbFainted(pkmn) # This method is called whenever a Pokémon faints end def pbChooseEnemyCommand(index) if !@battle.pbCanShowFightMenu?(index) @battle.pbAutoChooseMove(index) return end return if @battle.pbEnemyShouldWithdraw?(index) return if @battle.pbEnemyShouldUseItem?(index) return if @battle.pbAutoFightMenu(index) @battle.pbChooseMoves(index) end def pbChooseNewEnemy(index,party) # Use this method to choose a new Pokémon for the enemy # The enemy's party is guaranteed to have at least one choosable member. for i in 0..party.length-1 return i if @battle.pbCanSwitchLax?(index,i,false) end return -1 end def pbWildBattleSuccess # This method is called when the player wins a wild Pokémon battle. # This method can change the battle's music for example. end def pbTrainerBattleSuccess # This method is called when the player wins a Trainer battle. # This method can change the battle's music for example. end def pbEXPBar(battler,thispoke,startexp,endexp,tempexp1,tempexp2) end def pbLevelUp(battler,thispoke,oldtotalhp,oldattack, olddefense,oldspeed,oldspatk,oldspdef) end def pbShowOpponent(opp) end def pbHideOpponent end def pbRecall(battlerindex) end def pbDamageAnimation(pkmn,effectiveness) end def pbAnimation(moveid,attacker,opponent,side=true) if attacker if opponent PBDebug.log("[pbAnimation (#{attacker.pbThis}, #{opponent.pbThis}]") else PBDebug.log("[pbAnimation (#{attacker.pbThis}]") end else PBDebug.log("[pbAnimation]") end end end class PokeBattle_DebugSceneNoGraphics def initialize @battle=nil @lastcmd=[0,0,0,0] @lastmove=[0,0,0,0] end def pbDisplayMessage(msg,brief=false) end def pbDisplayPausedMessage(msg) end def pbDisplayConfirmMessage(msg) return true end def pbBeginCommandPhase # Called whenever a new round begins. end def pbStartBattle(battle) # Called whenever the battle begins @battle=battle @lastcmd=[0,0,0,0] @lastmove=[0,0,0,0] end def pbEndBattle(result) end def pbTrainerSendOut(battle,pkmn) end def pbSendOut(battle,pkmn) end def pbTrainerWithdraw(battle,pkmn) end def pbWithdraw(battle,pkmn) end def pbForgetMove(pkmn,move) # Called whenever a Pokémon should forget a move. It # should return -1 if the selection is canceled, or 0 to 3 # to indicate the move to forget. The function should not # allow HM moves to be forgotten. return 0 end def pbBeginAttackPhase end def pbCommandMenu(index) return 0 end def pbFightMenu(index) return 0 end def pbItemMenu(index) return -1 end def pbChooseTarget(index) return -1 end def pbRefresh end def pbSwitch(index,lax,cancancel) return -1 end def pbHPChanged(pkmn,oldhp) # This method is called whenever a Pokémon's HP changes. # Used to animate the HP bar. hpchange=pkmn.hp-oldhp if hpchange<0 hpchange=-hpchange PBDebug.log("[#{pkmn.pbThis} lost #{hpchange} HP, now has #{pkmn.hp} HP]") else PBDebug.log("[#{pkmn.pbThis} gained #{hpchange} HP, now has #{pkmn.hp} HP]") end pbRefresh end def pbFainted(pkmn) # This method is called whenever a Pokémon faints end def pbChooseEnemyCommand(index) if !@battle.pbCanShowFightMenu?(index) @battle.pbAutoChooseMove(index) return end return if @battle.pbEnemyShouldWithdraw?(index) return if @battle.pbEnemyShouldUseItem?(index) return if @battle.pbAutoFightMenu(index) @battle.pbChooseMoves(index) end def pbChooseNewEnemy(index,party) # Use this method to choose a new Pokémon for the enemy # The enemy's party is guaranteed to have at least one choosable member. for i in 0..party.length-1 return i if @battle.pbCanSwitchLax?(index,i,false) end return -1 end def pbWildBattleSuccess # This method is called when the player wins a wild Pokémon battle. # This method can change the battle's music for example. end def pbTrainerBattleSuccess # This method is called when the player wins a Trainer battle. # This method can change the battle's music for example. end def pbEXPBar(battler,thispoke,startexp,endexp,tempexp1,tempexp2) end def pbLevelUp(battler,thispoke,oldtotalhp,oldattack, olddefense,oldspeed,oldspatk,oldspdef) end def pbShowOpponent(opp) end def pbHideOpponent end def pbRecall(battlerindex) end def pbDamageAnimation(pkmn,effectiveness) end def pbCommonAnimation(moveid,attacker,opponent,side=true) if attacker if opponent PBDebug.log("[pbCommonAnimation #{moveid} (#{attacker.pbThis}, #{opponent.pbThis}]") else PBDebug.log("[pbCommonAnimation #{moveid} (#{attacker.pbThis}]") end else PBDebug.log("[pbCommonAnimation #{moveid}]") end end def pbAnimation(moveid,attacker,opponent,side=true) if attacker if opponent PBDebug.log("[pbAnimation (#{attacker.pbThis}, #{opponent.pbThis}]") else PBDebug.log("[pbAnimation (#{attacker.pbThis}]") end else PBDebug.log("[pbAnimation]") end end end
PokeBattle_SafariZone
[
Selecionar
] [
-
]
class PokeBattle_FakeBattler def initialize(pokemon,index) @pokemon=pokemon @index=index end def pokemon; @pokemon; end def species; @pokemon.species; end def gender; @pokemon.gender; end def status; @pokemon.status; end def hp; @pokemon.hp; end def level; @pokemon.level; end def name; @pokemon.name; end def totalhp; @pokemon.totalhp; end def index return @index end def pbThis return _INTL("Wild {1}",@pokemon.name) end end class PokeBattle_SafariZone attr_accessor :environment attr_accessor :party1 attr_accessor :party2 attr_reader :player include PokeBattle_BattleCommon def initialize(scene,player,party2) @scene=scene @party2=party2 @player=player @battlers=[ PokeBattle_FakeBattler.new(party2[0],0), PokeBattle_FakeBattler.new(party2[0],1), PokeBattle_FakeBattler.new(party2[0],2), PokeBattle_FakeBattler.new(party2[0],3) ] @decision=0 @ballcount=0 @environment=PBEnvironment::None end def battlers; return @battlers; end def opponent; return nil; end def doublebattle; return false; end def ballcount return (@ballcount<0) ? 0 : @ballcount end def ballcount=(value) @ballcount=(value<0) ? 0 : value end def pbPlayer return @player end class BattleAbortedException < Exception end def pbAbort raise BattleAbortedException.new("Battle aborted") end def pbEscapeRate(rareness) ret=25 ret=50 if rareness<200 ret=75 if rareness<150 ret=100 if rareness<100 ret=125 if rareness<25 return ret end def pbStartBattle begin wildpoke=@party2[0] self.pbPlayer.seen[wildpoke.species]=true @scene.pbStartBattle(self) pbDisplayPaused(_INTL("Wild {1} appeared!",wildpoke.name)) @scene.pbSafariStart dexdata=pbOpenDexData pbDexDataOffset(dexdata,wildpoke.species,16) rareness=dexdata.fgetb # Get rareness from dexdata file dexdata.close g=(rareness*100)/1275 e=(pbEscapeRate(rareness)*100)/1275 g=[[g,3].max,20].min e=[[e,3].max,20].min lastCommand=0 begin cmd=@scene.pbSafariCommandMenu(0) case cmd when 2 # Bait pbDisplay(_INTL("{1} threw bait at the wild {2}!",self.pbPlayer.name,wildpoke.name)) g/=2 # Harder to catch e/=2 # Less likely to escape g=[[g,3].max,20].min e=[[e,3].max,20].min lastCommand=1 when 1 # Rock pbDisplay(_INTL("{1} threw a rock at the wild {2}!",self.pbPlayer.name,wildpoke.name)) g*=2 # Easier to catch e*=2 # More likely to escape g=[[g,3].max,20].min e=[[e,3].max,20].min lastCommand=2 when 0 # Ball if pbBoxesFull? pbDisplay(_INTL("The boxes are full! You can't catch any more Pokémon!")) next end @ballcount-=1 rare=(g*1275)/100 pbThrowPokeBall(PBItems::SAFARIBALL,rare) when 3 # Run pbDisplayPaused(_INTL("Got away safely!")) @decision=3 end if @decision==0 if @ballcount<=0 pbDisplay(_INTL("PA: You have no Safari Balls left! Game over!")) @decision=2 elsif pbRandom(100)<5*e pbDisplay(_INTL("Wild {1} fled!",wildpoke.name)) @decision=3 elsif lastCommand==1 pbDisplay(_INTL("Wild {1} is eating!",wildpoke.name)) elsif lastCommand==2 pbDisplay(_INTL("Wild {1} is angry!",wildpoke.name)) else pbDisplay(_INTL("Wild {1} is watching carefully!",wildpoke.name)) end end end while @decision==0 @scene.pbEndBattle(@decision) rescue BattleAbortedException @decision=0 @scene.pbEndBattle(@decision) end return @decision end ############# def pbDebugUpdate @debugupdate+=1 if @debugupdate==30 # Graphics.update @debugupdate=0 end end def pbDisplayPaused(msg) if @debug pbDebugUpdate PBDebug.log(msg) else @scene.pbDisplayPausedMessage(msg) end end def pbDisplay(msg) if @debug pbDebugUpdate PBDebug.log(msg) else @scene.pbDisplayMessage(msg) end end def pbDisplayBrief(msg) if @debug pbDebugUpdate PBDebug.log(msg) else @scene.pbDisplayMessage(msg,true) end end def pbDisplayConfirm(msg) if @debug pbDebugUpdate PBDebug.log(msg) return true else return @scene.pbDisplayConfirmMessage(msg) end end def pbAIRandom(x) return rand(x) end def pbRandom(x) return rand(x) end end
PokemonMessages
[
Selecionar
] [
-
]
######### class Game_Temp attr_writer :message_window_showing attr_writer :player_transferring attr_writer :transition_processing def message_window_showing @message_window_showing=false if !@message_window_showing return @message_window_showing end def player_transferring @player_transferring=false if !@player_transferring return @player_transferring end def transition_processing @transition_processing=false if !@transition_processing return @transition_processing end end class Game_System attr_writer :message_position def message_position @message_position=2 if !@message_position return @message_position end end ######### class Scene_Map def updatemini oldmws=$game_temp.message_window_showing $game_temp.message_window_showing=true loop do $game_map.update $game_player.update $game_system.update if $game_screen $game_screen.update else $game_map.screen.update end unless $game_temp.player_transferring break end transfer_player if $game_temp.transition_processing break end end $game_temp.message_window_showing=oldmws @spriteset.update if @spriteset @message_window.update if @message_window end end class Scene_Battle def updatemini if self.respond_to?("update_basic") update_basic(true) update_info_viewport # Update information viewport if $game_message.visible @info_viewport.visible = false @message_window.visible = true end else oldmws=$game_temp.message_window_showing $game_temp.message_window_showing=true # Update system (timer) and screen $game_system.update if $game_screen $game_screen.update else $game_map.screen.update end # If timer has reached 0 if $game_system.timer_working and $game_system.timer == 0 # Abort battle $game_temp.battle_abort = true end # Update windows @help_window.update @party_command_window.update @actor_command_window.update @status_window.update $game_temp.message_window_showing=oldmws @message_window.update # Update sprite set @spriteset.update end end end def pbRefreshSceneMap if $scene && $scene.is_a?(Scene_Map) if $scene.respond_to?("miniupdate") $scene.miniupdate else $scene.updatemini end elsif $scene && $scene.is_a?(Scene_Battle) $scene.updatemini end end def pbUpdateSceneMap if $scene && $scene.is_a?(Scene_Map) && !pbIsFaded? if $scene.respond_to?("miniupdate") $scene.miniupdate else $scene.updatemini end elsif $scene && $scene.is_a?(Scene_Battle) $scene.updatemini end end ######### module PokemonSkins def self.getDefaultTextSkin return MessageConfig::TextSkinName end end def pbCsvField!(str) ret="" str.sub!(/^\\s*/,"") if str[0,1]=="\\"" str[0,1]="" escaped=false fieldbytes=0 str.scan(/./) do |s| fieldbytes+=s.length break if s=="\\"" && !escaped if s=="\\\\" && !escaped escaped=true else ret+=s escaped=false end end str[0,fieldbytes]="" if !str[/^\\s*,/] && !str[/^\\s*$/] raise _INTL("Invalid quoted field (in: {1})",ret) end str[0,str.length]=$~.post_match else if str[/,/] str[0,str.length]=$~.post_match ret=$~.pre_match else ret=str.clone str[0,str.length]="" end ret.gsub!(/\\s+$/,"") end return ret end def pbCsvPosInt!(str) ret=pbCsvField!(str) if !ret[/^\\d+$/] raise _INTL("Field {1} is not a positive integer",ret) end return ret.to_i end def pbEventCommentInput(*args) parameters = [] list = *args[0].list # Event or event page elements = *args[1] # Number of elements trigger = *args[2] # Trigger return nil if list == nil return nil unless list.is_a?(Array) for item in list next unless item.code == 108 || item.code == 408 if item.parameters[0] == trigger start = list.index(item) + 1 finish = start + elements for id in start...finish next if !list[id] parameters.push(list[id].parameters[0]) end return parameters end end return nil end def pbCurrentEventCommentInput(elements,trigger) return nil return nil if !$game_system || !$game_system.map_interpreter.running? event=$game_system.map_interpreter.get_character(0) return nil if !event return pbEventCommentInput(event,elements,trigger) end module InterpreterMixin def pbGlobalLock for event in $game_map.events.values event.minilock end end def pbGlobalUnlock for event in $game_map.events.values event.unlock end end def pbRepeatAbove(index) index=@list[index].indent loop do index-=1 if @list[index].indent==indent return index+1 end end end def pbBreakLoop(index) indent = @list[index].indent temp_index=index # Copy index to temporary variables loop do # Advance index temp_index += 1 # If a fitting loop was not found if temp_index >= @list.size-1 return index+1 end if @list[temp_index].code == 413 and @list[temp_index].indent < indent return temp_index+1 end end end def pbJumpToLabel(index,label_name) temp_index = 0 loop do if temp_index >= @list.size-1 return index+1 end if @list[temp_index].code == 118 and @list[temp_index].parameters[0] == label_name return temp_index+1 end temp_index += 1 end end # Gets the next index in the interpreter, ignoring # certain events between messages def pbNextIndex(index) return -1 if !@list || @list.length==0 i=index+1 loop do if i>=@list.length-1 return i end code=@list[i].code case code when 118, 108, 408 # Label, Comment i+=1 when 413 # Repeat Above i=pbRepeatAbove(i) when 113 # Break Loop i=pbBreakLoop(i) when 115 # Exit Event Processing i=-1 when 119 # Jump to Label i=pbJumpToLabel(i,@list[i].parameters[0]) else return i end end end # Helper function that shows a picture in a script. To be used in # a script event command. def pbShowPicture(number,name,origin,x,y,zoomX=100,zoomY=100,opacity=255,blendType=0) number = number + ($game_temp.in_battle ? 50 : 0) $game_screen.pictures[number].show(name,origin, x, y, zoomX,zoomY,opacity,blendType) end # Erases an event and adds it to the list of erased events so that # it can stay erased when the game is saved then loaded again. To be used in # a script event command. def pbEraseThisEvent $game_map.events[@event_id].erase $PokemonMap.addErasedEvent(@event_id) if $PokemonMap @index+=1 return true end # Runs a common event. To be used in # a script event command. def pbCommonEvent(id) if $game_temp.in_battle $game_temp.common_event_id = id else commonEvent = $data_common_events[id] $game_system.battle_interpreter.setup(commonEvent.list, 0) end end # Sets another event's self switch (eg. pbSetSelfSwitch(20,"A",true)). To be used in # a script event command. def pbSetSelfSwitch(event,swtch,value) $game_self_switches[[@map_id,event,swtch]]=value $game_map.need_refresh = true end # Used in boulder events. Allows an event to be pushed. To be used in # a script event command. def pbPushThisEvent event=get_character(0) oldx=event.x oldy=event.y # Apply strict version of passable, which makes impassable # tiles that are passable only from certain directions if !event.passableStrict?(event.x,event.y,$game_player.direction) return end case $game_player.direction when 2 # down event.move_down when 4 # left event.move_left when 6 # right event.move_right when 8 # up event.move_up end $PokemonMap.addMovedEvent(@event_id) if $PokemonMap if oldx!=event.x || oldy!=event.y $game_player.lock begin Graphics.update Input.update pbUpdateSceneMap end until !event.moving? $game_player.unlock end end end def pbButtonInputProcessing(variableNumber=0,timeoutFrames=0) msgwindow=Kernel.pbCreateMessageWindow skinfile=PokemonSkins.getDefaultTextSkin pbLoadSkin(msgwindow,"Graphics/Windowskins/#{skinfile}") Kernel.pbDisplayMessageFancy(msgwindow,_INTL("<ac>PRESS ANY CONTROL KEY"),nil,0) ret=0 loop do Graphics.update Input.update pbUpdateSceneMap n = 0 for i in 1..18 if Input.trigger?(i) n = i ret=n end end break if ret!=0 if timeoutFrames && timeoutFrames>0 i+=1 break if i>=timeoutFrames end end Kernel.pbDisposeMessageWindow(msgwindow) Input.update if variableNumber && variableNumber>0 $game_variables[variableNumber]=ret end return ret end class Game_Interpreter include InterpreterMixin def command_105 pbButtonInputProcessing(@list[@index].parameters[0]) @index+=1 end def command_101 if $game_temp.message_window_showing return false end message="" commands=nil numInputVar=nil numInputDigitsMax=nil text="" facename=@list[@index].parameters[0] faceindex=@list[@index].parameters[1] if facename && facename!="" text+="\\\\ff[#{facename},#{faceindex}]" end $game_message.background=@list[@index].parameters[2] $game_system.message_position=@list[@index].parameters[3] message+=text messageend="" loop do nextIndex=pbNextIndex(@index) code=@list[nextIndex].code if code == 401 text=@list[nextIndex].parameters[0] text+=" " if text[text.length-1,1]!=" " message+=text @index=nextIndex else if code == 102 commands=@list[nextIndex].parameters @index=nextIndex elsif code == 103 numInputVar=@list[nextIndex].parameters[0] numInputDigitsMax=@list[nextIndex].parameters[1] @index=nextIndex elsif code == 101 messageend="\\1" end break end end message=_MAPINTL($game_map.map_id,message) defaultskin=PokemonSkins.getDefaultTextSkin if commands cmdlist=[] for cmd in commands[0] cmdlist.push(_MAPINTL($game_map.map_id,cmd)) end command=Kernel.pbMessage(message+messageend,cmdlist,commands[1],defaultskin) @branch[@list[@index].indent] = command elsif numInputVar Kernel.pbMessageChooseNumberVarNew(message+messageend,numInputVar,numInputDigitsMax,defaultskin) else Kernel.pbMessage(message+messageend,nil,0,defaultskin) end return true end def command_102 command=Kernel.pbShowCommands(nil,@list[@index].parameters[0],@list[@index].parameters[1]) @branch[@list[@index].indent] = command Input.update # Must call Input.update again to avoid extra triggers return true end def command_103 varnumber=@list[@index].parameters[0] $game_variables[varnumber]=Kernel.pbChooseNumberNew(nil,$game_variables[varnumber],@list[@index].parameters[1]) Input.update # Must call Input.update again to avoid extra triggers return true end end class Interpreter include InterpreterMixin def command_105 pbButtonInputProcessing(@list[@index].parameters[0]) @index+=1 end def command_101 if $game_temp.message_window_showing return false end message="" commands=nil numInputVar=nil numInputDigitsMax=nil text="" if @list[@index].parameters.length==1 text+=@list[@index].parameters[0] text+=" " if text[text.length-1,1]!=" " message+=text else facename=@list[@index].parameters[0] faceindex=@list[@index].parameters[1] if facename && facename!="" text+="\\\\ff[#{facename},#{faceindex}]" message+=text end end messageend="" loop do nextIndex=pbNextIndex(@index) code=@list[nextIndex].code if code == 401 text=@list[nextIndex].parameters[0] text+=" " if text[text.length-1,1]!=" " message+=text @index=nextIndex else if code == 102 commands=@list[nextIndex].parameters @index=nextIndex elsif code == 103 numInputVar=@list[nextIndex].parameters[0] numInputDigitsMax=@list[nextIndex].parameters[1] @index=nextIndex elsif code == 101 messageend="\\1" end break end end message=_MAPINTL($game_map.map_id,message) defaultskin=PokemonSkins.getDefaultTextSkin if commands cmdlist=[] for cmd in commands[0] cmdlist.push(_MAPINTL($game_map.map_id,cmd)) end command=Kernel.pbMessage(message+messageend,cmdlist,commands[1],defaultskin) @branch[@list[@index].indent] = command elsif numInputVar Kernel.pbMessageChooseNumberVarNew(message+messageend,numInputVar,numInputDigitsMax,defaultskin) else Kernel.pbMessage(message+messageend,nil,0,defaultskin) end return true end def command_102 command=Kernel.pbShowCommands(nil,@list[@index].parameters[0],@list[@index].parameters[1]) @branch[@list[@index].indent] = command Input.update # Must call Input.update again to avoid extra triggers return true end def command_103 varnumber=@list[@index].parameters[0] $game_variables[varnumber]=Kernel.pbChooseNumberNew(nil,$game_variables[varnumber],@list[@index].parameters[1]) Input.update # Must call Input.update again to avoid extra triggers return true end end def pbEventFacesPlayer?(event,player,distance) return false if distance<=0 # Event can't reach player if no coordinates coincide return false if event.x!=player.x && event.y!=player.y deltaX = (event.direction == 6 ? 1 : event.direction == 4 ? -1 : 0) deltaY = (event.direction == 2 ? 1 : event.direction == 8 ? -1 : 0) # Check for existence of player curx=event.x cury=event.y found=false for i in 0...distance curx+=deltaX cury+=deltaY if player.x==curx && player.y==cury found=true break end end return found end def pbEventCanReachPlayer?(event,player,distance) return false if distance<=0 # Event can't reach player if no coordinates coincide return false if event.x!=player.x && event.y!=player.y deltaX = (event.direction == 6 ? 1 : event.direction == 4 ? -1 : 0) deltaY = (event.direction == 2 ? 1 : event.direction == 8 ? -1 : 0) # Check for existence of player curx=event.x cury=event.y found=false realdist=0 for i in 0...distance curx+=deltaX cury+=deltaY if player.x==curx && player.y==cury found=true break end realdist+=1 end return false if !found # Check passibility curx=event.x cury=event.y for i in 0...realdist if !event.passable?(curx,cury,event.direction) return false end curx+=deltaX cury+=deltaY end return true end def Kernel.pbChooseNumberNew(msgwindow,defaultNum,maxDigits,maxnum=nil,sign=false) ret=0 maximum=maxnum ? maxnum : (10**maxDigits)-1 cmdwindow=Window_InputNumberPokemon.new(maxDigits) cmdwindow.z=99999 cmdwindow.visible=true cmdwindow.sign=sign cmdwindow.number=defaultNum curnumber=defaultNum curnumber=0 if !curnumber pbPositionNearMsgWindow(cmdwindow,msgwindow,:right) command=0 loop do Graphics.update Input.update pbUpdateSceneMap cmdwindow.update if Input.trigger?(Input::C) ret=cmdwindow.number break elsif Input.trigger?(Input::B) ret=defaultNum ret=0 if !defaultNum break end end cmdwindow.dispose return ret end def numDigits(number) ans = 1 number=number.abs while number >= 10 ans+=1 number/=10; end return ans end def Kernel.pbChooseNumberEx(msgwindow,initialNumber,minNumber,maxNumber,cancelNumber) ret=0 return cancelNumber if minNumber>maxNumber maxDigits=numDigits(maxNumber) cmdwindow=Window_UnformattedTextPokemon.new("0"*maxDigits) cmdwindow.z=99999 cmdwindow.visible=true cmdwindow.resizeToFit(cmdwindow.text,Graphics.width) initialNumber=minNumber if initialNumber<minNumber initialNumber=maxNumber if initialNumber>maxNumber cmdwindow.text=sprintf("%0*d",maxDigits,initialNumber) curnumber=initialNumber curnumber=minNumber if !curnumber pbPositionNearMsgWindow(cmdwindow,msgwindow,:right) command=0 loop do Graphics.update Input.update pbUpdateSceneMap if Input.repeat?(Input::LEFT) curnumber-=10 curnumber=minNumber if curnumber<minNumber cmdwindow.text=sprintf("%0*d",maxDigits,curnumber) elsif Input.repeat?(Input::RIGHT) curnumber+=10 curnumber=maxNumber if curnumber>maxNumber cmdwindow.text=sprintf("%0*d",maxDigits,curnumber) elsif Input.repeat?(Input::UP) curnumber+=1 curnumber=minNumber if curnumber>maxNumber cmdwindow.text=sprintf("%0*d",maxDigits,curnumber) elsif Input.repeat?(Input::DOWN) curnumber-=1 curnumber=maxNumber if curnumber<minNumber cmdwindow.text=sprintf("%0*d",maxDigits,curnumber) elsif Input.trigger?(Input::C) ret=curnumber break elsif Input.trigger?(Input::B) ret=cancelNumber break end cmdwindow.update end cmdwindow.dispose return ret end def Kernel.pbChooseNumber(msgwindow,defaultNum,maxDigits,maxnum=nil) maximum=maxnum ? maxnum : (10**maxDigits)-1 return Kernel.pbChooseNumberEx(msgwindow,defaultNum,0,maximum,defaultNum) end def pbPositionNearMsgWindow(cmdwindow,msgwindow,side) return if !cmdwindow if msgwindow height=[cmdwindow.height,Graphics.height-msgwindow.height].min if cmdwindow.height!=height cmdwindow.height=height end cmdwindow.y=msgwindow.y-cmdwindow.height if cmdwindow.y<0 cmdwindow.y=msgwindow.y+msgwindow.height if cmdwindow.y+cmdwindow.height>Graphics.height cmdwindow.y=msgwindow.y-cmdwindow.height end end case side when :left cmdwindow.x=msgwindow.x when :right cmdwindow.x=msgwindow.x+msgwindow.width-cmdwindow.width else cmdwindow.x=msgwindow.x+msgwindow.width-cmdwindow.width end else cmdwindow.height=Graphics.height if cmdwindow.height>Graphics.height cmdwindow.x=0 cmdwindow.y=0 end end def Kernel.pbShowCommands(msgwindow,commands=nil,cmdIfCancel=0) ret=0 if commands cmdwindow=Window_CommandPokemonEx.new(commands) cmdwindow.z=99999 cmdwindow.visible=true cmdwindow.resizeToFit(cmdwindow.commands) pbPositionNearMsgWindow(cmdwindow,msgwindow,:right) command=0 loop do Graphics.update Input.update if Input.trigger?(Input::B) if cmdIfCancel>0 command=cmdIfCancel-1 break elsif cmdIfCancel<0 command=cmdIfCancel break end end if Input.trigger?(Input::C) command=cmdwindow.index break end pbUpdateSceneMap cmdwindow.update end ret=command cmdwindow.dispose end return ret end def pbGetMapNameFromId(id) begin map = pbLoadRxData("Data/MapInfos") return "" if !map return map[id].name rescue return "" end end def pbLoadSkin(window,skin) skinbase=skin.sub(/\\.....?$/,"") bitmap=Bitmap.new(skinbase+".png") if (bitmap.width==192 && bitmap.height==128) || # RPGXP Windowskin (bitmap.width==128 && bitmap.height==128) # RPGVX Windowskin window.skinformat=0 window.setSkin(skinbase+".png") else window.skinformat=1 window.setSkin(skinbase+".png") window.loadSkinFile("#{skinbase}.txt") end bitmap.dispose end def Kernel.pbMessage(message,commands=nil,cmdIfCancel=0,skin=nil) ret=0 msgwindow=Kernel.pbCreateMessageWindow if skin pbLoadSkin(msgwindow,"Graphics/Windowskins/#{skin}") else skinfile=PokemonSkins.getDefaultTextSkin pbLoadSkin(msgwindow,"Graphics/Windowskins/#{skinfile}") end if commands ret=Kernel.pbDisplayMessageFancy(msgwindow,message,-1,0,commands,cmdIfCancel,true) else Kernel.pbDisplayMessageFancy(msgwindow,message,-1,-1,nil,nil,true) end Kernel.pbDisposeMessageWindow(msgwindow) Input.update return ret end def Kernel.pbMessageBrief(message) msgwindow=Kernel.pbCreateMessageWindow Audio.se_play(pbGetDecisionSE) skinfile=PokemonSkins.getDefaultTextSkin pbLoadSkin(msgwindow,"Graphics/Windowskins/#{skinfile}") Kernel.pbDisplayMessageFancy(msgwindow,message,-1,0,nil,nil,true) Kernel.pbDisposeMessageWindow(msgwindow) Input.update end def Kernel.pbMessageSound(message,se) msgwindow=Kernel.pbCreateMessageWindow skinfile=PokemonSkins.getDefaultTextSkin pbLoadSkin(msgwindow,"Graphics/Windowskins/#{skinfile}") Kernel.pbDisplayMessageFancy(msgwindow,message,-1,0,nil,nil,false) Audio.se_play(se) if se Kernel.pbDisplayMessageFancy(msgwindow,message,nil,60) Kernel.pbDisposeMessageWindow(msgwindow) Input.update end def Kernel.pbMessageChooseNumber(message,defNumber,maxDigits,skin=nil,maxnumber=nil) msgwindow=Kernel.pbCreateMessageWindow skin=PokemonSkins.getDefaultTextSkin if !skin pbLoadSkin(msgwindow,"Graphics/Windowskins/#{skin}") if skin Kernel.pbDisplayMessageFancy(msgwindow,message,-1,0,nil,nil,true) ret=Kernel.pbChooseNumber(msgwindow,defNumber,maxDigits,maxnumber) Kernel.pbDisposeMessageWindow(msgwindow) Input.update return ret end def Kernel.pbMessageChooseNumberEx(message,initialNum,minNum,maxNum,cancelNum,skin=nil) msgwindow=Kernel.pbCreateMessageWindow skin=PokemonSkins.getDefaultTextSkin if !skin pbLoadSkin(msgwindow,"Graphics/Windowskins/#{skin}") Kernel.pbDisplayMessageFancy(msgwindow,message,-1,0,nil,nil,true) ret=Kernel.pbChooseNumberEx(msgwindow,initialNum,minNum,maxNum,cancelNum) Kernel.pbDisposeMessageWindow(msgwindow) Input.update return ret end def Kernel.pbMessageChooseNumberNew(message,defNumber,maxDigits,skin=nil,maxnumber=nil) msgwindow=Kernel.pbCreateMessageWindow skin=PokemonSkins.getDefaultTextSkin if !skin pbLoadSkin(msgwindow,"Graphics/Windowskins/#{skin}") Kernel.pbDisplayMessageFancy(msgwindow,message,-1,0,nil,nil,true) ret=Kernel.pbChooseNumberNew(msgwindow,defNumber,maxDigits,maxnumber) Kernel.pbDisposeMessageWindow(msgwindow) Input.update return ret end def Kernel.pbMessageChooseNumberVar(message,variable,maxDigits,skin=nil) msgwindow=Kernel.pbCreateMessageWindow skin=PokemonSkins.getDefaultTextSkin if !skin pbLoadSkin(msgwindow,"Graphics/Windowskins/#{skin}") Kernel.pbDisplayMessageFancy(msgwindow,message,-1,0,nil,nil,true) ret=Kernel.pbChooseNumber(msgwindow,$game_variables[variable],maxDigits) $game_variables[variable]=ret Kernel.pbDisposeMessageWindow(msgwindow) Input.update end def Kernel.pbMessageChooseNumberVarNew(message,variable,maxDigits,skin=nil) msgwindow=Kernel.pbCreateMessageWindow skin=PokemonSkins.getDefaultTextSkin if !skin pbLoadSkin(msgwindow,"Graphics/Windowskins/#{skin}") Kernel.pbDisplayMessageFancy(msgwindow,message,-1,0,nil,nil,true) ret=Kernel.pbChooseNumberNew(msgwindow,$game_variables[variable],maxDigits) $game_variables[variable]=ret Kernel.pbDisposeMessageWindow(msgwindow) Input.update end def Kernel.pbConfirmMessage(message) return (Kernel.pbMessage(message,[_INTL("YES"),_INTL("NO")],2)==0) end def Kernel.pbConfirmMessageSerious(message) return (Kernel.pbMessage(message,[_INTL("NO"),_INTL("YES")],1)==1) end def Kernel.pbCreateStatusWindow(viewport=nil) msgwindow=Window_AdvancedTextPokemon.new("") if !viewport msgwindow.z=99999 else msgwindow.viewport=viewport end msgwindow.visible=false msgwindow.letterbyletter=false pbBottomLeftLines(msgwindow,2) skinfile=PokemonSkins.getDefaultTextSkin pbLoadSkin(msgwindow,"Graphics/Windowskins/#{skinfile}") return msgwindow end def Kernel.pbCreateMessageWindow(viewport=nil) msgwindow=Window_AdvancedTextPokemon.new("") if !viewport msgwindow.z=99999 else msgwindow.viewport=viewport end msgwindow.visible=true msgwindow.letterbyletter=true msgwindow.back_opacity=MessageConfig::WindowOpacity pbBottomLeftLines(msgwindow,2) $game_temp.message_window_showing=true if $game_temp return msgwindow end def Kernel.pbDisposeMessageWindow(msgwindow) $game_temp.message_window_showing=false if $game_temp msgwindow.dispose end def pbRepositionMessageWindow if $game_temp && $game_temp.in_battle && !$scene.respond_to?("update_basic") msgwindow.y=0 elsif $game_system && $game_system.respond_to?("message_position") case $game_system.message_position when 0 # up msgwindow.y=0 when 1 # middle msgwindow.y=(Graphics.height/2)-(msgwindow.height/2) when 2 msgwindow.y=(Graphics.height)-(msgwindow.height) end end if $game_system && $game_system.respond_to?("message_frame") if $game_system.message_frame != 0 msgwindow.opacity = 0 end end end def isDarkWindowskin(windowskin) if !windowskin || windowskin.disposed? return true end if windowskin.width==192 && windowskin.height==128 y=8 r=0; g=0; b=0 16.times { x=8 16.times { clr=windowskin.get_pixel(x,y) r+=clr.red; g+=clr.green; b+=clr.blue x+=16 } y+=16 } r/=256 g/=256 b/=256 return (r+g+b)/3<128 elsif windowskin.width==128 && windowskin.height==128 y=4 r=0; g=0; b=0 16.times { x=4 16.times { clr=windowskin.get_pixel(x,y) r+=clr.red; g+=clr.green; b+=clr.blue x+=8 } y+=8 } r/=256 g/=256 b/=256 return (r+g+b)/3<128 else clr=windowskin.get_pixel(windowskin.width/2, windowskin.height/2) return (clr.red+clr.green+clr.blue)/3<128 end end class FaceWindowVX < SpriteWindow_Base def initialize(face) super(0,0,128,128) faceinfo=face.split(",") begin facebitmaptmp=RPG::Cache.load_bitmap("Graphics/Faces/",faceinfo[0]) rescue facebitmaptmp=RPG::Cache.load_bitmap("Graphics/Pictures/",faceinfo[0]) end self.contents.dispose if self.contents faceIndex=faceinfo[1].to_i @facebitmap=Bitmap.new(96,96) @facebitmap.blt(0,0,facebitmaptmp,Rect.new( (faceIndex % 4) * 96, (faceIndex / 4) * 96, 96, 96 )) self.contents=@facebitmap end def dispose @facebitmap.dispose if @facebitmap super end end def itemIconTag(item) return "" if !item if item.respond_to?("icon_name") return sprintf("<icon=%s>",item.icon_name) else ix=item.icon_index % 16 * 24 iy=item.icon_index / 16 * 24 return sprintf("<img=Graphics/System/Iconset|%d|%d|24|24>",ix,iy) end end def getSkinColor(windowskin,color,isDarkSkin) if !windowskin || windowskin.disposed? || windowskin.width!=128 || windowskin.height!=128 textcolors=[ isDarkSkin ? "<c2=7FFF5EF7>" : "<c2=318c675a>", "<c2=7E105D08>", "<c2=421F2117>", "<c2=43F022E8>", "<c2=7FF05EE8>", "<c2=7E1F5D17>", "<c2=43FF22F7>", "<c2=63184210>", "<c2=7FFF5EF7>" ] color=0 if color>textcolors.length return textcolors[color] else # VX windowskin color=0 if color>=32 x = 64 + (color % 8) * 8 y = 96 + (color / 8) * 8 pixel=windowskin.get_pixel(x, y) return shadowctagFromColor(pixel) end end def pbRecord(arg); end def Kernel.pbDisplayMessageFancy( msgwindow,message,textspeed=-1, delay=-1,msgCommands=nil,msgCommandsCancel=-1,sound=false) oldtextspeed=pbGetSystemTextSpeed oldletterbyletter=msgwindow.letterbyletter if textspeed==nil msgwindow.letterbyletter=false elsif textspeed>=0 pbSetSystemTextSpeed(textspeed) end ret=false count=0 commands=nil facewindow=nil goldwindow=nil cmdvariable=0 cmdIfCancel=0 waitcount=0 autoresume=false text=message.clone msgback=nil linecount=(Graphics.height>400) ? 3 : 2 ### Text replacement if $game_actors text.gsub!(/\\\\[Nn]\\[([0-8])\\]/){ m=$1.to_i next $game_actors[m].name } end text.gsub!(/\\\\[Pp][Nn]/,$Trainer.name) if $Trainer text.gsub!(/\\\\[Pp][Mm]/,_INTL("${1}",$Trainer.money)) if $Trainer text.gsub!(/\\\\[Nn]/,"\\n") text.gsub!(/\\\\\\[([0-9A-Fa-f]{8,8})\\]/){ "<c2="+$1+">" } text.gsub!(/\\\\[Bb]/,"<c2=6546675A>") text.gsub!(/\\\\[Rr]/,"<c2=043C675A>") text.gsub!(/\\\\1/,"\\1") colortag="" isDarkSkin=isDarkWindowskin(msgwindow.windowskin) if ($game_message && $game_message.background>0) || ($game_system && $game_system.respond_to?("message_frame") && $game_system.message_frame != 0) colortag=getSkinColor(msgwindow.windowskin,0,true) else colortag=getSkinColor(msgwindow.windowskin,0,isDarkSkin) end text.gsub!(/\\\\[Cc]\\[([0-9]+)\\]/){ m=$1.to_i next getSkinColor(msgwindow.windowskin,m,isDarkSkin) } begin last_text = text.clone text.gsub!(/\\\\[Vv]\\[([0-9]+)\\]/) { $game_variables[$1.to_i] } end until text == last_text begin last_text = text.clone text.gsub!(/\\\\[Ll]\\[([0-9]+)\\]/) { linecount=[1,$1.to_i].max; next "" } end until text == last_text text=colortag+text ### Controls textchunks=[] controls=[] while text[/(?:\\\\([WwFf]|[Ff][Ff]|[Mm][Ee]|[Ss][Ee]|[Ww][Tt]|[Ww][Tt][Nn][Pp]|[Cc][Hh])\\[([^\\]]*)\\]|\\\\([Gg]|[Ww][Dd]|[Ww][Mm]|[Ww][Uu]|[\\.]|[\\|]|[\\!]|[\\x5E])())/i] textchunks.push($~.pre_match) if $~[1] controls.push([$~[1].downcase,$~[2],-1]) else controls.push([$~[3].downcase,"",-1]) end text=$~.post_match end textchunks.push(text) for chunk in textchunks chunk.gsub!(/\\\\\\\\/,"\\\\") end textlen=0 for i in 0...controls.length control=controls[i][0] if control=="wt" || control=="wtnp" || control=="." || control=="|" textchunks[i]+="\\2" elsif control=="!" textchunks[i]+="\\1" end textlen+=toUnformattedText(textchunks[i]).scan(/./m).length controls[i][2]=textlen end text=textchunks.join("") unformattedText=toUnformattedText(text) startSE=sound ? pbGetDecisionSE : nil for i in 0...controls.length control=controls[i][0] param=controls[i][1] if control=="f" facewindow.dispose if facewindow facewindow=PictureWindow.new("Graphics/Pictures/#{param}") elsif control=="se" && controls[i][2]==0 startSE="Audio/SE/#{param}" controls[i]=nil elsif control=="ff" facewindow.dispose if facewindow facewindow=FaceWindowVX.new(param) elsif control=="ch" cmds=param.clone cmdvariable=pbCsvPosInt!(cmds) cmdIfCancel=pbCsvField!(cmds).to_i commands=[] while cmds.length>0 commands.push(pbCsvField!(cmds)) end elsif control=="wtnp" || control=="^" text=text.sub(/\\001$/,"") end end Audio.se_play(startSE) if startSE delay=0 if commands ########## Position message window ############## msgwindow.height=32*linecount+msgwindow.borderY msgwindow.y=(Graphics.height)-(msgwindow.height) facetop=false if $game_temp && $game_temp.in_battle && !$scene.respond_to?("update_basic") msgwindow.y=0 facetop=true elsif $game_system && $game_system.respond_to?("message_position") case $game_system.message_position when 0 # up msgwindow.y=0 facetop=true when 1 # middle msgwindow.y=(Graphics.height/2)-(msgwindow.height/2) when 2 msgwindow.y=(Graphics.height)-(msgwindow.height) end end if $game_system && $game_system.respond_to?("message_frame") if $game_system.message_frame != 0 msgwindow.opacity = 0 end end if $game_message case $game_message.background when 1 # dim msgwindow.opacity=0 msgback=Sprite.new(msgwindow.viewport) msgback.z=msgwindow.z-1 msgback.bitmap=RPG::Cache.load_bitmap("Graphics/System/","MessageBack") msgback.y=msgwindow.y when 2 # transparent msgwindow.opacity=0 end end if facewindow pbPositionNearMsgWindow(facewindow,msgwindow,:left) facewindow.viewport=msgwindow.viewport facewindow.z=msgwindow.z end ########## Show text ############################# msgwindow.text=text Graphics.frame_reset if Graphics.frame_rate>40 begin if !msgwindow.busy? && delay>0 count+=1 end for i in 0...controls.length if controls[i] && controls[i][2]<=msgwindow.position && waitcount==0 control=controls[i][0] param=controls[i][1] if control=="f" facewindow.dispose if facewindow facewindow=PictureWindow.new("Graphics/Pictures/#{param}") pbPositionNearMsgWindow(facewindow,msgwindow,:left) facewindow.viewport=msgwindow.viewport facewindow.z=msgwindow.z elsif control=="ff" facewindow.dispose if facewindow facewindow=FaceWindowVX.new(param) pbPositionNearMsgWindow(facewindow,msgwindow,:left) facewindow.viewport=msgwindow.viewport facewindow.z=msgwindow.z elsif control=="g" # Display gold window goldwindow.dispose if goldwindow moneyString="" if $Trainer moneyString=_INTL("${1}",$Trainer.money) else if $data_system.respond_to?("words") moneyString=_INTL("{1} {2}",$game_party.gold,$data_system.words.gold) else moneyString=_INTL("{1} {2}",$game_party.gold,Vocab.gold) end end goldwindow=Window_UnformattedTextPokemon.newWithSize( _INTL("MONEY:\\n{1}",moneyString),0,0,32,32,msgwindow.viewport) goldwindow.resizeToFit(goldwindow.text,Graphics.width) if facetop goldwindow.y=Graphics.height-goldwindow.height else goldwindow.y=0 end goldwindow.viewport=msgwindow.viewport goldwindow.z=msgwindow.z elsif control=="wu" msgwindow.y=0 msgback.y=msgwindow.y if msgback elsif control=="wm" msgwindow.y=(Graphics.height/2)-(msgwindow.height/2) msgback.y=msgwindow.y if msgback elsif control=="wd" msgwindow.y=(Graphics.height)-(msgwindow.height) msgback.y=msgwindow.y if msgback elsif control=="." waitcount+=Graphics.frame_rate/4 elsif control=="|" waitcount+=Graphics.frame_rate elsif control=="wt" # Wait param=param.sub(/^\\s+/,"").sub(/\\s+$/,"") waitcount+=param.to_i*2 elsif control=="w" # Windowskin if param=="" msgwindow.windowskin=nil else pbLoadSkin(msgwindow,"Graphics/Windowskins/#{param}") end elsif control=="^" # Wait, no pause autoresume=true elsif control=="wtnp" # Wait, no pause param=param.sub(/^\\s+/,"").sub(/\\s+$/,"") waitcount=param.to_i*2 autoresume=true elsif control=="se" # Play SE $game_system.se_play(pbStringToAudioFile(param)) elsif control=="me" # Play ME $game_system.me_play(pbStringToAudioFile(param)) end controls[i]=nil end end Graphics.update Input.update if $DEBUG && Input.trigger?(Input::F6) pbRecord(unformattedText) end if pbCurrentEventCommentInput(1,"Cut Scene") && Input.trigger?(Input::F5) event=$game_system.map_interpreter.get_character(0) $game_system.map_interpreter.pbSetSelfSwitch(event.id,"A",true) $game_system.map_interpreter.command_end event.start break end if autoresume && waitcount==0 msgwindow.resume if msgwindow.busy? break if !msgwindow.busy? end if (Input.trigger?(Input::C) || Input.trigger?(Input::B)) if msgwindow.busy? Audio.se_play(pbGetDecisionSE) if msgwindow.pausing? msgwindow.resume else break end end pbUpdateSceneMap if waitcount>0 waitcount-=1 else msgwindow.update end end until delay==count && !msgwindow.busy? Input.update # Must call Input.update again to avoid extra triggers pbSetSystemTextSpeed(oldtextspeed) msgwindow.letterbyletter=oldletterbyletter if commands $game_variables[cmdvariable]=Kernel.pbShowCommands( msgwindow,commands,cmdIfCancel) end if msgCommands ret=Kernel.pbShowCommands(msgwindow,msgCommands,msgCommandsCancel) end msgback.dispose if msgback goldwindow.dispose if goldwindow facewindow.dispose if facewindow return ret end def Kernel.pbFacingTerrainTag if $MapFactory return $MapFactory.getFacingTerrainTag else x=$game_player.x y=$game_player.y case $game_player.direction when 2 # down return $game_map.terrain_tag($game_player.x,$game_player.y+1) when 4 # left return $game_map.terrain_tag($game_player.x-1,$game_player.y) when 6 # right return $game_map.terrain_tag($game_player.x+1,$game_player.y) when 8 # up return $game_map.terrain_tag($game_player.x,$game_player.y-1) else return 0 end end end def pbTurnTowardEvent(event,otherEvent) sx = event.x - otherEvent.x sy = event.y - otherEvent.y if sx == 0 and sy == 0 return end if sx.abs > sy.abs sx > 0 ? event.turn_left : event.turn_right else sy > 0 ? event.turn_up : event.turn_down end end def pbNoticePlayer(event) if !event.keypress sprite=$scene.spriteset.addUserAnimation(EXCLAMATION_ANIMATION_ID,event.x,event.y) while !sprite.disposed? Graphics.update Input.update pbUpdateSceneMap end end Kernel.pbMoveTowardPlayer(event) pbTurnTowardEvent($game_player,event) end def Kernel.pbMoveTowardPlayer(event) maxsize=[$game_map.width,$game_map.height].max return if !pbEventCanReachPlayer?(event,$game_player,maxsize) loop do x=event.x y=event.y event.move_toward_player break if event.x==x && event.y==y while event.moving? Graphics.update Input.update pbUpdateSceneMap end end $PokemonMap.addMovedEvent(event.id) if $PokemonMap end def Kernel.pbJumpToward(dist=1,playSound=false) x=$game_player.x y=$game_player.y case $game_player.direction when 2 # down $game_player.jump(0,dist) when 4 # left $game_player.jump(-dist,0) when 6 # right $game_player.jump(dist,0) when 8 # up $game_player.jump(0,-dist) end if $game_player.x!=x || $game_player.y!=y if playSound Audio.se_play("Audio/SE/jump.wav") end while $game_player.jumping? Graphics.update Input.update pbUpdateSceneMap end return true end return false end def pbLedge(xOffset,yOffset) x=$game_player.x y=$game_player.y currentTag=$game_map.terrain_tag(x,y) facingTag=Kernel.pbFacingTerrainTag if(facingTag==PBTerrain::Ledge) # ledge terrain tag if Kernel.pbJumpToward(2,true) increase_steps $game_player.check_event_trigger_here([1,2]) end return true end return false end def pbWait(numframes) numframes.times do Graphics.update Input.update pbUpdateSceneMap end end module PBMoveRoute Down=1 Left=2 Right=3 Up=4 LowerLeft=5 LowerRight=6 UpperLeft=7 UpperRight=8 Random=9 TowardPlayer=10 AwayFromPlayer=11 Forward=12 Backward=13 Jump=14 # xoffset, yoffset Wait=15 # frames TurnDown=16 TurnLeft=17 TurnRight=18 TurnUp=19 TurnRight90=20 TurnLeft90=21 Turn180=22 TurnRightOrLeft90=23 TurnRandom=24 TurnTowardPlayer=25 TurnAwayFromPlayer=26 SwitchOn=27 # 1 param SwitchOff=28 # 1 param ChangeSpeed=29 # 1 param ChangeFreq=30 # 1 param WalkAnimeOn=31 WalkAnimeOff=32 StepAnimeOn=33 StepAnimeOff=34 DirectionFixOn=35 DirectionFixOff=36 ThroughOn=37 ThroughOff=38 AlwaysOnTopOn=39 AlwaysOnTopOff=40 Graphic=41 # Name, hue, direction, pattern Opacity=42 # 1 param Blending=43 # 1 param PlaySE=44 # 1 param Script=45 # 1 param ScriptAsync=101 # 1 param end class Game_Character def jumpForward case self.direction when 2 # down jump(0,1) when 4 # left jump(-1,0) when 6 # right jump(1,0) when 8 # up jump(0,-1) end end def jumpBackward case self.direction when 2 # down jump(0,-1) when 4 # left jump(1,0) when 6 # right jump(-1,0) when 8 # up jump(0,1) end end def moveLeft90 case self.direction when 2 # down move_right when 4 # left move_down when 6 # right move_up when 8 # up move_left end end def moveRight90 case self.direction when 2 # down move_left when 4 # left move_up when 6 # right move_down when 8 # up move_right end end def minilock @prelock_direction=@direction @locked=true end end def pbMoveRoute(event,commands,waitComplete=false) route=RPG::MoveRoute.new route.repeat=false route.skippable=true route.list.clear route.list.push(RPG::MoveCommand.new(PBMoveRoute::ThroughOn)) i=0;while i<commands.length case commands[i] when PBMoveRoute::Wait, PBMoveRoute::SwitchOn, PBMoveRoute::SwitchOff, PBMoveRoute::ChangeSpeed, PBMoveRoute::ChangeFreq, PBMoveRoute::Opacity, PBMoveRoute::Blending, PBMoveRoute::PlaySE, PBMoveRoute::Script route.list.push(RPG::MoveCommand.new(commands[i], [commands[i+1]])) i+=1 when PBMoveRoute::ScriptAsync route.list.push(RPG::MoveCommand.new(PBMoveRoute::Script, [commands[i+1]])) route.list.push(RPG::MoveCommand.new(PBMoveRoute::Wait,[0])) i+=1 when PBMoveRoute::Jump route.list.push(RPG::MoveCommand.new(commands[i], [commands[i+1],commands[i+2]])) i+=2 when PBMoveRoute::Graphic route.list.push(RPG::MoveCommand.new(commands[i], [commands[i+1],commands[i+2],commands[i+3],commands[i+4]])) i+=4 else route.list.push(RPG::MoveCommand.new(commands[i])) end i+=1 end route.list.push(RPG::MoveCommand.new(PBMoveRoute::ThroughOff)) route.list.push(RPG::MoveCommand.new(0)) if event event.force_move_route(route) end return route end def pbToneChangeAll(tone, duration) $game_screen.start_tone_change(tone,duration * 2) for picture in $game_screen.pictures picture.start_tone_change(tone,duration * 2) if picture end end def pbShake(power,speed,frames) $game_screen.start_shake(power,speed,frames * 2) end def pbFlash(color,frames) $game_screen.start_flash(color,frames * 2) end def pbScrollMap(direction, distance, speed) return if !$game_map if speed==0 case direction when 2 $game_map.scroll_down(distance * 128) when 4 $game_map.scroll_left(distance * 128) when 6 $game_map.scroll_right(distance * 128) when 8 $game_map.scroll_up(distance * 128) end else $game_map.start_scroll(direction, distance, speed); loop do Graphics.update Input.update break if !$game_map.scrolling? pbUpdateSceneMap end end end
PokemonField
[
Selecionar
] [
-
]
BADGEFORCUT=0 BADGEFORFLASH=1 BADGEFORROCKSMASH=2 BADGEFORSURF=3 BADGEFORFLY=4 BADGEFORSTRENGTH=5 BADGEFORDIVE=6 BADGEFORWATERFALL=7 STARTING_OVER_SWITCH=5 POKeRUS_SWITCH=3 GRASS_ANIMATION_ID=103 EXCLAMATION_ANIMATION_ID=17 FISHINGBEGINCOMMONEVENT=-1 FISHINGENDCOMMONEVENT=-1 HIDDENMACHINECOMMONEVENT=-1 module EncounterModifier @@procs=[] def self.register(p) @@procs.push(p) end def self.trigger(encounter) for prc in @@procs encounter=prc.call(encounter) end return encounter end end def moveFromSymbol(item) if item.is_a?(Symbol) || item.is_a?(String) begin return PBMoves.const_get(item.to_sym) rescue return nil end else return item end end module HiddenMoveHandlers @@canUseMove={} @@useMove={} def self.addCanUseMove(item,proc) return if (item=moveFromSymbol(item))==nil @@canUseMove[item]=proc end def self.addUseMove(item,proc) return if (item=moveFromSymbol(item))==nil @@useMove[item]=proc end def self.hasHandler(item) return false if (item=moveFromSymbol(item))==nil return @@canUseMove[item]!=nil && @@useMove[item]!=nil end def self.triggerCanUseMove(item,pokemon) # Returns whether move can be used return if (item=moveFromSymbol(item))==nil if !@@canUseMove[item] return false else return @@canUseMove[item].call(item,pokemon) end end def self.triggerUseMove(item,pokemon) # Returns whether move was used return if (item=moveFromSymbol(item))==nil if !@@useMove[item] return false else return @@useMove[item].call(item,pokemon) end end end module Events # This module stores events that can happen during # the game. A procedure can subscribe to an event by # adding itself to the event. It will then be called # whenever the event occurs. @@OnMapChange=Event.new @@OnMapSceneChange=Event.new @@OnMapUpdate=Event.new @@OnMapTransferring=Event.new @@OnStepTaken=Event.new @@OnWildBattleOverride=Event.new @@OnWildBattleEnd=Event.new @@OnWildPokemonCreate=Event.new @@OnSpritesetCreate=Event.new @@OnMapCreate=Event.new # Fires whenever a map is created. # Event handler receives two parameters: the map # (RPG::Map) and the tileset (RPG::Tileset) def self.onMapCreate=(v) @@OnMapCreate=v end def self.onMapCreate @@OnMapCreate end # Fires whenever the player moves to a new map. # Event handler receives the old map ID or 0 if none. def self.onMapChange=(v) @@OnMapChange=v end def self.onMapChange @@OnMapChange end # Fires whenever the player takes a step. def self.onStepTaken=(v) @@OnStepTaken=v end def self.onStepTaken @@OnStepTaken end # Fires each frame during a map update. def self.onMapUpdate=(v) @@OnMapUpdate=v end def self.onMapUpdate @@OnMapUpdate end # Triggers at the start of a wild battle # Event handlers can provide their own wild battle routines # to override the default behavior. def self.onWildBattleOverride=(v) @@OnWildBattleOverride=v end def self.onWildBattleOverride @@OnWildBattleOverride end # Triggers whenever a wild Pokémon battle ends # Parameters: # e[0] - Pokémon species # e[1] - Pokémon level # e[2] - Battle result (1-win, 2-loss, 3-escaped, 4-caught) def self.onWildBattleEnd=(v) @@OnWildBattleEnd=v end def self.onWildBattleEnd @@OnWildBattleEnd end # Triggers whenever a wild Pokémon is created # Parameters: # e[0] - Pokémon being created def self.onWildPokemonCreate=(v) @@OnWildPokemonCreate=v end def self.onWildPokemonCreate @@OnWildPokemonCreate end def self.onMapSceneChange=(v) @@OnMapSceneChange=v end def self.onMapSceneChange @@OnMapSceneChange end def self.onMapTransferring=(v) @@OnMapTransferring=v end def self.onMapTransferring @@OnMapTransferring end def self.onSpritesetCreate=(v) @@OnSpritesetCreate=v end def self.onSpritesetCreate @@OnSpritesetCreate end end def pbSceneStandby if $scene && $scene.is_a?(Scene_Map) $scene.disposeSpritesets end GC.start Graphics.frame_reset yield if $scene && $scene.is_a?(Scene_Map) $scene.createSpritesets end end class PBTerrain Ledge=1 Grass=2 Sand=3 Rock=4 DeepWater=5 StillWater=6 Water=7 Waterfall=8 WaterfallCrest=9 TallGrass=10 UnderwaterGrass=11 Ice=12 Neutral=13 end module PokemonSkins def self.getDefaultTextSkin skin=$PokemonSystem ? $PokemonSystem.textskin : nil if !skin || !$SpeechFrames[skin] skinfile=pbGetMetadata(0,MetadataTextSkin) return skinfile ? skinfile : "frlgtextskin" else return $SpeechFrames[skin] end end end def pbIsPassableWaterTag?(tag) return tag==PBTerrain::DeepWater|| tag==PBTerrain::Water|| tag==PBTerrain::StillWater|| tag==PBTerrain::WaterfallCrest end def pbIsGrassTag?(tag) return tag==PBTerrain::Grass|| tag==PBTerrain::TallGrass|| tag==PBTerrain::UnderwaterGrass end def pbIsWaterTag?(tag) return tag==PBTerrain::DeepWater|| tag==PBTerrain::Water|| tag==PBTerrain::StillWater|| tag==PBTerrain::WaterfallCrest|| tag==PBTerrain::Waterfall end class Game_Temp attr_accessor :background_bitmap end def pbBattleAnimation(bgm=nil) if bgm $game_system.bgm_play(bgm) else $game_system.bgm_play("002-Battle02.mid",100,100) end viewport=Viewport.new(0,0,Graphics.width,Graphics.height) viewport.z=99999 viewport.color=Color.new(17*8,17*8,17*8) 3.times do viewport.color.alpha=0 6.times do viewport.color.alpha+=30 Graphics.update Input.update pbUpdateSceneMap end 6.times do viewport.color.alpha-=30 Graphics.update Input.update pbUpdateSceneMap end end if $game_temp.background_bitmap $game_temp.background_bitmap.dispose end $game_temp.background_bitmap=Graphics.snap_to_bitmap if Sprite.method_defined?(:wave_amp) && rand(15)==0 viewport.color=Color.new(0,0,0,255) sprite = Sprite.new bitmap=Graphics.snap_to_bitmap bm=bitmap.clone sprite.z=99999 sprite.bitmap = bm sprite.wave_speed=500 for i in 0..25 sprite.opacity-=10 sprite.wave_amp+=60 sprite.update sprite.wave_speed+=30 2.times do Graphics.update end end bitmap.dispose bm.dispose sprite.dispose elsif Bitmap.method_defined?(:radial_blur) && rand(15)==0 viewport.color=Color.new(0,0,0,255) sprite = Sprite.new bitmap=Graphics.snap_to_bitmap bm=bitmap.clone sprite.z=99999 sprite.bitmap = bm for i in 0..15 bm.radial_blur(i,2) sprite.opacity-=15 2.times do Graphics.update end end bitmap.dispose bm.dispose sprite.dispose elsif rand(15)==0 scroll=["ScrollDown","ScrollLeft","ScrollRight","ScrollUp"] Graphics.freeze viewport.color=Color.new(0,0,0,255) Graphics.transition(50,sprintf("Graphics/Transitions/%s",scroll[rand(4)])) elsif rand(15)==0 scroll=["ScrollDownRight","ScrollDownLeft","ScrollUpRight","ScrollUpLeft"] Graphics.freeze viewport.color=Color.new(0,0,0,255) Graphics.transition(50,sprintf("Graphics/Transitions/%s",scroll[rand(4)])) else transitions=["Splash","Image1","Image2", "Image3","Image4","Random_stripe_h", "Random_stripe_v","BreakingGlass", "RotatingPieces","022-Normal02", "021-Normal01","Battle","Mosaic","ShrinkingPieces","zoomin", "computertrclose", "hexatr", "hexatzr", "battle1", "battle2", "battle3", "battle4", "computertr", "hexatrc" ] rnd=rand(transitions.length) Graphics.freeze viewport.color=Color.new(0,0,0,255) Graphics.transition(40, sprintf("Graphics/Transitions/%s",transitions[rnd])) end 5.times do Graphics.update Input.update pbUpdateSceneMap end pbPushFade yield if block_given? pbPopFade for j in 0..17 viewport.color=Color.new(0,0,0,(17-j)*15) Graphics.update Input.update pbUpdateSceneMap end viewport.dispose end def pbGenerateWildPokemon(species,level) genwildpoke=PokeBattle_Pokemon.new(species,level,$Trainer) dexdata=pbOpenDexData itemrnd=rand(100) if itemrnd<50 pbDexDataOffset(dexdata,species,48) genwildpoke.item=dexdata.fgetw elsif itemrnd<55 pbDexDataOffset(dexdata,species,50) genwildpoke.item=dexdata.fgetw end dexdata.close Events.onWildPokemonCreate.trigger(nil,genwildpoke) pokerus=(rand(8192)==0) if pokerus genwildpoke.pokerus=1 genwildpoke.pokerusTime=Time.now.to_i end return genwildpoke end def pbPrepareBattle(battle) if $game_screen.weather_type==1 || $game_screen.weather_type==2 battle.weather=PBWeather::RAINDANCE battle.weatherduration=-1 elsif $game_screen.weather_type==3 battle.weather=PBWeather::HAIL battle.weatherduration=-1 elsif $game_screen.weather_type==4 battle.weather=PBWeather::SANDSTORM battle.weatherduration=-1 elsif $game_screen.weather_type==5 battle.weather=PBWeather::SUNNYDAY battle.weatherduration=-1 end battle.shiftStyle=($PokemonSystem.battlestyle==0) battle.battlescene=($PokemonSystem.battlescene==0) battle.environment=pbGetEnvironment end def pbEvolutionCheck(currentlevels) # Check conditions for evolution for i in 0...currentlevels.length pokemon=$Trainer.party[i] if pokemon && pokemon.level!=currentlevels[i] newspecies=Kernel.pbCheckEvolution(pokemon) if newspecies>0 # Start evolution scene evo=PokemonEvolutionScene.new evo.pbStartScreen(pokemon,newspecies) evo.pbEvolution evo.pbEndScreen end end end end def pbPokerusCheck if rand(3)==0 first=0 last=$Trainer.party.length-1 if $Trainer.party[first].pokerus==0 && !$Trainer.party[first].egg? $Trainer.party[first].pokerus=1 $Trainer.party[first].pokerusTime=Time.now.to_i end if $Trainer.party[last].pokerus==0 && !$Trainer.party[last].egg? $Trainer.party[last].pokerus=1 $Trainer.party[last].pokerusTime=Time.now.to_i end end end def pbWildBattle(species,level,variable=nil,canescape=true) handled=[nil] Events.onWildBattleOverride.trigger(nil,species,level,handled) if handled[0]!=nil return handled[0] end if (Input.press?(Input::CTRL) && $DEBUG) || $Trainer.pokemonCount==0 if $Trainer.pokemonCount>0 Kernel.pbMessage(_INTL("SKIPPING BATTLE...")) end $game_variables[variable]=1 if variable $PokemonGlobal.nextBattleBGM=nil $PokemonGlobal.nextBattleME=nil $PokemonGlobal.nextBattleBack=nil return true end currentlevels=[] for i in $Trainer.party currentlevels.push(i.level) end genwildpoke=pbGenerateWildPokemon(species,level) pokerus=(genwildpoke.pokerus==1) scene=PokeBattle_Scene.new battle=PokeBattle_Battle.new(scene,$Trainer.party,[genwildpoke],$Trainer,nil) battle.internalbattle=true battle.cantescape=!canescape pbPrepareBattle(battle) wildbgm=pbGetWildBattleBGM(species) playingBGS=$game_system.getPlayingBGS playingBGM=$game_system.getPlayingBGM $game_system.bgm_pause $game_system.bgs_pause restorebgm=true decision=0 pbBattleAnimation(wildbgm) { pbSceneStandby { decision=battle.pbStartBattle } if decision==2 $game_system.bgm_unpause $game_system.bgs_unpause Kernel.pbStartOver restorebgm=false else # Check conditions for evolution pbEvolutionCheck(currentlevels) if decision==1 for pkmn in $Trainer.party Kernel.pbPickup(pkmn) end end pbPokerusCheck if pokerus end if restorebgm $game_system.bgm_resume(playingBGM) $game_system.bgs_resume(playingBGS) end } $PokemonGlobal.nextBattleBGM=nil $PokemonGlobal.nextBattleME=nil $PokemonGlobal.nextBattleBack=nil $PokemonEncounters.clearStepCount Input.update $game_variables[variable]=decision if variable Events.onWildBattleEnd.trigger(nil,species,level,decision) return (decision!=2) end def pbRegisterPartner(trainerid,trainername,partyid=0) trainer=pbLoadTrainer(trainerid,trainername,partyid) trainerobject=PokeBattle_Trainer.new(_INTL(trainername),trainerid) trainerobject.setForeignID($Trainer) for i in trainer[2] i.trainerID=trainerobject.id i.ot=trainerobject.name i.calcStats end $PokemonGlobal.partner=[trainerid,trainerobject.name,trainerobject.id,trainer[2]] end def pbDeregisterPartner $PokemonGlobal.partner=nil end def pbDoubleWildBattle(species1,level1,species2,level2,variable=nil,canescape=true) if (Input.press?(Input::CTRL) && $DEBUG) || $Trainer.pokemonCount==0 Kernel.pbMessage(_INTL("SKIPPING BATTLE...")) $game_variables[variable]=1 if variable $PokemonGlobal.nextBattleBGM=nil $PokemonGlobal.nextBattleME=nil $PokemonGlobal.nextBattleBack=nil return true end currentlevels=[] for i in $Trainer.party currentlevels.push(i.level) end genwildpoke=pbGenerateWildPokemon(species1,level1) genwildpoke2=pbGenerateWildPokemon(species2,level2) pokerus=(genwildpoke.pokerus==1)||(genwildpoke2.pokerus==1) scene=PokeBattle_Scene.new if $PokemonGlobal.partner othertrainer=PokeBattle_Trainer.new( $PokemonGlobal.partner[1], $PokemonGlobal.partner[0]) othertrainer.id=$PokemonGlobal.partner[2] othertrainer.party=$PokemonGlobal.partner[3] combinedParty=[] for i in othertrainer.party; i.heal; end for i in 0...$Trainer.party.length combinedParty[i]=$Trainer.party[i] end for i in 0...othertrainer.party.length combinedParty[6+i]=othertrainer.party[i] end battle=PokeBattle_Battle.new(scene,combinedParty,[genwildpoke,genwildpoke2], [$Trainer,othertrainer],nil) battle.fullparty1=true else battle=PokeBattle_Battle.new(scene,$Trainer.party,[genwildpoke,genwildpoke2], $Trainer,nil) end battle.internalbattle=true battle.doublebattle=true battle.cantescape=!canescape pbPrepareBattle(battle) wildbgm=pbGetWildBattleBGM(species1) playingBGS=$game_system.getPlayingBGS playingBGM=$game_system.getPlayingBGM $game_system.bgm_pause $game_system.bgs_pause restorebgm=true decision=0 pbBattleAnimation(wildbgm) { pbSceneStandby { decision=battle.pbStartBattle } if $PokemonGlobal.partner for i in $Trainer.party i.heal end end if decision==2 $game_system.bgm_unpause $game_system.bgs_unpause Kernel.pbStartOver restorebgm=false else # Check conditions for evolution pbEvolutionCheck(currentlevels) if decision==1 for pkmn in $Trainer.party Kernel.pbPickup(pkmn) end end pbPokerusCheck if pokerus end } if restorebgm $game_system.bgm_resume(playingBGM) $game_system.bgs_resume(playingBGS) end $PokemonGlobal.nextBattleBGM=nil $PokemonGlobal.nextBattleME=nil $PokemonGlobal.nextBattleBack=nil $PokemonEncounters.clearStepCount Input.update $game_variables[variable]=decision if variable return (decision!=2) end def pbDynamicItemList(*args) ret=[] for i in 0...args.length if hasConst?(PBItems,args[i]) ret.push(PBItems.const_get(args[i].to_sym)) end end return ret end def Kernel.pbPickup(pokemon) return if pokemon.ability!=PBAbilities::PICKUP || pokemon.egg? return if pokemon.item!=0 return if rand(10)!=0 pickupList=pbDynamicItemList( :POTION, :ANTIDOTE, :SUPERPOTION, :GREATBALL, :REPEL, :ESCAPEROPE, :XATTACK, :FULLHEAL, :ULTRABALL, :HYPERPOTION, :RARECANDY, :PROTEIN, :REVIVE, :HPUP, :FULLRESTORE, :MAXREVIVE, :PPUP, :MAXELIXIR ) pickupListRare=pbDynamicItemList( :HYPERPOTION, :NUGGET, :KINGSROCK, :FULLRESTORE, :ETHER, :WHITEHERB, :TM44, :ELIXIR, :TM01, :LEFTOVERS, :TM26 ) return if pickupList.length!=18 return if pickupListRare.length!=11 randlist=[30,10,10,10,10,10,10,5,3,1,1] items=[] rnd=rand(100) itemstart=(pokemon.level-1)/10 itemstart=0 if itemstart<0 for i in 0...9 items.push(pickupList[i+itemstart]) end items.push(pickupListRare[itemstart]) items.push(pickupListRare[itemstart+1]) cumnumber=0 for i in 0...11 cumnumber+=randlist[i] if rnd<cumnumber pokemon.item=items[i] break end end end def pbEncounter(enctype) if $PokemonGlobal.partner encounter1=$PokemonEncounters.pbEncounteredPokemon(enctype) return false if !encounter1 encounter2=$PokemonEncounters.pbEncounteredPokemon(enctype) return false if !encounter2 pbDoubleWildBattle(encounter1[0],encounter1[1], encounter2[0],encounter2[1]) return true else encounter=$PokemonEncounters.pbEncounteredPokemon(enctype) return false if !encounter pbWildBattle(encounter[0],encounter[1]) return true end end def Kernel.pbOnStepTaken(eventTriggered) if $game_player.move_route_forcing || $game_system.map_interpreter.running? || !$Trainer pbFieldMovementOnStepTaken return end for pkmn in $Trainer.party next if pkmn.egg? if pkmn.pokerus==1 && Time.now.to_i>=pkmn.pokerusTime+345600 # Cured pkmn.pokerus=2 end end $PokemonGlobal.stepcount=0 if !$PokemonGlobal.stepcount $PokemonGlobal.stepcount+=1 $PokemonGlobal.stepcount&=0xFFFFFF $PokemonGlobal.happinessSteps=0 if !$PokemonGlobal.happinessSteps $PokemonGlobal.happinessSteps+=1 if $PokemonGlobal.happinessSteps==256 for pkmn in $Trainer.party pkmn.happiness+=1 if pkmn.hp>0 && !pkmn.egg? pkmn.happiness=255 if pkmn.happiness>255 end $PokemonGlobal.happinessSteps=0 end if $PokemonGlobal.repel>0 $PokemonGlobal.repel-=1 if $PokemonGlobal.repel<=0 Kernel.pbMessage(_INTL("Repel's effect wore off...")) end end Events.onStepTaken.trigger(nil) if !pbSafariOnStepTaken return end if $PokemonGlobal.stepcount % 4 == 0 for i in $Trainer.party if i.status==PBStatuses::POISON && i.hp>0 && !i.egg? $game_screen.start_flash(Color.new(255,0,0,128), 4) i.hp-=1 if i.hp==0 Kernel.pbMessage(_INTL("{1} fainted...",i.name)) end if pbAllFainted Kernel.pbMessage(_INTL("{1} has no usable Pokémon!",$Trainer.name)) Kernel.pbMessage(_INTL("{1} whited out!",$Trainer.name)) $game_system.bgm_fade(1.0) $game_system.bgs_fade(1.0) pbFadeOutIn(99999){ Kernel.pbStartOver } return end end end end pbFieldMovementOnStepTaken if !eventTriggered && !$game_system.encounter_disabled if $PokemonGlobal.surfing encounter=$PokemonEncounters.pbGenerateEncounter(2) encounter=EncounterModifier.trigger(encounter) if encounter && !(Input.press?(Input::CTRL) && $DEBUG) && $Trainer.party.length > 0 if $PokemonGlobal.partner encounter2=$PokemonEncounters.pbEncounteredPokemon(2) pbDoubleWildBattle(encounter[0],encounter[1], encounter2[0],encounter2[1]) else pbWildBattle(encounter[0],encounter[1]) end end elsif $PokemonEncounters.isCave? encounter=$PokemonEncounters.pbGenerateEncounter(1) encounter=EncounterModifier.trigger(encounter) if encounter && !(Input.press?(Input::CTRL) && $DEBUG) && $Trainer.party.length > 0 if $PokemonGlobal.partner encounter2=$PokemonEncounters.pbEncounteredPokemon(1) pbDoubleWildBattle(encounter[0],encounter[1], encounter2[0],encounter2[1]) else pbWildBattle(encounter[0],encounter[1]) end end elsif $PokemonEncounters.isGrass? encounter=$PokemonEncounters.pbGenerateEncounter(pbLandEncounterType) if pbIsGrassTag?($game_map.terrain_tag($game_player.x,$game_player.y)) encounter=EncounterModifier.trigger(encounter) if encounter && !(Input.press?(Input::CTRL) && $DEBUG) && $Trainer.party.length > 0 if $PokemonGlobal.partner encounter2=$PokemonEncounters.pbEncounteredPokemon(pbLandEncounterType) pbDoubleWildBattle(encounter[0],encounter[1], encounter2[0],encounter2[1]) else pbWildBattle(encounter[0],encounter[1]) end end end end end end def pbLandEncounterType hour=Time.now.hour enctype=EncounterTypes::Land if pbInBugContest? if $PokemonEncounters.hasEncounter?(EncounterTypes::BugContest) enctype=EncounterTypes::BugContest end elsif hour<6 || hour>=20 if $PokemonEncounters.hasEncounter?(EncounterTypes::LandNight) enctype=EncounterTypes::LandNight end elsif hour<12 if $PokemonEncounters.hasEncounter?(EncounterTypes::LandMorning) enctype=EncounterTypes::LandMorning end else if $PokemonEncounters.hasEncounter?(EncounterTypes::LandDay) enctype=EncounterTypes::LandDay end end return enctype end def pbGetEnvironment return PBEnvironment::None if !$game_map if $PokemonGlobal.diving return PBEnvironment::Underwater elsif $PokemonEncounters.isCave? return PBEnvironment::Cave elsif !pbGetMetadata($game_map.map_id,MetadataOutdoor) return PBEnvironment::None else terrain=$game_player.terrain_tag if terrain==PBTerrain::Grass # Normal grass return PBEnvironment::Grass elsif terrain==PBTerrain::TallGrass # Tall grass return PBEnvironment::TallGrass elsif terrain==PBTerrain::DeepWater || terrain==PBTerrain::Water return PBEnvironment::MovingWater elsif terrain==PBTerrain::StillWater return PBEnvironment::StillWater elsif terrain==PBTerrain::Rock return PBEnvironment::Rock elsif terrain==PBTerrain::Sand return PBEnvironment::Sand end return PBEnvironment::None end end def pbFieldMovementOnStepTaken x=$game_player.x y=$game_player.y if $game_map.terrain_tag(x,y)==PBTerrain::Grass $scene.spriteset.addUserAnimation(GRASS_ANIMATION_ID,x,y) elsif $game_map.terrain_tag(x,y)==PBTerrain::WaterfallCrest Kernel.pbDescendWaterfall elsif $game_map.terrain_tag(x,y)==PBTerrain::Ice Kernel.pbSlideOnIce end end class DarknessSprite < SpriteWrapper attr_reader :radius def initialize(viewport=nil) super(viewport) @darkness=Bitmap.new(Graphics.width,Graphics.height) @radius=48 self.bitmap=@darkness self.z=99998 refresh end def dispose @darkness.dispose super end def radius=(value) @radius=value refresh end def refresh @darkness.fill_rect(0,0,Graphics.width,Graphics.height,Color.new(0,0,0,255)) cx=240 cy=160 cradius=@radius for i in cx-cradius..cx+cradius diff2 = (cradius * cradius) - ((i - cx) * (i - cx)); diff = Math.sqrt( diff2); @darkness.fill_rect(i,cy-diff,1,diff*2,Color.new(0,0,0,0)) end end end class WinSprite < Sprite def initialize(bitmap) super() self.bitmap=bitmap end def width return self.bitmap.width end def height return self.bitmap.height end end class LocationWindow def initialize(name) @window=Window_AdvancedTextPokemon.new(name) @window.resizeToFit(name,Graphics.width) @window.x=0 @window.y=-@window.height @window.z=99999 @currentmap=$game_map.map_id @frames=0 end def disposed? @window.disposed? end def dispose @window.dispose end def update return if @window.disposed? @window.update if $game_temp.message_window_showing || @currentmap!=$game_map.map_id || $PokemonTemp.mapChanged @window.dispose return end if @frames>60 @window.y-=4 @window.dispose if @window.y+@window.height<0 else @window.y+=4 if @window.y<0 @frames+=1 end end end class LightEffect def initialize(event,map=nil) @light = Sprite.new @light.bitmap = BitmapCache.picture("LE.PNG") @light.src_rect = Rect.new(0, 0, 64, 64) @light.visible = true @light.z = 1000 @event = event @map=map ? map : $game_map @disposed=false end def disposed? return @disposed end def dispose @light.bitmap.dispose @light.dispose @map=nil @event=nil @disposed=true end def update end end class LightEffect_Lamp < LightEffect def initialize(event,map=nil) @light = Sprite.new lamp = BitmapCache.picture("LE.PNG") @light.bitmap = Bitmap.new(128,64) src_rect = Rect.new(0, 0, 64, 64) @light.bitmap.blt(0, 0, lamp, src_rect) @light.bitmap.blt(20, 0, lamp, src_rect) lamp.dispose @light.visible = true @light.z = 1000 @map=map ? map : $game_map @event = event end end class LightEffect_Basic < LightEffect def initialize(event,map=nil) super end def update return if !@light || !@event super @light.opacity = 100 @light.ox=32 @light.oy=48 @light.x = ScreenPosHelper.pbScreenX(@event) @light.y = ScreenPosHelper.pbScreenY(@event) @light.zoom_x = ScreenPosHelper.pbScreenZoomX(@event) @light.zoom_y = @light.zoom_x @light.tone=$game_screen.tone end end class LightEffect_DayNight < LightEffect def initialize(event,map=nil) super @opacities=[ 180,180,180,160,110,100, 50,25,0,0,0,0, 0,0,0,0,0,25, 50,100,120,160,180,180 ] end def update return if !@light || !@event super @light.opacity = @opacities[Time.now.hour] if @light.opacity>0 @light.ox=32 @light.oy=48 @light.x = ScreenPosHelper.pbScreenX(@event) @light.y = ScreenPosHelper.pbScreenY(@event) @light.zoom_x = ScreenPosHelper.pbScreenZoomX(@event) @light.zoom_y = ScreenPosHelper.pbScreenZoomY(@event) @light.tone.set( $game_screen.tone.red, $game_screen.tone.green, $game_screen.tone.blue, $game_screen.tone.gray) end end end def pbCanUseBike?(mapid) return true if pbGetMetadata(mapid,MetadataBicycleAlways) val=pbGetMetadata(mapid,MetadataBicycle) val=pbGetMetadata(mapid,MetadataOutdoor) if val==nil return val ? true : false end Events.onMapChange+=proc {|sender,e| oldid=e[0] # previous map ID, 0 if no map ID healing=pbGetMetadata($game_map.map_id,MetadataHealingSpot) if healing $PokemonGlobal.healingSpot=healing end $PokemonMap.clear if $PokemonMap if $PokemonEncounters $PokemonEncounters.setup($game_map.map_id) end $PokemonGlobal.visitedMaps[$game_map.map_id]=true if oldid!=0 && oldid!=$game_map.map_id weather=pbGetMetadata($game_map.map_id,MetadataWeather) if weather && rand(100)<weather[1] $game_screen.weather(weather[0],8,20) else $game_screen.weather(0,0,0) end end $PokemonTemp.mapChanged=true } Events.onMapSceneChange+=proc{|sender,e| scene=e[0] mapChanged=e[1] return if !scene || !scene.spriteset darkmap=pbGetMetadata($game_map.map_id,MetadataDarkMap) if darkmap && !$PokemonGlobal.flashUsed $PokemonTemp.darknessSprite=DarknessSprite.new scene.spriteset.addUserSprite($PokemonTemp.darknessSprite) else if !darkmap $PokemonGlobal.flashUsed=false end if $PokemonTemp.darknessSprite $PokemonTemp.darknessSprite.dispose if $PokemonTemp.darknessSprite $PokemonTemp.darknessSprite=nil end end if mapChanged if pbGetMetadata($game_map.map_id,MetadataShowArea) scene.spriteset.addUserSprite(LocationWindow.new($game_map.name)) end end if pbGetMetadata($game_map.map_id,MetadataBicycleAlways) Kernel.pbMountBike else if !pbCanUseBike?($game_map.map_id) Kernel.pbDismountBike end end } Events.onMapTransferring+=proc{|sender,e| newmap=e[0] cancelVehicles=e[1] if cancelVehicles Kernel.pbCancelVehicles(newmap) 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). for i in map.events.keys if map.events[i].name=="OutdoorLight" spriteset.addUserSprite(LightEffect_DayNight.new(map.events[i],map)) elsif map.events[i].name=="Light" spriteset.addUserSprite(LightEffect_Basic.new(map.events[i],map)) end end spriteset.addUserSprite(Particle_Engine.new(viewport,map)) } def Kernel.pbOnSpritesetCreate(spriteset,viewport) Events.onSpritesetCreate.trigger(nil,spriteset,viewport) end def pbBatteryLow? power="\\0"*12 begin sps=Win32API.new('kernel32.dll','GetSystemPowerStatus','p','l') rescue return false end if sps.call(power)==1 status=power.unpack("CCCCVV") # Battery Flag if status[1]!=255 && (status[1]&6)!=0 # Low or Critical return true end # Battery Life Percent if status[2]<3 # Less than 3 percent return true end # Battery Life Time if status[4]<300 # Less than 5 minutes return true end end return false end class Game_Event def cooledDown?(seconds) if !(expired?(seconds) && tsOff?("A")) self.need_refresh=true return false else return true end end end class PokemonTemp attr_accessor :batterywarning attr_accessor :cueBGM attr_accessor :cueFrames end Events.onMapUpdate+=proc {|sender,e| if Time.now.sec==0 && $Trainer && $PokemonGlobal && !$game_player && !$game_map && !$PokemonTemp.batterywarning && !$game_player.move_route_forcing && !$game_system.map_interpreter.running? && !$game_temp.message_window_showing && pbBatteryLow? $PokemonTemp.batterywarning=true if Kernel.pbConfirmMessage(_INTL("The game has detected that the battery is low. Would you like to save the game now?")) pbSaveScreen elsif Kernel.pbConfirmMessage(_INTL("You may lose your progress if you don't save. Would you like to save now?")) pbSaveScreen end end if $PokemonTemp.cueFrames $PokemonTemp.cueFrames-=1 if $PokemonTemp.cueFrames<=0 $PokemonTemp.cueFrames=nil if $game_system.getPlayingBGM==nil $game_system.bgm_play($PokemonTemp.cueBGM) end end end } def pbCueBGM(bgm,seconds) return if !bgm if bgm.is_a?(String) bgm=RPG::AudioFile.new(bgm,100,100) end playingBGM=$game_system.playing_bgm if !playingBGM || playingBGM.name!=bgm.name || playingBGM.pitch!=bgm.pitch $game_system.bgm_fade(seconds) if !$PokemonTemp.cueFrames $PokemonTemp.cueFrames=(seconds*Graphics.frame_rate)*3/5 end $PokemonTemp.cueBGM=bgm; elsif playingBGM $game_system.bgm_play(bgm) end end def pbAutoplayOnTransition surfbgm=pbGetMetadata(0,MetadataSurfBGM) bikebgm=pbGetMetadata(0,MetadataBicycleBGM) if $PokemonGlobal.surfing && surfbgm $game_system.bgm_play(surfbgm) else $game_map.autoplayAsCue end end def pbAutoplayOnSave surfbgm=pbGetMetadata(0,MetadataSurfBGM) bikebgm=pbGetMetadata(0,MetadataBicycleBGM) if $PokemonGlobal.surfing && surfbgm $game_system.bgm_play(surfbgm) elsif $PokemonGlobal.bicycle && bikebgm $game_system.bgm_play(bikebgm) else $game_map.autoplay end end def Kernel.pbUpdateVehicle meta=pbGetMetadata(0,MetadataPlayerA+$PokemonGlobal.playerID) if meta if $PokemonGlobal.diving $game_player.character_name=meta[6] && meta[6]!="" ? meta[6] : meta[1] # Diving graphic elsif $PokemonGlobal.surfing $game_player.character_name=meta[4] && meta[4]!="" ? meta[4] : meta[1] # Surfing graphic elsif $PokemonGlobal.bicycle $game_player.character_name=meta[2] && meta[2]!="" ? meta[2] : meta[1] # Bicycle graphic else $game_player.character_name=meta[1] # Regular graphic end end end def Kernel.pbMountBike return if $PokemonGlobal.bicycle $PokemonGlobal.bicycle=true Kernel.pbUpdateVehicle bikebgm=pbGetMetadata(0,MetadataBicycleBGM) if bikebgm pbCueBGM(bikebgm,0.5) end end def Kernel.pbDismountBike return if !$PokemonGlobal.bicycle $PokemonGlobal.bicycle=false Kernel.pbUpdateVehicle $game_map.autoplayAsCue end def Kernel.pbCancelVehicles(destination=nil) $PokemonGlobal.surfing=false $PokemonGlobal.diving=false if !destination || !pbCanUseBike?(destination) $PokemonGlobal.bicycle=false end Kernel.pbUpdateVehicle end def pbFishingBegin if !pbCommonEvent(FISHINGBEGINCOMMONEVENT) pattern=0 playertrainer=pbGetPlayerTrainerType 5.times do |pattern| $game_player.setDefaultCharName(sprintf("fishing%03d",playertrainer),pattern) 2.times do Graphics.update Input.update pbUpdateSceneMap end end end end def pbFishingEnd(oldpattern) if !pbCommonEvent(FISHINGENDCOMMONEVENT) pattern=0 playertrainer=pbGetPlayerTrainerType 5.times do |pattern| $game_player.setDefaultCharName(sprintf("fishing%03d",playertrainer),4-pattern) pattern+=1 2.times do Graphics.update Input.update pbUpdateSceneMap end end end end def pbWaitMessage(msgwindow,time) message="" time.times do Kernel.pbDisplayMessageFancy(msgwindow,message,nil,0) 20.times do Graphics.update Input.update pbUpdateSceneMap if Input.trigger?(Input::C)||Input.trigger?(Input::B) return true end end message+=". " end return false end def pbWaitForInput(msgwindow,message,frames) Kernel.pbDisplayMessageFancy(msgwindow,message,nil,0) frames.times do Graphics.update Input.update pbUpdateSceneMap if Input.trigger?(Input::C)||Input.trigger?(Input::B) return true end end return false end def pbRecord(text,maxtime=30.0) text="" if !text textwindow=Window_UnformattedTextPokemon.newWithSize(text, 0,0,Graphics.width,Graphics.height-96) textwindow.z=99999 if text=="" textwindow.visible=false end wave=nil msgwindow=Kernel.pbCreateMessageWindow skinfile=PokemonSkins.getDefaultTextSkin pbLoadSkin(msgwindow,"Graphics/Windowskins/#{skinfile}") oldvolume=Kernel.Audio_bgm_get_volume() Kernel.Audio_bgm_set_volume(0) delay=2 delay.times do |i| Kernel.pbDisplayMessageFancy(msgwindow, _ISPRINTF("Recording in {1:d} second(s)...\\nPress ESC to cancel.",delay-i),nil,0) Graphics.frame_rate.times do Graphics.update Input.update textwindow.update msgwindow.update if Input.trigger?(Input::B) Kernel.Audio_bgm_set_volume(oldvolume) Kernel.pbDisposeMessageWindow(msgwindow) textwindow.dispose return nil end end end Kernel.pbDisplayMessageFancy(msgwindow, _INTL("NOW RECORDING\\nPress ESC to stop recording."),nil,0) if beginRecordUI frames=(maxtime*Graphics.frame_rate).to_i frames.times do Graphics.update Input.update textwindow.update msgwindow.update if Input.trigger?(Input::B) break end end endRecord("record.wav") wave=getWaveDataUI("record.wav",true) if wave Kernel.pbDisplayMessageFancy(msgwindow, _INTL("PLAYING BACK..."),nil,0) textwindow.update msgwindow.update Graphics.update Input.update wave.play (Graphics.frame_rate*wave.time).to_i.times do Graphics.update Input.update textwindow.update msgwindow.update end end end Kernel.Audio_bgm_set_volume(oldvolume) Kernel.pbDisposeMessageWindow(msgwindow) textwindow.dispose return wave end def pbFishing(hasencounter) bitechance=65 hookchance=65 oldpattern=$game_player.fullPattern pbFishingBegin msgwindow=Kernel.pbCreateMessageWindow loop do time=2+rand(10) message="" time.times do message+=". " end if pbWaitMessage(msgwindow,time) pbFishingEnd(oldpattern) $game_player.setDefaultCharName("",oldpattern) Kernel.pbDisplayMessageFancy(msgwindow,_INTL("Not even a nibble...")) Kernel.pbDisposeMessageWindow(msgwindow) return false end rnd=rand(100) if rnd<bitechance && hasencounter frames=rand(15)+30 if !pbWaitForInput(msgwindow,message+_INTL("\\r\\nOh! A bite!"),frames) pbFishingEnd(oldpattern) $game_player.setDefaultCharName("",oldpattern) Kernel.pbDisplayMessageFancy(msgwindow,_INTL("It got away...")) Kernel.pbDisposeMessageWindow(msgwindow) return false end rnd=rand(100) if rnd<hookchance Kernel.pbDisplayMessageFancy(msgwindow,_INTL("A Pokémon's on the hook!"),-1) Kernel.pbDisposeMessageWindow(msgwindow) $game_player.setDefaultCharName("",oldpattern) return true end hookchance+=15 bitechance+=15 else pbFishingEnd(oldpattern) $game_player.setDefaultCharName("",oldpattern) Kernel.pbDisplayMessageFancy(msgwindow,_INTL("Not even a nibble...")) Kernel.pbDisposeMessageWindow(msgwindow) return false end end Kernel.pbDisposeMessageWindow(msgwindow) return false end def pbAllFainted for i in $Trainer.party return false if !i.egg? && i.hp>0 end return true end def Kernel.pbSetPokemonCenter $PokemonGlobal.pokecenterMapId=$game_map.map_id $PokemonGlobal.pokecenterX=$game_player.x $PokemonGlobal.pokecenterY=$game_player.y $PokemonGlobal.pokecenterDirection=$game_player.direction end def Kernel.pbRxdataExists?(file) if $RPGVX return pbRgssExists?(file+".rvdata") else return pbRgssExists?(file+".rxdata") end end def Kernel.pbStartOver(gameover=false) if pbInBugContest? Kernel.pbBugContestStartOver return end for i in $Trainer.party i.heal end if $PokemonGlobal.pokecenterMapId && $PokemonGlobal.pokecenterMapId>=0 if gameover Kernel.pbMessage(_INTL("\\\\w[]\\\\wm\\\\c[8]\\\\l[3]After the unfortunate defeat, {1} scurried to a Pokémon Center.",$Trainer.name)) else Kernel.pbMessage(_INTL("\\\\w[]\\\\wm\\\\c[8]\\\\l[3]{1} scurried to a Pokémon Center, protecting the exhausted and fainted Pokémon from further harm.",$Trainer.name)) end Kernel.pbCancelVehicles $game_switches[STARTING_OVER_SWITCH]=true $game_temp.player_new_map_id=$PokemonGlobal.pokecenterMapId $game_temp.player_new_x=$PokemonGlobal.pokecenterX $game_temp.player_new_y=$PokemonGlobal.pokecenterY $game_temp.player_new_direction=$PokemonGlobal.pokecenterDirection $scene.transfer_player $game_map.refresh else homedata=pbGetMetadata(0,MetadataHome) if (homedata && !pbRxdataExists?(sprintf("Data/Map%03d",homedata[0])) ) if $DEBUG Kernel.pbMessage(_ISPRINTF("Can't find the map 'Map{1:03d}' in the Data folder. The game will resume at the player's position.",homedata[0])) end for i in $Trainer.party i.heal end return end if gameover Kernel.pbMessage(_INTL("\\\\w[]\\\\wm\\\\c[8]\\\\l[3]After the unfortunate defeat, {1} scurried home.",$Trainer.name)) else Kernel.pbMessage(_INTL("\\\\w[]\\\\wm\\\\c[8]\\\\l[3]{1} scurried home, protecting the exhausted and fainted Pokémon from further harm.",$Trainer.name)) end if homedata Kernel.pbCancelVehicles $game_switches[STARTING_OVER_SWITCH]=true $game_temp.player_new_map_id=homedata[0] $game_temp.player_new_x=homedata[1] $game_temp.player_new_y=homedata[2] $game_temp.player_new_direction=homedata[3] $scene.transfer_player $game_map.refresh else for i in $Trainer.party i.heal end end end end def Kernel.pbItemBall(item) itemname=PBItems.getName(item) Kernel.pbMessageSound(_INTL("{1} found one {2}!",$Trainer.name,itemname), "Audio/SE/itemlevel.wav") if $PokemonBag.pbStoreItem(item) case $ItemData[item][ITEMPOCKET] when 1 Kernel.pbMessage(_INTL("{1} put the {2} in the Items Pocket.",$Trainer.name,itemname)) when 2 Kernel.pbMessage(_INTL("{1} put the {2} in the Poke Balls Pocket.",$Trainer.name,itemname)) when 3 Kernel.pbMessage(_INTL("{1} put the {2} in the TMs/HMs Pocket.",$Trainer.name,itemname)) when 4 Kernel.pbMessage(_INTL("{1} put the {2} in the Berries Pocket.",$Trainer.name,itemname)) when 5 Kernel.pbMessage(_INTL("{1} put the {2} in the Key Items Pocket.",$Trainer.name,itemname)) end return true else Kernel.pbMessage(_INTL("Too bad... The Bag is full...")) return false end end def Kernel.pbReceiveItem(item) itemname=PBItems.getName(item) Kernel.pbMessageSound(_INTL("Obtained the {2}!",$Trainer.name,itemname), "Audio/SE/itemlevel.wav") if $PokemonBag.pbStoreItem(item) case $ItemData[item][ITEMPOCKET] when 1 Kernel.pbMessage(_INTL("{1} put the {2} in the Items Pocket.",$Trainer.name,itemname)) when 2 Kernel.pbMessage(_INTL("{1} put the {2} in the Poke Balls Pocket.",$Trainer.name,itemname)) when 3 Kernel.pbMessage(_INTL("{1} put the {2} in the TMs/HMs Pocket.",$Trainer.name,itemname)) when 4 Kernel.pbMessage(_INTL("{1} put the {2} in the Berries Pocket.",$Trainer.name,itemname)) when 5 Kernel.pbMessage(_INTL("{1} put the {2} in the Key Items Pocket.",$Trainer.name,itemname)) end return true else return false end end def Kernel.pbHealAll for i in $Trainer.party i.heal end end def Kernel.pbPokerus? return false if $game_switches[POKeRUS_SWITCH] for i in $Trainer.party return true if i.pokerus==1 && !i.egg? end return false end def Kernel.pbCheckMove(move) for i in $Trainer.party for j in i.moves return i if j.id==move end end return nil end def Kernel.pbCut if $DEBUG || $Trainer.badges[BADGEFORCUT] movefinder=Kernel.pbCheckMove(PBMoves::CUT) if $DEBUG || movefinder Kernel.pbMessage(_INTL("This tree looks like it can be cut down!")) if Kernel.pbConfirmMessage(_INTL("Would you like to cut it?")) speciesname=!movefinder ? PBSpecies.getName(0) : movefinder.name Kernel.pbMessage(_INTL("{1} used Cut!",speciesname)) pbHiddenMoveAnimation(movefinder) return true end else Kernel.pbMessage(_INTL("This tree looks like it can be cut down.")) end else Kernel.pbMessage(_INTL("This tree looks like it can be cut down.")) end return false end class RectInterpolator def initialize(oldrect,newrect,frames) restart(oldrect,newrect,frames) end def restart(oldrect,newrect,frames) @oldrect=oldrect @newrect=newrect @frames=[frames,1].max @curframe=0 @rect=oldrect.clone end def set(rect) rect.set(@rect.x,@rect.y,@rect.width,@rect.height) end def done? @curframe>@frames end def update return if done? t=(@curframe*1.0/@frames) x1=@oldrect.x x2=@newrect.x x=x1+t*(x2-x1) y1=@oldrect.y y2=@newrect.y y=y1+t*(y2-y1) rx1=@oldrect.x+@oldrect.width rx2=@newrect.x+@newrect.width rx=rx1+t*(rx2-rx1) ry1=@oldrect.y+@oldrect.height ry2=@newrect.y+@newrect.height ry=ry1+t*(ry2-ry1) minx=x<rx ? x : rx maxx=x>rx ? x : rx miny=y<ry ? y : ry maxy=y>ry ? y : ry @rect.set(minx,miny,maxx-minx,maxy-miny) @curframe+=1 end end class PointInterpolator def initialize(oldx,oldy,newx,newy,frames) restart(oldx,oldy,newx,newy,frames) end def restart(oldx,oldy,newx,newy,frames) @oldx=oldx @oldy=oldy @newx=newx @newy=newy @frames=frames @curframe=0 @x=oldx @y=oldy end def x; @x;end def y; @y;end def done? @curframe>@frames end def update return if done? t=(@curframe*1.0/@frames) rx1=@oldx rx2=@newx @x=rx1+t*(rx2-rx1) ry1=@oldy ry2=@newy @y=ry1+t*(ry2-ry1) @curframe+=1 end end def pbHiddenMoveAnimation(pokemon) return false if !pokemon viewport=Viewport.new(0,0,0,0) viewport.z=99999 ptinterp=nil pkmnbitmap=pbLoadPokemonBitmap(pokemon) interp=RectInterpolator.new( Rect.new(Graphics.width,Graphics.height/2,0,0), Rect.new(0,(Graphics.height-pkmnbitmap.height)/2, Graphics.width,pkmnbitmap.height),20 ) plane=ColoredPlane.new(Color.new(0,0,0,255),viewport) sprite=Sprite.new sprite.z=99999 sprite.bitmap=pkmnbitmap sprite.visible=false sprite.ox=pkmnbitmap.width/2 sprite.oy=pkmnbitmap.height/2 strobes=[] 15.times do |i| strobe=Sprite.new(viewport) strobe.bitmap=Bitmap.new(80,8) strobe.bitmap.fill_rect(0,0,80,8,Color.new(248,248,248)) strobe.visible=false strobes.push(strobe) end phase=1 frames=0 begin Graphics.update Input.update case phase when 1 interp.update interp.set(viewport.rect) if interp.done? phase=2 ptinterp=PointInterpolator.new( Graphics.width+(sprite.bitmap.width/2),Graphics.height/2, Graphics.width/2,Graphics.height/2,15 ) end when 2 ptinterp.update sprite.x=ptinterp.x sprite.y=ptinterp.y sprite.visible=true if ptinterp.done? phase=3 pbPlayCry(pokemon.species) frames=0 end when 3 frames+=1 if frames>30 phase=4 ptinterp=PointInterpolator.new( Graphics.width/2,Graphics.height/2, -(sprite.bitmap.width/2),Graphics.height/2,15 ) frames=0 end when 4 ptinterp.update sprite.x=ptinterp.x sprite.y=ptinterp.y if ptinterp.done? phase=5 sprite.visible=false interp=RectInterpolator.new( Rect.new(0,(Graphics.height-pkmnbitmap.height)/2, Graphics.width,pkmnbitmap.height), Rect.new(0,(Graphics.height)/2,Graphics.width,0),20 ) end when 5 interp.update interp.set(viewport.rect) phase=6 if interp.done? end for strobe in strobes strobe.ox=strobe.viewport.rect.x strobe.oy=strobe.viewport.rect.y if strobe.visible && strobe.x+strobe.src_rect.width>=0 strobe.x-=32 elsif !strobe.visible randomY=[80,100,120,140,160,180,200,220,240] strobe.y=randomY[rand(randomY.length)] strobe.x=rand(Graphics.width) strobe.src_rect.width=20+rand(40) strobe.visible=true else randomY=[80,100,120,140,160,180,200,220,240] strobe.y=randomY[rand(randomY.length)] strobe.x=Graphics.width+rand(Graphics.width/4) strobe.src_rect.width=20+rand(40) end end pbUpdateSceneMap end while phase!=6 sprite.bitmap.dispose sprite.dispose for strobe in strobes strobe.bitmap.dispose strobe.dispose end strobes.clear plane.dispose viewport.dispose return true end def pbRockSmashRandomEncounter if rand(100)<25 pbEncounter(3) end end def Kernel.pbHeadbuttEffect(event) a=((event.x*event.y+event.x*event.y)/5)%10 b=($Trainer.id&0xFFFF)%10 chance=1 if a==b chance=8 elsif a>b && (a-b).abs<5 chance=5 elsif a<b && (a-b).abs>5 chance=5 end if rand(10)>=chance Kernel.pbMessage(_INTL("Nope. Nothing...")) else if !pbEncounter(chance==1 ? 7 : 8) Kernel.pbMessage(_INTL("Nope. Nothing...")) end end end def Kernel.pbHeadbutt(event) movefinder=Kernel.pbCheckMove(PBMoves::HEADBUTT) if $DEBUG || movefinder if Kernel.pbConfirmMessage(_INTL("A Pokémon could be in this tree. Want to headbutt it?")) speciesname=!movefinder ? PBSpecies.getName(0) : movefinder.name Kernel.pbMessage(_INTL("{1} did a headbutt!",speciesname)) Kernel.pbHeadbuttEffect(event) end else Kernel.pbMessage(_INTL("A Pokémon could be in this tree. Maybe a Pokémon could shake it.")) end Input.update return end def Kernel.pbRockSmash if $DEBUG || $Trainer.badges[BADGEFORROCKSMASH] movefinder=Kernel.pbCheckMove(PBMoves::ROCKSMASH) if $DEBUG || movefinder if Kernel.pbConfirmMessage(_INTL("This rock appears breakable. Would you like to use Rock Smash?")) speciesname=!movefinder ? PBSpecies.getName(0) : movefinder.name Kernel.pbMessage(_INTL("{1} used Rock Smash!",speciesname)) pbHiddenMoveAnimation(movefinder) return true end else Kernel.pbMessage(_INTL("It's a rugged rock, but a Pokémon may be able to smash it.")) end else Kernel.pbMessage(_INTL("It's a rugged rock, but a Pokémon may be able to smash it.")) end return false end def Kernel.pbStrength if $PokemonMap.strengthUsed Kernel.pbMessage(_INTL("Strength made it possible to move boulders around.")) elsif $DEBUG || $Trainer.badges[BADGEFORSTRENGTH] movefinder=Kernel.pbCheckMove(PBMoves::STRENGTH) if $DEBUG || movefinder Kernel.pbMessage(_INTL("It's a big boulder, but a Pokémon may be able to push it aside.")) if Kernel.pbConfirmMessage(_INTL("Would you like to use Strength?")) speciesname=!movefinder ? PBSpecies.getName(0) : movefinder.name pbHiddenMoveAnimation(movefinder) Kernel.pbMessage(_INTL("{1} used Strength!\\1",speciesname)) Kernel.pbMessage(_INTL("{1}'s Strength made it possible to move boulders around!",speciesname)) $PokemonMap.strengthUsed=true return true end else Kernel.pbMessage(_INTL("It's a big boulder, but a Pokémon may be able to push it aside.")) end else Kernel.pbMessage(_INTL("It's a big boulder, but a Pokémon may be able to push it aside.")) end return false end def Kernel.pbSurf if $game_player.pbHasDependentEvents? return false end if $DEBUG || $Trainer.badges[BADGEFORSURF] movefinder=Kernel.pbCheckMove(PBMoves::SURF) if $DEBUG || movefinder if Kernel.pbConfirmMessage(_INTL("The water is dyed a deep blue... Would you like to surf?")) speciesname=!movefinder ? PBSpecies.getName(0) : movefinder.name Kernel.pbMessage(_INTL("{1} used Surf!",speciesname)) pbHiddenMoveAnimation(movefinder) surfbgm=pbGetMetadata(0,MetadataSurfBGM) if surfbgm pbCueBGM(surfbgm,0.5) end Kernel.pbCancelVehicles $PokemonGlobal.surfing=true $PokemonEncounters.clearStepCount Kernel.pbJumpToward Kernel.pbUpdateVehicle $game_player.check_event_trigger_here([1,2]) return true end end end return false end def Kernel.pbSurfacing return if !$PokemonGlobal.diving divemap=nil meta=pbLoadMetadata for i in 0...meta.length if meta[i] && meta[i][MetadataDiveMap] if meta[i][MetadataDiveMap]==$game_map.map_id divemap=i break end end end return if !divemap movefinder=Kernel.pbCheckMove(PBMoves::DIVE) if $DEBUG || movefinder if Kernel.pbConfirmMessage(_INTL("Light is filtering down from above. Would you like to use Dive?")) speciesname=!movefinder ? PBSpecies.getName(0) : movefinder.name Kernel.pbMessage(_INTL("{1} used Dive.",speciesname)) pbHiddenMoveAnimation(movefinder) pbFadeOutIn(99999){ $game_temp.player_new_map_id=divemap $game_temp.player_new_x=$game_player.x $game_temp.player_new_y=$game_player.y $game_temp.player_new_direction=$game_player.direction pbCancelVehicles $PokemonGlobal.surfing=true pbUpdateVehicle $scene.transfer_player(false) surfbgm=pbGetMetadata(0,MetadataSurfBGM) if surfbgm $game_system.bgm_play(surfbgm) else $game_map.autoplayAsCue end $game_map.refresh } return true end else raise _INTL("Can't find Pokémon with Dive...") end return false end def Kernel.pbAscendWaterfall return if $game_player.direction!=8 oldthrough=$game_player.through oldmovespeed=$game_player.move_speed terrain=Kernel.pbFacingTerrainTag return if terrain!=PBTerrain::Waterfall && terrain!=PBTerrain::WaterfallCrest $game_player.through=true $game_player.move_speed=2 loop do $game_player.move_up terrain=$game_player.terrain_tag break if terrain!=PBTerrain::Waterfall && terrain!=PBTerrain::WaterfallCrest end $game_player.through=oldthrough $game_player.move_speed=oldmovespeed end def Kernel.pbDescendWaterfall return if $game_player.direction!=2 oldthrough=$game_player.through oldmovespeed=$game_player.move_speed terrain=Kernel.pbFacingTerrainTag return if terrain!=PBTerrain::Waterfall && terrain!=PBTerrain::WaterfallCrest $game_player.through=true $game_player.move_speed=2 loop do $game_player.move_down terrain=$game_player.terrain_tag break if terrain!=PBTerrain::Waterfall && terrain!=PBTerrain::WaterfallCrest end $game_player.through=oldthrough $game_player.move_speed=oldmovespeed end def Kernel.pbSlideOnIce direction=$game_player.direction continuing=true oldwalkanime=$game_player.walk_anime $game_player.straighten $game_player.walk_anime=false begin break if !$game_player.passable?( $game_player.x,$game_player.y,direction) case direction when 2 $game_player.move_down when 4 $game_player.move_left when 6 $game_player.move_right when 8 $game_player.move_up end while $game_player.moving? Graphics.update Input.update pbUpdateSceneMap end end while $game_player.terrain_tag==PBTerrain::Ice $game_player.walk_anime=oldwalkanime end def Kernel.pbWaterfall if $DEBUG || $Trainer.badges[BADGEFORWATERFALL] movefinder=Kernel.pbCheckMove(PBMoves::WATERFALL) if $DEBUG || movefinder if Kernel.pbConfirmMessage(_INTL("It's a large waterfall. Would you like to use Waterfall?")) speciesname=!movefinder ? PBSpecies.getName(0) : movefinder.name Kernel.pbMessage(_INTL("{1} used Waterfall.",speciesname)) pbHiddenMoveAnimation(movefinder) pbAscendWaterfall return true end else Kernel.pbMessage(_INTL("A wall of water is crashing down with a mighty roar.")) end else Kernel.pbMessage(_INTL("A wall of water is crashing down with a mighty roar.")) end return false end def Kernel.pbDive divemap=pbGetMetadata($game_map.map_id,MetadataDiveMap) return false if !divemap if $DEBUG || $Trainer.badges[BADGEFORDIVE] movefinder=Kernel.pbCheckMove(PBMoves::DIVE) if $DEBUG || movefinder if Kernel.pbConfirmMessage(_INTL("The sea is deep here. Would you like to use Dive?")) speciesname=!movefinder ? PBSpecies.getName(0) : movefinder.name Kernel.pbMessage(_INTL("{1} used Dive.",speciesname)) pbHiddenMoveAnimation(movefinder) pbFadeOutIn(99999){ $game_temp.player_new_map_id=divemap $game_temp.player_new_x=$game_player.x $game_temp.player_new_y=$game_player.y $game_temp.player_new_direction=$game_player.direction pbCancelVehicles $PokemonGlobal.diving=true pbUpdateVehicle $scene.transfer_player(false) $game_map.autoplay $game_map.refresh } return true end else Kernel.pbMessage(_INTL("The sea is deep here. A Pokémon may be able to go underwater.")) end else Kernel.pbMessage(_INTL("The sea is deep here. A Pokémon may be able to go underwater.")) end return false end def pbEndSurf(xOffset,yOffset) return false if !$PokemonGlobal.surfing x=$game_player.x y=$game_player.y currentTag=$game_map.terrain_tag(x,y) facingTag=Kernel.pbFacingTerrainTag if pbIsWaterTag?(currentTag)&&!pbIsWaterTag?(facingTag) if Kernel.pbJumpToward Kernel.pbCancelVehicles $game_map.autoplayAsCue increase_steps result=$game_player.check_event_trigger_here([1,2]) Kernel.pbOnStepTaken(result) end return true end return false end class Interpreter def pbPushThisBoulder if $PokemonMap.strengthUsed pbPushThisEvent end return true end def pbHeadbutt Kernel.pbHeadbutt(get_character(0)) return true end def pbTrainerEnd pbGlobalUnlock e=get_character(0) e.erase_route if e end def pbTrainerIntro(symbol) if $DEBUG return if !Kernel.pbTrainerTypeCheck(symbol) end trtype=PBTrainers.const_get(symbol) pbGlobalLock Kernel.pbPlayTrainerIntroME(trtype) return true end def pbSetEventTime(*arg) $PokemonGlobal.eventvars={} if !$PokemonGlobal.eventvars time=Time.now.to_i pbSetSelfSwitch(@event_id,"A",true) $PokemonGlobal.eventvars[[@map_id,@event_id]]=time for otherevt in arg pbSetSelfSwitch(otherevt,"A",true) $PokemonGlobal.eventvars[[@map_id,otherevt]]=time end end def getVariable return nil if !$PokemonGlobal.eventvars return $PokemonGlobal.eventvars[[@map_id,@event_id]] end def setVariable(value) $PokemonGlobal.eventvars={} if !$PokemonGlobal.eventvars $PokemonGlobal.eventvars[[@map_id,@event_id]]=value end def setTempSwitchOn(c) get_character(0).setTempSwitchOn(c) end def setTempSwitchOff(c) get_character(0).setTempSwitchOff(c) end def command_353 $game_system.bgm_fade(1.0) $game_system.bgs_fade(1.0) pbFadeOutIn(99999){ Kernel.pbStartOver(true) } end def command_314 if @parameters[0] == 0 && $Trainer && $Trainer.party for i in $Trainer.party; i.heal; end end return true end def command_352 scene=PokemonSaveScene.new screen=PokemonSave.new(scene) screen.pbSaveScreen return true end def command_125 value = operate_value(@parameters[0], @parameters[1], @parameters[2]) $Trainer.money+=value $Trainer.money=0 if $Trainer.money<0 $Trainer.money=999999 if $Trainer.money>999999 return true end def command_132 $PokemonGlobal.nextBattleBGM=(@parameters[0]) ? @parameters[0].clone : nil return true end def command_133 $PokemonGlobal.nextBattleME=(@parameters[0]) ? @parameters[0].clone : nil return true end end def Kernel.pbCanUseHiddenMove?(pkmn,move) case move when PBMoves::FLY if !$DEBUG && !$Trainer.badges[BADGEFORFLY] Kernel.pbMessage(_INTL("Sorry, a new Badge is required.")) return false end if $game_player.pbHasDependentEvents? Kernel.pbMessage(_INTL("You can't use that if you have someone with you.")) return false end if !pbGetMetadata($game_map.map_id,MetadataOutdoor) Kernel.pbMessage(_INTL("Can't use that here.")) return false end return true when PBMoves::CUT if !$DEBUG && !$Trainer.badges[BADGEFORCUT] Kernel.pbMessage(_INTL("Sorry, a new Badge is required.")) return false end facingEvent=$game_player.pbFacingEvent if !facingEvent || facingEvent.name!="Tree" Kernel.pbMessage(_INTL("Can't use that here.")) return false end return true when PBMoves::HEADBUTT facingEvent=$game_player.pbFacingEvent if !facingEvent || facingEvent.name!="HeadbuttTree" Kernel.pbMessage(_INTL("Can't use that here.")) return false end return true when PBMoves::SURF terrain=Kernel.pbFacingTerrainTag if !$DEBUG && !$Trainer.badges[BADGEFORCUT] Kernel.pbMessage(_INTL("Sorry, a new Badge is required.")) return false end if $PokemonGlobal.surfing Kernel.pbMessage(_INTL("You're already surfing.")) return false end if $game_player.pbHasDependentEvents? Kernel.pbMessage(_INTL("You can't use that if you have someone with you.")) return false end terrain=Kernel.pbFacingTerrainTag if pbGetMetadata($game_map.map_id,MetadataBicycleAlways) Kernel.pbMessage(_INTL("Let's enjoy cycling!")) return false end if !pbIsWaterTag?(terrain) Kernel.pbMessage(_INTL("No surfing here!")) return false end return true when PBMoves::STRENGTH if !$DEBUG && !$Trainer.badges[BADGEFORSTRENGTH] Kernel.pbMessage(_INTL("Sorry, a new Badge is required.")) return false end facingEvent=$game_player.pbFacingEvent if !facingEvent || facingEvent.name!="Boulder" Kernel.pbMessage(_INTL("Can't use that here.")) return false end return true when PBMoves::ROCKSMASH terrain=Kernel.pbFacingTerrainTag if !$DEBUG && !$Trainer.badges[BADGEFORROCKSMASH] Kernel.pbMessage(_INTL("Sorry, a new Badge is required.")) return false end facingEvent=$game_player.pbFacingEvent if !facingEvent || facingEvent.name!="Rock" Kernel.pbMessage(_INTL("Can't use that here.")) return false end return true when PBMoves::FLASH if !$DEBUG && !$Trainer.badges[BADGEFORFLASH] Kernel.pbMessage(_INTL("Sorry, a new Badge is required.")) return false end if !pbGetMetadata($game_map.map_id,MetadataDarkMap) Kernel.pbMessage(_INTL("Can't use that here.")) return false end if $PokemonGlobal.flashUsed Kernel.pbMessage(_INTL("This is in use already.")) return false end return true when PBMoves::WATERFALL if !$DEBUG && !$Trainer.badges[BADGEFORWATERFALL] Kernel.pbMessage(_INTL("Sorry, a new Badge is required.")) return false end terrain=Kernel.pbFacingTerrainTag if terrain!=PBTerrain::Waterfall Kernel.pbMessage(_INTL("Can't use that here.")) return false end return true when PBMoves::DIVE if !$DEBUG && !$Trainer.badges[BADGEFORDIVE] Kernel.pbMessage(_INTL("Sorry, a new Badge is required.")) return false end if $PokemonGlobal.diving return true end if $game_player.terrain_tag!=PBTerrain::DeepWater Kernel.pbMessage(_INTL("Can't use that here.")) return false end if !pbGetMetadata($game_map.map_id,MetadataDiveMap) Kernel.pbMessage(_INTL("Can't use that here.")) return false end return true when PBMoves::TELEPORT if !pbGetMetadata($game_map.map_id,MetadataOutdoor) Kernel.pbMessage(_INTL("Can't use that here.")) return false end if $game_player.pbHasDependentEvents? Kernel.pbMessage(_INTL("You can't use that if you have someone with you.")) return false end healing=$PokemonGlobal.healingSpot if !healing healing=pbGetMetadata(0,MetadataHome) # Home end if healing mapname=pbGetMapNameFromId(healing[0]) if Kernel.pbConfirmMessage(_INTL("Want to return to the healing spot used last in {1}?",mapname)) return true end return false else Kernel.pbMessage(_INTL("Can't use that here.")) return false end when PBMoves::DIG escape=pbGetMetadata($game_map.map_id,MetadataEscapePoint) if !escape Kernel.pbMessage(_INTL("Can't use that here.")) return false end if $game_player.pbHasDependentEvents? Kernel.pbMessage(_INTL("You can't use that if you have someone with you.")) return false end mapname=pbGetMapNameFromId(escape[0]) if Kernel.pbConfirmMessage(_INTL("Want to escape from here and return to {1}?",mapname)) return true end return false when PBMoves::SWEETSCENT return true else return HiddenMoveHandlers.triggerCanUseMove(move,pkmn) end return false end def Kernel.pbUseHiddenMove(pokemon,move,flydata=nil) case move when PBMoves::FLY if !pbHiddenMoveAnimation(pokemon) Kernel.pbMessage(_INTL("{1} used Fly!",pokemon.name)) end pbFadeOutIn(99999){ Kernel.pbCancelVehicles $game_temp.player_new_map_id=flydata[0] $game_temp.player_new_x=flydata[1] $game_temp.player_new_y=flydata[2] $game_temp.player_new_direction=2 $scene.transfer_player $game_map.autoplay $game_map.refresh } return true when PBMoves::CUT if !pbHiddenMoveAnimation(pokemon) Kernel.pbMessage(_INTL("{1} used Cut!",pokemon.name)) end facingEvent=$game_player.pbFacingEvent if facingEvent facingEvent.erase $PokemonMap.addErasedEvent(facingEvent.id) end return true when PBMoves::SURF if !pbHiddenMoveAnimation(pokemon) Kernel.pbMessage(_INTL("{1} used Surf!",pokemon.name)) end Kernel.pbCancelVehicles $PokemonEncounters.clearStepCount $PokemonGlobal.surfing=true Kernel.pbJumpToward Kernel.pbUpdateVehicle $game_player.check_event_trigger_here([1,2]) return true when PBMoves::STRENGTH pbHiddenMoveAnimation(pokemon) Kernel.pbMessage(_INTL("{1} used Strength!\\1",pokemon.name)) Kernel.pbMessage(_INTL("{1}'s Strength made it possible to move boulders around!",pokemon.name)) $PokemonGlobal.strengthUsed=true return true when PBMoves::ROCKSMASH if !pbHiddenMoveAnimation(pokemon) Kernel.pbMessage(_INTL("{1} used Rock Smash!",pokemon.name)) end facingEvent=$game_player.pbFacingEvent if facingEvent facingEvent.erase $PokemonMap.addErasedEvent(facingEvent.id) end return true when PBMoves::FLASH darkness=$PokemonTemp.darknessSprite return false if !darkness || darkness.disposed? if !pbHiddenMoveAnimation(pokemon) Kernel.pbMessage(_INTL("{1} used Flash!",pokemon.name)) end $PokemonGlobal.flashUsed=true while darkness.radius<300 Graphics.update Input.update pbUpdateSceneMap darkness.radius+=2 end darkness.dispose $PokemonTemp.darknessSprite=nil return true when PBMoves::WATERFALL if !pbHiddenMoveAnimation(pokemon) Kernel.pbMessage(_INTL("{1} used Waterfall.",pokemon.name)) end pbAscendWaterfall return true when PBMoves::DIVE wasdiving=$PokemonGlobal.diving if $PokemonGlobal.diving divemap=nil meta=pbLoadMetadata for i in 0...meta.length if meta[i] && meta[i][MetadataDiveMap] if meta[i][MetadataDiveMap]==$game_map.map_id divemap=i break end end end else divemap=pbGetMetadata($game_map.map_id,MetadataDiveMap) end return false if !divemap if !pbHiddenMoveAnimation(pokemon) Kernel.pbMessage(_INTL("{1} used Dive.",speciesname)) end pbFadeOutIn(99999){ $game_temp.player_new_map_id=divemap $game_temp.player_new_x=$game_player.x $game_temp.player_new_y=$game_player.y $game_temp.player_new_direction=$game_player.direction pbCancelVehicles if wasdiving $PokemonGlobal.surfing=true else $PokemonGlobal.diving=true end pbUpdateVehicles $scene.transfer_player(false) $game_map.autoplay $game_map.refresh } return true when PBMoves::HEADBUTT if !pbHiddenMoveAnimation(pokemon) Kernel.pbMessage(_INTL("{1} used Headbutt!",pokemon.name)) end Kernel.pbHeadbuttEffect(event) when PBMoves::SWEETSCENT if !pbHiddenMoveAnimation(pokemon) Kernel.pbMessage(_INTL("{1} used Sweet Scent!",pokemon.name)) end pbSweetScent return true when PBMoves::DIG escape=pbGetMetadata($game_map.map_id,MetadataEscapePoint) if escape Kernel.pbMessage(_INTL("{1} used Dig!",pokemon.name)) pbFadeOutIn(99999){ Kernel.pbCancelVehicles $game_temp.player_new_map_id=escape[0] $game_temp.player_new_x=escape[1] $game_temp.player_new_y=escape[2] $game_temp.player_new_direction=2 $scene.transfer_player $game_map.autoplay $game_map.refresh } return true end return false when PBMoves::TELEPORT healing=$PokemonGlobal.healingSpot if !healing healing=pbGetMetadata(0,MetadataHome) end if healing Kernel.pbMessage(_INTL("{1} used Teleport!",pokemon.name)) pbFadeOutIn(99999){ Kernel.pbCancelVehicles $game_temp.player_new_map_id=healing[0] $game_temp.player_new_x=healing[1] $game_temp.player_new_y=healing[2] $game_temp.player_new_direction=2 $scene.transfer_player $game_map.autoplay $game_map.refresh } return true end return false else return HiddenMoveHandlers.triggerUseMove(move,pokemon) end end def pbSweetScent viewport=Viewport.new(0,0,Graphics.width,Graphics.height) viewport.z=99999 count=0 viewport.color.alpha-=10 begin if viewport.color.alpha<128 && count==0 viewport.color.red=255 viewport.color.green=0 viewport.color.blue=0 viewport.color.alpha+=10 else count+=1 if count>60 viewport.color.alpha-=10 end end Graphics.update Input.update pbUpdateSceneMap end until viewport.color.alpha<=0 viewport.dispose encounter=nil enctype=nil if $PokemonGlobal.surfing enctype=2 elsif $PokemonEncounters.isCave? enctype=1 elsif $PokemonEncounters.isGrass? && pbIsGrassTag?($game_player.terrain_tag) enctype=pbLandEncounterType end if !enctype || !pbEncounter(enctype) Kernel.pbMessage(_INTL("There appears to be nothing here...")) end end def pbUseKeyItem if $PokemonBag.registeredItem==0 Kernel.pbMessage(_INTL("A Key Item in the Bag can be registered to this key for instant use.")) else Kernel.pbUseKeyItemInField($PokemonBag.registeredItem) end end def Kernel.pbHiddenMoveEvent $PokemonTemp.hiddenMoveEventCalling=false terrain=Kernel.pbFacingTerrainTag if pbIsWaterTag?(terrain) && !$PokemonGlobal.surfing && !pbGetMetadata($game_map.map_id,MetadataBicycleAlways) Kernel.pbSurf return end if terrain==PBTerrain::Waterfall Kernel.pbWaterfall return end if terrain==PBTerrain::WaterfallCrest Kernel.pbMessage(_INTL("A wall of water is crashing down with a mighty roar.")) return end terrain=$game_player.terrain_tag if terrain==PBTerrain::DeepWater Kernel.pbDive return end if $PokemonGlobal.diving Kernel.pbSurfacing return end facingEvent=$game_player.pbFacingEvent if facingEvent if facingEvent.name=="Boulder" Kernel.pbStrength return end end end
PokemonScreen
[
Selecionar
] [
-
]
# Data structure representing mail that the Pokémon can hold class PokemonMail attr_accessor :item,:message,:sender def initialize(item,message,sender) @item=item # Item represented by this mail @message=message # Message text @sender=sender # Name of the message's sender end end def pbMoveToMailbox(pokemon) if !$PokemonGlobal.mailbox $PokemonGlobal.mailbox=[] end if $PokemonGlobal.mailbox.length>=10 return false end if !pokemon.mail return false end $PokemonGlobal.mailbox.push(pokemon.mail) pokemon.mail=nil return true end def pbStoreMail(pkmn,item,message) if pkmn.mail raise _INTL("Pokémon already has mail") end pkmn.mail=PokemonMail.new(item,message,$Trainer.name) end def pbDisplayMail(mail,bearer=nil) sprites={} viewport=Viewport.new(0,0,Graphics.width,Graphics.height) viewport.z=99999 addBackgroundPlane(@sprites,"background","mailbg",@viewport) sprites["card"]=Sprite.new(viewport) sprites["card"].bitmap=BitmapCache.load_bitmap(sprintf("Graphics/Pictures/item%03d.png",mail.item)) sprites["overlay"]=Sprite.new(viewport) sprites["overlay"].bitmap=Bitmap.new(Graphics.width,Graphics.height) overlay=sprites["overlay"].bitmap pbSetSystemFont(overlay) if $ItemData[mail.item][ITEMTYPE]==2 && bearer sprites["bearer"]=IconSprite.new(48,224,viewport) sprites["bearer"].setBitmap(pbPokemonIconFile(bearer)) sprites["bearer"].src_rect.set(0,0,64,64) end if mail.message && mail.message!="" drawTextEx(overlay,48,64,360,5,mail.message, Color.new(10*8,10*8,10*8),Color.new(25*8,25*8,25*8)) end if mail.sender && mail.sender!="" drawTextEx(overlay,240,240,240,1,_INTL("From {1}",mail.sender), Color.new(10*8,10*8,10*8),Color.new(25*8,25*8,25*8)) end pbFadeInAndShow(sprites) loop do Graphics.update Input.update pbUpdateSpriteHash(sprites) if Input.trigger?(Input::B) || Input.trigger?(Input::C) break end end pbFadeOutAndHide(sprites) pbDisposeSpriteHash(sprites) viewport.dispose end ########################### class PokemonPartyIcon < SpriteWrapper attr_accessor :selected attr_accessor :active attr_reader :pokemon def initialize(pokemon,active,viewport=nil) super(viewport) @animbitmap=nil @frames=[ Rect.new(0,0,64,64), Rect.new(64,0,64,64) ] @active=active @selected=false @animframe=0 self.pokemon=pokemon @frame=0 @pokemon=pokemon @spriteX=self.x @spriteY=self.y @updating=false end def pokemon=(value) @animbitmap.dispose if @animbitmap @animbitmap=pbLoadPokemonIcon(value) self.bitmap=@animbitmap self.src_rect=@frames[@animframe] end def dispose @animbitmap.dispose super end def x=(value) super @spriteX=value if !@updating end def y=(value) super @spriteY=value if !@updating end def update @updating=true super frameskip=5 frameskip=10 if @pokemon.hp<=(@pokemon.totalhp/2) frameskip=20 if @pokemon.hp<=(@pokemon.totalhp/4) frameskip=-1 if @pokemon.hp==0 if frameskip==-1 @animframe=0 self.src_rect=@frames[@animframe] else @frame+=1 @frame=0 if @frame>100 if @frame>=frameskip @animframe=(@animframe==1) ? 0 : 1 self.src_rect=@frames[@animframe] @frame=0 end end if self.selected if !self.active self.x=@spriteX+8 self.y=(@animframe==0) ? @spriteY-6 : @spriteY+2 else self.x=@spriteX self.y=(@animframe==0) ? @spriteY+2 : @spriteY+10 end end @updating=false end end class PokeSelectionPlaceholderSprite < SpriteWrapper attr_accessor :text def initialize(pokemon,index,doublebattle,viewport=nil) super(viewport) if !doublebattle xvalues=[16,192,192,192,192,192] yvalues=[52,20,68,116,164,212] else xvalues=[16,16,192,192,192,192] yvalues=[20,132,20,84,148,212] end self.bitmap=BitmapCache.load_bitmap("Graphics/Pictures/advPartyEmpty.png") self.x=xvalues[index] self.y=yvalues[index] @text=nil end def selected return false end def selected=(value) end def preselected return false end def preselected=(value) end def refresh end def dispose self.bitmap.dispose super end end class PokeSelectionConfirmCancelSprite < SpriteWrapper attr_reader :selected def initialize(text,x,y,smallicons=false,viewport=nil) super(viewport) @refreshBitmap=true @deselbitmap=Bitmap.new("Graphics/Pictures/pokeselcancel.png") @selbitmap=Bitmap.new("Graphics/Pictures/pokeselcancelsel.png") if smallicons @pokeballdesel=BitmapCache.load_bitmap("Graphics/Pictures/pokeselballsm.png") @pokeballsel=BitmapCache.load_bitmap("Graphics/Pictures/pokeselopenballsm.png") else @pokeballdesel=BitmapCache.load_bitmap("Graphics/Pictures/pokeselball.png") @pokeballsel=BitmapCache.load_bitmap("Graphics/Pictures/pokeselopenball.png") end pbSetSmallFont(@deselbitmap) pbSetSmallFont(@selbitmap) @yoffset=(smallicons) ? 0 : 8 base=Color.new(31*8,31*8,31*8) shadow=Color.new(14*8,14*8,14*8) textpos=[ [text,(smallicons) ? 24 : 36,4,false,base,shadow], ] pbDrawTextPositions(@deselbitmap,textpos) pbDrawTextPositions(@selbitmap,textpos) @pokeballsprite=SpriteWrapper.new(viewport) @pokeballsprite.z=self.z+1 # For compatibility with RGSS2 self.x=x self.y=y end def dispose @selbitmap.dispose @deselbitmap.dispose @pokeballsprite.dispose @pokeballsel.dispose @pokeballdesel.dispose super end def viewport=(value) super refresh end def color=(value) super refresh end def x=(value) super refresh end def y=(value) super refresh end def selected=(value) @selected=value refresh end def refresh self.bitmap=(@selected) ? @selbitmap : @deselbitmap if @pokeballsprite && !@pokeballsprite.disposed? @pokeballsprite.x=self.x-8 @pokeballsprite.y=self.y-@yoffset @pokeballsprite.bitmap=self.selected ? @pokeballsel : @pokeballdesel @pokeballsprite.color=self.color end end end class PokeSelectionCancelSprite < PokeSelectionConfirmCancelSprite def initialize(viewport=nil) super(_INTL("CANCEL"),186*2,136*2,false,viewport) end end class PokeSelectionConfirmSprite < PokeSelectionConfirmCancelSprite def initialize(viewport=nil) super(_INTL("CONFIRM"),187*2,256,true,viewport) end end class PokeSelectionCancelSprite2 < PokeSelectionConfirmCancelSprite def initialize(viewport=nil) super(_INTL("CANCEL"),187*2,288,true,viewport) end end class PokeSelectionSprite < SpriteWrapper attr_reader :selected attr_reader :preselected attr_reader :pokemon attr_reader :active attr_accessor :text def initialize(pokemon,index,doublebattle,viewport=nil) super(viewport) @pokemon=pokemon active=(doublebattle) ? (index<2) : (index<1) @active=active if active @deselbitmap=BitmapCache.load_bitmap("Graphics/Pictures/advPartyActive.png") @selbitmap=BitmapCache.load_bitmap("Graphics/Pictures/advPartyActiveSel.png") @spriteXOffset=-16 @spriteYOffset=-2 @pokeballXOffset=-16 @pokeballYOffset=-16 @pokenameX=48 @pokenameY=22 @levelX=64 @levelY=40 @statusX=64 @statusY=44 @genderX=128 @genderY=40 @hpX=144 @hpY=72 @hpbarX=18 @hpbarY=62 @gaugeX=48 @gaugeY=66 @itemXOffset=16 @itemYOffset=40 @annotX=16 @annotY=64 else @deselbitmap=BitmapCache.load_bitmap("Graphics/Pictures/advPartyInactive.png") @selbitmap=BitmapCache.load_bitmap("Graphics/Pictures/advPartyInactiveSel.png") @spriteXOffset=-16 @spriteYOffset=-16 @pokeballXOffset=-16 @pokeballYOffset=-2 @pokenameX=44 @pokenameY=4 @levelX=60 @levelY=22 @statusX=60 @statusY=26 @genderX=128 @genderY=22 @hpX=274 @hpY=22 @hpbarX=146 @hpbarY=12 @gaugeX=176 @gaugeY=16 @itemXOffset=16 @itemYOffset=28 @annotX=144 @annotY=8 end if !doublebattle xvalues=[16,192,192,192,192,192] yvalues=[52,20,68,116,164,212] else xvalues=[16,16,192,192,192,192] yvalues=[20,148,20,84,148,212] end @text=nil @statuses=BitmapCache.load_bitmap(_INTL("Graphics/Pictures/statuses.png")) @hpbar=BitmapCache.load_bitmap("Graphics/Pictures/advHPBar.png") @pokeballdesel=BitmapCache.load_bitmap("Graphics/Pictures/pokeselball.png") @pokeballsel=BitmapCache.load_bitmap("Graphics/Pictures/pokeselopenball.png") @pokeballsprite=SpriteWrapper.new(viewport) @pkmnsprite=PokemonPartyIcon.new(pokemon,active,viewport) @itemsprite=SpriteWrapper.new(viewport) @itembitmap=BitmapCache.load_bitmap("Graphics/Pictures/item.png") @mailbitmap=BitmapCache.load_bitmap("Graphics/Pictures/mail.png") @itemsprite.bitmap=@itembitmap @spriteX=xvalues[index] @spriteY=yvalues[index] @selframe=0 @refreshBitmap=true @refreshing=false @preselected=false @pkmnsprite.z=self.z+2 # For compatibility with RGSS2 @itemsprite.z=self.z+3 # For compatibility with RGSS2 @pokeballsprite.z=self.z+1 # For compatibility with RGSS2 self.selected=false self.x=@spriteX self.y=@spriteY refresh end def dispose @mailbitmap.dispose @itembitmap.dispose @selbitmap.dispose @statuses.dispose @hpbar.dispose @deselbitmap.dispose @pokeballsel.dispose @pokeballdesel.dispose @itemsprite.dispose @pkmnsprite.dispose @pokeballsprite.dispose self.bitmap.dispose super end def selected=(value) @selected=value @refreshBitmap=true refresh end def text=(value) @text=value @refreshBitmap=true refresh end def pokemon=(value) @pokemon=value if @pkmnsprite && !@pkmnsprite.disposed? @pkmnsprite.pokemon=value end @refreshBitmap=true refresh end def preselected=(value) if value!=@preselected @preselected=value refresh end end def viewport=(value) super refresh end def color=(value) super refresh end def x=(value) super refresh end def y=(value) super refresh end def hp return @pokemon.hp end def refresh return if @refreshing return if disposed? @refreshing=true if !self.bitmap || self.bitmap.disposed? self.bitmap=Bitmap.new(@selbitmap.width,@selbitmap.height) pbSetSmallFont(self.bitmap) end if @pkmnsprite && !@pkmnsprite.disposed? @pkmnsprite.x=self.x+@spriteXOffset @pkmnsprite.y=self.y+@spriteYOffset @pkmnsprite.color=self.color @pkmnsprite.selected=self.selected end if @pokeballsprite && !@pokeballsprite.disposed? @pokeballsprite.x=self.x+@pokeballXOffset @pokeballsprite.y=self.y+@pokeballYOffset @pokeballsprite.bitmap=self.selected ? @pokeballsel : @pokeballdesel @pokeballsprite.color=self.color end if @itemsprite && !@itemsprite.disposed? @itemsprite.visible=(@pokemon.item>0) if @itemsprite.visible @itemsprite.bitmap=(@pokemon.mail) ? @mailbitmap : @itembitmap @itemsprite.x=self.x+@itemXOffset @itemsprite.y=self.y+@itemYOffset @itemsprite.color=self.color end end if @refreshBitmap @refreshBitmap=false if self.selected self.bitmap.blt(0,0,@selbitmap,Rect.new(0,0,@selbitmap.width,@selbitmap.height)) self.bitmap.hue_change(180) if @pokemon.hp<=0 && !@pokemon.egg? else self.bitmap.blt(0,0,@deselbitmap,Rect.new(0,0,@deselbitmap.width,@deselbitmap.height)) self.bitmap.hue_change(180) if @pokemon.hp<=0 && !@pokemon.egg? end base=Color.new(31*8,31*8,31*8) shadow=Color.new(14*8,14*8,14*8) textpos=[ [@pokemon.name,@pokenameX,@pokenameY,false,base,shadow] ] if !@pokemon.egg? if @pokemon.hp>0 && @pokemon.status==0 textpos.push([_INTL("Lv{1}",@pokemon.level),@levelX,@levelY,false,base,shadow]) end if !@text || @text.length==0 textpos.push([_ISPRINTF("{1: 3d}/{2: 3d}",@pokemon.hp,@pokemon.totalhp), @hpX,@hpY,true,base,shadow]) self.bitmap.blt(@hpbarX,@hpbarY,@hpbar,Rect.new(0,0,@hpbar.width,@hpbar.height)) end if @pokemon.gender==0 textpos.push([_INTL("♂"),@genderX,@genderY,false,Color.new(120,184,248),Color.new(0,120,248)]) elsif @pokemon.gender==1 textpos.push([_INTL("♀"),@genderX,@genderY,false,Color.new(248,128,128),Color.new(168,24,24)]) end end pbDrawTextPositions(self.bitmap,textpos) if @text && @text.length>0 pbSetSystemFont(self.bitmap) textpos.clear textpos.push([@text,@annotX,@annotY,false,base,shadow]) pbDrawTextPositions(self.bitmap,textpos) pbSetSmallFont(self.bitmap) end if !@pokemon.egg? if @pokemon.hp==0 || @pokemon.status>0 status=(@pokemon.hp==0) ? 5 : @pokemon.status-1 statusrect=Rect.new(0,16*status,44,16) self.bitmap.blt(@statusX,@statusY,@statuses,statusrect) end end if !@pokemon.egg? && (!@text || @text.length==0) hpgauge=@pokemon.totalhp==0 ? 0 : (self.hp*96/@pokemon.totalhp) hpgauge=1 if hpgauge==0 && self.hp>0 hpzone=0 hpzone=1 if self.hp<=(@pokemon.totalhp/2).floor hpzone=2 if self.hp<=(@pokemon.totalhp/4).floor hpcolors=[ Color.new(11*8,26*8,16*8), # Green Color.new(14*8,31*8,21*8), Color.new(25*8,21*8,1*8), # Orange Color.new(31*8,28*8,7*8), Color.new(21*8,8*8,9*8), # Red Color.new(31*8,11*8,7*8) ] # fill with HP color self.bitmap.fill_rect(@gaugeX,@gaugeY,hpgauge,2,hpcolors[hpzone*2]) self.bitmap.fill_rect(@gaugeX,@gaugeY+2,hpgauge,4,hpcolors[hpzone*2+1]) # fill with black self.bitmap.fill_rect(@gaugeX+hpgauge,@gaugeY,96-hpgauge,2,Color.new(0,0,0)) self.bitmap.fill_rect(@gaugeX+hpgauge,@gaugeY+2,96-hpgauge,4,Color.new(0,0,0)) end end if self.preselected self.tone=Tone.new(50,50,50) else self.tone=Tone.new(0,0,0) end @refreshing=false end def update super if @pkmnsprite && !@pkmnsprite.disposed? @pkmnsprite.update end end end ############################## class PokemonScreen_Scene def pbShowCommands(helptext,commands) ret=-1 helpwindow=@sprites["helpwindow"] helpwindow.visible=true Audio.se_play(pbGetDecisionSE) using(cmdwindow=Window_CommandPokemon.new(commands)) { cmdwindow.z=@viewport.z+1 pbBottomRight(cmdwindow) helpwindow.text="" helpwindow.resizeHeightToFit(helptext,Graphics.width-cmdwindow.width) helpwindow.text=helptext pbBottomLeft(helpwindow) loop do Graphics.update Input.update cmdwindow.update self.update if Input.trigger?(Input::B) ret=-1 break end if Input.trigger?(Input::C) Audio.se_play(pbGetDecisionSE) ret=cmdwindow.index break end end } return ret end def update pbUpdateSpriteHash(@sprites) end def pbSetHelpText(helptext) helpwindow=@sprites["helpwindow"] pbBottomLeftLines(helpwindow,1) helpwindow.text=helptext helpwindow.width=360 helpwindow.visible=true end def pbStartScene(party,starthelptext,doublebattle=false,annotations=nil,multiselect=false) @sprites={} @party=party @viewport=Viewport.new(0,0,Graphics.width,Graphics.height) @viewport.z=99999 @doublebattle=doublebattle @numactive=(@doublebattle) ? 2 : 1 @rightcolumn=(@doublebattle) ? 2 : 1 @multiselect=multiselect addBackgroundPlane(@sprites,"partybg","pokeselbg",@viewport) @sprites["messagebox"]=Window_AdvancedTextPokemon.new("") @sprites["helpwindow"]=Window_UnformattedTextPokemon.new(starthelptext) @sprites["messagebox"].viewport=@viewport @sprites["messagebox"].visible=false @sprites["messagebox"].letterbyletter=true @sprites["helpwindow"].viewport=@viewport @sprites["helpwindow"].visible=true pbBottomLeftLines(@sprites["messagebox"],2) pbBottomLeftLines(@sprites["helpwindow"],1) pbSetHelpText(starthelptext) # Add party Pokémon sprites for i in 0...6 if @party[i] @sprites["pokemon#{i}"]=PokeSelectionSprite.new( @party[i],i,@doublebattle,@viewport) else @sprites["pokemon#{i}"]=PokeSelectionPlaceholderSprite.new( @party[i],i,@doublebattle,@viewport) end if annotations @sprites["pokemon#{i}"].text=annotations[i] end end if @multiselect @sprites["pokemon6"]=PokeSelectionConfirmSprite.new(@viewport) @sprites["pokemon7"]=PokeSelectionCancelSprite2.new(@viewport) else @sprites["pokemon6"]=PokeSelectionCancelSprite.new(@viewport) end # Select first Pokémon @activecmd=0 @sprites["pokemon0"].selected=true pbFadeInAndShow(@sprites) end def pbEndScene pbFadeOutAndHide(@sprites) pbDisposeSpriteHash(@sprites) @viewport.dispose end def pbChangeSelection(key,currentsel) numsprites=(@multiselect) ? 8 : 7 case key when Input::LEFT if currentsel>=@numactive && currentsel<@party.length currentsel=0 end when Input::RIGHT if currentsel==0 && @party.length>1 currentsel=@rightcolumn end when Input::UP begin currentsel-=1 end while currentsel>0 && !@party[currentsel] if currentsel>=@party.length && currentsel<6 currentsel=@party.length-1 end currentsel=numsprites-1 if currentsel<0 when Input::DOWN begin currentsel+=1 end while currentsel<@party.length && !@party[currentsel] if currentsel==@party.length currentsel=6 elsif currentsel==numsprites currentsel=0 end end if currentsel>=@numactive && currentsel<@party.length @rightcolumn=currentsel end return currentsel end def pbRefresh for i in 0...6 sprite=@sprites["pokemon#{i}"] if sprite if sprite.is_a?(PokeSelectionSprite) sprite.pokemon=sprite.pokemon else sprite.refresh end end end end def pbRefreshSingle(i) sprite=@sprites["pokemon#{i}"] if sprite if sprite.is_a?(PokeSelectionSprite) sprite.pokemon=sprite.pokemon else sprite.refresh end end end def pbHardRefresh oldtext=[] lastselected=-1 for i in 0...6 oldtext.push(@sprites["pokemon#{i}"].text) lastselected=i if @sprites["pokemon#{i}"].selected @sprites["pokemon#{i}"].dispose end lastselected=@party.length-1 if lastselected>=@party.length lastselected=0 if lastselected<0 for i in 0...6 if @party[i] @sprites["pokemon#{i}"]=PokeSelectionSprite.new( @party[i],i,@doublebattle,@viewport) else @sprites["pokemon#{i}"]=PokeSelectionPlaceholderSprite.new( @party[i],i,@doublebattle,@viewport) end @sprites["pokemon#{i}"].text=oldtext[i] end pbSelect(lastselected) end def pbPreSelect(pkmn) @activecmd=pkmn end def pbChoosePokemon(switching=false) for i in 0...6 @sprites["pokemon#{i}"].preselected=(switching&&i==@activecmd) end loop do Graphics.update Input.update self.update oldsel=@activecmd key=-1 key=Input::DOWN if Input.repeat?(Input::DOWN) key=Input::RIGHT if Input.repeat?(Input::RIGHT) key=Input::LEFT if Input.repeat?(Input::LEFT) key=Input::UP if Input.repeat?(Input::UP) if key>=0 @activecmd=pbChangeSelection(key,@activecmd) end if @activecmd!=oldsel Audio.se_play(pbGetDecisionSE) numsprites=(@multiselect) ? 8 : 7 for i in 0...numsprites @sprites["pokemon#{i}"].selected=(i==@activecmd) end end if Input.trigger?(Input::B) return -1 end if Input.trigger?(Input::C) cancelsprite=(@multiselect) ? 7 : 6 return (@activecmd==cancelsprite) ? -1 : @activecmd end end end def pbSelect(item) @activecmd=item numsprites=(@multiselect) ? 8 : 7 for i in 0...numsprites @sprites["pokemon#{i}"].selected=(i==@activecmd) end end def pbDisplay(text) @sprites["messagebox"].text=text @sprites["messagebox"].visible=true @sprites["helpwindow"].visible=false Audio.se_play(pbGetDecisionSE) loop do Graphics.update Input.update self.update if @sprites["messagebox"].busy? && Input.trigger?(Input::C) Audio.se_play(pbGetDecisionSE) if @sprites["messagebox"].pausing? @sprites["messagebox"].resume end if !@sprites["messagebox"].busy? && (Input.trigger?(Input::C) || Input.trigger?(Input::B)) break end end @sprites["messagebox"].visible=false @sprites["helpwindow"].visible=true end def pbSwitchBegin(oldid,newid) oldsprite=@sprites["pokemon#{oldid}"] newsprite=@sprites["pokemon#{newid}"] 30.times do oldsprite.x+=(oldsprite.active) ? -8 : 12 newsprite.x+=(newsprite.active) ? -8 : 12 Graphics.update Input.update self.update end end def pbSwitchEnd(oldid,newid) oldsprite=@sprites["pokemon#{oldid}"] newsprite=@sprites["pokemon#{newid}"] oldsprite.pokemon=@party[oldid] newsprite.pokemon=@party[newid] 30.times do oldsprite.x-=(oldsprite.active) ? -8 : 12 newsprite.x-=(newsprite.active) ? -8 : 12 Graphics.update Input.update self.update end end def pbDisplayConfirm(text) ret=-1 @sprites["messagebox"].text=text @sprites["messagebox"].visible=true @sprites["helpwindow"].visible=false using(cmdwindow=Window_CommandPokemon.new([_INTL("YES"),_INTL("NO")])){ cmdwindow.z=@viewport.z+1 cmdwindow.visible=false pbBottomRight(cmdwindow) cmdwindow.y-=@sprites["messagebox"].height loop do Graphics.update Input.update cmdwindow.visible=true if !@sprites["messagebox"].busy? cmdwindow.update self.update if Input.trigger?(Input::B) && !@sprites["messagebox"].busy? ret=false end if Input.trigger?(Input::C) && @sprites["messagebox"].resume && !@sprites["messagebox"].busy? ret=(cmdwindow.index==0) break end end } @sprites["messagebox"].visible=false @sprites["helpwindow"].visible=true return ret end def pbAnnotate(annot) for i in 0...6 if annot @sprites["pokemon#{i}"].text=annot[i] end end end def pbSummary(pkmnid) oldsprites=pbFadeOutAndHide(@sprites) scene=PokemonSummaryScene.new screen=PokemonSummary.new(scene) screen.pbStartScreen(@party,pkmnid) pbFadeInAndShow(@sprites,oldsprites) end def pbChooseItem(bag) oldsprites=pbFadeOutAndHide(@sprites) @sprites["helpwindow"].visible=false @sprites["messagebox"].visible=false scene=PokemonBag_Scene.new screen=PokemonBagScreen.new(scene,bag) ret=screen.pbGiveItemScreen pbFadeInAndShow(@sprites,oldsprites) return ret end end ###################################### class PokemonScreen def initialize(scene,party) @party=party @scene=scene end def pbHardRefresh @scene.pbHardRefresh end def pbRefresh @scene.pbRefresh end def pbRefreshSingle(i) @scene.pbRefreshSingle(i) end def pbDisplay(text) @scene.pbDisplay(text) end def pbConfirm(text) return @scene.pbDisplayConfirm(text) end def pbSwitch(oldid,newid) if oldid!=newid @scene.pbSwitchBegin(oldid,newid) tmp=@party[oldid] @party[oldid]=@party[newid] @party[newid]=tmp @scene.pbSwitchEnd(oldid,newid) end end def pbMailScreen(item,pkmn) message="" loop do message=Kernel.pbMessageFreeText(_INTL("Please enter a message (max. 128 characters)."),"",false,128) if message!="" # Store mail if a message was written pbStoreMail(pkmn,item,message) return true else if pbConfirm(_INTL("Stop giving the Pokémon Mail?")) return false end end end end def pbTakeMail(pkmn) if pkmn.item==0 pbDisplay(_INTL("{1} isn't holding anything.",pkmn.name)) elsif !$PokemonBag.pbCanStore?(pkmn.item) pbDisplay(_INTL("The Bag is full. The Pokémon's item could not be removed.")) elsif pkmn.mail if pbConfirm