refactor
This commit is contained in:
@@ -1,51 +1,93 @@
|
||||
extends Node
|
||||
|
||||
const ENEMY_SCENE: PackedScene = preload("res://scenes/enemy/enemy.tscn")
|
||||
const ENEMY_SCENE: PackedScene = preload("res://scenes/entities/enemy/enemy.tscn")
|
||||
const PORTAL_SCENE: PackedScene = preload("res://scenes/entities/portal/portal.tscn")
|
||||
const GATE_SCENE: PackedScene = preload("res://scenes/entities/gate/gate.tscn")
|
||||
|
||||
func _ready() -> void:
|
||||
EventBus.health_changed.connect(_on_health_changed)
|
||||
EventBus.entity_died.connect(_on_entity_died)
|
||||
func _enemy_root() -> Node3D:
|
||||
var n: Node = get_node_or_null("/root/World/EntityRoot/Enemies")
|
||||
if n == null:
|
||||
n = get_node_or_null("/root/Dungeon/EntityRoot/Enemies")
|
||||
return n
|
||||
|
||||
func _on_health_changed(entity: Node, current: float, max_val: float) -> void:
|
||||
if not entity.is_in_group("portals"):
|
||||
return
|
||||
if current <= 0:
|
||||
return
|
||||
var data: Dictionary = PortalData.entities.get(entity, {})
|
||||
if data.is_empty():
|
||||
return
|
||||
var ratio: float = current / max_val
|
||||
var thresholds: Array = data["thresholds"]
|
||||
var triggered: Array = data["triggered"]
|
||||
var spawn_count: int = data["spawn_count"]
|
||||
for i in range(thresholds.size()):
|
||||
if not triggered[i] and ratio <= thresholds[i]:
|
||||
triggered[i] = true
|
||||
_spawn_enemies(entity, spawn_count)
|
||||
func _portal_root() -> Node3D:
|
||||
var n: Node = get_node_or_null("/root/World/EntityRoot/Portals")
|
||||
if n == null:
|
||||
n = get_node_or_null("/root/Dungeon/EntityRoot/Portals")
|
||||
return n
|
||||
|
||||
func _spawn_enemies(portal: Node, count: int) -> void:
|
||||
var spawned: Array = []
|
||||
var is_red: bool = portal.is_in_group("red_portal")
|
||||
var portal_bonus: float = 10.0 if is_red else 1.0
|
||||
var total_scale: float = PlayerData.level_scale * portal_bonus
|
||||
for j in range(count):
|
||||
var entity: Node = ENEMY_SCENE.instantiate()
|
||||
entity.spawn_scale = total_scale
|
||||
var offset := Vector3(randf_range(-2, 2), 0, randf_range(-2, 2))
|
||||
portal.get_parent().add_child(entity)
|
||||
if is_red:
|
||||
entity.add_to_group("red_enemies")
|
||||
entity.global_position = portal.global_position + offset
|
||||
EnemyData.set_stat(entity, "portal", portal)
|
||||
spawned.append(entity)
|
||||
var player: Node = get_tree().get_first_node_in_group("player")
|
||||
if player:
|
||||
var dist: float = portal.global_position.distance_to(player.global_position)
|
||||
if dist <= 10.0:
|
||||
for entity in spawned:
|
||||
EventBus.enemy_detected.emit(entity, player)
|
||||
EventBus.portal_spawn.emit(portal, spawned)
|
||||
func _gate_root() -> Node3D:
|
||||
var n: Node = get_node_or_null("/root/World/EntityRoot/Gates")
|
||||
if n == null:
|
||||
n = get_node_or_null("/root/Dungeon/EntityRoot/Gates")
|
||||
return n
|
||||
|
||||
func _on_entity_died(entity: Node) -> void:
|
||||
if entity.is_in_group("portals"):
|
||||
PortalData.deregister(entity)
|
||||
func spawn_enemy_at(pos: Vector3, strong: bool = false, mult: float = 1.0) -> Node:
|
||||
if not multiplayer.is_server() and multiplayer.multiplayer_peer != null:
|
||||
return null
|
||||
var root := _enemy_root()
|
||||
if root == null:
|
||||
return null
|
||||
var e: CharacterBody3D = ENEMY_SCENE.instantiate()
|
||||
var stats := EnemyStats.new()
|
||||
var s: float = mult * (3.0 if strong else 1.0)
|
||||
stats.max_health = 30.0 * s
|
||||
stats.attack_damage = 5.0 * s
|
||||
stats.attack_range = 2.0
|
||||
stats.attack_cooldown = 1.5
|
||||
stats.speed = 3.0
|
||||
stats.aggro_radius = 12.0
|
||||
stats.xp_value = 5.0 * s
|
||||
e.stats_resource = stats
|
||||
e.name = "Enemy_%d" % (Time.get_ticks_msec() + randi() % 1000)
|
||||
root.add_child(e, true)
|
||||
e.global_position = pos
|
||||
return e
|
||||
|
||||
func spawn_boss_at(pos: Vector3, mult: float = 1.0) -> Node:
|
||||
if not multiplayer.is_server() and multiplayer.multiplayer_peer != null:
|
||||
return null
|
||||
var root := _enemy_root()
|
||||
if root == null:
|
||||
return null
|
||||
var b: CharacterBody3D = ENEMY_SCENE.instantiate()
|
||||
b.is_boss = true
|
||||
var stats := BossStats.new()
|
||||
stats.max_health = 250.0 * mult
|
||||
stats.attack_damage = 12.0 * mult
|
||||
stats.attack_range = 3.0
|
||||
stats.attack_cooldown = 1.6
|
||||
stats.speed = 3.5
|
||||
stats.xp_value = 100.0 * mult
|
||||
b.stats_resource = stats
|
||||
b.name = "Boss_%d" % Time.get_ticks_msec()
|
||||
root.add_child(b, true)
|
||||
b.global_position = pos
|
||||
return b
|
||||
|
||||
func spawn_portal_at(pos: Vector3, is_red: bool) -> Node:
|
||||
if not multiplayer.is_server() and multiplayer.multiplayer_peer != null:
|
||||
return null
|
||||
var root := _portal_root()
|
||||
if root == null:
|
||||
return null
|
||||
var p: StaticBody3D = PORTAL_SCENE.instantiate()
|
||||
p.is_red = is_red
|
||||
p.name = "Portal_%d" % Time.get_ticks_msec()
|
||||
root.add_child(p, true)
|
||||
p.global_position = pos
|
||||
EventBus.portal_spawned.emit(p)
|
||||
return p
|
||||
|
||||
func spawn_gate_at(pos: Vector3, is_red: bool) -> Node:
|
||||
if not multiplayer.is_server() and multiplayer.multiplayer_peer != null:
|
||||
return null
|
||||
var root := _gate_root()
|
||||
if root == null:
|
||||
return null
|
||||
var g: StaticBody3D = GATE_SCENE.instantiate()
|
||||
g.is_red = is_red
|
||||
g.name = "Gate_%s_%d" % ["red" if is_red else "n", Time.get_ticks_msec() + randi() % 1000]
|
||||
root.add_child(g, true)
|
||||
g.global_position = pos
|
||||
return g
|
||||
|
||||
Reference in New Issue
Block a user