feat(ai): Add city drift behavior for wild creatures to alter movement and state near cities

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
autocommit 2026-04-16 11:47:19 -07:00
parent 58f15ad885
commit 5f2428f438

View file

@ -13,8 +13,8 @@ const CombatResolverScript = preload("res://engine/src/modules/combat/combat_res
const DEFAULT_DETECTION_RADIUS: int = 4
const DEFAULT_LEASH_RADIUS: int = 5
const PREDATOR_RADIUS: int = 5
const ROAM_CHANCE: int = 40
const CITY_DRIFT_CHANCE: int = 20
var _rng: RandomNumberGenerator = RandomNumberGenerator.new()
var _unit_manager: RefCounted
@ -95,8 +95,7 @@ func _act(
var home_pos: Vector2i = _find_nearest_lair(
unit.position, leash_radius + detection_radius
)
var predator_scan: int = max(detection_radius, PREDATOR_RADIUS)
var target: RefCounted = _find_attack_target(unit, predator_scan)
var target: RefCounted = _find_attack_target(unit, detection_radius)
if target != null:
# Step toward target, then attack if adjacent and still able.
@ -113,6 +112,8 @@ func _act(
unit.movement_remaining = 0
elif _is_outside_leash(unit.position, home_pos, leash_radius):
_move_toward(unit, home_pos, game_map)
elif _rng.randi_range(1, 100) <= CITY_DRIFT_CHANCE:
_drift_toward_city(unit, game_map)
elif _rng.randi_range(1, 100) <= ROAM_CHANCE:
_roam(unit, home_pos, game_map, leash_radius)
@ -159,6 +160,34 @@ func _is_outside_leash(
return HexUtilsScript.hex_distance(unit_pos, home_pos) > leash_radius
func _drift_toward_city(unit: RefCounted, game_map: RefCounted) -> void:
var city_pos: Vector2i = unit.position
var best_d: int = 999999
for p: RefCounted in GameState.players:
for c: RefCounted in p.cities:
var d: int = HexUtilsScript.hex_distance(unit.position, c.position)
if d < best_d:
best_d = d
city_pos = c.position
if city_pos == unit.position:
return
var best: Vector2i = unit.position
for n: Vector2i in HexUtilsScript.get_neighbors(unit.position):
var tile: Resource = game_map.get_tile(n)
if tile == null or tile.is_water() or _has_player_unit_at(n):
continue
var d: int = HexUtilsScript.hex_distance(n, city_pos)
if d < best_d:
best_d = d
best = n
if best == unit.position:
return
var from_pos: Vector2i = unit.position
unit.movement_remaining -= 1
unit.position = best
EventBus.unit_moved.emit(unit, from_pos, best)
func _move_toward(
unit: RefCounted,
target: Vector2i,