feat: Implement Tekton roaming NPC with movement, combat, carry, throw, and knock mechanics.

This commit is contained in:
Yogi Wiguna
2026-02-19 17:29:14 +08:00
parent a7a8106b7e
commit e90cbfe246
11 changed files with 235 additions and 84 deletions
+21 -7
View File
@@ -38,7 +38,7 @@ func rotate_towards_target(target_pos: Vector2i):
if direction != Vector3.ZERO:
target_rotation = atan2(direction.x, direction.z)
# Sync rotation to other clients
if player.is_multiplayer_authority():
if player.is_multiplayer_authority() and player.has_method("can_rpc") and player.can_rpc():
player.rpc("sync_rotation", target_rotation)
func simple_move_to(grid_position: Vector2i) -> bool:
@@ -108,7 +108,9 @@ func simple_move_to(grid_position: Vector2i) -> bool:
rotate_towards_target(grid_position)
if player.is_multiplayer_authority() and multiplayer.has_multiplayer_peer() and multiplayer.multiplayer_peer.get_connection_status() == MultiplayerPeer.CONNECTION_CONNECTED:
rotate_towards_target(grid_position)
if player.is_multiplayer_authority() and player.has_method("can_rpc") and player.can_rpc():
if player.has_method("sync_walk_animation"):
player.rpc("sync_walk_animation")
@@ -117,7 +119,7 @@ func simple_move_to(grid_position: Vector2i) -> bool:
current_move_direction = grid_position - player.current_position
if multiplayer.has_multiplayer_peer() and multiplayer.multiplayer_peer.get_connection_status() == MultiplayerPeer.CONNECTION_CONNECTED:
if player.is_multiplayer_authority() and player.has_method("can_rpc") and player.can_rpc():
player.rpc("start_movement_along_path", path, not (player.is_bot or player.is_in_group("Bots")))
return true
@@ -139,9 +141,18 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
# === SUPER PUSH (Attack Mode) ===
print("Player %s SUPER PUSHING %s!" % [player.name, other_player.name])
# SAFE ZONE PROTECTION
# Columns 6, 7, 8 and 14, 15, 16 are Safe Zones
var safe_columns = [6, 7, 8, 14, 15, 16]
if target_pos.x in safe_columns:
print(" - Attack BLOCKED by Safe Zone!")
NotificationManager.send_message(player, "Cannot Attack in Safe Zone!", NotificationManager.MessageType.WARNING)
return false
# 1. Drop Victim's Tiles
if other_player.has_method("drop_all_tiles"):
other_player.rpc("drop_all_tiles") # Sync drop
if player.has_method("can_rpc") and player.can_rpc():
other_player.rpc("drop_all_tiles") # Sync drop
# 2. Spawn PowerUps around Victim
# We delegate this to the attacker's SpecialTilesManager to handle the spawning authority
@@ -158,15 +169,18 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
not _is_position_blocked_by_physics(pushed_to_pos):
# Valid push
var push_path = [Vector2(pushed_to_pos.x, pushed_to_pos.y)]
other_player.rpc("start_movement_along_path", push_path, false)
if player.has_method("can_rpc") and player.can_rpc():
other_player.rpc("start_movement_along_path", push_path, false)
other_player.target_position = pushed_to_pos # Logical update
# Apply stun/freeze effect as requested (same as wall stagger)
other_player.rpc("apply_stagger", 1.5)
if player.has_method("can_rpc") and player.can_rpc():
other_player.rpc("apply_stagger", 1.5)
else:
# Wall/Blocked -> Stagger in place
other_player.rpc("apply_stagger", 1.5)
if player.has_method("can_rpc") and player.can_rpc():
other_player.rpc("apply_stagger", 1.5)
# 4. Consume Boost (Full) - One hit per charge
if player.powerup_manager: