All checks were successful
Build Docker Image / build (pull_request) Successful in 2m5s
Adds helpers/evolution_notifs.py with build_tier_up_embed() and notify_tier_completion(). Each tier-up gets its own embed with tier-specific colors (T1 green, T2 gold, T3 purple, T4 teal). Tier 4 uses a special 'FULLY EVOLVED!' title with a future rating boosts note. Notification failure is non-fatal (try/except). 23 unit tests cover all tiers, empty list, and failure path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
108 lines
2.9 KiB
Python
108 lines
2.9 KiB
Python
"""
|
|
Evolution Tier Completion Notifications
|
|
|
|
Builds and sends Discord embeds when a player completes an evolution tier
|
|
during post-game evaluation. Each tier-up event gets its own embed.
|
|
|
|
Notification failures are non-fatal: the send is wrapped in try/except so
|
|
a Discord API hiccup never disrupts game flow.
|
|
"""
|
|
|
|
import logging
|
|
from typing import Optional
|
|
|
|
import discord
|
|
|
|
logger = logging.getLogger("discord_app")
|
|
|
|
# Human-readable display names for each tier number.
|
|
TIER_NAMES = {
|
|
0: "Unranked",
|
|
1: "Initiate",
|
|
2: "Rising",
|
|
3: "Ascendant",
|
|
4: "Evolved",
|
|
}
|
|
|
|
# Tier-specific embed colors.
|
|
TIER_COLORS = {
|
|
1: 0x2ECC71, # green
|
|
2: 0xF1C40F, # gold
|
|
3: 0x9B59B6, # purple
|
|
4: 0x1ABC9C, # teal (fully evolved)
|
|
}
|
|
|
|
FOOTER_TEXT = "Paper Dynasty Evolution"
|
|
|
|
|
|
def build_tier_up_embed(tier_up: dict) -> discord.Embed:
|
|
"""Build a Discord embed for a tier-up event.
|
|
|
|
Parameters
|
|
----------
|
|
tier_up:
|
|
Dict with keys: player_name, old_tier, new_tier, current_value, track_name.
|
|
|
|
Returns
|
|
-------
|
|
discord.Embed
|
|
A fully configured embed ready to send to a channel.
|
|
"""
|
|
player_name: str = tier_up["player_name"]
|
|
new_tier: int = tier_up["new_tier"]
|
|
track_name: str = tier_up["track_name"]
|
|
|
|
tier_name = TIER_NAMES.get(new_tier, f"Tier {new_tier}")
|
|
color = TIER_COLORS.get(new_tier, 0x2ECC71)
|
|
|
|
if new_tier >= 4:
|
|
# Fully evolved — special title and description.
|
|
embed = discord.Embed(
|
|
title="FULLY EVOLVED!",
|
|
description=(
|
|
f"**{player_name}** has reached maximum evolution on the **{track_name}** track"
|
|
),
|
|
color=color,
|
|
)
|
|
embed.add_field(
|
|
name="Rating Boosts",
|
|
value="Rating boosts coming in a future update!",
|
|
inline=False,
|
|
)
|
|
else:
|
|
embed = discord.Embed(
|
|
title="Evolution Tier Up!",
|
|
description=(
|
|
f"**{player_name}** reached **Tier {new_tier} ({tier_name})** on the **{track_name}** track"
|
|
),
|
|
color=color,
|
|
)
|
|
|
|
embed.set_footer(text=FOOTER_TEXT)
|
|
return embed
|
|
|
|
|
|
async def notify_tier_completion(channel, tier_up: dict) -> None:
|
|
"""Send a tier-up notification embed to the given channel.
|
|
|
|
Non-fatal: any exception during send is caught and logged so that a
|
|
Discord API failure never interrupts game evaluation.
|
|
|
|
Parameters
|
|
----------
|
|
channel:
|
|
A discord.TextChannel (or any object with an async ``send`` method).
|
|
tier_up:
|
|
Dict with keys: player_name, old_tier, new_tier, current_value, track_name.
|
|
"""
|
|
try:
|
|
embed = build_tier_up_embed(tier_up)
|
|
await channel.send(embed=embed)
|
|
except Exception as exc:
|
|
logger.error(
|
|
"Failed to send tier-up notification for %s (tier %s): %s",
|
|
tier_up.get("player_name", "unknown"),
|
|
tier_up.get("new_tier"),
|
|
exc,
|
|
)
|