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.

Would like some help with a run time bug in battle system.

Dko

Member

Hello's again.
I guess ill start off with what im doing. Im trying to modify Ccoa's side view battle system so when its a characters turn they can input multiple commands for different attacks. To understand what I mean look at the game Chrono Trigger or Xenogears. Ive added quite a bit of code so far(with everyone's help here. :3) and ive been working on the code that adds the actual multiple attacks. But after fixing any obvious errors I get two problems I need to work on.
1: its still making only one attack and ive tested that the character should have 3. (his stamina stat that I added in is set to 3 during run time).

2: Damage is not "poping up" nor are monsters dissapearing when they die.

Could someone help look thru what I have and point out anything I might of missed thats causing the problems? Im not an expert yet at Ruby. Here is my current code.

Scene_Battle 3
Code:
#--------------------------------------------------------------------------
  # * Frame Updat (actor command phase : enemy selection)
  #--------------------------------------------------------------------------
 def update_phase3_enemy_select
    # Update enemy arrow
    @enemy_arrow.update
    # If B button was pressed
    if Input.trigger?(Input::B)
      # Play cancel SE
      $game_system.se_play($data_system.cancel_se)
      # End enemy selection
      end_enemy_select
      return
    end
    
    # If C button was pressed
    if Input.trigger?(Input::C) or Input.trigger?(Input::Y) or Input.trigger?(Input::X) or Input.trigger?(Input::Z)
      # Play decision SE
      $game_system.se_play($data_system.decision_se)
      # Set action
      if @active_battler.is_a?(Game_Actor)
        @num_attacks = @active_battler.stam
        
      else
        @num_attacks = 0
      end
      # Set each attacks strength
      for i in (0..@num_attacks)
        
        if Input.trigger?(Input::C) or Input.trigger?(Input::Y)
          $atk_power[i] = "MED"
        end
        if Input.trigger?(Input::X)
          $atk_power[i] = "STR"
        end
        if Input.trigger?(Input::Z)
          $atk_power[i] = "WEAK"
        end
      end
     
      
    
      # Set action
      @active_battler.current_action.target_index = @enemy_arrow.index
      # End enemy selection
      end_enemy_select
      # If skill window is showing
      if @skill_window != nil
        # End skill selection
        end_skill_select
      end
      # If item window is showing
      if @item_window != nil
        # End item selection
        end_item_select
      end
      # Go to command input for next actor
      phase3_next_actor
    end
  end

CBS Game_Battler
Code:
class Game_Battler
  attr_accessor :pose                     # what pose the battle sprite is in
  attr_accessor :base_pose                # the pose to return to
  attr_accessor :loop                     # loop the pose, or return to base
  attr_accessor :target_x                 # the target x coord
  attr_accessor :target_y                 # the target y coord
  attr_accessor :actual_x                 # current x coord
  attr_accessor :actual_y                 # current y coord
  attr_accessor :base_x                   # starting x coord
  attr_accessor :base_y                   # starting y coord
  attr_accessor :height                   # how tall is the sprite
  attr_accessor :width                    # how wide is the sprite
  attr_accessor :attack_frames            # how many frames in the attack animation
  attr_reader   :back_row                 # is the battler in the back row
  attr_reader   :animated                 # is the battler animated
  attr_reader   :moves                    # does the battler move
   
  def set_pose(pose, loop = true)
    if loop
      @base_pose = pose
    else
      @base_pose = @pose
    end
    @pose = pose
    @loop = loop
  end
  
  def low_hp?
    return ((@hp * 100) / maxhp <= 15)
  end
  
  #--------------------------------------------------------------------------
  # * Applying Normal Attack Effects
  #     attacker : battler
  #--------------------------------------------------------------------------
  def attack_effect(attacker)
    # Clear critical flag
    self.critical = false
      
    if !@active_battler.is_a?(Game_Actor)
      @num_attacks = 0
    else
      @num_attacks = @active_battler.stam
    end
    for i in (0..@num_attacks)
      # First hit detection
      hit_result = (rand(100) < attacker.hit)
      # If hit occurs
      if hit_result == true
        # Calculate basic damage    
          atk = [attacker.ap * 4 * (1 - self.pdef/255), 0].max
          self.damage[i] = atk 
    
        #Calculate damg based on which attack picked
          if $atk_power[i] == "STR" 
            self.damage[i] *= 3
            self.damage[i] /= 2
            $atk_power[i] = "MED"
          end
          if $atk_power[i] == "WEAK" 
            self.damage[i] /= 2
            $atk_power[i] = "MED"
          end
         
           
        # Element correction
        self.damage[i] *= elements_correct(attacker.element_set)
        self.damage[i] /= 100
        # If damage value is strictly positive
        if self.damage[i] > 0
          # Critical correction
          if rand(100) < 4 * attacker.dex / self.agi
            self.damage[i] *= 2
            self.critical = true
          end
          # Guard correction
          if self.guarding?
            self.damage[i] /= 2
          end
        
          # Row correction - self
          if @back_row
            # check to see if attacker has a ranged weapon
            if attacker.is_a?(Game_Actor)
              weapon = $data_weapons[attacker.weapon_id]
              if weapon == nil or !weapon.element_set.include?($RANGED_ELEMENT)
                # if the attacker does not have a ranged weapon, reduce damage
                self.damage[i] /= 2
              end
            end
          end
        
          # Row correction - attacker
          if attacker.back_row
            weapon = $data_weapons[attacker.weapon_id]
            if weapon == nil or !weapon.element_set.include?($RANGED_ELEMENT)
              # the attacker is in the back row with a nonranged weapon
              self.damage[i] /= 2
            end
          end
        end
        # Dispersion
        if self.damage[i].abs > 0
          amp = [self.damage[i].abs * 15 / 100, 1].max
          self.damage[i] += rand(amp+1) + rand(amp+1) - amp
        end
        # Second hit detection
        eva = 8 * self.agi / attacker.dex + self.eva
        hit = self.damage[i] < 0 ? 100 : 100 - eva
        hit = self.cant_evade? ? 100 : hit
      
        hit_result = (rand(100) < hit)
      end
      # If hit occurs
      if hit_result == true
        # State Removed by Shock
        remove_states_shock
        # Substract damage from HP
        self.hp -= self.damage[i]
        # State change
        @state_changed = false
        states_plus(attacker.plus_state_set)
        states_minus(attacker.minus_state_set)
      # When missing
      else
        # Set damage to "Miss"
        self.damage[i] = "Miss"
        # Clear critical flag
        self.critical = false
      end
      # End Method
      return true
    end
    
  end
  
  #--------------------------------------------------------------------------
  # * Apply Skill Effects
  #     user  : the one using skills (battler)
  #     skill : skill
  #--------------------------------------------------------------------------
  def skill_effect(user, skill)
    # Clear critical flag
    self.critical = false
    # If skill scope is for ally with 1 or more HP, and your own HP = 0,
    # or skill scope is for ally with 0, and your own HP = 1 or more
    if ((skill.scope == 3 or skill.scope == 4) and self.hp == 0) or
       ((skill.scope == 5 or skill.scope == 6) and self.hp >= 1)
      # End Method
      return false
    end
    # Clear effective flag
    effective = false
    # Set effective flag if common ID is effective
    effective |= skill.common_event_id > 0
    # First hit detection
    hit = skill.hit
    if skill.atk_f > 0
      hit *= user.hit / 100
    end
    hit_result = (rand(100) < hit)
    # Set effective flag if skill is uncertain
    effective |= hit < 100
    # If hit occurs
    if hit_result == true
      # Calculate power
      power = skill.power + user.atk * skill.atk_f / 100
      if power > 0
        power -= self.pdef * skill.pdef_f / 200
        power -= self.mdef * skill.mdef_f / 200
        power = [power, 0].max
      end
      # Calculate rate
      rate = 20
      rate += (user.str * skill.str_f / 100)
      rate += (user.dex * skill.dex_f / 100)
      rate += (user.agi * skill.agi_f / 100)
      rate += (user.int * skill.int_f / 100)
      # Calculate basic damage
      self.damage[0] = power * rate / 20
      # Element correction
      self.damage[0] *= elements_correct(skill.element_set)
      self.damage[0] /= 100
      # If damage value is strictly positive
      if self.damage[0] > 0
        # Guard correction
        if self.guarding?
          self.damage[0] /= 2
        end
      end
      # Dispersion
      if skill.variance > 0 and self.damage[0].abs > 0
        amp = [self.damage[0].abs * skill.variance / 100, 1].max
        self.damage += rand(amp+1) + rand(amp+1) - amp
      end
      # Second hit detection
      eva = 8 * self.agi / user.dex + self.eva
      hit = self.damage[0] < 0 ? 100 : 100 - eva * skill.eva_f / 100
      hit = self.cant_evade? ? 100 : hit
      hit_result = (rand(100) < hit)
      # Set effective flag if skill is uncertain
      effective |= hit < 100
    end
    # If hit occurs
    if hit_result == true
      if self.damage[0] > 0
      end
      # If physical attack has power other than 0
      if skill.power != 0 and skill.atk_f > 0
        # State Removed by Shock
        remove_states_shock
        # Set to effective flag
        effective = true
      end
      # Substract damage from HP
      last_hp = self.hp
      self.hp -= self.damage[0]
      effective |= self.hp != last_hp
      # State change
      @state_changed = false
      effective |= states_plus(skill.plus_state_set)
      effective |= states_minus(skill.minus_state_set)
      # If power is 0
      if skill.power == 0
        # Set damage to an empty string
        self.damage[0] = ""
        # If state is unchanged
        unless @state_changed
          # Set damage to "Miss"
          self.damage[0] = "Miss"
        end
      end
    # If miss occurs
    else
      # Set damage to "Miss"
      self.damage[0] = "Miss"
    end
    # If not in battle
    unless $game_temp.in_battle
      # Set damage to nil
      self.damage[0] = nil
    end
    # End Method
    return effective
  end
  #--------------------------------------------------------------------------
  # * Application of Item Effects
  #     item : item
  #--------------------------------------------------------------------------
  def item_effect(item)
    # Clear critical flag
    self.critical = false
    # If item scope is for ally with 1 or more HP, and your own HP = 0,
    # or item scope is for ally with 0 HP, and your own HP = 1 or more
    if ((item.scope == 3 or item.scope == 4) and self.hp == 0) or
       ((item.scope == 5 or item.scope == 6) and self.hp >= 1)
      # End Method
      return false
    end
    # Clear effective flag
    effective = false
    # Set effective flag if common ID is effective
    effective |= item.common_event_id > 0
    # Determine hit
    hit_result = (rand(100) < item.hit)
    # Set effective flag is skill is uncertain
    effective |= item.hit < 100
    # If hit occurs
    if hit_result == true
      # Calculate amount of recovery
      recover_hp = maxhp * item.recover_hp_rate / 100 + item.recover_hp
      recover_sp = maxsp * item.recover_sp_rate / 100 + item.recover_sp
      if recover_hp < 0
        recover_hp += self.pdef * item.pdef_f / 20
        recover_hp += self.mdef * item.mdef_f / 20
        recover_hp = [recover_hp, 0].min
      end
      # Element correction
      recover_hp *= elements_correct(item.element_set)
      recover_hp /= 100
      recover_sp *= elements_correct(item.element_set)
      recover_sp /= 100
      # Dispersion
      if item.variance > 0 and recover_hp.abs > 0
        amp = [recover_hp.abs * item.variance / 100, 1].max
        recover_hp += rand(amp+1) + rand(amp+1) - amp
      end
      if item.variance > 0 and recover_sp.abs > 0
        amp = [recover_sp.abs * item.variance / 100, 1].max
        recover_sp += rand(amp+1) + rand(amp+1) - amp
      end
      # If recovery code is negative
      if recover_hp < 0
        # Guard correction
        if self.guarding?
          recover_hp /= 2
        end
      end
      # Set damage value and reverse HP recovery amount
      self.damage[0] = -recover_hp
      # HP and SP recovery
      last_hp = self.hp
      last_sp = self.sp
      self.hp += recover_hp
      self.sp += recover_sp
      effective |= self.hp != last_hp
      effective |= self.sp != last_sp
      # State change
      @state_changed = false
      effective |= states_plus(item.plus_state_set)
      effective |= states_minus(item.minus_state_set)
      # If parameter value increase is effective
      if item.parameter_type > 0 and item.parameter_points != 0
        # Branch by parameter
        case item.parameter_type
        when 1  # Max HP
          @maxhp_plus += item.parameter_points
        when 2  # Max SP
          @maxsp_plus += item.parameter_points
        when 3  # Strength
          @str_plus += item.parameter_points
        when 4  # Dexterity
          @dex_plus += item.parameter_points
        when 5  # Agility
          @agi_plus += item.parameter_points
        when 6  # Intelligence
          @int_plus += item.parameter_points
        end
        # Set to effective flag
        effective = true
      end
      # If HP recovery rate and recovery amount are 0
      if item.recover_hp_rate == 0 and item.recover_hp == 0
        # Set damage to empty string
        self.damage = ""
        # If SP recovery rate / recovery amount are 0, and parameter increase
        # value is ineffective.
        if item.recover_sp_rate == 0 and item.recover_sp == 0 and
           (item.parameter_type == 0 or item.parameter_points == 0)
          # If state is unchanged
          unless @state_changed
            # Set damage to "Miss"
            self.damage[0] = "Miss"
          end
        end
      end
    # If miss occurs
    else
      # Set damage to "Miss"
      self.damage[0] = "Miss"
    end
    # If not in battle
    unless $game_temp.in_battle
      # Set damage to nil
      self.damage[0] = nil
    end
    # End Method
    return effective
  end
end

CBS Sprite_Battler
Code:
 Damage
      if @battler.damage_pop
        if @battler.stam == nil
          damage(@battler.damage[0], @battler.critical)
          @battler.damage[0] = nil
          @battler.critical = false
        else
          for i in (0..@battler.stam)
            damage(@battler.damage[i], @battler.critical)
            @battler.damage[i] = nil
            @battler.critical = false
          end          
        end
        
        @battler.damage_pop = false
      end
      # Collapse
      if @battler.damage.empty? == true and @battler.dead?
        if @battler.is_a?(Game_Enemy)
          $game_system.se_play($data_system.enemy_collapse_se)
          @battler_visible = false
          collapse
        elsif @pose != $DEAD
          $game_system.se_play($data_system.actor_collapse_se)
          @battler.set_pose($DEAD)
        end
      end
    end

CBS Scene_Battle
Code:
#--------------------------------------------------------------------------
  # * Frame Update (main phase step 4 : animation for target)
  #--------------------------------------------------------------------------
  def update_phase4_step4
    # Animation for target
    for target in @target_battlers
      for i in (0..target.damage.length)
        target.animation_id = @animation2_id
        target.animation_hit = (target.damage[i] != "Miss")
        if target.damage[i] != nil
          if target.damage[i].is_a?(String)
            if target.damage[i] == "Miss"
              target.set_pose($MISS, false)
            end
          elsif target.damage[i] > 0 
            target.set_pose($HIT, false)
          end
        end        
      end      
    end
    
    # Animation has at least 8 frames, regardless of its length
    @wait_count = 8
    # Shift to step 5
    @phase4_step = 5
  end

I think this is all of it. Im sorry if its a lot to look thru.
 

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