feat: support extra health state mechanics
This commit is contained in:
@@ -164,6 +164,53 @@ describe('loadout mechanic timeline', () => {
|
||||
expect(sprinting.every((event) => event.values?.state === 'sprinting')).toBe(true);
|
||||
});
|
||||
|
||||
it('seeds Extra Health state before periodic stack evaluation', () => {
|
||||
const profile = createDraft().combatProfile;
|
||||
profile.encounterSeconds = 2;
|
||||
profile.extraHealthActive = true;
|
||||
const timeline = buildWeaponMechanicTimeline(
|
||||
{ rpm: 60, magazine: 100, reload_speed: 0 },
|
||||
profile
|
||||
);
|
||||
expect(timeline.filter((event) => event.kind === 'extra_health_changed')).toEqual([{
|
||||
kind: 'extra_health_changed',
|
||||
at: 0,
|
||||
actorId: 'agent',
|
||||
values: { hasExtraHealth: true }
|
||||
}]);
|
||||
|
||||
const program: MechanicProgram = {
|
||||
id: 'extra-health-periodic-stacks',
|
||||
name: 'Extra Health periodic stacks',
|
||||
pools: [
|
||||
{ key: 'active', label: 'Active', scope: 'agent', initial: 0, min: 0, max: 1 },
|
||||
{ key: 'stacks', label: 'Stacks', scope: 'agent', initial: 0, min: 0, max: 10 }
|
||||
],
|
||||
clauses: [{
|
||||
id: 'set-active',
|
||||
when: 'extra_health_changed',
|
||||
if: { kind: 'compare', left: { source: 'event', path: 'values.hasExtraHealth' }, operator: 'eq', right: true },
|
||||
reducer: { kind: 'none' },
|
||||
mutations: [{ kind: 'set', pool: 'active', value: 1 }]
|
||||
}, {
|
||||
id: 'gain-stack',
|
||||
when: 'tick',
|
||||
if: { kind: 'compare', left: { source: 'pool', pool: 'active' }, operator: 'eq', right: 1 },
|
||||
reducer: { kind: 'periodic', intervalSeconds: 1 },
|
||||
mutations: [{ kind: 'add', pool: 'stacks', value: 1 }]
|
||||
}]
|
||||
};
|
||||
const result = evaluateMechanicProgram(program, timeline, {
|
||||
mode: 'custom',
|
||||
encounterSeconds: 2
|
||||
});
|
||||
expect(result.finalState).toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({ pool: 'stacks', value: 2 })
|
||||
]));
|
||||
expect(result.emissions.filter((emission) => emission.clauseId === 'gain-stack')
|
||||
.map((emission) => emission.at)).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
it('falls back to a documented Tier I mechanic when equipment Tier II is absent', () => {
|
||||
const persistedRule = {
|
||||
rule: {
|
||||
|
||||
Reference in New Issue
Block a user