Initial commit: Siege Protocol
Inverted tower-defense browser game — deploy enemies yourself, tower auto-kills them, pocket credits, upgrade weapons. HTML + Canvas + vanilla JS, no build step. Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
+113
@@ -0,0 +1,113 @@
|
||||
// ═══ inventory.js ═══
|
||||
// ============================================================
|
||||
// INVENTORY — weapon picker state and equip helpers
|
||||
// ============================================================
|
||||
|
||||
const MAX_WEAPON_SLOTS = 8;
|
||||
|
||||
let _pickerSlot = -1;
|
||||
let _pickerScrollY = 0;
|
||||
let _pickerScrollMax = 0;
|
||||
|
||||
function weaponUpgradeCount(w) {
|
||||
return (G.weaponUpgradesBought[w.instanceId] || []).length;
|
||||
}
|
||||
|
||||
function weaponElementLabel(w) {
|
||||
return getWeaponElements(w)
|
||||
.map(el => ELEMENTS[el]?.icon || '')
|
||||
.join('');
|
||||
}
|
||||
|
||||
function weaponStatRows(w) {
|
||||
return [
|
||||
['DMG', w.damage],
|
||||
['RATE', w.fireRate + 'f'],
|
||||
w.aoeRadius ? ['AOE', w.aoeRadius] : null,
|
||||
w.targets && w.targets > 1 ? ['TARGETS', w.targets] : null,
|
||||
w.pierce ? ['PIERCE', w.pierce] : null,
|
||||
w.chains ? ['CHAINS', w.chains] : null,
|
||||
['TARGET', (w.targeting || 'nearest').toUpperCase()],
|
||||
].filter(Boolean);
|
||||
}
|
||||
|
||||
function weaponUpgradeLabels(w) {
|
||||
const bought = G.weaponUpgradesBought[w.instanceId] || [];
|
||||
const tree = WEAPON_UPGRADE_TREES[w.defId] || [];
|
||||
return bought.map(id => tree.find(u => u.id === id)?.label || id);
|
||||
}
|
||||
|
||||
function openWeaponPicker(slotIndex) {
|
||||
if (slotIndex >= G.tower.weaponSlots) return;
|
||||
_pickerSlot = slotIndex;
|
||||
_pickerScrollY = 0;
|
||||
setPaused(true, false);
|
||||
document.body.classList.add('inventory-open');
|
||||
G.weaponInventory = G.weaponInventory || [];
|
||||
}
|
||||
|
||||
function closeWeaponPicker() {
|
||||
document.body.classList.remove('inventory-open');
|
||||
_pickerSlot = -1;
|
||||
_pickerScrollY = 0;
|
||||
if (!G.shopOpen) setPaused(false);
|
||||
}
|
||||
|
||||
function equipWeaponInstanceToSlot(slotIndex, instanceId) {
|
||||
if (slotIndex >= G.tower.weaponSlots) return;
|
||||
G.weaponInventory = G.weaponInventory || [];
|
||||
|
||||
const sourceSlot = G.weapons.slice(0, G.tower.weaponSlots).findIndex(w => w && w.instanceId === instanceId);
|
||||
if (sourceSlot === slotIndex) return;
|
||||
|
||||
const displaced = G.weapons[slotIndex];
|
||||
if (sourceSlot >= 0) {
|
||||
G.weapons[slotIndex] = G.weapons[sourceSlot];
|
||||
G.weapons[sourceSlot] = displaced || null;
|
||||
} else {
|
||||
const invIdx = G.weaponInventory.findIndex(w => w.instanceId === instanceId);
|
||||
if (invIdx === -1) return;
|
||||
const invWeapon = G.weaponInventory.splice(invIdx, 1)[0];
|
||||
G.weapons[slotIndex] = invWeapon;
|
||||
if (displaced) G.weaponInventory.push(displaced);
|
||||
}
|
||||
|
||||
addLog(getWeaponDef(G.weapons[slotIndex]).name + ' equipped.', 'info');
|
||||
updateHUD();
|
||||
}
|
||||
|
||||
function removeWeaponFromSlot(slotIndex) {
|
||||
if (slotIndex >= G.tower.weaponSlots) return;
|
||||
const activeCount = G.weapons.slice(0, G.tower.weaponSlots).filter(w => w != null).length;
|
||||
if (activeCount <= 1) { addLog('Cannot remove last weapon!', 'lose'); return; }
|
||||
const w = G.weapons[slotIndex];
|
||||
if (!w) return;
|
||||
G.weaponInventory = G.weaponInventory || [];
|
||||
G.weaponInventory.push(w);
|
||||
G.weapons[slotIndex] = null;
|
||||
addLog(getWeaponDef(w).name + ' moved to inventory.', 'info');
|
||||
updateHUD();
|
||||
}
|
||||
|
||||
function buyAndEquipWeapon(slotIndex, defId) {
|
||||
const def = WEAPON_DEFS.find(w => w.id === defId);
|
||||
if (!def || slotIndex >= G.tower.weaponSlots || spendableCredits() < def.cost) return;
|
||||
if (!canBuyWeaponType(defId)) {
|
||||
addLog(`${def.name} limit reached (${MAX_WEAPONS_PER_TYPE}/${MAX_WEAPONS_PER_TYPE}).`, 'lose');
|
||||
return;
|
||||
}
|
||||
G.credits -= def.cost;
|
||||
const instance = makeWeaponInstance(defId);
|
||||
G.weaponUpgradesBought[instance.instanceId] = [];
|
||||
|
||||
const displaced = G.weapons[slotIndex];
|
||||
G.weapons[slotIndex] = instance;
|
||||
if (displaced) {
|
||||
G.weaponInventory = G.weaponInventory || [];
|
||||
G.weaponInventory.push(displaced);
|
||||
addLog(`Purchased ${def.name}! Swapped previous weapon to inventory.`, 'win');
|
||||
} else {
|
||||
addLog(`Purchased ${def.name}!`, 'win');
|
||||
}
|
||||
updateHUD();
|
||||
}
|
||||
Reference in New Issue
Block a user