feat(industry): add invention registration helper

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-03-08 23:48:10 +00:00
parent d7fbe5f547
commit 3480405185
2 changed files with 145 additions and 0 deletions
@@ -0,0 +1,97 @@
import { describe, it, expect } from 'vitest';
import { registerInvention } from '../inventionRegistrar.js';
import { ItemRegistry } from '../itemRegistry.js';
import { RecipeRegistry } from '../recipeRegistry.js';
import { createInventionTimeline } from '../inventionTimeline.js';
import type { RawInvention } from '../inventionValidator.js';
function createRegistries() {
return {
itemRegistry: ItemRegistry.createDefault(),
recipeRegistry: RecipeRegistry.createDefault(),
timeline: createInventionTimeline(),
};
}
describe('registerInvention', () => {
it('registers new item and recipe', () => {
const { itemRegistry, recipeRegistry, timeline } = createRegistries();
const raw: RawInvention = {
name: 'rope',
description: 'Twisted plant fibers',
category: 'material',
inputs: [{ itemId: 'log', quantity: 2 }],
};
const result = registerInvention({
raw,
itemId: 'rope',
itemRegistry,
recipeRegistry,
timeline,
inventorEntityId: 1,
inventorName: 'Gwen',
tick: 500,
day: 2,
});
expect(result).toBe(true);
expect(itemRegistry.get('rope')).toBeDefined();
expect(itemRegistry.get('rope')!.source).toBe('invented');
expect(itemRegistry.get('rope')!.inventedBy!.name).toBe('Gwen');
expect(recipeRegistry.get('craft_rope')).toBeDefined();
expect(recipeRegistry.get('craft_rope')!.source).toBe('invented');
expect(timeline.getAll()).toHaveLength(1);
});
it('registers structure recipe with build_ prefix', () => {
const { itemRegistry, recipeRegistry, timeline } = createRegistries();
const raw: RawInvention = {
name: 'kiln',
description: 'A stone furnace',
category: 'structure',
inputs: [{ itemId: 'stone', quantity: 5 }],
workshopType: 'kiln',
};
registerInvention({
raw,
itemId: 'kiln',
itemRegistry,
recipeRegistry,
timeline,
inventorEntityId: 2,
inventorName: 'Bram',
tick: 700,
day: 3,
});
expect(recipeRegistry.get('build_kiln')).toBeDefined();
expect(recipeRegistry.get('build_kiln')!.outputItemId).toBe('kiln');
});
it('includes toolRequired in recipe', () => {
const { itemRegistry, recipeRegistry, timeline } = createRegistries();
const raw: RawInvention = {
name: 'plank',
description: 'A wooden plank',
category: 'material',
inputs: [{ itemId: 'log', quantity: 1 }],
toolRequired: 'wooden_axe',
};
registerInvention({
raw,
itemId: 'plank',
itemRegistry,
recipeRegistry,
timeline,
inventorEntityId: 1,
inventorName: 'Gwen',
tick: 500,
day: 2,
});
expect(recipeRegistry.get('craft_plank')!.toolRequired).toBe('wooden_axe');
});
});
+48
View File
@@ -0,0 +1,48 @@
import type { EntityId } from '@dflike/shared';
import type { ItemRegistry } from './itemRegistry.js';
import type { RecipeRegistry } from './recipeRegistry.js';
import type { InventionTimeline } from './inventionTimeline.js';
import type { RawInvention } from './inventionValidator.js';
export interface RegisterInventionArgs {
raw: RawInvention;
itemId: string;
itemRegistry: ItemRegistry;
recipeRegistry: RecipeRegistry;
timeline: InventionTimeline;
inventorEntityId: EntityId;
inventorName: string;
tick: number;
day: number;
}
export function registerInvention(args: RegisterInventionArgs): boolean {
const { raw, itemId, itemRegistry, recipeRegistry, timeline, inventorEntityId, inventorName, tick, day } = args;
// Register item
itemRegistry.register({
id: itemId,
name: raw.name,
description: raw.description,
category: raw.category as 'resource' | 'tool' | 'material' | 'structure',
source: 'invented',
inventedBy: { entityId: inventorEntityId, name: inventorName, tick, day },
});
// Register recipe
const recipePrefix = raw.category === 'structure' ? 'build_' : 'craft_';
recipeRegistry.register({
id: `${recipePrefix}${itemId}`,
outputItemId: itemId,
outputQuantity: 1,
inputs: raw.inputs,
workshopType: raw.workshopType ?? undefined,
toolRequired: raw.toolRequired ?? undefined,
source: 'invented',
});
// Record in timeline
timeline.record({ itemId, inventorEntityId, inventorName, tick, day });
return true;
}