feat: introduce core player logic with manager integration and power-up inventory UI.
This commit is contained in:
@@ -26,7 +26,6 @@ const FREEZE_SLOW_DURATION = 3.0
|
||||
signal cooldown_updated(effect: int, time_left: float, max_time: float)
|
||||
signal powerup_unlocked(effect: int, level: int)
|
||||
|
||||
var wall_orientation_horizontal: bool = false # False = Vertical, True = Horizontal
|
||||
|
||||
# New Helper functions for Targeting and Preview
|
||||
|
||||
@@ -35,28 +34,12 @@ func get_skill_affected_area(effect: int, center_pos: Vector2i) -> Array[Vector2
|
||||
|
||||
match effect:
|
||||
SpecialEffect.AREA_FREEZE:
|
||||
var current_lvl = powerup_levels.get(SpecialEffect.AREA_FREEZE, 1)
|
||||
var radius = 1
|
||||
if current_lvl >= 5:
|
||||
radius = 2
|
||||
|
||||
for x in range(-radius, radius + 1):
|
||||
for y in range(-radius, radius + 1):
|
||||
var pos = center_pos + Vector2i(x, y)
|
||||
# Validate bounds
|
||||
if enhanced_gridmap.is_position_valid(pos):
|
||||
area.append(pos)
|
||||
# Preview 3 blocks ahead of current hover (if we ever re-enable targeting)
|
||||
area.append(center_pos)
|
||||
|
||||
SpecialEffect.BLOCK_FLOOR:
|
||||
# Logic: Based on toggled orientation state
|
||||
var is_horizontal = wall_orientation_horizontal
|
||||
|
||||
if is_horizontal:
|
||||
for x in range(enhanced_gridmap.columns):
|
||||
area.append(Vector2i(x, center_pos.y))
|
||||
else:
|
||||
for z in range(enhanced_gridmap.rows):
|
||||
area.append(Vector2i(center_pos.x, z))
|
||||
# Preview just the single block
|
||||
area.append(center_pos)
|
||||
|
||||
return area
|
||||
|
||||
@@ -143,12 +126,8 @@ func get_effect_from_item(item_id: int) -> int:
|
||||
|
||||
match item_id:
|
||||
11: return SpecialEffect.FASTER_SPEED
|
||||
12:
|
||||
if is_restricted: return -1
|
||||
return SpecialEffect.AREA_FREEZE
|
||||
13:
|
||||
if is_restricted: return -1
|
||||
return SpecialEffect.BLOCK_FLOOR
|
||||
12: return SpecialEffect.AREA_FREEZE
|
||||
13: return SpecialEffect.BLOCK_FLOOR
|
||||
14: return SpecialEffect.INVISIBLE_MODE
|
||||
_: return -1
|
||||
|
||||
@@ -231,32 +210,11 @@ func activate_effect(effect: int, target_player: Node3D = null):
|
||||
SpecialEffect.FASTER_SPEED:
|
||||
_execute_faster_speed()
|
||||
SpecialEffect.AREA_FREEZE, SpecialEffect.BLOCK_FLOOR:
|
||||
# Enter Targeting Mode instead of executing immediately (ONLY for human players)
|
||||
if not (player.is_bot or player.is_in_group("Bots")):
|
||||
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||
if main and main.ui_manager:
|
||||
# Toggle Logic for Wall Block
|
||||
if main.ui_manager.current_action_state == main.ui_manager.ActionState.TARGETING and main.ui_manager.pending_skill_id == effect:
|
||||
if effect == SpecialEffect.BLOCK_FLOOR:
|
||||
toggle_wall_orientation()
|
||||
powerup_cooldowns[effect] = 0.0 # Revert cooldown
|
||||
emit_signal("cooldown_updated", effect, 0.0, 0.0)
|
||||
return
|
||||
|
||||
main.ui_manager.current_action_state = main.ui_manager.ActionState.TARGETING
|
||||
main.ui_manager.pending_skill_id = effect
|
||||
|
||||
var msg = "Select a target area..."
|
||||
if effect == SpecialEffect.BLOCK_FLOOR:
|
||||
msg = "Click again to toggle Vertical/Horizontal"
|
||||
|
||||
NotificationManager.send_message(player, msg, NotificationManager.MessageType.NORMAL)
|
||||
# Do NOT set cooldown yet. Cooldown sets on execution.
|
||||
# Revert the cooldown set above (hacky but handles the split flow)
|
||||
powerup_cooldowns[effect] = 0.0
|
||||
emit_signal("cooldown_updated", effect, 0.0, 0.0)
|
||||
print("[SpecialTiles] Entered Targeting Mode for %s" % SpecialEffect.keys()[effect])
|
||||
return # Exit, wait for input
|
||||
# Execute immediately based on direction instead of entering Targeting Mode
|
||||
if effect == SpecialEffect.BLOCK_FLOOR:
|
||||
_execute_block_floor()
|
||||
else:
|
||||
_execute_area_freeze()
|
||||
SpecialEffect.INVISIBLE_MODE:
|
||||
_execute_invisible_mode(player)
|
||||
|
||||
@@ -284,13 +242,33 @@ func _execute_faster_speed():
|
||||
active_buffs[SpecialEffect.FASTER_SPEED] = FASTER_DURATION
|
||||
NotificationManager.send_message(player, "Speed Boost! (5s)", NotificationManager.MessageType.POWERUP)
|
||||
|
||||
func _execute_area_freeze(center_pos: Vector2i = Vector2i.ZERO):
|
||||
func _execute_area_freeze(target_pos: Vector2i = Vector2i.ZERO):
|
||||
var center_pos = target_pos
|
||||
|
||||
# Determine Level early for distance calculation
|
||||
var current_lvl = powerup_levels.get(SpecialEffect.AREA_FREEZE, 1)
|
||||
|
||||
if center_pos == Vector2i.ZERO:
|
||||
# Fallback to old behavior if no target provided (or error)
|
||||
return
|
||||
# Calculate distance ahead based on Level
|
||||
# Gap of 3 floors = 4 tiles ahead
|
||||
# Gap of 5 floors = 6 tiles ahead
|
||||
var distance = 4 if current_lvl < 5 else 6
|
||||
|
||||
var movement = player.movement_manager
|
||||
if movement and movement.current_move_direction != Vector2i.ZERO:
|
||||
center_pos = player.current_position + movement.current_move_direction * distance
|
||||
else:
|
||||
# Fallback if standing still
|
||||
var last_dir = player.movement_manager.last_move_direction if movement else Vector2i(0, 1)
|
||||
center_pos = player.current_position + last_dir * distance
|
||||
|
||||
if not enhanced_gridmap.is_position_valid(center_pos):
|
||||
# Try a bit closer if out of bounds
|
||||
center_pos = player.current_position + (center_pos - player.current_position).normalized() * 1.0
|
||||
if not enhanced_gridmap.is_position_valid(center_pos):
|
||||
return
|
||||
|
||||
# 3. Determine Radius based on Level
|
||||
var current_lvl = powerup_levels.get(SpecialEffect.AREA_FREEZE, 1)
|
||||
var radius = 1
|
||||
if current_lvl >= 5:
|
||||
radius = 2 # Bigger area at high levels
|
||||
@@ -366,29 +344,29 @@ func _execute_area_freeze(center_pos: Vector2i = Vector2i.ZERO):
|
||||
main.rpc("sync_grid_items_batch", restore_batch)
|
||||
)
|
||||
|
||||
func toggle_wall_orientation():
|
||||
wall_orientation_horizontal = !wall_orientation_horizontal
|
||||
var mode_str = "HORIZONTAL" if wall_orientation_horizontal else "VERTICAL"
|
||||
NotificationManager.send_message(player, "Wall Mode: " + mode_str, NotificationManager.MessageType.NORMAL)
|
||||
|
||||
func _execute_block_floor(target_pos: Vector2i):
|
||||
# "Wall Block"
|
||||
var is_horizontal = wall_orientation_horizontal
|
||||
func _execute_block_floor(target_pos: Vector2i = Vector2i.ZERO):
|
||||
# "Wall Block" - Spawn line behind player
|
||||
var behind_pos = target_pos
|
||||
var last_dir = player.movement_manager.last_move_direction if player.movement_manager else Vector2i(0, 1)
|
||||
|
||||
if behind_pos == Vector2i.ZERO:
|
||||
behind_pos = player.current_position - last_dir
|
||||
|
||||
if not enhanced_gridmap.is_position_valid(behind_pos):
|
||||
return
|
||||
|
||||
print("Player %s activated Wall Block behind at %s" % [player.name, behind_pos])
|
||||
|
||||
var neighbors = []
|
||||
|
||||
if is_horizontal:
|
||||
# Block entire Row (Fixed Z, iterate all X)
|
||||
var row_z = target_pos.y
|
||||
for x in range(enhanced_gridmap.columns):
|
||||
neighbors.append({"position": Vector2i(x, row_z)})
|
||||
print("Player %s activated Wall Block: HORIZONTAL ROW (Z=%d)" % [player.name, row_z])
|
||||
else:
|
||||
# Block entire Column (Fixed X, iterate all Z)
|
||||
var col_x = target_pos.x
|
||||
if last_dir.x != 0:
|
||||
# Moving on X-axis (Columns) -> Vertical Wall (Fixed X, all Z)
|
||||
for z in range(enhanced_gridmap.rows):
|
||||
neighbors.append({"position": Vector2i(col_x, z)})
|
||||
print("Player %s activated Wall Block: VERTICAL COLUMN (X=%d)" % [player.name, col_x])
|
||||
neighbors.append({"position": Vector2i(behind_pos.x, z)})
|
||||
else:
|
||||
# Moving on Z-axis (Rows) -> Horizontal Wall (Fixed Z, all X)
|
||||
for x in range(enhanced_gridmap.columns):
|
||||
neighbors.append({"position": Vector2i(x, behind_pos.y)})
|
||||
|
||||
if player.is_multiplayer_authority():
|
||||
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||
@@ -420,10 +398,7 @@ func _execute_block_floor(target_pos: Vector2i):
|
||||
main.rpc("sync_grid_items_batch", batch_data)
|
||||
|
||||
# Notify
|
||||
var all_players = player.get_tree().get_nodes_in_group("Players")
|
||||
for p in all_players:
|
||||
if p.current_position == target_pos:
|
||||
NotificationManager.send_message(p, "Wall Block Created!", NotificationManager.MessageType.POWERUP)
|
||||
NotificationManager.send_message(player, "Defensive Wall Deployed!", NotificationManager.MessageType.POWERUP)
|
||||
|
||||
func _execute_invisible_mode(target: Node3D):
|
||||
target.is_invisible = true
|
||||
|
||||
Reference in New Issue
Block a user