feat: spawn enemies from reusable definitions
This commit is contained in:
@@ -34,8 +34,7 @@ var factions: Dictionary = {}
|
||||
var economy: RefCounted
|
||||
var npcs: Array[SimNPC] = []
|
||||
var _npcs_by_id: Dictionary = {}
|
||||
var next_combatant_id := 0
|
||||
var next_wolf_id := 0
|
||||
var combatant_factory := CombatantFactory.new()
|
||||
var current_tick := 0
|
||||
var village_center := Vector3.ZERO
|
||||
var last_war_resolved_tick := -1
|
||||
@@ -222,24 +221,18 @@ func player_attack(combatant_id: StringName) -> float:
|
||||
|
||||
|
||||
func spawn_wolf(position: Vector3) -> StringName:
|
||||
var definition := SimulationEnemies.get_enemy(&"enemy_wolf")
|
||||
var wolf_id := StringName("wolf_%d" % next_wolf_id)
|
||||
next_wolf_id += 1
|
||||
var wolf := CombatantStateRecord.create(
|
||||
wolf_id,
|
||||
SimulationIds.COMBATANT_KIND_WOLF,
|
||||
SimulationIds.FACTION_TRIBE,
|
||||
definition.display_name if definition != null else "Wolf",
|
||||
position,
|
||||
definition.health if definition != null else 40.0,
|
||||
definition.weapon_id if definition != null else SimulationIds.ITEM_CLAW,
|
||||
CombatantStateRecord.NO_NPC_ID,
|
||||
true
|
||||
)
|
||||
combatants[wolf_id] = wolf
|
||||
return spawn_enemy(&"enemy_wolf", position)
|
||||
|
||||
|
||||
func spawn_enemy(enemy_definition_id: StringName, position: Vector3) -> StringName:
|
||||
var enemy := combatant_factory.create_enemy(enemy_definition_id, position)
|
||||
if enemy == null:
|
||||
return &""
|
||||
var combatant_id := enemy.get_combatant_id()
|
||||
combatants[combatant_id] = enemy
|
||||
_combatant_ids_dirty = true
|
||||
combatant_spawned.emit(wolf_id)
|
||||
return wolf_id
|
||||
combatant_spawned.emit(combatant_id)
|
||||
return combatant_id
|
||||
|
||||
|
||||
func _apply_damage(target: CombatantStateRecord, damage: float, actor_id: int) -> float:
|
||||
@@ -291,7 +284,11 @@ func _advance_wolves() -> void:
|
||||
var combatant := combatants[combatant_id] as CombatantStateRecord
|
||||
if combatant == null or not combatant.is_alive():
|
||||
continue
|
||||
if combatant.get_kind() != SimulationIds.COMBATANT_KIND_WOLF:
|
||||
var definition := _enemy_definition_for(combatant)
|
||||
if (
|
||||
definition == null
|
||||
or definition.behavior_profile_id != EnemyDefinition.BEHAVIOR_PROFILE_WOLF_HUNT
|
||||
):
|
||||
continue
|
||||
var target := _find_nearest_defender(combatant.get_position(), WOLF_HUNT_RADIUS)
|
||||
if target == null:
|
||||
@@ -302,8 +299,7 @@ func _advance_wolves() -> void:
|
||||
var to_target := target.get_position() - combatant.get_position()
|
||||
to_target.y = 0.0
|
||||
if to_target.length() > reach:
|
||||
var definition := SimulationEnemies.get_enemy(&"enemy_wolf")
|
||||
var speed := definition.move_speed if definition != null else 3.2
|
||||
var speed := definition.move_speed
|
||||
var step_distance := minf(speed * tick_interval, to_target.length() - reach)
|
||||
combatant.set_position(
|
||||
combatant.get_position() + to_target.normalized() * maxf(step_distance, 0.0)
|
||||
@@ -422,25 +418,17 @@ func village_defender_count() -> int:
|
||||
|
||||
|
||||
func _start_raid(tribe: FactionStateRecord, simulation_tick: int) -> void:
|
||||
var definition := SimulationEnemies.get_enemy(&"enemy_raider")
|
||||
tribe.set_war_plan(SimulationIds.WAR_PLAN_RAIDING, simulation_tick)
|
||||
tribe.set_stance(SimulationIds.STANCE_HOSTILE)
|
||||
var raider_ids: Array[StringName] = []
|
||||
for index in range(tribe.get_warriors()):
|
||||
var raider_id := StringName("raider_%d" % next_combatant_id)
|
||||
next_combatant_id += 1
|
||||
var offset := Vector3(float(index * 2 - tribe.get_warriors()), 0.0, 0.0)
|
||||
var raider := CombatantStateRecord.create(
|
||||
raider_id,
|
||||
SimulationIds.COMBATANT_KIND_RAIDER,
|
||||
SimulationIds.FACTION_TRIBE,
|
||||
definition.display_name if definition != null else "Raider",
|
||||
village_center + RAID_SPAWN_OFFSET + offset,
|
||||
definition.health if definition != null else 60.0,
|
||||
definition.weapon_id if definition != null else SimulationIds.ITEM_SWORD,
|
||||
CombatantStateRecord.NO_NPC_ID,
|
||||
true
|
||||
var raider := combatant_factory.create_enemy(
|
||||
&"enemy_raider", village_center + RAID_SPAWN_OFFSET + offset
|
||||
)
|
||||
if raider == null:
|
||||
continue
|
||||
var raider_id := raider.get_combatant_id()
|
||||
combatants[raider_id] = raider
|
||||
_combatant_ids_dirty = true
|
||||
raider_ids.append(raider_id)
|
||||
@@ -695,6 +683,12 @@ func _get_faction(faction_id: StringName) -> FactionStateRecord:
|
||||
return factions.get(faction_id) as FactionStateRecord
|
||||
|
||||
|
||||
func _enemy_definition_for(combatant: CombatantStateRecord) -> EnemyDefinition:
|
||||
if combatant == null or combatant.get_enemy_definition_id().is_empty():
|
||||
return null
|
||||
return SimulationEnemies.get_enemy(combatant.get_enemy_definition_id())
|
||||
|
||||
|
||||
func _narrative_event_requested(
|
||||
event_type: StringName,
|
||||
actor_id: int,
|
||||
@@ -738,6 +732,7 @@ func restore_state_records(
|
||||
combatants.clear()
|
||||
for combatant in combatant_records:
|
||||
combatants[combatant.get_combatant_id()] = combatant
|
||||
combatant_factory.restore_allocator(combatant_records)
|
||||
_combatant_ids_dirty = true
|
||||
factions.clear()
|
||||
for faction in faction_records:
|
||||
|
||||
Reference in New Issue
Block a user