feat: quick slots with 1-4 hotkeys (Phase 4.6)
4 quick slots bound to keys 1-4. Active slot determines what F key throws. Auto-assigns new items on collection. Clears slot when item depleted. 15 new tests (213 total). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -23,6 +23,7 @@ import {
|
||||
projectileSystem,
|
||||
type ProjectileData,
|
||||
} from '../player/projectile';
|
||||
import { QuickSlots } from '../player/quickslots';
|
||||
import type { InputState } from '../player/types';
|
||||
|
||||
export class GameScene extends Phaser.Scene {
|
||||
@@ -40,6 +41,7 @@ export class GameScene extends Phaser.Scene {
|
||||
private tileSize!: number;
|
||||
private resourceData!: Map<number, ResourceInfo>;
|
||||
private projectileData!: Map<number, ProjectileData>;
|
||||
private quickSlots!: QuickSlots;
|
||||
private keys!: {
|
||||
W: Phaser.Input.Keyboard.Key;
|
||||
A: Phaser.Input.Keyboard.Key;
|
||||
@@ -47,6 +49,10 @@ export class GameScene extends Phaser.Scene {
|
||||
D: Phaser.Input.Keyboard.Key;
|
||||
E: Phaser.Input.Keyboard.Key;
|
||||
F: Phaser.Input.Keyboard.Key;
|
||||
ONE: Phaser.Input.Keyboard.Key;
|
||||
TWO: Phaser.Input.Keyboard.Key;
|
||||
THREE: Phaser.Input.Keyboard.Key;
|
||||
FOUR: Phaser.Input.Keyboard.Key;
|
||||
};
|
||||
|
||||
// Interaction feedback
|
||||
@@ -89,6 +95,7 @@ export class GameScene extends Phaser.Scene {
|
||||
const spawnY = spawn?.y ?? (biome.mapHeight * biome.tileSize) / 2;
|
||||
this.playerEid = createPlayerEntity(this.gameWorld.world, spawnX, spawnY);
|
||||
this.inventory = new Inventory(500, 20);
|
||||
this.quickSlots = new QuickSlots();
|
||||
|
||||
// 7. Camera — follow player, zoom via scroll wheel
|
||||
const worldPixelW = biome.mapWidth * biome.tileSize;
|
||||
@@ -113,6 +120,10 @@ export class GameScene extends Phaser.Scene {
|
||||
D: keyboard.addKey('D'),
|
||||
E: keyboard.addKey('E'),
|
||||
F: keyboard.addKey('F'),
|
||||
ONE: keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.ONE),
|
||||
TWO: keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.TWO),
|
||||
THREE: keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.THREE),
|
||||
FOUR: keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.FOUR),
|
||||
};
|
||||
|
||||
// 9. Minimap
|
||||
@@ -189,10 +200,22 @@ export class GameScene extends Phaser.Scene {
|
||||
this.gameWorld.world, justPressedE, this.inventory, this.resourceData,
|
||||
);
|
||||
if (interaction) {
|
||||
// Auto-assign collected items to quick slots
|
||||
if (interaction.type === 'collected' || interaction.type === 'depleted') {
|
||||
if (interaction.itemId) {
|
||||
this.quickSlots.autoAssign(interaction.itemId);
|
||||
}
|
||||
}
|
||||
this.showInteractionFeedback(interaction.type, interaction.itemId);
|
||||
}
|
||||
|
||||
// 8. Throw projectile (F key, debounced)
|
||||
// 8. Quick slot selection (1-4 keys)
|
||||
if (this.keys.ONE.isDown) this.quickSlots.setActive(0);
|
||||
if (this.keys.TWO.isDown) this.quickSlots.setActive(1);
|
||||
if (this.keys.THREE.isDown) this.quickSlots.setActive(2);
|
||||
if (this.keys.FOUR.isDown) this.quickSlots.setActive(3);
|
||||
|
||||
// 9. Throw projectile (F key, debounced) — uses active quick slot
|
||||
const isFDown = this.keys.F.isDown;
|
||||
const justPressedF = isFDown && !this.wasFDown;
|
||||
this.wasFDown = isFDown;
|
||||
@@ -231,17 +254,15 @@ export class GameScene extends Phaser.Scene {
|
||||
);
|
||||
}
|
||||
|
||||
/** Try to launch a projectile from the first inventory item toward mouse */
|
||||
/** Try to launch a projectile from active quick slot toward mouse */
|
||||
private tryLaunchProjectile(): void {
|
||||
const items = this.inventory.getItems();
|
||||
if (items.length === 0) {
|
||||
const itemId = this.quickSlots.getActive();
|
||||
if (!itemId || !this.inventory.hasItem(itemId)) {
|
||||
this.showInteractionFeedback('nothing_nearby');
|
||||
return;
|
||||
}
|
||||
|
||||
// Use first item in inventory (quick slots will replace this in 4.6)
|
||||
const item = items[0];
|
||||
const removed = this.inventory.removeItem(item.id, 1);
|
||||
const removed = this.inventory.removeItem(itemId, 1);
|
||||
if (removed === 0) return;
|
||||
|
||||
// Get mouse world position for direction
|
||||
@@ -256,10 +277,16 @@ export class GameScene extends Phaser.Scene {
|
||||
this.projectileData,
|
||||
px, py,
|
||||
worldPoint.x, worldPoint.y,
|
||||
item.id,
|
||||
itemId,
|
||||
);
|
||||
|
||||
this.showInteractionFeedback('collected', `Threw ${item.id}`);
|
||||
// Clear quick slot if inventory is now empty for this item
|
||||
if (!this.inventory.hasItem(itemId)) {
|
||||
const slotIdx = this.quickSlots.getAll().indexOf(itemId);
|
||||
if (slotIdx >= 0) this.quickSlots.assign(slotIdx, null);
|
||||
}
|
||||
|
||||
this.showInteractionFeedback('collected', `Threw ${itemId}`);
|
||||
}
|
||||
|
||||
private showInteractionFeedback(type: string, itemId?: string): void {
|
||||
|
||||
Reference in New Issue
Block a user