feat: Implement core game managers for power-ups, UI, goals, and player actions, and establish initial game scene and player.
This commit is contained in:
@@ -2,7 +2,7 @@ extends Node
|
||||
|
||||
# GoalsCycleManager - Handles 60-second goal cycles, scoring, and goal regeneration
|
||||
|
||||
const CYCLE_DURATION: float = 60.0
|
||||
const CYCLE_DURATION: float = 30.0
|
||||
const BASE_SCORE: int = 100
|
||||
const TIME_BONUS_MULTIPLIER: float = 2.0
|
||||
|
||||
@@ -126,6 +126,10 @@ func on_goal_completed(player: Node, time_remaining: float):
|
||||
# Sync score to all clients
|
||||
rpc("sync_player_score", peer_id, player_scores[peer_id])
|
||||
|
||||
# Clear playerboard tiles (they convert to powerup bar reward)
|
||||
player.playerboard.fill(-1)
|
||||
player.rpc("sync_playerboard", player.playerboard)
|
||||
|
||||
# Regenerate goals for this player
|
||||
regenerate_goals_for_player(player)
|
||||
|
||||
|
||||
@@ -21,22 +21,17 @@ func consume_action_points(points: int):
|
||||
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||
if not main:
|
||||
return
|
||||
|
||||
# Don't consume points for bots in non-turn-based mode
|
||||
if player.is_bot == true and not TurnManager.turn_based_mode:
|
||||
|
||||
# Non-turn-based mode: unlimited action points for real-time fast-paced gameplay
|
||||
if not TurnManager.turn_based_mode:
|
||||
after_action_completed()
|
||||
return
|
||||
|
||||
# Turn-based mode: consume action points normally
|
||||
player.action_points -= points
|
||||
|
||||
if player.action_points <= 0:
|
||||
if TurnManager.turn_based_mode:
|
||||
main.request_next_turn()
|
||||
else:
|
||||
player.action_points = 2
|
||||
player.has_performed_action = false
|
||||
player.has_moved_this_turn = false
|
||||
player.rpc("display_message", "Action Points Reset!")
|
||||
main.request_next_turn()
|
||||
|
||||
after_action_completed()
|
||||
|
||||
@@ -55,12 +50,6 @@ func after_action_completed():
|
||||
if multiplayer.get_unique_id() == player.get_multiplayer_authority():
|
||||
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||
if main:
|
||||
# Add this condition for bots
|
||||
if not TurnManager.turn_based_mode and (player.action_points <= 0 or player.is_bot):
|
||||
player.action_points = 20 # For bots in non-turn-based mode, this will keep refreshing
|
||||
player.has_performed_action = false
|
||||
player.has_moved_this_turn = false
|
||||
|
||||
main.ui_manager.update_button_states()
|
||||
main.ui_manager.update_playerboard_ui()
|
||||
|
||||
|
||||
@@ -47,7 +47,8 @@ func _add_bar():
|
||||
emit_signal("bar_filled")
|
||||
emit_signal("points_changed", current_points, MAX_POINTS)
|
||||
|
||||
player.rpc("display_message", "Power-up bar filled!")
|
||||
# Type 1 = POWERUP message for special styling
|
||||
player.rpc("display_message", "Power-up bar filled!", 1)
|
||||
print("[PowerUp] Player %s gained 1 bar! Total: %d/%d points" % [player.name, current_points, MAX_POINTS])
|
||||
|
||||
# =============================================================================
|
||||
@@ -74,7 +75,8 @@ func get_bars() -> int:
|
||||
func use_special_effect():
|
||||
"""Consume 1 bar and trigger a random special effect."""
|
||||
if not can_use_special():
|
||||
player.rpc("display_message", "Not enough power-up!")
|
||||
# Type 3 = WARNING message
|
||||
player.rpc("display_message", "Not enough power-up!", 3)
|
||||
return false
|
||||
|
||||
# Consume 1 bar
|
||||
|
||||
@@ -97,6 +97,13 @@ func update_playerboard_ui():
|
||||
if not local_player_character:
|
||||
return
|
||||
|
||||
# Center 3x3 slot indices in a 5x5 grid (0-indexed)
|
||||
# Row 1: 6, 7, 8
|
||||
# Row 2: 11, 12, 13
|
||||
# Row 3: 16, 17, 18
|
||||
var center_slots = [6, 7, 8, 11, 12, 13, 16, 17, 18]
|
||||
var goals = local_player_character.goals if local_player_character.goals else []
|
||||
|
||||
for i in range(25):
|
||||
var slot = playerboard_ui.get_child(i)
|
||||
|
||||
@@ -106,13 +113,43 @@ func update_playerboard_ui():
|
||||
|
||||
var item = local_player_character.playerboard[i]
|
||||
|
||||
# Default texture (empty)
|
||||
slot.texture = item_tex[0]
|
||||
slot.modulate = Color.WHITE
|
||||
|
||||
match item:
|
||||
7: slot.texture = item_tex[1]
|
||||
8: slot.texture = item_tex[2]
|
||||
9: slot.texture = item_tex[3]
|
||||
10: slot.texture = item_tex[4]
|
||||
# Check if this is a center slot that should show a goal
|
||||
var center_index = center_slots.find(i)
|
||||
if center_index != -1 and center_index < goals.size():
|
||||
var goal_value = goals[center_index]
|
||||
|
||||
# Check if player has collected this tile
|
||||
var _has_tile = item == goal_value
|
||||
|
||||
if item != -1:
|
||||
# Player has a tile in this slot - show it at full brightness
|
||||
match item:
|
||||
7: slot.texture = item_tex[1]
|
||||
8: slot.texture = item_tex[2]
|
||||
9: slot.texture = item_tex[3]
|
||||
10: slot.texture = item_tex[4]
|
||||
slot.modulate = Color.WHITE
|
||||
else:
|
||||
# Show goal tile dimmed (not collected yet)
|
||||
match goal_value:
|
||||
7: slot.texture = item_tex[1]
|
||||
8: slot.texture = item_tex[2]
|
||||
9: slot.texture = item_tex[3]
|
||||
10: slot.texture = item_tex[4]
|
||||
_: slot.texture = item_tex[0]
|
||||
# Dim uncollected goals with black overlay
|
||||
slot.modulate = Color(0.3, 0.3, 0.3, 1.0)
|
||||
else:
|
||||
# Non-center slot - just show playerboard item normally
|
||||
match item:
|
||||
7: slot.texture = item_tex[1]
|
||||
8: slot.texture = item_tex[2]
|
||||
9: slot.texture = item_tex[3]
|
||||
10: slot.texture = item_tex[4]
|
||||
|
||||
func update_button_states():
|
||||
if not local_player_character or local_player_character.is_in_group("Bots"):
|
||||
@@ -184,7 +221,7 @@ func setup_powerup_bar_ui(main_node):
|
||||
segment.add_theme_stylebox_override("panel", style)
|
||||
powerup_segments.append(segment)
|
||||
|
||||
func update_powerup_bar(current_points: int, max_points: int):
|
||||
func update_powerup_bar(current_points: int, _max_points: int):
|
||||
"""Update battery segments based on current power-up points."""
|
||||
var bars_filled = current_points / 4 # 4 points per bar
|
||||
|
||||
@@ -201,9 +238,30 @@ func update_powerup_bar(current_points: int, max_points: int):
|
||||
|
||||
segment.add_theme_stylebox_override("panel", style)
|
||||
|
||||
var _previous_bars: int = 0
|
||||
|
||||
func _on_powerup_points_changed(current: int, max_points: int):
|
||||
var new_bars = current / 4
|
||||
|
||||
# Detect if a new bar was filled
|
||||
if new_bars > _previous_bars and powerup_bar:
|
||||
# Pulse effect on newly filled segment
|
||||
var segment_index = new_bars - 1
|
||||
if segment_index >= 0 and segment_index < powerup_segments.size():
|
||||
var segment = powerup_segments[segment_index]
|
||||
_pulse_segment(segment)
|
||||
|
||||
_previous_bars = new_bars
|
||||
update_powerup_bar(current, max_points)
|
||||
|
||||
func _pulse_segment(segment: Panel):
|
||||
"""Create a visual pulse effect on a powerup segment."""
|
||||
var original_scale = segment.scale
|
||||
var tween = segment.create_tween()
|
||||
tween.set_loops(2)
|
||||
tween.tween_property(segment, "scale", Vector2(1.3, 1.3), 0.1).set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT)
|
||||
tween.tween_property(segment, "scale", original_scale, 0.15).set_trans(Tween.TRANS_SINE)
|
||||
|
||||
# =============================================================================
|
||||
# Leaderboard UI
|
||||
# =============================================================================
|
||||
|
||||
Reference in New Issue
Block a user