Files
tekton/scripts/managers/powerup_manager.gd
T
2026-02-02 00:21:32 +08:00

130 lines
3.6 KiB
GDScript

extends Node
# PowerUpManager - Handles Boost Meter (Time-based logic)
# Note: Inventory logic is now in SpecialTilesManager + PlayerboardManager
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
# Boost State
var current_boost: float = 0.0
# Alias for compatibility with BotStrategicPlanner
var current_points: float:
get:
return current_boost
set(value):
current_boost = value
# Also alias MAX_POINTS
const MAX_POINTS = MAX_BOOST
signal points_changed(current: int, max_points: int) # Reused for UI (int casting)
signal bar_filled()
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):
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()
func _on_boost_full():
player.is_attack_mode = true
emit_signal("bar_filled")
NotificationManager.send_message(player, NotificationManager.MESSAGES.ATTACK_MODE_READY, NotificationManager.MessageType.POWERUP)
print("[PowerUp] Player %s Boost Full! Entering Attack Mode." % player.name)
if player.is_multiplayer_authority():
rpc("sync_boost", current_boost)
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_boost", 0.0)
# =============================================================================
# Sync
# =============================================================================
@rpc("any_peer", "call_local", "reliable")
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 int(current_boost)
func get_max_points() -> int:
return int(MAX_BOOST)
func get_fill_percentage() -> float:
return current_boost / MAX_BOOST
func can_use_special() -> bool:
return current_boost >= MAX_BOOST
func use_special_effect() -> bool:
if not can_use_special():
return false
# Consume boost
reset_boost()
return true
func acquire_smash_bonus():
current_boost += 25.0 # Add 25% boost
current_boost = min(current_boost, MAX_BOOST)
emit_signal("points_changed", int(current_boost), int(MAX_BOOST))
if current_boost >= MAX_BOOST:
_on_boost_full()
func add_goal_completion_reward():
current_boost += 50.0 # Reward for completing goal
current_boost = min(current_boost, MAX_BOOST)
emit_signal("points_changed", int(current_boost), int(MAX_BOOST))
if current_boost >= MAX_BOOST:
_on_boost_full()