Auto reload last reloadble weapon when reload is triggered
This commit is contained in:
145
src/scenes/systems/__tests__/ReloadLastWeapon.test.ts
Normal file
145
src/scenes/systems/__tests__/ReloadLastWeapon.test.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
|
||||
// Mock Phaser
|
||||
vi.mock('phaser', () => {
|
||||
class MockEventEmitter {
|
||||
on = vi.fn().mockReturnThis();
|
||||
once = vi.fn().mockReturnThis();
|
||||
emit = vi.fn().mockReturnThis();
|
||||
off = vi.fn().mockReturnThis();
|
||||
removeAllListeners = vi.fn().mockReturnThis();
|
||||
}
|
||||
|
||||
return {
|
||||
default: {
|
||||
Events: {
|
||||
EventEmitter: MockEventEmitter
|
||||
},
|
||||
Scene: class {
|
||||
events = new MockEventEmitter();
|
||||
add = {
|
||||
graphics: vi.fn(),
|
||||
sprite: vi.fn(),
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
import { PlayerInputHandler } from '../PlayerInputHandler';
|
||||
import { GameScene } from '../../GameScene';
|
||||
import type { CombatantActor, RangedWeaponItem } from '../../../core/types';
|
||||
|
||||
// Minimal mock for GameScene
|
||||
const createMockScene = () => {
|
||||
const scene = {
|
||||
gameInput: {
|
||||
on: vi.fn(),
|
||||
},
|
||||
targetingSystem: {
|
||||
itemId: null,
|
||||
isActive: false,
|
||||
},
|
||||
entityAccessor: {
|
||||
getPlayer: vi.fn(),
|
||||
},
|
||||
runState: {
|
||||
lastReloadableWeaponId: null,
|
||||
},
|
||||
startReload: vi.fn(),
|
||||
} as any;
|
||||
return scene;
|
||||
};
|
||||
|
||||
describe('Reload Last Used Weapon Logic', () => {
|
||||
let scene: any;
|
||||
let inputHandler: PlayerInputHandler;
|
||||
let reloadCallback: Function;
|
||||
|
||||
beforeEach(() => {
|
||||
scene = createMockScene();
|
||||
inputHandler = new PlayerInputHandler(scene);
|
||||
inputHandler.registerListeners();
|
||||
|
||||
// Find the reload listener
|
||||
const reloadCall = scene.gameInput.on.mock.calls.find((call: any[]) => call[0] === 'reload');
|
||||
reloadCallback = reloadCall[1];
|
||||
});
|
||||
|
||||
it('should reload the last reloadable weapon if nothing else is targeted or equipped', () => {
|
||||
const pistol: RangedWeaponItem = {
|
||||
id: 'pistol-1',
|
||||
name: 'Pistol',
|
||||
type: 'Weapon',
|
||||
weaponType: 'ranged',
|
||||
currentAmmo: 0,
|
||||
reloadingTurnsLeft: 0,
|
||||
stats: { attack: 1, range: 5, magazineSize: 6, ammoType: '9mm', projectileSpeed: 10 },
|
||||
textureKey: 'weapons',
|
||||
spriteIndex: 0
|
||||
};
|
||||
|
||||
const player: CombatantActor = {
|
||||
id: 1,
|
||||
pos: { x: 0, y: 0 },
|
||||
category: 'combatant',
|
||||
isPlayer: true,
|
||||
type: 'player',
|
||||
inventory: { items: [pistol], gold: 0 },
|
||||
equipment: { mainHand: { type: 'Weapon', weaponType: 'melee', id: 'sword-1' } as any },
|
||||
stats: {} as any,
|
||||
energy: 100,
|
||||
speed: 100
|
||||
};
|
||||
|
||||
scene.entityAccessor.getPlayer.mockReturnValue(player);
|
||||
scene.runState.lastReloadableWeaponId = 'pistol-1';
|
||||
|
||||
// Trigger reload (simulating 'R' press)
|
||||
reloadCallback();
|
||||
|
||||
expect(scene.startReload).toHaveBeenCalledWith(player, pistol);
|
||||
});
|
||||
|
||||
it('should prioritize targeted item over last used', () => {
|
||||
const pistol1: RangedWeaponItem = { id: 'p1', name: 'P1', type: 'Weapon', weaponType: 'ranged' } as any;
|
||||
const pistol2: RangedWeaponItem = { id: 'p2', name: 'P2', type: 'Weapon', weaponType: 'ranged' } as any;
|
||||
|
||||
const player: CombatantActor = {
|
||||
id: 1, inventory: { items: [pistol1, pistol2] }, equipment: {}
|
||||
} as any;
|
||||
|
||||
scene.entityAccessor.getPlayer.mockReturnValue(player);
|
||||
scene.targetingSystem.itemId = 'p2';
|
||||
scene.runState.lastReloadableWeaponId = 'p1';
|
||||
|
||||
reloadCallback();
|
||||
|
||||
expect(scene.startReload).toHaveBeenCalledWith(player, pistol2);
|
||||
});
|
||||
|
||||
it('should prioritize equipped ranged weapon over last used', () => {
|
||||
const pistol1: RangedWeaponItem = { id: 'p1', name: 'P1', type: 'Weapon', weaponType: 'ranged' } as any;
|
||||
const pistol2: RangedWeaponItem = { id: 'p2', name: 'P2', type: 'Weapon', weaponType: 'ranged' } as any;
|
||||
|
||||
const player: CombatantActor = {
|
||||
id: 1, inventory: { items: [pistol1, pistol2] }, equipment: { mainHand: pistol2 }
|
||||
} as any;
|
||||
|
||||
scene.entityAccessor.getPlayer.mockReturnValue(player);
|
||||
scene.runState.lastReloadableWeaponId = 'p1';
|
||||
|
||||
reloadCallback();
|
||||
|
||||
expect(scene.startReload).toHaveBeenCalledWith(player, pistol2);
|
||||
});
|
||||
|
||||
it('should do nothing if no weapon is found', () => {
|
||||
const player: CombatantActor = { id: 1, inventory: { items: [] }, equipment: {} } as any;
|
||||
scene.entityAccessor.getPlayer.mockReturnValue(player);
|
||||
|
||||
reloadCallback();
|
||||
|
||||
expect(scene.startReload).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user