feat(spawner): add productivity need and inventory to spawned NPCs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@ import { describe, it, expect } from 'vitest';
|
||||
import { World } from '../../ecs/World.js';
|
||||
import { GameMap } from '../../map/GameMap.js';
|
||||
import { spawnNPC } from '../spawner.js';
|
||||
import type { Position, Stats } from '@dflike/shared';
|
||||
import type { Position, Stats, Needs } from '@dflike/shared';
|
||||
|
||||
describe('spawnNPC', () => {
|
||||
it('spawns at random position when no hint given', () => {
|
||||
@@ -49,6 +49,25 @@ describe('spawnNPC', () => {
|
||||
expect(world.getComponent(entity, 'backstory')).toBe('');
|
||||
});
|
||||
|
||||
it('spawned NPC has productivity need', () => {
|
||||
const world = new World();
|
||||
const map = new GameMap();
|
||||
const entity = spawnNPC(world, map);
|
||||
const needs = world.getComponent<Needs>(entity, 'needs')!;
|
||||
expect(needs.productivity).toBeDefined();
|
||||
expect(needs.productivity).toBeGreaterThanOrEqual(60);
|
||||
});
|
||||
|
||||
it('spawned NPC has empty inventory', () => {
|
||||
const world = new World();
|
||||
const map = new GameMap();
|
||||
const entity = spawnNPC(world, map);
|
||||
const inventory = world.getComponent<Map<string, number>>(entity, 'inventory')!;
|
||||
expect(inventory).toBeDefined();
|
||||
expect(inventory).toBeInstanceOf(Map);
|
||||
expect(inventory.size).toBe(0);
|
||||
});
|
||||
|
||||
it('generates stats in 3-18 range', () => {
|
||||
const world = new World();
|
||||
const map = new GameMap();
|
||||
|
||||
@@ -16,6 +16,7 @@ export function spawnNPC(world: World, map: GameMap, positionHint?: Position, ev
|
||||
world.addComponent<Needs>(entity, 'needs', {
|
||||
hunger: 40 + Math.random() * 40, // 40-80
|
||||
energy: 40 + Math.random() * 40,
|
||||
productivity: 60 + Math.random() * 40, // 60-100
|
||||
});
|
||||
world.addComponent<Movement>(entity, 'movement', {
|
||||
state: 'idle',
|
||||
@@ -46,6 +47,7 @@ export function spawnNPC(world: World, map: GameMap, positionHint?: Position, ev
|
||||
world.addComponent<StatModifiers>(entity, 'statModifiers', { modifiers: [] });
|
||||
world.addComponent<Relationships>(entity, 'relationships', new Map());
|
||||
world.addComponent<string>(entity, 'backstory', '');
|
||||
world.addComponent<Map<string, number>>(entity, 'inventory', new Map());
|
||||
|
||||
eventMemoryService?.record(entity, {
|
||||
type: 'spawned',
|
||||
|
||||
@@ -33,7 +33,7 @@ function createNPC(
|
||||
): EntityId {
|
||||
const e = world.createEntity();
|
||||
world.addComponent<Position>(e, 'position', { x: 0, y: 0 });
|
||||
world.addComponent<Needs>(e, 'needs', { hunger: 80, energy: 80 });
|
||||
world.addComponent<Needs>(e, 'needs', { hunger: 80, energy: 80, productivity: 80 });
|
||||
world.addComponent<Movement>(e, 'movement', {
|
||||
state: 'idle', target: null, path: [], direction: 0, moveProgress: 0,
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ function createNPC(
|
||||
): EntityId {
|
||||
const e = world.createEntity();
|
||||
world.addComponent<Position>(e, 'position', { x, y });
|
||||
world.addComponent<Needs>(e, 'needs', { hunger: 80, energy: 80 });
|
||||
world.addComponent<Needs>(e, 'needs', { hunger: 80, energy: 80, productivity: 80 });
|
||||
world.addComponent<Movement>(e, 'movement', {
|
||||
state: 'idle', target: null, path: [], direction: 0, moveProgress: 0,
|
||||
});
|
||||
|
||||
@@ -22,6 +22,7 @@ function createNPC(
|
||||
world.addComponent<Needs>(e, 'needs', {
|
||||
hunger: opts?.hunger ?? 80,
|
||||
energy: opts?.energy ?? 80,
|
||||
productivity: 80,
|
||||
});
|
||||
world.addComponent<Movement>(e, 'movement', {
|
||||
state: opts?.walking ? 'walking' : 'idle',
|
||||
|
||||
@@ -18,7 +18,7 @@ function setupEntity(
|
||||
world.addComponent<Stats>(e, 'stats', base);
|
||||
world.addComponent<StatModifiers>(e, 'statModifiers', { modifiers: [...modifiers] });
|
||||
if (needs) {
|
||||
world.addComponent<Needs>(e, 'needs', { hunger: 80, energy: 80, ...needs });
|
||||
world.addComponent<Needs>(e, 'needs', { hunger: 80, energy: 80, productivity: 80, ...needs });
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ function makeNpc(world: World, name: string, needs?: Partial<Needs>): number {
|
||||
world.addComponent(entity, 'name', name);
|
||||
world.addComponent(entity, 'npcBrain', { currentGoal: 'wander' });
|
||||
world.addComponent<Stats>(entity, 'stats', makeStats());
|
||||
world.addComponent<Needs>(entity, 'needs', { hunger: 80, energy: 80, ...needs });
|
||||
world.addComponent<Needs>(entity, 'needs', { hunger: 80, energy: 80, productivity: 80, ...needs });
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user