11-15-2015, 05:14 AM
For the past while I've been struggling with the weirdest bug that emerged while making my "pure RGSS enemy AI" thingy.
If an enemy is in a confused/berserk state and the skill they use (normally only Attack) costs MP they don't have, even after they just paid the cost, the action is negated. Since it gets negated, there is no active skill (even though they already "passed go"), no targets, and the following error occurs:
Scene_Battle, line 584, NoMethodError
undefined method 'make_targets' for nil:NilClass
The line in question:
targets = @subject.current_action.make_targets.compact
This error happens because... somehow... the current_action has been erased the moment before it was used.
It took me a lot of messing around to be able to recreate this bug in a fresh project - it wasn't to do with my custom AI or anything, it was... to do with my "tiredness" script? It adds/removes a Tired state for "critical" MP. Like, literally all it is is this:
If an enemy is in a confused/berserk state and the skill they use (normally only Attack) costs MP they don't have, even after they just paid the cost, the action is negated. Since it gets negated, there is no active skill (even though they already "passed go"), no targets, and the following error occurs:
Scene_Battle, line 584, NoMethodError
undefined method 'make_targets' for nil:NilClass
The line in question:
targets = @subject.current_action.make_targets.compact
This error happens because... somehow... the current_action has been erased the moment before it was used.
It took me a lot of messing around to be able to recreate this bug in a fresh project - it wasn't to do with my custom AI or anything, it was... to do with my "tiredness" script? It adds/removes a Tired state for "critical" MP. Like, literally all it is is this:
PHP Code:
<?php
class Game_BattlerBase
alias :tayruu_tiredness_gamebattlerbase_refresh :refresh
def refresh
tayruu_tiredness_gamebattlerbase_refresh
mp_rate <= 0.25 ? add_state(2) : remove_state(2)
end
end
I have no idea as of yet why this code would do this? It's also possible refresh isn't the best place for this code (even though this is where the dead state is refreshed too).
EDIT: ...
PHP Code:
<?php
class Game_Battler < Game_BattlerBase
def add_new_state(state_id)
die if state_id == death_state_id
@states.push(state_id)
on_restrict if restriction > 0
sort_states
refresh
end
def on_restrict
clear_actions
states.each do |state|
remove_state(state.id) if state.remove_by_restriction
end
end