*namedrops scripter with actual skill while typing out script introduction*
Hello Kread-EX.
...
I've sort of put stuff together to make an MP Death script as an add-on for Melody. It works for what it was is intended to do. The problem is that if I use a reviving item that only restores HP or MP, the actor will invariably only recover 1 HP and 1 MP regardless of the values in the Recovery Effect fields in the database. I don't think it's a difficult thing but I don't know where to look anymore in the scripts.
spoiler tag is my friend
CODE
#============================================================================== # MP Death v 1.0 - YEM Add-On #------------------------------------------------------------------------------ # Description: # Actors and enemies will be flagged with Incapacitated status if their MP is # brought down to 0 similarly to what happens with HP. # Upon death BOTH HP and MP will be brought down to 0. #==============================================================================
#============================================================================== # ** Game_Battler #------------------------------------------------------------------------------ # Summary of changes: # Battler dies if MP reach 0. # Return dead? if MP reach 0. # Incapacitated state also brings actors MP down to 0. # Revived actors are brought back to life with 1 MP at minimum. # Cannot perform skills that bring MP down to 0. MP suicide is bad. # MP poisoning can kill. #==============================================================================
class Game_Battler #-------------------------------------------------------------------------- # * Change MP #-------------------------------------------------------------------------- def mp=(mp) @mp = [[mp, maxmp].min, 0].max if @mp == 0 and not state?(1) and not @immortal # ADDED add_state(1) # Add incapacitated (state #1) # ADDED @added_states.push(1) # ADDED elsif @mp > 0 and state?(1) # ADDED remove_state(1) # Remove incapacitated (state #1) # ADDED @removed_states.push(1) # ADDED end # ADDED end #-------------------------------------------------------------------------- # * Determine Incapacitation #-------------------------------------------------------------------------- def dead? # return (not @hidden and @hp == 0 and not @immortal) return (not @hidden and (@hp == 0 or @mp == 0) and not @immortal) # EDITED end #-------------------------------------------------------------------------- # * Add State #-------------------------------------------------------------------------- def add_state(state_id) state = $data_states[state_id] # Get state data return if state == nil # Is data invalid? return if state_ignore?(state_id) # Is it a state should be ignored? unless state?(state_id) # Is this state not added? unless state_offset?(state_id) # Is it a state should be offset? @states.push(state_id) # Add the ID to the @states array end if state_id == 1 # If it is incapacitated (state 1) @hp = 0 # Change HP to 0 @mp = 0 # Change MP to 0 # ADDED end unless inputable? # If the character cannot act @action.clear # Clear battle actions end for i in state.state_set # Take the [States to Cancel] remove_state(i) # And actually remove them @removed_states.delete(i) # It will not be displayed end sort_states # Sort states with priority end @state_turns[state_id] = state.hold_turn # Set the number of turns end #-------------------------------------------------------------------------- # * Remove State #-------------------------------------------------------------------------- def remove_state(state_id) return unless state?(state_id) # Is this state not added? # if state_id == 1 and @hp == 0 # If it is incapacitated (state 1) if state_id == 1 and (@hp == 0 or @mp == 0) # EDITED @hp = 1 # Change HP to 1 @mp = 1 # Change MP to 1 # ADDED end @states.delete(state_id) # Remove the ID from the @states @state_turns.delete(state_id) # Remove from the @state_turns end
#------------------------------------------------------------------------ # <cost: x item:y> #------------------------------------------------------------------------ when /(\d+)[ ]ITEM:(\d+)/i #--- calc_cost = self.enemy? ? 0 : $1.to_i name = $data_items[$2.to_i].name.upcase calc_cost = apply_skill_cost_changes(skill, calc_cost, name) #--- item = $data_items[$2.to_i] text_cost = calc_cost.to_s use_icon = item.icon_index can_use = $game_party.item_number(item) >= calc_cost if perform and self.actor? calc_cost.times do; $game_party.consume_item(item); end end
#------------------------------------------------------------------------ # Stop editting past this point. #------------------------------------------------------------------------ end use_icon = skill.cost_icon if skill.cost_icon != nil case type when :perform; return when :calc_cost; return calc_cost when :text_cost; return text_cost when :can_use; return can_use when :use_icon; return use_icon when :suffix; return suffix when :font_size; return font_size when :colour; return colour end end
#-------------------------------------------------------------------------- # new method: perform_slip_effect #-------------------------------------------------------------------------- def perform_slip_effect(state) return if state == nil return unless exist? return unless state.slip_damage hp_dmg = 0; mp_dmg = 0 hash = state.slip_effect #--- hp_dmg += maxhp * hash[:hp_degen_per] / 100 if hash [:hp_degen_per] != nil hp_dmg += hash[:hp_degen_set] if hash[:hp_degen_set] != nil hp_dmg *= stack(state) if hp_dmg != 0 mp_dmg += maxmp * hash[:mp_degen_per] / 100 if hash [:mp_degen_per] != nil mp_dmg += hash[:mp_degen_set] if hash[:mp_degen_set] != nil mp_dmg *= stack(state) if mp_dmg != 0 #--- hp_dmg = [hp_dmg, @hp - 1].min hp_dmg = 0 if anti_hp_regen if hp_dmg < 0 hp_dmg = 0 if anti_hp_degen if hp_dmg > 0 mp_dmg = 0 if anti_mp_regen if mp_dmg < 0 mp_dmg = 0 if anti_mp_degen if mp_dmg > 0 #--- if hp_dmg != 0 @hp = [[@hp - hp_dmg, maxhp].min, 0].max if hp_dmg > 0 rules = "HP_DMG" value = hp_dmg sprint = YEM::BATTLE_ENGINE::POPUP_SETTINGS[:hp_dmg] else rules = "HP_HEAL" value = -hp_dmg sprint = YEM::BATTLE_ENGINE::POPUP_SETTINGS[:hp_heal] end create_popup(value, rules) if $scene.is_a?(Scene_Battle) end if mp_dmg != 0 @mp = [[@mp - mp_dmg, maxmp].min, 0].max if mp_dmg > 0 rules = "MP_DMG" value = mp_dmg sprint = YEM::BATTLE_ENGINE::POPUP_SETTINGS[:mp_dmg] else rules = "MP_HEAL" value = -mp_dmg sprint = YEM::BATTLE_ENGINE::POPUP_SETTINGS[:mp_heal] end value = sprintf(sprint, value) create_popup(value, rules) if $scene.is_a?(Scene_Battle) end if @hp == 0 or @mp == 0; add_state(1); perform_collapse; end # ADDED end
end # Game_Battler
#=============================================================================== # Scene_Battle #------------------------------------------------------------------------------ # Summary of changes: # In Test Mode F8 will bring MP down to 1 to avoid MP Death. #===============================================================================
class Scene_Battle < Scene_Base
#-------------------------------------------------------------------------- # overwrite method: update_actor_command_selection #-------------------------------------------------------------------------- def update_actor_command_selection if @selected_battler.battle_command_index != @actor_command_window.index @selected_battler.battle_command_index = @actor_command_window.index if (dtb? or ctb?) and !@selected_battler.auto_battle $game_troop.clear_ctb_cache last_action = @selected_battler.action.clone case @actor_command_window.item when :attack; @selected_battler.action.set_attack when :guard; @selected_battler.action.set_guard else item = @actor_command_window.item array = YEM::BATTLE_ENGINE::SKILL_COMMANDS[item] if array != nil skill = $data_skills[array[0]] @selected_battler.action.set_skill(skill.id) if skill != nil end end make_action_orders @selected_battler.action = last_action end make_action_orders if @selected_battler.auto_battle and (dtb? or ctb?) end #--- if Input.trigger?(Input::B) Sound.play_cancel cancel_action elsif Input.trigger?(Input::C) actor_command_case elsif Input.repeat?(Input::LEFT) Sound.play_cursor prior_actor elsif Input.repeat?(Input::RIGHT) Sound.play_cursor next_actor elsif Input.trigger?(Input::L) Sound.play_cursor @status_shortcut_index = @status_window.index start_party_command_selection elsif Input.trigger?(Input::R) Sound.play_cursor @status_shortcut_index = @status_window.index start_confirm_command_selection #--- Debug Shortcuts --- elsif ($TEST or $BTEST) and Input.trigger?(Input::F5) Sound.play_recovery @selected_battler.recover_all @selected_battler.gain_rage(@selected_battler.max_rage) elsif ($TEST or $BTEST) and Input.trigger?(Input::F6) Sound.play_use_item if Input.press?(Input::SHIFT) @selected_battler.hp += @selected_battler.maxhp/5 else @selected_battler.hp = @selected_battler.maxhp end elsif ($TEST or $BTEST) and Input.trigger?(Input::F7) Sound.play_use_skill if Input.press?(Input::SHIFT) @selected_battler.mp += @selected_battler.maxmp/5 @selected_battler.gain_rage(@selected_battler.max_rage/5) else @selected_battler.mp = @selected_battler.maxmp @selected_battler.gain_rage(@selected_battler.max_rage) end elsif ($TEST or $BTEST) and Input.trigger?(Input::F8) Sound.play_actor_damage if Input.press?(Input::SHIFT) @selected_battler.hp -= @selected_battler.maxhp/4 + 4 @selected_battler.perform_collapse elsif Input.press?(Input::CTRL) @selected_battler.mp -= @selected_battler.maxmp/4 + 4 @selected_battler.lose_rage(@selected_battler.max_rage/4) else @selected_battler.hp = 1 # @selected_battler.mp = 0 @selected_battler.mp = 1 # EDITED @selected_battler.lose_rage(@selected_battler.max_rage) end elsif ($TEST or $BTEST) and Input.press?(Input::CTRL) and Input.press?(Input::SHIFT) for enemy in $game_troop.existing_members enemy.hp = 0 enemy.perform_collapse end end end
end # Scene_Battle
Also, the code is full of junk. I fear it has to do with my inability to understand aliases?
"# if state_id == 1 and @hp == 0 # If it is incapacitated (state 1) if state_id == 1 and (@hp == 0 or @mp == 0) # EDITED @hp = 1 # Change HP to 1 @mp = 1 # Change MP to 1 # ADDED"
is your problem. It's setting HP/MP to 1, regardless of the item's healing properties once the state is removed.
The "@hp = 1" bit is part of the original code (Game_Battler 497), as in if you're revived, your HP have to forcefully be at least at 1 point. My guess was that if I copied the same line, but for MP, reviving would automatically bring your MP to 1 at minimum, because death is either upon HP or MP depleting, so having any of those parameters below 1 would still flag you as dead.
Though if I have an item that revives, heals 10 HP and 5 MP, it works normally and dead actors recover said amount of HP and MP, so "@hp = 1/@mp = 1" are not permanent things. The problem arises only when the reviving item just heals one parameter.
Yup the workaround is really quite simple. Still, I thought this was interesting enough to submit in Script Submissions but didn't want to knowing there's a bug.