#==============================================================================
# ** 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
##:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#
# ALTERNATE ATTACK ALGORITHMS CONFIGURATION
#
##:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# How to use this script :
#
# This allows your weapons to follow different damage algorithms. If your weapon
# uses a normal attack algorithm, you MUST place its ID in the
# NORMAL_WEAPONS_IDS, or else it wouldn't be good for your game. Also place all
# weapons ID except SP damaging and absorbing ones, into the
# "ALL_WEAPONS_IDS", because if you don't, a nasty bug will prevent you from
# dealing damage with normal attack.
#
# ATMA_WEAPON_IDS = [X,X...] : A weapon with an ID equal to X will inflict
# more damage depending on the user’s HP. If HP are full, attack power is doubled.
# If HP are at minimum, attack power is normal. If HP are equal to half, attack
# power is equal to 1.5 of the normal Attack power, and so on...
#
# VALIANT_IDS = [X, X...] : The opposite effect of Atma Weapon.
# If HP are at minimum, attack power is doubled, and so on...
#
# WHITE_MOON_IDS = [X, X...] : Follows the same formula than Atma Weapon
# but works with SP
#
# CONFORMER_IDS = [X, X...] : Deals damage based on user’s Level.
#
# INTEL_WEAPON_IDS = [X, X...] : Inflicts damage based on user's Intelligence
# instead of Strength
#
# NINJA_IDS = [X, X...] : Inflicts damage based on user's Agility
# instead of Strength
#
# MIND_BLASTER_IDS = [X, X...] : Damage is inflicted to SP. Damage
# relies also on the opponent's Magic Defense and your Intelligence
#
# BLOOD_SWORD_IDS = [X, X...] & PERCENT_DRAINED = X :
# some damage is absorbed from the attack. How many? PERCENT_DRAINED %
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
OTHER_WEAPONS_IDS = [0]
ALL_WEAPONS_IDS = []
ATMA_WEAPON_IDS = []
VALIANT_IDS = []
WHITE_MOON_IDS = []
CONFORMER_IDS = []
INTEL_WEAPON_IDS = []
NINJA_IDS = []
MIND_BLASTER_IDS = []
BLOOD_SWORD_IDS = []
PERCENT_DRAINED = 50
#--------------------------------------------------------------------------
# * 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
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Alternative Attack Algorithms
# Authors: Xelias and PhoenixFire
# Version: 1.00
# Type: Battle Add-ON
# Date v1.00: 7.11.2009
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#
# This work is protected by the following license:
# #----------------------------------------------------------------------------
# #
# # Creative Commons - Attribution-NonCommercial-ShareAlike 3.0 Unported
# # ( http://creativecommons.org/licenses/by-nc-sa/3.0/ )
# #
# # You are free:
# #
# # to Share - to copy, distribute and transmit the work
# # to Remix - to adapt the work
# #
# # Under the following conditions:
# #
# # Attribution. You must attribute the work in the manner specified by the
# # author or licensor (but not in any way that suggests that they endorse you
# # or your use of the work).
# #
# # Noncommercial. You may not use this work for commercial purposes.
# #
# # Share alike. If you alter, transform, or build upon this work, you may
# # distribute the resulting work only under the same or similar license to
# # this one.
# #
# # - For any reuse or distribution, you must make clear to others the license
# # terms of this work. The best way to do this is with a link to this web
# # page.
# #
# # - Any of the above conditions can be waived if you get permission from the
# # copyright holder.
# #
# # - Nothing in this license impairs or restricts the author's moral rights.
# #
# #----------------------------------------------------------------------------
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
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.is_a?(Game_Actor)
if OTHER_WEAPONS_IDS.include?(attacker.weapon_id)
atk = [attacker.atk - self.pdef / 2, 0].max
self.damage = atk * (20 + attacker.str) / 20
end
if ATMA_WEAPON_IDS.include?(attacker.weapon_id)
atk = [attacker.atk - self.pdef / 2,0].max
atk2 = atk * (20 + attacker.str) / 20
self.damage = atk2 + ((atk2*((attacker.hp*100)/attacker.maxhp))/100)
end
if VALIANT_IDS.include?(attacker.weapon_id)
atk = [attacker.atk - self.pdef / 2,0].max
atk2 = atk * (20 + attacker.str) / 20
minushp = attacker.maxhp - attacker.hp
self.damage = atk2 + ((atk2*((minushp*100)/attacker.maxhp))/100)
end
if WHITE_MOON_IDS.include?(attacker.weapon_id)
atk = [attacker.atk - self.pdef / 2,0].max
atk2 = atk * (20 + attacker.str) / 20
self.damage = atk2 + ((atk2*((attacker.sp*100)/attacker.maxsp))/100)
end
if CONFORMER_IDS.include?(attacker.weapon_id)
atk = [attacker.atk - self.pdef / 2,0].max
atk2 = atk * (20 + attacker.str) / 20
self.damage = atk2 + (atk2*(((attacker.level*100) / 99)/100))
end
if INTEL_WEAPON_IDS.include?(attacker.weapon_id)
atk = [attacker.atk - self.pdef / 2, 0].max
self.damage = atk * (20 + attacker.int) / 20
end
if NINJA_IDS.include?(attacker.weapon_id)
atk = [attacker.atk - self.pdef / 2, 0].max
self.damage = atk * (20 + attacker.agi) / 20
end
if BLOOD_SWORD_IDS.include?(attacker.weapon_id)
atk = [attacker.atk - self.pdef / 2, 0].max
self.damage = atk * (20 + attacker.str) / 20
end
end
if attacker.is_a?(Game_Enemy)
atk = [attacker.atk - self.pdef / 2, 0].max
self.damage = atk * (20 + attacker.str) / 20
end
# 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 attacker.is_a?(Game_Actor)
if GENJI_WEAPON_IDS.include?(attacker.weapon_id)
if rand(100) < 8 * attacker.dex / self.agi
self.damage *= 2
self.critical = true
end
end
if KIKU_ICHIMONJI_IDS.include?(attacker.weapon_id)
if rand(100) < 4 * attacker.dex / self.agi
self.damage *= 4
self.critical = true
end
end
elsif rand(100) < 4 * attacker.dex / self.agi
self.damage *= 2
self.critical = true
end
# Guard correction
if self.guarding?
if GUARD_BREAKER_IDS.include?(attacker.weapon_id)
self.damage /=1
end
else
self.damage /=2
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
if attacker.is_a?(Game_Actor)
if MIND_BLASTER_IDS.include?(attacker.weapon_id)
self.sp -= self.damage
self.damage = sprintf('%+d %s', -self.damage, $data_system.words.sp)
end
if BLOOD_SWORD_IDS.include?(attacker.weapon_id)
healing = (self.damage*PERCENT_DRAINED)/100
self.hp -= self.damage
attacker.hp += healing
end
if ALL_WEAPONS_IDS.include?(attacker.weapon_id)
self.hp -= self.damage
end
else self.hp -= self.damage
end
end
# 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
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
# 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 / 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