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.

Error: Demi Skill KILLS Target When HP is 1

Culex

Member

I made a variation of Trickster's demi/quarter skill effect from his famous skill effect bag (I was initially having problems with it...see NOTE) and now it works magnificently, except for one thing. When the monster's hit points reach 1, it takes away whatever is set for the skill's power in the database (in this case, 50) instead of taking away 0. Here is the script segment:

Code:
Located in Game_Battler 3, under these lines:[COLOR=Gray]

      if skill.power != 0 and skill.atk_f > 0
        # State Removed by Shock
        remove_states_shock
        # Set to effective flag
        effective = true
      end[/COLOR]

[...]
[COLOR=Red]      if skill.element_set.include?(9) 
        @damage_hp = self.hp * (100 - skill.power) / 100
        if @damage_hp != 0 
          self.damage = @damage_hp 
        end
      end[/COLOR]
[...]

I changed a few lines, hoping to remedy it:

Code:
From:

          @damage_hp = self.hp * (100 - skill.power) / 100

To:

[COLOR=Red]
        if self.hp == 1
          self.damage = 0
        else
          @damage_hp = self.hp * (100 - skill.power) / 100
        end
[/COLOR]

Now, instead of taking away the skill power's amount, it takes away 1. However, it still doesn't take away 0. It also kills the enemy.

There are no other modifications to the default Game_Battler_3. So, how can I edit these lines so that...

1.) If the monster's hit points are 1, it takes away 0 damage.

2.) It does not kill the enemy...?

Thank you! :)

NOTE (reason for making modification)

The first problem I was having was that all damage-causing skills inflicted 1/2 damage (or whatever the skill power was), despite the fact that I had a conditional statement for the Demi element. That was why I made modifications in the first place.
 

Culex

Member

Ah, I did try that before now that I think about it, and it gave me this error:

Script 'Game_Battler 3' line 190: TypeError occured.

nil can't be coerced into Fixnum

...and then it walks me down to this line:

Code:
self.hp -= self.damage

I actually found it at dubealex's site. But the topic date was definitely from those days.

Oh, I tried downloading your bag of skill effects .zip file from this site's Submitted Scripts section (assuming an answer might lie within), but it's down right now.
 
ahh, I forgot I posted it there XD

Well whats the line that causes the error

and yeah the version I have now is massively updated and is better than the older versions and includes them all so there is no confusion on where to put this stuff
 

Culex

Member

Here, let's just do this:

Game_Battler 3:

Code:
#==============================================================================
# ** Game_Battler (part 3)
#------------------------------------------------------------------------------
#  This class deals with battlers. It's used as a superclass for the Game_Actor
#  and Game_Enemy classes.
#==============================================================================

class Game_Battler
  #--------------------------------------------------------------------------
  # * Determine Usable Skills
  #     skill_id : skill ID
  #--------------------------------------------------------------------------
  def skill_can_use?(skill_id)
    # If there's not enough SP, the skill cannot be used.
    if $data_skills[skill_id].sp_cost > self.sp
      return false
    end
    # Unusable if incapacitated
    if dead?
      return false
    end
    # If silent, only physical skills can be used
    if $data_skills[skill_id].atk_f == 0 and self.restriction == 1
      return false
    end
    # Get usable time
    occasion = $data_skills[skill_id].occasion
    # If in battle
    if $game_temp.in_battle
      # Usable with [Normal] and [Only Battle]
      return (occasion == 0 or occasion == 1)
    # If not in battle
    else
      # Usable with [Normal] and [Only Menu]
      return (occasion == 0 or occasion == 2)
    end
  end
  #--------------------------------------------------------------------------
  # * Applying Normal Attack Effects
  #     attacker : battler
  #--------------------------------------------------------------------------
  def attack_effect(attacker)
    # Clear critical flag
    self.critical = false
    # First hit detection
    hit_result = (rand(100) < attacker.hit)
    # If hit occurs
    if hit_result == true
      # Calculate basic damage
      atk = [attacker.atk - self.pdef / 2, 0].max
      self.damage = atk * (20 + attacker.str) / 20
      # Element correction
      self.damage *= elements_correct(attacker.element_set)
      self.damage /= 100
      # If damage value is strictly positive
      if self.damage > 0
        # Critical correction
        if rand(100) < 4 * attacker.dex / self.agi
          self.damage *= 2
          self.critical = true
        end
        # Guard correction
        if self.guarding?
          self.damage /= 2
        end
      end
      # Dispersion
      if self.damage.abs > 0
        amp = [self.damage.abs * 15 / 100, 1].max
        self.damage += rand(amp+1) + rand(amp+1) - amp
      end
      # Second hit detection
      eva = 8 * self.agi / attacker.dex + self.eva
      hit = self.damage < 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
      # 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 = "Miss"
      # Clear critical flag
      self.critical = false
    end
    # End Method
    return true
  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 = power * rate / 20
      # Element correction
      self.damage *= elements_correct(skill.element_set)
      self.damage /= 100
      # If damage value is strictly positive
      if self.damage > 0
        # Guard correction
        if self.guarding?
          self.damage /= 2
        end
      end
      # Dispersion
      if skill.variance > 0 and self.damage.abs > 0
        amp = [self.damage.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 ? 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 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
      [COLOR=Blue]if skill.element_set.include?(9) 
        if self.hp == 1
          @damage_hp = 0
        else
          @damage_hp = self.hp * (100 - skill.power) / 100
        end
        if @damage_hp != 0 
          self.damage = @damage_hp 
        end
      end[/COLOR]      
      # Subtract damage from HP
      last_hp = self.hp
      [COLOR=Red]self.hp -= self.damage[/COLOR]
      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 = ""
        # If state is unchanged
        unless @state_changed
          #Set damage to "MISS!"
          self.damage = "MISS!" 
        end
      end
    # If miss occurs
    else
      # Set damage to "MISS!"
      self.damage = "MISS!"
    end
    # If not in battle
    unless $game_temp.in_battle
      # Set damage to nil
      self.damage = 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 = -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 = "MISS!"
          end
        end
      end
    # If miss occurs
    else
      # Set damage to "MISS!"
      self.damage = "MISS!"
    end
    # If not in battle
    unless $game_temp.in_battle
      # Set damage to nil
      self.damage = nil
    end
    # End Method
    return effective
  end
  #--------------------------------------------------------------------------
  # * Application of Slip Damage Effects
  #--------------------------------------------------------------------------
  def slip_damage_effect
    # Set damage
    self.damage = self.maxhp / 10
    # Dispersion
    if self.damage.abs > 0
      amp = [self.damage.abs * 15 / 100, 1].max
      self.damage += rand(amp+1) + rand(amp+1) - amp
    end
    # Subtract damage from HP
    self.hp -= self.damage
    # End Method
    return true
  end
  #--------------------------------------------------------------------------
  # * Calculating Element Correction
  #     element_set : element
  #--------------------------------------------------------------------------
  def elements_correct(element_set)
    # If not an element
    if element_set == []
      # Return 100
      return 100
    end
    # Return the weakest object among the elements given
    # * "element_rate" method is defined by Game_Actor and Game_Enemy classes,
    #    which inherit from this class.
    weakest = -100
    for i in element_set
      weakest = [weakest, self.element_rate(i)].max
    end
    return weakest
  end
end

The blue is what I added into Game_Battler 3, and the red is where the error occurs.
 

Culex

Member

Is this what you're talking about?*

Code:
      if @damage_hp != 0 
        self.damage = @damage_hp 
        last_hp = self.hp 
        self.hp -= @damage_hp 
        @hp_damaging = true 
      end

I tried that too, and it still does the skill's power rating as damage when the enemy's hp is 1. The link is here. If I add the if self.hp == 1 segment that we went over, it causes sudden-death for some reason (5 damage doesn't normally kill a monster with ten hit points if he hasn't been hurt yet :P).

I put that* code in the if skill.element_set.include?(9) branch so that it would stop affecting other non-demi spells. I deleted a few lines because they didn't do anything. This is what I'm talking about:

Code:
if skill.element_set.include?(9) 
        @damage_hp = self.hp * (100 - skill.power) / 100
        if @damage_hp != 0 
          self.damage = @damage_hp 
        end
      end

On the other hand, I found another demi script from the crankeye website, created by a user known as Sir Edeon X:

Code:
DEMI AND QUARTER SPELLS:

a) create two attributes in the database (system). call them like 'Demi' or '1/2 HP' and 'Quarter' or '1/4'. What
you like
b) Memorize the IDs and go to the script editor
c) Go to Game_Battler3 and search for 'last_hp = self.hp' in 'def skill_effect(user, skill)'
d) Replace 

last_hp = self.hp
self.hp -= self.damage

for

if skill.element_set.include?(DEMI STATUS ID!!!!)
  @damage_hp = self.hp * 50 / 100
  self.damage = @damage_hp 
  last_hp = self.hp
  self.hp -= @damage_hp
  @hp_damaging = true
elsif skill.element_set.include?(QUARTER STATUS ID!!!!)      
  @damage_hp = self.hp * 25 / 100
  self.damage = @damage_hp 
  last_hp = self.hp
  self.hp -= @damage_hp 
  @hp_damaging = true
else
   last_hp = self.hp
   self.hp -= self.damage
end

e) Now, below 'unless @status_changed' there's a 'self.damage = "Miss" '. Replace it for

[COLOR=red]if @hp_damaging = true
   self.damage = @damage_hp
   @hp_damaging = false
else
   self.damage = "Miss"
end   [/COLOR]

f) And that's all. Create a skill WITH NO effect rating, but WITH the element you want it to do. That's all

The demi skills work, and normal skills work, but whenever I use a status inflicting skill (i.e. sleep) after I use the demi skill, all the status-inflicting skill does is show how much the maximum hp for the monster is as pop damage. It doesn't inflict status or anything. I even followed all of the database requirements and made sure they didn't have elements checked next to the skills. I have isolated the area of script where the problem occurs, and it is in red.

My only objective is to create a demi skill that doesn't kill the enemy and causes 0 damage when the enemy's hp is 1, however I have to do it.

EDIT: Fixed the link. I don't know what happened there.
 

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