Alternate Challenge HUD Proposal: Previously obtained coins/eggs are transparent (#712)

* Challenge Hunt: Transparent HUD for previously obtained coins/eggs

* Add 'score potential' tracker, make egg not default to empty if egg isn't in the current room on a replay

* Make transparent HUD elements render on top, and become invisible if their fully-opaque equivalents should be enabled instead
This commit is contained in:
jdaster64 2025-11-22 11:41:04 -05:00 committed by GitHub
parent 5a0a72daeb
commit 5daa630a72
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 273 additions and 25 deletions

View file

@ -11,7 +11,7 @@ var can_spawn_particles := false
signal collected
func _ready() -> void:
if ChallengeModeHandler.is_coin_collected(id):
if ChallengeModeHandler.is_coin_collected(id) or ChallengeModeHandler.is_coin_permanently_collected(id):
already_collected = true
$Sprite.play("Collected")
set_visibility_layer_bit(0, false)

View file

@ -12,7 +12,7 @@ var can_spawn_particles := false
@onready var COIN_SPARKLE = load("res://Scenes/Prefabs/Particles/RedCoinSparkle.tscn")
func _ready() -> void:
already_collected = ChallengeModeHandler.is_coin_collected(id)
already_collected = ChallengeModeHandler.is_coin_collected(id) or ChallengeModeHandler.is_coin_permanently_collected(id)
if already_collected == false:
ChallengeModeHandler.red_coins += 1
AudioManager.play_sfx(collection_sounds[ChallengeModeHandler.red_coins - 1], global_position)

View file

@ -83,6 +83,10 @@ static func set_value(coin_id := CoinValues.R_COIN_1, value := false) -> void:
static func is_coin_collected(coin_id: CoinValues = CoinValues.R_COIN_1, num := current_run_red_coins_collected) -> bool:
return num & (1 << coin_id) != 0
static func is_coin_permanently_collected(coin_id: CoinValues = CoinValues.R_COIN_1) -> bool:
var permanently_collected = int(red_coins_collected[Global.world_num - 1][Global.level_num - 1])
return permanently_collected & (1 << coin_id) != 0
func check_for_achievement() -> void:
for x in red_coins_collected:
for i in x:

View file

@ -100,54 +100,78 @@ func handle_challenge_mode_hud() -> void:
%ModernLifeCount.hide()
%CharacterIcon.hide()
var red_coins_collected = ChallengeModeHandler.current_run_red_coins_collected
var idx := 0
if Global.world_num > 8:
return
if Global.in_title_screen:
red_coins_collected = int(ChallengeModeHandler.red_coins_collected[Global.world_num - 1][Global.level_num - 1])
var idx := 0
for i in [$Main/RedCoins/Coin1, $Main/RedCoins/Coin2, $Main/RedCoins/Coin3, $Main/RedCoins/Coin4, $Main/RedCoins/Coin5]:
i.frame = int(ChallengeModeHandler.is_coin_collected(idx, red_coins_collected))
idx += 1
idx = 0
for i in [$Main/RedCoins/Coin1Transparent, $Main/RedCoins/Coin2Transparent, $Main/RedCoins/Coin3Transparent, $Main/RedCoins/Coin4Transparent, $Main/RedCoins/Coin5Transparent]:
i.visible = false
if ChallengeModeHandler.is_coin_permanently_collected(idx) and not ChallengeModeHandler.is_coin_collected(idx, red_coins_collected):
i.visible = true
i.frame = 1
idx += 1
$Main/RedCoins/ScoreMedal.frame = 0
$Main/RedCoins/ScoreMedalTransparent.visible = false
var score_target = ChallengeModeHandler.CHALLENGE_TARGETS[Global.current_campaign][Global.world_num - 1][Global.level_num - 1]
if Global.score >= score_target or ChallengeModeHandler.top_challenge_scores[Global.world_num - 1][Global.level_num - 1] >= score_target:
$Main/RedCoins/ScoreMedal.frame = 1
elif Global.score > 0 and (Global.score + (Global.time * 50)) >= score_target:
$Main/RedCoins/ScoreMedalTransparent.frame = 1
$Main/RedCoins/ScoreMedalTransparent.visible = true
if ChallengeModeHandler.is_coin_collected(ChallengeModeHandler.CoinValues.YOSHI_EGG, red_coins_collected):
$Main/RedCoins/YoshiEgg.frame = Global.level_num
else:
$Main/RedCoins/YoshiEgg.frame = 0
$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])
if is_instance_valid(Global.current_level):
handle_yoshi_radar()
handle_yoshi_radar()
for i in $Main/RedCoins.get_children():
i.get_node("Shadow").frame = i.frame
i.get_node("Shadow").visible = i.visible
for i in $ModernHUD/TopLeft/RedCoins.get_child_count():
$ModernHUD/TopLeft/RedCoins.get_child(i).frame = $Main/RedCoins.get_child(i).frame
$ModernHUD/TopLeft/RedCoins.get_child(i).visible = $Main/RedCoins.get_child(i).visible
$ModernHUD/TopLeft/RedCoins.get_child(i).get_node("Shadow").frame = $Main/RedCoins.get_child(i).frame
$ModernHUD/TopLeft/RedCoins.get_child(i).get_node("Shadow").visible = $Main/RedCoins.get_child(i).visible
func handle_yoshi_radar() -> void:
if not is_instance_valid(Global.current_level) or ChallengeModeHandler.is_coin_collected(ChallengeModeHandler.CoinValues.YOSHI_EGG):
%Radar.get_node("AnimationPlayer").play("RESET")
%ModernRadar.get_node("AnimationPlayer").play("RESET")
return
var has_egg = false
var egg_position = Vector2.ZERO
var distance = 999
for i in get_tree().get_nodes_in_group("Blocks"):
if i.item != null:
if i.item.resource_path == "res://Scenes/Prefabs/Entities/Items/YoshiEgg.tscn":
has_egg = true
egg_position = i.global_position
break
if has_egg:
var player_position = get_tree().get_first_node_in_group("Players").global_position
distance = (egg_position - player_position).length()
%Radar.frame = Global.level_num
%ModernRadar.frame = Global.level_num
if has_egg == false or ChallengeModeHandler.is_coin_collected(ChallengeModeHandler.CoinValues.YOSHI_EGG):
%Radar.get_node("AnimationPlayer").play("RESET")
%ModernRadar.get_node("AnimationPlayer").play("RESET")
return
var player_position = get_tree().get_first_node_in_group("Players").global_position
var distance = (egg_position - player_position).length()
%Radar.get_node("AnimationPlayer").speed_scale = (250 / distance)
%ModernRadar.get_node("AnimationPlayer").speed_scale = $Main/RedCoins/YoshiEgg/Radar/AnimationPlayer.speed_scale
if distance < 512:
%Radar.get_node("AnimationPlayer").speed_scale = (250 / distance)
%ModernRadar.get_node("AnimationPlayer").speed_scale = $Main/RedCoins/YoshiEgg/Radar/AnimationPlayer.speed_scale
%Radar.get_node("AnimationPlayer").play("Flash")
%ModernRadar.get_node("AnimationPlayer").play("Flash")
elif ChallengeModeHandler.is_coin_permanently_collected(ChallengeModeHandler.CoinValues.YOSHI_EGG):
%Radar.get_node("AnimationPlayer").play("AlwaysOn")
%ModernRadar.get_node("AnimationPlayer").play("AlwaysOn")
else:
%Radar.get_node("AnimationPlayer").play("RESET")
%ModernRadar.get_node("AnimationPlayer").play("RESET")

View file

@ -50,7 +50,7 @@ func quit_to_menu() -> void:
func reset_values() -> void:
if Global.world_num <= 8:
ChallengeModeHandler.current_run_red_coins_collected = ChallengeModeHandler.red_coins_collected[Global.world_num - 1][Global.level_num - 1]
ChallengeModeHandler.current_run_red_coins_collected = 0
Global.lives = 3
Global.score = 0
Global.player_power_states = "0000"

View file

@ -195,7 +195,7 @@ func challenge_hunt_start() -> void:
LevelTransition.level_to_transition_to = Level.get_scene_string(Global.world_num, Global.level_num)
ChallengeModeHandler.current_run_red_coins_collected = ChallengeModeHandler.red_coins_collected[Global.world_num - 1][Global.level_num -1]
ChallengeModeHandler.current_run_red_coins_collected = 0
Global.transition_to_scene("res://Scenes/Levels/LevelTransition.tscn")
func world_9_selected() -> void:

View file

@ -46,7 +46,7 @@ func save_results() -> void:
func retry_level() -> void:
Global.player_power_states = "0000"
ChallengeModeHandler.current_run_red_coins_collected = ChallengeModeHandler.red_coins_collected[Global.world_num - 1][Global.level_num - 1]
ChallengeModeHandler.current_run_red_coins_collected = 0
Global.score = 0
LevelTransition.level_to_transition_to = Level.get_scene_string(Global.world_num, Global.level_num)
Global.transition_to_scene("res://Scenes/Levels/LevelTransition.tscn")
@ -90,7 +90,8 @@ func update_score() -> void:
func give_red_coin_medal() -> void:
const mask = (1 << ChallengeModeHandler.CoinValues.R_COIN_1) | (1 << ChallengeModeHandler.CoinValues.R_COIN_2) | (1 << ChallengeModeHandler.CoinValues.R_COIN_3) | (1 << ChallengeModeHandler.CoinValues.R_COIN_4) | (1 << ChallengeModeHandler.CoinValues.R_COIN_5)
var valid := (ChallengeModeHandler.current_run_red_coins_collected & mask) == mask
var all_collected = int(ChallengeModeHandler.red_coins_collected[Global.world_num - 1][Global.level_num - 1]) | ChallengeModeHandler.current_run_red_coins_collected
var valid := (int(all_collected) & mask) == mask
if valid and not coin_medal:
do_medal_give_animation($Sprite2D3/RedCoins)