318 lines
8.8 KiB
JavaScript
318 lines
8.8 KiB
JavaScript
/**
|
|
* INVENTORY SYSTEM EXPANDED (P30)
|
|
* Extends basic InventorySystem with tiered upgrades, tool belt, dog backpack, and UI features.
|
|
*
|
|
* Features:
|
|
* - 6 Inventory Tiers: 5 → 10 → 15 → 20 → 25 → 30 slots (progressive upgrades at Jakob's shop)
|
|
* - Tool Belt: +5 tool-only slots with quick-switch hotkeys (1-5 keys)
|
|
* - Dog Backpack: +10 material storage slots (requires dog companion)
|
|
* - Inventory UI: Quick Sort, Stack All, Quick Deposit, visual backpack upgrades
|
|
* - MAXIMUM: 45 total slots (30 main + 5 tool belt + 10 dog backpack)
|
|
*/
|
|
class InventorySystemExpanded {
|
|
constructor(scene, baseInventory) {
|
|
this.scene = scene;
|
|
this.baseInventory = baseInventory; // Reference to basic InventorySystem
|
|
|
|
// Inventory tiers
|
|
this.inventoryTiers = [
|
|
{ tier: 1, slots: 9, cost: 0, name: 'Basic Backpack' },
|
|
{ tier: 2, slots: 15, cost: 500, name: 'Leather Backpack' },
|
|
{ tier: 3, slots: 20, cost: 2000, name: 'Reinforced Backpack' },
|
|
{ tier: 4, slots: 25, cost: 5000, name: 'Large Backpack' },
|
|
{ tier: 5, slots: 30, cost: 12000, name: 'Military Backpack' },
|
|
{ tier: 6, slots: 35, cost: 25000, name: 'Ultimate Backpack' }
|
|
];
|
|
|
|
// Current tier
|
|
this.currentTier = 1;
|
|
|
|
// Tool belt (tools only)
|
|
this.toolBelt = {
|
|
unlocked: false,
|
|
slots: 5,
|
|
tools: [],
|
|
activeSlot: 0
|
|
};
|
|
|
|
// Dog backpack (materials only)
|
|
this.dogBackpack = {
|
|
unlocked: false,
|
|
slots: 10,
|
|
materials: []
|
|
};
|
|
|
|
console.log('🎒 Inventory System Expanded initialized!');
|
|
}
|
|
|
|
/**
|
|
* Upgrade inventory tier at Jakob's shop
|
|
*/
|
|
upgradeTier() {
|
|
if (this.currentTier >= 6) {
|
|
return { success: false, message: 'Already at max tier!' };
|
|
}
|
|
|
|
const nextTier = this.inventoryTiers[this.currentTier];
|
|
|
|
// Check gold
|
|
if (this.baseInventory.gold < nextTier.cost) {
|
|
return { success: false, message: `Need ${nextTier.cost} gold!` };
|
|
}
|
|
|
|
// Deduct gold
|
|
this.baseInventory.gold -= nextTier.cost;
|
|
|
|
// Expand slots
|
|
const slotsToAdd = nextTier.slots - this.baseInventory.slots.length;
|
|
for (let i = 0; i < slotsToAdd; i++) {
|
|
this.baseInventory.slots.push(null);
|
|
}
|
|
|
|
this.currentTier = nextTier.tier;
|
|
|
|
console.log(`⬆️ Upgraded to ${nextTier.name}! Capacity: ${nextTier.slots} slots`);
|
|
|
|
this.scene.events.emit('notification', {
|
|
title: 'Inventory Upgraded!',
|
|
message: `${nextTier.name} - ${nextTier.slots} slots!`,
|
|
icon: '🎒'
|
|
});
|
|
|
|
this.baseInventory.updateUI();
|
|
|
|
return { success: true, tier: this.currentTier, slots: nextTier.slots };
|
|
}
|
|
|
|
/**
|
|
* Unlock tool belt (+5 tool slots)
|
|
*/
|
|
unlockToolBelt() {
|
|
if (this.toolBelt.unlocked) {
|
|
return { success: false, message: 'Already unlocked!' };
|
|
}
|
|
|
|
const cost = 1000;
|
|
|
|
if (this.baseInventory.gold < cost) {
|
|
return { success: false, message: `Need ${cost} gold!` };
|
|
}
|
|
|
|
this.baseInventory.gold -= cost;
|
|
this.toolBelt.unlocked = true;
|
|
this.toolBelt.tools = new Array(5).fill(null);
|
|
|
|
console.log('⚒️ Tool Belt unlocked! +5 tool-only slots!');
|
|
|
|
this.scene.events.emit('notification', {
|
|
title: 'Tool Belt Unlocked!',
|
|
message: '+5 slots for tools! Use 1-5 keys!',
|
|
icon: '⚒️'
|
|
});
|
|
|
|
return { success: true };
|
|
}
|
|
|
|
/**
|
|
* Equip tool to belt
|
|
*/
|
|
equipTool(toolType, slot) {
|
|
if (!this.toolBelt.unlocked || slot < 0 || slot >= 5) {
|
|
return { success: false };
|
|
}
|
|
|
|
// Check if player has tool
|
|
if (!this.baseInventory.hasItem(toolType, 1)) {
|
|
return { success: false, message: 'Tool not in inventory!' };
|
|
}
|
|
|
|
// Remove from main inventory
|
|
this.baseInventory.removeItem(toolType, 1);
|
|
|
|
// Add to tool belt
|
|
this.toolBelt.tools[slot] = toolType;
|
|
|
|
console.log(`⚒️ Equipped ${toolType} to slot ${slot + 1}`);
|
|
return { success: true };
|
|
}
|
|
|
|
/**
|
|
* Switch active tool slot (1-5 keys)
|
|
*/
|
|
switchToolSlot(slot) {
|
|
if (!this.toolBelt.unlocked || slot < 0 || slot >= 5) return null;
|
|
|
|
this.toolBelt.activeSlot = slot;
|
|
return this.toolBelt.tools[slot];
|
|
}
|
|
|
|
/**
|
|
* Unlock dog backpack (+10 material slots)
|
|
*/
|
|
unlockDogBackpack() {
|
|
if (this.dogBackpack.unlocked) {
|
|
return { success: false, message: 'Already unlocked!' };
|
|
}
|
|
|
|
const cost = 2000;
|
|
|
|
if (this.baseInventory.gold < cost) {
|
|
return { success: false, message: `Need ${cost} gold!` };
|
|
}
|
|
|
|
this.baseInventory.gold -= cost;
|
|
this.dogBackpack.unlocked = true;
|
|
this.dogBackpack.materials = new Array(10).fill(null);
|
|
|
|
console.log('🐶 Dog Backpack unlocked! +10 material slots!');
|
|
|
|
this.scene.events.emit('notification', {
|
|
title: 'Dog Backpack!',
|
|
message: '+10 material slots! Good boy!',
|
|
icon: '🐶'
|
|
});
|
|
|
|
return { success: true };
|
|
}
|
|
|
|
/**
|
|
* Quick Sort inventory
|
|
*/
|
|
quickSort(mode = 'type') {
|
|
const items = this.baseInventory.slots.filter(s => s !== null);
|
|
|
|
items.sort((a, b) => {
|
|
switch (mode) {
|
|
case 'type':
|
|
return a.type.localeCompare(b.type);
|
|
case 'quantity':
|
|
return b.count - a.count;
|
|
case 'name':
|
|
return a.type.localeCompare(b.type); // Fallback to type
|
|
default:
|
|
return 0;
|
|
}
|
|
});
|
|
|
|
// Rebuild slots
|
|
this.baseInventory.slots.fill(null);
|
|
items.forEach((item, i) => {
|
|
this.baseInventory.slots[i] = item;
|
|
});
|
|
|
|
console.log(`📋 Sorted by ${mode}!`);
|
|
this.baseInventory.updateUI();
|
|
|
|
return { success: true };
|
|
}
|
|
|
|
/**
|
|
* Stack all similar items
|
|
*/
|
|
stackAll() {
|
|
const stacked = {};
|
|
|
|
// Collect all items
|
|
this.baseInventory.slots.forEach(slot => {
|
|
if (slot) {
|
|
if (!stacked[slot.type]) {
|
|
stacked[slot.type] = 0;
|
|
}
|
|
stacked[slot.type] += slot.count;
|
|
}
|
|
});
|
|
|
|
// Rebuild with stacks
|
|
this.baseInventory.slots.fill(null);
|
|
let index = 0;
|
|
|
|
Object.keys(stacked).forEach(type => {
|
|
let count = stacked[type];
|
|
while (count > 0) {
|
|
const stackSize = Math.min(count, 99);
|
|
this.baseInventory.slots[index] = { type: type, count: stackSize };
|
|
count -= stackSize;
|
|
index++;
|
|
}
|
|
});
|
|
|
|
console.log('📦 All items stacked!');
|
|
this.baseInventory.updateUI();
|
|
|
|
return { success: true };
|
|
}
|
|
|
|
/**
|
|
* Quick deposit to chest
|
|
*/
|
|
quickDeposit() {
|
|
let deposited = 0;
|
|
|
|
// Keep tools, deposit everything else
|
|
const tools = ['axe', 'pickaxe', 'hoe', 'watering_can', 'sword'];
|
|
|
|
this.baseInventory.slots.forEach((slot, i) => {
|
|
if (slot && !tools.includes(slot.type)) {
|
|
deposited += slot.count;
|
|
this.baseInventory.slots[i] = null;
|
|
}
|
|
});
|
|
|
|
console.log(`📦 Deposited ${deposited} items!`);
|
|
this.baseInventory.updateUI();
|
|
|
|
this.scene.events.emit('notification', {
|
|
title: 'Quick Deposit!',
|
|
message: `${deposited} items stored!`,
|
|
icon: '📦'
|
|
});
|
|
|
|
return { success: true, deposited };
|
|
}
|
|
|
|
/**
|
|
* Get total capacity
|
|
*/
|
|
getTotalCapacity() {
|
|
let total = this.baseInventory.slots.length;
|
|
|
|
if (this.toolBelt.unlocked) total += 5;
|
|
if (this.dogBackpack.unlocked) total += 10;
|
|
|
|
return total;
|
|
}
|
|
|
|
/**
|
|
* Get stats
|
|
*/
|
|
getStats() {
|
|
return {
|
|
tier: this.currentTier,
|
|
tierName: this.inventoryTiers[this.currentTier - 1].name,
|
|
mainSlots: this.baseInventory.slots.length,
|
|
toolBelt: this.toolBelt.unlocked ? '5 slots' : 'Locked',
|
|
dogBackpack: this.dogBackpack.unlocked ? '10 slots' : 'Locked',
|
|
totalCapacity: this.getTotalCapacity()
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get next upgrade info
|
|
*/
|
|
getNextUpgrade() {
|
|
if (this.currentTier >= 6) {
|
|
return { available: false };
|
|
}
|
|
|
|
const next = this.inventoryTiers[this.currentTier];
|
|
|
|
return {
|
|
available: true,
|
|
tier: next.tier,
|
|
name: next.name,
|
|
slots: next.slots,
|
|
cost: next.cost
|
|
};
|
|
}
|
|
}
|