This commit is contained in:
2025-08-29 12:01:50 -05:00
parent 000b119641
commit 94ebef11bd
11 changed files with 7 additions and 50 deletions

View File

@@ -4,7 +4,7 @@ from . import db
intents = discord.Intents.default() intents = discord.Intents.default()
intents.message_content = True intents.message_content = True
intents.members = True # better name resolution intents.members = True
BOT_PREFIX = os.getenv("BOT_PREFIX", "!") BOT_PREFIX = os.getenv("BOT_PREFIX", "!")
TOKEN = os.getenv("DISCORD_TOKEN") TOKEN = os.getenv("DISCORD_TOKEN")

View File

@@ -5,7 +5,6 @@ from typing import Optional, List, Tuple, Dict
from .. import db from .. import db
# ====== Config (inline so you don't have to touch constants.py) ======
BAC_MIN_BET = 10 BAC_MIN_BET = 10
BAC_MAX_BET = 100_000 BAC_MAX_BET = 100_000
TIE_PAYS = 8 # 8:1 (plus stake => ×9 return) TIE_PAYS = 8 # 8:1 (plus stake => ×9 return)
@@ -309,7 +308,6 @@ class Baccarat(commands.Cog):
async def baccarat(self, ctx: commands.Context): async def baccarat(self, ctx: commands.Context):
uid = ctx.author.id uid = ctx.author.id
if uid in _active_bac: if uid in _active_bac:
# Replace their old panel if it's still around
try: try:
old = _active_bac[uid] old = _active_bac[uid]
if old.message: await old.message.delete() if old.message: await old.message.delete()

View File

@@ -96,7 +96,6 @@ class BlackjackGame:
self.game_over = True self.game_over = True
def create_embed(game: BlackjackGame, reveal: bool = False) -> discord.Embed: def create_embed(game: BlackjackGame, reveal: bool = False) -> discord.Embed:
# (unchanged renderer from your file)
dv = game.dealer_hand.get_value() dv = game.dealer_hand.get_value()
if game.game_over: if game.game_over:
if game.is_split_game: if game.is_split_game:
@@ -164,7 +163,6 @@ def create_embed(game: BlackjackGame, reveal: bool = False) -> discord.Embed:
embed.add_field(name="📊 Result", value=txt, inline=False) embed.add_field(name="📊 Result", value=txt, inline=False)
return embed return embed
# ====== New UI layer (Set Bet / ×2 / ½ / Deal + in-game buttons) ======
MIN_BJ_BET = 10 # simple minimum MIN_BJ_BET = 10 # simple minimum
@@ -227,7 +225,6 @@ class BlackjackPanel(discord.ui.View):
b = self._btn(lbl) b = self._btn(lbl)
if b: b.disabled = not hand_active if b: b.disabled = not hand_active
# More granular in-hand state
if hand_active: if hand_active:
h = self.game.get_current_hand() h = self.game.get_current_hand()
b_hit = self._btn("Hit") b_hit = self._btn("Hit")
@@ -313,7 +310,6 @@ class BlackjackPanel(discord.ui.View):
if self.user_id in active_games: if self.user_id in active_games:
return await itx.response.send_message("You already have an active blackjack hand.", ephemeral=True) return await itx.response.send_message("You already have an active blackjack hand.", ephemeral=True)
# validate funds similar to old command
cash,_ = db.get_wallet(self.user_id) cash,_ = db.get_wallet(self.user_id)
if self.bet < MIN_BJ_BET: if self.bet < MIN_BJ_BET:
return await itx.response.send_message(f"Minimum bet is ${MIN_BJ_BET}.", ephemeral=True) return await itx.response.send_message(f"Minimum bet is ${MIN_BJ_BET}.", ephemeral=True)

View File

@@ -1,10 +1,4 @@
# src/cogs/coinflip.py # src/cogs/coinflip.py
# Coin Flip with Towers-style "Set Bet" modal and a minimal 2-row UI.
# Buttons: [Set Bet, ×2, ½] and [Heads, Tails]
#
# Commands:
# !coin (aliases: !coinflip, !cf, !flip)
# !rules_coin (optional)
import random import random
import discord import discord
@@ -128,7 +122,6 @@ class CoinFlipView(discord.ui.View):
if return_amount: if return_amount:
db.add_cash(self.user_id, return_amount) db.add_cash(self.user_id, return_amount)
# record stats (kept even if not shown on balance)
try: try:
db.record_coinflip(self.user_id, bet=self.chip, return_amount=return_amount, won=won) db.record_coinflip(self.user_id, bet=self.chip, return_amount=return_amount, won=won)
except Exception: except Exception:

View File

@@ -2,7 +2,6 @@ import discord
from discord.ext import commands from discord.ext import commands
from .. import db from .. import db
# Try to import constants; provide safe defaults if missing.
try: try:
from ..utils.constants import ( from ..utils.constants import (
DAILY_CASH, DAILY_FREE_SPINS, DAILY_CASH, DAILY_FREE_SPINS,
@@ -57,6 +56,8 @@ class RulesSelect(discord.ui.Select):
embed = rules_blackjack_embed() embed = rules_blackjack_embed()
elif choice == "Slots": elif choice == "Slots":
embed = rules_slots_embed() embed = rules_slots_embed()
elif choice == "Coin Flip":
embed = rules_coinflip_embed()
elif choice == "Roulette (Mini)": elif choice == "Roulette (Mini)":
embed = rules_roulette_mini_embed() embed = rules_roulette_mini_embed()
elif choice == "Towers": elif choice == "Towers":
@@ -67,7 +68,7 @@ class RulesSelect(discord.ui.Select):
embed = rules_hilo_embed() embed = rules_hilo_embed()
elif choice == "Mines": elif choice == "Mines":
embed = rules_mines_embed() embed = rules_mines_embed()
else: # Packs or fallback else:
embed = rules_packs_embed() embed = rules_packs_embed()
await interaction.response.edit_message(embed=embed, view=self.view) await interaction.response.edit_message(embed=embed, view=self.view)
@@ -138,7 +139,6 @@ def rules_blackjack_embed():
return e return e
def rules_slots_embed(): def rules_slots_embed():
# Payout table (if provided) to pretty-print
if PAYOUTS: if PAYOUTS:
pairs = sorted(PAYOUTS.items(), key=lambda kv: kv[1], reverse=True) pairs = sorted(PAYOUTS.items(), key=lambda kv: kv[1], reverse=True)
lines = [f"{sym} x{mult}" for sym, mult in pairs] lines = [f"{sym} x{mult}" for sym, mult in pairs]
@@ -197,13 +197,11 @@ class CasinoView(discord.ui.View):
return True return True
async def _launch(self, interaction: discord.Interaction, command_name: str): async def _launch(self, interaction: discord.Interaction, command_name: str):
# Acknowledge fast
try: try:
await interaction.response.defer(thinking=False) await interaction.response.defer(thinking=False)
except Exception: except Exception:
pass pass
# Delete the menu to reduce clutter
try: try:
await interaction.message.delete() await interaction.message.delete()
except Exception: except Exception:
@@ -214,7 +212,6 @@ class CasinoView(discord.ui.View):
except Exception: except Exception:
pass pass
# Invoke command
cmd = self.cog.bot.get_command(command_name) cmd = self.cog.bot.get_command(command_name)
if cmd is None: if cmd is None:
return await self.ctx.send(f"⚠️ Command `{command_name}` not found.") return await self.ctx.send(f"⚠️ Command `{command_name}` not found.")

View File

@@ -6,7 +6,6 @@ from typing import Optional
from .. import db from .. import db
# ---- Config (safe fallbacks; override in constants.py if you like) ----
try: try:
from ..utils.constants import HILO_EDGE_PER_STEP, HILO_MAX_MULT, HILO_MIN_BET from ..utils.constants import HILO_EDGE_PER_STEP, HILO_MAX_MULT, HILO_MIN_BET
except Exception: except Exception:
@@ -89,8 +88,6 @@ class HiloView(discord.ui.View):
self.last_note: Optional[str] = None self.last_note: Optional[str] = None
self.message: Optional[discord.Message] = None self.message: Optional[discord.Message] = None
# NEW: summary of the last finished round (loss or cashout)
# keys: 'from','to','guess','net','returned','steps','mult'
self.last_summary: Optional[dict] = None self.last_summary: Optional[dict] = None
self._busy = False self._busy = False
@@ -184,7 +181,6 @@ class HiloView(discord.ui.View):
b = self._btn(lbl) b = self._btn(lbl)
if b: b.disabled = not hand_active if b: b.disabled = not hand_active
# Edge cases: disable impossible guesses
if hand_active and self.current_card: if hand_active and self.current_card:
cur = RANK_TO_VAL[self.current_card[0]] cur = RANK_TO_VAL[self.current_card[0]]
if self._btn("LOWER"): if self._btn("LOWER"):
@@ -233,11 +229,10 @@ class HiloView(discord.ui.View):
nrank, nsuit = draw_card() nrank, nsuit = draw_card()
if nrank != from_rank: if nrank != from_rank:
break break
# gentle note, no state change
self.last_note = "Tie (same rank) — try again." self.last_note = "Tie (same rank) — try again."
await itx.response.edit_message(embed=self.render(), view=self) await itx.response.edit_message(embed=self.render(), view=self)
self._busy = False self._busy = False
return # require another click to proceed return
win = (RANK_TO_VAL[nrank] > cur_val) if direction == "up" else (RANK_TO_VAL[nrank] < cur_val) win = (RANK_TO_VAL[nrank] > cur_val) if direction == "up" else (RANK_TO_VAL[nrank] < cur_val)
@@ -258,7 +253,6 @@ class HiloView(discord.ui.View):
# lose round: no return, bet already debited # lose round: no return, bet already debited
returned = 0 returned = 0
db.record_hilo(self.user_id, bet=self.bet, return_amount=returned, won=False) db.record_hilo(self.user_id, bet=self.bet, return_amount=returned, won=False)
# Save a visible summary BEFORE resetting state
self.last_summary = { self.last_summary = {
"from": (from_rank, from_suit), "from": (from_rank, from_suit),
"to": (nrank, nsuit), "to": (nrank, nsuit),

View File

@@ -6,7 +6,6 @@ from typing import Optional, Set, Tuple
from .. import db from .. import db
# --- Config (override via constants.py if present) ---
try: try:
from ..utils.constants import ( from ..utils.constants import (
MINES_MIN_BET, MINES_EDGE_PER_STEP, MINES_MAX_MULT, MINES_CHOICES MINES_MIN_BET, MINES_EDGE_PER_STEP, MINES_MAX_MULT, MINES_CHOICES
@@ -170,7 +169,6 @@ class MinesView(discord.ui.View):
for c in range(GRID_N): for c in range(GRID_N):
idx = coord_to_idx((r, c)) idx = coord_to_idx((r, c))
if idx in revealed: if idx in revealed:
# if we want the clicked bomb to show as 💥 even if counted as revealed, prefer 💥
if show_mines and hit_idx is not None and idx == hit_idx: if show_mines and hit_idx is not None and idx == hit_idx:
row_emojis.append(EMO_HIT) row_emojis.append(EMO_HIT)
else: else:
@@ -229,7 +227,6 @@ class MinesView(discord.ui.View):
] ]
e.description = "\n".join(desc) e.description = "\n".join(desc)
# NEW: show snapshot board if present
if self.last_summary is not None and self.last_summary.get("board"): if self.last_summary is not None and self.last_summary.get("board"):
e.add_field(name="Board", value=self.last_summary["board"], inline=False) e.add_field(name="Board", value=self.last_summary["board"], inline=False)
@@ -306,13 +303,11 @@ class MinesView(discord.ui.View):
self._busy = True self._busy = True
idx = coord_to_idx(rc) idx = coord_to_idx(rc)
# already revealed?
if idx in self.revealed: if idx in self.revealed:
self._busy = False self._busy = False
return return
if idx in self.mines: if idx in self.mines:
# build snapshot BEFORE resetting: show all mines and mark the hit
snapshot_board = self._grid_text( snapshot_board = self._grid_text(
show_mines=True, with_labels=True, show_mines=True, with_labels=True,
mines=set(self.mines), revealed=set(self.revealed), hit_idx=idx mines=set(self.mines), revealed=set(self.revealed), hit_idx=idx
@@ -335,7 +330,6 @@ class MinesView(discord.ui.View):
self._busy = False self._busy = False
return return
# success — update multiplier and state
step_mult = step_multiplier(self.total_rem, self.safe_rem) step_mult = step_multiplier(self.total_rem, self.safe_rem)
self.mult = min(self.mult * step_mult, MINES_MAX_MULT) self.mult = min(self.mult * step_mult, MINES_MAX_MULT)
self.revealed.add(idx) self.revealed.add(idx)

View File

@@ -6,13 +6,11 @@ from typing import Optional, Dict, List, Tuple
from .. import db from .. import db
# ---- Tunables (override via constants.py if you want) ----
try: try:
from ..utils.constants import PACK_MIN_BET, PACK_SIZE, PACK_RARITY_WEIGHTS from ..utils.constants import PACK_MIN_BET, PACK_SIZE, PACK_RARITY_WEIGHTS
except Exception: except Exception:
PACK_MIN_BET = 50 PACK_MIN_BET = 50
PACK_SIZE = 5 PACK_SIZE = 5
# weights per rarity (sum doesn't need to be 1; we normalize)
PACK_RARITY_WEIGHTS = { PACK_RARITY_WEIGHTS = {
"Common": 600, "Common": 600,
"Uncommon": 250, "Uncommon": 250,
@@ -22,10 +20,6 @@ except Exception:
"Mythic": 1, "Mythic": 1,
} }
# -----------------------------------------------------------------------------
# Catalog: id, emoji, display name, rarity, multiplier (× bet)
# Kept your original 25 items & IDs; expanded to 100 total.
# -----------------------------------------------------------------------------
CATALOG: List[Dict] = [ CATALOG: List[Dict] = [
# ---------------------- Common (40) ---------------------- # ---------------------- Common (40) ----------------------
{"id":"cherry","emoji":"🍒","name":"Cherries","rarity":"Common","mult":0.10}, {"id":"cherry","emoji":"🍒","name":"Cherries","rarity":"Common","mult":0.10},
@@ -277,7 +271,6 @@ class PacksCollectionView(discord.ui.View):
return True return True
def _sync(self): def _sync(self):
# enable/disable nav buttons based on current page
for c in self.children: for c in self.children:
if isinstance(c, discord.ui.Button): if isinstance(c, discord.ui.Button):
if c.custom_id == "first": c.disabled = (self.page <= 0) if c.custom_id == "first": c.disabled = (self.page <= 0)

View File

@@ -1,12 +1,4 @@
# src/cogs/roulette.py # src/cogs/roulette.py
# Mini Roulette (018) with a single ephemeral "Bet Builder" panel.
# - Outside/Inside flows live in ONE popup; each step edits the same ephemeral message.
# - Back / Close buttons on every picker.
# - Clear Slip also resets chip to $0.
# - Requires:
# from ..utils.constants import (ROULETTE_NUMBERS, ROULETTE_RED, ROULETTE_BLACK,
# ROULETTE_MIN_CHIP, ROULETTE_MIN_BET, ROULETTE_MAX_BET)
# from .. import db
import random, discord import random, discord
from typing import List, Tuple, Dict, Any, Optional from typing import List, Tuple, Dict, Any, Optional

View File

@@ -67,7 +67,7 @@ def evaluate(board, active_indices: List[int]):
if len(non_stars) == 2 and non_stars[0] == non_stars[1]: if len(non_stars) == 2 and non_stars[0] == non_stars[1]:
fruit = non_stars[0] fruit = non_stars[0]
base = PAYOUTS.get(fruit, 0) base = PAYOUTS.get(fruit, 0)
mult = max(1, int(base * WILDCARD_FACTOR)) # reduced payout for wild wins mult = max(1, int(base * WILDCARD_FACTOR))
total_mult += mult total_mult += mult
winning_lines.append((idx, fruit, mult)) winning_lines.append((idx, fruit, mult))
continue continue

View File

@@ -5,7 +5,7 @@ DAILY_CASH = int(os.getenv("DAILY_BONUS", "10000"))
DAILY_COOLDOWN_HOURS = int(os.getenv("DAILY_COOLDOWN_HOURS", "24")) DAILY_COOLDOWN_HOURS = int(os.getenv("DAILY_COOLDOWN_HOURS", "24"))
DAILY_FREE_SPINS = int(os.getenv("DAILY_FREE_SPINS", "10")) DAILY_FREE_SPINS = int(os.getenv("DAILY_FREE_SPINS", "10"))
# Slots base (now we support variable bets; this acts as default if user omits) # Slots base
SLOTS_DEFAULT_BET = int(os.getenv("SLOTS_DEFAULT_BET", "8")) SLOTS_DEFAULT_BET = int(os.getenv("SLOTS_DEFAULT_BET", "8"))
SLOTS_MIN_BET = int(os.getenv("SLOTS_MIN_BET", "8")) SLOTS_MIN_BET = int(os.getenv("SLOTS_MIN_BET", "8"))
SLOTS_MAX_BET = int(os.getenv("SLOTS_MAX_BET", "5000")) SLOTS_MAX_BET = int(os.getenv("SLOTS_MAX_BET", "5000"))