Problem with Galv timed hit script [Defending issue]

● ARCHIVED · READ-ONLY
Started by Rokazulu 7 posts View original ↗
  1. I'm using Galv's timed hit script:
    https://galvs-scripts.com/2013/03/11/timed-button-attacks/

    It works great, except that when I defend there is no change in damage for the actor. It is suppose to reduce the damage by the multiplier amount.

    Script I have setup so far:
    My script
    Code:
    #  Galv's Timed Button Attacks
    #------------------------------------------------------------------------------#
    #  For: RPGMAKER VX ACE
    #  Version 1.7
    #------------------------------------------------------------------------------#
    #  2013-04-25 - Version 1.7 - Added compatibility with Yanfly's cast animation
    #  2013-04-17 - Version 1.6 - Fixed a pretty big bug with ending battle.
    #  2013-04-17 - Version 1.5 - Fixed evaded popup appearing in Yanfly's engine
    #                           - when hitting using 'guarantee hit' option. Added
    #                           - fix for if battle ends early while indicator live
    #  2013-04-08 - Version 1.4 - Fixed bug with defend indicator not showing on
    #                           - correct actor.
    #  2013-03-15 - Version 1.3 - Fixed animation option
    #  2013-03-15 - Version 1.2 - Fixed a bug with not pressing button at all
    #  2013-03-15 - Version 1.1 - added option to turn off battle log messages
    #                           - disabled hit indicator when actor is confused
    #                           - fixed yanfly battle engine compatability bug
    #  2013-03-11 - Version 1.0 - release
    #------------------------------------------------------------------------------#
    #  Adds a graphical indicator to selected attacks that allows the player to
    #  press a button at a certain time for the attack to do extra damage or apply
    #  a state. Different attacks can use different buttons, graphics and have
    #  varied speeds and difficulty.
    #
    #  NOTES: Put this script below any battle scripts. Tested in default battle
    #  system as well as Yanfly's default battle script.
    #
    #  MORE NOTES: If the indicator disappears too soon, increase the frames of the
    #  skill's animation in the Database Animations tab.
    #
    #------------------------------------------------------------------------------#
    #------------------------------------------------------------------------------#
    #  NOTE TAGS for SKILLS or ITEMS
    #------------------------------------------------------------------------------#
    #
    #  <btnpress>     # Enables the btn press with flash and SE when successful
    #      OR
    #  <btnpress n>   # Enables the btn press and plays animation n when successful
    #                 # This animation cancels the current skill's animation.
    #
    #   # NOTE: Only one of these is required for a skill.
    #
    #------------------------------------------------------------------------------#
    #  NOTE TAGS for SKILLS or ITEMS (Leaving any of these out will use defaults)
    #------------------------------------------------------------------------------#
    #
    #  <btn x>                 # Use a different button to press (default :X)
    #  <btnmsg x>              # Use a different message number when hit successful
    #
    #  <btnmultiply x>         # Multiply the damage/healing by x (default 2)
    #
    #  <btnstates x,x,x>       # Apply states with id x when timing is hit.
    #  <btnrstates x,x,x>      # Remove states with id x when timing is hit.
    #
    #  <btnopt a,b,c,d>        # a = start time (delay before indicator moves)
    #                          # b = target time (when button should be pressed)
    #                          # c = indicator image number to use
    #                          # d = difficulty number. Higher is easier to hit
    #
    #   # The indicator will appear at the start time (a) and shrink down to meet
    #   # the target circle at the target time (b) when the player should press
    #   # the button.
    #   # DEFAULTS: a = 0   b = 31   c = 1   d = 0
    #------------------------------------------------------------------------------#
    #  EXAMPLES:
    #
    #  <btnpress 4>               # Enables script and uses animation 4 on success
    #  <btn Y>                    # Use the :Y ("s" on the keyboard) button instead
    #  <btnmultiply 3>            # 3 x damage
    #  <btnstates 2,3>            # Applies states 2 and 3
    #  <btnrstates 5,6,7>         # Removes states 5, 6 and 7
    #  <btnopt 10,61,2,0>         # Indicator runs from 10-61 frames using image 2
    #                             # and no change in difficulty
    #
    #------------------------------------------------------------------------------#
    #------------------------------------------------------------------------------#
    #  NOTE TAGS for ACTORS or EQUIPS - These determine a defending timed hit
    #------------------------------------------------------------------------------#
    #
    #  <btnpress>     # Enables an actor or equip defending timed hit.
    #      OR
    #  <btnpress n>   # Enables def timed hit and plays animation n when successful
    #                 # Only use this if you are using a sideview battle script.
    #                 # Only works with battle scripts that show animations on actors
    #
    #  # NOTE: Only one of these is required for an equip or actor.
    #
    #------------------------------------------------------------------------------#
    #  Optional NOTE TAGS for ACTORS or EQUIPS (Leaving any out will use defaults)
    #------------------------------------------------------------------------------#
    #  <btn x>                 # Use a different button to press (default :Z)
    #  <btnmsg x>              # Use a different message number when hit successful
    #
    #  <btnmultiply x>         # Multiply the damage/healing by x (default 0.5)
    #
    #  <btnstates x,x,x>       # Apply states with id x when timing is hit.
    #  <btnrstates x,x,x>      # Remove states with id x when timing is hit.
    #
    #  <btnopt a,b,c,d>        # a = start time (delay before indicator moves)
    #  # DEFAULTS: a = 10   b = 31   c = 3   d = 0
    #
    #------------------------------------------------------------------------------#
    ($imported ||= {})["Galv_BtnPress_Hit"] = true
    module Galv_BtnAtk
     
    #------------------------------------------------------------------------------#
    #  SETUP OPTIONS
    #------------------------------------------------------------------------------#
      #---------------#
      #  PREFERENCES  #
      #---------------#
      GUARANTEE_HIT = true   # If player hits the timing, the attack cannot miss
      SHOW_AS_CRIT = true   # Displays hits on enemy as critical hits.
     
      ATK_MULTIPLIER = 2.00    # Default damage/healing multipliers if the timing is
      DEF_MULTIPLIER = 1.0      # successful for attacking and defending.
     
      DIFFICULTY = 2.5         # The higher this number, the further away from the
                             # center circle will score a success. 0 is extremely
                             # difficult, the higher this number the easier.
      DISABLE_SWITCH = 500   # Turn swith ON to disable this
     
      ATK_BTN = :C           # Default attack button to press. :X is "a"
      DEF_BTN = :C           # Default defend button to press. :Z is "d"
     
      Y_OFFSET = -50         # 0 is positioned at bottom of a battler.
     
      Y_FRONT_OFFSET = 0     # x and y offset for targeting your party when using a
      X_FRONT_OFFSET = 0     # battle system with no actor x,y locations. By default
                             # it centers at the top of the battle status window.
      #---------------#
      #     VOCAB     #
      #---------------#
     
      BATTLE_LOG_TXT = true     # Display battle log text (below) true or false
                                 # Displaying battle messages slows down multi-hit
                                 # skills in some battle systems.
     
      # Below is a list of battlelog vocab that you can add to and use for timed hit
      TXT = [ # don't touch
     
          "CRITICAL HIT",      # 0) Default attacking timed hit success
          "CRITICAL HIT",    # 1) Default allied spell timed hit success
          "CRITICAL BLOCK",      # 2) Default defending timed hit success
       
          "CUSTOM TEST!",        # 3) When <btnmsg 3> notetag
       
          #"Another one",        # 4) Add as many as you need
          #"Another one",        # 5) Add as many as you need
          #"Another one",        # 6) Add as many as you need
          #"Another one",        # 7) Add as many as you need
     
      ] # don't touch
      #---------------#
      #   GRAPHICS    #
      #---------------#
     
      TARGET_IMG = "hit_target"         # The inner target that the indicator meets
      INDICATOR_IMG = "hit_indicator"   # The indicator that shrinks to the target
      # NOTE: These are the base image names for the graphics. The actual files will
      # have a number appended to them. By default this number is 1, so the file
      # names by default would be: "hit_target1.png", "hit_indicator1.png"
      # This number can be changed using the option notetag so different skills can
      # use a different graphic. Images go in /Graphics/System/ folder.
      COLOR_HIT = [0, 255, 0]    # [R,G,B] indicator turns this color when success
      COLOR_MISS = [255, 0, 0]   # [R,G,B] indicator turns this color when fail
      #---------------#
      #    SOUNDS     #
      #---------------#
      SE_HIT = ["Flash1",30,75]    # "SE_Name", volume, pitch when hit timing
      SE_MISS = ["Buzzer1",0,100]   # "SE_Name", volume, pitch when missed timing
     
     
    #------------------------------------------------------------------------------#
    #  END SETUP OPTIONS
    #------------------------------------------------------------------------------#
    end
    class RPG::BaseItem
      def btnpress
        if @btnpress.nil?
          if [USER=90460]@note[/USER] =~ /<btnpress>/i
            @btnpress = 0
          elsif [USER=90460]@note[/USER] =~ /<btnpress[ ](.*)>/i
            @btnpress = $1.to_i
          else
            @btnpress = -1
          end
        end
        @btnpress
      end
      def btnmultiply
        if @btnmultiply.nil?
          if [USER=90460]@note[/USER] =~ /<btnmultiply[ ](.*)>/i
            @btnmultiply = $1.to_f
          else
            if self.is_a?(RPG::Actor) || self.is_a?(RPG::EquipItem)
              @btnmultiply = Galv_BtnAtk::DEF_MULTIPLIER
            else
              @btnmultiply = Galv_BtnAtk::ATK_MULTIPLIER
            end
          end
        end
        @btnmultiply
      end
      def btn
        if @btn.nil?
          if [USER=90460]@note[/USER] =~ /<btn[ ](.*)>/i
            @btn = $1.to_sym
          else
            if self.is_a?(RPG::Actor) || self.is_a?(RPG::EquipItem)
              @btn = Galv_BtnAtk::DEF_BTN
            else
              @btn = Galv_BtnAtk::ATK_BTN
            end
          end
        end
        @btn
      end
      def btnmsg
        if @btnmsg.nil?
          if [USER=90460]@note[/USER] =~ /<btnmsg[ ](.*)>/i
            @btnmsg = $1.to_i
          else
            @btnmsg = nil
          end
        end
        @btnmsg
      end
      def btnstates
        if @btnstates.nil?
          if [USER=90460]@note[/USER] =~ /<btnstates[ ](.*)>/i
            @btnstates = $1.to_s.split(",").map {|i| i.to_i}
          else
            @btnstates = []
          end
        end
        @btnstates
      end
      def btnrstates
        if @btnrstates.nil?
          if [USER=90460]@note[/USER] =~ /<btnrstates[ ](.*)>/i
            @btnrstates = $1.to_s.split(",").map {|i| i.to_i}
          else
            @btnrstates = []
          end
        end
        @btnrstates
      end
      def btnopt
        if @btnopt.nil?
          if [USER=90460]@note[/USER] =~ /<btnopt[ ](.*)>/i
            @btnopt = $1.to_s.split(",").map {|i| i.to_i}
          else
            if self.is_a?(RPG::Actor) || self.is_a?(RPG::EquipItem)
              @btnopt = [0,31,3,0]
            else
              @btnopt = [0,31,1,0]
            end
          end
        end
        @btnopt
      end
    end # RPG::BaseItem
    class Game_Temp
      attr_accessor :btncrit
      attr_accessor :btndata
      alias galv_btnhit_gt_initialize initialize
      def initialize
        galv_btnhit_gt_initialize
        @btncrit = false
        @btndata = [2,nil]  # [multipler,vocab]
      end
    end # Game_Temp
    class Game_Actor < Game_Battler
      if !$imported["YEA-BattleEngine"]
        attr_accessor :screen_x
        attr_accessor :screen_y
      end
    end # Game_Actor < Game_Battler
    class Game_ActionResult
      # Cannot miss if hit button at right time
      alias galv_btnhit_gar_hit? hit?
      def hit?
        if $game_temp.btncrit && Galv_BtnAtk::GUARANTEE_HIT
          @missed = false
          @evaded = false
          @used
        else
          galv_btnhit_gar_hit?
        end
      end
     
      # Modify damage if button is hit and make it show critical
      alias galv_btnhit_gar_make_damage make_damage
      def make_damage(value, item)
        if $game_temp.btncrit
          value = (value * $game_temp.btndata[0]).to_i
          @critical = true if @battler.is_a?(Game_Enemy) && Galv_BtnAtk::SHOW_AS_CRIT
        end
        galv_btnhit_gar_make_damage(value, item)
      end
     
    end # Game_ActionResult
    class Window_BattleLog < Window_Selectable
      alias galv_btnhit_wblog_display_critical display_critical
      def display_critical(target, item)
        if $game_temp.btncrit && Galv_BtnAtk::BATTLE_LOG_TXT
          if $game_temp.btndata[1]
            text = $game_temp.btndata[1]
          else
            text = target.actor? ? Galv_BtnAtk::TXT[1] : Galv_BtnAtk::TXT[0]
          end
          add_text(text)
          wait
        else
          galv_btnhit_wblog_display_critical(target, item)
        end
      end
    end # Window_BattleLog < Window_Selectable
    class Scene_Battle < Scene_Base
      attr_accessor :btnactive
     
      alias galv_btnhit_sb_update_basic update_basic
      def update_basic
        if @btnactive
          btn_pressed
          @hit_indicator.update if @hit_indicator
        end
        galv_btnhit_sb_update_basic
      end
     
      def hskill
        if @def_opts
          @def_opts
        else
          @subject.current_action.item
        end
      end
     
      def btn_pressed
        return if $game_switches[Galv_BtnAtk::DISABLE_SWITCH] || $game_troop.all_dead?
        if Input.trigger?(hskill.btn) && @hit_indicator.hit?
          $game_temp.btncrit = true
          $game_temp.btndata[0] = hskill.btnmultiply
          btn_addstate if hskill.btnstates
          btn_remstate if hskill.btnrstates
          @hit_indicator.success
          if hskill.btnpress > 0
            show_hit_success_anim(@current_inditargets, hskill.btnpress)
          else
            $game_troop.screen.start_flash(Color.new(255,255,255,255),25)
            RPG::SE.new(Galv_BtnAtk::SE_HIT[0],Galv_BtnAtk::SE_HIT[1],Galv_BtnAtk::SE_HIT[2]).play
          end
          @btnactive = nil
        elsif Input.trigger?(hskill.btn)
          $game_temp.btncrit = false
          @hit_indicator.fail
          RPG::SE.new(Galv_BtnAtk::SE_MISS[0],Galv_BtnAtk::SE_MISS[1],Galv_BtnAtk::SE_MISS[2]).play
          @btnactive = nil
        end
      end
     
      def btn_addstate
        @current_inditargets.each { |t|
          already_dead = t.dead?
          hskill.btnstates.each { |state| t.add_state(state) if !already_dead }
          t.perform_collapse_effect if t.dead? && !already_dead
        }
      end
     
      def btn_remstate
        @current_inditargets.each { |t|
          already_dead = t.dead?
          hskill.btnrstates.each { |state| t.remove_state(state) }
          t.perform_collapse_effect if t.dead? && !already_dead
        }
      end
     
      def show_hit_success_anim(targets, animation_id, mirror = false)
        if $data_animations[animation_id]
          targets[0].animation_id = animation_id
          targets[0].animation_mirror = mirror
        end
      end
     
      alias galv_btnhit_sb_use_item use_item
      def use_item
        galv_btnhit_sb_use_item
        $game_temp.btncrit = false
      end
     
      def do_indicator(targets)
        return if targets.nil? || targets.empty? || @castanim
        @def_opts = nil
        item = @subject.current_action.item
        target = targets[0]
        if @subject.is_a?(Game_Actor) && !@subject.confusion? && item.btnpress >= 0
          $game_temp.btndata[1] = item.btnmsg ? Galv_BtnAtk::TXT[item.btnmsg] : nil
          @current_inditargets = targets
          setup_hit_indicator(item.btnopt)
          @btnactive = true
        elsif target && defender?(target)
          $game_temp.btndata[1] = @def_opts.btnmsg ?
              Galv_BtnAtk::TXT[@def_opts.btnmsg] : Galv_BtnAtk::TXT[2]
          @current_inditargets = targets
          setup_hit_indicator(@def_opts.btnopt)
          @btnactive = true
        end
        update_for_wait
      end
     
      alias galv_btnhit_sb_show_animation show_animation
      def show_animation(targets, animation_id)
        do_indicator(targets)
        galv_btnhit_sb_show_animation(targets, animation_id)
      end
     
      def defender?(target)
        return false if !target.is_a?(Game_Actor)
        return false if @subject.is_a?(Game_Actor)
        defend = -1
        defend = $data_actors[target.id].btnpress
        @def_opts = $data_actors[target.id]
        target.equips.each { |i|
        next if i.nil?
        if i.btnpress > defend
          defend = i.btnpress
          @def_opts = i
        end
        }
        return true if defend >= 0
      end
     
      def setup_hit_indicator(array)
        return if @current_inditargets[0].nil? ||
          $game_switches[Galv_BtnAtk::DISABLE_SWITCH] || $game_troop.all_dead?
       
        if !@current_inditargets.empty? && @current_inditargets[0].screen_x
          x = @current_inditargets[0].screen_x
          y = @current_inditargets[0].screen_y + Galv_BtnAtk::Y_OFFSET
        else
          x = Graphics.width / 2 + Galv_BtnAtk::X_FRONT_OFFSET
          y = Graphics.width / 1.7 + Galv_BtnAtk::Y_FRONT_OFFSET
        end
        @hit_indicator = Timed_Hits.new(x,y,array)
      end
     
      alias galv_btnhit_sb_invoke_item invoke_item
      def invoke_item(target, item)
        if !$imported["YEA-BattleEngine"]
          @btnactive = nil
          @hit_indicator.dispose if @hit_indicator
        end
        galv_btnhit_sb_invoke_item(target, item)
        if $imported["YEA-BattleEngine"]
          @btnactive = nil
          @hit_indicator.dispose if @hit_indicator
        end
      end
     
      alias galv_btnhit_sb_terminate terminate
      def terminate
        galv_btnhit_sb_terminate
        @hit_indicator.dispose if @hit_indicator
      end
     
      if $imported["YEA-CastAnimations"]
        alias galv_btnhit_sb_process_casting_animation process_casting_animation
        def process_casting_animation
          @castanim = true
          item = @subject.current_action.item
          cast_ani = item.cast_ani
          return if cast_ani <= 0
          show_animation([@subject], cast_ani)
          @castanim = false
        end
      end
     
    end # Scene_Battle < Scene_Base
    #------------------------------------------------------------------------------#
    #  Class Timed_Hits
    #------------------------------------------------------------------------------#
    class Timed_Hits
      def initialize(x,y,options)
        @x = x
        @y = y
        @opt = options
        @img = @opt[2].to_s
        @start_frame = @opt[0]
        @target_frame = @opt[1]
        @current_frame = 0
        @s = (3.to_f - 0.6) / (@target_frame - @start_frame)
        @d = (Galv_BtnAtk::DIFFICULTY + @opt[3]).to_f * 0.5
        create_hit_indicator
        create_target_indicator
      end
     
      def create_target_indicator
        @hittarget = Sprite.new(@viewport1)
        @hittarget.bitmap = Cache.system(Galv_BtnAtk::TARGET_IMG + @img)
        @hittarget.z = 100
        @hittarget.x = @x - (@hittarget.bitmap.width / 2)
        @hittarget.y = @y - (@hittarget.bitmap.height / 2)
        @hittarget.opacity = 130
      end
      def create_hit_indicator
        @hitindi = Sprite.new(@viewport1)
        @hitindi.bitmap = Cache.system(Galv_BtnAtk::INDICATOR_IMG + @img)
        @hitindi.x = @x
        @hitindi.y = @y
        @hitindi.z = 100
        @hitindi.opacity = 0
        @hitindi.zoom_x = 3
        @hitindi.zoom_y = 3
        @hitindi.color = Color.new(0, 0, 0, 0)
      end
     
      def hit?
        @current_frame.between?(@target_frame - @d,@target_frame + @d)
      end
     
      def success
        c = Galv_BtnAtk::COLOR_HIT
        @hitindi.color = Color.new(c[0],c[1],c[2],255)
      end
      def fail
        c = Galv_BtnAtk::COLOR_MISS
        @hitindi.color = Color.new(c[0],c[1],c[2],255)
      end
     
      def update
        update_indicators
      end
     
      def update_indicators
        return @current_frame += 1 if @current_frame < @start_frame
        @hitindi.opacity = 100
        @hitindi.zoom_x -= @s
        @hitindi.zoom_y -= @s
        @hitindi.x = @x - (@hitindi.bitmap.width / 2) * @hitindi.zoom_x
        @hitindi.y = @y - (@hitindi.bitmap.height / 2) * @hitindi.zoom_y
        @current_frame += 1
        if @hitindi.zoom_x <= 0
          fail
          SceneManager.scene.btnactive = nil
        end
      end
     
      def dispose
        @hitindi.dispose if @hitindi
        @hittarget.dispose if @hittarget
      end
    end # Timed_Hits


    I believe all I'm supposed to do is to place <btnpress> in the notes of my actor and then whenever an enemy attacks and I time my defend it will reduce damage for that actor. I did this, and the indicator shows up correctly and I can even see the indicator lighting up when I succeed in a defend but, no change in damage occurs. What am I missing?

    By the way I use Yanfly's AceBattle/AceCore scripts as well for my game.
  2. You should have put a link to where the script is found, not the script itself. Also the way you posted the script has changed it. There are now smiley faces in parts of it.

    Can you put a picture of your configuration where you have <btnpress> in your settings for attack.
  3. Here is a quick screenshot of attack/defend <btnpress>, but remember it is defend that is not working (and just the damage calculation). Though, I'm sure I already posted the script location link in the OP. I also put the script into a better format.
  4. I wonder if it's because you have the same button programmed for the script.
    Try :C for the attack and :B for the defend. (Z and X)
    Let us know if that does it.
  5. A good suggestion. Though I just tested it and the damage calculation remains the same when I create two separate buttons for attack/defend.
  6. I just realized after looking at your setting in the script that you have the defend multiplier at 1.
    This means that the damage will be X * 1 = X
    The multiplier is supposed to be lower than 1. In the script the default is 0.5
    X * 0.5 = 1/2X
  7. Roninator2 said:
    The multiplier is supposed to be lower than 1. In the script the default is 0.5
    X * 0.5 = 1/2X

    I actually had it set to default 0.8, but after realizing that the damage calculations weren't working I changed the number around to see if that was the reason. I just tested it again to make sure, at multiplier 0.1 . It doesn't change the damage at all when I succeed in a defend.