update
This commit is contained in:
@@ -1,161 +1,95 @@
|
||||
extends Node
|
||||
|
||||
# PowerUpManager - Handles power-up points, holo tile tracking, and special effect usage
|
||||
# PowerUpManager - Handles Boost Meter (Time-based logic)
|
||||
# Note: Inventory logic is now in SpecialTilesManager + PlayerboardManager
|
||||
|
||||
const MAX_POINTS: int = 12
|
||||
const POINTS_PER_BAR: int = 4
|
||||
const MAX_BARS: int = 4
|
||||
const HOLO_PICKUPS_PER_BAR: int = 4
|
||||
const SPECIAL_COOLDOWN: float = 4.0 # 4 second cooldown
|
||||
const MAX_BOOST: float = 100.0
|
||||
const BASE_FILL_RATE: float = 4.0 # 4 points per second baseline (25s to full)
|
||||
|
||||
var player: Node3D
|
||||
var enhanced_gridmap: Node
|
||||
var goal_manager: Node
|
||||
|
||||
# Power-up state
|
||||
var current_points: int = 0
|
||||
var holo_pickup_count: int = 0
|
||||
var special_cooldown_timer: float = 0.0 # Current cooldown remaining
|
||||
# Boost State
|
||||
var current_boost: float = 0.0
|
||||
|
||||
signal points_changed(current: int, max_points: int)
|
||||
signal points_changed(current: int, max_points: int) # Reused for UI (int casting)
|
||||
signal bar_filled()
|
||||
signal effect_used()
|
||||
signal boost_reset()
|
||||
|
||||
func initialize(p_player: Node3D, p_gridmap: Node):
|
||||
player = p_player
|
||||
enhanced_gridmap = p_gridmap
|
||||
|
||||
# Find GoalManager
|
||||
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||
if main:
|
||||
goal_manager = main.get_node_or_null("GoalManager")
|
||||
|
||||
set_process(true)
|
||||
|
||||
func _process(delta):
|
||||
# Update cooldown timer
|
||||
if special_cooldown_timer > 0:
|
||||
special_cooldown_timer -= delta
|
||||
if not is_instance_valid(player) or not player.is_multiplayer_authority():
|
||||
return
|
||||
|
||||
# Only fill if not full
|
||||
if current_boost < MAX_BOOST:
|
||||
var multiplier = 1.0
|
||||
if goal_manager:
|
||||
# Use authority ID for lookup
|
||||
multiplier = goal_manager.get_boost_multiplier(player.get_multiplayer_authority())
|
||||
|
||||
current_boost += BASE_FILL_RATE * multiplier * delta
|
||||
current_boost = min(current_boost, MAX_BOOST)
|
||||
|
||||
# Update UI (Cast to int for compatibility with existing UI slider/bar)
|
||||
emit_signal("points_changed", int(current_boost), int(MAX_BOOST))
|
||||
|
||||
if current_boost >= MAX_BOOST:
|
||||
_on_boost_full()
|
||||
|
||||
# =============================================================================
|
||||
# Holo Tile Pickup
|
||||
# =============================================================================
|
||||
|
||||
func add_holo_pickup():
|
||||
"""Called when player picks up a holo tile (11-14)."""
|
||||
holo_pickup_count += 1
|
||||
|
||||
if holo_pickup_count >= HOLO_PICKUPS_PER_BAR:
|
||||
holo_pickup_count = 0
|
||||
_add_bar()
|
||||
|
||||
print("[PowerUp] Player %s picked up holo tile. Count: %d/4" % [player.name, holo_pickup_count])
|
||||
|
||||
if player.is_multiplayer_authority():
|
||||
rpc("sync_holo_count", holo_pickup_count, current_points)
|
||||
|
||||
func _add_bar():
|
||||
"""Add one full bar (4 points) of power-up."""
|
||||
var points_to_add = POINTS_PER_BAR
|
||||
current_points = min(current_points + points_to_add, MAX_POINTS)
|
||||
|
||||
func _on_boost_full():
|
||||
player.is_attack_mode = true
|
||||
emit_signal("bar_filled")
|
||||
emit_signal("points_changed", current_points, MAX_POINTS)
|
||||
|
||||
# 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])
|
||||
player.rpc("display_message", "ATTACK MODE READY!", 1)
|
||||
print("[PowerUp] Player %s Boost Full! Entering Attack Mode." % player.name)
|
||||
|
||||
if player.is_multiplayer_authority():
|
||||
player.get_node("PowerUpManager").rpc("sync_points", current_points)
|
||||
rpc("sync_boost", current_boost)
|
||||
|
||||
# =============================================================================
|
||||
# Goal Completion Reward
|
||||
# =============================================================================
|
||||
|
||||
func acquire_smash_bonus():
|
||||
"""Called when player is smashed. Grants 1 bar up to a max of 2 bars."""
|
||||
if get_bars() < 2:
|
||||
_add_bar()
|
||||
print("[PowerUp] Player %s gained smash bonus bar! Total: %d/%d" % [player.name, current_points, MAX_POINTS])
|
||||
else:
|
||||
print("[PowerUp] Player %s smash bonus capped (already has >= 2 bars)" % player.name)
|
||||
|
||||
func add_goal_completion_reward():
|
||||
"""Called when player completes a goal pattern. Awards 1 bar."""
|
||||
_add_bar()
|
||||
print("[PowerUp] Player %s completed goal - awarded 1 bar" % [player.name])
|
||||
|
||||
# =============================================================================
|
||||
# Using Special Effects
|
||||
# =============================================================================
|
||||
|
||||
func can_use_special() -> bool:
|
||||
"""Returns true if player has at least 1 bar (4 points) AND IS NOT ON COOLDOWN."""
|
||||
return current_points >= POINTS_PER_BAR and special_cooldown_timer <= 0
|
||||
|
||||
func get_bars() -> int:
|
||||
"""Returns current number of full bars."""
|
||||
return current_points / POINTS_PER_BAR
|
||||
|
||||
func use_special_effect():
|
||||
"""Consume 1 bar and trigger a random special effect."""
|
||||
if not can_use_special():
|
||||
# Type 3 = WARNING message
|
||||
player.rpc("display_message", "Not enough power-up!", 3)
|
||||
return false
|
||||
|
||||
# Check cooldown
|
||||
if special_cooldown_timer > 0:
|
||||
player.rpc("display_message", "Special on cooldown! (%.1fs)" % special_cooldown_timer, 3)
|
||||
return false
|
||||
|
||||
# Consume 1 bar
|
||||
current_points -= POINTS_PER_BAR
|
||||
emit_signal("effect_used")
|
||||
emit_signal("points_changed", current_points, MAX_POINTS)
|
||||
|
||||
# Start cooldown
|
||||
special_cooldown_timer = SPECIAL_COOLDOWN
|
||||
|
||||
# Play special animation (backflip) - synced across network
|
||||
if player.is_multiplayer_authority() and player.has_method("sync_special_animation"):
|
||||
player.rpc("sync_special_animation")
|
||||
|
||||
# Trigger random special effect via SpecialTilesManager
|
||||
var special_tiles_manager = player.get_node_or_null("SpecialTilesManager")
|
||||
if special_tiles_manager:
|
||||
special_tiles_manager.trigger_random_effect()
|
||||
|
||||
print("[PowerUp] Player %s used special effect! Remaining: %d/%d points, Cooldown: %.1fs" % [player.name, current_points, MAX_POINTS, SPECIAL_COOLDOWN])
|
||||
func reset_boost():
|
||||
current_boost = 0.0
|
||||
player.is_attack_mode = false
|
||||
emit_signal("points_changed", 0, int(MAX_BOOST))
|
||||
emit_signal("boost_reset")
|
||||
|
||||
if player.is_multiplayer_authority():
|
||||
rpc("sync_points", current_points)
|
||||
|
||||
return true
|
||||
rpc("sync_boost", 0.0)
|
||||
|
||||
# =============================================================================
|
||||
# Sync
|
||||
# =============================================================================
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func sync_holo_count(count: int, points: int):
|
||||
holo_pickup_count = count
|
||||
current_points = points
|
||||
emit_signal("points_changed", current_points, MAX_POINTS)
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func sync_points(points: int):
|
||||
current_points = points
|
||||
emit_signal("points_changed", current_points, MAX_POINTS)
|
||||
func sync_boost(value: float):
|
||||
current_boost = value
|
||||
emit_signal("points_changed", int(current_boost), int(MAX_BOOST))
|
||||
|
||||
# Client-side Attack Mode visual check (?)
|
||||
if current_boost >= MAX_BOOST:
|
||||
# Could trigger visual effect here
|
||||
pass
|
||||
|
||||
# =============================================================================
|
||||
# Getters
|
||||
# =============================================================================
|
||||
|
||||
func get_points() -> int:
|
||||
return current_points
|
||||
return int(current_boost)
|
||||
|
||||
func get_max_points() -> int:
|
||||
return MAX_POINTS
|
||||
return int(MAX_BOOST)
|
||||
|
||||
func get_fill_percentage() -> float:
|
||||
return float(current_points) / float(MAX_POINTS)
|
||||
return current_boost / MAX_BOOST
|
||||
|
||||
func reset():
|
||||
current_points = 0
|
||||
holo_pickup_count = 0
|
||||
emit_signal("points_changed", current_points, MAX_POINTS)
|
||||
|
||||
Reference in New Issue
Block a user