Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- STR_MOD_OVERCAP_MOD = 1 #0.5 # modifier values above softcap will apply at this rate
- # 1.0 in the above will disable this scaling
- STR_MOD_SOFTCAP = 2.22 # str modifier softcap
- ATTACK_DAMAGE_STR_FOCUS = 200.0 # 300.0 previous default
- ATTACK_DAMAGE_VIT_FOCUS = 500.0 # 500.0 previous default
- HEAL_NORMAL_WIS_FOCUS = 1000.0
- module DamageFormula
- # This new constant bank overrides all previous settings
- # dont change
- OFFENSE_STAT_FOCUS = {}
- DEFENSE_STAT_FOCUS = {}
- OFFENSE_MOD_SOFTCAP = {}
- OFFENSE_MOD_OVERCAP_RATIO = {}
- DEFENSE_MOD_SOFTCAP = {}
- DEFENSE_MOD_OVERCAP_RATIO = {}
- # symbol bank
- # :attack_damage
- # :aura_glaive
- # :spell_damage
- # :xbow_damage
- # :blood_damage
- # :gun_damage
- # :heal_normal
- # :blood_heal_direct
- # for heals, only the offense stat matters
- # Offense Stat Focus - The the amout of offensive stat it takes to reach double damage
- # calculated on a curve
- # (ie, 500 = double, 1000 = triple)
- # higher numbers means the stat takes longer to get to broken numbers
- OFFENSE_STAT_FOCUS.default = 500
- OFFENSE_STAT_FOCUS[:attack_damage] = 300 # primarily why attack is so OP
- OFFENSE_STAT_FOCUS[:aura_glaive] = 500
- OFFENSE_STAT_FOCUS[:xbow_damage] = 400
- OFFENSE_STAT_FOCUS[:spell_damage] = 500
- OFFENSE_STAT_FOCUS[:gun_damage] = 500 # uses weapon power as "str" for ingrid now, default disabled
- OFFENSE_STAT_FOCUS[:blood_damage] = 500
- OFFENSE_STAT_FOCUS[:heal_normal] = 1000
- OFFENSE_STAT_FOCUS[:blood_heal_direct] = 500 # blood heal is only half efficent by default, hence lower numbers here
- # Defensive Stat Focus - The amout of defensive stat it takes to half damage
- # caluclated on a curve
- # (ie, 500 = half, 1000 = third)
- DEFENSE_STAT_FOCUS.default = 500
- DEFENSE_STAT_FOCUS[:attack_damage] = 450
- DEFENSE_STAT_FOCUS[:aura_glaive] = 500 # irrelevant/ignored in calc
- DEFENSE_STAT_FOCUS[:xbow_damage] = 500
- DEFENSE_STAT_FOCUS[:spell_damage] = 350
- DEFENSE_STAT_FOCUS[:gun_damage] = 500
- DEFENSE_STAT_FOCUS[:blood_damage] = 500
- DEFENSE_STAT_FOCUS[:heal_normal] = 500 # irrelevant/ignored in calc
- DEFENSE_STAT_FOCUS[:blood_heal_direct] = 500 # irrelevant/ignored in calc
- # Offense mod softcap - the point at which a damage modifier stops rising at a 1:1 ratio
- # ratios below
- # (a 3x modifier with a softcap of 2 and overcap ratio of 0.5 becomes 2.5)
- OFFENSE_MOD_SOFTCAP.default = 1.0
- OFFENSE_MOD_SOFTCAP[:attack_damage] = 2.22
- OFFENSE_MOD_SOFTCAP[:aura_glaive] = 1.0
- OFFENSE_MOD_SOFTCAP[:xbow_damage] = 2.22
- OFFENSE_MOD_SOFTCAP[:spell_damage] = 1.0
- OFFENSE_MOD_SOFTCAP[:gun_damage] = 1.0
- OFFENSE_MOD_SOFTCAP[:blood_damage] = 2.22
- OFFENSE_MOD_SOFTCAP[:heal_normal] = 1.0
- OFFENSE_MOD_SOFTCAP[:blood_heal_direct] = 1.0
- # Offense mod overcap ratio - how much of a bonus is applied
- # (a 3x modifier with a softcap of 2 and overcap ratio of 0.5 becomes 2.5)
- OFFENSE_MOD_OVERCAP_RATIO.default = 1.0
- OFFENSE_MOD_OVERCAP_RATIO[:attack_damage] = 0.5
- OFFENSE_MOD_OVERCAP_RATIO[:aura_glaive] = 1.0
- OFFENSE_MOD_OVERCAP_RATIO[:xbow_damage] = 0.5
- OFFENSE_MOD_OVERCAP_RATIO[:spell_damage] = 1.0
- OFFENSE_MOD_OVERCAP_RATIO[:gun_damage] = 0.0 # turned off gun scaling to match prior values
- OFFENSE_MOD_OVERCAP_RATIO[:blood_damage] = 0.5
- OFFENSE_MOD_OVERCAP_RATIO[:heal_normal] = 1.0
- OFFENSE_MOD_OVERCAP_RATIO[:blood_heal_direct] = 1.0
- # same as with offense
- DEFENSE_MOD_SOFTCAP.default = 1.0
- DEFENSE_MOD_SOFTCAP[:attack_damage] = 1.0
- DEFENSE_MOD_SOFTCAP[:aura_glaive] = 1.0 # no defense stat
- DEFENSE_MOD_SOFTCAP[:xbow_damage] = 1.0
- DEFENSE_MOD_SOFTCAP[:spell_damage] = 1.0
- DEFENSE_MOD_SOFTCAP[:gun_damage] = 1.0
- DEFENSE_MOD_SOFTCAP[:blood_damage] = 2.22
- DEFENSE_MOD_SOFTCAP[:heal_normal] = 1.0 # no defense stat
- DEFENSE_MOD_SOFTCAP[:blood_heal_direct] = 1.0 # no defense stat
- DEFENSE_MOD_OVERCAP_RATIO.default = 1.0
- DEFENSE_MOD_OVERCAP_RATIO[:attack_damage] = 1.0
- DEFENSE_MOD_OVERCAP_RATIO[:aura_glaive] = 1.0 # no defense stat
- DEFENSE_MOD_OVERCAP_RATIO[:xbow_damage] = 1.0
- DEFENSE_MOD_OVERCAP_RATIO[:spell_damage] = 1.0
- DEFENSE_MOD_OVERCAP_RATIO[:gun_damage] = 1.0
- DEFENSE_MOD_OVERCAP_RATIO[:blood_damage] = 1.0
- DEFENSE_MOD_OVERCAP_RATIO[:heal_normal] = 1.0 # no defense stat
- DEFENSE_MOD_OVERCAP_RATIO[:blood_heal_direct] = 1.0 # no defense stat
- end
- # cannot be zero or negative
- # DAMAGE FORMULA
- # These additions are for linked proc skills with secondary effects
- #
- # formulas available
- # attack_damage - for normal attacks and physical skills
- # mixed_damage - ONLY for non-proc dual component skills with splash
- # deritivave_damage - does the skill power mod percent of the main skill's damage
- # gun_damage - for ingrid's gun attacks, no str mod but gains a very slight bonus
- # from level to keep it in line with other skills
- # xbow_damage - for Eskandar's xbow skills
- # blood_damage - for Soha's NON WEAPON blood skills
- # spell_damage - for any int based non-weapon power skill
- # heal_normal - normal heal based on wis
- # blood_heal_direct - heal from blood power, some is lost, less is lost with higher int
- # final_reckoning_damage - for the final reckoning skill, damage based on absorbed HP
- # tags (goes in the skill's note)
- # <skill damage mod n> skill does n% of normal damage
- # <str scale mod n> str scaling is n% of normal
- # <int scale mod n> int scaling is n% of normal
- # <dex scale mod n> dex scaling is n% of normal (for extra hits on hits skills, and xbow damage)
- # <physical weight n> n is a value > 1. The weight given to physical for non-proc multicomponent skills
- # <magical weight n> n is a value > 1. The weight given to magical for non-proc multicomponent skills
- # <drain ratio n> n% HP is healed to the user from this skill (default is 50%)
- # only affects skills with the damage type "HP Drain"
- # <spell power mod n> affects the main component of spell_damage and blood_damage ONLY
- # <proc damage x y> skill with id x will proc with y% of its normal damage when this skill is used
- # if used on a state, damage will proc when a physical attack is used
- # <noproc> this skill will not proc "physical attack" based procs
- # (for use with the ice blades etc, since they are techincally physical)
- #
- # spells, dots, and blood skills have 3 new tags
- # <base damage n>
- # sets the absolute base of the skill, default is 100
- # <offense scale n>
- # offensive stat will contribute n% toward the base
- # (default is 100%)
- # <defense scale n>
- # defending stat will subtract n% of its value from the base
- # (default is 50%)
- # new formula is (base + offense_stat - defense_stat) * scalar mods
- # recommend DoTs be reduced significantly in either skill power, or
- # offense / defense scale
- # 50 skill power DoT * 5 stacks = more damage /tick than a finisher
- # endgame power of spells will hopefully be around the same as weapon attacks
- # but is likely to drop off slightly in post game
- class Game_Battler
- # original damage values
- #~ def make_damage_value(user, item)
- #~ value = item.damage.eval(user, self, $game_variables)
- #~ value *= item_element_rate(user, item)
- #~ #value *= pdr if item.physical?
- #~ #value *= mdr if item.magical?
- #~ check_force_remove_barrier(user, item)
- #~ value = 0 if barrier?
- #~ value *= rec if item.damage.recover?
- #~ value = apply_critical(value) if @result.critical
- #~ value = apply_variance(value, item.damage.variance)
- #~ value = apply_guard(value)
- #~ @result.make_damage(value.to_i, item)
- #~ end
- attr_accessor :backdash
- def null_blood_cost
- false
- end
- def force_action_counter(skill_id, target_index)
- #clear_actions
- action = Game_Action.new(self, true)
- action.set_skill(skill_id)
- if target_index == -2
- action.target_index = last_target_index
- elsif target_index == -1
- action.decide_random_target
- else
- action.target_index = target_index
- end
- @actions.unshift(action)
- end
- #~ def make_damage_value_old(user, item, splash_index = 0, stacks = 1, result = @result)
- #~ main_damage = item.damage
- #~ base_value = item.damage.evaluate(user, self, $game_variables, $game_switches, item, nil, nil, 0)
- #~ base_value = apply_all_damage_mods(base_value, user, item, main_damage, splash_index, stacks)
- #~ value = base_value.to_i
- #~ values = [[base_value.to_i, main_damage, result.critical]]
- #~ hits = 1
- #~ proc_damages = item.proc_damages.clone
- #~ proc_damages += user.proc_damages if item.physical? && !item.noproc
- #~ #p user.proc_damages
- #~ proc_damages.each { |ary|
- #~ skill = ary[0]
- #~ rate = ary[1]
- #~ dmg = skill.damage
- #~ v = dmg.evaluate(user, self, $game_variables, $game_switches, skill, main_damage, base_value, hits)
- #~ v *= rate
- #~ v = apply_all_damage_mods(v, user, item, dmg, splash_index, stacks)
- #~ crit = skill.damage.critical && @result.critical
- #~ v = v.to_i
- #~ next if v == 0
- #~ value += v
- #~ values.push([v, dmg, crit])
- #~ hits += 1
- #~ }
- #~ if item.feral_frenzy != :none
- #~ extra_hits = calc_feral_frenzy(user, item, self)
- #~ elsif item.barrage > 0
- #~ extra_hits = calc_barrage(user, item, self)
- #~ elsif item.repeats > 1
- #~ extra_hits = item.repeats - 1
- #~ elsif item.normal_attack?
- #~ extra_hits = calc_multihit(user, item, self)
- #~ extra_hits += 1 if user == soha && soha.battle_skill_learn?(740) && item.normal_attack?
- #~ extra_hits += user.hits.to_i if user.hits > 0
- #~ extra_hits += user.atk_times_add.to_i
- #~ end
- #~ if extra_hits
- #~ extra_hits.times { |i|
- #~ v = item.damage.evaluate(user, self, $game_variables, $game_switches, item, main_damage, base_value, 0)
- #~ #v *= 0.10 * 0.9 ** i if item.normal_attack?
- #~ # weak extra hits - 20% for the first extra hit, 90% of that hit for additional
- #~ #v *= 0.95 * 0.95 ** i unless item.normal_attack?
- #~ # strong extra hits hits - 95% for the first extra hit, 95% of that hit for additional
- #~ v = v.to_i
- #~ next if v == 0
- #~ value += v
- #~ crit = item.damage.critical && result.critical
- #~ values.push([v, item.damage, crit])
- #~ hits += 1
- #~ }
- #~ end
- #~ #check_force_remove_barrier(user, item)
- #~ ([[item, 100]] + proc_damages).each { |ary|
- #~ skill = ary[0]
- #~ rate = ary[1]
- #~ check_force_remove_barrier(user, skill)
- #~ no_damage = barrier? || state?(535) # last stand, barrier, invincibility
- #~ no_damage = true if state?(631)
- #~ value = 0 if no_damage
- #~ values = [[0, item.damage, false]] if no_damage
- #~ }
- #~ #p values.collect { |v| v[0] }
- #~ result.make_damage(value.to_i, item, user, self, values)
- #~ end
- def make_damage_value(user, item, splash_index = 0, stacks = 1, result = @result)
- make_damage_value_main(user, item, splash_index, stacks, result)
- end
- def make_damage_value_main(user, item, splash_index = 0, stacks = 1, result = @result)
- main_damage = item.damage
- unmod_value = item.damage.evaluate(user, self, $game_variables, $game_switches, item, nil, nil, 0)
- base_value = apply_all_damage_mods(unmod_value, user, item, main_damage, splash_index, stacks)
- value = base_value.to_i
- proc_damages = item.proc_damages.clone
- proc_damages += user.proc_damages if item.physical? && !item.noproc
- proc_damages.each { |ary|
- skill = ary[0]
- rate = ary[1]
- dmg = skill.damage
- v = dmg.evaluate(user, self, $game_variables, $game_switches, skill, main_damage, base_value, hits)
- v *= rate
- v = apply_all_damage_mods(v, user, item, dmg, splash_index, stacks)
- crit = skill.damage.critical && result.critical
- v = v.to_i
- value += v
- }
- ehits = user.element_hits
- ehits = [] unless item.physical?
- ehits.each_with_index { |ehit, i|
- next if ehit == 0
- rate = ehit
- ni = item.clone
- ni.damage = item.damage.clone
- ni.damage.element_id = i
- v = apply_all_damage_mods(unmod_value, user, ni, ni.damage, splash_index, stacks)
- v *= rate
- v = v.to_i
- value += v
- }
- no_damage = false
- ([[item, 100]] + proc_damages).each { |ary|
- skill = ary[0]
- rate = ary[1]
- check_force_remove_barrier(user, skill)
- no_damage = barrier? || state?(535) || state?(631) # last stand, barrier, invincibility
- }
- value = 0 if no_damage
- result.item = item
- result.user = user
- result.make_damage(value.to_i, item, user, self)
- end
- def target_multihit_expand(item, targets)
- result = []
- targets.each { |target|
- hits = target.make_extra_hits(self, item) #, splash_index = 0, stacks = 1, result = @result)
- hits.times { result.push(target) }
- }
- result
- end
- def make_extra_hits(user, item, splash_index = 0, stacks = 1, result = @result)
- extra_hits = 1
- if item.feral_frenzy != :none
- extra_hits += calc_feral_frenzy(user, item, self)
- elsif item.barrage > 0
- extra_hits += calc_barrage(user, item, self)
- elsif item.repeats > 1
- extra_hits += item.repeats - 1
- elsif item.normal_attack?
- extra_hits += calc_multihit(user, item, self)
- extra_hits += 1 if user == soha && soha.battle_skill_learn?(740) && item.normal_attack?
- extra_hits += user.hits.to_i if user.hits > 0
- extra_hits += user.atk_times_add.to_i
- end
- extra_hits
- end
- def calc_multihit(user, item, target)
- value = item.repeats - 1
- return value
- #return value unless item.normal_attack?
- dex = user.luk * item.dex_mod / 100
- loop do
- if dex > rand(200) + 50
- value += 1
- dex -= 200
- else
- break
- end
- end
- value
- end
- def proc_damages
- ary = []
- states.each { |obj|
- #p obj.proc_damages
- ary += obj.proc_damages unless obj.proc_damages.empty? # != :none
- }
- ary += [[$data_skills[188], 1.0]] if actor? && battle_skill_learn?(1135) # aura glaive
- #p ary
- ary
- end
- def calc_feral_frenzy(user, item, target)
- return 9
- hit = calced_hit(user, item)
- hits = 0
- loop do
- hit *= item.feral_frenzy
- miss = rand > hit
- break if miss
- hits += 1
- return 9 if hits > 9
- end
- hits
- end
- def calc_barrage(user, item, target)
- item.barrage + calc_multihit(user, item, target)
- end
- def apply_all_damage_mods(value, user, item, dmg, splash_index, stacks = 1)
- return value if item.no_damage_mod
- value *= stacks
- value *= item_element_rate(user, item)
- value *= item_element_boost(user, item)
- value *= rec if item.damage.recover?
- value *= pdr if item.physical? && value > 0
- #p ["magic damage rate #{mdr}, prior value #{value}"] if item.magical?
- value *= mdr if item.magical? && value > 0
- value *= dra if value > 0
- value *= user.pda if item.physical? && value > 0
- value += value * item.chi_power * user.friends_unit.tp / 10000
- value *= cull_mod(user, item)
- value *= stealth_rate(user, item) if user.state?(425) # stealth
- value *= consume_stacks_mod(user, item)
- value = apply_regal_presence(value, user, item) if opposite?(user)
- value = apply_divine_barrier_mod(value, user, item) if opposite?(user)
- value = apply_critical(value, user, item) if result.critical && dmg.critical # only if this hit allows splash
- #value *= 2 if @result.critical && dmg.critical && user.actor? && user.battle_skill_learn?(545) && item.target_data_default_symbol == :ranged_single && item.physical?
- value = apply_splash_rate(value, user.action.splash_power(splash_index)) unless splash_index == 0
- value = apply_variance(value, item.damage.variance) if item.allow_variance
- value = apply_guard(value) #if value > 0
- value
- end
- def consume_stacks_mod(user, item)
- return 1 unless item.consume_stacks
- state_id, rate = item.consume_stacks
- if state_id == 200 && user.is_a?(Game_Actor) && fire_mastery #opts[:user].battle_skill_learn?(350)
- state_id += 1
- elsif state_id == 205 && user.is_a?(Game_Actor) && ice_mastery #opts[:user].battle_skill_learn?(360)
- state_id += 1
- elsif state_id == 210 && user.is_a?(Game_Actor) && lightning_mastery # opts[:user].battle_skill_learn?(355)
- state_id += 1
- end
- rate /= 100.0
- state = find_state?(state_id)
- return 1 unless state
- return 1 unless state.id == state_id
- 1 + rate * state.stacks
- end
- def cull_mod(user, item)
- return 1 if item.cull == 0
- 1 + (item.cull * (1 - hp_rate) / 100)
- end
- def stealth_rate(user, item)
- item.stealth_mod
- end
- def item_element_boost(user, item)
- rate = 1.0
- if user.actor? && user.battle_skill_learn?(350) # fire mastery
- rate *= 1.5 if item.damage.element_id == 3 # fire
- elsif item.id == 151 && lucian.battle_skill_learn?(350)
- rate *= 1.5 # burn
- end
- if user.actor? && user.battle_skill_learn?(360) # ice mastery
- rate *= 1.25 if item.damage.element_id == 4 # ice
- end
- if user.actor? && user.battle_skill_learn?(355) # lit mastery
- rate *= 1.25 if item.damage.element_id == 5 # thunder
- end
- if user.actor? && user.battle_skill_learn?(540) # pyromaniac
- rate *= 1.33 if item.damage.element_id == 3
- end
- p "element attack rate at #{rate}" if ECHO_ELEMENT_ATTACK_RATE
- rate
- end
- def apply_divine_barrier_mod(value, user, item)
- return value unless state?(530)
- barrier_mod = 1 - (kesh.wis / (kesh.wis + 5000.0 / kesh.barrier_value))
- value * barrier_mod
- end
- def barrier_value
- 5.times { |i|
- return 100 + i * 20 if battle_skill_learn?(1040 + i) # divine barrier
- }
- return 100
- end
- def apply_critical(damage, user, item)
- mod = [(user.cdb + item.cdb - 2.0) * user.cdr * item.cdr, 2.0].max
- if item.target_data_default_symbol == :ranged_single && item.physical? && user == ingrid && user.battle_skill_learn?(545) # deadeye
- mod += 1.0
- end
- if user == eskandar && user.battle_skill_learn?(915) # acuity
- mod *= 1 / (1 - (user.int / (user.int + 500.0)))
- end
- mod *= item.cdr
- p "critical damage modifier #{mod}"
- damage * mod
- end
- def apply_regal_presence(damage, user, item)
- return damage unless soha.battle_skill_learn?(715) # regal presence
- damage *= 1.25 if user == soha && opposite?(soha) && self.enemy.tagged_with?('human')
- damage *= 0.75 if self == soha && user.opposite?(soha) && user.enemy.tagged_with?('human')
- damage
- end
- def item_element_rate(user, item)
- if item.damage.element_id < 0
- user.atk_elements.empty? ? 1.0 : elements_max_rate(user.atk_elements) #* user.element_attack(item.damage.element_id)
- else
- element_rate(item.damage.element_id) #* user.element_attack(item.damage.element_id)
- end
- end
- def apply_splash_rate(value, splash_rate)
- value = value * splash_rate / 100
- end
- def barrier?
- state?(185)
- end
- def check_force_remove_barrier(user, item)
- if item.remove_barrier || user.remove_barrier
- remove_state(185)
- end
- end
- def remove_barrier
- return false unless actor?
- lightfury_equipped?
- end
- def lightfury_equipped?
- equips.any? { |i| i && i.object && i.object.tagged_with?('remove barrier') }
- end
- def item_apply_old(user, item, splash_index = 0)
- #p "#{self} is getting used by #{item.name}"
- @result.clear
- @result.used = item_test(user, item)
- #@result.missed = false
- @result.missed = (@result.used && rand >= item_hit(user, item))
- @result.missed = true if state?(515) && item.target_data_default_symbol == :ranged_single && item.physical? # staff spin
- @result.evaded = (!@result.missed && rand < item_eva(user, item))
- check_backdash(user, item) if state?(440) && opposite?(user)
- @result.evaded = false unless opposite?(user)
- @result.evaded = true if @result.missed
- if @result.hit?
- grabby = state?(634)
- #p "#{self} is getting hit by #{item.name}"
- aspect_link = state?(630)
- unless item.damage.none?
- check_critical(user, item)
- make_damage_value(user, item, splash_index)
- check_damage_share(user, item) if actor?
- execute_damage(user)
- aether_battery_effect if self.actor? && $game_party.alive_members.include?(ingrid) && ingrid.battle_skill_learn?(555) && item.damage.element_id == 7
- apply_poison_coating(user, item) if user.actor? && user.battle_skill_learn?(925) #poison coating
- apply_deep_cuts(user, item) if user.actor? && user.battle_skill_learn?(905) # bleed/ deep cuts
- end
- item.effects.each {|effect| item_effect_apply(user, item, effect) }
- execute_ctb_damage(user, item)
- apply_ctb_gain(item)
- apply_stagger_damage(user, item)
- do_interrupt if item.interrupt
- apply_meditation_effect if item && (1080..1084).include?(item.id)
- apply_stack_consume(user, item)
- #p @result.hp_damage
- check_autostealth
- item_user_effect(user, item)
- user_hit_tp_gain(user, item)
- giovany_hit_check(user, item) if self.enemy?
- kormag_checks(user, item, aspect_link)
- soha_grab_release_check(user, item) if self.enemy?
- death_release_check(user, item) if self.actor? && grabby
- user.giovany_user_check(user, item) if user.enemy?
- #user.result.hits += 1
- #user.result.states_added += @result.added_states.size
- #user.result.success = true
- else
- user_miss_tp_gain(user, item)
- end
- user.tp_gain_buffer[:uses] += 1
- end
- def check_item_hit(user, item, splash_index = 0, result = @result)
- #result.clear unless $game_party.in_battle
- result.used = item_test_simple(user, item)
- result.damage_fake = true if dead? && !item.allow_dead?
- p result.damage_fake
- #@result.missed = false
- result.missed = (result.used && rand >= item_hit(user, item))
- result.missed = true if state?(515) && item.target_data_default_symbol == :ranged_single && item.physical? # staff spin
- result.evaded = (!result.missed && rand < item_eva(user, item))
- check_backdash(user, item) if state?(440) && opposite?(user)
- result.evaded = false unless opposite?(user)
- result.evaded = true if result.missed
- end
- def item_apply(user, item, splash_index = 0, result = nil)
- result ||= results.last
- clear_result unless $game_party.in_battle
- if result.used
- #p [@result.used, "herehere", results.size]
- add_result
- #self.results.push(Game_ActionResult.new(self))
- result = results.last
- #p [@result.used, "herehere", results.size]
- end
- check_item_hit(user, item, splash_index, result)
- if result.hit?
- grabby = state?(634)
- aspect_link = state?(630)
- unless item.damage.none?
- result.used_damage = true
- check_critical(user, item, result)
- make_damage_value(user, item, splash_index, 1, result)
- check_damage_share(user, item, result) if actor? unless result.damage_fake
- execute_damage(user, result) unless result.damage_fake
- aether_battery_effect if self == ingrid && battle_skill_learn?(555) && item.damage.element_id == 7
- apply_poison_coating(user, item) if user.actor? && user.battle_skill_learn?(925) #poison coating
- apply_deep_cuts(user, item) if user.actor? && user.battle_skill_learn?(905) # bleed/ deep cuts
- #p [user == soha, user.actor? ? user.battle_skill_learn?(750) : nil, item.element_id == 6 ]
- apply_forced_insight(user, item) if user == soha && user.battle_skill_learn?(750) && item.damage.element_id == 6 # psychic prowess
- end
- item.effects.each {|effect| item_effect_apply(user, item, effect) } unless result.damage_fake
- add_guaranteed_states(user, item) unless result.damage_fake
- execute_ctb_damage(user, item) unless result.damage_fake
- apply_ctb_gain(item) unless result.damage_fake
- apply_stagger_damage(user, item) unless result.damage_fake
- do_interrupt if item.interrupt unless result.damage_fake
- apply_meditation_effect(result) if item && (1080..1084).include?(item.id)
- apply_stack_consume(user, item) unless result.damage_fake
- check_autostealth unless result.damage_fake
- item_user_effect(user, item) unless result.damage_fake
- user_hit_tp_gain(user, item, result) unless result.damage_fake
- giovany_hit_check(user, item) if self.enemy? unless result.damage_fake
- kormag_checks(user, item, aspect_link) unless result.damage_fake
- soha_grab_release_check(user, item) if self.enemy? unless result.damage_fake
- death_release_check(user, item) if self.actor? && grabby unless result.damage_fake
- user.giovany_user_check(user, item) if user.enemy? unless result.damage_fake
- #p result.hp_damage
- else
- user_miss_tp_gain(user, item)
- end
- user.tp_gain_buffer[:uses] += 1
- end
- def add_guaranteed_states(user, item)
- if item.guaranteed_state > 0
- opts = {}
- opts[:user] = user
- add_state(item.guaranteed_state, opts)
- end
- end
- def check_backdash(user, item)
- blocked = friends_unit.at_position(position + 5)
- if position < 10 && !blocked
- self.backdash = true
- #self.position += 5
- @result.evaded = true
- remove_state(440)
- else
- remove_state(440)
- end
- end
- def do_interrupt
- if ctb_count >= 0
- self.ctb_count = -100
- action.clear
- self.popup("Interrupt!", WHITE)
- end
- end
- def item_test(user, item)
- return false if dead? && !item.allow_dead?
- return true if user.enemy? && user.call_for_help_test(item)
- return true if $game_party.in_battle
- return true if item.for_opponent?
- return true if item.damage.recover? && item.damage.to_hp? && hp < mhp
- return true if item.damage.recover? && item.damage.to_mp? && mp < mmp
- return true if item_has_any_valid_effects?(user, item)
- return false
- end
- def item_test_simple(user, item)
- return true if user.enemy? && user.call_for_help_test(item)
- return true if $game_party.in_battle
- return true if item.for_opponent?
- return true if item.damage.recover? && item.damage.to_hp? && hp < mhp
- return true if item.damage.recover? && item.damage.to_mp? && mp < mmp
- return true if item_has_any_valid_effects?(user, item)
- return false
- end
- def apply_stack_consume(user, item)
- return false unless item.consume_stacks
- state_id, rate = item.consume_stacks
- if state_id == 200 && user.is_a?(Game_Actor) && fire_mastery #opts[:user].battle_skill_learn?(350)
- state_id += 1
- elsif state_id == 205 && user.is_a?(Game_Actor) && ice_mastery #opts[:user].battle_skill_learn?(360)
- state_id += 1
- elsif state_id == 210 && user.is_a?(Game_Actor) && lightning_mastery # opts[:user].battle_skill_learn?(355)
- state_id += 1
- end
- remove_state(state_id) if state?(state_id)
- end
- def apply_ctb_gain(item)
- self.ctb_count += item.ctb_gain
- end
- def apply_poison_coating(user, item)
- return 0 unless item.is_a?(RPG::Skill)
- chance = 0.5
- chance = 0 unless opposite?(user)
- state_id = 190
- chance *= state_effect_rate(user, item, state_id) if opposite?(user) # poison
- opts = {}
- opts[:item] = item
- try_add_state(state_id, user, chance, opts)
- end
- def apply_deep_cuts(user, item)
- return 0 unless item.is_a?(RPG::Skill)
- return 0 unless result.critical
- return 0 unless opposite?(user)
- chance = 2.0
- state_id = 195 # bleed
- chance *= state_effect_rate(user, item, state_id) if opposite?(user) # poison
- opts = {}
- opts[:item] = item
- try_add_state(state_id, user, chance, opts)
- end
- def apply_forced_insight(user, item)
- #p "reached here"
- return 0 unless item.is_a?(RPG::Skill)
- return 0 unless opposite?(user)
- #p "but not here"
- chance = 1.0
- state_id = 405 # insight
- chance *= state_effect_rate(user, item, state_id) if opposite?(user) # poison
- opts = {}
- opts[:item] = item
- try_add_state(state_id, user, chance, opts)
- end
- def apply_meditation_effect(result)
- #p debuff_states
- state = debuff_states.sample
- #p state
- return if state.nil?
- if state.stacks > 1
- state.stacks -= 1
- result.removed_states.push(state.id)
- result.used = true
- else
- remove_state(state.id)
- result.used = true
- end
- end
- def execute_ctb_damage(user, item)
- if item.ctb_damage > 0 || item.ctb_gain > 0
- value = item.ctb_damage - item.ctb_gain
- apply_ctb_damage(item.ctb_damage * self.ctdr)
- end
- end
- def apply_ctb_damage(value)
- self.ctb_count -= value if action && !action.charging
- end
- def check_autostealth
- dmg_check = results.inject(0) { |m, o| m += o.hp_damage }
- if self == eskandar && alive? && battle_skill_learn?(930) # better part of valor
- add_state(425) if dmg_check > mhp / 3
- end
- end
- def check_critical(user, item, result = nil)
- result.critical = (rand < item_cri(user, item))
- end
- def aether_battery_effect
- # aether battery
- self.tp += 5
- self.ctb_count += 250 unless dead? || action_charging?
- end
- def user_miss_tp_gain(user, item)
- user.tp_gain_buffer[:misses] += 1
- end
- def user_hit_tp_gain(user, item, result)
- user.tp_gain_buffer[:kills] += result.added_states.include?(1) ? 1 : 0
- user.tp_gain_buffer[:kills] += 1 if $game_party.alive_members.include?(ingrid) && ingrid.skill_learn?($data_skills[530]) && dead? && enemy? && enemy.tagged_with?('automaton') # scavenge
- return if item.no_tp_gain
- user.tp_gain_buffer[:criticals] += 1 if result.critical
- # user.tp_gain_buffer[:hits] += 1 unless item.damage.none?
- # user.tp_gain_buffer[:hits] += item.damage.extra_damages.size - 1
- user.tp_gain_buffer[:hits] += 1 if result.hit? # all_hits.size
- # user.tp_gain_buffer[:hits] -= 1 if @result.critical # critical counts for all hits
- user.tp_gain_buffer[:states] += result.added_states.size
- if result.hp_damage >= 0 && !item.damage.recover?
- self.tp_gain_buffer[:damage] += 1 # charge tp for taking a hit
- self.tp_gain_buffer[:damage] += 2 if self == lucian && battle_skill_learn?(320) # battle hardened
- self.tp_gain_buffer[:damage] += 2 if item.magical? && actor? && $game_party.alive_members.include?(kesh) && kesh.battle_skill_learn?(1150)
- end
- self.tp_gain_buffer[:used] = true
- user.tp_gain_buffer[:used] = true
- end
- def tp_gain_buffer
- @tp_gain_buffer ||= Hash.new(0)
- end
- def clear_tp_buffer
- uses = tp_gain_buffer[:uses]
- used = tp_gain_buffer[:used]
- taken_damage = tp_gain_buffer[:damage]
- return unless used == true
- misses = tp_gain_buffer[:misses]
- hits = tp_gain_buffer[:hits]
- states = tp_gain_buffer[:states]
- kills = tp_gain_buffer[:kills]
- criticals = tp_gain_buffer[:criticals]
- tp_gained = 0 #if hits == 0
- tp_gained = 3 + tp_hit_bonus if hits == 1
- tp_gained = 5 + tp_hit_bonus * 2 if hits == 2
- tp_gained += 5 + tp_hit_bonus + (1 + tp_hit_bonus) * hits ** 0.66 if hits > 2
- #tp_gained += hits - 2 if hits > 0 * tp_extra_hit_rate
- #tp_gained += states ** 0.66 * 2 * tp_state_rate
- # remove state
- tp_gained += misses * tp_miss_rate
- tp_gained += kills ** 1 * 3 * tp_kill_rate
- tp_gained += criticals ** 0.66 * tp_crit_rate
- #tp_gained = 3 if tp_gained < 3 && self == kesh && skill_learn?($data_skills[1115]) # Chi Channeling
- tp_gained += 3 if self == kesh && skill_learn?($data_skills[1115]) if uses > 0 # Chi Channeling
- tp_gained *= tcr
- tp_gained += taken_damage
- p "#{name} hit #{hits} time(s)" if ECHO_HITS && $TEST
- p "#{name} charged #{tp_gained.ceil} TP" if ECHO_TP_CHARGE && $TEST
- self.tp += tp_gained.ceil
- tp_gain_buffer.clear
- end
- def tp_state_rate
- 1
- end
- def tp_miss_rate
- 0
- end
- def tp_kill_rate
- return 1 unless actor?
- skill_learn?($data_skills[935]) ? 2 : 1
- end
- def tp_hit_bonus
- 0
- end
- def tp_crit_rate
- return 3 unless actor?
- return 3 unless $game_party.battle_members.include?(lucian) && lucian.skill_learn?($data_skills[335])
- return 5
- end
- def item_user_effect(user, item)
- user.tp += (item.tp_gain * user.tcr).to_i
- if item.self_buff_id > 0
- opts = {}
- opts[:user] = user
- opts[:item] = item
- user.add_state(item.self_buff_id, opts)
- user.result.used = true
- user.result.success = true
- user.result.no_damage = true
- end
- if item.success_buff_id > 0 && self.result.added_states.size > 0
- result.added_states.size.times { user.add_state(item.success_buff_id) }
- user.result.used = true
- user.result.success = true
- user.result.no_damage = true
- end
- end
- def item_cri_old_version(user, item)
- return 0 unless item.damage.critical
- #return 50
- dex_mod = 1 / (1 - (user.luk / (user.luk + luk + 1000.0)))
- eagle_eye_mod = 1
- if user == eskandar && user.battle_skill_learn?(920) # eagle eye
- hit_mod = calced_hit(user, item)
- eagle_eye_mod = hit_mod + 0.1 if hit_mod > 0.9
- end
- thunder_mastery_bonus = 0.0
- if user.actor? && party.alive_members.include?(lucian)
- thunder_mastery_bonus = 0.2 if item.damage.element_id == 5 || (item.damage.element_id < 2 && state?(230)) # enchant lightning
- thunder_mastery_bonus = 0.2 if item.proc_damages.any? { |d| d[0].damage.element_id == 5 }
- end
- base = user.cri + self.hunters_mark + thunder_mastery_bonus
- base += 0.25 if user == soha && item.swordplay && soha.battle_skill_learn?(740) # swordplay mastery
- crit = base * dex_mod * eagle_eye_mod + item.cri
- p ["Critical Values #{user.cri} base, #{item.cri} item, #{self.hunters_mark} mark bonus, #{eagle_eye_mod} eagle eye mod #{thunder_mastery_bonus} thunder mastery bonus #{crit} TOTAL" ] if ECHO_CRIT && $TEST
- crit * (1 - cev)
- end
- def item_cri(user, item)
- return 0 unless item.damage.critical
- #return 50
- dex_diff = user.luk - self.luk
- if dex_diff >= 0
- cri_plus = dex_diff / (dex_diff + 200.0) / 2
- else
- cri_plus = dex_diff / (-dex_diff + 200.0) / 2
- end
- eagle_eye_mod = 0.0
- if user == eskandar && user.battle_skill_learn?(920) # eagle eye
- hit_mod = calced_hit(user, item) - 0.9
- eagle_eye_mod = hit_mod / (hit_mod + 1.0) / 3 if hit_mod > 0
- end
- thunder_mastery_bonus = 0.0
- if user.actor? && party.alive_members.include?(lucian)
- thunder_mastery_bonus = 0.2 if item.damage.element_id == 5 || (item.damage.element_id < 2 && state?(230)) # enchant lightning
- thunder_mastery_bonus = 0.2 if item.proc_damages.any? { |d| d[0].damage.element_id == 5 }
- end
- swordplay = 0
- swordplay += 0.25 if user == soha && item.swordplay && soha.battle_skill_learn?(740) # swordplay mastery
- base = item.cri + user.cri + self.hunters_mark + thunder_mastery_bonus + cri_plus + swordplay - cev
- #crit = base # * dex_mod * eagle_eye_mod + item.cri
- #p ["Critical Values #{user.cri} base, #{item.cri} item, #{self.hunters_mark} mark bonus, #{eagle_eye_mod} eagle eye mod #{thunder_mastery_bonus} thunder mastery bonus #{crit} TOTAL" ] if $TEST
- crit = [base, thunder_mastery_bonus, eagle_eye_mod, swordplay, item.cri, user.cri - cev].max
- crit = 0 if cev == 1.0
- aStr = "\n\n\nCritical values NEW formula
- User: #{user.name}
- Target #{name}
- #{item.cri.round(3)}(skill cri) + #{user.cri.round(3)}(user cri) + #{swordplay.round(3)}(swordplay bonus)
- + #{hunters_mark.round(3)}(hunters mark) + #{thunder_mastery_bonus.round(3)}(thundermastery)
- - #{cev.round(3)}(target critical evasion) + #{cri_plus.round(3)}(dex component)
- Calculated CRI value: #{base}
- Actual value (minimum value from skill/bonuses/immunity) #{crit}\n\n\n"
- print aStr if $TEST && ECHO_CRI
- crit #* (1 - cev)
- end
- def execute_damage(user, result = @result)
- on_damage(result.hp_damage) if result.hp_damage > 0
- tapped = state?(375) # blood tap
- result.hp_damage = result.hp_damage.to_i
- dmg = result.hp_damage
- if self == kesh && self.battle_skill_learn?(1140) # iron will
- dmg = self.hp - 1 if dmg >= hp && rand < hp_rate
- end
- #p [dmg, self.name]
- self.hp -= dmg
- #self.tp += 1 if dmg > 0 # charge tp from damage
- #self.tp += 4 if dmg > 0 && self == lucian && battle_skill_learn?(320)
- #self.mp -= @result.mp_damage
- check_overdrain(user, result.hp_drain)
- user.draining = true if user.actor?
- user.hp += result.hp_drain
- user.draining = false if user.actor?
- #user.mp += @result.mp_drain
- apply_soul_steal(user, tapped, result) if dead?
- end
- def apply_soul_steal(user, tapped, result = @result)
- return unless $game_party.alive_members.include?(soha) && soha.battle_skill_learn?(730)
- if (result.hp_drain > 0 && user == soha) || tapped
- #soha.result.added_states.push(420)
- soha.result.used = true
- soha.add_state(420) # empowered
- end
- end
- def check_overdrain(user, drain)
- beacon = user.actor? && user.battle_skill_learn?(710) # Life Beacon
- #p "draining #{drain}" if beacon
- if beacon && drain + user.hp > user.mhp + user.overhp_max
- overdrain = drain + user.hp - (user.mhp + user.overhp_max)
- overdrain = user.mhp * 2 if overdrain > user.mhp * 2
- unit = user.friends_unit.alive_members.reject { |m| m == user }
- unit.each { |m|
- amount = overdrain / unit.size
- #p "overdrain #{amount} for #{m.name}"
- m.hp += amount
- m.result.hp_damage -= amount
- m.result.used_damage = true
- }
- result.hp_drain -= 0 #overdrain
- end
- end
- def check_damage_share(user, item, result)
- link = find_state?(415) # blood link
- disperse = find_state?(520) # disperse damage
- if disperse
- damage = result.hp_damage
- damage = damage * disperse.sv / 100
- shared_damage = 0
- share_members = adjacent_alive_members
- share_members.each { |m|
- mresult = Game_ActionResult.new(m)
- m.results.push(mresult)
- mresult.hp_damage += damage
- shared_damage += damage
- mresult.used_damage = true
- m.execute_damage(user, mresult)
- }
- result.hp_damage -= shared_damage
- elsif link
- damage = result.hp_damage
- damage = damage * link.sv / 100
- #@result.all_hits.each { |d| d[0] = d[0] * link.sv / 100}
- share_members = $game_party.battle_members.select { |m| m.state?(415) }
- shared_damage = 0
- share_members.each { |m|
- next if m == self
- mresult = Game_ActionResult.new(m)
- m.results.push(mresult)
- #p [m.name, damage]
- mresult.hp_damage = damage / share_members.size
- shared_damage += damage / share_members.size
- mresult.used_damage = true
- m.execute_damage(user, mresult) #unless m == self
- }
- #lhit = @result.all_hits.last
- #lhit[0] = damage - shared_damage if lhit && lhit[0] == @result.hp_damage
- result.hp_damage = damage - shared_damage
- end
- end
- def adjacent_alive_members
- friends_unit.alive_members.select { |m|
- row_diff = (m.row - self.row).abs
- col_diff = (m.column - self.column).abs
- row_diff <= 1 && col_diff <= 1 && row_diff + col_diff <= 1
- }
- end
- def intercept_damage_rate
- intercept = find_state?(271)
- if intercept && self == lucian
- equipped_skills.max_by { |s| s.intercept_rate }.intercept_rate
- else
- 1.0
- end
- end
- end
- class Game_ActionResult
- attr_accessor :stagger_damage
- attr_accessor :states_added, :hits
- attr_accessor :all_hits
- attr_accessor :no_damage
- attr_accessor :used_damage
- attr_accessor :damage_fake
- attr_accessor :user
- attr_accessor :item
- attr_accessor :dot # damage over time
- def make_damage_old(value, item, user, target, all_hits = nil)
- @critical = false if value == 0
- @hp_damage = value if item.damage.to_hp?
- all_hits.each { |hit|
- value = hit[0]
- dmg = hit[1]
- @hp_drain += value if dmg.drain?
- }
- @all_hits = all_hits.clone
- @hp_drain = @hp_damage if item.damage.drain?
- #@mp_drain = @mp_damage if item.damage.drain?
- @hp_drain *= user.drain_ratio # drain ratio of user
- @hp_drain *= item.drain_ratio # drain ratio of skill
- @hp_drain += @hp_damage * 15 / 100 if item.physical? && user.special_flag(5)
- @hp_drain = [@battler.hp, @hp_drain].min.to_i # cap at target's HP
- @success = true if item.damage.to_hp? # || @mp_damage != 0
- #p [@hp_damage, @hp_drain]
- end
- def make_damage(value, item, user, target, all_hits = nil)
- @critical = false if value == 0
- @hp_damage = value if item.damage.to_hp?
- @all_hits = all_hits.clone if all_hits
- @hp_drain = @hp_damage if item.damage.drain?
- @hp_drain *= user.drain_ratio # drain ratio of user
- @hp_drain *= item.drain_ratio # drain ratio of skill
- @hp_drain += @hp_damage * 15 / 100 if item.physical? && user.special_flag(5)
- @hp_drain = [@battler.hp, @hp_drain].min.to_i # cap at target's HP
- #p @hp_drain
- @success = true if item.damage.to_hp?
- end
- def clear_hit_flags
- @used = false
- @missed = false
- @evaded = false
- @critical = false
- @success = false
- @no_damage = false
- @used_damage = false
- @damage_fake = false
- @user = nil
- @target = nil
- @dot = false
- end
- def clear_damage_values
- @all_hits = []
- @hp_damage = 0
- @mp_damage = 0
- @tp_damage = 0
- @hp_drain = 0
- @mp_drain = 0
- @hits = 0
- @states_added = 0
- @stagger_damage = 0
- end
- def added_state_stacks
- h = Hash.new(0)
- @added_states.each {|id| h[$data_states[id]] += 1 }
- h
- end
- alias clear_b4_multiresult clear
- def clear
- clear_b4_multiresult
- #@battler.results.clear
- #@battler.results.push(@battler.result_orig)
- end
- end
- class Game_ActionResultMerged < Game_ActionResult
- NUMBERS_METHODS = ['hp_damage']
- def hp_damage
- @battler.results.inject(0) { |m, o| m += o.hp_damage }
- end
- def evaded
- @battler.results.all? { |r| r.evaded }
- end
- def clear
- super
- #@battler.result_orig.clear
- #@battler.results.clear
- end
- end
- class RPG::BaseItem
- def normal_multihit?
- false
- end
- def intercept_rate
- @intercept_rate ||= note =~ /<intercept (\d+)>/i ? $1.to_i / 100.0 : 1.0
- end
- def self_buff_id
- @self_buff_id ||= note =~ /<self buff (\d+)>/i ? $1.to_i : 0
- end
- def success_buff_id
- @success_buff_id ||= note =~ /<success self buff (\d+)>/i ? $1.to_i : 0
- end
- def no_tp_gain
- tagged_with?('no tp gain')
- end
- def charge_time_text
- return "Instant" if ready_cost <= 10
- ready_cost
- end
- def proc_damages_note
- @proc_damages_note ||= note_parse_proc_damages
- end
- def proc_damages
- proc_damages_note
- end
- def note_parse_proc_damages
- ary = []
- note.each_line { |line|
- if line =~ /<proc damage (\d+) (\d+)>/
- skill_id = $1.to_i
- rate = $2.to_i / 100.0
- skill = $data_skills[skill_id]
- ary.push([skill, rate])
- end
- }
- ary
- end
- def chi_power
- @chi_power ||= note =~ /<chi power (\d+)>/i ? $1.to_i : 0
- end
- def consume_stacks
- @consume_stacks ||= note =~ /<consume (\d+) (\d+)/i ? [$1.to_i, $2.to_i] : nil
- end
- def guaranteed_state
- @guaranteed_state ||= note =~ /<guaranteed state (\d+)>/i ? $1.to_i : 0
- end
- def damage_color
- @damage_color ||= note =~ /<damage color (.+)>/i ? Color.html($1) : :none
- end
- def dot_color
- @dot_color ||= note =~ /<dot color (.+)>/i ? Color.html($1) : :none
- end
- def dot_sound
- @dot_sound ||= note =~ /<dot sound (.+)>/i ? $1.to_s : :none
- end
- def weapon_power_mod
- @weapon_power_mod ||= note =~ /<weapon power mod (\d+)>/i ? $1.to_i : 100
- end
- def skill_power_mod
- @skill_power_mod ||= note =~ /<skill power mod (\d+)>/i ? $1.to_i : 100
- end
- def stealth_mod
- @stealth_mod ||= note =~ /<stealth mod (\d+)>/i ? $1.to_i / 100.0 : 1.0
- end
- def spell_power_mod
- @spell_power_mod ||= note =~ /<spell power mod (\d+)>/i ? $1.to_i : 100
- end
- def str_scale_mod
- @str_scale_mod ||= note =~ /<str scale mod (\d+)>/i ? $1.to_i : 100
- end
- def int_scale_mod
- @int_scale_mod ||= note =~ /<int scale mod (\d+)>/i ? $1.to_i : 100
- end
- def dex_mod
- @dex_mod ||= note =~ /<dex scale mod (\d+)>/i ? $1.to_i : 100
- end
- def final_reckoning
- @final_reckoning ||= note =~ /<final reckoning (\d+)>/i ? $1.to_i : 0
- end
- def cull
- @cull ||= note =~ /<cull (\d+)>/i ? $1.to_i : 0
- end
- def normal_attack?
- false
- end
- def null_blood_cost
- tagged_with?('null blood cost')
- end
- def feral_frenzy
- @feral_frenzy ||= note =~ /<feral frenzy (\d+)%>/i ? $1.to_i / 100.0 : :none
- end
- def barrage
- @barrage ||= note =~ /<barrage (\d+)>/i ? $1.to_i : 0
- end
- def drain_ratio
- @drain_ratio ||= note =~ /<drain ratio (\d+)%?>/i ? $1.to_i / 100.0 : 1.0
- end
- def physical_weight
- @physical_weight ||= note =~ /<physical weight (\d+)>/i ? $1.to_i : 1
- end
- def magical_weight
- @magical_weight ||= note =~ /<magical weight (\d+)>/i ? $1.to_i : 1
- end
- def noproc
- tagged_with?('noproc')
- end
- def remove_on_ready
- tagged_with?('remove on ready')
- end
- def no_damage_mod
- tagged_with?('no damage mod')
- end
- def allow_dead?
- !target_data.target_restrictions.include?(:alive)
- end
- def base_damage
- @base_damage ||= note =~ /<base damage (\d+)>/i ? $1.to_i : 100
- end
- def offense_scale
- @offense_scale ||= note =~ /<offense scale (\d+)>/i ? $1.to_i / 100.0 : 1.0
- end
- def defense_scale
- @defense_scale ||= note =~ /<defense scale (\d+)>/i ? $1.to_i / 100.0: 0.5
- end
- def no_cover
- tagged_with?('no cover')
- end
- def interrupt
- tagged_with?('interrupt')
- end
- end
- class RPG::Skill
- def normal_attack?
- @id == 1 || @id == 5
- end
- def normal_multihit?
- repeats > 1 && animate_type != :coup_de_grace
- end
- end
- class RPG::UsableItem::Damage
- include DamageFormula
- # a - attacker
- # b - defender
- # v - variables
- # s - switches
- # i - item (skill used)
- # md - main_damage (damage field of main skill used)
- # bv - base_value (damage main skill has already inflicted)
- # h = hits (hits so far)
- def evaluate(a, b, v, s = nil, i = nil, md = nil, bv = 0, h)
- # setting up main values
- @user = a
- @target = b
- @variables = v
- @switches = s
- @item = i
- @main_damage = md
- @base_value = bv
- #@blood_mod = @item.blood_mod
- @wp_mod = @item.weapon_power_mod
- @sp_mod = @item.skill_power_mod
- #p [@item.name, @item.note, @item.skill_power_mod, @sp_mod, "sp mod here"]
- @armor_rate = (1 - @user.armor_pierce / 100.0) * (1 - @item.armor_pierce / 100.0)
- # inverse of armor pierce is armor rate, the rate of which enemy armor is effective
- value = formula_eval(a, b, v)
- clear
- value
- end
- remove_method(:eval)
- def formula_eval(a, b, v)
- begin
- v = [eval(@formula, binding), 0].max * sign #rescue 0
- rescue => err
- p "problem with damage formula: #{err}"
- return 0
- end
- v
- end
- def clear
- @user = @target = @variables = @switches = @item = @main_damage = @base_value =
- @blood_mod = @wp_mod = @armor_rate = nil
- end
- def str_mod_softcap(str_mod) # deprecated
- if str_mod > STR_MOD_SOFTCAP
- mod_extra = str_mod - STR_MOD_SOFTCAP
- mod_base = STR_MOD_SOFTCAP
- mod_extra *= STR_MOD_OVERCAP_MOD
- mod_extra + mod_base
- else
- str_mod
- end
- end
- def shotgun_distance_mod(user, target)
- dist = (user.row - target.row).abs + (user.column - target.column).abs
- if dist < 4
- 1 + 0.25 * (4 - dist)
- else
- 1.0
- end
- end
- #~ def attack_damage
- #~ wp = @user.weapon_power * @wp_mod / 100
- #~ armor = @target.armor * @armor_rate
- #~ vit = @target.def
- #~ str = @user.atk * @item.str_scale_mod / 100 # unused for ingrid
- #~ str_mod = 1 / (1 - (str / (str + ATTACK_DAMAGE_STR_FOCUS)))
- #~ str_mod = str_mod_softcap(str_mod)
- #~ vit_mod = 1 - (vit / (vit + ATTACK_DAMAGE_VIT_FOCUS))
- #~ #str_ratio = 0
- #~ #vit_ratio = vit / vit + 100
- #~ vit = 0 if @user == soha && @target.state?(405)
- #~ armor = 0 if @user == soha && @target.state?(405)
- #~ armor = 0 if @item && @item.damage.element_id == 7
- #~ damage = wp * 4 - armor
- #~ damage += str / 2
- #~ damage -= vit / 4 unless @item && @item.damage.element_id == 7
- #~ base = damage
- #~ #p [wp, armor, damage]
- #~ damage = damage * str_mod * vit_mod
- #~ damage = damage * @sp_mod / 100
- #~ damage *= @user.intercept_damage_rate if @user.state?(271)
- #~ p ["attack damage", "#{base} base", "#{str_mod.round(2)} attacking stat mod", "#{vit_mod.round(2)} defending mod", "#{@sp_mod / 100.0} skill power mod", "#{damage} total damage"] if ECHO_DAMAGE
- #~ damage.to_i
- #~ end
- #~
- #~ def aura_glaive
- #~ wp = @user.weapon_power * @wp_mod / 100
- #~ armor = @target.armor * @armor_rate
- #~ vit = @target.def
- #~ str = @user.mdf # * @item.str_scale_mod / 100 # unused for ingrid
- #~ str_mod = 1 / (1 - (str / (str + 500.0)))
- #~ #vit_mod = 1 - (vit / (vit + 500.0))
- #~ #str_ratio = 0
- #~ #vit_ratio = vit / vit + 100
- #~ #vit = 0 if @user == soha && @target.state?(405)
- #~ #armor = 0 if @user == soha && @target.state?(405)
- #~ damage = wp #* 4 - armor
- #~ damage += str / 10
- #~ #damage -= vit / 4
- #~ #p [wp, armor, damage]
- #~ damage = damage * str_mod #* vit_mod
- #~ damage = damage * @sp_mod / 100
- #~ #damage *= @user.intercept_damage_rate if @user.state?(271)
- #~ damage.to_i
- #~ end
- #~
- #~ def gun_damage
- #~ wp = @user.weapon_power * @wp_mod / 100
- #~ wp *= shotgun_distance_mod(@user, @target) if @user.actor? && @user.battle_skill_learn?(520)
- #~ armor = @target.armor * @armor_rate
- #~ vit = @target.def
- #~ str = @user.weapon_power # unused for ingrid
- #~ str_mod = 1 / (1 - (str / (str + 500.0)))
- #~ level = @user.level
- #~ #str_mod = 1 / (1 - (level / (level + 30.0)))
- #~ #(level + 30) / 30.0 # for Ingrid
- #~ vit_mod = 1 - (vit / (vit + 500.0))
- #~ #str_ratio = 0
- #~ #vit_ratio = vit / vit + 100
- #~ armor = 0 if @item && @item.damage.element_id == 7
- #~ base = damage = wp * 4 - armor
- #~ damage = damage * str_mod * vit_mod
- #~ damage = damage * @sp_mod / 100.0
- #~ p ["gun", base, damage, str_mod, vit_mod, @sp_mod] if ECHO_DAMAGE
- #~ damage.to_i
- #~ end
- #~
- #~ def xbow_damage
- #~ wp = @user.weapon_power * @wp_mod / 100
- #~ armor = @target.armor * @armor_rate
- #~ vit = @target.def
- #~ str = @user.luk # dex replaced for xbow
- #~ #level = @user.level
- #~ str_mod = 1 / (1 - (str / (str + 400.0)))
- #~ str_mod = str_mod_softcap(str_mod)
- #~ #(level + 30) / 30.0 # for Ingrid
- #~ vit_mod = 1 - (vit / (vit + 500.0))
- #~ #str_ratio = 0
- #~ #vit_ratio = vit / vit + 100
- #~ armor = 0 if @item && @item.damage.element_id == 7
- #~ damage = wp * 4 - armor * 2
- #~ damage = damage * str_mod * vit_mod
- #~ if @user == eskandar && @user.battle_skill_learn?(920) # Eagle Eye
- #~ hit_rate = @target.calced_hit(@user, @item)
- #~ p "#{hit_rate} eagle eye damage rate (if higher than 1.0)"
- #~ damage *= hit_rate if hit_rate > 1.0
- #~ end
- #~ p "xbow skill #{damage} damage, #{str_mod} str mod #{vit_mod} vit mod" if ECHO_DAMAGE
- #~ damage = damage * @sp_mod / 100.0
- #~ damage.to_i
- #~ end
- #~
- #~
- #~ def spell_damage
- #~ int = @user.mat
- #~ wis = @target.mdf
- #~ wis = 0 if @user == soha && @target.state?(405)
- #~ level = @user.level
- #~ sub_portion = @item.defense_scale * wis
- #~ sub_portion = 0 if @item && @item.damage.element_id == 7
- #~ base = @item.base_damage + int * @item.offense_scale - sub_portion
- #~ base += @user.mdf if @user.state?(525) # Aura Guide
- #~ base = @item.base_damage / 2 if base < @item.base_damage / 2
- #~ int_mod1 = 1 / (1 - (int / (int + 500.0)))
- #~ wis_mod1 = 1 - (wis / (wis + 500.0))
- #~ damage = base * int_mod1 * wis_mod1 # * wis_mod2
- #~ damage += damage * @item.blood_power / 100
- #~ damage = damage * @sp_mod / 100
- #~ damage *= 2 if @user.actor? && @user.battle_skill_learn?(370) # spellblade
- #~ p ["spell damage", "#{base} base", "#{int_mod1.round(2)} attacking stat mod", "#{wis_mod1.round(2)} defending mod", "#{@sp_mod / 100.0} skill power mod", "#{damage} total damage"] if ECHO_DAMAGE
- #~ damage.to_i
- #~ end
- #~
- #~ def blood_damage
- #~ int = @user.atk
- #~ wis = @target.def
- #~ wis = 0 if @user == soha && @target.state?(405)
- #~ base = @item.base_damage + int * @item.offense_scale - @item.defense_scale * wis
- #~ base = @item.base_damage / 2 if base < @item.base_damage / 2
- #~ int_mod1 = 1 / (1 - (int / (int + 500.0)))
- #~ wis_mod1 = 1 - (wis / (wis + 500.0))
- #~ damage = base * int_mod1 * wis_mod1
- #~ damage += damage * @item.blood_power / 100
- #~ damage = damage * @sp_mod / 100
- #~ p ["Blood damage", "#{base} base", "#{int_mod1.round(2)} attacking stat mod", "#{wis_mod1.round(2)} defending mod", "#{@sp_mod / 100.0} skill power mod", "#{damage} total damage"] if ECHO_DAMAGE
- #~ damage.to_i
- #~ end
- #~
- #~ def heal_normal
- #~ wis = @user.mdf
- #~ level = @user.level
- #~ base = @item.base_damage + wis * @item.offense_scale
- #~ #base += @user.mdf if @user.state?(525) # Aura Guide
- #~ #base = @item.base_damage / 2 if base < @item.base_damage / 2
- #~ wis_mod1 = 1 / (1 - (wis / (wis + HEAL_NORMAL_WIS_FOCUS)))
- #~ damage = base * wis_mod1
- #~ damage += damage * @item.blood_power / 100
- #~ damage = damage * @sp_mod / 100
- #~ p ["heal normal", "#{base} base", "#{wis_mod1.round(2)} stat mod", "#{@sp_mod / 100.0} skill power mod", "#{damage} total heal"] if ECHO_DAMAGE
- #~ damage.to_i
- #~ end
- #~
- #~ def blood_heal_direct
- #~ base = @user.mhp * @item.blood_power / 200.0
- #~ wis = @user.mat
- #~ wis_mod = 1 / (1 - (wis / (wis + 500.0)))
- #~ damage = base * wis_mod
- #~ damage = damage * @sp_mod / 100
- #~ p ["blood heal", base, wis_mod, damage] if ECHO_DAMAGE
- #~ damage.to_i
- #~ end
- def mixed_damage
- (attack_damage * @item.physical_weight + spell_damage * @item.magical_weight) / (@item.magical_weight + @item.physical_weight)
- end
- def dot_damage_magical
- int = @user.mat
- wis = @target.mdf
- wis = 0 if @user == soha && @target.state?(405)
- base = @item.base_damage + int * @item.offense_scale - @item.defense_scale * wis
- base = @item.base_damage / 2 if base < @item.base_damage / 2
- int_mod1 = 1 / (1 - (int / (int + 500.0)))
- wis_mod1 = 1 - (wis / (wis + 500.0))
- damage = base * int_mod1 * wis_mod1
- damage += damage * @item.blood_power / 100
- damage = damage * @sp_mod / 100
- p ["Magical DoT", "#{base} base", "#{int_mod1.round(2)} attacking stat mod", "#{wis_mod1.round(2)} defending mod", "#{@sp_mod / 100.0} skill power mod", "#{damage} total damage"] if ECHO_DAMAGE
- damage.to_i
- end
- def dot_damage_physical
- int = @user.mat
- wis = @target.def
- base = @item.base_damage + int * @item.offense_scale - @item.defense_scale * wis
- base = @item.base_damage / 2 if base < @item.base_damage / 2
- int_mod1 = 1 / (1 - (int / (int + 500.0)))
- wis_mod1 = 1 - (wis / (wis + 500.0))
- damage = base * int_mod1 * wis_mod1
- damage += damage * @item.blood_power / 100
- damage = damage * @sp_mod / 100
- p ["Physical DoT", "#{base} base", "#{int_mod1.round(2)} attacking stat mod", "#{wis_mod1.round(2)} defending mod", "#{@sp_mod / 100.0} skill power mod", "#{damage} total damage"] if ECHO_DAMAGE
- damage.to_i
- end
- def dot_damage_blood_tap
- int = @user.atk
- wis = @target.def
- wis = 0 if @user == soha && @target.state?(405)
- base = @item.base_damage + int * @item.offense_scale - @item.defense_scale * wis
- base = @item.base_damage / 2 if base < @item.base_damage / 2
- int_mod1 = 1 / (1 - (int / (int + 500.0)))
- wis_mod1 = 1 - (wis / (wis + 500.0))
- damage = base * int_mod1 * wis_mod1
- damage += damage * @item.blood_power / 100
- damage = damage * @sp_mod / 100
- p ["Blood tap DoT", "#{base} base", "#{int_mod1.round(2)} attacking stat mod", "#{wis_mod1.round(2)} defending mod", "#{@sp_mod / 100.0} skill power mod", "#{damage} total damage"] if ECHO_DAMAGE
- damage.to_i
- end
- def final_reckoning_damage
- return @target.hp * @item.final_reckoning / 100 unless @target.opposite?(@user)
- rc = @user.friends_unit.alive_members.inject(0) { |m, o| m += o.hp * @item.final_reckoning / 100 }
- int = @user.mat
- base = Math.sqrt(int) / (1 - (int / (int + 10000.0)))
- fr_mod = ((rc + 1000) ** 0.33) * Math.log(rc + 5) - 50
- int = @user.mat
- int_mod = 1 / (1 - (int / (int + 2000.0)))
- # very weak int scaling
- damage = base * int_mod * fr_mod - 1000
- damage = rc / 3 if damage < rc / 3
- damage = damage * @sp_mod / 100
- damage.to_i
- end
- def derivative_damage
- base = base_value
- damage = base * @sp_mod / 100
- damage.to_i
- end
- def calc_stat_damage_mod(name, astat, dstat = 0) #, abase = nil, dbase = nil)
- offense_focus = OFFENSE_STAT_FOCUS[name]
- defense_focus = DEFENSE_STAT_FOCUS[name]
- offense_cap = OFFENSE_MOD_SOFTCAP[name]
- defense_cap = DEFENSE_MOD_SOFTCAP[name]
- offense_cap_ratio = OFFENSE_MOD_OVERCAP_RATIO[name]
- defense_cap_ratio = DEFENSE_MOD_OVERCAP_RATIO[name]
- #astat = aparam ? @user.send(aparam) : 1.0
- #dstat = dparam ? @target.send(dparam) : 0
- dstat = 0 if @user == soha && @target.state?(405)
- #base = abase ? @user.send(abase) : @item.base_damage
- #base -= dbase ? @user.send(dbase) : 0
- #base += astat * @item.offense_scale - dstat * @item.defense_scale
- omod = 1 / (1 - (astat / (astat + offense_focus.to_f)))
- dmod = 1 - (dstat / (dstat + defense_focus.to_f))
- omod2 = apply_mod_softcap(omod, offense_cap, offense_cap_ratio)
- dmod2 = apply_mod_softcap(dmod, defense_cap, defense_cap_ratio)
- mod = omod2 * dmod2
- if ECHO_DAMAGE_LONG
- print "
- Damage mods applied for #{name}:
- Offensive: base mod - #{omod.round(2)} / after softcap - #{omod2.round(2)}
- Defensive: base mod - #{dmod.round(2)} / after softcap - #{dmod2.round(2)}
- total modifier applied to skill #{mod.round(4)}
- "
- end
- mod
- end
- def apply_mod_softcap(value, softcap, ratio)
- if value > softcap
- mod_extra = value - softcap
- mod_base = softcap
- mod_extra *= ratio
- mod_extra + mod_base
- else
- value
- end
- end
- def attack_damage
- wp = @user.weapon_power * @wp_mod / 100
- armor = @target.armor * @armor_rate
- armor = 0 if @user == soha && @target.state?(405)
- armor = 0 if @item && @item.damage.element_id == 7
- aparam = @user.atk * @item.str_scale_mod / 100
- dparam = @target.def
- mod = calc_stat_damage_mod(:attack_damage, aparam, dparam)
- dparam = 0 if @user == soha && @target.state?(405)
- damage = wp * 4 - armor
- damage += aparam / 2
- damage -= dparam / 4 unless @item && @item.damage.element_id == 7
- base = damage
- damage = damage * mod
- damage = damage * @sp_mod / 100
- damage *= @user.intercept_damage_rate if @user.state?(271)
- #p ["attack damage", "#{base} base", "#{str_mod.round(2)} attacking stat mod", "#{vit_mod.round(2)} defending mod", "#{@sp_mod / 100.0} skill power mod", "#{damage} total damage"] if ECHO_DAMAGE
- damage.to_i
- end
- def aura_glaive
- wp = @user.weapon_power * @wp_mod / 100
- armor = @target.armor * @armor_rate
- str = @user.mdf
- mod = calc_stat_damage_mod(:aura_glaive, str, 0)
- damage = wp
- damage += str / 10
- damage = damage * mod
- damage = damage * @sp_mod / 100
- #damage *= @user.intercept_damage_rate if @user.state?(271)
- damage.to_i
- end
- def gun_damage
- wp = @user.weapon_power * @wp_mod / 100
- wp *= shotgun_distance_mod(@user, @target) if @user.actor? && @user.battle_skill_learn?(520)
- armor = @target.armor * @armor_rate
- armor = 0 if @item && @item.damage.element_id == 7
- vit = @target.def
- str = @user.weapon_power # unused for ingrid
- mod = calc_stat_damage_mod(:gun_damage, str, vit)
- base = damage = wp * 4 - armor
- damage = damage * mod
- damage = damage * @sp_mod / 100.0
- #p ["gun", base, damage, str_mod, vit_mod, @sp_mod] if ECHO_DAMAGE
- damage.to_i
- end
- def xbow_damage
- wp = @user.weapon_power * @wp_mod / 100
- armor = @target.armor * @armor_rate
- vit = @target.def
- str = @user.luk # dex replaced for xbow
- mod = calc_stat_damage_mod(:xbow_damage, str, vit)
- armor = 0 if @item && @item.damage.element_id == 7
- damage = wp * 4 - armor * 2
- damage = damage * mod
- if @user == eskandar && @user.battle_skill_learn?(920) # Eagle Eye
- hit_rate = @target.calced_hit(@user, @item)
- p "#{hit_rate} eagle eye damage rate (if higher than 1.0)"
- damage *= hit_rate if hit_rate > 1.0
- end
- #p "xbow skill #{damage} damage, #{str_mod} str mod #{vit_mod} vit mod" if ECHO_DAMAGE
- damage = damage * @sp_mod / 100.0
- damage.to_i
- end
- def spell_damage
- int = @user.mat
- wis = @target.mdf
- wis = 0 if @user == soha && @target.state?(405)
- level = @user.level
- sub_portion = @item.defense_scale * wis
- sub_portion = 0 if @item && @item.damage.element_id == 7
- base = @item.base_damage + int * @item.offense_scale - sub_portion
- base += @user.mdf if @user.state?(525) # Aura Guide
- base = @item.base_damage / 2 if base < @item.base_damage / 2
- mod = calc_stat_damage_mod(:spell_damage, int, wis)
- damage = base * mod
- damage += damage * @item.blood_power / 100
- damage = damage * @sp_mod / 100
- damage *= 2 if @user.actor? && @user.battle_skill_learn?(370) # spellblade
- #p ["spell damage", "#{base} base", "#{int_mod1.round(2)} attacking stat mod", "#{wis_mod1.round(2)} defending mod", "#{@sp_mod / 100.0} skill power mod", "#{damage} total damage"] if ECHO_DAMAGE
- damage.to_i
- end
- def blood_damage
- int = @user.atk
- wis = @target.def
- wis = 0 if @user == soha && @target.state?(405)
- base = @item.base_damage + int * @item.offense_scale - @item.defense_scale * wis
- base = @item.base_damage / 2 if base < @item.base_damage / 2
- mod = calc_stat_damage_mod(:blood_damage, int, wis)
- damage = base * mod
- damage += damage * @item.blood_power / 100
- damage = damage * @sp_mod / 100
- #p ["Blood damage", "#{base} base", "#{int_mod1.round(2)} attacking stat mod", "#{wis_mod1.round(2)} defending mod", "#{@sp_mod / 100.0} skill power mod", "#{damage} total damage"] if ECHO_DAMAGE
- damage.to_i
- end
- def heal_normal
- wis = @user.mdf
- level = @user.level
- base = @item.base_damage + wis * @item.offense_scale
- mod = calc_stat_damage_mod(:blood_damage, wis, 0)
- damage = base * mod
- damage += damage * @item.blood_power / 100
- damage = damage * @sp_mod / 100
- #p ["heal normal", "#{base} base", "#{wis_mod1.round(2)} stat mod", "#{@sp_mod / 100.0} skill power mod", "#{damage} total heal"] if ECHO_DAMAGE
- damage.to_i
- end
- def blood_heal_direct
- base = @user.mhp * @item.blood_power / 200.0
- wis = @user.mat
- mod = calc_stat_damage_mod(:blood_damage, wis, 0)
- damage = base * mod
- damage = damage * @sp_mod / 100
- #p ["blood heal", base, wis_mod, damage] if ECHO_DAMAGE
- damage.to_i
- end
- end
- class Game_Enemy
- def null_blood_cost
- enemy.null_blood_cost
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement