Chaos Project

RPG Maker => Event Systems => Event System Troubleshooting => Topic started by: Lucern7 on June 03, 2017, 11:44:05 am

Title: [Resolved][XP] Target conditional for event based dodging in battle
Post by: Lucern7 on June 03, 2017, 11:44:05 am
Okay after fixing the states bug, I've run into another issue. I'm working on a very simple dodging system that runs with the default battle system. It works so far but there's a little aesthetic thing that I haven't been able to fix.

Simply put I press a key, a dodging animation plays and the enemy's attack either hits or misses depending on the timing. However I can't find a way to play a specific animation depending on which party member was targeted. Otherwise everyone looks silly dodging an attack aimed at one person. Ideally I could store the id of "Last Target" to a variable and create a conditional with that variable. Though I'm not sure how to do that.

Also is there a command to disable the damage pop ups? I have a few moves that are only meant to target enemies, so the common event can target them and it looks odd having 0 damage pop up.
Title: Re: [XP] Target conditional for event based dodging in battle
Post by: KK20 on June 03, 2017, 04:50:04 pm
Could you explain how you implemented your dodging system and how exactly it works? It's a "there are many ways you can do this, but there's only one that fits your needs" kind of problem.
Title: Re: [XP] Target conditional for event based dodging in battle
Post by: Lucern7 on June 03, 2017, 05:53:48 pm
Oh sure, I'm not sure it's the best method but here's how it goes

-The enemy does an attack for testing purposes I call it Attack Query it does nothing but do 0 damage to a random target (To ensure "Last Target" isn't a blank value) and call a common event I called "Dodge Query" which simplified looks like this.

Dodge Query
@>Show Battle Animation [1],[Attack Animation]
@>Wait 15 Frames
@>Conditional Branch The Left button is being pressed
@>Force Action[1],[Miss] Last target, Execute Now
: Else
@> Force Action[1],[Hit] Last target, Execute Now
:Branch End

and that's pretty much it.

I'd like to add a conditional to check which player is targeted so the right animation could play when a successful dodge is executed.

Now if there's a better way of doing it, or a way to hide the damage 0 pop up for attack query I'd love to hear it. This was the simplest way I could think of. I'm not looking for a full action battle system, just want to give the player a bit more control over the normally RNG based hit and miss system.

Title: Re: [XP] Target conditional for event based dodging in battle
Post by: KK20 on June 04, 2017, 03:35:51 pm
This is gonna be a little complicated, so bear with me here.

First you want to put this script probably right under Scene_Debug

class Scene_Battle
  attr_reader :active_battler, :target_battlers
  attr_writer :forced_action
  #--------------------------------------------------------------------------
  # * Make Skill Action Results
  #--------------------------------------------------------------------------
  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)
        # Clear battler being forced into action
        $game_temp.forcing_battler = nil
        # Shift to step 1
        @phase4_step = 1
        return
      end
    end
    # Use up SP
    @active_battler.sp -= @skill.sp_cost
    # Refresh status window
    @status_window.refresh
    # Show skill name on help window
    @help_window.set_text(@skill.name, 1) unless @forced_action
    # Set animation ID
    @animation1_id = @skill.animation1_id
    @animation2_id = @skill.animation2_id
    # Set command event ID
    @common_event_id = @skill.common_event_id
    # Set target battlers
    set_target_battlers(@skill.scope)
    # Apply skill effect
    for target in @target_battlers
      target.skill_effect(@active_battler, @skill)
    end
  end
  #--------------------------------------------------------------------------
  # * Frame Update (main phase step 3 : animation for action performer)
  #--------------------------------------------------------------------------
  def update_phase4_step3
    # Animation for action performer (if ID is 0, then white flash)
    if @animation1_id == 0
      @active_battler.white_flash = !@forced_action
    else
      @active_battler.animation_id = @animation1_id
      @active_battler.animation_hit = true
    end
    # Shift to step 4
    @phase4_step = 4
    @forced_action = false
  end
  #--------------------------------------------------------------------------
  # * Frame Update (main phase step 4 : animation for target)
  #--------------------------------------------------------------------------
  def update_phase4_step4
    # Animation for target
    for target in @target_battlers
      target.animation_id = @animation2_id
      target.animation_hit = (target.damage != "Miss")
    end
    # Animation has at least 8 frames, regardless of its length
    # If no animation is played, then do not apply any wait
    if @active_battler.current_action.kind == 0
      @wait_count = 8
    else
      @wait_count = (@animation2_id == 0 ? 0 : 8)
    end
    # Shift to step 5
    @phase4_step = 5
  end
end

class Interpreter
  def play_anim_on_targetted(anim_id)
    # Script command does nothing if currently not in battle
    return unless $scene.is_a?(Scene_Battle)
    # Play animation on targetted battlers
    $scene.target_battlers.each { |battler|
      next unless battler.exist?
      battler.animation_id = anim_id
      battler.animation_hit = true
    }
    true
  end
 
  def force_skill(skill_id)
    # Script command does nothing if currently not in battle
    return unless $scene.is_a?(Scene_Battle)
    # Force the skill on active battler and damage last targets
    battler = $scene.active_battler
    battler.current_action.skill_id = skill_id
    battler.current_action.decide_last_target_for_actor
    $scene.forced_action = true
    # Set force flag
    battler.current_action.forcing = true
    $scene.forced_action = true
    # If action is valid, then execute now
    if battler.current_action.valid?
      # Set battler being forced into action
      $game_temp.forcing_battler = battler
      # Advance index
      @index += 1
      # End
      return false
    end
    # Continue
    true
  end
 
  def targetted?(actor_id)
    # Script command does nothing if currently not in battle
    return unless $scene.is_a?(Scene_Battle)
    $scene.target_battlers.each { |battler|
      return true if battler.id == actor_id
    }
    false
  end
end

# The damage pop-up animation still plays even though its 'value' is blank.
# This fixes that.
class RPG::Sprite < Sprite
  alias no_show_damage_when_blank damage
  def damage(value, critical)
    return if value == '' || value.nil?
    no_show_damage_when_blank(value, critical)
  end
end


In your event command example you provided, change Show Battle Animation to this script call:
play_anim_on_targetted(ANIMATION_ID)

replacing ANIMATION_ID with the index of the animation you want to play.

Also replace Force Action to this script call:
force_skill(SKILL_ID)

again, replacing SKILL_ID with the index of the skill you want the enemy to use.

As for hiding damage pop-ups, the only way to do that is by making a skill have a Power of 0 but is able to apply a state to a battler successfully. Make a new State (call it dummy or something), check the box for Nonresistance, and a Rating of 0. For your Attack Query skill, make it apply this dummy state.

Here's a GIF of it working. All instances of MISS are when I was holding left. Disregard the 0 damage, I just made their attacks too weak.
Spoiler: ShowHide
(http://i.imgur.com/V5xIm5a.gif)
Title: Re: [XP] Target conditional for event based dodging in battle
Post by: Lucern7 on June 04, 2017, 05:38:55 pm
All that worked perfectly! Though I have one more question how could I set up a conditional to determine who in the party is targeted, in your example lets say I had something like Aluxes shielding, I'd want that animation to play only if he dodged successfully, and so on for the other members.

Still thank you so much for the help so far you've definitely earned a spot in the credits.
Title: Re: [XP] Target conditional for event based dodging in battle
Post by: KK20 on June 04, 2017, 05:40:54 pm
Are you saying you have unique animations for each battler?

In any case, add this method to the Interpreter class in my script (will edit previous post to include this):

  def targetted?(actor_id)
    # Script command does nothing if currently not in battle
    return unless $scene.is_a?(Scene_Battle)
    $scene.target_battlers.each { |battler|
      return true if battler.id == actor_id
    }
    false
  end

Use a conditional branch and choose script. Making the condition this
targetted?(1)

will return TRUE if Aluxes (actor ID 1) is being targetted, FALSE otherwise.
Title: Re: [XP] Target conditional for event based dodging in battle
Post by: Lucern7 on June 04, 2017, 06:00:54 pm
Yeah I have a few set up. Only for the party members though the enemies use more generic animations.