feat(ai-specific): ✨ Implement combat resolution logic for WildCreatureAI to enhance strategic behavior during combat
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
75a5cdc0cf
commit
2a3f459bb2
1 changed files with 24 additions and 17 deletions
|
|
@ -9,6 +9,7 @@ const UnitScript = preload("res://engine/src/entities/unit.gd")
|
|||
const HexUtilsScript = preload("res://engine/src/map/hex_utils.gd")
|
||||
const PathfinderScript = preload("res://engine/src/map/pathfinder.gd")
|
||||
const UnitManagerScript = preload("res://engine/src/modules/management/unit_manager.gd")
|
||||
const CombatResolverScript = preload("res://engine/src/modules/combat/combat_resolver.gd")
|
||||
|
||||
const DEFAULT_DETECTION_RADIUS: int = 4
|
||||
const DEFAULT_LEASH_RADIUS: int = 5
|
||||
|
|
@ -93,10 +94,21 @@ func _act(
|
|||
var home_pos: Vector2i = _find_nearest_lair(
|
||||
unit.position, leash_radius + detection_radius
|
||||
)
|
||||
var target_pos: Variant = _find_attack_target(unit, detection_radius)
|
||||
var target: RefCounted = _find_attack_target(unit, detection_radius)
|
||||
|
||||
if target_pos != null:
|
||||
_move_toward(unit, target_pos, game_map)
|
||||
if target != null:
|
||||
# Step toward target, then attack if adjacent and still able.
|
||||
if HexUtilsScript.hex_distance(unit.position, target.position) > 1:
|
||||
_move_toward(unit, target.position, game_map)
|
||||
if (
|
||||
HexUtilsScript.hex_distance(unit.position, target.position) <= 1
|
||||
and not unit.has_attacked
|
||||
):
|
||||
var all_units: Array = GameState.get_primary_layer().get("units", [])
|
||||
var resolver: RefCounted = CombatResolverScript.new()
|
||||
resolver.resolve(unit, target, game_map, all_units)
|
||||
unit.has_attacked = true
|
||||
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) <= ROAM_CHANCE:
|
||||
|
|
@ -106,26 +118,21 @@ func _act(
|
|||
func _find_attack_target(
|
||||
unit: RefCounted,
|
||||
detection_radius: int,
|
||||
) -> Variant:
|
||||
) -> RefCounted:
|
||||
## Returns the nearest player-owned unit within detection_radius, or null.
|
||||
var primary_layer: Dictionary = GameState.get_primary_layer()
|
||||
var candidates: Array[Dictionary] = []
|
||||
var best: RefCounted = null
|
||||
var best_dist: int = 999999
|
||||
|
||||
for other: Variant in primary_layer.get("units", []):
|
||||
if not other is UnitScript:
|
||||
continue
|
||||
if other.owner < 0:
|
||||
if not other is UnitScript or other.owner < 0 or not other.is_alive():
|
||||
continue
|
||||
var dist: int = HexUtilsScript.hex_distance(unit.position, other.position)
|
||||
if dist <= detection_radius:
|
||||
candidates.append({"pos": other.position, "dist": dist})
|
||||
if dist <= detection_radius and dist < best_dist:
|
||||
best_dist = dist
|
||||
best = other
|
||||
|
||||
if candidates.is_empty():
|
||||
return null
|
||||
|
||||
candidates.sort_custom(func(a: Dictionary, b: Dictionary) -> bool:
|
||||
return a["dist"] < b["dist"]
|
||||
)
|
||||
return candidates[0]["pos"]
|
||||
return best
|
||||
|
||||
|
||||
func _find_nearest_lair(from_pos: Vector2i, search_radius: int) -> Vector2i:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue