sword.gd 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. extends Area2D
  2. signal attack_finished
  3. enum States { IDLE, ATTACK }
  4. var state = null
  5. enum AttackInputStates { IDLE, LISTENING, REGISTERED }
  6. var attack_input_state = AttackInputStates.IDLE
  7. var ready_for_next_attack = false
  8. const MAX_COMBO_COUNT = 3
  9. var combo_count = 0
  10. var attack_current = {}
  11. var combo = [{
  12. "damage": 1,
  13. "animation": "attack_fast",
  14. "effect": null
  15. },
  16. {
  17. "damage": 1,
  18. "animation": "attack_fast",
  19. "effect": null
  20. },
  21. {
  22. "damage": 3,
  23. "animation": "attack_medium",
  24. "effect": null
  25. }]
  26. var hit_objects = []
  27. func _ready():
  28. $AnimationPlayer.animation_finished.connect(self._on_animation_finished)
  29. body_entered.connect(self._on_body_entered)
  30. _change_state(States.IDLE)
  31. func _change_state(new_state):
  32. match state:
  33. States.ATTACK:
  34. hit_objects = []
  35. attack_input_state = AttackInputStates.LISTENING
  36. ready_for_next_attack = false
  37. match new_state:
  38. States.IDLE:
  39. combo_count = 0
  40. $AnimationPlayer.stop()
  41. visible = false
  42. monitoring = false
  43. States.ATTACK:
  44. attack_current = combo[combo_count -1]
  45. $AnimationPlayer.play(attack_current["animation"])
  46. visible = true
  47. monitoring = true
  48. state = new_state
  49. func _unhandled_input(event):
  50. if not state == States.ATTACK:
  51. return
  52. if attack_input_state != AttackInputStates.LISTENING:
  53. return
  54. if event.is_action_pressed("attack"):
  55. attack_input_state = AttackInputStates.REGISTERED
  56. func _physics_process(_delta):
  57. if attack_input_state == AttackInputStates.REGISTERED and ready_for_next_attack:
  58. attack()
  59. func attack():
  60. combo_count += 1
  61. _change_state(States.ATTACK)
  62. # Use with AnimationPlayer func track.
  63. func set_attack_input_listening():
  64. attack_input_state = AttackInputStates.LISTENING
  65. # Use with AnimationPlayer func track.
  66. func set_ready_for_next_attack():
  67. ready_for_next_attack = true
  68. func _on_body_entered(body):
  69. if not body.has_node("Health"):
  70. return
  71. if body.get_rid().get_id() in hit_objects:
  72. return
  73. hit_objects.append(body.get_rid().get_id())
  74. body.take_damage(self, attack_current["damage"], attack_current["effect"])
  75. func _on_animation_finished(_name):
  76. if attack_current.is_empty():
  77. return
  78. if attack_input_state == AttackInputStates.REGISTERED and combo_count < MAX_COMBO_COUNT:
  79. attack()
  80. else:
  81. _change_state(States.IDLE)
  82. emit_signal("attack_finished")
  83. func _on_StateMachine_state_changed(current_state):
  84. if current_state.name == "Attack":
  85. attack()