Add freshness bar, enhance overlays and renderers
- Add enemy freshness tracking (novelty bonus for repeated deploys) - Add freshness bar to sidepanel enemy cards with penalty indicator - Major overhaul of renderer-overlays.js (790+ lines for UI polish) - Enhanced combat log, shop overlays, and inventory UI - Improved weapon/upgrade display with partial ownership colors - Added element icons and weakness/resistance indicators to cards - Enhanced radial menu and tooltip system - Add "stale/%" penalty text when freshness depleted - Update play link to ffazeshift.net in index.html
This commit is contained in:
+70
-8
@@ -1,24 +1,86 @@
|
||||
// ═══ shop.js ═══
|
||||
// ============================================================
|
||||
// SHOP.JS — Shop state management (canvas draws each frame)
|
||||
// SHOP.JS — Armory / Command overlay state management
|
||||
// ============================================================
|
||||
|
||||
function openShop() {
|
||||
function openArmory() {
|
||||
if (G.gameOver) return;
|
||||
G.shopOpen = true;
|
||||
G.armoryOpen = true;
|
||||
G.commandOpen = false;
|
||||
G.threatOpen = false;
|
||||
G.prestigeOpen = false;
|
||||
_radialSlot = -1;
|
||||
_shopScrollY = 0;
|
||||
setPaused(true, false);
|
||||
}
|
||||
|
||||
function closeShop() {
|
||||
G.shopOpen = false;
|
||||
function closeArmory() {
|
||||
G.armoryOpen = false;
|
||||
_shopScrollY = 0;
|
||||
setPaused(false);
|
||||
}
|
||||
|
||||
function setShopTab(tab) {
|
||||
G.shopTab = tab;
|
||||
function openCommand() {
|
||||
if (G.gameOver) return;
|
||||
G.commandOpen = true;
|
||||
G.armoryOpen = false;
|
||||
G.threatOpen = false;
|
||||
G.prestigeOpen = false;
|
||||
_radialSlot = -1;
|
||||
_shopScrollY = 0;
|
||||
setPaused(true, false);
|
||||
}
|
||||
|
||||
function renderShop() { /* canvas draws shop each frame via drawShopOverlay() */ }
|
||||
function closeCommand() {
|
||||
G.commandOpen = false;
|
||||
_shopScrollY = 0;
|
||||
setPaused(false);
|
||||
}
|
||||
|
||||
function openWeaponDetail(slotIndex) {
|
||||
if (!G.weapons[slotIndex]) return;
|
||||
G.weaponDetailSlot = slotIndex;
|
||||
_radialSlot = -1;
|
||||
G.armoryOpen = false;
|
||||
G.commandOpen = false;
|
||||
G.threatOpen = false;
|
||||
G.prestigeOpen = false;
|
||||
_weaponDetailScrollY = 0;
|
||||
setPaused(true, false);
|
||||
}
|
||||
|
||||
function closeWeaponDetail() {
|
||||
G.weaponDetailSlot = -1;
|
||||
_weaponDetailScrollY = 0;
|
||||
if (!G.armoryOpen && !G.commandOpen) setPaused(false);
|
||||
}
|
||||
|
||||
function calcSellPrice(weapon) {
|
||||
const def = WEAPON_DEFS.find(d => d.id === weapon.defId);
|
||||
const baseSell = Math.floor((def?.cost ?? 0) * 0.5);
|
||||
const upgTree = WEAPON_UPGRADE_TREES[weapon.defId] || [];
|
||||
const upgSell = (G.weaponUpgradesBought[weapon.instanceId] || []).reduce((sum, id) => {
|
||||
const u = upgTree.find(u => u.id === id);
|
||||
return sum + Math.floor((u?.cost ?? 0) * 0.5);
|
||||
}, 0);
|
||||
return baseSell + upgSell;
|
||||
}
|
||||
|
||||
function renderShop() { /* no-op — render loop redraws every frame */ }
|
||||
|
||||
function sellWeapon(slotIndex) {
|
||||
const w = G.weapons[slotIndex];
|
||||
if (!w) return;
|
||||
const activeCount = (G.weapons || []).slice(0, G.tower.weaponSlots).filter(x => x != null).length;
|
||||
if (activeCount <= 1) { addLog('Cannot sell last weapon!', 'lose'); return; }
|
||||
const price = calcSellPrice(w);
|
||||
removeWeaponFromSlot(slotIndex);
|
||||
const invIdx = (G.weaponInventory || []).findIndex(x => x.instanceId === w.instanceId);
|
||||
if (invIdx >= 0) G.weaponInventory.splice(invIdx, 1);
|
||||
G.credits += price;
|
||||
_radialSlot = -1;
|
||||
_sellHoldSlot = -1;
|
||||
closeWeaponDetail();
|
||||
addLog('Sold ' + getWeaponDef(w).name + ' for ' + price + '¢.', 'win');
|
||||
updateHUD();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user