feat(expansion): implement Phase 3 (Town Restoration) and Phase 4 (Cannabis Textiles)

- Added TownSquareScene and linked it with M key transition
- Integrated TownRestorationSystem with material costs and inventory
- Added locked shop items in NPCShopSystem until buildings are restored
- Updated InteractionSystem to handle ruin restoration triggers
- Expanded Cannabis farming to yield Hemp Fiber
- Added Hemp Clothing crafting recipe and procedural icons
- Refactored StatusEffectSystem and NPCShopSystem to global classes
This commit is contained in:
2025-12-27 23:32:22 +01:00
parent 611cd35777
commit 822c586843
12 changed files with 454 additions and 40 deletions

View File

@@ -164,7 +164,8 @@ class Player {
right: Phaser.Input.Keyboard.KeyCodes.RIGHT,
// Actions
space: Phaser.Input.Keyboard.KeyCodes.SPACE,
shift: Phaser.Input.Keyboard.KeyCodes.SHIFT
shift: Phaser.Input.Keyboard.KeyCodes.SHIFT,
r: Phaser.Input.Keyboard.KeyCodes.R
});
// Gamepad Events
@@ -306,6 +307,11 @@ class Player {
if (this.keys.space && Phaser.Input.Keyboard.JustDown(this.keys.space)) {
this.handleFarmingAction();
}
// 🚬 R KEY - Use Item
if (this.keys.r && Phaser.Input.Keyboard.JustDown(this.keys.r)) {
this.useSelectedItem();
}
}
updateHeldItem() {
@@ -748,4 +754,57 @@ class Player {
return false;
}
useSelectedItem() {
const uiScene = this.scene.scene.get('UIScene');
const invSys = this.scene.inventorySystem;
if (!uiScene || !invSys) return;
const selectedIdx = uiScene.selectedSlot;
const slot = invSys.slots[selectedIdx];
if (!slot || slot.count <= 0) return;
console.log(`🌀 Attempting to use item: ${slot.type}`);
if (slot.type === 'cannabis_buds') {
// SMOKE IT!
if (this.scene.statusEffectSystem) {
const used = this.scene.statusEffectSystem.applyEffect('high');
if (used) {
invSys.removeItem(slot.type, 1);
// Visual feedback
this.createSmokeParticles(this.gridX, this.gridY);
this.scene.events.emit('show-floating-text', {
x: this.sprite.x, y: this.sprite.y - 60, text: '🚬 *puff puff*', color: '#55ff55'
});
}
}
} else if (slot.type === 'health_potion' || slot.type === 'medicine') {
// Generic healing
if (this.hp < this.maxHp) {
this.hp = Math.min(this.maxHp, this.hp + 20);
invSys.removeItem(slot.type, 1);
this.scene.events.emit('show-floating-text', {
x: this.sprite.x, y: this.sprite.y - 60, text: '💖 Recovered!', color: '#ff5555'
});
}
}
}
createSmokeParticles(gridX, gridY) {
// Reuse particle logic, or create locally
for (let i = 0; i < 10; i++) {
const smoke = this.scene.add.circle(this.sprite.x, this.sprite.y - 40, 4 + Math.random() * 4, 0xcccccc, 0.6);
this.scene.tweens.add({
targets: smoke,
x: smoke.x + (Math.random() - 0.5) * 50,
y: smoke.y - 100 - Math.random() * 50,
alpha: 0,
scale: 3,
duration: 2000 + Math.random() * 1000,
onComplete: () => smoke.destroy()
});
}
}
}