feat: Add player action and input managers to handle player actions, movement, targeting, and visual feedback.
This commit is contained in:
+5
-2
@@ -1411,6 +1411,9 @@ func auto_put_item() -> bool:
|
|||||||
@rpc("any_peer", "call_local", "reliable")
|
@rpc("any_peer", "call_local", "reliable")
|
||||||
func force_action_state_none():
|
func force_action_state_none():
|
||||||
# This is called by the server on the client to reset the UI
|
# This is called by the server on the client to reset the UI
|
||||||
|
if is_bot or is_in_group("Bots"):
|
||||||
|
return
|
||||||
|
|
||||||
var main = get_tree().get_root().get_node_or_null("Main")
|
var main = get_tree().get_root().get_node_or_null("Main")
|
||||||
if main and main.ui_manager:
|
if main and main.ui_manager:
|
||||||
main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE
|
main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE
|
||||||
@@ -1524,8 +1527,8 @@ func has_items_in_playerboard() -> bool:
|
|||||||
func playerboard_is_full() -> bool:
|
func playerboard_is_full() -> bool:
|
||||||
return playerboard.find(-1) == -1
|
return playerboard.find(-1) == -1
|
||||||
|
|
||||||
func highlight_cells_if_authorized(cells_to_highlight: Array):
|
func highlight_cells_if_authorized(cells_to_highlight: Array, item_id: int = -1):
|
||||||
action_manager.highlight_cells_if_authorized(cells_to_highlight)
|
action_manager.highlight_cells_if_authorized(cells_to_highlight, item_id)
|
||||||
|
|
||||||
# Update highlight_movement_range to respect the expanded obstacle blocking
|
# Update highlight_movement_range to respect the expanded obstacle blocking
|
||||||
func highlight_movement_range():
|
func highlight_movement_range():
|
||||||
|
|||||||
@@ -71,16 +71,23 @@ func after_action_completed():
|
|||||||
# Highlight Operations
|
# Highlight Operations
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
func highlight_cells_if_authorized(cells_to_highlight: Array):
|
func highlight_cells_if_authorized(cells_to_highlight: Array, item_id: int = -1):
|
||||||
if not player.is_multiplayer_authority() or player.is_bot or player.is_in_group("Bots"):
|
if not player.is_multiplayer_authority() or player.is_bot or player.is_in_group("Bots"):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Start with fresh highlights if logical state changes?
|
||||||
|
# But dragging mouse calls this every frame. We need to clear previous calls.
|
||||||
|
# The simplistic clear_highlights() clears ALL highlights.
|
||||||
|
# Which is fine for targeting mode as we only highlight the target area.
|
||||||
clear_highlights()
|
clear_highlights()
|
||||||
|
|
||||||
|
var highlight_item = item_id if item_id != -1 else enhanced_gridmap.hover_item
|
||||||
|
|
||||||
for cell in cells_to_highlight:
|
for cell in cells_to_highlight:
|
||||||
highlighted_cells.append(cell)
|
highlighted_cells.append(cell)
|
||||||
enhanced_gridmap.set_cell_item(
|
enhanced_gridmap.set_cell_item(
|
||||||
Vector3i(cell.x, 0, cell.y),
|
Vector3i(cell.x, 0, cell.y),
|
||||||
enhanced_gridmap.hover_item
|
highlight_item
|
||||||
)
|
)
|
||||||
|
|
||||||
func highlight_empty_adjacent_cells():
|
func highlight_empty_adjacent_cells():
|
||||||
|
|||||||
@@ -55,6 +55,31 @@ func _process(delta):
|
|||||||
player.attempt_target_action(2)
|
player.attempt_target_action(2)
|
||||||
elif Input.is_key_pressed(KEY_4):
|
elif Input.is_key_pressed(KEY_4):
|
||||||
player.attempt_target_action(3)
|
player.attempt_target_action(3)
|
||||||
|
|
||||||
|
# Targeting Mode Preview
|
||||||
|
var main = player.get_node_or_null("/root/Main")
|
||||||
|
if main and main.ui_manager and main.ui_manager.current_action_state == main.ui_manager.ActionState.TARGETING:
|
||||||
|
# Use mouse position raycast to determine hover
|
||||||
|
var viewport = player.get_viewport()
|
||||||
|
var mouse_pos = viewport.get_mouse_position()
|
||||||
|
var camera = viewport.get_camera_3d()
|
||||||
|
var from = camera.project_ray_origin(mouse_pos)
|
||||||
|
var to = from + camera.project_ray_normal(mouse_pos) * 1000
|
||||||
|
var hover_grid = player.raycast_to_grid(from, to)
|
||||||
|
|
||||||
|
# print("Targeting Hover: %s, Skill: %d" % [hover_grid, main.ui_manager.pending_skill_id]) # Debug
|
||||||
|
|
||||||
|
# Only update if valid position
|
||||||
|
if hover_grid != Vector2i(-1, -1):
|
||||||
|
var st_manager = player.get_node_or_null("SpecialTilesManager")
|
||||||
|
if st_manager:
|
||||||
|
var area = st_manager.get_skill_affected_area(main.ui_manager.pending_skill_id, hover_grid)
|
||||||
|
|
||||||
|
# Choose highlight color/mesh based on skill
|
||||||
|
# User Request: Use default hover item (1)
|
||||||
|
var highlight_id = 1
|
||||||
|
|
||||||
|
player.highlight_cells_if_authorized(area, highlight_id)
|
||||||
|
|
||||||
func handle_unhandled_input(event):
|
func handle_unhandled_input(event):
|
||||||
# Early return if not authorized human player
|
# Early return if not authorized human player
|
||||||
@@ -120,6 +145,19 @@ func handle_grid_click(grid_position: Vector2i):
|
|||||||
main.ui_manager.ActionState.RANDOMIZING:
|
main.ui_manager.ActionState.RANDOMIZING:
|
||||||
if grid_position in player.highlighted_cells:
|
if grid_position in player.highlighted_cells:
|
||||||
main.randomize_item_at_position(grid_position)
|
main.randomize_item_at_position(grid_position)
|
||||||
|
# Add TARGETING State
|
||||||
|
main.ui_manager.ActionState.TARGETING:
|
||||||
|
var skill_id = main.ui_manager.pending_skill_id
|
||||||
|
if skill_id != -1:
|
||||||
|
var st_manager = player.get_node_or_null("SpecialTilesManager")
|
||||||
|
if st_manager:
|
||||||
|
# Clear Highlights FIRST to avoid overwriting the newly placed tiles
|
||||||
|
player.clear_highlights()
|
||||||
|
|
||||||
|
st_manager.execute_targeted_effect(skill_id, grid_position)
|
||||||
|
# Reset state
|
||||||
|
main.ui_manager.pending_skill_id = -1
|
||||||
|
main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE
|
||||||
|
|
||||||
|
|
||||||
func handle_slot_gui_input(event, slot_index, slot_ui) -> int:
|
func handle_slot_gui_input(event, slot_index, slot_ui) -> int:
|
||||||
|
|||||||
@@ -26,7 +26,68 @@ const FREEZE_SLOW_DURATION = 3.0
|
|||||||
signal cooldown_updated(effect: int, time_left: float, max_time: float)
|
signal cooldown_updated(effect: int, time_left: float, max_time: float)
|
||||||
signal powerup_unlocked(effect: int, level: int)
|
signal powerup_unlocked(effect: int, level: int)
|
||||||
|
|
||||||
|
# New Helper functions for Targeting and Preview
|
||||||
|
|
||||||
|
func get_skill_affected_area(effect: int, center_pos: Vector2i) -> Array[Vector2i]:
|
||||||
|
var area: Array[Vector2i] = []
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
SpecialEffect.BLOCK_FLOOR:
|
||||||
|
# Logic: Perpendicular to player direction or based on major axis difference
|
||||||
|
var diff = center_pos - player.current_position
|
||||||
|
var is_horizontal = false
|
||||||
|
if abs(diff.x) > abs(diff.y):
|
||||||
|
is_horizontal = false # Vertical Column
|
||||||
|
else:
|
||||||
|
is_horizontal = true # Horizontal Row
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
return area
|
||||||
|
|
||||||
|
func execute_targeted_effect(effect: int, target_pos: Vector2i):
|
||||||
|
# Apply Cooldown NOW
|
||||||
|
var level = powerup_levels.get(effect, 1)
|
||||||
|
var cooldown_time = COOLDOWN_L1 + ((level - 1) * (COOLDOWN_L8 - COOLDOWN_L1) / 7.0)
|
||||||
|
powerup_cooldowns[effect] = cooldown_time
|
||||||
|
emit_signal("cooldown_updated", effect, cooldown_time, cooldown_time)
|
||||||
|
|
||||||
|
print("[SpecialTiles] Executing Targeted Effect %s at %s" % [SpecialEffect.keys()[effect], target_pos])
|
||||||
|
|
||||||
|
match effect:
|
||||||
|
SpecialEffect.AREA_FREEZE:
|
||||||
|
_execute_area_freeze(target_pos)
|
||||||
|
SpecialEffect.BLOCK_FLOOR:
|
||||||
|
_execute_block_floor(target_pos)
|
||||||
|
|
||||||
|
# Animation / Shake
|
||||||
|
if player.is_multiplayer_authority():
|
||||||
|
player.rpc("trigger_screen_shake", "light")
|
||||||
|
# Also reset action loop?
|
||||||
|
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||||
|
if main and main.ui_manager:
|
||||||
|
main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE
|
||||||
|
|
||||||
# Random shape patterns for 3x3 area (relative offsets from center)
|
# Random shape patterns for 3x3 area (relative offsets from center)
|
||||||
|
|
||||||
const PATTERNS = {
|
const PATTERNS = {
|
||||||
"T": [Vector2i(0, -1), Vector2i(-1, 0), Vector2i(0, 0), Vector2i(1, 0)],
|
"T": [Vector2i(0, -1), Vector2i(-1, 0), Vector2i(0, 0), Vector2i(1, 0)],
|
||||||
"L": [Vector2i(0, -1), Vector2i(0, 0), Vector2i(0, 1), Vector2i(1, 1)],
|
"L": [Vector2i(0, -1), Vector2i(0, 0), Vector2i(0, 1), Vector2i(1, 1)],
|
||||||
@@ -159,12 +220,21 @@ func activate_effect(effect: int, target_player: Node3D = null):
|
|||||||
match effect:
|
match effect:
|
||||||
SpecialEffect.FASTER_SPEED:
|
SpecialEffect.FASTER_SPEED:
|
||||||
_execute_faster_speed()
|
_execute_faster_speed()
|
||||||
SpecialEffect.AREA_FREEZE:
|
SpecialEffect.AREA_FREEZE, SpecialEffect.BLOCK_FLOOR:
|
||||||
_execute_area_freeze()
|
# Enter Targeting Mode instead of executing immediately
|
||||||
SpecialEffect.BLOCK_FLOOR:
|
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||||
_execute_block_floor(target_player if target_player else player) # Self or Target? Usually defensive wall? "Wall Block"
|
if main and main.ui_manager:
|
||||||
|
main.ui_manager.current_action_state = main.ui_manager.ActionState.TARGETING
|
||||||
|
main.ui_manager.pending_skill_id = effect
|
||||||
|
NotificationManager.send_message(player, "Select a target area...", 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
|
||||||
SpecialEffect.INVISIBLE_MODE:
|
SpecialEffect.INVISIBLE_MODE:
|
||||||
_execute_invisible_mode(player) # Or whatever ID 14 is
|
_execute_invisible_mode(player)
|
||||||
|
|
||||||
# Play generic cast animation or sound?
|
# Play generic cast animation or sound?
|
||||||
if player.is_multiplayer_authority():
|
if player.is_multiplayer_authority():
|
||||||
@@ -190,50 +260,32 @@ func _execute_faster_speed():
|
|||||||
active_buffs[SpecialEffect.FASTER_SPEED] = FASTER_DURATION
|
active_buffs[SpecialEffect.FASTER_SPEED] = FASTER_DURATION
|
||||||
NotificationManager.send_message(player, "Speed Boost! (5s)", NotificationManager.MessageType.POWERUP)
|
NotificationManager.send_message(player, "Speed Boost! (5s)", NotificationManager.MessageType.POWERUP)
|
||||||
|
|
||||||
func _execute_area_freeze():
|
func _execute_area_freeze(center_pos: Vector2i = Vector2i.ZERO):
|
||||||
# "area with blue like wall but with far away from the player who use it"
|
if center_pos == Vector2i.ZERO:
|
||||||
# "Make it like 4 floor first (offset 4) and the continue to bigger when the level... is close to max"
|
# Fallback to old behavior if no target provided (or error)
|
||||||
|
return
|
||||||
# 1. Calculate Forward Direction based on Rotation
|
|
||||||
# Rotation 0 = South (+Z), PI = North (-Z)
|
|
||||||
var rot = player.rotation.y
|
|
||||||
var forward_x = round(sin(rot))
|
|
||||||
var forward_z = round(cos(rot))
|
|
||||||
var forward_vec = Vector2i(forward_x, forward_z)
|
|
||||||
|
|
||||||
# If rotation is diagonal or imprecise, normalize to cardinal
|
|
||||||
if abs(forward_x) > abs(forward_z):
|
|
||||||
forward_vec = Vector2i(sign(forward_x), 0)
|
|
||||||
else:
|
|
||||||
forward_vec = Vector2i(0, sign(forward_z))
|
|
||||||
|
|
||||||
# 2. Offset Center (4 tiles away)
|
|
||||||
var offset_dist = 4
|
|
||||||
var center = player.current_position + (forward_vec * offset_dist)
|
|
||||||
|
|
||||||
# 3. Determine Radius based on Level
|
# 3. Determine Radius based on Level
|
||||||
# Level 1-4: Radius 1 (3x3 area)
|
|
||||||
# Level 5-8: Radius 2 (5x5 area)
|
|
||||||
var current_lvl = powerup_levels.get(SpecialEffect.AREA_FREEZE, 1)
|
var current_lvl = powerup_levels.get(SpecialEffect.AREA_FREEZE, 1)
|
||||||
var radius = 1
|
var radius = 1
|
||||||
if current_lvl >= 5:
|
if current_lvl >= 5:
|
||||||
radius = 2 # Bigger area at high levels
|
radius = 2 # Bigger area at high levels
|
||||||
|
|
||||||
print("Player %s executing Area Freeze at %s (Offset %s, Lvl %d, Rad %d)" % [player.name, center, forward_vec, current_lvl, radius])
|
print("Player %s executing Area Freeze at %s (Lvl %d, Rad %d)" % [player.name, center_pos, current_lvl, radius])
|
||||||
|
|
||||||
# Register Zone for persistence
|
# Register Zone for persistence
|
||||||
active_freeze_zones.append({
|
active_freeze_zones.append({
|
||||||
"center": center,
|
"center": center_pos,
|
||||||
"radius": radius,
|
"radius": radius,
|
||||||
"timer": FREEZE_SLOW_DURATION # Same duration as the visual
|
"timer": FREEZE_SLOW_DURATION
|
||||||
})
|
})
|
||||||
|
|
||||||
# Initial Check (Instant Feedback)
|
# Initial Check (Instant Feedback)
|
||||||
var all_players = player.get_tree().get_nodes_in_group("Players")
|
var all_players = player.get_tree().get_nodes_in_group("Players")
|
||||||
for p in all_players:
|
for p in all_players:
|
||||||
# Check distance (Chebyshev distance for square area)
|
# Check distance (Chebyshev distance for square area)
|
||||||
var dx = abs(p.current_position.x - center.x)
|
var dx = abs(p.current_position.x - center_pos.x)
|
||||||
var dy = abs(p.current_position.y - center.y)
|
var dy = abs(p.current_position.y - center_pos.y)
|
||||||
|
|
||||||
# If inside square radius
|
# If inside square radius
|
||||||
if dx <= radius and dy <= radius:
|
if dx <= radius and dy <= radius:
|
||||||
@@ -245,7 +297,7 @@ func _execute_area_freeze():
|
|||||||
# Sync Icy Floor (Layer 0)
|
# Sync Icy Floor (Layer 0)
|
||||||
for x in range(-radius, radius + 1):
|
for x in range(-radius, radius + 1):
|
||||||
for y in range(-radius, radius + 1):
|
for y in range(-radius, radius + 1):
|
||||||
var pos = center + Vector2i(x, y)
|
var pos = center_pos + Vector2i(x, y)
|
||||||
if enhanced_gridmap.is_position_valid(pos):
|
if enhanced_gridmap.is_position_valid(pos):
|
||||||
var main = player.get_tree().get_root().get_node_or_null("Main")
|
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||||
# Use Item 12 (Blue Freeze Tile) on Layer 0 (Floor)
|
# Use Item 12 (Blue Freeze Tile) on Layer 0 (Floor)
|
||||||
@@ -255,40 +307,58 @@ func _execute_area_freeze():
|
|||||||
get_tree().create_timer(FREEZE_SLOW_DURATION).timeout.connect(func():
|
get_tree().create_timer(FREEZE_SLOW_DURATION).timeout.connect(func():
|
||||||
for x in range(-radius, radius + 1):
|
for x in range(-radius, radius + 1):
|
||||||
for y in range(-radius, radius + 1):
|
for y in range(-radius, radius + 1):
|
||||||
var pos = center + Vector2i(x, y)
|
var pos = center_pos + Vector2i(x, y)
|
||||||
if enhanced_gridmap.is_position_valid(pos):
|
if enhanced_gridmap.is_position_valid(pos):
|
||||||
var main = player.get_tree().get_root().get_node_or_null("Main")
|
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||||
# Restore to Item 0 (Standard Floor)
|
# Restore to Item 0 (Standard Floor)
|
||||||
if main: main.rpc("sync_grid_item", pos.x, 0, pos.y, 0)
|
if main: main.rpc("sync_grid_item", pos.x, 0, pos.y, 0)
|
||||||
)
|
)
|
||||||
|
|
||||||
func _execute_block_floor(target: Node3D):
|
func _execute_block_floor(target_pos: Vector2i):
|
||||||
# Existing logic for blocking, reused
|
# "Wall Block"
|
||||||
# "Wall Block" usually means block WHERE YOU ARE or FRONT?
|
# Determine Row or Column based on click?
|
||||||
# Original code blocked target's floor.
|
# Or let's imply orientation (North/South = Row, East/West = Column) relative to Player?
|
||||||
# User Request: "choose one between horizontal or vertical all the way to the colus or rows"
|
# Or just Row vs Column based on closest axis?
|
||||||
# We interpret "Choose one" as random 50/50 since there's no UI for sub-selection.
|
# Let's use simple logic: If click is further along X than Z from player, use Column(X), else Row(Z).
|
||||||
|
|
||||||
# Check for Immunity (Invisible Mode)
|
var diff = target_pos - player.current_position
|
||||||
if target.get("is_invisible"):
|
var is_horizontal = false
|
||||||
NotificationManager.send_message(target, "blocked!", NotificationManager.MessageType.POWERUP)
|
if abs(diff.x) > abs(diff.y):
|
||||||
# We should probably notify the attacker too?
|
is_horizontal = false # Aligned with X axis roughly? Logic check:
|
||||||
return
|
# If I am at (0,0) and click (5,0), diff is (5,0). X is dominant.
|
||||||
|
# I want to block the vertical column at X=5? Or the horizontal row?
|
||||||
|
# Original logic "is_horizontal" meant blocking the Row (all X at fixed Z).
|
||||||
|
# If I click (5,0), I likely want to block that column or row?
|
||||||
|
# Let's default to blocking the axis perpendicular to where I'm looking/clicking?
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Actually, simpler: Let's block the line that passes through the target point
|
||||||
|
# perpendicular to the direction from player to target.
|
||||||
|
# If I shoot North (change in Y/Z), I want a wall ACROSS (Row/X).
|
||||||
|
# If I shoot East (change in X), I want a wall ACROSS (Column/Z).
|
||||||
|
|
||||||
|
if abs(diff.x) > abs(diff.y):
|
||||||
|
# Target is East/West. I want a wall perpendicular -> Vertical (Fixed X, varying Z)
|
||||||
|
# Wait, "Column" in grid usually means Fixed X. "Row" means Fixed Z.
|
||||||
|
# So if X diff is big, I am shooting along X. I want a wall AT that X? No, I want a wall BLOCKING that X?
|
||||||
|
# Let's stick to the visual preview logic we will implement:
|
||||||
|
# If abs(diff.x) > abs(diff.y) -> Show Column (Vertical strip at target.x)
|
||||||
|
is_horizontal = false
|
||||||
|
else:
|
||||||
|
# Target is North/South. Show Row (Horizontal strip at target.y)
|
||||||
|
is_horizontal = true
|
||||||
|
|
||||||
var center = target.current_position
|
|
||||||
var is_horizontal = rng.randf() < 0.5
|
|
||||||
var neighbors = []
|
var neighbors = []
|
||||||
|
|
||||||
if is_horizontal:
|
if is_horizontal:
|
||||||
# Block entire Row (Fixed Z, iterate all X)
|
# Block entire Row (Fixed Z, iterate all X)
|
||||||
# Assuming 'center.y' corresponds to Grid Z-row
|
var row_z = target_pos.y
|
||||||
var row_z = center.y
|
|
||||||
for x in range(enhanced_gridmap.columns):
|
for x in range(enhanced_gridmap.columns):
|
||||||
neighbors.append({"position": Vector2i(x, row_z)})
|
neighbors.append({"position": Vector2i(x, row_z)})
|
||||||
print("Player %s activated Wall Block: HORIZONTAL ROW (Z=%d)" % [player.name, row_z])
|
print("Player %s activated Wall Block: HORIZONTAL ROW (Z=%d)" % [player.name, row_z])
|
||||||
else:
|
else:
|
||||||
# Block entire Column (Fixed X, iterate all Z)
|
# Block entire Column (Fixed X, iterate all Z)
|
||||||
var col_x = center.x
|
var col_x = target_pos.x
|
||||||
for z in range(enhanced_gridmap.rows):
|
for z in range(enhanced_gridmap.rows):
|
||||||
neighbors.append({"position": Vector2i(col_x, z)})
|
neighbors.append({"position": Vector2i(col_x, z)})
|
||||||
print("Player %s activated Wall Block: VERTICAL COLUMN (X=%d)" % [player.name, col_x])
|
print("Player %s activated Wall Block: VERTICAL COLUMN (X=%d)" % [player.name, col_x])
|
||||||
@@ -302,15 +372,18 @@ func _execute_block_floor(target: Node3D):
|
|||||||
if main:
|
if main:
|
||||||
main.rpc("sync_grid_item", block_pos.x, block_pos.y, block_pos.z, 4)
|
main.rpc("sync_grid_item", block_pos.x, block_pos.y, block_pos.z, 4)
|
||||||
|
|
||||||
# We don't save original item here properly in this loop if we overwrite something important,
|
# Record for restoration
|
||||||
# but for Floor 0 it's usually just ground (0) or obstacles.
|
|
||||||
# If we overwrite another Wall, it's fine.
|
|
||||||
blocked_tiles.append({
|
blocked_tiles.append({
|
||||||
"position": block_pos,
|
"position": block_pos,
|
||||||
"original_item": 0,
|
"original_item": 0,
|
||||||
"timer": BLOCK_DURATION
|
"timer": BLOCK_DURATION
|
||||||
})
|
})
|
||||||
NotificationManager.send_message(target, "Wall Block Created!", NotificationManager.MessageType.POWERUP)
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
func _execute_invisible_mode(target: Node3D):
|
func _execute_invisible_mode(target: Node3D):
|
||||||
target.is_invisible = true
|
target.is_invisible = true
|
||||||
|
|||||||
@@ -35,10 +35,12 @@ enum ActionState {
|
|||||||
MOVING,
|
MOVING,
|
||||||
GRABBING,
|
GRABBING,
|
||||||
ARRANGING,
|
ARRANGING,
|
||||||
RANDOMIZING
|
RANDOMIZING,
|
||||||
|
TARGETING
|
||||||
}
|
}
|
||||||
|
|
||||||
var current_action_state = ActionState.NONE
|
var current_action_state = ActionState.NONE
|
||||||
|
var pending_skill_id: int = -1
|
||||||
|
|
||||||
func initialize(player_node):
|
func initialize(player_node):
|
||||||
# Get PowerUp Inventory UI from scene
|
# Get PowerUp Inventory UI from scene
|
||||||
|
|||||||
Reference in New Issue
Block a user