87 lines
2.6 KiB
TypeScript
87 lines
2.6 KiB
TypeScript
import { DamageSystem, FIREBALL_KILL_RADIUS, SMOKE_KILL_RADIUS } from '@logic/DamageSystem';
|
|
import { PlayerStateMachine } from '@logic/PlayerStateMachine';
|
|
import { PlayerColorState } from '@common/Constants';
|
|
|
|
function setup() {
|
|
const psm = new PlayerStateMachine();
|
|
return { psm, ds: new DamageSystem(psm) };
|
|
}
|
|
|
|
describe('DamageSystem — fireball distance gate (req 10.4)', () => {
|
|
it('misses when distance exceeds FIREBALL_KILL_RADIUS', () => {
|
|
const { ds } = setup();
|
|
const r = ds.applyToPlayer({
|
|
attackType: 'fireball',
|
|
attackerX: 0,
|
|
attackerY: 0,
|
|
victimX: FIREBALL_KILL_RADIUS + 10,
|
|
victimY: 0,
|
|
});
|
|
expect(r).toBeNull();
|
|
});
|
|
|
|
it('kills when within radius regardless of color', () => {
|
|
const { psm, ds } = setup();
|
|
psm.pickupCrystalJade();
|
|
psm.pickupCrystalJade();
|
|
const r = ds.applyToPlayer({
|
|
attackType: 'fireball',
|
|
attackerX: 0,
|
|
attackerY: 0,
|
|
victimX: 50,
|
|
victimY: 0,
|
|
});
|
|
expect(r!.kind).toBe('died');
|
|
expect(psm.color).toBe(PlayerColorState.Red);
|
|
});
|
|
});
|
|
|
|
describe('DamageSystem — smoke bomb distance gate (req 10.5)', () => {
|
|
it('misses when distance exceeds SMOKE_KILL_RADIUS', () => {
|
|
const { ds } = setup();
|
|
const r = ds.applyToPlayer({
|
|
attackType: 'smoke_bomb',
|
|
attackerX: 0,
|
|
attackerY: 0,
|
|
victimX: SMOKE_KILL_RADIUS + 1,
|
|
victimY: 0,
|
|
});
|
|
expect(r).toBeNull();
|
|
});
|
|
|
|
it('kills when within radius', () => {
|
|
const { ds } = setup();
|
|
const r = ds.applyToPlayer({
|
|
attackType: 'smoke_bomb',
|
|
attackerX: 0,
|
|
attackerY: 0,
|
|
victimX: 40,
|
|
victimY: 0,
|
|
});
|
|
expect(r!.kind).toBe('died');
|
|
});
|
|
});
|
|
|
|
describe('DamageSystem — precedence (req 10.3)', () => {
|
|
it('i-frames beat fireball distance check', () => {
|
|
const { psm, ds } = setup();
|
|
psm.takeHit('shuriken'); // die → consumes a life and starts i-frames
|
|
const r = ds.applyToPlayer({
|
|
attackType: 'fireball',
|
|
attackerX: 0,
|
|
attackerY: 0,
|
|
victimX: 10,
|
|
victimY: 0,
|
|
});
|
|
expect(r).toEqual({ kind: 'no_effect', reason: 'iframe' });
|
|
});
|
|
});
|
|
|
|
describe('DamageSystem — applyToEnemy helper', () => {
|
|
it('reduces HP and floors at 0', () => {
|
|
const { ds } = setup();
|
|
expect(ds.applyToEnemy(3, 2)).toBe(1);
|
|
expect(ds.applyToEnemy(1, 5)).toBe(0);
|
|
});
|
|
});
|