2023-06-19 14:20:17 +00:00
|
|
|
import asyncio
|
|
|
|
import os
|
|
|
|
import random
|
|
|
|
|
|
|
|
import discord
|
|
|
|
from discord.ext import commands
|
|
|
|
from dotenv import load_dotenv
|
|
|
|
|
|
|
|
from data.BlackJackStats import BlackJackStats
|
|
|
|
from data.Currency import Currency
|
2023-06-29 19:42:58 +00:00
|
|
|
from data.Inventory import Inventory
|
|
|
|
from data.Item import Item
|
2023-06-19 14:20:17 +00:00
|
|
|
from data.SlotsStats import SlotsStats
|
2023-06-22 09:52:34 +00:00
|
|
|
from main import economy_config
|
2023-06-19 14:20:17 +00:00
|
|
|
from sb_tools import economy_embeds, economy_functions, universal, interaction, embeds
|
|
|
|
|
|
|
|
load_dotenv('.env')
|
|
|
|
|
|
|
|
active_blackjack_games = {}
|
|
|
|
special_balance_name = os.getenv("SPECIAL_BALANCE_NAME")
|
|
|
|
cash_balance_name = os.getenv("CASH_BALANCE_NAME")
|
|
|
|
|
|
|
|
|
2023-06-23 09:12:02 +00:00
|
|
|
class GamblingCog(commands.Cog):
|
2023-06-19 14:20:17 +00:00
|
|
|
def __init__(self, sbbot):
|
|
|
|
self.bot = sbbot
|
|
|
|
|
|
|
|
@commands.slash_command(
|
|
|
|
name="blackjack",
|
|
|
|
description="Start a game of blackjack.",
|
|
|
|
guild_only=True
|
|
|
|
)
|
|
|
|
@commands.check(universal.channel_check)
|
|
|
|
async def blackjack(self, ctx, *, bet: discord.Option(int)):
|
|
|
|
|
|
|
|
# check if the player already has an active blackjack going
|
|
|
|
if ctx.author.id in active_blackjack_games:
|
|
|
|
await ctx.respond(embed=economy_embeds.already_playing("BlackJack"))
|
|
|
|
return
|
|
|
|
|
2023-06-19 18:18:23 +00:00
|
|
|
# Currency handler
|
|
|
|
ctx_currency = Currency(ctx.author.id)
|
|
|
|
|
2023-06-19 14:20:17 +00:00
|
|
|
# check if the user has enough cash
|
2023-06-19 18:18:23 +00:00
|
|
|
player_cash_balance = ctx_currency.cash
|
2023-06-19 14:20:17 +00:00
|
|
|
if bet > player_cash_balance or bet <= 0:
|
|
|
|
await ctx.respond(embed=economy_embeds.not_enough_cash())
|
|
|
|
return
|
|
|
|
|
|
|
|
active_blackjack_games[ctx.author.id] = True
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
player_hand = []
|
|
|
|
dealer_hand = []
|
|
|
|
deck = economy_functions.blackjack_get_new_deck()
|
|
|
|
|
|
|
|
# deal initial cards (player draws two & dealer one)
|
|
|
|
player_hand.append(economy_functions.blackjack_deal_card(deck))
|
|
|
|
player_hand.append(economy_functions.blackjack_deal_card(deck))
|
|
|
|
dealer_hand.append(economy_functions.blackjack_deal_card(deck))
|
|
|
|
|
|
|
|
# calculate initial hands
|
|
|
|
player_hand_value = economy_functions.blackjack_calculate_hand_value(player_hand)
|
|
|
|
dealer_hand_value = economy_functions.blackjack_calculate_hand_value(dealer_hand)
|
|
|
|
|
2023-06-29 16:27:44 +00:00
|
|
|
status = "game_start" if player_hand_value != 21 else "player_blackjack"
|
|
|
|
view = interaction.BlackJackButtons(ctx) if status == "game_start" else None
|
2023-06-19 14:20:17 +00:00
|
|
|
|
|
|
|
await ctx.respond(embed=economy_embeds.blackjack_show(ctx, bet, player_hand,
|
|
|
|
dealer_hand, player_hand_value,
|
|
|
|
dealer_hand_value, status=status), view=view,
|
|
|
|
content=ctx.author.mention)
|
|
|
|
|
|
|
|
while status == "game_start":
|
|
|
|
await view.wait()
|
|
|
|
|
|
|
|
if view.clickedHit:
|
|
|
|
# player draws a card & value is calculated
|
|
|
|
player_hand.append(economy_functions.blackjack_deal_card(deck))
|
|
|
|
player_hand_value = economy_functions.blackjack_calculate_hand_value(player_hand)
|
|
|
|
|
|
|
|
if player_hand_value > 21:
|
|
|
|
status = "player_busted"
|
2023-06-29 16:27:44 +00:00
|
|
|
elif player_hand_value == 21:
|
2023-06-29 19:42:58 +00:00
|
|
|
status = "player_won_21"
|
2023-06-19 14:20:17 +00:00
|
|
|
|
|
|
|
elif view.clickedStand:
|
|
|
|
# player stands, dealer draws cards until he wins OR busts
|
|
|
|
while dealer_hand_value <= player_hand_value:
|
|
|
|
dealer_hand.append(economy_functions.blackjack_deal_card(deck))
|
|
|
|
dealer_hand_value = economy_functions.blackjack_calculate_hand_value(dealer_hand)
|
|
|
|
|
|
|
|
if dealer_hand_value > 21:
|
|
|
|
status = "dealer_busted"
|
|
|
|
else:
|
|
|
|
status = "dealer_won"
|
|
|
|
|
|
|
|
else:
|
|
|
|
status = "timed_out"
|
|
|
|
break
|
|
|
|
|
|
|
|
# edit the embed, disable view if game is over.
|
|
|
|
if status == "game_start":
|
|
|
|
view = interaction.BlackJackButtons(ctx)
|
|
|
|
else:
|
|
|
|
view = None
|
|
|
|
|
|
|
|
await ctx.edit(embed=economy_embeds.blackjack_show(ctx, bet, player_hand,
|
|
|
|
dealer_hand, player_hand_value,
|
|
|
|
dealer_hand_value, status=status), view=view,
|
|
|
|
content=ctx.author.mention)
|
|
|
|
|
|
|
|
# change balance
|
|
|
|
if status == "player_busted" or status == "dealer_won":
|
2023-06-19 18:18:23 +00:00
|
|
|
ctx_currency.take_cash(bet)
|
|
|
|
ctx_currency.push()
|
2023-06-19 14:20:17 +00:00
|
|
|
|
|
|
|
# push stats (low priority)
|
|
|
|
stats = BlackJackStats(
|
|
|
|
user_id=ctx.author.id,
|
|
|
|
is_won=False,
|
|
|
|
bet=bet,
|
|
|
|
payout=0,
|
|
|
|
hand_player=player_hand,
|
|
|
|
hand_dealer=dealer_hand
|
|
|
|
)
|
2023-06-19 18:18:23 +00:00
|
|
|
stats.push()
|
2023-06-19 14:20:17 +00:00
|
|
|
|
|
|
|
elif status == "timed_out":
|
|
|
|
await ctx.send(embed=economy_embeds.out_of_time(), content=ctx.author.mention)
|
2023-06-19 18:18:23 +00:00
|
|
|
ctx_currency.take_cash(bet)
|
|
|
|
ctx_currency.push()
|
2023-06-19 14:20:17 +00:00
|
|
|
|
|
|
|
else:
|
|
|
|
# bet multiplier
|
2023-06-22 09:52:34 +00:00
|
|
|
payout = bet * float(economy_config["blackjack"]["reward_multiplier"])
|
2023-06-19 18:18:23 +00:00
|
|
|
ctx_currency.add_cash(payout)
|
|
|
|
ctx_currency.push()
|
2023-06-19 14:20:17 +00:00
|
|
|
|
2023-06-29 19:42:58 +00:00
|
|
|
if status == "player_blackjack":
|
|
|
|
# if 21 -> add item
|
|
|
|
inventory = Inventory(ctx.author.id)
|
|
|
|
item = Item.get_item_by_name("bitch_coin")
|
|
|
|
inventory.add_item(item)
|
|
|
|
|
|
|
|
embed = discord.Embed(
|
|
|
|
color=discord.Color.embed_background(),
|
|
|
|
title="You hit a BlackJack!",
|
|
|
|
description=f"Yous a bitch for winning with a natural hand so I gave you 1 "
|
|
|
|
f"**{item.display_name}**."
|
|
|
|
)
|
|
|
|
embed.set_footer(text="Take a look in /inventory")
|
|
|
|
|
|
|
|
await ctx.respond(embed=embed)
|
|
|
|
|
2023-06-19 14:20:17 +00:00
|
|
|
# push stats (low priority)
|
|
|
|
stats = BlackJackStats(
|
|
|
|
user_id=ctx.author.id,
|
|
|
|
is_won=True,
|
|
|
|
bet=bet,
|
|
|
|
payout=payout,
|
|
|
|
hand_player=player_hand,
|
|
|
|
hand_dealer=dealer_hand
|
|
|
|
)
|
2023-06-19 18:18:23 +00:00
|
|
|
stats.push()
|
2023-06-19 14:20:17 +00:00
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
await ctx.respond(embed=embeds.command_error_1())
|
|
|
|
print("Something went wrong in the gambling command:\n", e)
|
|
|
|
|
|
|
|
finally:
|
|
|
|
# remove player from active games list
|
|
|
|
del active_blackjack_games[ctx.author.id]
|
|
|
|
|
|
|
|
@commands.slash_command(
|
|
|
|
name="slots",
|
|
|
|
descriptions="Spin the slots for a chance to win the jackpot!",
|
|
|
|
guild_only=True
|
|
|
|
)
|
|
|
|
@commands.check(universal.channel_check)
|
|
|
|
async def slots(self, ctx, *, bet: discord.Option(int)):
|
|
|
|
|
2023-06-19 18:18:23 +00:00
|
|
|
# Currency handler
|
|
|
|
ctx_currency = Currency(ctx.author.id)
|
|
|
|
|
2023-06-19 14:20:17 +00:00
|
|
|
# check if the user has enough cash
|
2023-06-19 18:18:23 +00:00
|
|
|
player_cash_balance = ctx_currency.cash
|
2023-06-19 14:20:17 +00:00
|
|
|
if bet > player_cash_balance or bet <= 0:
|
|
|
|
await ctx.respond(embed=economy_embeds.not_enough_cash())
|
|
|
|
return
|
|
|
|
|
|
|
|
# calculate the results before the command is shown
|
|
|
|
results = [random.randint(0, 6) for i in range(3)]
|
|
|
|
calculated_results = economy_functions.calculate_slots_results(bet, results)
|
|
|
|
|
|
|
|
type = calculated_results[0]
|
|
|
|
payout = calculated_results[1]
|
|
|
|
multiplier = calculated_results[2]
|
|
|
|
is_won = True
|
|
|
|
|
|
|
|
if type == "lost":
|
|
|
|
is_won = False
|
|
|
|
|
|
|
|
# start with default "spinning" embed
|
|
|
|
await ctx.respond(embed=economy_embeds.slots_spinning(ctx, 3, bet, results, self.bot))
|
|
|
|
await asyncio.sleep(1)
|
|
|
|
await ctx.edit(embed=economy_embeds.slots_spinning(ctx, 2, bet, results, self.bot),
|
|
|
|
allowed_mentions=discord.AllowedMentions.none())
|
|
|
|
await asyncio.sleep(1)
|
|
|
|
await ctx.edit(embed=economy_embeds.slots_spinning(ctx, 1, bet, results, self.bot),
|
|
|
|
allowed_mentions=discord.AllowedMentions.none())
|
|
|
|
await asyncio.sleep(1)
|
|
|
|
await ctx.edit(embed=economy_embeds.slots_finished(ctx, type, multiplier, bet, results, self.bot),
|
|
|
|
allowed_mentions=discord.AllowedMentions.none())
|
|
|
|
|
|
|
|
# user payout
|
2023-06-19 18:18:23 +00:00
|
|
|
if payout >= 0:
|
|
|
|
ctx_currency.add_cash(payout)
|
|
|
|
else:
|
|
|
|
ctx_currency.take_cash(payout)
|
2023-06-19 14:20:17 +00:00
|
|
|
|
|
|
|
# push stats (low priority)
|
|
|
|
if payout <= 0:
|
|
|
|
payout = 0
|
|
|
|
|
|
|
|
stats = SlotsStats(
|
|
|
|
user_id=ctx.author.id,
|
|
|
|
is_won=is_won,
|
|
|
|
bet=bet,
|
|
|
|
payout=payout,
|
|
|
|
spin_type=type,
|
|
|
|
icons=results
|
|
|
|
)
|
|
|
|
|
2023-06-19 18:18:23 +00:00
|
|
|
ctx_currency.push()
|
|
|
|
stats.push()
|
2023-06-19 14:20:17 +00:00
|
|
|
|
|
|
|
@commands.slash_command(
|
|
|
|
name="duel",
|
|
|
|
description="Challenge another player to a fight.",
|
|
|
|
guild_only=True
|
|
|
|
)
|
|
|
|
@commands.check(universal.channel_check)
|
|
|
|
async def duel(self, ctx, *, opponent: discord.Option(discord.Member), bet: discord.Option(int)):
|
|
|
|
challenger = ctx.author
|
|
|
|
|
|
|
|
if challenger.id == opponent.id:
|
|
|
|
return await ctx.respond(content="You cannot duel yourself.")
|
|
|
|
elif opponent.bot:
|
|
|
|
return await ctx.respond(content="You cannot duel a bot.")
|
|
|
|
|
2023-06-19 18:18:23 +00:00
|
|
|
# Currency handler
|
|
|
|
challenger_currency = Currency(ctx.author.id)
|
|
|
|
opponent_currency = Currency(opponent.id)
|
|
|
|
|
2023-06-19 14:20:17 +00:00
|
|
|
# check if challenger has enough cash
|
2023-06-19 18:18:23 +00:00
|
|
|
challenger_cash_balance = challenger_currency.cash
|
2023-06-19 14:20:17 +00:00
|
|
|
if bet > challenger_cash_balance or bet <= 0:
|
|
|
|
return await ctx.respond(embed=economy_embeds.not_enough_cash())
|
|
|
|
|
|
|
|
# if opponent doesn't have sufficient money, the bet will become the opponent's cash
|
2023-06-19 18:18:23 +00:00
|
|
|
opponent_cash_balance = opponent_currency.cash
|
2023-06-19 14:20:17 +00:00
|
|
|
all_in = ""
|
|
|
|
if opponent_cash_balance <= 0:
|
|
|
|
return await ctx.respond(f"Woops, you can't do that because **{opponent.name}** has no money.")
|
|
|
|
elif bet > opponent_cash_balance:
|
|
|
|
bet = opponent_cash_balance
|
|
|
|
all_in = " | opponent's all-in"
|
|
|
|
|
|
|
|
# challenge message
|
|
|
|
view = interaction.DuelChallenge(opponent)
|
|
|
|
|
|
|
|
await ctx.respond(
|
|
|
|
content=f"**{challenger.name}** challenges {opponent.mention} to a duel ({cash_balance_name}{bet}{all_in})\n"
|
|
|
|
f"Use the buttons to accept/deny (challenge expires after 60s)", view=view)
|
|
|
|
await view.wait()
|
|
|
|
|
|
|
|
if view.clickedConfirm:
|
|
|
|
winner = random.choice([challenger, opponent])
|
|
|
|
loser = opponent if winner == challenger else challenger
|
2023-06-22 09:52:34 +00:00
|
|
|
combat_message = random.choice(economy_config["duel"]["combat_messages"]).format(f"**{winner.name}**",
|
|
|
|
f"**{loser.name}**")
|
2023-06-19 14:20:17 +00:00
|
|
|
|
|
|
|
await ctx.respond(content=f"{combat_message}\n\n"
|
|
|
|
f"{winner.mention} wins **{cash_balance_name}{bet}**\n"
|
|
|
|
f"{loser.mention} loses this bet.")
|
|
|
|
|
|
|
|
# payouts
|
|
|
|
if winner == challenger:
|
2023-06-19 18:18:23 +00:00
|
|
|
challenger_currency.add_cash(bet)
|
|
|
|
opponent_currency.take_cash(bet)
|
2023-06-19 14:20:17 +00:00
|
|
|
|
|
|
|
elif winner == opponent:
|
2023-06-19 18:18:23 +00:00
|
|
|
opponent_currency.add_cash(bet)
|
|
|
|
challenger_currency.take_cash(bet)
|
2023-06-19 14:20:17 +00:00
|
|
|
|
|
|
|
elif view.clickedDeny:
|
|
|
|
await ctx.edit(content=f"**{opponent.name}** canceled the duel.")
|
|
|
|
|
|
|
|
else:
|
|
|
|
await ctx.edit(content=f"Time ran out.")
|
|
|
|
|
2023-06-19 18:18:23 +00:00
|
|
|
challenger_currency.push()
|
|
|
|
opponent_currency.push()
|
|
|
|
|
2023-06-19 14:20:17 +00:00
|
|
|
|
|
|
|
def setup(sbbot):
|
2023-06-23 09:12:02 +00:00
|
|
|
sbbot.add_cog(GamblingCog(sbbot))
|