Hey guys, I just finished ironing out the bugs after doing some edits to the default damage formulas and whatnot. I'm definitely no scripter, but after some digging, I found the lines I needed, and made the necessary adjustments until things were working how I wanted them.
Overall, it expands your skill options a bit, and definitely makes things easier to calculate.
Notes:
All right, so here's what I've done:
Standard Attack
For standard attacks, the Attack stat is the base damage, so a sword with 10 Atk would give you 10 damage. Strength affects your base damage by adding it to itself for every 100 Str. So, 100 Str would double your base damage, 200 would triple, 300 would quadruple, etc. Standard stats go up to 999, and 900 Str would increase your base damage by 10x.
Physical Defense of the target reduces damage dealt linearly after all calculations, but before Critical Hits and Guarding. So, a 10 Atk sword with 100 Str against a target with 5 PDef would do the following:
Base Damage = Attack * (100 + Strength) / 100
Base Damage = 10 * (100 + 100) / 100
Base Damage = 10 * 200 / 100
Base Damage = 2000 / 100
Base Damage = 20
Damage = Base Damage - Physical Defense
Damage = 20 - 5
Damage = 15
Critical Hits and Guarding were moved to the end of the calculations, so you take the final damage to be dealt, THEN adjust, giving you as close to doubling and halving as possible.
Skills
This was a bit trickier, but I believe it adds a lot more options to making different skill types and whatnot. Originally, you had to set a base power for the skill and work off of that. Now, if you set the Attack-F (Atk influence) to 0, skills still work normally. But if you set the Atk-F to anything else (1-100) you get skills that base their damage off of your actual Attack stat, ignoring the skill power completely.
You might be asking yourself how this helps at all. Its best use is to make skills that are based off of only the Attack stat, and not the skill power. So if you wanted a skill that always did around double of whatever a standard attack would do, now you can. This makes long-term balancing of skills vs. attacks so much easier, since your Attack stat would always be increasing, but the skill power was always constant.
I've set the Attack-F to influence damage in a certain way, but it is very easily modifiable.
*checks to see if Attack-F is over 0*
Skill Power = Attack * Skill Attack-F / 10
So, if Attack-F is set to 10, the skill power equals your Attack stat (which equals a standard attack). If set to 5 for example, the skill's damage will be equal to 50% of a standard attack. Setting to 20 gives you double, 50 gives you 5x, etc.
The script then checks for the standard rates, so if Strength-F is 100, it will influence the base damage the same way it would for a standard attack. The same applies for the other stats. It then checks to see if either the PDefense-F or the MDefense-F are above 0. If one is set to 100, it reduces linearly like it would for standard attacks. Setting to 50 would reduce by 1 for every 2 in the respective stat, 25 would be 1 for every 4, etc.
The drawback of setting up the rates this way is that having a skill affected by more than one stat, and both defenses makes things messy, so it's ideal for single type, single stat-based skills.
I think that about covers it, sorry for the essay, here's the script. Just replace Game_Battler 3 entirely with this:
It was exciting actually making this work myself. If you have any questions or comments, I'd be more than happy to read them
Overall, it expands your skill options a bit, and definitely makes things easier to calculate.
Notes:
- This is meant for the Default Battle System in RMXP.
- Some of the script work might be a bit ugly. Me not being a scripter is fully to blame. Feel free to criticize
- Magic Defense reductions have not been fully tested. After testing PDef, I presumed MDef would work as well.
- No credit is needed, as this is just a small edit done by a non-scripter.
All right, so here's what I've done:
Standard Attack
For standard attacks, the Attack stat is the base damage, so a sword with 10 Atk would give you 10 damage. Strength affects your base damage by adding it to itself for every 100 Str. So, 100 Str would double your base damage, 200 would triple, 300 would quadruple, etc. Standard stats go up to 999, and 900 Str would increase your base damage by 10x.
Physical Defense of the target reduces damage dealt linearly after all calculations, but before Critical Hits and Guarding. So, a 10 Atk sword with 100 Str against a target with 5 PDef would do the following:
Base Damage = Attack * (100 + Strength) / 100
Base Damage = 10 * (100 + 100) / 100
Base Damage = 10 * 200 / 100
Base Damage = 2000 / 100
Base Damage = 20
Damage = Base Damage - Physical Defense
Damage = 20 - 5
Damage = 15
Critical Hits and Guarding were moved to the end of the calculations, so you take the final damage to be dealt, THEN adjust, giving you as close to doubling and halving as possible.
Skills
This was a bit trickier, but I believe it adds a lot more options to making different skill types and whatnot. Originally, you had to set a base power for the skill and work off of that. Now, if you set the Attack-F (Atk influence) to 0, skills still work normally. But if you set the Atk-F to anything else (1-100) you get skills that base their damage off of your actual Attack stat, ignoring the skill power completely.
You might be asking yourself how this helps at all. Its best use is to make skills that are based off of only the Attack stat, and not the skill power. So if you wanted a skill that always did around double of whatever a standard attack would do, now you can. This makes long-term balancing of skills vs. attacks so much easier, since your Attack stat would always be increasing, but the skill power was always constant.
I've set the Attack-F to influence damage in a certain way, but it is very easily modifiable.
*checks to see if Attack-F is over 0*
Skill Power = Attack * Skill Attack-F / 10
So, if Attack-F is set to 10, the skill power equals your Attack stat (which equals a standard attack). If set to 5 for example, the skill's damage will be equal to 50% of a standard attack. Setting to 20 gives you double, 50 gives you 5x, etc.
The script then checks for the standard rates, so if Strength-F is 100, it will influence the base damage the same way it would for a standard attack. The same applies for the other stats. It then checks to see if either the PDefense-F or the MDefense-F are above 0. If one is set to 100, it reduces linearly like it would for standard attacks. Setting to 50 would reduce by 1 for every 2 in the respective stat, 25 would be 1 for every 4, etc.
The drawback of setting up the rates this way is that having a skill affected by more than one stat, and both defenses makes things messy, so it's ideal for single type, single stat-based skills.
I think that about covers it, sorry for the essay, here's the script. Just replace Game_Battler 3 entirely with this:
Code:
[sp]#==============================================================================
# ** 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
self.damage = attacker.atk * (100 + attacker.str) / 100
# Element correction
self.damage *= elements_correct(attacker.element_set)
self.damage /= 100
# If damage value is strictly positive
if self.damage > 0
self.damage -= self.pdef
# 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 = 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
# 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
# Calculate rate
rate = 100
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 = skill.power * rate / 100
# Element correction
self.damage *= elements_correct(skill.element_set)
self.damage /= 100
if skill.pdef_f > 0
self.damage -= (self.pdef * skill.pdef_f / 100)
end
if skill.mdef_f > 0
self.damage -= (self.mdef * skill.mdef_f / 100)
end
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 = 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
# 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 / 5
# 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
[/sp]
It was exciting actually making this work myself. If you have any questions or comments, I'd be more than happy to read them