feat: Implement the core "Tekton Doors" game mode including arena setup, portal management, special tiles, and mission tracking HUD.

Tekton Armageddon V.0.8
This commit is contained in:
Yogi Wiguna
2026-03-03 15:38:09 +08:00
parent 09d08093e2
commit 8b33ed3f56
7 changed files with 164 additions and 89 deletions
+1 -1
View File
@@ -301,7 +301,7 @@ func _spawn_portal_doors():
const PORTAL_COLORS = [
Color(0, 1, 1), # Cyan
Color(1, 0, 1), # Magenta
Color(1, 1, 0), # Yellow
Color(1, 0, 0), # Red
Color(0, 1, 0), # Green
Color(1, 0.5, 0) # Orange
]
+67 -65
View File
@@ -328,37 +328,36 @@ func _execute_area_freeze(center_pos: Vector2i = Vector2i.ZERO):
else:
NotificationManager.send_message(player, "Hit %d Players!" % hit_count, NotificationManager.MessageType.GOAL)
# Visual Feedback (Turn Floor Blue - Item 12 on Layer 0)
# Visual Feedback (Overlay Layer 2)
if player.is_multiplayer_authority():
# Sync Icy Floor (Layer 0)
for x in range(-radius, radius + 1):
for y in range(-radius, radius + 1):
var pos = center_pos + Vector2i(x, y)
if enhanced_gridmap.is_position_valid(pos):
var main = player.get_tree().get_root().get_node_or_null("Main")
if main:
# CHECK: Don't overwrite Wall Block (Item 4)
var current_item = enhanced_gridmap.get_cell_item(Vector3i(pos.x, 0, pos.y))
if current_item != 4: # 4 is Wall Block
# Use Item 12 (Blue Freeze Tile) on Layer 0 (Floor)
if multiplayer.has_multiplayer_peer() and multiplayer.multiplayer_peer.get_connection_status() == MultiplayerPeer.CONNECTION_CONNECTED:
main.rpc("sync_grid_item", pos.x, 0, pos.y, 12)
# Cleanup visual timer (managed locally by author)
get_tree().create_timer(FREEZE_SLOW_DURATION).timeout.connect(func():
var main = player.get_tree().get_root().get_node_or_null("Main")
if main and main.has_method("sync_grid_items_batch"):
var batch_data = []
for x in range(-radius, radius + 1):
for y in range(-radius, radius + 1):
var pos = center_pos + Vector2i(x, y)
if enhanced_gridmap.is_position_valid(pos):
var main = player.get_tree().get_root().get_node_or_null("Main")
if main:
# CHECK: Only restore if it is STILL Ice (Item 12)
# This prevents removing a Wall that was placed AFTER the freeze started
var current_check = enhanced_gridmap.get_cell_item(Vector3i(pos.x, 0, pos.y))
if current_check == 12:
# Restore to Item 0 (Standard Floor)
main.rpc("sync_grid_item", pos.x, 0, pos.y, 0)
)
# Use Item 5 (Freeze Floor) on Layer 2
batch_data.append({"x": pos.x, "y": 2, "z": pos.y, "item": 5})
if not batch_data.is_empty():
main.rpc("sync_grid_items_batch", batch_data)
# Cleanup visual timer (managed locally by author)
get_tree().create_timer(FREEZE_SLOW_DURATION).timeout.connect(func():
var restore_batch = []
for x in range(-radius, radius + 1):
for y in range(-radius, radius + 1):
var pos = center_pos + Vector2i(x, y)
if enhanced_gridmap.is_position_valid(pos):
# Check if it is STILL Freeze Overlay
var current_check = enhanced_gridmap.get_cell_item(Vector3i(pos.x, 2, pos.y))
if current_check == 5:
restore_batch.append({"x": pos.x, "y": 2, "z": pos.y, "item": -1})
if not restore_batch.is_empty():
main.rpc("sync_grid_items_batch", restore_batch)
)
func toggle_wall_orientation():
wall_orientation_horizontal = !wall_orientation_horizontal
@@ -384,41 +383,34 @@ func _execute_block_floor(target_pos: Vector2i):
neighbors.append({"position": Vector2i(col_x, z)})
print("Player %s activated Wall Block: VERTICAL COLUMN (X=%d)" % [player.name, col_x])
for n in neighbors:
var pos = n.position
# PHYSICS CHECK
if _is_position_blocked_by_stand(pos):
continue
if player.is_multiplayer_authority():
var main = player.get_tree().get_root().get_node_or_null("Main")
if main and main.has_method("sync_grid_items_batch"):
var batch_data = []
for n in neighbors:
var pos = n.position
if _is_position_blocked_by_stand(pos): continue
var block_pos = Vector3i(pos.x, 0, pos.y)
var current_item = enhanced_gridmap.get_cell_item(block_pos)
var is_immutable = false
if "immutable_items" in enhanced_gridmap:
if current_item in enhanced_gridmap.immutable_items:
is_immutable = true
if current_item == 4 or is_immutable: continue
batch_data.append({"x": block_pos.x, "y": 0, "z": block_pos.z, "item": 4})
# Record for restoration
blocked_tiles.append({
"position": block_pos,
"original_item": current_item,
"timer": BLOCK_DURATION
})
var block_pos = Vector3i(pos.x, 0, pos.y)
# Check current item first
var current_item = enhanced_gridmap.get_cell_item(block_pos)
# Skip if already a wall or immutable
# We assume Item 4 is the wall/stand.
# Also check enhanced_gridmap.immutable_items if available
var is_immutable = false
if "immutable_items" in enhanced_gridmap:
if current_item in enhanced_gridmap.immutable_items:
is_immutable = true
if current_item == 4 or is_immutable:
# Don't overwrite existing walls/stands, and don't schedule them for "restoration" (deletion)
continue
if player.is_multiplayer_authority():
var main = player.get_tree().get_root().get_node_or_null("Main")
if main and multiplayer.has_multiplayer_peer() and multiplayer.multiplayer_peer.get_connection_status() == MultiplayerPeer.CONNECTION_CONNECTED:
main.rpc("sync_grid_item", block_pos.x, block_pos.y, block_pos.z, 4)
# Record for restoration
blocked_tiles.append({
"position": block_pos,
"original_item": current_item, # Restore the ACTUAL item that was there (e.g. ground 0 or maybe a dropped item?)
"timer": BLOCK_DURATION
})
if not batch_data.is_empty():
main.rpc("sync_grid_items_batch", batch_data)
# Notify
var all_players = player.get_tree().get_nodes_in_group("Players")
@@ -471,6 +463,16 @@ func spawn_powerups_around(center: Vector2i, force_powerups: bool = true):
var cell = Vector3i(pos.x, 1, pos.y)
# PREVENT SPAWNING ON FROZEN FLOORS (Visual/Lag Fix)
var is_frozen = false
if enhanced_gridmap:
# Check Layer 2 for Freeze Overlay (ID 5)
if enhanced_gridmap.get_cell_item(Vector3i(pos.x, 2, pos.y)) == 5:
is_frozen = true
if is_frozen:
continue
if player.is_multiplayer_authority():
var main = player.get_tree().get_root().get_node_or_null("Main")
if main and multiplayer.has_multiplayer_peer() and multiplayer.multiplayer_peer.get_connection_status() == MultiplayerPeer.CONNECTION_CONNECTED:
@@ -497,9 +499,9 @@ func _update_freeze_zones(delta: float):
# If inside zone
if dx <= zone.radius and dy <= zone.radius:
# Apply slow effect repeatedly
# We use a short duration so it expires quickly if they leave
p.rpc("apply_slow_effect", 0.5)
# Apply slow effect via RPC only IF not already slowed to prevent network flood
if "movement_manager" in p and p.movement_manager and p.movement_manager.speed_multiplier >= 1.0:
p.rpc("apply_slow_effect", 0.5)
if zone.timer <= 0:
zones_to_remove.append(i)
@@ -523,7 +525,7 @@ func _check_for_icy_floor():
return
var current_item = enhanced_gridmap.get_cell_item(Vector3i(player.current_position.x, 2, player.current_position.y))
if current_item == 15:
if current_item == 5: # Freeze Floor
_apply_slow_mo(player)
elif player.movement_manager and player.movement_manager.speed_multiplier < 1.0:
# Check if we should restore speed
@@ -581,7 +583,7 @@ func _create_restore_speed_timer(target_player: Node3D, duration: float):
var still_in_zone = false
if enhanced_gridmap:
var item = enhanced_gridmap.get_cell_item(Vector3i(target_player.current_position.x, 2, target_player.current_position.y))
if item == 15:
if item == 5: # Freeze Floor
still_in_zone = true
if not still_in_zone: