1
0
forked from sass/tipibot

Refacor emoijs to use application emoijs

This commit is contained in:
Rene Arumetsa
2026-06-03 18:34:29 +03:00
10 changed files with 244 additions and 127 deletions

7
bot.py
View File

@@ -83,7 +83,7 @@ _txn_logger = logging.getLogger("tipiCOIN.txn")
_txn_logger.addHandler(_txn_h) _txn_logger.addHandler(_txn_h)
_txn_logger.propagate = False # don't double-log to console/bot.log _txn_logger.propagate = False # don't double-log to console/bot.log
log = logging.getLogger("tipilan") log = logging.getLogger(f"tipilan.{config.BOT_PROFILE}")
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Bot setup # Bot setup
@@ -594,7 +594,12 @@ class HelpSelect(discord.ui.Select):
@tree.command(name="help", description=S.CMD["help"]) @tree.command(name="help", description=S.CMD["help"])
async def cmd_help(interaction: discord.Interaction): async def cmd_help(interaction: discord.Interaction):
<<<<<<< HEAD
is_admin = is_bot_admin(interaction.user) is_admin = is_bot_admin(interaction.user)
=======
member = interaction.user
is_admin = isinstance(member, discord.Member) and is_bot_admin(member)
>>>>>>> 42f7bae68124fa6a9824780ba17b46d00f3f2b36
await interaction.response.send_message( await interaction.response.send_message(
embed=_help_embed("üldine"), view=HelpView(is_admin), ephemeral=True embed=_help_embed("üldine"), view=HelpView(is_admin), ephemeral=True
) )

View File

@@ -10,6 +10,7 @@ import discord
from discord import app_commands from discord import app_commands
from core import economy from core import economy
from core.emoji import EMOJI as E
import strings as S import strings as S
@@ -288,12 +289,12 @@ def register_economy_extra_commands(
# /jailbreak - Monopoly-style dice escape # /jailbreak - Monopoly-style dice escape
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
_DICE_EMOJI = [ _DICE_EMOJI = [
"<:TipiYKS:1483103190491856916>", E["TipiYKS"],
"<:TipiKAKS:1483103215841972404>", E["TipiKAKS"],
"<:TipiKOLM:1483103217846980781>", E["TipiKOLM"],
"<:TipiNELI:1483103237585240114>", E["TipiNELI"],
"<:TipiVIIS:1483103239036469289>", E["TipiVIIS"],
"<:TipiKUUS:1483103253163020348>", E["TipiKUUS"],
] ]
class JailbreakView(discord.ui.View): class JailbreakView(discord.ui.View):
@@ -813,7 +814,6 @@ def register_economy_extra_commands(
btn = discord.ui.Button( btn = discord.ui.Button(
label=label, label=label,
style=discord.ButtonStyle.primary if t == self._tier else discord.ButtonStyle.secondary, style=discord.ButtonStyle.primary if t == self._tier else discord.ButtonStyle.secondary,
custom_id=f"shop_tier_{t}",
) )
btn.callback = self._make_callback(t) btn.callback = self._make_callback(t)
self.add_item(btn) self.add_item(btn)
@@ -822,8 +822,9 @@ def register_economy_extra_commands(
async def callback(interaction: discord.Interaction): async def callback(interaction: discord.Interaction):
self._tier = tier self._tier = tier
self._update_buttons() self._update_buttons()
await interaction.response.defer()
self._user_data = await economy.get_user(interaction.user.id) self._user_data = await economy.get_user(interaction.user.id)
await interaction.response.edit_message( await interaction.edit_original_response(
embed=_shop_embed(self._tier, self._user_data), embed=_shop_embed(self._tier, self._user_data),
view=self, view=self,
) )

View File

@@ -9,6 +9,7 @@ import discord
from discord import app_commands from discord import app_commands
from core import economy from core import economy
from core.emoji import EMOJI as E
import strings as S import strings as S
@@ -611,7 +612,7 @@ def register_economy_games_commands(
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
# /slots # /slots
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
_SLOTS_SPIN = "<a:TipiSLOTS:1483444233863037101>" _SLOTS_SPIN = E["TipiSLOTS"]
_SLOTS_DELAY = 0.7 _SLOTS_DELAY = 0.7
def _slots_embed( def _slots_embed(

View File

@@ -22,12 +22,13 @@ def register_economy_income_commands(
) -> None: ) -> None:
@tree.command(name="daily", description=S.CMD["daily"]) @tree.command(name="daily", description=S.CMD["daily"])
async def cmd_daily(interaction: discord.Interaction): async def cmd_daily(interaction: discord.Interaction):
await interaction.response.defer()
res = await economy.do_daily(interaction.user.id) res = await economy.do_daily(interaction.user.id)
if not res["ok"]: if not res["ok"]:
if res["reason"] == "banned": if res["reason"] == "banned":
await interaction.response.send_message(S.MSG_BANNED, ephemeral=True) await interaction.followup.send(S.MSG_BANNED, ephemeral=True)
elif res["reason"] == "cooldown": elif res["reason"] == "cooldown":
await interaction.response.send_message( await interaction.followup.send(
S.CD_MSG["daily"].format(ts=cd_ts(res["remaining"])), S.CD_MSG["daily"].format(ts=cd_ts(res["remaining"])),
ephemeral=True, ephemeral=True,
) )
@@ -51,7 +52,7 @@ def register_economy_income_commands(
lines.append(S.DAILY_UI["footer"].format(streak_str=streak_str, balance=coin(res["balance"]))) lines.append(S.DAILY_UI["footer"].format(streak_str=streak_str, balance=coin(res["balance"])))
embed = discord.Embed(title=S.TITLE["daily"], description="\n".join(lines), color=0xF4C430) embed = discord.Embed(title=S.TITLE["daily"], description="\n".join(lines), color=0xF4C430)
await interaction.response.send_message(embed=embed) await interaction.followup.send(embed=embed)
asyncio.create_task(maybe_remind(interaction.user.id, "daily")) asyncio.create_task(maybe_remind(interaction.user.id, "daily"))
asyncio.create_task(award_exp(interaction, economy.EXP_REWARDS["daily"])) asyncio.create_task(award_exp(interaction, economy.EXP_REWARDS["daily"]))
@@ -59,17 +60,18 @@ def register_economy_income_commands(
async def cmd_work(interaction: discord.Interaction): async def cmd_work(interaction: discord.Interaction):
if await check_cmd_rate(interaction): if await check_cmd_rate(interaction):
return return
await interaction.response.defer()
res = await economy.do_work(interaction.user.id) res = await economy.do_work(interaction.user.id)
if not res["ok"]: if not res["ok"]:
if res["reason"] == "banned": if res["reason"] == "banned":
await interaction.response.send_message(S.MSG_BANNED, ephemeral=True) await interaction.followup.send(S.MSG_BANNED, ephemeral=True)
elif res["reason"] == "cooldown": elif res["reason"] == "cooldown":
await interaction.response.send_message( await interaction.followup.send(
S.CD_MSG["work"].format(ts=cd_ts(res["remaining"])), S.CD_MSG["work"].format(ts=cd_ts(res["remaining"])),
ephemeral=True, ephemeral=True,
) )
elif res["reason"] == "jailed": elif res["reason"] == "jailed":
await interaction.response.send_message( await interaction.followup.send(
S.CD_MSG["jailed"].format(ts=cd_ts(res["remaining"])), S.CD_MSG["jailed"].format(ts=cd_ts(res["remaining"])),
ephemeral=True, ephemeral=True,
) )
@@ -84,7 +86,7 @@ def register_economy_income_commands(
desc += S.WORK_UI["laud"] desc += S.WORK_UI["laud"]
desc += S.WORK_UI["balance"].format(balance=coin(res["balance"])) desc += S.WORK_UI["balance"].format(balance=coin(res["balance"]))
embed = discord.Embed(title=S.TITLE["work"], description=desc, color=0x57F287) embed = discord.Embed(title=S.TITLE["work"], description=desc, color=0x57F287)
await interaction.response.send_message(embed=embed) await interaction.followup.send(embed=embed)
asyncio.create_task(maybe_remind(interaction.user.id, "work")) asyncio.create_task(maybe_remind(interaction.user.id, "work"))
asyncio.create_task(award_exp(interaction, economy.EXP_REWARDS["work"])) asyncio.create_task(award_exp(interaction, economy.EXP_REWARDS["work"]))
@@ -92,12 +94,13 @@ def register_economy_income_commands(
async def cmd_beg(interaction: discord.Interaction): async def cmd_beg(interaction: discord.Interaction):
if await check_cmd_rate(interaction): if await check_cmd_rate(interaction):
return return
await interaction.response.defer()
res = await economy.do_beg(interaction.user.id) res = await economy.do_beg(interaction.user.id)
if not res["ok"]: if not res["ok"]:
if res["reason"] == "banned": if res["reason"] == "banned":
await interaction.response.send_message(S.MSG_BANNED, ephemeral=True) await interaction.followup.send(S.MSG_BANNED, ephemeral=True)
elif res["reason"] == "cooldown": elif res["reason"] == "cooldown":
await interaction.response.send_message( await interaction.followup.send(
S.CD_MSG["beg"].format(ts=cd_ts(res["remaining"])), S.CD_MSG["beg"].format(ts=cd_ts(res["remaining"])),
ephemeral=True, ephemeral=True,
) )
@@ -114,7 +117,7 @@ def register_economy_income_commands(
beg_lines.append(S.BEG_UI["klaviatuur"]) beg_lines.append(S.BEG_UI["klaviatuur"])
beg_lines.append(S.BEG_UI["balance"].format(balance=coin(res["balance"]))) beg_lines.append(S.BEG_UI["balance"].format(balance=coin(res["balance"])))
embed = discord.Embed(title=title, description="\n".join(beg_lines), color=color) embed = discord.Embed(title=title, description="\n".join(beg_lines), color=color)
await interaction.response.send_message(embed=embed) await interaction.followup.send(embed=embed)
asyncio.create_task(maybe_remind(interaction.user.id, "beg")) asyncio.create_task(maybe_remind(interaction.user.id, "beg"))
asyncio.create_task(award_exp(interaction, economy.EXP_REWARDS["beg"])) asyncio.create_task(award_exp(interaction, economy.EXP_REWARDS["beg"]))
@@ -122,17 +125,18 @@ def register_economy_income_commands(
async def cmd_crime(interaction: discord.Interaction): async def cmd_crime(interaction: discord.Interaction):
if await check_cmd_rate(interaction): if await check_cmd_rate(interaction):
return return
await interaction.response.defer()
res = await economy.do_crime(interaction.user.id) res = await economy.do_crime(interaction.user.id)
if not res["ok"]: if not res["ok"]:
if res["reason"] == "banned": if res["reason"] == "banned":
await interaction.response.send_message(S.MSG_BANNED, ephemeral=True) await interaction.followup.send(S.MSG_BANNED, ephemeral=True)
elif res["reason"] == "cooldown": elif res["reason"] == "cooldown":
await interaction.response.send_message( await interaction.followup.send(
S.CD_MSG["crime"].format(ts=cd_ts(res["remaining"])), S.CD_MSG["crime"].format(ts=cd_ts(res["remaining"])),
ephemeral=True, ephemeral=True,
) )
elif res["reason"] == "jailed": elif res["reason"] == "jailed":
await interaction.response.send_message( await interaction.followup.send(
S.CD_MSG["jailed"].format(ts=cd_ts(res["remaining"])), S.CD_MSG["jailed"].format(ts=cd_ts(res["remaining"])),
ephemeral=True, ephemeral=True,
) )
@@ -161,7 +165,7 @@ def register_economy_income_commands(
+ S.CRIME_UI["balance"].format(balance=coin(res["balance"])), + S.CRIME_UI["balance"].format(balance=coin(res["balance"])),
color=0xED4245, color=0xED4245,
) )
await interaction.response.send_message(embed=embed) await interaction.followup.send(embed=embed)
asyncio.create_task(maybe_remind(interaction.user.id, "crime")) asyncio.create_task(maybe_remind(interaction.user.id, "crime"))
if res["success"]: if res["success"]:
asyncio.create_task(award_exp(interaction, economy.EXP_REWARDS["crime_win"])) asyncio.create_task(award_exp(interaction, economy.EXP_REWARDS["crime_win"]))
@@ -180,27 +184,28 @@ def register_economy_income_commands(
await interaction.response.send_message(S.ERR["rob_house_blocked"], ephemeral=True) await interaction.response.send_message(S.ERR["rob_house_blocked"], ephemeral=True)
return return
await interaction.response.defer()
res = await economy.do_rob(interaction.user.id, sihtmärk.id) res = await economy.do_rob(interaction.user.id, sihtmärk.id)
if not res["ok"]: if not res["ok"]:
if res["reason"] == "banned": if res["reason"] == "banned":
await interaction.response.send_message(S.MSG_BANNED, ephemeral=True) await interaction.followup.send(S.MSG_BANNED, ephemeral=True)
elif res["reason"] == "cooldown": elif res["reason"] == "cooldown":
await interaction.response.send_message( await interaction.followup.send(
S.CD_MSG["rob"].format(ts=cd_ts(res["remaining"])), S.CD_MSG["rob"].format(ts=cd_ts(res["remaining"])),
ephemeral=True, ephemeral=True,
) )
elif res["reason"] == "jailed": elif res["reason"] == "jailed":
await interaction.response.send_message( await interaction.followup.send(
S.CD_MSG["jailed"].format(ts=cd_ts(res["remaining"])), S.CD_MSG["jailed"].format(ts=cd_ts(res["remaining"])),
ephemeral=True, ephemeral=True,
) )
elif res["reason"] == "broke": elif res["reason"] == "broke":
await interaction.response.send_message( await interaction.followup.send(
S.ERR["rob_too_poor"].format(name=sihtmärk.display_name), S.ERR["rob_too_poor"].format(name=sihtmärk.display_name),
ephemeral=True, ephemeral=True,
) )
elif res["reason"] == "target_jailed": elif res["reason"] == "target_jailed":
await interaction.response.send_message( await interaction.followup.send(
S.ERR["rob_target_jailed"].format(name=sihtmärk.display_name), S.ERR["rob_target_jailed"].format(name=sihtmärk.display_name),
ephemeral=True, ephemeral=True,
) )
@@ -242,7 +247,7 @@ def register_economy_income_commands(
), ),
color=0xED4245, color=0xED4245,
) )
await interaction.response.send_message(embed=embed) await interaction.followup.send(embed=embed)
asyncio.create_task(maybe_remind(interaction.user.id, "rob")) asyncio.create_task(maybe_remind(interaction.user.id, "rob"))
if res["success"]: if res["success"]:
asyncio.create_task(award_exp(interaction, economy.EXP_REWARDS["rob_win"])) asyncio.create_task(award_exp(interaction, economy.EXP_REWARDS["rob_win"]))

View File

@@ -15,6 +15,7 @@ from discord import app_commands
from core.admin import bot_admin_check from core.admin import bot_admin_check
import strings as S import strings as S
from core.admin import bot_admin_check
def register_ops_admin_commands( def register_ops_admin_commands(

View File

@@ -75,3 +75,26 @@ PB_ECONOMY_COLLECTION_ECONOMY = (
PB_ECONOMY_COLLECTION = ( PB_ECONOMY_COLLECTION = (
PB_ECONOMY_COLLECTION_ECONOMY if BOT_PROFILE == "economy" else PB_ECONOMY_COLLECTION_DEV PB_ECONOMY_COLLECTION_ECONOMY if BOT_PROFILE == "economy" else PB_ECONOMY_COLLECTION_DEV
) )
def _parse_admin_roles() -> dict[int, int]:
"""Parse BOT_ADMIN_ROLES env var (format: guild_id:role_id,guild_id:role_id)."""
raw = os.getenv("BOT_ADMIN_ROLES", "").strip()
if not raw:
return {}
result: dict[int, int] = {}
for pair in raw.split(","):
pair = pair.strip()
if not pair:
continue
parts = pair.split(":")
if len(parts) != 2:
continue
try:
result[int(parts[0].strip())] = int(parts[1].strip())
except ValueError:
continue
return result
BOT_ADMIN_ROLES: dict[int, int] = _parse_admin_roles()

View File

@@ -6,10 +6,15 @@ from discord import app_commands
import config import config
<<<<<<< HEAD
def is_bot_admin(member: discord.abc.User | None) -> bool: def is_bot_admin(member: discord.abc.User | None) -> bool:
"""True when the member has the configured admin role for their guild.""" """True when the member has the configured admin role for their guild."""
if not isinstance(member, discord.Member) or member.guild is None: if not isinstance(member, discord.Member) or member.guild is None:
return False return False
=======
def is_bot_admin(member: discord.Member) -> bool:
"""Return True if the member has the configured bot-admin role for their guild."""
>>>>>>> 42f7bae68124fa6a9824780ba17b46d00f3f2b36
role_id = config.BOT_ADMIN_ROLES.get(member.guild.id) role_id = config.BOT_ADMIN_ROLES.get(member.guild.id)
if role_id is None: if role_id is None:
return False return False
@@ -17,11 +22,22 @@ def is_bot_admin(member: discord.abc.User | None) -> bool:
def bot_admin_check(): def bot_admin_check():
<<<<<<< HEAD
"""Slash-command decorator that gates execution behind ``is_bot_admin``.""" """Slash-command decorator that gates execution behind ``is_bot_admin``."""
async def predicate(interaction: discord.Interaction) -> bool: async def predicate(interaction: discord.Interaction) -> bool:
if is_bot_admin(interaction.user): if is_bot_admin(interaction.user):
return True return True
raise app_commands.MissingPermissions(["bot_admin_role"]) raise app_commands.MissingPermissions(["bot_admin_role"])
=======
"""Slash-command check decorator: raises MissingPermissions if not a bot admin."""
def predicate(interaction: discord.Interaction) -> bool:
member = interaction.user
if not isinstance(member, discord.Member):
raise app_commands.MissingPermissions(["bot_admin"])
if not is_bot_admin(member):
raise app_commands.MissingPermissions(["bot_admin"])
return True
>>>>>>> 42f7bae68124fa6a9824780ba17b46d00f3f2b36
return app_commands.check(predicate) return app_commands.check(predicate)

View File

@@ -17,6 +17,7 @@ import aiohttp
from . import pb_client from . import pb_client
from .pb_client import DatabaseError from .pb_client import DatabaseError
from .emoji import EMOJI as E
import strings import strings
@@ -29,13 +30,9 @@ def _txn(event: str, **fields) -> None:
_txn_log.info("%-16s %s", event, body) _txn_log.info("%-16s %s", event, body)
# --------------------------------------------------------------------------- # Per-profile emoji values live in core/emoji.py; add new IDs there.
# Emoji config COIN = E["TipiCOIN"]
# To use your custom Discord emoji replace COIN with the full tag, e.g.: PP_EMOJI = E["TipiFIRE"]
# COIN = "<:tipicoin:1234567890123456789>"
# ---------------------------------------------------------------------------
COIN = "<:TipiCOIN:1483000209188589628>"
PP_EMOJI = "<:TipiFIRE:1483431381668335687>"
PRESTIGE_ROLE = "TipiPRESTIGE" PRESTIGE_ROLE = "TipiPRESTIGE"
PRESTIGE_MIN_LEVEL = 30 # minimum level required to prestige PRESTIGE_MIN_LEVEL = 30 # minimum level required to prestige
@@ -52,99 +49,99 @@ class ShopItem(TypedDict):
SHOP: dict[str, ShopItem] = { SHOP: dict[str, ShopItem] = {
"gaming_hiir": { "gaming_hiir": {
"name": "Mängurihiir", "name": "Mängurihiir",
"emoji": "<:TipiHIIR:1483004306012504128>", "emoji": E["TipiHIIR"],
"cost": 500, "cost": 500,
"description": strings.ITEM_DESCRIPTIONS["gaming_hiir"], "description": strings.ITEM_DESCRIPTIONS["gaming_hiir"],
}, },
"hiirematt": { "hiirematt": {
"name": "Hiirematt", "name": "Hiirematt",
"emoji": "<:TipiMATT:1483387697132208128>", "emoji": E["TipiMATT"],
"cost": 600, "cost": 600,
"description": strings.ITEM_DESCRIPTIONS["hiirematt"], "description": strings.ITEM_DESCRIPTIONS["hiirematt"],
}, },
"korvaklapid": { "korvaklapid": {
"name": "K\u00f5rvaklapid", "name": "K\u00f5rvaklapid",
"emoji": "<:TipiKLAPID:1483387694083084349>", "emoji": E["TipiKLAPID"],
"cost": 1200, "cost": 1200,
"description": strings.ITEM_DESCRIPTIONS["korvaklapid"], "description": strings.ITEM_DESCRIPTIONS["korvaklapid"],
}, },
"lan_pass": { "lan_pass": {
"name": "LAN pilet", "name": "LAN pilet",
"emoji": "<:TipiPILET:1483004308353060904>", "emoji": E["TipiPILET"],
"cost": 1200, "cost": 1200,
"description": strings.ITEM_DESCRIPTIONS["lan_pass"], "description": strings.ITEM_DESCRIPTIONS["lan_pass"],
}, },
"energiajook": { "energiajook": {
"name": "Red Bull", "name": "Red Bull",
"emoji": "<:TipiBULL:1483004310924300409>", "emoji": E["TipiBULL"],
"cost": 800, "cost": 800,
"description": strings.ITEM_DESCRIPTIONS["energiajook"], "description": strings.ITEM_DESCRIPTIONS["energiajook"],
}, },
"gaming_laptop": { "gaming_laptop": {
"name": "Bot Farm", "name": "Bot Farm",
"emoji": "<:TipiLAP:1483004307161874566>", "emoji": E["TipiLAP"],
"cost": 1500, "cost": 1500,
"description": strings.ITEM_DESCRIPTIONS["gaming_laptop"], "description": strings.ITEM_DESCRIPTIONS["gaming_laptop"],
}, },
"anticheat": { "anticheat": {
"name": "Anticheat", "name": "Anticheat",
"emoji": "<:TipiVAC:1483004309510819860>", "emoji": E["TipiVAC"],
"cost": 1000, "cost": 1000,
"description": strings.ITEM_DESCRIPTIONS["anticheat"], "description": strings.ITEM_DESCRIPTIONS["anticheat"],
}, },
# ----- Tier 2 ----- # ----- Tier 2 -----
"reguleeritav_laud": { "reguleeritav_laud": {
"name": "Reguleeritav laud", "name": "Reguleeritav laud",
"emoji": "<:TipiLAUD:1483387695576125440>", "emoji": E["TipiLAUD"],
"cost": 3500, "cost": 3500,
"description": strings.ITEM_DESCRIPTIONS["reguleeritav_laud"], "description": strings.ITEM_DESCRIPTIONS["reguleeritav_laud"],
}, },
"jellyfin": { "jellyfin": {
"name": "Jellyfin server", "name": "Jellyfin server",
"emoji": "<:TipiSERVER:1483387701032910969>", "emoji": E["TipiSERVER"],
"cost": 4000, "cost": 4000,
"description": strings.ITEM_DESCRIPTIONS["jellyfin"], "description": strings.ITEM_DESCRIPTIONS["jellyfin"],
}, },
"mikrofon": { "mikrofon": {
"name": "Eraldiseisev mikrofon", "name": "Eraldiseisev mikrofon",
"emoji": "<:TipiMIC:1483387698499551313>", "emoji": E["TipiMIC"],
"cost": 2800, "cost": 2800,
"description": strings.ITEM_DESCRIPTIONS["mikrofon"], "description": strings.ITEM_DESCRIPTIONS["mikrofon"],
}, },
"klaviatuur": { "klaviatuur": {
"name": "Mehaaniline klaviatuur", "name": "Mehaaniline klaviatuur",
"emoji": "<:TipiKLAVA:1483014339228078140>", "emoji": E["TipiKLAVA"],
"cost": 1800, "cost": 1800,
"description": strings.ITEM_DESCRIPTIONS["klaviatuur"], "description": strings.ITEM_DESCRIPTIONS["klaviatuur"],
}, },
"monitor": { "monitor": {
"name": "Ultralai monitor", "name": "Ultralai monitor",
"emoji": "<:TipiMONITOR:1483014340327243908>", "emoji": E["TipiMONITOR"],
"cost": 2500, "cost": 2500,
"description": strings.ITEM_DESCRIPTIONS["monitor"], "description": strings.ITEM_DESCRIPTIONS["monitor"],
}, },
"cat6": { "cat6": {
"name": "Cat6 kaabel", "name": "Cat6 kaabel",
"emoji": "<:TipiCAT:1483014337663602718>", "emoji": E["TipiCAT"],
"cost": 3500, "cost": 3500,
"description": strings.ITEM_DESCRIPTIONS["cat6"], "description": strings.ITEM_DESCRIPTIONS["cat6"],
}, },
# ----- Tier 3 ----- # ----- Tier 3 -----
"monitor_360": { "monitor_360": {
"name": "360Hz monitor", "name": "360Hz monitor",
"emoji": "<:TipiMONITOR2:1483387699514839162>", "emoji": E["TipiMONITOR2"],
"cost": 7500, "cost": 7500,
"description": strings.ITEM_DESCRIPTIONS["monitor_360"], "description": strings.ITEM_DESCRIPTIONS["monitor_360"],
}, },
"karikas": { "karikas": {
"name": "TipiLAN karikas", "name": "TipiLAN karikas",
"emoji": "<:TipiKARIKAS:1483014841148112977>", "emoji": E["TipiKARIKAS"],
"cost": 6000, "cost": 6000,
"description": strings.ITEM_DESCRIPTIONS["karikas"], "description": strings.ITEM_DESCRIPTIONS["karikas"],
}, },
"gaming_tool": { "gaming_tool": {
"name": "Gaming tool", "name": "Gaming tool",
"emoji": "<:TipiTOOL:1483014341648187613>", "emoji": E["TipiTOOL"],
"cost": 9000, "cost": 9000,
"description": strings.ITEM_DESCRIPTIONS["gaming_tool"], "description": strings.ITEM_DESCRIPTIONS["gaming_tool"],
}, },
@@ -204,7 +201,7 @@ class PrestigeItem(TypedDict):
PRESTIGE_SHOP: dict[str, PrestigeItem] = { PRESTIGE_SHOP: dict[str, PrestigeItem] = {
"coin_mult": { "coin_mult": {
"emoji": "<:TipiCOIN:1483000209188589628>", "emoji": E["TipiCOIN"],
"max_level": 5, "max_level": 5,
"pp_cost": 5, "pp_cost": 5,
"effect": 0.08, "effect": 0.08,
@@ -1482,21 +1479,21 @@ async def do_rps_pvp_refund(user_id: int, bet: int) -> dict:
# /slots # /slots
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
_SLOTS_SYMBOLS: list[tuple[str, int]] = [ _SLOTS_SYMBOLS: list[tuple[str, int]] = [
("<:TipiHEART:1483431377561976853>", 27), (E["TipiHEART"], 27),
("<:TipiFIRE:1483431381668335687>", 22), (E["TipiFIRE"], 22),
("<:TipiTROLL:1483431380166774895>", 18), (E["TipiTROLL"], 18),
("<:TipICRY:1483431288852709387>", 15), (E["TipICRY"], 15),
("<:TipiSKULL:1483431378929451028>", 10), (E["TipiSKULL"], 10),
("<:TipiKARIKAS:1483014841148112977>", 8), (E["TipiKARIKAS"], 8),
] ]
_SLOTS_JACKPOT = "<:TipiKARIKAS:1483014841148112977>" _SLOTS_JACKPOT = E["TipiKARIKAS"]
_SLOTS_TRIPLE_MULT: dict[str, int] = { _SLOTS_TRIPLE_MULT: dict[str, int] = {
"<:TipiHEART:1483431377561976853>": 4, E["TipiHEART"]: 4,
"<:TipiFIRE:1483431381668335687>": 5, E["TipiFIRE"]: 5,
"<:TipiTROLL:1483431380166774895>": 7, E["TipiTROLL"]: 7,
"<:TipICRY:1483431288852709387>": 10, E["TipICRY"]: 10,
"<:TipiSKULL:1483431378929451028>": 15, E["TipiSKULL"]: 15,
"<:TipiKARIKAS:1483014841148112977>": 25, # jackpot E["TipiKARIKAS"]: 25, # jackpot
} }

66
core/emoji.py Normal file
View File

@@ -0,0 +1,66 @@
"""Custom Discord emoji registry, keyed by symbolic name and resolved per BOT_PROFILE.
Emojis are uploaded as application emojis via the Discord Developer Portal
and are scoped to a single bot application. Dev and production are separate
applications, so the same logical emoji has a different ID in each — hence
two dicts below, selected by BOT_PROFILE.
To add a new emoji: upload it to both applications in the dev portal, grab
the two IDs, and add one line to each dict.
"""
from __future__ import annotations
from config import BOT_PROFILE
_DEV: dict[str, str] = {
"TipiCOIN": "<:TipiCOIN:1483000209188589628>",
"TipiFIRE": "<:TipiFIRE:1483431381668335687>",
"TipiHIIR": "<:TipiHIIR:1483004306012504128>",
"TipiMATT": "<:TipiMATT:1483387697132208128>",
"TipiKLAPID": "<:TipiKLAPID:1483387694083084349>",
"TipiPILET": "<:TipiPILET:1483004308353060904>",
"TipiBULL": "<:TipiBULL:1483004310924300409>",
"TipiLAP": "<:TipiLAP:1483004307161874566>",
"TipiVAC": "<:TipiVAC:1483004309510819860>",
"TipiLAUD": "<:TipiLAUD:1483387695576125440>",
"TipiSERVER": "<:TipiSERVER:1483387701032910969>",
"TipiMIC": "<:TipiMIC:1483387698499551313>",
"TipiKLAVA": "<:TipiKLAVA:1483014339228078140>",
"TipiMONITOR": "<:TipiMONITOR:1483014340327243908>",
"TipiCAT": "<:TipiCAT:1483014337663602718>",
"TipiMONITOR2": "<:TipiMONITOR2:1483387699514839162>",
"TipiKARIKAS": "<:TipiKARIKAS:1483014841148112977>",
"TipiTOOL": "<:TipiTOOL:1483014341648187613>",
"TipiHEART": "<:TipiHEART:1483431377561976853>",
"TipiTROLL": "<:TipiTROLL:1483431380166774895>",
"TipICRY": "<:TipICRY:1483431288852709387>",
"TipiSKULL": "<:TipiSKULL:1483431378929451028>",
"TipiDICE": "<:TipiDICE:1485923107108556950>",
"TipiYKS": "<:TipiYKS:1483103190491856916>",
"TipiKAKS": "<:TipiKAKS:1483103215841972404>",
"TipiKOLM": "<:TipiKOLM:1483103217846980781>",
"TipiNELI": "<:TipiNELI:1483103237585240114>",
"TipiVIIS": "<:TipiVIIS:1483103239036469289>",
"TipiKUUS": "<:TipiKUUS:1483103253163020348>",
"TipiSLOTS": "<a:TipiSLOTS:1483444233863037101>",
}
# Production application emoji IDs. Replace each ID with the one from the
# prod application in the dev portal. The dev IDs below are placeholders so
# this dict is structurally complete — they will NOT render in prod because
# they belong to a different application.
_ECONOMY: dict[str, str] = dict(_DEV)
_EMOJI_SETS = {
"dev": _DEV,
"economy": _ECONOMY,
}
EMOJI: dict[str, str] = _EMOJI_SETS[BOT_PROFILE]
_missing = set(_DEV) - set(EMOJI)
if _missing:
raise RuntimeError(f"Emoji set {BOT_PROFILE!r} missing keys: {sorted(_missing)}")

View File

@@ -4,6 +4,8 @@ Edit this file to change any message, description, or flavour text
without touching any logic code. without touching any logic code.
""" """
from core.emoji import EMOJI as E
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Flavour text # Flavour text
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@@ -256,22 +258,22 @@ HELP_CATEGORIES: dict[str, dict] = {
"description": "TipiBOTi poe esemed ja nende efektid", "description": "TipiBOTi poe esemed ja nende efektid",
"color": 0xF4C430, "color": 0xF4C430,
"fields": [ "fields": [
("<:TipiHIIR:1483004306012504128> Mängurihiir - 500 ⬡", "Teeni töötades 50% rohkem TipiCOINe."), (f"{E['TipiHIIR']} Mängurihiir - 500 ⬡", "Teeni töötades 50% rohkem TipiCOINe."),
("<:TipiMATT:1483387697132208128> XL hiirematt - 600 ⬡", "Kerjamise ooteaeg 5min → 3min."), (f"{E['TipiMATT']} XL hiirematt - 600 ⬡", "Kerjamise ooteaeg 5min → 3min."),
("<:TipiKLAPID:1483387694083084349> Kõrvaklapid - 1200 ⬡", "Päevase boonuse ooteaeg 20h → 18h."), (f"{E['TipiKLAPID']} Kõrvaklapid - 1200 ⬡", "Päevase boonuse ooteaeg 20h → 18h."),
("<:TipiPILET:1483004308353060904> LAN pilet (2025) - 1200 ⬡", "Päevane boonus on duubeldatud."), (f"{E['TipiPILET']} LAN pilet (2025) - 1200 ⬡", "Päevane boonus on duubeldatud."),
("<:TipiVAC:1483004309510819860> Anticheat - 750 ⬡", "Röövimine sinu vastu ebaõnnestub. Pärast 2 kasutust pead ostma uue."), (f"{E['TipiVAC']} Anticheat - 750 ⬡", "Röövimine sinu vastu ebaõnnestub. Pärast 2 kasutust pead ostma uue."),
("<:TipiBULL:1483004310924300409> Red Bull - 800 ⬡", "30% tõenäosus, et teenid töötades 3x rohkem."), (f"{E['TipiBULL']} Red Bull - 800 ⬡", "30% tõenäosus, et teenid töötades 3x rohkem."),
("<:TipiLAP:1483004307161874566> Botikoobas - 1500 ⬡", "RTX 5090 jooksutab botte 24/7. Päevane boonus genereerib 5% intressi sinu saldo pealt."), (f"{E['TipiLAP']} Botikoobas - 1500 ⬡", "RTX 5090 jooksutab botte 24/7. Päevane boonus genereerib 5% intressi sinu saldo pealt."),
("<:TipiLAUD:1483387695576125440> Reguleeritav laud - 3500 ⬡ *(T2)*", "/work teenib 25% rohkem (stackib mängurihiirega)."), (f"{E['TipiLAUD']} Reguleeritav laud - 3500 ⬡ *(T2)*", "/work teenib 25% rohkem (stackib mängurihiirega)."),
("<:TipiSERVER:1483387701032910969> Jellyfin server - 4000 ⬡ *(T2)*", "Röövimise edu tõenäosus 45% → 60%."), (f"{E['TipiSERVER']} Jellyfin server - 4000 ⬡ *(T2)*", "Röövimise edu tõenäosus 45% → 60%."),
("<:TipiMIC:1483387698499551313> Mikrofon - 2800 ⬡ *(T2)*", "Teeni 30% rohkem eduka /crime puhul."), (f"{E['TipiMIC']} Mikrofon - 2800 ⬡ *(T2)*", "Teeni 30% rohkem eduka /crime puhul."),
("<:TipiKLAVA:1483014339228078140> Mehhaaniline klaviatuur - 1800 ⬡ *(T2)*", "/beg teenib 2x rohkem."), (f"{E['TipiKLAVA']} Mehhaaniline klaviatuur - 1800 ⬡ *(T2)*", "/beg teenib 2x rohkem."),
("<:TipiMONITOR:1483014340327243908> Ultralai monitor - 2500 ⬡ *(T2)*", "/work ooteaeg: 1h → 40min."), (f"{E['TipiMONITOR']} Ultralai monitor - 2500 ⬡ *(T2)*", "/work ooteaeg: 1h → 40min."),
("<:TipiCAT:1483014337663602718> CAT6 netikaabel - 3500 ⬡ *(T2)*", "/crime edu tõenäosus tõuseb 60% → 75%."), (f"{E['TipiCAT']} CAT6 netikaabel - 3500 ⬡ *(T2)*", "/crime edu tõenäosus tõuseb 60% → 75%."),
("<:TipiMONITOR2:1483387699514839162> 360hz monitor - 7500 ⬡ *(T3)*", "Mänguautomaadi jackpot 10x → 15x, kolmik 4x → 6x."), (f"{E['TipiMONITOR2']} 360hz monitor - 7500 ⬡ *(T3)*", "Mänguautomaadi jackpot 10x → 15x, kolmik 4x → 6x."),
("<:TipiKARIKAS:1483014841148112977> TipiLANi trofee - 6000 ⬡ *(T3)*", "Streak ei nulli, kui sa mõne päeva vahele jätad."), (f"{E['TipiKARIKAS']} TipiLANi trofee - 6000 ⬡ *(T3)*", "Streak ei nulli, kui sa mõne päeva vahele jätad."),
("<:TipiTOOL:1483014341648187613> Mänguritool - 9000 ⬡ *(T3)*", "/crime ebaõnnestumine ei saada sind vanglasse."), (f"{E['TipiTOOL']} Mänguritool - 9000 ⬡ *(T3)*", "/crime ebaõnnestumine ei saada sind vanglasse."),
], ],
}, },
"games": { "games": {
@@ -347,10 +349,10 @@ REMINDER_OPTS: list[tuple[str, str, str]] = [
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
SLOTS_TIERS: dict[str, tuple[str, int]] = { SLOTS_TIERS: dict[str, tuple[str, int]] = {
"jackpot": ("<:TipiFIRE:1483431381668335687> JACKPOT!!!", 0xF4C430), "jackpot": (f"{E['TipiFIRE']} JACKPOT!!!", 0xF4C430),
"triple": ("🎰 Kolmik!", 0x57F287), "triple": ("🎰 Kolmik!", 0x57F287),
"pair": ("🎰 Paar", 0x99AAB5), "pair": ("🎰 Paar", 0x99AAB5),
"miss": ("<:TipICRY:1483431288852709387> Ei õnnestunud", 0xED4245), "miss": (f"{E['TipICRY']} Ei õnnestunud", 0xED4245),
} }
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@@ -534,22 +536,22 @@ TITLE: dict[str, str] = {
"daily": "📅 Päevane boonus", "daily": "📅 Päevane boonus",
"work": "💼 Töö", "work": "💼 Töö",
"beg": "🙏 Kerjamine", "beg": "🙏 Kerjamine",
"crime_win": "<:TipiFIRE:1483431381668335687> Kuritegu õnnestus!", "crime_win": f"{E['TipiFIRE']} Kuritegu õnnestus!",
"crime_fail": "<:TipiTROLL:1483431380166774895> Vahele jäid!", "crime_fail": f"{E['TipiTROLL']} Vahele jäid!",
"rob_win": "<:TipiFIRE:1483431381668335687> Rööv õnnestus!", "rob_win": f"{E['TipiFIRE']} Rööv õnnestus!",
"rob_fail": "<:TipiTROLL:1483431380166774895> Rööv ebaõnnestus!", "rob_fail": f"{E['TipiTROLL']} Rööv ebaõnnestus!",
"rob_anticheat": "<:TipiVAC:1483004309510819860> Anticheat peatas sind!", "rob_anticheat": f"{E['TipiVAC']} Anticheat peatas sind!",
"jailbreak": "🎲 Vanglast põgenemine", "jailbreak": "🎲 Vanglast põgenemine",
"jailbreak_free": "🎲 <:TipiFIRE:1483431381668335687> DUUBEL! Oled vaba!", "jailbreak_free": f"🎲 {E['TipiFIRE']} DUUBEL! Oled vaba!",
"jailbreak_fail": "<:TipICRY:1483431288852709387> Kolm katset läbi!", "jailbreak_fail": f"{E['TipICRY']} Kolm katset läbi!",
"jailbreak_miss": "🎲 <:TipICRY:1483431288852709387> Ei saanud duublit ({tries}/{max})", "jailbreak_miss": "🎲 " + E["TipICRY"] + " Ei saanud duublit ({tries}/{max})",
"jailbreak_bail": "💸 Kautsjon", "jailbreak_bail": "💸 Kautsjon",
"give": "<:TipiHEART:1483431377561976853> TipiCOINi ülekanne", "give": f"{E['TipiHEART']} TipiCOINi ülekanne",
"stats": "📊 Mängustatistika", "stats": "📊 Mängustatistika",
"leaderboard_coins": "🪙 TipiBOTi edetabel - Mündid", "leaderboard_coins": "🪙 TipiBOTi edetabel - Mündid",
"leaderboard_exp": "📊 TipiBOTi edetabel - EXP / Tase", "leaderboard_exp": "📊 TipiBOTi edetabel - EXP / Tase",
"leaderboard_season": "🏆 TipiBOTi edetabel - Hooaja EXP", "leaderboard_season": "🏆 TipiBOTi edetabel - Hooaja EXP",
"leaderboard_prestige": "<:TipiFIRE:1483431381668335687> TipiBOTi edetabel - Prestiiž", "leaderboard_prestige": f"{E['TipiFIRE']} TipiBOTi edetabel - Prestiiž",
"leaderboard_wagered": "🎲 TipiBOTi edetabel - Hasartmängud", "leaderboard_wagered": "🎲 TipiBOTi edetabel - Hasartmängud",
"leaderboard_fish": "🎣 TipiBOTi edetabel - Kalapüük", "leaderboard_fish": "🎣 TipiBOTi edetabel - Kalapüük",
"rps": "⚔️ Kivi, Paber, Käärid", "rps": "⚔️ Kivi, Paber, Käärid",
@@ -560,26 +562,26 @@ TITLE: dict[str, str] = {
"rps_duel_expire": "⚔️ KPK duell - aegus", "rps_duel_expire": "⚔️ KPK duell - aegus",
"rps_duel_decline": "⚔️ KPK duell - keelduti", "rps_duel_decline": "⚔️ KPK duell - keelduti",
"heist_lobby": "🔫 Grupirööv - kogunemine", "heist_lobby": "🔫 Grupirööv - kogunemine",
"heist_win": "<:TipiFIRE:1483431381668335687> Grupirööv õnnestus!", "heist_win": f"{E['TipiFIRE']} Grupirööv õnnestus!",
"heist_fail": "<:TipiSKULL:1483431378929451028> Grupirööv ebaõnnestus!", "heist_fail": f"{E['TipiSKULL']} Grupirööv ebaõnnestus!",
"heist_cancel": "🔫 Grupirööv tühistatud", "heist_cancel": "🔫 Grupirööv tühistatud",
"request": "<:TipiHEART:1483431377561976853> Rahataotlus", "request": f"{E['TipiHEART']} Rahataotlus",
"reminders": "⏰ Meeldetuletused", "reminders": "⏰ Meeldetuletused",
"cooldowns": "⏱️ Sinu ooteajad", "cooldowns": "⏱️ Sinu ooteajad",
"adminseason": "🏆 Hooaeg lõppes!", "adminseason": "🏆 Hooaeg lõppes!",
"economysetup": "⚙️ Majanduse seadistamine", "economysetup": "⚙️ Majanduse seadistamine",
"blackjack": "🃏 Blackjack", "blackjack": "🃏 Blackjack",
"blackjack_bj": "🃏 <:TipiFIRE:1483431381668335687> BLACKJACK!", "blackjack_bj": f"🃏 {E['TipiFIRE']} BLACKJACK!",
"blackjack_win": "<:TipiFIRE:1483431381668335687> Võitsid!", "blackjack_win": f"{E['TipiFIRE']} Võitsid!",
"blackjack_lose": "<:TipiSKULL:1483431378929451028> Kaotasid!", "blackjack_lose": f"{E['TipiSKULL']} Kaotasid!",
"blackjack_bust": "<:TipiSKULL:1483431378929451028> Üle 21 - kaotasid!", "blackjack_bust": f"{E['TipiSKULL']} Üle 21 - kaotasid!",
"blackjack_push": "🤝 Viik!", "blackjack_push": "🤝 Viik!",
"blackjack_dbust": "<:TipiSKULL:1483431378929451028> Üle 21 - mõlemad kaotasid!", "blackjack_dbust": f"{E['TipiSKULL']} Üle 21 - mõlemad kaotasid!",
"blackjack_dwin": "<:TipiFIRE:1483431381668335687> Topeltpanus võitis!", "blackjack_dwin": f"{E['TipiFIRE']} Topeltpanus võitis!",
"prestige_confirm": "🔥 Prestiiž - kinnita", "prestige_confirm": "🔥 Prestiiž - kinnita",
"prestige_success": "<:TipiFIRE:1483431381668335687> Prestiiž {level} saavutatud!", "prestige_success": E["TipiFIRE"] + " Prestiiž {level} saavutatud!",
"prestige_too_low": "❌ Prestiiž pole saadaval", "prestige_too_low": "❌ Prestiiž pole saadaval",
"prestige_shop": "<:TipiFIRE:1483431381668335687> Prestiižipood", "prestige_shop": f"{E['TipiFIRE']} Prestiižipood",
"prestige_buy_ok": "✅ Uuendus ostetud!", "prestige_buy_ok": "✅ Uuendus ostetud!",
"fish_cast": "🎣 Otsid kala...", "fish_cast": "🎣 Otsid kala...",
"fish_bite": "🐟 KALA NÄKKAB!", "fish_bite": "🐟 KALA NÄKKAB!",
@@ -609,8 +611,8 @@ ERR: dict[str, str] = {
"heist_active": "❌ Serveris on juba aktiivne grupirööv käimas! Oota, kuni see lõpeb.", "heist_active": "❌ Serveris on juba aktiivne grupirööv käimas! Oota, kuni see lõpeb.",
"heist_full": "❌ Grupirööv on täis!", "heist_full": "❌ Grupirööv on täis!",
"heist_min_players": "❌ Grupiröövi alustamiseks on vaja vähemalt **{min}** osalejat.", "heist_min_players": "❌ Grupiröövi alustamiseks on vaja vähemalt **{min}** osalejat.",
"broke": "<:TipICRY:1483431288852709387> Sul pole piisavalt TipiCOINe. Saldo: {bal}", "broke": E["TipICRY"] + " Sul pole piisavalt TipiCOINe. Saldo: {bal}",
"broke_need": "<:TipICRY:1483431288852709387> Sul pole piisavalt TipiCOINe. Vajad veel {need}.", "broke_need": E["TipICRY"] + " Sul pole piisavalt TipiCOINe. Vajad veel {need}.",
"item_owned": "❌ Sul on see ese juba olemas.", "item_owned": "❌ Sul on see ese juba olemas.",
"item_not_found": "❌ Eset ei leitud.", "item_not_found": "❌ Eset ei leitud.",
"item_level_req": "🔒 Selle eseme ostmiseks vajad **taset {min_level}** (sul on tase {user_level}). Teeni EXP-id kõiki käske kasutades.", "item_level_req": "🔒 Selle eseme ostmiseks vajad **taset {min_level}** (sul on tase {user_level}). Teeni EXP-id kõiki käske kasutades.",
@@ -653,7 +655,7 @@ CD_MSG: dict[str, str] = {
"rob": "⏳ Saad uuesti röövida {ts}.", "rob": "⏳ Saad uuesti röövida {ts}.",
"heist": "⏳ Saad uuesti heisti teha {ts}.", "heist": "⏳ Saad uuesti heisti teha {ts}.",
"heist_global": "⏳ Pangahoidla alles kosub eelmisest röövist. Järgmine heist võimalik {ts}.", "heist_global": "⏳ Pangahoidla alles kosub eelmisest röövist. Järgmine heist võimalik {ts}.",
"jailed": "<:TipiTROLL:1483431380166774895> Oled vangis! Pääsed välja {ts}. Kasuta `/jailbreak`, et varem välja pääseda.", "jailed": E["TipiTROLL"] + " Oled vangis! Pääsed välja {ts}. Kasuta `/jailbreak`, et varem välja pääseda.",
"fish": "🎣 Saad uuesti kalastada {ts}.", "fish": "🎣 Saad uuesti kalastada {ts}.",
} }
@@ -837,8 +839,8 @@ CHANNEL_UI: dict[str, str] = {
DAILY_UI: dict[str, str] = { DAILY_UI: dict[str, str] = {
"earned": "✅ Said {earned}!", "earned": "✅ Said {earned}!",
"interest": "<:TipiLAP:1483004307161874566> Bot Farm tootis: +{interest}", "interest": E["TipiLAP"] + " Bot Farm tootis: +{interest}",
"vip": "<:TipiPILET:1483004308353060904> LAN pileti boonus rakendus!", "vip": f"{E['TipiPILET']} LAN pileti boonus rakendus!",
"footer": "Streak: {streak_str} · Saldo: {balance}", "footer": "Streak: {streak_str} · Saldo: {balance}",
} }
@@ -1050,9 +1052,9 @@ RANK_UI: dict[str, str] = {
WORK_UI: dict[str, str] = { WORK_UI: dict[str, str] = {
"desc": "Sa {job} ja teenisid {earned}!", "desc": "Sa {job} ja teenisid {earned}!",
"redbull": "\n<:TipiBULL:1483004310924300409> Red Bull aktiveerus - 3x boonus!", "redbull": f"\n{E['TipiBULL']} Red Bull aktiveerus - 3x boonus!",
"hiir": "\n<:TipiHIIR:1483004306012504128> Mängurihiir: +50% palk", "hiir": f"\n{E['TipiHIIR']} Mängurihiir: +50% palk",
"laud": "\n<:TipiLAUD:1483387695576125440> Reguleeritav laud: +25% palk", "laud": f"\n{E['TipiLAUD']} Reguleeritav laud: +25% palk",
"balance": "\nSaldo: {balance}", "balance": "\nSaldo: {balance}",
} }
@@ -1062,7 +1064,7 @@ WORK_UI: dict[str, str] = {
BEG_UI: dict[str, str] = { BEG_UI: dict[str, str] = {
"desc": "Sa {text} ja said {earned}.", "desc": "Sa {text} ja said {earned}.",
"klaviatuur": "<:TipiKLAVA:1483014339228078140> Mehhaaniline klaviatuur: 2x tulu", "klaviatuur": f"{E['TipiKLAVA']} Mehhaaniline klaviatuur: 2x tulu",
"balance": "Saldo: {balance}", "balance": "Saldo: {balance}",
} }
@@ -1075,8 +1077,8 @@ CRIME_UI: dict[str, str] = {
"fail_base": "Sa {text} ja said trahvi {fine}.", "fail_base": "Sa {text} ja said trahvi {fine}.",
"fail_jailed": "\n\ud83d\udd12 Oled vangis! P\u00e4\u00e4sed {ts}.", "fail_jailed": "\n\ud83d\udd12 Oled vangis! P\u00e4\u00e4sed {ts}.",
"fail_shield": "\n\ud83d\udee1\ufe0f Gaming Tool hoidis sind vanglast!", "fail_shield": "\n\ud83d\udee1\ufe0f Gaming Tool hoidis sind vanglast!",
"mikrofon": "\n<:TipiMIC:1483387698499551313> Mikrofon: +30% saak", "mikrofon": f"\n{E['TipiMIC']} Mikrofon: +30% saak",
"cat6": "\n<:TipiCAT:1483014337663602718> CAT6: 75% edu t\u00f5en\u00e4osus", "cat6": f"\n{E['TipiCAT']} CAT6: 75% edu t\u00f5en\u00e4osus",
"balance": "\nSaldo: {balance}", "balance": "\nSaldo: {balance}",
} }
@@ -1116,7 +1118,7 @@ BUY_UI: dict[str, str] = {
JAILBREAK_UI: dict[str, str] = { JAILBREAK_UI: dict[str, str] = {
"btn_roll": "🎲 Viska täringud ({try_}/{max})", "btn_roll": "🎲 Viska täringud ({try_}/{max})",
"rolling_desc": "<:TipiDICE:1485923107108556950> *Täringud lendavad...*", "rolling_desc": f"{E['TipiDICE']} *Täringud lendavad...*",
"free_desc": "{d1} {d2}\n\n✅ Viskasid duubli - pääsesid vanglast!", "free_desc": "{d1} {d2}\n\n✅ Viskasid duubli - pääsesid vanglast!",
"miss_desc": "{d1} {d2}\n\n{left} katset jäänud. Proovi uuesti!", "miss_desc": "{d1} {d2}\n\n{left} katset jäänud. Proovi uuesti!",
"intro_desc": "Oled vangis kuni {ts}.\n\nViska täringuid ja proovi **duublit** saada - siis pääsed tasuta vabaks!\nSul on **{tries} katset**. Ebaõnnestumisel saad valida: maksa kautsjon **(2030% saldost, min 350 ⬡)** või jää vanglasse kuni aja lõpuni.", "intro_desc": "Oled vangis kuni {ts}.\n\nViska täringuid ja proovi **duublit** saada - siis pääsed tasuta vabaks!\nSul on **{tries} katset**. Ebaõnnestumisel saad valida: maksa kautsjon **(2030% saldost, min 350 ⬡)** või jää vanglasse kuni aja lõpuni.",
@@ -1160,7 +1162,7 @@ LEADERBOARD_UI: dict[str, str] = {
SLOTS_UI: dict[str, str] = { SLOTS_UI: dict[str, str] = {
"playing": "🎰 Mängimas...", "playing": "🎰 Mängimas...",
"jackpot_footer": "<:TipiKARIKAS:1483014841148112977> Kolm karikat! +{change}", "jackpot_footer": E["TipiKARIKAS"] + " Kolm karikat! +{change}",
"triple_footer": "✅ Kolm ühesugust! +{change}", "triple_footer": "✅ Kolm ühesugust! +{change}",
"pair_footer": "Kaks ühesugust! +{change}", "pair_footer": "Kaks ühesugust! +{change}",
"miss_footer": "-{amount}", "miss_footer": "-{amount}",
@@ -1264,7 +1266,7 @@ PRESTIGE_SHOP_DESCRIPTIONS: dict[str, str] = {
PRESTIGE_UI: dict[str, str] = { PRESTIGE_UI: dict[str, str] = {
"confirm_desc": ( "confirm_desc": (
"Oled tasemel **{level}** ({exp} EXP).\n\n" "Oled tasemel **{level}** ({exp} EXP).\n\n"
"Prestiiži korral saad **{pp}** <:TipiFIRE:1483431381668335687> ja kõik lähtestub:\n" "Prestiiži korral saad **{pp}** " + E["TipiFIRE"] + " ja kõik lähtestub:\n"
"• Saldo, EXP, esemed, ooteajad\n\n" "• Saldo, EXP, esemed, ooteajad\n\n"
"**Kalakogu jääb alles!**\n\nKas oled kindel?" "**Kalakogu jääb alles!**\n\nKas oled kindel?"
), ),
@@ -1273,21 +1275,21 @@ PRESTIGE_UI: dict[str, str] = {
"btn_tab_status": "⭐ Prestiiz", "btn_tab_status": "⭐ Prestiiz",
"btn_tab_shop": "🛍️ Uuendused", "btn_tab_shop": "🛍️ Uuendused",
"success_desc": ( "success_desc": (
"Said **{pp}** <:TipiFIRE:1483431381668335687>\n" "Said **{pp}** " + E["TipiFIRE"] + "\n"
"Prestiiži tase: **{level}**\n" "Prestiiži tase: **{level}**\n"
"Kogutud PP: **{total_pp}** <:TipiFIRE:1483431381668335687>\n\n" "Kogutud PP: **{total_pp}** " + E["TipiFIRE"] + "\n\n"
"*Kõik lähtestati. Alusta otsast!*" "*Kõik lähtestati. Alusta otsast!*"
), ),
"too_low_desc": "Prestiiži jaoks vajad taset **{required}** (sul on tase {level}).", "too_low_desc": "Prestiiži jaoks vajad taset **{required}** (sul on tase {level}).",
"shop_desc": "Sul on **{pp}** <:TipiFIRE:1483431381668335687> · Vajuta nuppu uuenduse ostmiseks", "shop_desc": "Sul on **{pp}** " + E["TipiFIRE"] + " · Vajuta nuppu uuenduse ostmiseks",
"shop_maxed": "✅ Max", "shop_maxed": "✅ Max",
"shop_level_fmt": "Tase {cur}/{max}", "shop_level_fmt": "Tase {cur}/{max}",
"shop_cost_fmt": "{cost} <:TipiFIRE:1483431381668335687>", "shop_cost_fmt": "{cost} " + E["TipiFIRE"],
"buy_success_desc":"**{name}** uuendatud tasemele **{new_level}/{max_level}**!\nPP alles: **{pp}** <:TipiFIRE:1483431381668335687>", "buy_success_desc":"**{name}** uuendatud tasemele **{new_level}/{max_level}**!\nPP alles: **{pp}** " + E["TipiFIRE"],
"buy_no_pp": "<:TipICRY:1483431288852709387> Sul pole piisavalt PP. Sul on **{have}**, vajad **{need}** <:TipiFIRE:1483431381668335687>.", "buy_no_pp": E["TipICRY"] + " Sul pole piisavalt PP. Sul on **{have}**, vajad **{need}** " + E["TipiFIRE"] + ".",
"buy_maxed": "❌ See uuendus on juba maksimumtasemel.", "buy_maxed": "❌ See uuendus on juba maksimumtasemel.",
"buy_not_found": "❌ Sellist uuendust ei leitud. Vaata `/prestigeshop`.", "buy_not_found": "❌ Sellist uuendust ei leitud. Vaata `/prestigeshop`.",
"rank_line": "<:TipiFIRE:1483431381668335687> Prestiiž **{level}** · {pp} PP", "rank_line": E["TipiFIRE"] + " Prestiiž **{level}** · {pp} PP",
"rank_season": "🏆 Hooaja EXP: **{exp}**", "rank_season": "🏆 Hooaja EXP: **{exp}**",
"btn_buy_upgrade": "{emoji} {name} +1 ({cost} PP)", "btn_buy_upgrade": "{emoji} {name} +1 ({cost} PP)",
"status_footer": "⭐ Prestiiž {level} · {pp} PP", "status_footer": "⭐ Prestiiž {level} · {pp} PP",