// plugins/slots.js - Slot Machine game plugin const fs = require('fs'); const path = require('path'); module.exports = { init(bot) { console.log('Slot Machine plugin initialized'); this.bot = bot; // Player scores storage this.playerScores = new Map(); // nick -> { totalWins, biggestWin, totalSpins, jackpots, name } // Slot machine symbols with weights and payouts this.symbols = [ { emoji: '🍒', name: 'Cherry', weight: 25, payout: 2 }, { emoji: '🍊', name: 'Orange', weight: 20, payout: 3 }, { emoji: '🍋', name: 'Lemon', weight: 20, payout: 3 }, { emoji: '🍇', name: 'Grapes', weight: 15, payout: 5 }, { emoji: '🔔', name: 'Bell', weight: 10, payout: 10 }, { emoji: '⭐', name: 'Star', weight: 6, payout: 15 }, { emoji: '💎', name: 'Diamond', weight: 3, payout: 25 }, { emoji: '🎰', name: 'Jackpot', weight: 1, payout: 100 } ]; // Set up score file path this.scoresFile = path.join(__dirname, 'slots_scores.json'); // Load existing scores this.loadScores(); }, cleanup(bot) { console.log('Slot Machine plugin cleaned up'); // Save scores before cleanup this.saveScores(); }, // Load scores from file loadScores() { try { if (fs.existsSync(this.scoresFile)) { const data = fs.readFileSync(this.scoresFile, 'utf8'); const scoresObject = JSON.parse(data); // Convert back to Map this.playerScores = new Map(Object.entries(scoresObject)); console.log(`🎰 Loaded ${this.playerScores.size} slot player scores from ${this.scoresFile}`); // Log top 3 players if any exist if (this.playerScores.size > 0) { const topPlayers = Array.from(this.playerScores.values()) .sort((a, b) => b.totalWins - a.totalWins) .slice(0, 3); console.log('🏆 Top slot players:', topPlayers.map(p => `${p.name}(${p.totalWins})`).join(', ')); } } else { console.log(`🎰 No existing slot scores file found, starting fresh`); } } catch (error) { console.error(`❌ Error loading slot scores:`, error); this.playerScores = new Map(); // Reset to empty if load fails } }, // Save scores to file saveScores() { try { // Convert Map to plain object for JSON serialization const scoresObject = Object.fromEntries(this.playerScores); const data = JSON.stringify(scoresObject, null, 2); fs.writeFileSync(this.scoresFile, data, 'utf8'); console.log(`💾 Saved ${this.playerScores.size} slot player scores to ${this.scoresFile}`); } catch (error) { console.error(`❌ Error saving slot scores:`, error); } }, // Update a player's score and save to file updatePlayerScore(nick, updates) { if (!this.playerScores.has(nick)) { this.playerScores.set(nick, { totalWins: 0, biggestWin: 0, totalSpins: 0, jackpots: 0, name: nick }); } const player = this.playerScores.get(nick); Object.assign(player, updates); // Save to file after each update this.saveScores(); }, // Weighted random symbol selection getRandomSymbol() { const totalWeight = this.symbols.reduce((sum, symbol) => sum + symbol.weight, 0); let random = Math.random() * totalWeight; for (const symbol of this.symbols) { random -= symbol.weight; if (random <= 0) { return symbol; } } return this.symbols[0]; // fallback }, // Spin the slot machine spinSlots() { const reel1 = this.getRandomSymbol(); const reel2 = this.getRandomSymbol(); const reel3 = this.getRandomSymbol(); return { reel1, reel2, reel3 }; }, // Calculate winnings based on the spin result calculateWinnings(spin) { const { reel1, reel2, reel3 } = spin; // Check for three of a kind (jackpot) if (reel1.emoji === reel2.emoji && reel2.emoji === reel3.emoji) { return { type: 'triple', amount: reel1.payout, symbol: reel1, message: `🎉 TRIPLE ${reel1.name.toUpperCase()}! 🎉` }; } // Check for two of a kind if (reel1.emoji === reel2.emoji || reel2.emoji === reel3.emoji || reel1.emoji === reel3.emoji) { let matchSymbol; if (reel1.emoji === reel2.emoji) matchSymbol = reel1; else if (reel2.emoji === reel3.emoji) matchSymbol = reel2; else matchSymbol = reel1; const payout = Math.floor(matchSymbol.payout / 3); // Reduced payout for pairs if (payout > 0) { return { type: 'pair', amount: payout, symbol: matchSymbol, message: `✨ Pair of ${matchSymbol.name}s! ✨` }; } } // No match return { type: 'none', amount: 0, symbol: null, message: '💸 No match, try again!' }; }, commands: [ { name: 'slots', description: 'Spin the slot machine!', execute: function(context, bot) { const plugin = module.exports; const target = context.replyTo; const from = context.nick; // Initialize player if new if (!plugin.playerScores.has(from)) { plugin.updatePlayerScore(from, { totalWins: 0, biggestWin: 0, totalSpins: 0, jackpots: 0, name: from }); } // Spin the slots const spin = plugin.spinSlots(); const result = plugin.calculateWinnings(spin); // Update player stats const player = plugin.playerScores.get(from); const updates = { totalSpins: player.totalSpins + 1 }; let output = `🎰 ${from}: [${spin.reel1.emoji}|${spin.reel2.emoji}|${spin.reel3.emoji}] `; if (result.amount > 0) { // Player won! updates.totalWins = player.totalWins + result.amount; if (result.amount > player.biggestWin) { updates.biggestWin = result.amount; } if (result.type === 'triple' && result.symbol.emoji === '🎰') { updates.jackpots = player.jackpots + 1; output += `🚨 JACKPOT! 🚨 `; } else if (result.amount >= 50) { output += `🔥 BIG WIN! 🔥 `; } else if (result.type === 'triple') { output += `🎉 TRIPLE! 🎉 `; } else { output += `✨ PAIR! ✨ `; } output += `+${result.amount} pts | Total: ${updates.totalWins}`; } else { // Player lost output += `💸 No match | Spins: ${updates.totalSpins} | Total: ${player.totalWins}`; } bot.say(target, output); plugin.updatePlayerScore(from, updates); } }, { name: 'slotsstats', description: 'Show your slot machine statistics', execute: function(context, bot) { const plugin = module.exports; const target = context.replyTo; const from = context.nick; if (!plugin.playerScores.has(from)) { bot.say(target, `${from}: You haven't played slots yet! Use !slots to start.`); return; } const player = plugin.playerScores.get(from); const avgPts = player.totalSpins > 0 ? (player.totalWins / player.totalSpins).toFixed(1) : 0; bot.say(target, `🎰 ${from}: ${player.totalWins} total pts | Best: ${player.biggestWin} | Spins: ${player.totalSpins} | Jackpots: ${player.jackpots} | Avg: ${avgPts} pts/spin`); } }, { name: 'topslots', description: 'Show top slot machine players', execute: function(context, bot) { const plugin = module.exports; const target = context.replyTo; if (plugin.playerScores.size === 0) { bot.say(target, 'No slot scores recorded yet! Use !slots to start playing.'); return; } // Get top 3 players and biggest win const topPlayers = Array.from(plugin.playerScores.values()) .sort((a, b) => b.totalWins - a.totalWins) .slice(0, 3); const biggestWin = Array.from(plugin.playerScores.values()) .sort((a, b) => b.biggestWin - a.biggestWin)[0]; let output = '🏆 Top Slots: '; topPlayers.forEach((player, i) => { const trophy = i === 0 ? '🥇' : i === 1 ? '🥈' : '🥉'; output += `${trophy}${player.name}(${player.totalWins}) `; }); if (biggestWin && biggestWin.biggestWin > 0) { output += `| 🎰 Biggest Win: ${biggestWin.name}(${biggestWin.biggestWin})`; } bot.say(target, output); } }, { name: 'slotspayouts', description: 'Show slot machine payout table', execute: function(context, bot) { const plugin = module.exports; const target = context.replyTo; // Create compact payout display let output = '🎰 Payouts: '; const sortedSymbols = [...plugin.symbols].sort((a, b) => b.payout - a.payout); sortedSymbols.forEach((symbol, i) => { const pairPayout = Math.floor(symbol.payout / 3); if (i > 0) output += ' | '; if (symbol.emoji === '🎰') { output += `${symbol.emoji}x3=${symbol.payout}(JACKPOT!)`; } else { output += `${symbol.emoji}x3=${symbol.payout} x2=${pairPayout}`; } }); bot.say(target, output); } }, { name: 'resetslots', description: 'Reset all slot scores (admin command)', execute: function(context, bot) { const plugin = module.exports; const target = context.replyTo; const from = context.nick; // Simple admin check - you can customize this list const adminNicks = ['admin', 'owner', 'cancerbot']; // Add your admin nicks here if (!adminNicks.includes(from)) { bot.say(target, `${from}: Access denied - admin only command`); return; } const playerCount = plugin.playerScores.size; plugin.playerScores.clear(); plugin.saveScores(); bot.say(target, `🗑️ ${from}: Reset ${playerCount} slot player scores`); } } ] };