GameHUD.gd 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. class_name GameHUD
  2. extends CanvasLayer
  3. var current_chara := ""
  4. static var character_icons := [preload("res://Assets/Sprites/Players/Mario/LifeIcon.json"),preload("res://Assets/Sprites/Players/Luigi/LifeIcon.json"), preload("res://Assets/Sprites/Players/Toad/LifeIcon.json"), preload("res://Assets/Sprites/Players/Toadette/LifeIcon.json")]
  5. const RANK_COLOURS := {"F": Color.DIM_GRAY, "D": Color.WEB_MAROON, "C": Color.PALE_GREEN, "B": Color.DODGER_BLUE, "A": Color.RED, "S": Color.GOLD, "P": Color.PURPLE}
  6. func _ready() -> void:
  7. Global.level_theme_changed.connect(update_character_info)
  8. func _process(_delta: float) -> void:
  9. handle_main_hud()
  10. handle_pausing()
  11. func handle_main_hud() -> void:
  12. $Main.visible = not Settings.file.visuals.modern_hud
  13. $ModernHUD.visible = Settings.file.visuals.modern_hud
  14. $Main/RedCoins.hide()
  15. $Main/CoinCount.show()
  16. %Combo.hide()
  17. $%Time.show()
  18. %Stopwatch.hide()
  19. %PB.hide()
  20. $Main/CoinCount/KeyCount.visible = KeyItem.total_collected > 0
  21. %KeyAmount.text = "*" + str(KeyItem.total_collected).pad_zeros(2)
  22. $Main.set_anchors_preset(Control.PRESET_CENTER_TOP if Settings.file.video.hud_size == 1 else Control.PRESET_TOP_WIDE, true)
  23. $ModernHUD.set_anchors_preset(Control.PRESET_CENTER_TOP if Settings.file.video.hud_size == 1 else Control.PRESET_TOP_WIDE, true)
  24. %Score.text = str(Global.score).pad_zeros(6)
  25. %CoinLabel.text = "*" + str(Global.coins).pad_zeros(2)
  26. if current_chara != Global.player_characters[0]:
  27. update_character_info()
  28. %CharacterIcon.get_node("Shadow").texture = %CharacterIcon.texture
  29. %ModernLifeCount.text = "*" + (str(Global.lives).pad_zeros(2) if Settings.file.difficulty.inf_lives == 0 else "∞")
  30. var world_num := str(Global.world_num)
  31. if int(world_num) >= 10:
  32. world_num = ["A", "B", "C", "D"][int(world_num) % 10]
  33. elif int(world_num) < 1:
  34. world_num = " "
  35. %LevelNum.text = world_num + "-" + str(Global.level_num)
  36. %Crown.visible = Global.second_quest
  37. %Time.text = " " + str(Global.time).pad_zeros(3)
  38. if Settings.file.difficulty.time_limit == 0:
  39. %Time.text = " ---"
  40. %Time.visible = get_tree().get_first_node_in_group("Players") != null
  41. handle_modern_hud()
  42. if Global.current_game_mode == Global.GameMode.CHALLENGE:
  43. handle_challenge_mode_hud()
  44. if DiscoLevel.in_disco_level:
  45. handle_disco_combo()
  46. if SpeedrunHandler.show_timer:
  47. handle_speedrun_timer()
  48. func update_character_info() -> void:
  49. %CharacterName.text = tr(Player.CHARACTER_NAMES[int(Global.player_characters[0])])
  50. %CharacterIcon.get_node("ResourceSetterNew").resource_json = (character_icons[int(Global.player_characters[0])])
  51. current_chara = Global.player_characters[0]
  52. func handle_modern_hud() -> void:
  53. $ModernHUD/TopLeft/RedCoins.hide()
  54. $ModernHUD/TopLeft/CoinCount.show()
  55. %ModernPB.hide()
  56. %ModernCoinCount.text = "*" + str(Global.coins).pad_zeros(2)
  57. %ModernScore.text = str(Global.score).pad_zeros(9)
  58. %ModernTime.text = "⏲" + str(Global.time).pad_zeros(3)
  59. %ModernKeyCount.visible = KeyItem.total_collected > 0
  60. %ModernKeyAmount.text = "*" + str(KeyItem.total_collected).pad_zeros(2)
  61. if get_tree().get_first_node_in_group("Players") == null or Settings.file.difficulty.time_limit == 0:
  62. %ModernTime.text = "⏲---"
  63. func handle_disco_combo() -> void:
  64. %Combo.show()
  65. %ComboAmount.text = "Combo*" + str(DiscoLevel.combo_amount)
  66. %ComboMeter.value = DiscoLevel.combo_meter
  67. %ComboMeter.modulate = Color.PURPLE if DiscoLevel.combo_breaks <= 0 else Color.WHITE
  68. %MedalIcon.region_rect.position.x = ("FDCBASP".find(DiscoLevel.current_rank) + 1) * 16
  69. func handle_challenge_mode_hud() -> void:
  70. $Main/RedCoins.show()
  71. $ModernHUD/TopLeft/RedCoins.show()
  72. $ModernHUD/TopLeft/CoinCount.hide()
  73. $Main/CoinCount.hide()
  74. var red_coins_collected = ChallengeModeHandler.current_run_red_coins_collected
  75. var idx := 0
  76. if Global.in_title_screen:
  77. red_coins_collected = int(ChallengeModeHandler.red_coins_collected[Global.world_num - 1][Global.level_num - 1])
  78. for i in [$Main/RedCoins/Coin1, $Main/RedCoins/Coin2, $Main/RedCoins/Coin3, $Main/RedCoins/Coin4, $Main/RedCoins/Coin5]:
  79. i.frame = int(ChallengeModeHandler.is_coin_collected(idx, red_coins_collected))
  80. idx += 1
  81. if ChallengeModeHandler.is_coin_collected(ChallengeModeHandler.CoinValues.YOSHI_EGG, red_coins_collected):
  82. $Main/RedCoins/YoshiEgg.frame = Global.level_num
  83. else:
  84. $Main/RedCoins/YoshiEgg.frame = 0
  85. $Main/RedCoins/ScoreMedal.frame = (Global.score > ChallengeModeHandler.CHALLENGE_TARGETS[Global.current_campaign][Global.world_num - 1][Global.level_num - 1] or ChallengeModeHandler.top_challenge_scores[Global.world_num - 1][Global.level_num - 1] >= ChallengeModeHandler.CHALLENGE_TARGETS[Global.current_campaign][Global.world_num - 1][Global.level_num - 1])
  86. if is_instance_valid(Global.current_level):
  87. handle_yoshi_radar()
  88. for i in $Main/RedCoins.get_children():
  89. i.get_node("Shadow").frame = i.frame
  90. for i in $ModernHUD/TopLeft/RedCoins.get_child_count():
  91. $ModernHUD/TopLeft/RedCoins.get_child(i).frame = $Main/RedCoins.get_child(i).frame
  92. $ModernHUD/TopLeft/RedCoins.get_child(i).get_node("Shadow").frame = $Main/RedCoins.get_child(i).frame
  93. func handle_yoshi_radar() -> void:
  94. var has_egg = false
  95. var egg_position = Vector2.ZERO
  96. for i in get_tree().get_nodes_in_group("Blocks"):
  97. if i.item != null:
  98. if i.item.resource_path == "res://Scenes/Prefabs/Entities/Items/YoshiEgg.tscn":
  99. has_egg = true
  100. egg_position = i.global_position
  101. break
  102. %Radar.frame = Global.level_num
  103. %ModernRadar.frame = Global.level_num
  104. if has_egg == false or ChallengeModeHandler.is_coin_collected(5):
  105. %Radar.get_node("AnimationPlayer").play("RESET")
  106. %ModernRadar.get_node("AnimationPlayer").play("RESET")
  107. return
  108. var player_position = get_tree().get_first_node_in_group("Players").global_position
  109. var distance = (egg_position - player_position).length()
  110. %Radar.get_node("AnimationPlayer").speed_scale = (250 / distance)
  111. %ModernRadar.get_node("AnimationPlayer").speed_scale = $Main/RedCoins/YoshiEgg/Radar/AnimationPlayer.speed_scale
  112. if distance < 512:
  113. %Radar.get_node("AnimationPlayer").play("Flash")
  114. %ModernRadar.get_node("AnimationPlayer").play("Flash")
  115. else:
  116. %Radar.get_node("AnimationPlayer").play("RESET")
  117. %ModernRadar.get_node("AnimationPlayer").play("RESET")
  118. func handle_speedrun_timer() -> void:
  119. %Time.hide()
  120. %Stopwatch.show()
  121. var late = SpeedrunHandler.timer > SpeedrunHandler.best_time
  122. var diff = SpeedrunHandler.best_time - SpeedrunHandler.timer
  123. %PB.visible = SpeedrunHandler.best_time > 0 and (SpeedrunHandler.timer > 0 or Global.current_level != null)
  124. %ModernPB.visible = %PB.visible
  125. var time_string = SpeedrunHandler.gen_time_string(SpeedrunHandler.format_time(SpeedrunHandler.timer))
  126. %Stopwatch.text = time_string
  127. %ModernTime.text = "⏲" + time_string
  128. %PB.text = ("+" if late else "-") + SpeedrunHandler.gen_time_string(SpeedrunHandler.format_time(diff))
  129. %PB.modulate = Color.RED if late else Color.GREEN
  130. %ModernPB.text = %PB.text
  131. %ModernPB.modulate = %PB.modulate
  132. func handle_pausing() -> void:
  133. if get_tree().get_first_node_in_group("Players") != null and Global.can_pause and (Global.current_game_mode != Global.GameMode.LEVEL_EDITOR):
  134. if get_tree().paused == false and Global.game_paused == false:
  135. if Input.is_action_just_pressed("pause"):
  136. activate_pause_menu()
  137. func activate_pause_menu() -> void:
  138. match Global.current_game_mode:
  139. Global.GameMode.BOO_RACE:
  140. $BooRacePause.open()
  141. Global.GameMode.MARATHON:
  142. $MarathonPause.open()
  143. Global.GameMode.MARATHON_PRACTICE:
  144. $MarathonPause.open()
  145. _:
  146. $StoryPause.open()
  147. const HURRY_UP = preload("res://Assets/Audio/BGM/HurryUp.mp3")
  148. func on_timeout() -> void:
  149. if Global.can_time_tick and is_instance_valid(Global.current_level) and Settings.file.difficulty.time_limit == 1:
  150. if Global.level_editor != null:
  151. if Global.level_editor.current_state != LevelEditor.EditorState.PLAYTESTING:
  152. return
  153. if Global.time == 0:
  154. get_tree().call_group("Players", "time_up")
  155. return
  156. Global.time -= 1
  157. if Global.time == 100:
  158. AudioManager.set_music_override(AudioManager.MUSIC_OVERRIDES.TIME_WARNING, 5, true)