Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Counter Attack : Small Delay Problem, thats it...

Code:
#===============================================================================

# ** Battler : Counter Attacks

#===============================================================================

 

#-------------------------------------------------------------------------------

# * SDK Log

#-------------------------------------------------------------------------------

SDK.log('Battler.CounterAttacks', 'Kain Nobel ©', 0, '04.05.2009')

#-------------------------------------------------------------------------------

# * SDK Enabled Test : BEGIN

#-------------------------------------------------------------------------------

if SDK.enabled?('Battler.CounterAttacks')

 

#===============================================================================

# * CounterAttacks

#===============================================================================

 

module CounterAttacks

  #=============================================================================

  # ** Actor

  #=============================================================================

  module Actor

    #---------------------------------------------------------------------------

    # * Counter Efficiency against Attacks              {actor_id => value, ...}

    #---------------------------------------------------------------------------

    Attack_Effeciency_Attack = {}

    #---------------------------------------------------------------------------

    # * Counter Efficiency against Skills               {actor_id => value, ...}

    #---------------------------------------------------------------------------

    Attack_Effeciency_Skill  = {}

    #---------------------------------------------------------------------------

    # * Counter Efficiency against Items                {actor_id => value, ...}

    #---------------------------------------------------------------------------

    Attack_Effeciency_Item   = {}

    #---------------------------------------------------------------------------

    # * Counter Efficiency against Attacks              {actor_id => value, ...}

    #---------------------------------------------------------------------------

    Defend_Effeciency_Attack = {}

    #---------------------------------------------------------------------------

    # * Counter Efficiency against Skills               {actor_id => value, ...}

    #---------------------------------------------------------------------------

    Defend_Effeciency_Skill  = {}

    #---------------------------------------------------------------------------

    # * Counter Efficiency against Items                {actor_id => value, ...}

    #---------------------------------------------------------------------------

    Defend_Effeciency_Item   = {}

    #---------------------------------------------------------------------------

    # * Default Settings

    #---------------------------------------------------------------------------

    Attack_Effeciency_Attack.default = 100

    Attack_Effeciency_Skill.default  = 100

    Attack_Effeciency_Item.default   = 100

    Defend_Effeciency_Attack.default = 0

    Defend_Effeciency_Skill.default  = 0

    Defend_Effeciency_Item.default   = 0

  end

  #=============================================================================

  # * Enemy

  #=============================================================================

  module Enemy

    #---------------------------------------------------------------------------

    # * Counter Efficiency against Attacks              {enemy_id => value, ...}

    #---------------------------------------------------------------------------

    Attack_Effeciency_Attack = {}

    #---------------------------------------------------------------------------

    # * Counter Efficiency against Skills               {enemy_id => value, ...}

    #---------------------------------------------------------------------------

    Attack_Effeciency_Skill  = {}

    #---------------------------------------------------------------------------

    # * Counter Efficiency against Items                {enemy_id => value, ...}

    #---------------------------------------------------------------------------

    Attack_Effeciency_Item   = {}

    #---------------------------------------------------------------------------

    # * Counter Efficiency against Attacks              {enemy_id => value, ...}

    #---------------------------------------------------------------------------

    Defend_Effeciency_Attack = {}

    #---------------------------------------------------------------------------

    # * Counter Efficiency against Skills               {enemy_id => value, ...}

    #---------------------------------------------------------------------------

    Defend_Effeciency_Skill  = {}

    #---------------------------------------------------------------------------

    # * Counter Efficiency against Items                {enemy_id => value, ...}

    #---------------------------------------------------------------------------

    Defend_Effeciency_Item   = {}

    #---------------------------------------------------------------------------

    # * Default Settings

    #---------------------------------------------------------------------------

    Attack_Effeciency_Attack.default = 100

    Attack_Effeciency_Skill.default  = 100

    Attack_Effeciency_Item.default   = 100

    Defend_Effeciency_Attack.default = 0

    Defend_Effeciency_Skill.default  = 0

    Defend_Effeciency_Item.default   = 0

  end

  #-----------------------------------------------------------------------------

  # * Font Name for damage string

  #-----------------------------------------------------------------------------

  FontName = "Arial Black"

  #-----------------------------------------------------------------------------

  # * Font Size for damage string

  #-----------------------------------------------------------------------------

  FontSize = 22

  #-----------------------------------------------------------------------------

  # * Damage String

  #-----------------------------------------------------------------------------

  DamageString = "Counter!"

  #-----------------------------------------------------------------------------

  # * Damage Color A

  #-----------------------------------------------------------------------------

  DamageColorA = Color.new(160, 160, 160)

  #-----------------------------------------------------------------------------

  # * Damage Color B

  #-----------------------------------------------------------------------------

  DamageColorB = Color.new(255, 255, 255)

end

 

#===============================================================================

# ** Game_Battler

#===============================================================================

 

class Game_Battler

  #-----------------------------------------------------------------------------

  # * Public Instance Variables

  #-----------------------------------------------------------------------------

  attr_accessor :counter_animation

  attr_accessor :counter_attacking

  attr_accessor :counter_defending

  #-----------------------------------------------------------------------------

  # * Alias Listings

  #-----------------------------------------------------------------------------

  alias_method :counterattacks_gmbtlr_initialize, :initialize

  alias_method :counterattacks_gmbtlr_atkeffect,  :attack_effect

  alias_method :counterattacks_gmbtlr_skleffect,  :skill_effect

  alias_method :counterattacks_gmbtlr_itmeffect,  :item_effect

  #-----------------------------------------------------------------------------

  # * Object Initialization

  #-----------------------------------------------------------------------------

  def initialize(*args)

    counterattacks_gmbtlr_initialize(*args)

    @counter_animation = 0

  end

  #-----------------------------------------------------------------------------

  # * Attack Effect

  #-----------------------------------------------------------------------------

  def attack_effect(attacker)

    self.counterattacks_gmbtlr_atkeffect(attacker)

    self.counter_effect(0, attacker)

  end

  #-----------------------------------------------------------------------------

  # * Skill Effect

  #-----------------------------------------------------------------------------

  def skill_effect(user, skill)

    self.counterattacks_gmbtlr_skleffect(user, skill)

    self.counter_effect(1, user, skill)

  end

  #-----------------------------------------------------------------------------

  # * Item Effect

  #-----------------------------------------------------------------------------

  def item_effect(user, item)

    self.counterattacks_gmbtlr_itmeffect(user, item)

    self.counter_effect(2, user, item)

  end

  #-----------------------------------------------------------------------------

  # * Counter Effect

  #-----------------------------------------------------------------------------

  def counter_effect(effect_type, opponent, object = nil)

    if counter_effective?(effect_type, opponent, object)

      case effect_type

      when 0 ; opponent.counterattacks_gmbtlr_atkeffect(self)

      when 1 ; opponent.counterattacks_gmbtlr_skleffect(self, object)

      when 2 ; opponent.counterattacks_gmbtlr_itmeffect(self, object)

      end

      self.counter_effect_finish(opponent)

    end

  end

  #-----------------------------------------------------------------------------

  # * Counter Effect : Effective ?

  #-----------------------------------------------------------------------------

  def counter_effective?(type, opponent, object)

    effective = false

    effective |= !(self.dead? && opponent.dead?)

    effective |= self.counter_attack_odds(type) > 0

    if object.nil? || (object.scope == 1 || object.scope == 2)

      attack_odds = rand(self.counter_attack_odds(type))

      defend_odds = rand(opponent.counter_defend_odds(type))

      effective |= attack_odds >= defend_odds

    end

    opponent.counter_defending = effective

    self.counter_defending     = effective

    return effective

  end

  #-----------------------------------------------------------------------------

  # * Counter Effect Finish

  #-----------------------------------------------------------------------------

  def counter_effect_finish(opponent)

    opponent.counter_animation = opponent.animation2_id

    self.counter_animation     = opponent.animation1_id

    $scene.counter_battlers_attacking << self

    $scene.counter_battlers_defending << opponent

  end

  #-----------------------------------------------------------------------------

  # * Is Counter Attacking ?

  #-----------------------------------------------------------------------------

  def is_counter_attacking?

    return self.counter_attacking

  end

  #-----------------------------------------------------------------------------

  # * Is Counter Defending ?

  #-----------------------------------------------------------------------------

  def is_counter_defending?

    return self.counter_defending

  end

end

 

#===============================================================================

# ** Game_Actor

#===============================================================================

 

class Game_Actor < Game_Battler

  #-----------------------------------------------------------------------------

  # * Counter Effeciency : Attack

  #-----------------------------------------------------------------------------

  def counter_attack_odds(type)

    case type

    when 0 then return CounterAttacks::Actor::Attack_Effeciency_Attack[id]

    when 1 then return CounterAttacks::Actor::Attack_Effeciency_Skill[id]

    when 2 then return CounterAttacks::Actor::Attack_Effeciency_Item[id]

    end

  end

  #-----------------------------------------------------------------------------

  # * Counter Effeciency : Defend

  #-----------------------------------------------------------------------------

  def counter_defend_odds(type)

    case type

    when 0 then return CounterAttacks::Actor::Defend_Effeciency_Attack[id]

    when 1 then return CounterAttacks::Actor::Defend_Effeciency_Skill[id]

    when 2 then return CounterAttacks::Actor::Defend_Effeciency_Item[id]

    end

  end

end

 

#===============================================================================

# ** Game_Enemy

#===============================================================================

 

class Game_Enemy < Game_Battler

  #-----------------------------------------------------------------------------

  # * Counter Effeciency : Attack

  #-----------------------------------------------------------------------------

  def counter_attack_odds(type)

    case type

    when 0 then return CounterAttacks::Enemy::Attack_Effeciency_Attack[id]

    when 1 then return CounterAttacks::Enemy::Attack_Effeciency_Skill[id]

    when 2 then return CounterAttacks::Enemy::Attack_Effeciency_Item[id]

    end

  end

  #-----------------------------------------------------------------------------

  # * Counter Effeciency : Defend

  #-----------------------------------------------------------------------------

  def counter_defend_odds(type)

    case type

    when 0 then return CounterAttacks::Enemy::Defend_Effeciency_Attack[id]

    when 1 then return CounterAttacks::Enemy::Defend_Effeciency_Skill[id]

    when 2 then return CounterAttacks::Enemy::Defend_Effeciency_Item[id]

    end

  end

end

 

#===============================================================================

# ** Scene_Battle

#===============================================================================

 

class Scene_Battle < SDK::Scene_Base

  #-----------------------------------------------------------------------------

  # * Public Instance Variables

  #-----------------------------------------------------------------------------

  attr_accessor :counter_battlers_attacking

  attr_accessor :counter_battlers_defending

  #-----------------------------------------------------------------------------

  # * Alias Listings

  #-----------------------------------------------------------------------------

  alias_method :counterattacks_snbtl_updatephase4step5, :update_phase4_step5

  #-----------------------------------------------------------------------------

  # * Update Phase 4 : Step 5

  #-----------------------------------------------------------------------------

  def update_phase4_step5

    counterattacks_snbtl_updatephase4step5

    @counter_battlers_attacking ||= Array.new

    @counter_battlers_defending ||= Array.new

    @counter_battlers_attacking.each do |battler|

      unless battler.hp.zero? || battler.counter_animation.nil?

        battler.animation_id = battler.counter_animation

        battler.damage_pop = !battler.damage.nil?

      end

    end

    @target_battlers.each do |battler|

      unless battler.counter_animation.nil? || battler.hp.zero?

        if battler.counter_animation == 0

          battler.white_flash = true

        elsif battler.counter_animation > 0

          battler.animation_id = battler.counter_animation

          battler.animation_hit = true

        end

        battler.damage_pop = !battler.damage.nil?

        battler.counter_animation = 0

      end

    end

    @active_battler.animation_id      = @active_battler.counter_animation

    @active_battler.damage_pop        = @active_battler.damage.nil?

    @active_battler.counter_animation = 0

    @wait_count += 8

  end

end

 

#-------------------------------------------------------------------------------

# * SDK Enabled Test : END

#-------------------------------------------------------------------------------

end
 
I've edited this topic quite a few times since I posted it, I've ALMOST got it perfect now!

Okay, the last few minor problems deal with delay and targets counter attacking after they've been killed. In Game_Battler.counter_effect, I use a sub method .counter_effective? which checks the conditions of if the counter attack is going to happen or not, which this in turn checks if target/opponent is .dead?.

Still, after the origional target dies, they'll still counter attack from the dead. Sometimes the damage pop won't occur on the counter reciever, so I don't know if they're receiving damage or not but the animation still plays out. What extra step/fix do I need to take so the origional reciever of the attack doesn't "counter attack from the dead"?

Also, on a side note, damage pop sometimes executes late (ie won't happen 'til next turn), perhaps I'll try messing with the @wait_count and see what happens.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top