New account registration is temporarily disabled.

PROBLEMS WITH GAME_UNIT

Posts

Pages: 1
After getting back into RPG Maker and successfully implementing a turn-based system in VX, I'm now trying to implement a turn order framework. I've managed to grouped together the functions used to determine turn order in a class Game_Battlers, inheriting from Game_Unit, without breaking the combat system. Now to make things simpler for the system, I tried to put $game_party.members and $game_troop.members into a single array "@battlers", which like the former two can be referenced with the method "members," and is initialized in Game_Battler before anything else.


#--------------------------------------------------------------------------
# * Initial Battlers Setup
#--------------------------------------------------------------------------
def setup_members
members = []
for i in $game_party.members + $game_troop.members
members.push(i)
end
end

There's a bug in this method, and I want to know what it is. To make sure it wasn't anything else, I setup combat to automatically start a game over if members.empty? returns true, and unsurprisingly it does. Naturally, this would cause the combat to break down into an infinite loop of @active_battler being nil, which is why I had to test it in this way. When I tested to see if the native members were okay, though ($game_party.members and $game_troop.members), they returned false - they weren't empty, yet members was leaving the method empty anyways.

Just be sure it wasn't the way I was doing it, I changed the method to a single line: members = $game_party.members + $game_troop.members. Short, sweet, and to the point, yet still nada. Just what the heck is going on here, and what can I do about it? Just solving it is not enough, either - I need to know the cause so I can avoid it in the rest of my code.
That code is 100% redundant, you're discarding members when you're done

@members = $game_party.members + $game_troop.members

If there's no @, Ruby interprets it as a temporary variable and it is unique from a variable with the same name but a @ at its start.

*edit*
Only for members attributes, you don't reference variables in other classes with @, just a class' own variables
EDIT: Nevermind, you were right in a way. members = defined members as local instead of using the method called members. Removing that and setting @battlers = instead solved that.

I had another problem, too, but I think I know how to resolve it. I'll post again if I don't get any results. Until then, thanks.
Of course @battlers will return empty if you're never setting it to anything. Setup_members isn't doing anything because its never storing or returning any of its work.


def setup_members
@battlers = $game_party.members + $game_troops.members
end

def members
return @battlers if @battlers != nil
return
end


When you call setup_members, it will store the contents of the party and troop inside @battlers and when you call members it returns it if its been initialized.

#--------------------------------------------------------------------------
# * Create Action Orders
#--------------------------------------------------------------------------
def make_action_orders
return if members.empty?
@action_battlers.clear
@action_battlers = members
@action_battlers -= $game_party.members if $game_troop.surprise
@action_battlers -= $game_troop.members if $game_troop.preemptive
for battler in @action_battlers
battler.action.make_speed
end
@action_battlers.sort! do |a,b|
b.action.speed - a.action.speed
end
@battler_sprites.clear
for battler in @action_battlers
@battler_sprites.push(Sprite_BattlerFace.new(@viewport, battler))
end
end

#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
return if @battler_sprites.empty?
for sprite in @battler_sprites
offset = @action_battlers.index(@active_battler) -
@action_battlers.index(sprite.battler)
sprite.update(224 - offset * 96, 256, (offset <= 2 and offset >= (-2)))
end
@viewport.update
end

Okay, so the new problem is that Sprite_BattlerFace contains a reference to a battler in @action_battlers, which is set with make_action_orders. But when it comes time to update, the game returns an error basically saying that @action_battlers.index(sprite.battler) returned nil - it couldn't find the reference back in its original source. Why is that?
One possible problem is when you're "@action_battlers = members" then subtracting battlers you're also making chances to @battlers (@action_battlers and @battlers will point to the same array). You'll probably want to .dup the array somewhere (probably in '@action_battlers = members.dup' so it's only being copied when needed)

I'm not sure if that'll fix your current problem, but I'd bet the issue is somewhere when you're cutting out battlers. In times like these, I print stuff out and check that what the game is doing is what I'm expecting. Print out the @battler_sprites and make sure everything that should be in it is there because I'm not seeing any other problems.

Also that sort! is neat and I didn't know you could do that (yes goodbye credibility)
Wow, I had some stupid preconceived idea on how print works in Ruby, and now that I've actually tried it out, it's become my new best friend. =O

Anyways, I used to discover that it was @active_battler that was going nil, not sprite.battler. Understandable: @action_battlers' lopping off the top reference and passing it to @active_battler, so it's not longer there when I go back to check. *smacks forehead* I think I can take it from here, thanks.

Also, that sorting trick is a default part of make_action_orders in both xp and vx. I didn't write it.
Last tip: You can skip
print "words " + variable.to_s + " more words"
and just do
print "word #{variable} more words"

This makes print (and p which is just short for print) a thousand times better
Pages: 1