Guest User

Effect Receiver

a guest
Jul 19th, 2025
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.31 KB | None | 0 0
  1. extends Node2D
  2. class_name EffectReceiver
  3.  
  4. signal effect_started(effect_type: Util.EffectType)
  5. signal effect_ended(effect_type: Util.EffectType)
  6. signal health_changed(current_hp: int, max_hp: int)
  7. signal damaged(amount: float)
  8. signal died()
  9.  
  10. @export var max_hp: int = 100
  11. var current_hp: int = 100
  12.  
  13. var velocity_knockback: Vector2 = Vector2.ZERO
  14. var knockback_friction: float = 800.0
  15.  
  16. var active_dots: Array[Dictionary] = []
  17. var active_stat_modifiers: Dictionary = {}
  18.  
  19. var speed_multiplier := 1.0
  20. var attack_multiplier := 1.0
  21. var defense_multiplier := 1.0
  22.  
  23. var active_states: Dictionary = {} # { EffectType: true }
  24. var state_timers: Dictionary = {} # { EffectType: float }
  25.  
  26. func _process(delta: float) -> void:
  27. _process_dots(delta)
  28. _process_stat_modifiers(delta)
  29. _process_state_timers(delta)
  30. _process_knockback(delta)
  31.  
  32. func apply_effect(effect: Effect, source: Node = null):
  33. print(effect.name)
  34. emit_signal("effect_started", effect.effect_type)
  35.  
  36. match effect.behavior:
  37. Util.EffectBehavior.INSTANT:
  38. _apply_instant_effect(effect, source)
  39. Util.EffectBehavior.DOT:
  40. _add_dot_effect(effect)
  41. Util.EffectBehavior.BUFF, Util.EffectBehavior.DEBUFF:
  42. _add_stat_modifier(effect)
  43.  
  44. func _apply_instant_effect(effect: Effect, source: Node = null):
  45. if effect.damage:
  46. take_damage(effect.damage)
  47.  
  48. if effect.effect_type == Util.EffectType.KNOCKBACK:
  49. if source:
  50. apply_knockback_from(source.global_position, effect.knockback_strength)
  51.  
  52. if effect.effect_type in [Util.EffectType.STUN, Util.EffectType.ROOT, Util.EffectType.FEAR]:
  53. _apply_state(effect.effect_type, effect.duration)
  54.  
  55. if effect.stat_modifiers:
  56. _add_stat_modifier(effect)
  57.  
  58. func _apply_state(effect_type: Util.EffectType, duration: float):
  59. active_states[effect_type] = true
  60. state_timers[effect_type] = duration
  61.  
  62. func _process_state_timers(delta: float):
  63. for effect_type in state_timers.keys():
  64. state_timers[effect_type] -= delta
  65. if state_timers[effect_type] <= 0:
  66. active_states[effect_type] = false
  67. state_timers.erase(effect_type)
  68. emit_signal("effect_ended", effect_type)
  69.  
  70. func is_under(effect_type: Util.EffectType) -> bool:
  71. return active_states.get(effect_type, false)
  72.  
  73. func take_damage(damage: DamageData):
  74. var final_damage = damage.amount
  75. current_hp = clamp(current_hp - final_damage, 0, max_hp)
  76. emit_signal("damaged", final_damage)
  77. emit_signal("health_changed", current_hp, max_hp)
  78.  
  79. if current_hp <= 0:
  80. died.emit()
  81.  
  82. func _add_dot_effect(effect: Effect):
  83. active_dots.append({"effect": effect, "timer": 0.0, "elapsed": 0.0})
  84.  
  85. func _process_dots(delta: float):
  86. for i in active_dots.size():
  87. var dot = active_dots[i]
  88. var e: Effect = dot.effect
  89. dot["elapsed"] += delta
  90. dot["timer"] += delta
  91.  
  92. if dot["timer"] >= e.tick_interval:
  93. dot["timer"] = 0.0
  94. if e.damage:
  95. take_damage(e.damage)
  96.  
  97. if dot["elapsed"] >= e.duration:
  98. emit_signal("effect_ended", e.effect_type)
  99. active_dots.remove_at(i)
  100. return
  101.  
  102. func _add_stat_modifier(effect: Effect):
  103. if effect.stat_modifiers == null:
  104. return
  105.  
  106. active_stat_modifiers[effect.effect_type] = {
  107. "modifier": effect.stat_modifiers,
  108. "remaining_time": effect.duration
  109. }
  110.  
  111. _apply_stat(effect.stat_modifiers)
  112.  
  113. func _apply_stat(data: StatModifierData):
  114. speed_multiplier *= data.speed_multiplier
  115. attack_multiplier *= data.attack_multiplier
  116. defense_multiplier *= data.defense_multiplier
  117.  
  118. func _remove_stat(data: StatModifierData):
  119. speed_multiplier /= data.speed_multiplier
  120. attack_multiplier /= data.attack_multiplier
  121. defense_multiplier /= data.defense_multiplier
  122.  
  123. func _process_stat_modifiers(delta: float):
  124. for effect_type in active_stat_modifiers.keys():
  125. active_stat_modifiers[effect_type].remaining_time -= delta
  126. if active_stat_modifiers[effect_type].remaining_time <= 0:
  127. var mod = active_stat_modifiers[effect_type].modifier
  128. _remove_stat(mod)
  129. emit_signal("effect_ended", effect_type)
  130. active_stat_modifiers.erase(effect_type)
  131. break
  132.  
  133. func apply_knockback_from(origin: Vector2, strength: float):
  134. var direction = (global_position - origin).normalized()
  135. velocity_knockback = direction * strength
  136.  
  137. func _process_knockback(delta: float):
  138. if velocity_knockback.length_squared() > 0.1:
  139. velocity_knockback = velocity_knockback.move_toward(Vector2.ZERO, knockback_friction * delta)
  140.  
Advertisement
Add Comment
Please, Sign In to add comment