first commmit
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user