feat: implement core player entity with state management, network synchronization, and bot logic.
This commit is contained in:
+60
-4
@@ -751,7 +751,7 @@ func _apply_tint_recursive(node: Node, color: Color):
|
|||||||
|
|
||||||
var immunity_timer: float = 0.0
|
var immunity_timer: float = 0.0
|
||||||
var tekton_carry_timer: float = 0.0
|
var tekton_carry_timer: float = 0.0
|
||||||
const MAX_TEKTON_CARRY_TIME: float = 3.0
|
const MAX_TEKTON_CARRY_TIME: float = 4.0
|
||||||
|
|
||||||
|
|
||||||
@rpc("any_peer", "call_local")
|
@rpc("any_peer", "call_local")
|
||||||
@@ -2139,12 +2139,58 @@ func grab_tekton():
|
|||||||
if not is_multiplayer_authority() or is_carrying_tekton or is_frozen or is_stop_frozen:
|
if not is_multiplayer_authority() or is_carrying_tekton or is_frozen or is_stop_frozen:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Find nearby Tekton
|
# 1. Check for nearby carrier to snatch from
|
||||||
|
var carrier = _find_nearby_carrier()
|
||||||
|
if carrier:
|
||||||
|
snatch_tekton(carrier)
|
||||||
|
return
|
||||||
|
|
||||||
|
# 2. Find nearby roaming Tekton
|
||||||
var tekton = _find_nearby_tekton()
|
var tekton = _find_nearby_tekton()
|
||||||
if tekton:
|
if tekton:
|
||||||
if is_multiplayer_authority() and can_rpc():
|
if is_multiplayer_authority() and can_rpc():
|
||||||
rpc("sync_grab_tekton", tekton.get_path())
|
rpc("sync_grab_tekton", tekton.get_path())
|
||||||
|
|
||||||
|
func snatch_tekton(target_carrier: Node3D):
|
||||||
|
if not is_multiplayer_authority() or not target_carrier.is_carrying_tekton:
|
||||||
|
return
|
||||||
|
|
||||||
|
var tekton = target_carrier.carried_tekton
|
||||||
|
if tekton:
|
||||||
|
if is_multiplayer_authority() and can_rpc():
|
||||||
|
rpc("sync_snatch_tekton", target_carrier.get_path(), tekton.get_path())
|
||||||
|
|
||||||
|
@rpc("any_peer", "call_local", "reliable")
|
||||||
|
func sync_snatch_tekton(carrier_path: NodePath, tekton_path: NodePath):
|
||||||
|
var carrier = get_node_or_null(carrier_path)
|
||||||
|
var tekton = get_node_or_null(tekton_path)
|
||||||
|
if carrier and tekton:
|
||||||
|
# Security: ensure multiple people don't think they are carrying it
|
||||||
|
# Transfer logic
|
||||||
|
carrier.is_carrying_tekton = false
|
||||||
|
carrier.carried_tekton = null
|
||||||
|
|
||||||
|
self.is_carrying_tekton = true
|
||||||
|
self.carried_tekton = tekton
|
||||||
|
tekton.set_carried(true, self)
|
||||||
|
|
||||||
|
# Reset my carry timer (3s rule starts fresh)
|
||||||
|
tekton_carry_timer = 0.0
|
||||||
|
|
||||||
|
# Visual/Logic side effects
|
||||||
|
if is_attack_mode:
|
||||||
|
is_attack_mode = false
|
||||||
|
|
||||||
|
SfxManager.play("pick_up_tekton_roaming")
|
||||||
|
play_pickup_animation()
|
||||||
|
|
||||||
|
# Visual feedback for the victim
|
||||||
|
if carrier.has_method("sync_bump"):
|
||||||
|
# Bump away from the snatcher
|
||||||
|
carrier.sync_bump(current_position, true)
|
||||||
|
|
||||||
|
print("[Player %s] SNATCHED Tekton from %s" % [name, carrier.name])
|
||||||
|
|
||||||
@rpc("any_peer", "call_local", "reliable")
|
@rpc("any_peer", "call_local", "reliable")
|
||||||
func sync_grab_tekton(tekton_path: NodePath):
|
func sync_grab_tekton(tekton_path: NodePath):
|
||||||
var tekton = get_node_or_null(tekton_path)
|
var tekton = get_node_or_null(tekton_path)
|
||||||
@@ -2409,8 +2455,6 @@ func _find_nearby_tekton() -> Node3D: # Find closest Tekton
|
|||||||
if t.get("is_recovering"): continue # Cannot grab recovering/shrunk Tekton
|
if t.get("is_recovering"): continue # Cannot grab recovering/shrunk Tekton
|
||||||
if t.get("is_static_turret"): continue # Cannot grab/knock static turret
|
if t.get("is_static_turret"): continue # Cannot grab/knock static turret
|
||||||
|
|
||||||
# Check adjacency (or same tile)
|
|
||||||
# Assuming is_adjacent_or_same is a helper function that checks if two Vector2i are adjacent or the same.
|
|
||||||
# For example: (pos1 - pos2).length_squared() <= 2 (for adjacent or same tile)
|
# For example: (pos1 - pos2).length_squared() <= 2 (for adjacent or same tile)
|
||||||
var dist_grid = (t.current_position - current_position).length()
|
var dist_grid = (t.current_position - current_position).length()
|
||||||
if dist_grid <= 1.5: # Adjacent (1.0 or 1.41) or same tile (0.0)
|
if dist_grid <= 1.5: # Adjacent (1.0 or 1.41) or same tile (0.0)
|
||||||
@@ -2419,3 +2463,15 @@ func _find_nearby_tekton() -> Node3D: # Find closest Tekton
|
|||||||
min_dist = dist
|
min_dist = dist
|
||||||
closest_tekton = t
|
closest_tekton = t
|
||||||
return closest_tekton
|
return closest_tekton
|
||||||
|
|
||||||
|
func _find_nearby_carrier() -> Node3D:
|
||||||
|
"""Find a nearby player who is carrying a Tekton."""
|
||||||
|
var players = get_tree().get_nodes_in_group("Players")
|
||||||
|
for p in players:
|
||||||
|
if p == self: continue
|
||||||
|
if p.is_carrying_tekton:
|
||||||
|
# Check adjacency or same tile
|
||||||
|
var dist = Vector2(p.current_position.x, p.current_position.y).distance_to(Vector2(current_position.x, current_position.y))
|
||||||
|
if dist <= 1.5:
|
||||||
|
return p
|
||||||
|
return null
|
||||||
|
|||||||
Reference in New Issue
Block a user