Files
ai-qpid-pvz/game/js/systems/casino.js
T

263 lines
8.7 KiB
JavaScript

// Crazy Dave's Casino & Bank System (Slot Machine & Bank Deposits/Loans)
window.CasinoSystem = class CasinoSystem {
constructor(economy) {
this.economy = economy;
// Slot machine symbols
this.symbols = [
{ id: 'sunflower', icon: '🌻', name: 'Подсолнух', weight: 30, mult: 4 },
{ id: 'pea', icon: '🟢', name: 'Горох', weight: 25, mult: 8 },
{ id: 'wallnut', icon: '🌰', name: 'Орех', weight: 20, mult: 12 },
{ id: 'cherry', icon: '🍒', name: 'Вишня', weight: 12, mult: 25 },
{ id: 'diamond', icon: '💎', name: 'Алмаз', weight: 6, mult: 60, crystals: 2 },
{ id: 'jackpot7', icon: '7️⃣', name: 'Семёрка', weight: 3, mult: 200, crystals: 5 },
{ id: 'brains', icon: '🧠', name: 'Мозги', weight: 4, mult: 0, isZombie: true }
];
// Bank State
this.deposit = 0;
this.depositStartTime = 0;
this.interestRatePerHour = 0.05; // 5% per hour (up to 48 hours max)
this.loan = 0;
this.loanLimit = 2500;
this.loanInterest = 0.10; // 10% fee
// Statistics
this.spinsTotal = 0;
this.totalWon = 0;
this.jackpotsWon = 0;
this.isSpinning = false;
this.currentBet = 50;
this.lastReels = ['🌻', '🟢', '🌰'];
this.loadFromAuth();
}
loadFromAuth() {
if (window.PvZAuth) {
const uData = window.PvZAuth.getUserData();
if (uData.casino) {
const c = uData.casino;
this.deposit = Number(c.deposit) || 0;
this.depositStartTime = Number(c.depositStartTime) || 0;
this.loan = Number(c.loan) || 0;
this.spinsTotal = Number(c.spinsTotal) || 0;
this.totalWon = Number(c.totalWon) || 0;
this.jackpotsWon = Number(c.jackpotsWon) || 0;
}
}
}
saveToAuth() {
if (window.PvZAuth && !window.PvZAuth.isGuest()) {
window.PvZAuth.saveUserData({
casino: {
deposit: this.deposit,
depositStartTime: this.depositStartTime,
loan: this.loan,
spinsTotal: this.spinsTotal,
totalWon: this.totalWon,
jackpotsWon: this.jackpotsWon
}
});
}
}
// Get random symbol based on weights
getRandomSymbol() {
const totalWeight = this.symbols.reduce((sum, s) => sum + s.weight, 0);
let rand = Math.random() * totalWeight;
for (const s of this.symbols) {
if (rand < s.weight) return s;
rand -= s.weight;
}
return this.symbols[0];
}
// Spin the reels
spin(bet = this.currentBet) {
if (this.isSpinning) return { error: 'Уже крутится!' };
if (!this.economy || this.economy.totalCoins < bet) {
return { error: 'Недостаточно монет для ставки!' };
}
// Deduct bet
this.economy.totalCoins -= bet;
this.economy.saveProfileData();
this.spinsTotal++;
this.isSpinning = true;
// Pick 3 symbols
const s1 = this.getRandomSymbol();
const s2 = this.getRandomSymbol();
const s3 = this.getRandomSymbol();
this.lastReels = [s1.icon, s2.icon, s3.icon];
let payout = 0;
let crystalsAwarded = 0;
let message = 'Повезет в следующий раз!';
let isJackpot = false;
// Check matches
if (s1.id === s2.id && s2.id === s3.id) {
// 3 of a kind
if (s1.id === 'jackpot7') {
payout = bet * s1.mult;
crystalsAwarded = s1.crystals || 5;
isJackpot = true;
this.jackpotsWon++;
message = `🔥 МЕГА ДЖЕКПОТ! +${payout} монет и +${crystalsAwarded} алмазов!`;
} else if (s1.id === 'brains') {
payout = 0;
message = '🧟 АТАКА ЗОМБИ! Все барабаны съедены!';
} else {
payout = bet * s1.mult;
if (s1.crystals) crystalsAwarded = s1.crystals;
message = `🎉 СУПЕР ВЫИГРЫШ: 3x ${s1.name}! +${payout} монет!`;
}
} else if (s1.id === s2.id || s2.id === s3.id || s1.id === s3.id) {
// 2 of a kind
const matched = (s1.id === s2.id) ? s1 : (s2.id === s3.id ? s2 : s1);
if (!matched.isZombie) {
payout = Math.round(bet * Math.max(1.5, matched.mult * 0.35));
message = `✨ Выигрыш: пара ${matched.icon}! +${payout} монет`;
}
}
if (payout > 0) {
this.economy.totalCoins += payout;
this.totalWon += payout;
this.economy.saveProfileData();
if (crystalsAwarded > 0 && this.economy.engine && this.economy.engine.workshop) {
this.economy.engine.workshop.addMaterial('crystals', crystalsAwarded);
}
if (window.PvZAudio) {
if (isJackpot) window.PvZAudio.playWin();
else window.PvZAudio.playCoin();
}
}
this.isSpinning = false;
this.saveToAuth();
return {
reels: [s1, s2, s3],
icons: [s1.icon, s2.icon, s3.icon],
payout,
crystals: crystalsAwarded,
isJackpot,
message,
coinsLeft: this.economy.totalCoins
};
}
// Calculate accrued interest on deposit
getAccruedInterest() {
if (this.deposit <= 0 || !this.depositStartTime) return 0;
const elapsedMs = Date.now() - this.depositStartTime;
const hours = Math.min(elapsedMs / (1000 * 3600), 48); // max 48h cap
return Math.floor(this.deposit * (this.interestRatePerHour * hours));
}
// Deposit coins into bank
depositCoins(amount) {
amount = Math.floor(amount);
if (amount <= 0) return { success: false, message: 'Некорректная сумма' };
if (!this.economy || this.economy.totalCoins < amount) {
return { success: false, message: 'Недостаточно монет на руках' };
}
// Collect any prior accrued interest
const interest = this.getAccruedInterest();
const priorDeposit = this.deposit;
this.economy.totalCoins -= amount;
this.deposit = priorDeposit + interest + amount;
this.depositStartTime = Date.now();
this.economy.saveProfileData();
this.saveToAuth();
if (window.PvZAudio) window.PvZAudio.playCoin();
return {
success: true,
deposit: this.deposit,
addedInterest: interest,
coinsLeft: this.economy.totalCoins,
message: `Успешно внесено ${amount} монет! (Начислено %: +${interest})`
};
}
// Withdraw full deposit + interest
withdrawDeposit() {
if (this.deposit <= 0) return { success: false, message: 'В банке нет вклада' };
const interest = this.getAccruedInterest();
const totalPayout = this.deposit + interest;
this.economy.totalCoins += totalPayout;
this.deposit = 0;
this.depositStartTime = 0;
this.economy.saveProfileData();
this.saveToAuth();
if (window.PvZAudio) window.PvZAudio.playWin();
return {
success: true,
payout: totalPayout,
interest,
coinsLeft: this.economy.totalCoins,
message: `Снято из банка: ${totalPayout} монет (включая % доход: +${interest})`
};
}
// Take a loan from Crazy Dave
takeLoan(amount) {
amount = Math.floor(amount);
if (this.loan > 0) {
return { success: false, message: `У вас уже есть непогашенный кредит: ${this.loan} монет!` };
}
if (amount <= 0 || amount > this.loanLimit) {
return { success: false, message: `Лимит кредита: от 100 до ${this.loanLimit} монет` };
}
const totalDebt = Math.round(amount * (1 + this.loanInterest));
this.loan = totalDebt;
this.economy.totalCoins += amount;
this.economy.saveProfileData();
this.saveToAuth();
if (window.PvZAudio) window.PvZAudio.playCoin();
return {
success: true,
amount,
debt: totalDebt,
coinsLeft: this.economy.totalCoins,
message: `Кредит выдан! Получено +${amount} монет. К возврату: ${totalDebt} монет.`
};
}
// Repay part or all loan
repayLoan(amount) {
if (this.loan <= 0) return { success: false, message: 'У вас нет долгов!' };
amount = Math.min(this.loan, Math.floor(amount));
if (amount <= 0 || this.economy.totalCoins < amount) {
return { success: false, message: 'Недостаточно монет для погашения' };
}
this.economy.totalCoins -= amount;
this.loan -= amount;
this.economy.saveProfileData();
this.saveToAuth();
if (window.PvZAudio) window.PvZAudio.playCoin();
return {
success: true,
paid: amount,
debtLeft: this.loan,
coinsLeft: this.economy.totalCoins,
message: this.loan === 0 ? '🎉 КРЕДИТ ПОЛНОСТЬЮ ПОГАШЕН!' : `Погашено ${amount} монет. Остаток долга: ${this.loan}`
};
}
};