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:
2026-06-17 11:58:17 -04:00
parent 6a710c3f03
commit 626879ed0c
21 changed files with 1884 additions and 312 deletions
+16 -10
View File
@@ -11,7 +11,7 @@ function _shopDrawTowerContent(yOff, cx, cw, H) {
['HP', G.tower.hp + ' / ' + G.tower.maxHp],
['Armor', G.tower.armor],
['Aim Speed', G.tower.aimSpeed.toFixed(3)],
['Vision', G.tower.range + 'px'],
['Vision', (() => { const ws = (G.weapons||[]).filter(w=>w); return (ws.length > 0 ? Math.max(...ws.map(w=>w.range??0)) : 0) + 'px'; })()],
['Slots', getEquippedWeapons().length + '/' + G.tower.weaponSlots],
['Shield', G.tower.shield ? G.tower.shield.toUpperCase() + ' (' + G.tower.shieldHp + '/' + G.tower.shieldMaxHp + ')' : 'None'],
];
@@ -77,12 +77,15 @@ function _shopDrawTowerContent(yOff, cx, cw, H) {
(upg.id === 'shield_dir' && G.tower.shield === 'directional');
const effectiveBought = isBought || shieldConflict;
const reqsMet = upg.requires.every(r => G.towerUpgradesBought.includes(r));
const canAfford = spendableCredits() >= upg.cost;
const tierLocked = (upg.minTier ?? 0) > (G.difficultyTier || 0);
const canAfford = !tierLocked && spendableCredits() >= upg.cost;
const tierLockLabel = tierLocked ? (DIFFICULTY_TIERS[upg.minTier]?.name ?? '') : null;
const uid = upg.id;
_shopUpgNode(nx, sy(yOff), upg, effectiveBought,
!reqsMet && !isBought, !canAfford && reqsMet && !isBought,
(!effectiveBought && reqsMet && canAfford) ? () => buyTowerUpgrade(uid) : null,
(isBought && !upg.repeatable) ? () => refundTowerUpgrade(uid) : null
tierLocked || (!reqsMet && !isBought), !canAfford && reqsMet && !isBought && !tierLocked,
(!effectiveBought && reqsMet && canAfford && !tierLocked) ? () => buyTowerUpgrade(uid) : null,
(isBought && !upg.repeatable) ? () => refundTowerUpgrade(uid) : null,
tierLockLabel
);
nx += _SH_UPG_W;
}
@@ -203,7 +206,7 @@ function _shopDrawBuyContent(yOff, cx, cw, H) {
ctx.restore();
ctx.font = '10px "Share Tech Mono", monospace';
ctx.fillStyle = atCap ? '#ff3355' : '#1a3048';
ctx.fillStyle = atCap ? '#ff3355' : owned > 0 ? '#8ab8d0' : '#3a6080';
ctx.textBaseline = 'top'; ctx.textAlign = 'left';
ctx.fillText('Owned: ' + owned + '/' + MAX_WEAPONS_PER_TYPE + (atCap ? ' (MAX)' : ''), cardX + 8, csy + 88);
ctx.restore();
@@ -391,12 +394,15 @@ function _shopDrawWeaponContent(yOff, cx, cw, H, weapon) {
}
const isBought = bought.includes(upg.id);
const reqsMet = upg.requires.every(r => bought.includes(r));
const canAfford = spendableCredits() >= upg.cost;
const tierLocked = (upg.minTier ?? 0) > (G.difficultyTier || 0);
const canAfford = !tierLocked && spendableCredits() >= upg.cost;
const tierLockLabel = tierLocked ? (DIFFICULTY_TIERS[upg.minTier]?.name ?? '') : null;
const uid = upg.id, iid = weapon.instanceId;
_shopUpgNode(colX + (COL_W - _SH_UPG_W) / 2, sy(ny), upg, isBought,
!reqsMet && !isBought, !canAfford && reqsMet && !isBought,
(!isBought && reqsMet && canAfford) ? () => buyWeaponUpgrade(iid, uid) : null,
(isBought && !upg.repeatable) ? () => refundWeaponUpgrade(iid, uid) : null
tierLocked || (!reqsMet && !isBought), !canAfford && reqsMet && !isBought && !tierLocked,
(!isBought && reqsMet && canAfford && !tierLocked) ? () => buyWeaponUpgrade(iid, uid) : null,
(isBought && !upg.repeatable) ? () => refundWeaponUpgrade(iid, uid) : null,
tierLockLabel
);
ny += _SH_UPG_H + 4;
}