Merge pull request 'enhance/scouting' (#81) from enhance/scouting into main
All checks were successful
Build Docker Image / build (push) Successful in 1m21s
All checks were successful
Build Docker Image / build (push) Successful in 1m21s
Reviewed-on: #81
This commit is contained in:
commit
eb17b17dd4
@ -10,11 +10,14 @@ from discord import app_commands
|
||||
from discord.ext import commands, tasks
|
||||
|
||||
from api_calls import db_get
|
||||
from helpers.scouting import SCOUT_TOKENS_PER_DAY, get_scout_tokens_used
|
||||
from helpers.scouting import (
|
||||
SCOUT_TOKEN_COST,
|
||||
SCOUT_TOKENS_PER_DAY,
|
||||
get_scout_tokens_used,
|
||||
)
|
||||
from helpers.utils import int_timestamp
|
||||
from helpers.discord_utils import get_team_embed
|
||||
from helpers.main import get_team_by_owner
|
||||
from helpers.constants import PD_SEASON, IMAGES
|
||||
|
||||
logger = logging.getLogger("discord_app")
|
||||
|
||||
@ -54,7 +57,10 @@ class Scouting(commands.Cog):
|
||||
)
|
||||
|
||||
if tokens_remaining == 0:
|
||||
embed.description += "\n\nYou've used all your tokens! Check back tomorrow."
|
||||
embed.description += (
|
||||
f"\n\nYou've used all your free tokens! "
|
||||
f"You can still scout by purchasing a token for **{SCOUT_TOKEN_COST}₼**."
|
||||
)
|
||||
|
||||
await interaction.followup.send(embed=embed, ephemeral=True)
|
||||
|
||||
|
||||
@ -11,9 +11,10 @@ import logging
|
||||
|
||||
import discord
|
||||
|
||||
from api_calls import db_get, db_post
|
||||
from api_calls import db_get, db_patch, db_post
|
||||
from helpers.main import get_team_by_owner, get_card_embeds
|
||||
from helpers.scouting import (
|
||||
SCOUT_TOKEN_COST,
|
||||
SCOUT_TOKENS_PER_DAY,
|
||||
build_scout_embed,
|
||||
get_scout_tokens_used,
|
||||
@ -87,7 +88,7 @@ class ScoutView(discord.ui.View):
|
||||
)
|
||||
|
||||
try:
|
||||
await self.message.edit(embed=embed, view=self)
|
||||
await self.message.edit(embed=embed)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to update scout message: {e}")
|
||||
|
||||
@ -167,11 +168,27 @@ class ScoutButton(discord.ui.Button):
|
||||
tokens_used = await get_scout_tokens_used(scouter_team["id"])
|
||||
|
||||
if tokens_used >= SCOUT_TOKENS_PER_DAY:
|
||||
await interaction.followup.send(
|
||||
"You're out of scout tokens for today! You get 2 per day, resetting at midnight Central.",
|
||||
ephemeral=True,
|
||||
# Offer to buy an extra scout token
|
||||
buy_view = BuyScoutTokenView(
|
||||
scouter_team=scouter_team,
|
||||
responder_id=interaction.user.id,
|
||||
)
|
||||
return
|
||||
buy_msg = await interaction.followup.send(
|
||||
f"You're out of scout tokens for today! "
|
||||
f"You can buy one for **{SCOUT_TOKEN_COST}₼** "
|
||||
f"(wallet: {scouter_team['wallet']}₼).",
|
||||
view=buy_view,
|
||||
ephemeral=True,
|
||||
wait=True,
|
||||
)
|
||||
buy_view.message = buy_msg
|
||||
await buy_view.wait()
|
||||
|
||||
if not buy_view.value:
|
||||
return
|
||||
|
||||
# Refresh team data after purchase
|
||||
scouter_team = buy_view.scouter_team
|
||||
|
||||
# Record the claim in the database
|
||||
try:
|
||||
@ -272,3 +289,88 @@ class ScoutButton(discord.ui.Button):
|
||||
pass
|
||||
finally:
|
||||
view.processing_users.discard(interaction.user.id)
|
||||
|
||||
|
||||
class BuyScoutTokenView(discord.ui.View):
|
||||
"""Ephemeral confirmation view for purchasing an extra scout token."""
|
||||
|
||||
def __init__(self, scouter_team: dict, responder_id: int):
|
||||
super().__init__(timeout=30.0)
|
||||
self.scouter_team = scouter_team
|
||||
self.responder_id = responder_id
|
||||
self.value = False
|
||||
self.message: discord.Message | None = None
|
||||
|
||||
if scouter_team["wallet"] < SCOUT_TOKEN_COST:
|
||||
self.buy_button.disabled = True
|
||||
self.buy_button.label = (
|
||||
f"Not enough ₼ ({scouter_team['wallet']}/{SCOUT_TOKEN_COST})"
|
||||
)
|
||||
|
||||
async def on_timeout(self):
|
||||
"""Disable buttons when the buy window expires."""
|
||||
for item in self.children:
|
||||
item.disabled = True
|
||||
if self.message:
|
||||
try:
|
||||
await self.message.edit(view=self)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@discord.ui.button(
|
||||
label=f"Buy Scout Token ({SCOUT_TOKEN_COST}₼)",
|
||||
style=discord.ButtonStyle.green,
|
||||
)
|
||||
async def buy_button(
|
||||
self, interaction: discord.Interaction, button: discord.ui.Button
|
||||
):
|
||||
if interaction.user.id != self.responder_id:
|
||||
return
|
||||
|
||||
# Re-fetch team to get current wallet (prevent stale data)
|
||||
team = await get_team_by_owner(interaction.user.id)
|
||||
if not team or team["wallet"] < SCOUT_TOKEN_COST:
|
||||
await interaction.response.edit_message(
|
||||
content="You don't have enough ₼ for a scout token.",
|
||||
view=None,
|
||||
)
|
||||
self.stop()
|
||||
return
|
||||
|
||||
# Deduct currency
|
||||
new_wallet = team["wallet"] - SCOUT_TOKEN_COST
|
||||
try:
|
||||
await db_patch(
|
||||
"teams", object_id=team["id"], params=[("wallet", new_wallet)]
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to deduct scout token cost: {e}")
|
||||
await interaction.response.edit_message(
|
||||
content="Something went wrong processing your purchase. Try again!",
|
||||
view=None,
|
||||
)
|
||||
self.stop()
|
||||
return
|
||||
|
||||
self.scouter_team = team
|
||||
self.scouter_team["wallet"] = new_wallet
|
||||
self.value = True
|
||||
|
||||
await interaction.response.edit_message(
|
||||
content=f"Scout token purchased for {SCOUT_TOKEN_COST}₼! Scouting your card...",
|
||||
view=None,
|
||||
)
|
||||
self.stop()
|
||||
|
||||
@discord.ui.button(label="No thanks", style=discord.ButtonStyle.grey)
|
||||
async def cancel_button(
|
||||
self, interaction: discord.Interaction, button: discord.ui.Button
|
||||
):
|
||||
if interaction.user.id != self.responder_id:
|
||||
return
|
||||
|
||||
await interaction.response.edit_message(
|
||||
content="Saving that money. Smart.",
|
||||
view=None,
|
||||
)
|
||||
self.stop()
|
||||
|
||||
@ -20,6 +20,7 @@ from helpers.constants import IMAGES, PD_SEASON
|
||||
logger = logging.getLogger("discord_app")
|
||||
|
||||
SCOUT_TOKENS_PER_DAY = 2
|
||||
SCOUT_TOKEN_COST = 200 # Currency cost to buy an extra scout token
|
||||
SCOUT_WINDOW_SECONDS = 1800 # 30 minutes
|
||||
_scoutable_raw = os.environ.get("SCOUTABLE_PACK_TYPES", "Standard,Premium")
|
||||
SCOUTABLE_PACK_TYPES = {s.strip() for s in _scoutable_raw.split(",") if s.strip()}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user