delete files in nickes
This commit is contained in:
@@ -10,13 +10,14 @@ extends Node2D
|
||||
var spawned_enemies: Array = []
|
||||
var respawn_timer: float = 0.0
|
||||
var smoke_puff_scene = preload("res://scenes/smoke_puff.tscn")
|
||||
var has_ever_spawned: bool = false # Track if this spawner has ever spawned an enemy
|
||||
|
||||
func _ready():
|
||||
print("========== EnemySpawner READY ==========")
|
||||
print(" Position: ", global_position)
|
||||
print(" Is server: ", multiplayer.is_server())
|
||||
print(" Has multiplayer peer: ", multiplayer.has_multiplayer_peer())
|
||||
print(" Is authority: ", is_multiplayer_authority() if multiplayer.has_multiplayer_peer() else "N/A")
|
||||
print(" Is authority: ", str(is_multiplayer_authority()) if multiplayer.has_multiplayer_peer() else "N/A")
|
||||
print(" spawn_on_ready: ", spawn_on_ready)
|
||||
print(" max_enemies: ", max_enemies)
|
||||
print(" enemy_scenes.size(): ", enemy_scenes.size())
|
||||
@@ -45,8 +46,9 @@ func _process(delta):
|
||||
# Clean up dead enemies from list
|
||||
spawned_enemies = spawned_enemies.filter(func(e): return is_instance_valid(e) and not e.is_dead)
|
||||
|
||||
# Check if we need to respawn
|
||||
if spawned_enemies.size() < max_enemies:
|
||||
# Check if we need to respawn (only if respawn_time > 0)
|
||||
# Puzzle spawners have respawn_time = 0.0, so they won't respawn
|
||||
if respawn_time > 0.0 and spawned_enemies.size() < max_enemies:
|
||||
respawn_timer += delta
|
||||
if respawn_timer >= respawn_time:
|
||||
spawn_enemy()
|
||||
@@ -95,19 +97,40 @@ func spawn_enemy():
|
||||
# Spawn multiple smoke puffs at slightly different positions
|
||||
var smoke_puffs = []
|
||||
var puff_spawn_radius = 8.0 # Pixels - spawn puffs in a small area around spawner
|
||||
var puff_positions = [] # Store positions for syncing to clients
|
||||
|
||||
# Calculate puff positions first
|
||||
for i in range(num_puffs):
|
||||
var puff_offset = Vector2(
|
||||
randf_range(-puff_spawn_radius, puff_spawn_radius),
|
||||
randf_range(-puff_spawn_radius, puff_spawn_radius)
|
||||
)
|
||||
var puff = _spawn_smoke_puff_at_position(global_position + puff_offset)
|
||||
puff_positions.append(global_position + puff_offset)
|
||||
|
||||
# Spawn smoke puffs on server
|
||||
for puff_pos in puff_positions:
|
||||
var puff = _spawn_smoke_puff_at_position(puff_pos)
|
||||
if puff:
|
||||
smoke_puffs.append(puff)
|
||||
|
||||
# Sync smoke puffs to all clients
|
||||
if multiplayer.has_multiplayer_peer() and multiplayer.is_server():
|
||||
var game_world = get_tree().get_first_node_in_group("game_world")
|
||||
if not game_world:
|
||||
# Fallback: traverse up the tree to find GameWorld
|
||||
var node = get_parent()
|
||||
while node:
|
||||
if node.has_method("_sync_smoke_puffs"):
|
||||
game_world = node
|
||||
break
|
||||
node = node.get_parent()
|
||||
|
||||
if game_world and game_world.has_method("_sync_smoke_puffs"):
|
||||
game_world._sync_smoke_puffs.rpc(name, puff_positions)
|
||||
|
||||
# Wait for smoke puffs to finish animating before spawning enemy
|
||||
# Smoke puff animation: 4 frames * (1/10.0) seconds per frame = 0.4s, plus move_duration 1.5s, plus fade_duration 0.5s = ~2.4s total
|
||||
var smoke_animation_duration = (4.0 / 10.0) + 1.5 + 0.5 # Total animation time
|
||||
# Reduced duration for faster spawning: 4 frames * (1/10.0) seconds per frame = 0.4s, plus move_duration 1.0s, plus fade_duration 0.3s = ~1.7s total
|
||||
var smoke_animation_duration = (4.0 / 10.0) + 1.0 + 0.3 # Reduced from 2.4s to 1.7s
|
||||
await get_tree().create_timer(smoke_animation_duration).timeout
|
||||
|
||||
print(" Smoke puffs finished - now spawning enemy...")
|
||||
@@ -126,6 +149,27 @@ func spawn_enemy():
|
||||
enemy.spawn_position = global_position
|
||||
print(" Set enemy position to: ", global_position)
|
||||
|
||||
# If it's a humanoid enemy, randomize the humanoid_type
|
||||
var humanoid_type = null
|
||||
if scene_to_spawn.resource_path.ends_with("enemy_humanoid.tscn"):
|
||||
# Random humanoid type: 0=CYCLOPS, 1=DEMON, 2=HUMANOID, 3=NIGHTELF, 4=GOBLIN, 5=ORC, 6=SKELETON
|
||||
# Weight towards common types (goblins, humans, orcs) - 40% goblin, 30% humanoid, 20% orc, 10% other
|
||||
var rand_val = randf()
|
||||
var type_value = 2 # Default to HUMANOID
|
||||
if rand_val < 0.4:
|
||||
type_value = 4 # GOBLIN (40%)
|
||||
elif rand_val < 0.7:
|
||||
type_value = 2 # HUMANOID (30%)
|
||||
elif rand_val < 0.9:
|
||||
type_value = 5 # ORC (20%)
|
||||
else:
|
||||
# 10% for other types (distributed evenly)
|
||||
var other_types = [0, 1, 3, 6] # CYCLOPS, DEMON, NIGHTELF, SKELETON
|
||||
type_value = other_types[randi() % other_types.size()]
|
||||
enemy.humanoid_type = type_value
|
||||
humanoid_type = type_value
|
||||
print(" Randomized humanoid_type: ", type_value)
|
||||
|
||||
# CRITICAL: Mark this enemy as spawned from a spawner (for door puzzle tracking)
|
||||
enemy.set_meta("spawned_from_spawner", true)
|
||||
enemy.set_meta("spawner_name", name)
|
||||
@@ -167,6 +211,7 @@ func spawn_enemy():
|
||||
enemy.set_meta("spawn_scene_index", scene_index)
|
||||
|
||||
spawned_enemies.append(enemy)
|
||||
has_ever_spawned = true # Mark that this spawner has spawned at least once
|
||||
|
||||
print(" ✓ Successfully spawned enemy: ", enemy.name, " at ", global_position, " scene_index: ", scene_index)
|
||||
print(" Total spawned enemies: ", spawned_enemies.size())
|
||||
@@ -191,16 +236,19 @@ func spawn_enemy():
|
||||
|
||||
if game_world and game_world.has_method("_sync_enemy_spawn"):
|
||||
# Use spawner name for identification
|
||||
print(" DEBUG: Calling _sync_enemy_spawn.rpc with name=", name, " pos=", global_position, " scene_index=", scene_index)
|
||||
game_world._sync_enemy_spawn.rpc(name, global_position, scene_index)
|
||||
print(" Sent RPC to sync enemy spawn to clients: spawner=", name, " pos=", global_position, " scene_index=", scene_index)
|
||||
# Pass humanoid_type if it's a humanoid enemy (for syncing to clients)
|
||||
var sync_humanoid_type = humanoid_type if humanoid_type != null else -1
|
||||
print(" DEBUG: Calling _sync_enemy_spawn.rpc with name=", name, " pos=", global_position, " scene_index=", scene_index, " humanoid_type=", sync_humanoid_type)
|
||||
game_world._sync_enemy_spawn.rpc(name, global_position, scene_index, sync_humanoid_type)
|
||||
print(" Sent RPC to sync enemy spawn to clients: spawner=", name, " pos=", global_position, " scene_index=", scene_index, " humanoid_type=", sync_humanoid_type)
|
||||
else:
|
||||
var has_method_str = str(game_world.has_method("_sync_enemy_spawn")) if game_world else "N/A"
|
||||
push_error("ERROR: Could not find GameWorld or _sync_enemy_spawn method! game_world=", game_world, " has_method=", has_method_str)
|
||||
|
||||
func spawn_enemy_at_position(spawn_pos: Vector2, scene_index: int = -1):
|
||||
func spawn_enemy_at_position(spawn_pos: Vector2, scene_index: int = -1, humanoid_type: int = -1):
|
||||
# This method is called by GameWorld RPC to spawn enemies on clients
|
||||
# scene_index tells us which scene from enemy_scenes array was used on the server
|
||||
# humanoid_type tells us the humanoid type if it's a humanoid enemy (for syncing from server)
|
||||
var scene_to_spawn: PackedScene = null
|
||||
if scene_index >= 0 and scene_index < enemy_scenes.size():
|
||||
# Use the scene index that was synced from server
|
||||
@@ -215,10 +263,10 @@ func spawn_enemy_at_position(spawn_pos: Vector2, scene_index: int = -1):
|
||||
push_error("ERROR: Spawner has no enemy scenes set! Add scenes to enemy_scenes array.")
|
||||
return
|
||||
|
||||
print("Client: spawn_enemy_at_position called at ", spawn_pos)
|
||||
print("Client: spawn_enemy_at_position called at ", spawn_pos, " humanoid_type: ", humanoid_type)
|
||||
|
||||
# Spawn smoke puff effect
|
||||
_spawn_smoke_puff()
|
||||
# NOTE: Smoke puffs are synced via RPC (_sync_smoke_puffs) from server
|
||||
# so we don't spawn them here - they're already spawned by the RPC handler
|
||||
|
||||
# Instantiate and add enemy
|
||||
var enemy = scene_to_spawn.instantiate()
|
||||
@@ -231,6 +279,11 @@ func spawn_enemy_at_position(spawn_pos: Vector2, scene_index: int = -1):
|
||||
if "spawn_position" in enemy:
|
||||
enemy.spawn_position = spawn_pos
|
||||
|
||||
# If it's a humanoid enemy, set the humanoid_type from server
|
||||
if humanoid_type >= 0 and scene_to_spawn.resource_path.ends_with("enemy_humanoid.tscn"):
|
||||
enemy.humanoid_type = humanoid_type
|
||||
print("Client: Set humanoid_type to ", humanoid_type)
|
||||
|
||||
# CRITICAL: Set collision mask BEFORE adding to scene to ensure enemies collide with walls (layer 7 = bit 6 = 64)
|
||||
# This overrides any collision_mask set in the scene file
|
||||
enemy.collision_mask = 1 | 2 | 64 # Collide with players (layer 1), objects (layer 2), and walls (layer 7 = bit 6 = 64)
|
||||
@@ -255,14 +308,20 @@ func spawn_enemy_at_position(spawn_pos: Vector2, scene_index: int = -1):
|
||||
print(" ✓ Client spawned enemy: ", enemy.name, " at ", spawn_pos)
|
||||
|
||||
func get_spawned_enemy_positions() -> Array:
|
||||
# Return array of dictionaries with position and scene_index for all currently spawned enemies
|
||||
# Return array of dictionaries with position, scene_index, and humanoid_type for all currently spawned enemies
|
||||
var enemy_data = []
|
||||
for enemy in spawned_enemies:
|
||||
if is_instance_valid(enemy) and not enemy.is_dead:
|
||||
var scene_index = -1
|
||||
if enemy.has_meta("spawn_scene_index"):
|
||||
scene_index = enemy.get_meta("spawn_scene_index")
|
||||
enemy_data.append({"position": enemy.global_position, "scene_index": scene_index})
|
||||
var data = {"position": enemy.global_position, "scene_index": scene_index}
|
||||
# Include humanoid_type if it's a humanoid enemy
|
||||
if "humanoid_type" in enemy:
|
||||
data["humanoid_type"] = enemy.humanoid_type
|
||||
else:
|
||||
data["humanoid_type"] = -1
|
||||
enemy_data.append(data)
|
||||
return enemy_data
|
||||
|
||||
func _verify_enemy_collision_mask(enemy: Node):
|
||||
@@ -297,10 +356,17 @@ func _spawn_smoke_puff_at_position(puff_position: Vector2) -> Node:
|
||||
var puff = smoke_puff_scene.instantiate()
|
||||
if puff:
|
||||
puff.global_position = puff_position
|
||||
var parent = get_parent()
|
||||
# Ensure smoke puff is visible - set high z_index so it appears above ground
|
||||
puff.z_index = 10 # High z-index to ensure visibility
|
||||
if puff.has_node("Sprite2D"):
|
||||
puff.get_node("Sprite2D").z_index = 10
|
||||
|
||||
# Add to Entities node (same as enemies) for proper layering
|
||||
var entities_node = get_parent().get_node_or_null("Entities")
|
||||
var parent = entities_node if entities_node else get_parent()
|
||||
if parent:
|
||||
parent.add_child(puff)
|
||||
print(" ✓ Smoke puff spawned at ", puff_position)
|
||||
print(" ✓ Smoke puff spawned at ", puff_position, " z_index: ", puff.z_index)
|
||||
return puff
|
||||
else:
|
||||
print(" ERROR: No parent node for smoke puff!")
|
||||
|
||||
Reference in New Issue
Block a user