TheRiotInside

Extra Ordinaire
Veteran
Joined
Sep 3, 2012
Messages
270
Reaction score
124
First Language
English
Primarily Uses
Hey there, thanks up front for reading and also possibly helping! I'll try and keep this to the point.

I am not a scripter, nor do I claim to know what I'm doing. I have stumbled my way through making a few little edits to Game_Battler 3 in order to change how damage is calculated for normal attacks and skills. It was working fine, but I didn't want the skills to use the 0-100 stat influence functions in the database, and after changing around a few things, I've hit a snag. I'll post the script at the end, as I haven't figured out how to hide it in a click-to-open bar yet, sorry about that haha.

The error I'm getting is this:

Script 'Game_Battler 3' line 177: NoMethodError occured.

undefined method '*' for nil:NilClass
 This error comes up whenever an enemy tries to cast a skill. Casting my own skills works fine, as does attacking for both parties.

It's referring to the line where the elemental modifier is added to a skill after the damage is calculated (I haven't modified anything past the damage calculations, so the error is on a line I haven't touched). It was working before I changed the damage formulas, so I'm guessing it's just some kind of syntax error or something silly like that causing the error elsewhere, but I can't figure it out for the life of me. I just want it to calculate damage, then go on and do the rest of the unmodified script. Any help would be greatly appreciated, thanks! :)

(I added the number to the beginning of the line to make it easier to find, as well as markings right above it to show what I've modified)

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      if attacker.str >= self.pdef        self.damage = attacker.atk * (50 + attacker.str - self.pdef) / 50      end      if attacker.str < self.pdef        self.damage = attacker.atk * 50 / (50 + self.pdef - attacker.str)      end      # Element correction      self.damage *= elements_correct(attacker.element_set)      self.damage /= 100      # If damage value is strictly positive      if self.damage < 0        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 * 10 / 100, 1].max        self.damage += rand(amp+1) + rand(amp+1) - amp      end      # Second hit detection      eva = 5 * 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***   # Attack Influence Multipliers      #  1 = 10%  |  2 = 20%  | (...) |  9 = 90%  |  10 = 100%      # 11 = 1.1x | 12 = 1.2x | (...) | 19 = 1.9x |  20 = 2x      # 21 = 2.1x | 22 = 2.2x | (...) | 99 = 9.9x | 100 = 10x      if skill.atk_f > 0        skill.power = user.atk * skill.atk_f / 10      end      # Damage formulae depending on physical/magic attack and resistance      if skill.str_f > 0        if skill.pdef_f > 0          if user.str >= self.pdef            self.damage = skill.power * (50 + user.str - self.pdef) / 50          end          if user.str < self.pdef            self.damage = skill.power * 50 / (50 + self.pdef - user.str)          end        end        if skill.mdef_f > 0          if user.str >= self.mdef            self.damage = skill.power * (50 + user.str - self.mdef) / 50          end          if user.str < self.mdef            self.damage = skill.power * 50 / (50 + self.mdef - user.str)          end        end      end      if skill.int_f > 0        if skill.pdef_f > 0          if user.int >= self.pdef            self.damage = skill.power * (50 + user.int - self.pdef) / 50          end          if user.int < self.pdef            self.damage = skill.power * 50 / (50 + self.pdef - user.int)          end        end        if skill.mdef_f > 0          if user.int >= self.mdef            self.damage = skill.power * (50 + user.int - self.mdef) / 50          end          if user.int < self.mdef            self.damage = skill.power * 50 / (50 + self.mdef - user.int)          end        end***   end      # Element correction177   self.damage *= elements_correct(skill.element_set)      self.damage /= 100      if self.damage <= 0        self.damage == 0      end      # 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 = 5 * 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      # Substract damage from HP      last_hp = self.hp      self.hp -= self.damage      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 / 20    # Dispersion    if self.damage.abs > 0      amp = [self.damage.abs * 10 / 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  endend
 
Last edited by a moderator:

Shaz

Global Moderators
Global Mod
Joined
Mar 2, 2012
Messages
43,344
Reaction score
15,158
First Language
English
Primarily Uses
RMMV
It's saying self.damage hasn't been defined.

In the original script, self.damage is always calculated. In your modified script, it's only calculated if certain conditions are met. To overcome this, just do self.damage = 0 before all of your mods to give it an initial value. OR re-evaluate your logic, because there may be other conditions you need to cater for.

Also, this:

if self.damage <= 0 self.damage == 0endwon't work.== is comparison, not assignment. Change it to =
 
Last edited by a moderator:

TheRiotInside

Extra Ordinaire
Veteran
Joined
Sep 3, 2012
Messages
270
Reaction score
124
First Language
English
Primarily Uses
I added a self.damage = 0 to the start before the calculations for any strange situations. Thanks to your advice, I found out that the error was to do with me not being diligent in giving enemy skills STR-F and INT-F numbers, so whenever one would be used, no damage calculating conditions were met, not defining the self.damage value in the first place, thus causing the errors further down the script.

Thanks for the help! As an aside, did you have any recommendations for making the damage calculations more efficient? It's not necessary, just wondering. I assume that there is always a better way to do scripting than the way I am doing it, haha.
 

Latest Threads

Latest Posts

Latest Profile Posts

Changed my avatar, goodbye Alan Sugar, hello George Carlin (one of my favorite human beings ever)
If you still don't subscribe our Polish channel please consider it :)
1.png
Who wants to see my review of the worst star wars movie? This movie has all the excitement of being on Jury Duty of the most boring case ever about trade negotiations.
A lot to learn to make a game. Can I handle it?
I've been working on status effects since last thursday, and today I finished the core mechanic of Zombie, Teleport, Curse and Recall. Zombie and Curse are lacking a few things to make them complete atm. Teleport though is the "HAHA" spell for some of my mobs, but can "NOPE" at them with Recall.

Forum statistics

Threads
115,169
Messages
1,087,777
Members
149,711
Latest member
GHench
Top