conforms file names to consistant standard
This commit is contained in:
139
scripts/enemy_spawner.gd
Normal file
139
scripts/enemy_spawner.gd
Normal file
@@ -0,0 +1,139 @@
|
||||
class_name EnemySpawner
|
||||
extends Node3D
|
||||
|
||||
signal enemy_spawned()
|
||||
|
||||
@export var land_enemy_scene: PackedScene
|
||||
@export var leap_enemy_scene: PackedScene
|
||||
@export var air_enemy_scene: PackedScene
|
||||
@export var flow_field: FlowField
|
||||
@export var own_id: int = 0
|
||||
@export var type: Data.EnemyType
|
||||
@export var dest: Node3D
|
||||
@export var enemy_path: Node
|
||||
|
||||
var enemy_died_callback: Callable
|
||||
var enemy_reached_goal_callback: Callable
|
||||
var current_wave: Array[EnemyGroup]
|
||||
var enemy_types_to_spawn: Dictionary = {}
|
||||
var enemy_spawn_timers: Dictionary = {}
|
||||
var enemies_spawned: Dictionary = {}
|
||||
var enemies_to_spawn: int = 0
|
||||
var done_spawning: bool = true
|
||||
var enemy_id: int = 0
|
||||
var game_manager: GameManager
|
||||
var path_vfx: PathVFX
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if enemies_to_spawn == 0:
|
||||
done_spawning = true
|
||||
return
|
||||
|
||||
for enemy: Enemy in enemy_spawn_timers:
|
||||
var enemy_code: int = -1
|
||||
for enemy_in_pool: Enemy in game_manager.level.enemy_pool:
|
||||
enemy_code += 1
|
||||
if enemy.title == enemy_in_pool.title:
|
||||
break
|
||||
|
||||
if enemies_spawned[enemy] == enemy_types_to_spawn[enemy]:
|
||||
continue
|
||||
|
||||
enemy_spawn_timers[enemy] += delta
|
||||
|
||||
if enemy_spawn_timers[enemy] >= enemy.spawn_cooldown:
|
||||
if is_multiplayer_authority():
|
||||
if type == Data.EnemyType.LAND:
|
||||
#print(enemy)
|
||||
#print(game_manager.level.enemy_pool[0])
|
||||
#print("Finding " + enemy.title + " in enemy pool and sending to spawn with num " + str(enemy_code))
|
||||
networked_spawn_land_enemy.rpc(enemy_code, own_id, enemy_id)
|
||||
if type == Data.EnemyType.AIR:
|
||||
var radius: float = 10.0
|
||||
var random_dir: Vector3 = Vector3(randf_range(-1, 1), randf_range(-1, 1), randf_range(-1, 1))
|
||||
var random_pos: Vector3 = randf_range(0, radius) * random_dir.normalized()
|
||||
networked_spawn_air_enemy.rpc(enemy_code, random_pos, own_id, enemy_id)
|
||||
|
||||
enemy_spawn_timers[enemy] -= enemy.spawn_cooldown
|
||||
enemy_spawned.emit()
|
||||
enemy_id += 1
|
||||
enemies_spawned[enemy] += 1
|
||||
enemies_to_spawn -= 1
|
||||
|
||||
|
||||
#TODO: not sure enemies need all this info over the network
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_spawn_land_enemy(enemy_num: int, id1: int, id2: int) -> void:
|
||||
var enemy: EnemyController
|
||||
#print("Received spawn rpc code " + str(enemy_num) + " for " + game_manager.level.enemy_pool[enemy_num].title)
|
||||
enemy = game_manager.level.enemy_pool[enemy_num].scene.instantiate()
|
||||
enemy.stats = game_manager.level.enemy_pool[enemy_num]
|
||||
enemy.corpse_root = game_manager.level.corpses
|
||||
enemy.name = str(id1) + str(id2)
|
||||
enemy.died.connect(enemy_died_callback)
|
||||
enemy.reached_goal.connect(enemy_reached_goal_callback)
|
||||
#enemy.movement_controller.path = path.curve
|
||||
#enemy.movement_controller.astar = astar
|
||||
enemy.movement_controller.flow_field = flow_field
|
||||
enemy.position = global_position
|
||||
enemy_path.add_child(enemy)
|
||||
|
||||
|
||||
func create_path() -> void:
|
||||
if type != Data.EnemyType.LAND:
|
||||
return
|
||||
if path_vfx:
|
||||
path_vfx.queue_free()
|
||||
path_vfx = PathVFX.new()
|
||||
path_vfx.line_width = 0.2
|
||||
path_vfx.material = load("res://path_material.tres")
|
||||
add_child(path_vfx)
|
||||
path_vfx.global_position = Vector3.ZERO
|
||||
update_path()
|
||||
|
||||
|
||||
|
||||
func update_path() -> void:
|
||||
if type != Data.EnemyType.LAND or !flow_field.data.nodes:
|
||||
return
|
||||
var points: Array[Vector3] = []
|
||||
var node: FlowNodeData = flow_field.get_closest_point(flow_field.start_nodes[0].position, true, false)
|
||||
points.append(global_position + Vector3(0, 0.15, 0))
|
||||
while node.best_path:
|
||||
node = node.best_path
|
||||
points.append(node.position + Vector3(0, 0.15, 0))
|
||||
path_vfx.path(points)
|
||||
|
||||
|
||||
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_spawn_air_enemy(enemy_num: int, pos: Vector3, id1: int, id2: int) -> void:
|
||||
var enemy: EnemyController
|
||||
enemy = game_manager.level.enemy_pool[enemy_num].scene.instantiate()
|
||||
enemy.stats = game_manager.level.enemy_pool[enemy_num]
|
||||
enemy.corpse_root = game_manager.level.corpses
|
||||
enemy.name = str(id1) + str(id2)
|
||||
enemy.position = pos + global_position
|
||||
enemy.died.connect(enemy_died_callback)
|
||||
enemy.reached_goal.connect(enemy_reached_goal_callback)
|
||||
enemy.movement_controller.goal = dest
|
||||
enemy_path.add_child(enemy)
|
||||
|
||||
|
||||
func spawn_wave() -> void:
|
||||
enemies_to_spawn = 0
|
||||
enemy_spawn_timers = {}
|
||||
for cassette: EnemyGroup in current_wave:
|
||||
enemy_types_to_spawn[cassette.enemy] += cassette.count
|
||||
enemies_to_spawn += cassette.count
|
||||
#print(cassette.enemy.title + ": " + str(cassette.count))
|
||||
enemy_spawn_timers[cassette.enemy] = 0.0
|
||||
enemies_spawned[cassette.enemy] = 0
|
||||
current_wave = []
|
||||
done_spawning = false
|
||||
|
||||
|
||||
func add_cassette(new_cassette: EnemyGroup) -> void:
|
||||
current_wave.append(new_cassette)
|
||||
enemy_types_to_spawn[new_cassette.enemy] = 0
|
||||
Reference in New Issue
Block a user