126 lines
3.7 KiB
TypeScript
126 lines
3.7 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { applyAction } from '../simulation';
|
|
import { type World, type Actor, type EntityId } from '../types';
|
|
|
|
describe('Combat Simulation', () => {
|
|
const createTestWorld = (actors: Map<EntityId, Actor>): World => ({
|
|
width: 10,
|
|
height: 10,
|
|
tiles: new Array(100).fill(0),
|
|
actors,
|
|
exit: { x: 9, y: 9 }
|
|
});
|
|
|
|
describe('applyAction - attack', () => {
|
|
it('should deal damage when player attacks enemy', () => {
|
|
const actors = new Map<EntityId, Actor>();
|
|
actors.set(1, {
|
|
id: 1,
|
|
isPlayer: true,
|
|
pos: { x: 3, y: 3 },
|
|
speed: 100,
|
|
energy: 0,
|
|
stats: { maxHp: 20, hp: 20, attack: 5, defense: 2 }
|
|
});
|
|
actors.set(2, {
|
|
id: 2,
|
|
isPlayer: false,
|
|
pos: { x: 4, y: 3 },
|
|
speed: 100,
|
|
energy: 0,
|
|
stats: { maxHp: 10, hp: 10, attack: 3, defense: 1 }
|
|
});
|
|
|
|
const world = createTestWorld(actors);
|
|
const events = applyAction(world, 1, { type: 'attack', targetId: 2 });
|
|
|
|
const enemy = world.actors.get(2)!;
|
|
expect(enemy.hp).toBeLessThan(10);
|
|
|
|
// Should have attack event
|
|
expect(events.some(e => e.type === 'attacked')).toBe(true);
|
|
});
|
|
|
|
it('should kill enemy when damage exceeds hp', () => {
|
|
const actors = new Map<EntityId, Actor>();
|
|
actors.set(1, {
|
|
id: 1,
|
|
isPlayer: true,
|
|
pos: { x: 3, y: 3 },
|
|
speed: 100,
|
|
energy: 0,
|
|
stats: { maxHp: 20, hp: 20, attack: 50, defense: 2 }
|
|
});
|
|
actors.set(2, {
|
|
id: 2,
|
|
isPlayer: false,
|
|
pos: { x: 4, y: 3 },
|
|
speed: 100,
|
|
energy: 0,
|
|
stats: { maxHp: 10, hp: 10, attack: 3, defense: 1 }
|
|
});
|
|
|
|
const world = createTestWorld(actors);
|
|
const events = applyAction(world, 1, { type: 'attack', targetId: 2 });
|
|
|
|
// Enemy should be removed from world
|
|
expect(world.actors.has(2)).toBe(false);
|
|
|
|
// Should have killed event
|
|
expect(events.some(e => e.type === 'killed')).toBe(true);
|
|
});
|
|
|
|
it('should apply defense to reduce damage', () => {
|
|
const actors = new Map<EntityId, Actor>();
|
|
actors.set(1, {
|
|
id: 1,
|
|
isPlayer: true,
|
|
pos: { x: 3, y: 3 },
|
|
speed: 100,
|
|
energy: 0,
|
|
stats: { maxHp: 20, hp: 20, attack: 5, defense: 2 }
|
|
});
|
|
actors.set(2, {
|
|
id: 2,
|
|
isPlayer: false,
|
|
pos: { x: 4, y: 3 },
|
|
speed: 100,
|
|
energy: 0,
|
|
stats: { maxHp: 10, hp: 10, attack: 3, defense: 3 }
|
|
});
|
|
|
|
const world = createTestWorld(actors);
|
|
const events = applyAction(world, 1, { type: 'attack', targetId: 2 });
|
|
|
|
const enemy = world.actors.get(2)!;
|
|
const damage = 10 - enemy.stats!. hp;
|
|
|
|
// Damage should be reduced by defense (5 attack - 3 defense = 2 damage)
|
|
expect(damage).toBe(2);
|
|
});
|
|
});
|
|
|
|
describe('applyAction - move', () => {
|
|
it('should move actor to new position', () => {
|
|
const actors = new Map<EntityId, Actor>();
|
|
actors.set(1, {
|
|
id: 1,
|
|
isPlayer: true,
|
|
pos: { x: 3, y: 3 },
|
|
speed: 100,
|
|
energy: 0,
|
|
stats: { maxHp: 20, hp: 20, attack: 5, defense: 2 }
|
|
});
|
|
|
|
const world = createTestWorld(actors);
|
|
const events = applyAction(world, 1, { type: 'move', dx: 1, dy: 0 });
|
|
|
|
const player = world.actors.get(1)!;
|
|
expect(player.pos).toEqual({ x: 4, y: 3 });
|
|
|
|
// Should have moved event
|
|
expect(events.some(e => e.type === 'moved')).toBe(true);
|
|
});
|
|
});
|
|
});
|