feat: score resource discovery by comfort and safety
This commit is contained in:
@@ -30,16 +30,16 @@ func _resolve_resource(
|
||||
active_world_adapter: Node
|
||||
) -> Dictionary:
|
||||
var best: Dictionary = {}
|
||||
var best_distance := INF
|
||||
var best_score := INF
|
||||
for candidate in active_world_adapter.get_resource_candidates(definition.resource_action_id):
|
||||
var node_id := StringName(candidate["target_id"])
|
||||
var state: ResourceStateRecord = simulation_manager.get_resource_state(node_id)
|
||||
if state == null or not state.can_npc_use() or not state.is_available_for(npc.id):
|
||||
continue
|
||||
var position: Vector3 = candidate["position"]
|
||||
var distance := origin.distance_squared_to(position)
|
||||
if distance < best_distance:
|
||||
best_distance = distance
|
||||
var score := score_resource_candidate(npc, origin, position, state)
|
||||
if score < best_score:
|
||||
best_score = score
|
||||
best = candidate
|
||||
if best.is_empty():
|
||||
return {}
|
||||
@@ -47,3 +47,17 @@ func _resolve_resource(
|
||||
if not simulation_manager.reserve_resource(target_id, npc.id):
|
||||
return {}
|
||||
return best
|
||||
|
||||
|
||||
func score_resource_candidate(
|
||||
npc: SimNPC, origin: Vector3, position: Vector3, state: ResourceStateRecord
|
||||
) -> float:
|
||||
var distance := origin.distance_to(position)
|
||||
var comfort_overage := maxf(distance - state.get_comfort_distance(), 0.0)
|
||||
var risk_weight := 20.0 + maxf(100.0 - npc.energy, 0.0) * 0.2
|
||||
return (
|
||||
distance
|
||||
+ comfort_overage * 2.5
|
||||
+ state.get_safety_risk() * risk_weight
|
||||
- state.get_discovery_priority()
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user