Class: Battle::Logic::DamageHandler

Inherits:
ChangeHandlerBase show all
Includes:
Hooks
Defined in:
scripts/01600 Alpha 25 Battle Engine/00200 Battle_Logic/00001 Handlers/01004 DamageHandler.rb

Instance Attribute Summary

Attributes inherited from ChangeHandlerBase

#logic, #scene

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Hooks

#exec_hooks, #force_return, included, register, remove, remove_without_name

Methods inherited from ChangeHandlerBase

#initialize, #prevent_change, #process_prevention_reason, #reset_prevention_reason

Constructor Details

This class inherits a constructor from Battle::Logic::ChangeHandlerBase

Class Method Details

.register_damage_prevention_hook(reason) {|handler, hp, target, launcher, skill| ... }

Function that registers a damage_prevention hook

Parameters:

  • reason (String)

    reason of the damage_prevention registration

Yield Parameters:

Yield Returns:

  • (:prevent, Integer)

    :prevent if the damage cannot be applied, Integer if the hp variable should be updated



149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'scripts/01600 Alpha 25 Battle Engine/00200 Battle_Logic/00001 Handlers/01004 DamageHandler.rb', line 149

def register_damage_prevention_hook(reason)
  Hooks.register(DamageHandler, :damage_prevention, reason) do |hook_binding|
    result = yield(
      self,
      hook_binding.local_variable_get(:hp),
      hook_binding.local_variable_get(:target),
      hook_binding.local_variable_get(:launcher),
      hook_binding.local_variable_get(:skill)
    )
    hook_binding.local_variable_set(:hp, result) if result.is_a?(Integer)
    force_return(false) if result == :prevent
  end
end

.register_post_damage_death_hook(reason) {|handler, hp, target, launcher, skill| ... }

Function that registers a post_damage_death hook (when target is KO)

Parameters:

  • reason (String)

    reason of the post_damage_death registration

Yield Parameters:



189
190
191
192
193
194
195
196
197
198
199
# File 'scripts/01600 Alpha 25 Battle Engine/00200 Battle_Logic/00001 Handlers/01004 DamageHandler.rb', line 189

def register_post_damage_death_hook(reason)
  Hooks.register(DamageHandler, :post_damage_death, reason) do |hook_binding|
    yield(
      self,
      hook_binding.local_variable_get(:hp),
      hook_binding.local_variable_get(:target),
      hook_binding.local_variable_get(:launcher),
      hook_binding.local_variable_get(:skill)
    )
  end
end

.register_post_damage_hook(reason) {|handler, hp, target, launcher, skill| ... }

Function that registers a post_damage hook (when target is still alive)

Parameters:

  • reason (String)

    reason of the post_damage registration

Yield Parameters:



170
171
172
173
174
175
176
177
178
179
180
# File 'scripts/01600 Alpha 25 Battle Engine/00200 Battle_Logic/00001 Handlers/01004 DamageHandler.rb', line 170

def register_post_damage_hook(reason)
  Hooks.register(DamageHandler, :post_damage, reason) do |hook_binding|
    yield(
      self,
      hook_binding.local_variable_get(:hp),
      hook_binding.local_variable_get(:target),
      hook_binding.local_variable_get(:launcher),
      hook_binding.local_variable_get(:skill)
    )
  end
end

Instance Method Details

#damage_appliable(hp, target, launcher = nil, skill = nil) ⇒ Integer, false

Note:

Thing that prevents the damage from being applied should be defined using :damage_prevention Hook.

Function telling if a damage can be applied and how much

Parameters:

Returns:



12
13
14
15
16
17
18
19
20
21
22
# File 'scripts/01600 Alpha 25 Battle Engine/00200 Battle_Logic/00001 Handlers/01004 DamageHandler.rb', line 12

def damage_appliable(hp, target, launcher = nil, skill = nil)
  log_data("# damage_appliable(#{hp}, #{target}, #{launcher}, #{skill})")
  return false if target.hp <= 0

  reset_prevention_reason
  exec_hooks(DamageHandler, :damage_prevention, binding)
  return hp
rescue Hooks::ForceReturn => e
  log_data("# FR: damage_appliable #{e.data} from #{e.hook_name} (#{e.reason})")
  return e.data
end

#damage_change(hp, target, launcher = nil, skill = nil, &messages)

Function that actually deal the damage

Parameters:

  • hp (Integer)

    number of hp (damage) dealt

  • target (PFM::PokemonBattler)
  • launcher (PFM::PokemonBattler, nil) (defaults to: nil)

    Potential launcher of a move

  • skill (Battle::Move, nil) (defaults to: nil)

    Potential move used

  • messages (Proc)

    messages shown right before the post processing



30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'scripts/01600 Alpha 25 Battle Engine/00200 Battle_Logic/00001 Handlers/01004 DamageHandler.rb', line 30

def damage_change(hp, target, launcher = nil, skill = nil, &messages)
  skill&.damage_dealt += hp
  @scene.visual.show_hp_animations([target], [-hp], [skill&.effectiveness], &messages)
  target.last_hit_by_move = skill if skill
  exec_hooks(DamageHandler, :post_damage, binding) if target.hp > 0
  exec_hooks(DamageHandler, :post_damage_death, binding) if target.hp <= 0
  target.add_damage_to_history(hp, launcher, skill, target.hp <= 0)
  log_data("# damage_change(#{hp}, #{target}, #{launcher}, #{skill}, #{target.hp <= 0})")
rescue Hooks::ForceReturn => e
  log_data("# FR: damage_change #{e.data} from #{e.hook_name} (#{e.reason})")
  return e.data
ensure
  @scene.visual.refresh_info_bar(target)
end

#damage_change_with_process(hp, target, launcher = nil, skill = nil, &messages)

Function that test if the damage can be dealt and deal the damage if so

Parameters:

  • hp (Integer)

    number of hp (damage) dealt

  • target (PFM::PokemonBattler)
  • launcher (PFM::PokemonBattler, nil) (defaults to: nil)

    Potential launcher of a move

  • skill (Battle::Move, nil) (defaults to: nil)

    Potential move used

  • messages (Proc)

    messages shown right before the post processing



51
52
53
54
55
56
# File 'scripts/01600 Alpha 25 Battle Engine/00200 Battle_Logic/00001 Handlers/01004 DamageHandler.rb', line 51

def damage_change_with_process(hp, target, launcher = nil, skill = nil, &messages)
  return process_prevention_reason unless (hp = damage_appliable(hp, target, launcher, skill))

  process_prevention_reason # Ensure that things with damage change like substitute shows something
  damage_change(hp, target, launcher, skill, &messages)
end

#drain(hp_factor, target, launcher, skill = nil, hp_overwrite: nil, drain_factor: 1, &messages)

Function that drains a certain quantity of HP from the target and give it to the user

Parameters:

  • hp_factor (Integer)

    the division factor of HP to drain

  • target (PFM::PokemonBattler)

    target that get HP drained

  • launcher (PFM::PokemonBattler)

    launcher of a draining move/effect

  • skill (Battle::Move, nil) (defaults to: nil)

    Potential move used

  • hp_overwrite (Integer, nil) (defaults to: nil)

    for the number of hp drained by the move

  • drain_factor (Integer) (defaults to: 1)

    the division factor of HP drained

  • messages (Proc)

    messages shown right before the post processing



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'scripts/01600 Alpha 25 Battle Engine/00200 Battle_Logic/00001 Handlers/01004 DamageHandler.rb', line 96

def drain(hp_factor, target, launcher, skill = nil, hp_overwrite: nil, drain_factor: 1, &messages)
  hp = hp_overwrite || (target.max_hp / hp_factor).clamp(1, Float::INFINITY)
  skill&.damage_dealt += hp
  @scene.visual.show_hp_animations([target], [-hp], [skill&.effectiveness], &messages)
  target.last_hit_by_move = skill if skill
  # TODO: Add hooks for all those stuff
  if target.has_ability?(:liquid_ooze)
    @scene.visual.show_ability(target)
    damage_change(hp, launcher, launcher, nil)
    @scene.display_message_and_wait(parse_text_with_pokemon(19, 457, launcher))
  elsif launcher.effects.has?(:heal_block)
    @scene.display_message_and_wait(parse_text_with_pokemon(19, 890, launcher))
  elsif launcher.alive? && launcher.hp < launcher.max_hp
    hp = hp * 130 / 100 if launcher.hold_item?(:big_root)
    hp = hp * 3 / 2 if skill&.pulse? && launcher.has_ability?(:mega_launcher)
    @scene.visual.show_hp_animations([launcher], [(hp / drain_factor).clamp(1, Float::INFINITY)])
    @scene.display_message_and_wait(parse_text_with_pokemon(19, 905, target))
  end
  exec_hooks(DamageHandler, :post_damage, binding) if target.hp > 0
  exec_hooks(DamageHandler, :post_damage_death, binding) if target.hp <= 0
  target.add_damage_to_history(hp, launcher, skill, target.hp <= 0)
  log_data("# drain damage_change(#{hp}, #{target}, #{launcher}, #{skill}, #{target.hp <= 0})")
rescue Hooks::ForceReturn => e
  log_data("# FR: drain damage_change #{e.data} from #{e.hook_name} (#{e.reason})")
  return e.data
ensure
  @scene.visual.refresh_info_bar(target)
end

#drain_with_process(hp_factor, target, launcher, skill = nil, hp_overwrite: nil, drain_factor: 1, &messages)

Function that test if the drain damages can be dealt and perform the drain if so

Parameters:

  • hp_factor (Integer)

    the division factor of HP to drain

  • target (PFM::PokemonBattler)
  • launcher (PFM::PokemonBattler)

    Potential launcher of a move

  • skill (Battle::Move, nil) (defaults to: nil)

    Potential move used

  • hp_overwrite (Integer, nil) (defaults to: nil)

    for the number of hp drained by the move

  • drain_factor (Integer) (defaults to: 1)

    the division factor of HP drained

  • messages (Proc)

    messages shown right before the post processing



133
134
135
136
137
138
# File 'scripts/01600 Alpha 25 Battle Engine/00200 Battle_Logic/00001 Handlers/01004 DamageHandler.rb', line 133

def drain_with_process(hp_factor, target, launcher, skill = nil, hp_overwrite: nil, drain_factor: 1, &messages)
  hp = hp_overwrite || (target.max_hp / hp_factor).clamp(0, Float::INFINITY)
  return process_prevention_reason unless (hp = damage_appliable(hp, target, launcher, skill))

  drain(hp_factor, target, launcher, skill, hp_overwrite: hp, drain_factor: drain_factor, &messages)
end

#heal(target, hp, test_heal_block: true, animation_id: nil) {|hp| ... } ⇒ Boolean

Note:

this method yields a block in order to show the message after the animation

Note:

this shows the default message if no block has been given

Function that proceed the heal of a Pokemon

Parameters:

  • target (PFM::PokemonBattler)
  • hp (Integer)

    number of HP to heal

  • test_heal_block (Boolean) (defaults to: true)
  • animation_id (Symbol, Integer) (defaults to: nil)

    animation to use instead of the original one

Yield Parameters:

  • hp (Integer)

    the actual hp healed

Returns:

  • (Boolean)

    if the heal was successfull or not



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'scripts/01600 Alpha 25 Battle Engine/00200 Battle_Logic/00001 Handlers/01004 DamageHandler.rb', line 67

def heal(target, hp, test_heal_block: true, animation_id: nil)
  if test_heal_block && target.effects.has?(:heal_block)
    @scene.display_message_and_wait(parse_text_with_pokemon(19, 890, target))
    return false
  end
  if target.hp >= target.max_hp
    @scene.display_message_and_wait(parse_text_with_pokemon(19, 896, target))
    return false
  end

  actual_hp = hp.clamp(1, target.max_hp - target.hp)
  # TODO: play the animation that should be played on all hp heal (+think about animation_id)
  target.position == -1 ? target.hp += actual_hp : scene.visual.show_hp_animations([target], [actual_hp])
  if block_given?
    yield(actual_hp)
  else
    scene.display_message_and_wait(parse_text_with_pokemon(19, 387, target))
  end
  return true
end