I've been working for the last while on a new
module-based Default-Styled Battle System for RMXP. And it was going pretty well. I added in a component for Desperation Attacks from FFVI, another one for the various Overdrive modes from FFX, and I was working on the layout for the actual Actors.
Now, I've seen the scripts to make your party be able to hold as many people as you need in them. And all of them have the same problem: The Battle Scene. The best thing you can do is squish them all up and hope for the best. I went ahead with a different idea: Having the Battle Status Window show only one person at a time (and have it only take up 1/4 the space), and then switch the focus when needed.
And then the problems really picked up.
I now am completely stumped. The game will eventually crash with this plugged in, and I still cannot figure out what the blazes the game is doing to get in this state. I'd appreciate it if anyone could take a look at this and show me where exactly I managed to go wrong. The main problem I'm having with it is that it crashes because the Battle Status window focuses on something that doesn't exist. That is, I think, because of the id numbers being thrown out in Scene_Battle during the update of phase 4, steps 3, 4, 5, and 6 (if it gets there with skills that target more than one person, it loops the second one indefinitely).
Any help would be
greatly appreciated.
class Sprite_Battler
alias trsup update
def update
trsup
if @battler.is_a?(Game_Actor)
self.x = 80
self.y = 464
self.z = 0
end
end
end
class Spriteset_Battle
attr_reader :viewport1
attr_reader :viewport2
attr_accessor :actor_id
def initialize
@viewport1 = Viewport.new(0, 0, 640, 320)
@viewport2 = Viewport.new(0, 0, 640, 480)
@viewport3 = Viewport.new(0, 0, 640, 480)
@viewport4 = Viewport.new(0, 0, 640, 480)
@viewport2.z = 101
@viewport3.z = 200
@viewport4.z = 5000
@battleback_sprite = Sprite.new(@viewport1)
@enemy_sprites = []
$game_troop.enemies.reverse.each {|enemy|
@enemy_sprites.push(Sprite_Battler.new(@viewport1, enemy))
}
@actor_sprites = []
4.times {@actor_sprites.push(Sprite_Battler.new(@viewport2))}
@actor_id = 0
@vactor = @actor_sprites[0]
@weather = RPG::Weather.new(@viewport1)
@picture_sprites = []
(51..100).each {|i|
@picture_sprites.push(Sprite_Picture.new(@viewport3,
$game_screen.pictures[i]))
}
@timer_sprite = Sprite_Timer.new
update
end
def dispose
@battleback_sprite.bitmap.dispose if @battleback_sprite.bitmap != nil
@battleback_sprite.dispose
(@enemy_sprites + @actor_sprites).each {|sprite| sprite.dispose}
@weather.dispose
@picture_sprites.each {|sprite| sprite.dispose}
@timer_sprite.dispose
@viewport1.dispose
@viewport2.dispose
@viewport3.dispose
@viewport4.dispose
end
def effect?
return (@enemy_sprites + @actor_sprites).any? {|sprite| sprite.effect?}
end
def update
@vactor.battler = $game_party.actors[@actor_id]
if @battleback_name != $game_temp.battleback_name
@battleback_name = $game_temp.battleback_name
@battleback_sprite.bitmap.dispose if @battleback_sprite.bitmap != nil
@battleback_sprite.bitmap = RPG::Cache.battleback(@battleback_name)
@battleback_sprite.src_rect.set(0, 0, 640, 320)
end
(@enemy_sprites + @actor_sprites).each {|sprite| sprite.update}
@weather.type = $game_screen.weather_type
@weather.max = $game_screen.weather_max
@weather.update
@picture_sprites.each {|sprite| sprite.update}
@timer_sprite.update
@viewport1.tone = $game_screen.tone
@viewport1.ox = $game_screen.shake
@viewport4.color = $game_screen.flash_color
@viewport1.update
@viewport2.update
@viewport4.update
end
end
class Window_BattleStatus < Window_Base
attr_accessor :actor_id
def initialize
super(0, 320, 160, 160)
self.contents = Bitmap.new(width - 32, height - 32)
@level_up = false
@actor_id = 0
refresh
end
def refresh
self.contents.clear
actor = $game_party.actors[@actor_id]
self.contents.font.size = 22
draw_actor_name(actor, actor.name.size/2+40, 0)
draw_actor_hp(actor, 4, 32, 120)
draw_actor_sp(actor, 4, 48, 120)
if @level_up
self.contents.font.color = normal_color
self.contents.draw_text(4, 72, 120, 32, 'LEVEL UP!')
else
draw_actor_state(actor, 4, 72)
end
end
def need_refresh
return false
end
def update
super
if $game_temp.battle_main_phase
self.contents_opacity -= 4 if self.contents_opacity > 191
else
self.contents_opacity += 4 if self.contents_opacity < 255
end
end
end
class Arrow_Actor < Arrow_Base
def actor
return $game_party.actors[@index]
end
def update
super
if Input.repeat?(Input::RIGHT)
$game_system.se_play($data_system.cursor_se)
@index = (@index + 1) % $game_party.actors.size
$scene.change_actor(self.actor)
elsif Input.repeat?(Input::LEFT)
$game_system.se_play($data_system.cursor_se)
@index = (@index + $game_party.actors.size - 1) % $game_party.actors.size
$scene.change_actor(self.actor)
end
if self.actor != nil
self.x = self.actor.screen_x
self.y = self.actor.screen_y
end
end
def update_help
@help_window.set_actor(self.actor)
end
end
class Scene_Battle
attr_reader :actor_id
alias as2_p3sca phase3_setup_command_window
def phase3_setup_command_window
as2_p3sca
@actor_command_window.x = 0
change_actor(@actor_index)
end
alias as2_up4s3 update_phase4_step3
def update_phase4_step3
if @active_battler.is_a?(Game_Actor) &&
@status_window.actor_id-1 != @active_battler.id
change_actor(@active_battler.id-1)
end
as2_up4s3
end
def update_phase4_step4
if @target_battler.is_a?(Game_Actor) &&
@status_window.actor_id-1 != @target_battler.id
change_actor(@target_battler.id-1)
end
if @target_battler == nil
@target_battler = @target_battlers[0]
@battler_rotations = 0
end
@target_battler.animation_id = @animation2_id
@target_battler.animation_hit = (@target_battler.damage != 'Miss')
@wait_count = 8
@phase4_step = 5
end
def update_phase4_step5
@help_window.visible = false
@status_window.refresh
@target_battler.damage_pop = true if @target_battler.damage != nil
@phase4_step = 6
end
def update_phase4_step6
if @target_battlers[@battler_rotations+1] != nil
@target_battler = @target_battlers[@battler_rotations+1]
@phase4_step = 4
else
$game_temp.forcing_battler = nil
if @common_event_id > 0
common_event = $data_common_events[@common_event_id]
$game_system.battle_interpreter.setup(common_event.list, 0)
end
@target_battler = @battler_rotations = nil
@phase4_step = 1
end
end
def change_actor(id)
@status_window.actor_id = @spriteset.actor_id = id
@status_window.refresh
end
end
What's the exact error message and at which line does it crash? Also, have you thought about using control prints to see what's actually going on?
Oops. I thought I may have forgotten something. The error message is at Window_Base, in the draw_actor_name definition. It says that there isn't a name. I did use control prints. It's being fed nil for the actor. I then traced the problem to a fault in the id numbers at the aforementioned sections of step 4.
Yep. Definitely there. You reminded me that I hadn't used control prints somewhere I'd been meaning to. The id number is normal up to a point, and then it throws out 6's and 7's during combat. I think the array I'm using has all battlers, both enemies and actors, and it's not able to counter the change.
Where do you change the ID? Find that place and add a control point. You should be able to figure out why it goes over the max boundary. Maybe you forgot a "% $game_party.actors.size"?
Quote from: Blizzard on March 25, 2009, 02:12:41 pm
Maybe you forgot a "% $game_party.actors.size"?
I didn't even know I needed it. And now that I know, it works almost perfectly. Thanks!
Well, it cycles the index. When it gets to the maximum, it starts over at 0. xD