feat(brain): add gather goal when productivity is low
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,24 @@
|
||||
import {
|
||||
HUNGER_THRESHOLD, ENERGY_THRESHOLD, Direction,
|
||||
type Needs, type Movement, type NPCBrain, type Position, type SocialState,
|
||||
HUNGER_THRESHOLD, ENERGY_THRESHOLD, PRODUCTIVITY_THRESHOLD, Direction,
|
||||
type GoalType, type Needs, type Movement, type NPCBrain, type Position, type SocialState,
|
||||
} from '@dflike/shared';
|
||||
import type { World } from '../ecs/World.js';
|
||||
import type { GameMap } from '../map/GameMap.js';
|
||||
import { findPath } from '../map/pathfinding.js';
|
||||
import type { EventMemoryService } from '../llm/eventMemoryService.js';
|
||||
|
||||
function findNearestResource(map: GameMap, from: Position): Position | null {
|
||||
const tiles = map.resourceTiles;
|
||||
if (tiles.length === 0) return null;
|
||||
let best = tiles[0];
|
||||
let bestDist = Math.abs(from.x - best.x) + Math.abs(from.y - best.y);
|
||||
for (let i = 1; i < tiles.length; i++) {
|
||||
const d = Math.abs(from.x - tiles[i].x) + Math.abs(from.y - tiles[i].y);
|
||||
if (d < bestDist) { best = tiles[i]; bestDist = d; }
|
||||
}
|
||||
return { x: best.x, y: best.y };
|
||||
}
|
||||
|
||||
function closestPOI(map: GameMap, from: Position, type: 'food' | 'rest'): Position | null {
|
||||
const pois = map.getPointsOfInterest(type);
|
||||
if (pois.length === 0) return null;
|
||||
@@ -71,15 +83,16 @@ export function npcBrainSystem(world: World, map: GameMap, eventMemoryService?:
|
||||
|
||||
// Determine new goal based on needs priority
|
||||
const prevGoal = brain.currentGoal;
|
||||
let goal: 'rest' | 'eat' | 'wander' = 'wander';
|
||||
let goal: GoalType = 'wander';
|
||||
if (needs.energy < ENERGY_THRESHOLD) goal = 'rest';
|
||||
else if (needs.hunger < HUNGER_THRESHOLD) goal = 'eat';
|
||||
else if (needs.productivity < PRODUCTIVITY_THRESHOLD) goal = 'gather';
|
||||
|
||||
brain.currentGoal = goal;
|
||||
|
||||
if (eventMemoryService && brain.currentGoal !== prevGoal && prevGoal !== null) {
|
||||
const name = world.getComponent<string>(entity, 'name') ?? 'Unknown';
|
||||
const goalLabels: Record<string, string> = { wander: 'wandering', eat: 'looking for food', rest: 'looking for rest' };
|
||||
const goalLabels: Record<string, string> = { wander: 'wandering', eat: 'looking for food', rest: 'looking for rest', gather: 'looking for resources' };
|
||||
eventMemoryService.record(entity, {
|
||||
type: 'goal_change',
|
||||
tick: 0,
|
||||
@@ -95,6 +108,12 @@ export function npcBrainSystem(world: World, map: GameMap, eventMemoryService?:
|
||||
target = closestPOI(map, pos, 'food');
|
||||
} else if (goal === 'rest') {
|
||||
target = closestPOI(map, pos, 'rest');
|
||||
} else if (goal === 'gather') {
|
||||
target = findNearestResource(map, pos);
|
||||
if (!target) {
|
||||
goal = 'wander';
|
||||
brain.currentGoal = 'wander';
|
||||
}
|
||||
}
|
||||
if (!target) {
|
||||
target = map.getRandomWalkable();
|
||||
|
||||
Reference in New Issue
Block a user