fix(gameplay & db): fix casino spin freeze, bank deposit sync, and plant selection menu (fixes #8, #9, #10)

This commit is contained in:
Antigravity committed 2026-09-22 12:04:30 +00:00
1 parent 351d5f1cca
commit bd314730ff
7 files changed
+247 -33

No files matched your search

+16 -1
View File
@@ -746,6 +746,16 @@ canvas#gameCanvas {
width: 95%;
max-height: 90vh;
overflow-y: auto;
position: relative;
}
.seed-select-card .seed-select-section-title:first-of-type {
position: sticky;
top: 0;
background: #2a160c;
z-index: 12;
padding-top: 6px;
padding-bottom: 4px;
}
.seed-select-section-title {
@@ -761,16 +771,21 @@ canvas#gameCanvas {
}
.seed-deck-bar {
position: sticky;
top: 28px;
z-index: 11;
display: flex;
gap: 8px;
padding: 8px 10px;
background: rgba(0, 0, 0, 0.4);
background: rgba(35, 18, 11, 0.96);
backdrop-filter: blur(6px);
border: 1.5px solid #81c784;
border-radius: 8px;
min-height: 76px;
align-items: center;
flex-wrap: wrap;
margin-bottom: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
}
.seed-slot-card {
+35 -20
View File
@@ -448,7 +448,8 @@ window.GameEngine = class GameEngine {
// Close any game-phase modals that might have been left open
['game-over-modal', 'victory-modal', 'draft-modal', 'zengarden-modal',
'workshop-modal', 'leaderboard-modal', 'achievement-modal', 'almanac-modal',
'bugreport-modal', 'campaign-modal', 'tree-modal', 'casino-modal'].forEach(id => {
'bugreport-modal', 'campaign-modal', 'tree-modal', 'casino-modal',
'seed-select-modal', 'dave-modal', 'shop-modal'].forEach(id => {
const el = document.getElementById(id);
if (el) el.classList.add('hidden');
});
@@ -492,6 +493,12 @@ window.GameEngine = class GameEngine {
this.currentLevel = level;
this.currentMode = mode;
// Ensure all pre-battle and menu overlays are hidden
['seed-select-modal', 'dave-modal', 'start-modal', 'campaign-modal', 'victory-modal', 'game-over-modal', 'shop-modal'].forEach(id => {
const el = document.getElementById(id);
if (el) el.classList.add('hidden');
});
// Pre-set economy mode flags BEFORE reset() so economy.reset() computes
// the correct baseSun (avoids stale isConveyor/isIZombie from previous game)
this.economy.isConveyor = (mode === 'bowling' || mode === 'boss' || mode === 'bossrush');
@@ -1876,6 +1883,7 @@ window.GameEngine = class GameEngine {
}
// Animate spin
this.casino.isSpinning = true;
[reel1, reel2, reel3].forEach(r => { if (r) r.classList.add('spinning'); });
if (btnSpin) btnSpin.disabled = true;
if (resultBanner) {
@@ -1884,27 +1892,34 @@ window.GameEngine = class GameEngine {
}
setTimeout(() => {
if (this.casino) {
this.casino.isSpinning = false;
const res = this.casino.spin(bet);
try {
if (this.casino) {
this.casino.isSpinning = false;
const res = this.casino.spin(bet);
this.casino.isSpinning = false;
if (res && res.icons) {
if (reel1) reel1.innerHTML = `<span class="reel-symbol">${res.icons[0]}</span>`;
if (reel2) reel2.innerHTML = `<span class="reel-symbol">${res.icons[1]}</span>`;
if (reel3) reel3.innerHTML = `<span class="reel-symbol">${res.icons[2]}</span>`;
}
if (resultBanner && res) {
resultBanner.textContent = res.message || '';
if (res.isJackpot) resultBanner.style.color = '#ffd700';
else if (res.payout > 0) resultBanner.style.color = '#69f0ae';
else resultBanner.style.color = '#b0bec5';
}
this.updateCasinoUI();
this.updateRecordDisplay();
}
} catch (e) {
console.error('Casino spin error:', e);
} finally {
if (this.casino) this.casino.isSpinning = false;
[reel1, reel2, reel3].forEach(r => { if (r) r.classList.remove('spinning'); });
if (btnSpin) btnSpin.disabled = false;
if (res.icons) {
if (reel1) reel1.innerHTML = `<span class="reel-symbol">${res.icons[0]}</span>`;
if (reel2) reel2.innerHTML = `<span class="reel-symbol">${res.icons[1]}</span>`;
if (reel3) reel3.innerHTML = `<span class="reel-symbol">${res.icons[2]}</span>`;
}
if (resultBanner) {
resultBanner.textContent = res.message || '';
if (res.isJackpot) resultBanner.style.color = '#ffd700';
else if (res.payout > 0) resultBanner.style.color = '#69f0ae';
else resultBanner.style.color = '#b0bec5';
}
this.updateCasinoUI();
this.updateRecordDisplay();
}
}, 500);
});
+45 -2
View File
@@ -117,7 +117,20 @@ window.PvZAuth = (function () {
lastVisit: Date.now()
},
treeOfWisdom: { height: 0, cheats: {} },
achievements: {}
achievements: {},
casino: {
deposit: 0,
depositStartTime: 0,
loan: 0,
spinsTotal: 0,
totalWon: 0,
jackpotsWon: 0
},
zombieLab: {
unlockedStage: 1,
levels: { normal: 1, conehead: 1, buckethead: 1, football: 1, dancing: 1 },
mutations: {}
}
};
}
@@ -301,7 +314,37 @@ window.PvZAuth = (function () {
achievements: {
...(loc.achievements || {}),
...(base.achievements || {})
}
},
casino: (base.casino || loc.casino)
? {
...def.casino,
...(loc.casino || {}),
...(base.casino || {}),
deposit: (base.casino && base.casino.deposit !== undefined) ? Number(base.casino.deposit) : (Number(loc.casino?.deposit) || 0),
depositStartTime: (base.casino && base.casino.depositStartTime) ? Number(base.casino.depositStartTime) : (Number(loc.casino?.depositStartTime) || 0),
loan: (base.casino && base.casino.loan !== undefined) ? Number(base.casino.loan) : (Number(loc.casino?.loan) || 0),
spinsTotal: Math.max(Number(base.casino?.spinsTotal) || 0, Number(loc.casino?.spinsTotal) || 0),
totalWon: Math.max(Number(base.casino?.totalWon) || 0, Number(loc.casino?.totalWon) || 0),
jackpotsWon: Math.max(Number(base.casino?.jackpotsWon) || 0, Number(loc.casino?.jackpotsWon) || 0)
}
: def.casino,
zombieLab: (base.zombieLab || loc.zombieLab)
? {
...def.zombieLab,
...(loc.zombieLab || {}),
...(base.zombieLab || {}),
unlockedStage: Math.max(Number(base.zombieLab?.unlockedStage) || 1, Number(loc.zombieLab?.unlockedStage) || 1),
levels: {
...def.zombieLab.levels,
...(loc.zombieLab?.levels || {}),
...(base.zombieLab?.levels || {})
},
mutations: {
...(loc.zombieLab?.mutations || {}),
...(base.zombieLab?.mutations || {})
}
}
: def.zombieLab
};
}
+1
View File
@@ -138,6 +138,7 @@ window.CasinoSystem = class CasinoSystem {
}
}
this.isSpinning = false;
this.saveToAuth();
return {
+14 -1
View File
@@ -130,11 +130,21 @@ window.EconomySystem = class EconomySystem {
this.selectedDeck = deckIds.filter(id => this.isPlantUnlocked(id)).slice(0, this.getMaxSlots());
this.saveProfileData();
}
const chosen = this.selectedDeck.length > 0 ? this.selectedDeck : this.defaultUnlocked;
const chosen = (this.selectedDeck && this.selectedDeck.length > 0) ? this.selectedDeck : this.defaultUnlocked;
this.cards = chosen.map(id => {
const found = this.allCards.find(c => c.id === id);
return found ? { ...found, timer: 0 } : null;
}).filter(Boolean);
// Guaranteed fallback: If this.cards is empty, restore default starter cards so top menu never disappears
if (!this.cards || this.cards.length === 0) {
this.selectedDeck = [...this.defaultUnlocked];
this.cards = this.defaultUnlocked.map(id => {
const found = this.allCards.find(c => c.id === id);
return found ? { ...found, timer: 0 } : null;
}).filter(Boolean);
this.saveProfileData();
}
}
reloadProfileData() {
@@ -720,6 +730,9 @@ window.EconomySystem = class EconomySystem {
}
// 2. Draw Cards
if (!this.isConveyor && !this.isIZombie && (!this.cards || this.cards.length === 0)) {
this.setDeckFromSelection();
}
const cardStartX = 105;
const cardY = 8;
const cardW = 66;