[Resolved][RMXP]Weird Sequencing of Battle Events

Started by Wraith89, July 05, 2017, 02:07:04 am

Previous topic - Next topic

Wraith89

July 05, 2017, 02:07:04 am Last Edit: July 07, 2017, 01:43:52 pm by Wraith89
(I know this script is messy but it does everything I want it to do, edit of Scene_Battle 3 and some parts of 4)

https://pastebin.com/0A2DqCT7

The real problem really is about the battle turn update.

Of course MP Shield is doing weird things, as I realised when a character gets hit by a foe that uses an attack that eats up all their MP, and has a skill cued beforehand, no animation for the cued skill plays, but its effect still persists, such as using Heal, the enemy is faster and takes my character's MP down. However, the Heal animation would not play because it should not when a character has 0 MP, as expected, but the target of Heal still gets healed anyways  :facepalm:

It is even funnier with Revive, as a downed character is revived, but comes off with no sprite.

I think the problem here is, one turn is defined as every single actors and enemies in the scene must act before everything is updated. This is also a thing when status such as stun, which should only last one turn, has its status icon listed even after the turn ends, but disappears as soon as I make an action in the next turn. I suspect it is something in Scene_Battle 4 that determines this. Is there a way so that every single individual action by individual characters forces an update on the battle scene or do I stick with such buggy battle mechanics?

KK20

Can't reproduce your issue, even with the old demo you provided me. I don't think this has anything to do with the MP Shield. The problem clearly states "skills are usable even with 0 MP".

In Scene_Battle, there's a method that even checks if a battler has enough MP before using the skill on their turn. If not, it skips it.

  def make_skill_action_result
    # Get skill
    @skill = $data_skills[@active_battler.current_action.skill_id]
    # If not a forcing action
    unless @active_battler.current_action.forcing
      # If unable to use due to SP running out
      unless @active_battler.skill_can_use?(@skill.id)  #<==== Here
        # Clear battler being forced into action
        $game_temp.forcing_battler = nil
        # Shift to step 1
        @phase4_step = 1
        return
      end
    end

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Wraith89

July 06, 2017, 01:34:50 pm #2 Last Edit: July 06, 2017, 01:42:03 pm by Wraith89
Yes, I figured that particular section influenced the turn sequence events. And MP Shield part was just an example, but it is the best mechanic to show that there is a bug here.

I tested it out with that old demo I gave you, but I think I just explained things wrong (I am very sorry if I am not good at expressing myself).

I will reupload the same one, with just a few things in the database changed. What the exact problem is: test out battle vs that Scorpion, have Aluxes get defeated, and have Gloria become weakened (it only takes one hit). After that, cast Revive on Aluxes with Gloria, but Scorpion should attack Gloria first, reducing her MP to 0, which means Revive should not work. However, see what happens.

https://www.sendspace.com/file/d8hgmp

This also happens with offensive skills too. If you cast a character's offensive skill on a foe who is on the verge of defeat, but he attacks your said character bringing their MP to 0, you still win with the victory screen, but the foe still remains on the field.

Again I apologise if my English does not make sense, but I am trying my best. I am very grateful for your help though.

KK20

Looks like the problem script is Blizzard's Full Reflection, specifically for the same method I called out earlier. Disabling the script no longer reproduced the issue. Let's take a look why:

  #----------------------------------------------------------------------------
  # override make_skill_action_result
  #----------------------------------------------------------------------------
  alias make_skill_action_result_reflect_later make_skill_action_result
  def make_skill_action_result(battler = nil, plus_id = nil)
    # if RTAB is not installed
    if battler == nil
      # call original method
      make_skill_action_result_reflect_later
      # set battler and targets
      tmp, targets = @active_battler, @target_battlers
    # additional compatibility
    elsif plus_id == nil
      # call original method with RTAB compatibility
      make_skill_action_result_reflect_later(battler)
      # set targets
      targets = battler.target
    else
      # call original method with higher RTAB compatibility
      make_skill_action_result_reflect_later(battler, plus_id)
      # set targets
      targets = battler.target
    end
    # if not breaking reflection skill
    unless BlizzCFG::BREAK_REFLECT.include?(@skill.id)
      # set targets allowing reflection
      set_target_battlers(@skill.scope, battler, true)
      # set battler if doesn't exist
      battler = tmp if battler == nil && tmp != nil
      # execute reflection effect and get old targets
      @old_targets = BlizzCFG.reflection_effect(battler, targets, @skill)
    end
  end

If the battler does not have the SP to use a skill, recall that make_skill_action_result changes @phase4_step to equal 1 and effectively stops further processing for that battler. In the above script, this happens when it calls the alias make_skill_action_result_reflect_later. The problem though is that it doesn't stop processing after calling the alias; it will move onto the next line setting the targets variable. The script then enters the unless BlizzCFG::BREAK_REFLECT.include?(@skill.id) check, satisfies the condition, and eventually calls BlizzCFG.reflection_effect, which will call target.skill_effect in line 161 of the script.

The script always assumes that the battler had enough SP to use their skill--there's no check otherwise. One way to resolve this issue is using the known fact that @phase4_step equals 1 when the battler does not have enough SP. You just do this:
unless BlizzCFG::BREAK_REFLECT.include?(@skill.id) || @phase4_step == 1

So now we no longer satisfy the condition and no longer call BlizzCFG.reflection_effect.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Wraith89

I had a sneaking suspicion.  :<_<:

Thank you sir.