game.gd 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. extends Node2D
  2. class_name Game
  3. @onready var health_bar: HealthBar = $HealthBar
  4. @onready var overlay: CanvasLayer = $Overlay
  5. @onready var transition: Transition = $Overlay/Transition
  6. @onready var player_spawn: PlayerSpawnZone = $PlayerSpawnZone
  7. @onready var spawn_timer: Timer = $Timer
  8. @onready var ui_root: Control = $UI/Root
  9. @onready var wave_label: Label = $UI/Root/WaveLabel
  10. @onready var phase_label: Label = $UI/Root/PhaseLabel
  11. @onready var next_phase_button: Button = $UI/Root/NextPhaseButton
  12. @onready var combat_start_sound: AudioStreamPlayer = $Sounds/CombatStartSound
  13. @onready var main_menu: PackedScene = load("res://screens/main_menu.tscn")
  14. @onready var bot_scene: PackedScene = load("res://assets/scenes/bot.tscn")
  15. @onready var game_over_scene: PackedScene = load("res://assets/scenes/game_over.tscn")
  16. @onready var victory_scene: PackedScene = load("res://assets/scenes/victory.tscn")
  17. @onready var spawn_points: Array[Marker2D] = [
  18. $EnemySpawns/EnemySpawn_1,
  19. $EnemySpawns/EnemySpawn_2,
  20. $EnemySpawns/EnemySpawn_3,
  21. ]
  22. enum Phase {
  23. PHASE_SETUP,
  24. PHASE_COMBAT,
  25. PHASE_LOOT,
  26. }
  27. enum Loot {
  28. LOOT_SURVIVOR,
  29. LOOT_HEAL,
  30. LOOT_LOWER_COOLDOWN,
  31. }
  32. const RELOAD_TIME: float = 4.0
  33. static var reload_time: float = RELOAD_TIME # seconds
  34. static var max_ammo: int = 1 # shots
  35. static var base_accuracy: float = 0.33 # percent
  36. var phase: Phase = Phase.PHASE_SETUP:
  37. set(new_value):
  38. phase = new_value
  39. match new_value:
  40. Phase.PHASE_SETUP:
  41. phase_label.text = "PHASE: SETUP"
  42. Phase.PHASE_COMBAT:
  43. phase_label.text = "PHASE: COMBAT"
  44. Phase.PHASE_LOOT:
  45. phase_label.text = "PHASE: LOOT"
  46. var waves_completed: int = 0:
  47. set(new_value):
  48. waves_completed = new_value
  49. wave_label.text = "WAVE: %d" % (new_value + 1)
  50. func _ready() -> void:
  51. Game.reload_time = RELOAD_TIME # seconds
  52. Game.max_ammo = 1 # shots
  53. waves_completed = 0
  54. phase = Phase.PHASE_SETUP
  55. overlay.visible = true
  56. player_spawn.add_survivor()
  57. transition.slide_out()
  58. await transition.game_fully_visible
  59. func _process(_delta: float) -> void:
  60. if Input.is_action_pressed("ui_cancel"):
  61. go_to_main_menu()
  62. if phase == Phase.PHASE_COMBAT:
  63. if get_foes().is_empty() and health_bar.health != 0:
  64. end_combat()
  65. func go_to_main_menu() -> void:
  66. var tree = get_tree()
  67. transition.text = ""
  68. tree.paused = true
  69. transition.slide_in()
  70. await transition.game_fully_hidden
  71. tree.change_scene_to_packed(main_menu)
  72. tree.paused = false
  73. func spawn_bot(spawn: Marker2D) -> void:
  74. var bot: Bot = bot_scene.instantiate()
  75. bot.global_position = spawn.global_position
  76. bot.speed += waves_completed
  77. bot.visible = false
  78. add_child(bot)
  79. func get_foes() -> Array[Area2D]:
  80. var foes: Array[Area2D] = []
  81. foes.assign(get_tree().get_nodes_in_group("foe"))
  82. return foes
  83. func get_survivors() -> Array[Area2D]:
  84. var survivors: Array[Area2D] = []
  85. survivors.assign(get_tree().get_nodes_in_group("survivor"))
  86. return survivors
  87. func get_waiting_foes() -> Array[Area2D]:
  88. return get_foes().filter(func (foe): return not foe.visible)
  89. func get_active_foes() -> Array[Area2D]:
  90. return get_foes().filter(func (foe): return foe.visible)
  91. func activate_foe() -> void:
  92. var foes = get_waiting_foes()
  93. if not foes.is_empty():
  94. foes.pick_random().visible = true
  95. func reset_survivors() -> void:
  96. var survivors = get_survivors()
  97. #for survivor in survivors:
  98. # survivor.reparent(self)
  99. for survivor in survivors:
  100. #player_spawn.drop(survivor)
  101. #survivor.position = Vector2.ZERO
  102. #survivor.rotation = 0.0
  103. survivor.ammo = Game.max_ammo
  104. func _on_timer_timeout() -> void:
  105. activate_foe()
  106. func base_hit() -> void:
  107. health_bar.health -= 1
  108. if health_bar.health == 0:
  109. await game_over()
  110. func game_over() -> void:
  111. spawn_timer.stop()
  112. var foes = get_tree().get_nodes_in_group("foe")
  113. for foe in foes:
  114. foe.queue_free()
  115. var gos: GameOver = game_over_scene.instantiate()
  116. gos.message = "YOU DIED AFTER\nCOMPLETING %d WAVES!" % waves_completed
  117. ui_root.add_child(gos)
  118. await gos.closed
  119. await go_to_main_menu()
  120. func _on_base_area_entered(area: Area2D) -> void:
  121. if area.is_in_group("foe") || area.is_in_group("foe_weapons"):
  122. base_hit()
  123. func start_combat() -> void:
  124. GlobalInput.dragging_disabled = true
  125. for n in (waves_completed + 1):
  126. var spawner = spawn_points.pick_random()
  127. spawn_bot(spawner)
  128. spawn_timer.wait_time = lerpf(3.5, 0.5, minf(float(waves_completed)/20.0, 1.0))
  129. spawn_timer.start()
  130. combat_start_sound.play()
  131. activate_foe()
  132. const LOOT_SURVIVOR: String = "+1 SURVIVOR"
  133. const LOOT_HEALTH: String = "+3 HEALTH"
  134. const LOOT_AMMO: String = "BIGGER MAGAZINES"
  135. const LOOT_RELOAD_TIME: String = "FASTER RELOADING"
  136. const LOOT_ACCURACY: String = "HIGHER ACCURACY"
  137. const LOOTS: Array[String] = [LOOT_SURVIVOR, LOOT_HEALTH, LOOT_AMMO, LOOT_RELOAD_TIME, LOOT_ACCURACY]
  138. func end_combat() -> void:
  139. phase = Phase.PHASE_LOOT
  140. spawn_timer.stop()
  141. await get_tree().create_timer(1.5).timeout
  142. var vs: Victory = victory_scene.instantiate()
  143. ui_root.add_child(vs)
  144. var loots: Array[String] = []
  145. loots.assign(LOOTS)
  146. if get_survivors().size() >= 9:
  147. loots.erase(LOOT_SURVIVOR)
  148. loots.shuffle()
  149. vs.set_loot_options(loots[0], loots[1], loots[2])
  150. await vs.loot_selected
  151. var loot: String = loots[vs.selection]
  152. print("selected loot: " + str(loot))
  153. var next_wave = waves_completed + 2
  154. await transition.transition("WAVE %d" % next_wave, func ():
  155. self.waves_completed += 1
  156. self.phase = Phase.PHASE_SETUP
  157. self.next_phase_button.disabled = false
  158. match loot:
  159. LOOT_SURVIVOR:
  160. self.player_spawn.add_survivor()
  161. LOOT_HEALTH:
  162. self.health_bar.health += 3
  163. LOOT_RELOAD_TIME:
  164. Game.reload_time *= 0.9
  165. LOOT_AMMO:
  166. Game.max_ammo += 1
  167. LOOT_ACCURACY:
  168. Game.base_accuracy += 0.1
  169. self.reset_survivors()
  170. )
  171. GlobalInput.dragging_disabled = false
  172. func _on_next_phase_button_pressed() -> void:
  173. match phase:
  174. Phase.PHASE_SETUP:
  175. phase = Phase.PHASE_COMBAT
  176. next_phase_button.disabled = true
  177. start_combat()
  178. Phase.PHASE_COMBAT:
  179. pass # this should not happen
  180. Phase.PHASE_LOOT:
  181. pass # this should not happen