feat: Implement tile scarcity model for tile generation and power-up inventory UI for player interaction.

This commit is contained in:
Yogi Wiguna
2026-02-25 12:09:14 +08:00
parent 040e6e53ce
commit 4990ce3c89
7 changed files with 116 additions and 36 deletions
+22 -3
View File
@@ -19,6 +19,7 @@ var is_match_active: bool = false
# Score tracking: peer_id -> score
var player_scores: Dictionary = {}
var player_goal_counts: Dictionary = {} # peer_id -> count
var stop_n_go_winner_id: int = -1 # Track winner for Stop n Go sorting
# Reference to main scene
var main_scene: Node = null
@@ -299,8 +300,16 @@ func _update_leaderboard():
var sorted_scores = []
for peer_id in player_scores.keys():
sorted_scores.append({"peer_id": peer_id, "score": player_scores[peer_id]})
sorted_scores.sort_custom(func(a, b): return a.score > b.score)
# Custom Sort for Stop n Go
if stop_n_go_winner_id != -1:
sorted_scores.sort_custom(func(a, b):
if a.peer_id == stop_n_go_winner_id: return true
if b.peer_id == stop_n_go_winner_id: return false
return a.score > b.score
)
else:
sorted_scores.sort_custom(func(a, b): return a.score > b.score)
emit_signal("leaderboard_updated", sorted_scores)
# =============================================================================
@@ -432,7 +441,17 @@ func get_leaderboard() -> Array:
var sorted_scores = []
for peer_id in player_scores.keys():
sorted_scores.append({"peer_id": peer_id, "score": player_scores[peer_id]})
sorted_scores.sort_custom(func(a, b): return a.score > b.score)
# Custom Sort for Stop n Go
if stop_n_go_winner_id != -1:
sorted_scores.sort_custom(func(a, b):
if a.peer_id == stop_n_go_winner_id: return true
if b.peer_id == stop_n_go_winner_id: return false
return a.score > b.score
)
else:
sorted_scores.sort_custom(func(a, b): return a.score > b.score)
return sorted_scores
func get_time_remaining() -> float:
+18 -8
View File
@@ -89,14 +89,24 @@ func handle_unhandled_input(event):
# --- Keyboard Shortcuts (Event-based) ---
if event is InputEventKey and event.pressed and not event.echo:
match event.keycode:
KEY_KP_1, KEY_1:
player.activate_powerup(0) # FASTER_SPEED
KEY_KP_2, KEY_2:
player.activate_powerup(2) # BLOCK_FLOOR
KEY_KP_3, KEY_3:
player.activate_powerup(1) # AREA_FREEZE
KEY_KP_4, KEY_4:
player.activate_powerup(3) # INVISIBLE_MODE
KEY_KP_1, KEY_1, KEY_KP_2, KEY_2, KEY_KP_3, KEY_3, KEY_KP_4, KEY_4:
var is_sng = LobbyManager.game_mode == "Stop n Go"
match event.keycode:
KEY_KP_1, KEY_1:
player.activate_powerup(0) # FASTER_SPEED
KEY_KP_2, KEY_2:
if is_sng:
player.activate_powerup(1) # AREA_FREEZE (StopNGo)
else:
player.activate_powerup(2) # BLOCK_FLOOR (Free)
KEY_KP_3, KEY_3:
if is_sng:
player.activate_powerup(3) # INVISIBLE_MODE (StopNGo)
else:
player.activate_powerup(1) # AREA_FREEZE (Free)
KEY_KP_4, KEY_4:
if not is_sng:
player.activate_powerup(3) # INVISIBLE_MODE (Free)
# KEY_R:
# player.auto_put_item()
KEY_Q:
+5 -2
View File
@@ -461,8 +461,11 @@ func spawn_powerups_around(center: Vector2i, force_powerups: bool = true):
if rng.randf() < 0.7:
item_id = rng.randi_range(7, 10)
else:
# 30% Chance for PowerUp (11-14)
item_id = rng.randi_range(11, 14)
# 30% Chance for PowerUp (Exclude Wall 13 only in Stop n Go)
if LobbyManager.game_mode == "Stop n Go":
item_id = [11, 12, 14].pick_random()
else:
item_id = rng.randi_range(11, 14)
var cell = Vector3i(pos.x, 1, pos.y)
+5 -3
View File
@@ -245,11 +245,13 @@ func _ensure_shortcut_label(btn: Button, button_name: String):
if btn.has_node("ShortcutLabel"):
# Update Label content if it exists to match potential remapping
var existing_lbl = btn.get_node("ShortcutLabel")
var is_sng = LobbyManager.game_mode == "Stop n Go"
match button_name:
"Grab": existing_lbl.text = "Space"
"Grab": existing_lbl.text = "Space" if is_sng else ""
"Put": existing_lbl.text = ""
"AttackMode": existing_lbl.text = "Q"
"SpawnBoost": existing_lbl.text = "E"
"AttackMode": existing_lbl.text = "Q" if is_sng else ""
"SpawnBoost": existing_lbl.text = "E" if is_sng else ""
return
# Add Keyboard Shortcut Label
+3
View File
@@ -50,7 +50,10 @@ static func get_tile_weights() -> Dictionary:
weights[tile] = STANDARD_WEIGHT
# Special tiles
var is_sng = LobbyManager.game_mode == "Stop n Go"
for tile in SPECIAL_TILES:
if is_sng and tile == TILE_FREEZE:
continue # Hide Wall Block only in Stop n Go
weights[tile] = special_weight
return weights
+17 -10
View File
@@ -29,7 +29,10 @@ func _ready():
# We use 0, 1, 2, 3 to match SpecialTilesManager.SpecialEffect enum
_setup_btn(0, container.get_node_or_null("SpeedBtn"))
_setup_btn(1, container.get_node_or_null("FreezeAreaBtn"))
_setup_btn(2, container.get_node_or_null("WallBtn"))
var wall_btn = container.get_node_or_null("WallBtn")
_setup_btn(2, wall_btn)
if wall_btn and LobbyManager.game_mode == "Stop n Go":
wall_btn.visible = false # Hide Wall Power-up only in Stop n Go
_setup_btn(3, container.get_node_or_null("GhostBtn"))
print("[PowerUpUI] UI Initialization Complete. Mapped %d buttons." % icon_containers.size())
@@ -103,16 +106,20 @@ func _setup_btn(effect_id: int, btn: Button):
sc_lbl.add_theme_color_override("font_color", Color(0.9, 0.9, 0.9))
# Determine Label Text based on Effect ID
# 0: Speed -> 1
# 2: Wall -> 2
# 1: Freeze -> 3
# 3: Ghost -> 4
var key_text = ""
match effect_id:
0: key_text = "1"
2: key_text = "2"
1: key_text = "3"
3: key_text = "4"
if LobbyManager.game_mode == "Stop n Go":
# Stop n Go Mapping: 1, 2, 3 (No Wall)
match effect_id:
0: key_text = "1"
1: key_text = "2"
3: key_text = "3"
else:
# Free Mode Mapping: 1, 2, 3, 4 (Original)
match effect_id:
0: key_text = "1"
2: key_text = "2"
1: key_text = "3"
3: key_text = "4"
sc_lbl.text = key_text
btn.add_child(sc_lbl)