diff --git a/README.md b/README.md index 23976c2..f400608 100644 --- a/README.md +++ b/README.md @@ -222,7 +222,7 @@ If a member joins and their birthday is within `BIRTHDAY_WINDOW_DAYS` days, a bi ## TipiCOIN Economy -All economy data is stored in **PocketBase** (`economy_users` collection - see `core/pb_client.py`). The currency is **TipiCOIN** (⬡), displayed as a custom Discord emoji configured in `core/economy.py → COIN`. +All economy data is stored in **PocketBase** (`economy_users` collection - see `core/pb_client.py`). The currency is **TipiCOIN** (⬡), displayed as a custom Discord emoji configured in `core/economy/store.py → COIN`. --- @@ -457,7 +457,7 @@ All items are **permanent** once purchased **except Anticheat**, which expires a Commands that accept a coin amount (`/give`, `/roulette`, `/rps`, `/slots`, `/blackjack`) accept `"all"` as the amount to wager your entire balance. ### Custom emoji -Change `COIN` in `core/economy.py` to any Discord emoji string: +Change `COIN` in `core/economy/store.py` to any Discord emoji string: ```python COIN = "<:tipicoin:YOUR_EMOJI_ID>" ``` @@ -483,7 +483,15 @@ Every slash command invocation is logged with the user ID, display name, and all ``` ├── bot.py # Discord client, event handlers, shared helpers; wires command modules together -├── strings.py # All user-facing strings (command descriptions, help text, errors) +├── strings/ # All user-facing strings, split by domain; re-exported so `import strings` works unchanged +│ ├── __init__.py # Re-exports every name from the submodules +│ ├── common.py # System messages, embed TITLEs, ERR, CD_MSG, status/send/patchnotes/reminders +│ ├── commands.py # CMD + OPT descriptions, HELP_CATEGORIES, HELP_UI +│ ├── member.py # /check, member/birthday/channel/economy-setup UI +│ ├── economy.py # Income flavour + income/profile/shop/quests/leaderboard/request UI +│ ├── admin.py # Admin responses, season reset, prestige +│ ├── games.py # Slots, roulette, RPS, blackjack, heist, jailbreak +│ └── fishing.py # Fish catalogue, rarities, /fish UI ├── config.py # Environment variable loader ├── core/ │ ├── economy/ # TipiCOIN business logic (re-exported via core/economy/__init__.py) diff --git a/commands/economy_support_commands.py b/commands/economy_support_commands.py index 4d4c25d..5d11e56 100644 --- a/commands/economy_support_commands.py +++ b/commands/economy_support_commands.py @@ -38,15 +38,21 @@ def register_economy_support_commands( ) return + # Reserve the amount synchronously (no await between the range check + # and the decrement) so two concurrent modal submits can't both fund + # the same request. discord.py runs each submit as its own task and + # do_give is not idempotent, so without this reservation a funder + # could double-submit and transfer `amount` more than once. + self._view.remaining -= amount res = await economy.do_give(interaction.user.id, self._view.requester.id, amount) if not res["ok"]: + self._view.remaining += amount # roll back the reservation data = await economy.get_user(interaction.user.id) await interaction.response.send_message( S.ERR["broke"].format(bal=coin(data["balance"])), ephemeral=True ) return - self._view.remaining -= amount funded_line = S.REQUEST_UI["funded_line"].format( name=interaction.user.display_name, amount=coin(amount), @@ -84,6 +90,9 @@ def register_economy_support_commands( self.add_item(self.fund_btn) async def _fund(self, interaction: discord.Interaction): + if self.remaining <= 0 or self.is_finished(): + await interaction.response.send_message(S.ERR["request_closed"], ephemeral=True) + return if interaction.user.id == self.requester.id: await interaction.response.send_message(S.ERR["request_self_fund"], ephemeral=True) return diff --git a/core/sheets.py b/core/sheets.py index aac6cdc..cdcbd28 100644 --- a/core/sheets.py +++ b/core/sheets.py @@ -7,12 +7,15 @@ Pure-cache helpers (get_cache, find_*) remain sync. """ import asyncio +import logging import gspread from google.oauth2.service_account import Credentials import config +log = logging.getLogger(__name__) + # Scopes needed: read + write to Sheets SCOPES = [ "https://www.googleapis.com/auth/spreadsheets", @@ -69,12 +72,25 @@ def _get_worksheet() -> gspread.Worksheet: def _ensure_headers(ws: gspread.Worksheet) -> None: - """If the sheet is empty or missing headers, write them (headers are in row 1).""" + """Verify the header row matches what we expect. + + The production sheet is owner-managed and its header row (row 1) is a + protected range, so the bot must NOT write to it — attempting to do so + raises `APIError [400]: You are trying to edit a protected cell or object` + and aborts the whole refresh. We only log a mismatch so it can be fixed + by hand; column lookups still work as long as the headers we rely on exist. + """ existing = ws.row_values(1) if existing != EXPECTED_HEADERS: - for col_idx, header in enumerate(EXPECTED_HEADERS, start=1): - if col_idx > len(existing) or existing[col_idx - 1] != header: - ws.update_cell(1, col_idx, header) + missing = [h for h in EXPECTED_HEADERS if h not in existing] + log.warning( + "Sheet header row does not match EXPECTED_HEADERS " + "(missing/renamed: %s). Expected %s, found %s. " + "Not writing to the (protected) header row; fix it manually if needed.", + missing or "none — order/whitespace differs", + EXPECTED_HEADERS, + existing, + ) def _refresh_sync() -> list[dict]: diff --git a/docs/DEV_NOTES.md b/docs/DEV_NOTES.md index 3ce8aeb..8fa1796 100644 --- a/docs/DEV_NOTES.md +++ b/docs/DEV_NOTES.md @@ -9,14 +9,14 @@ The codebase is split into **`core/`** (domain logic), **`commands/`** (Discord | File | Purpose | |---|---| | `bot.py` | Discord client, event handlers (`on_ready`, `on_member_join`, ...), background tasks (presence rotation, daily birthday loop), shared helpers (`_award_exp`, `_maybe_remind`, `_parse_amount`, `_PAUSED`), and `register_*_commands(...)` wiring for every command module | -| `strings.py` | **Single source of truth for all user-facing text.** Edit here to change any message. | +| `strings/` | **Single source of truth for all user-facing text**, split into domain submodules (`common`, `commands`, `member`, `economy`, `admin`, `games`, `fishing`) and re-exported via `strings/__init__.py` so `import strings` / `strings.NAME` works unchanged. Edit the relevant submodule to change any message. | | `config.py` | Environment variables (TOKEN, GUILD_ID, PB_URL, etc.) | ### `core/` - domain logic, no Discord coupling | File | Purpose | |---|---| -| `core/economy.py` | All economy business logic (`do_daily`, `do_work`, ...), data model, constants (SHOP, COOLDOWNS, LEVEL_ROLES, EXP_REWARDS, JAIL_DURATION, ...) | +| `core/economy/` | Economy business logic **package**, re-exported via `core/economy/__init__.py` so callers use `from core import economy` + attribute access (`economy.do_daily`, `economy.SHOP`, ...). Submodules: `store.py` (user records, per-user locks, `COOLDOWNS`, `JAIL_DURATION`, `COIN`, `get_user`/`_commit`/`_txn`), `income.py`, `gambling.py`, `fishing.py`, `jail.py`, `heist.py`, `prestige.py`, `shop.py`, `levels.py`, `quests.py`, `leaderboards.py`, `house.py`, `admin.py` | | `core/pb_client.py` | Async PocketBase REST client - auth token cache, CRUD on `economy_users` collection | | `core/sheets.py` | Google Sheets integration (member sync) | | `core/member_sync.py` | Birthday/member sync helpers | @@ -57,19 +57,19 @@ Pick the `commands/economy_*_commands.py` file that matches the new command's ca Checklist - do all of these, in order: -1. **`core/economy.py`** - add the `do_` async function with cooldown check, logic, `_commit`, and `_txn` logging -2. **`core/economy.py`** - add the cooldown to `COOLDOWNS` dict if it has one -3. **`core/economy.py`** - add the EXP reward to `EXP_REWARDS` dict -4. **`strings.py` `CMD`** - add the slash command description -5. **`strings.py` `OPT`** - add any parameter descriptions -6. **`strings.py` `TITLE`** - add embed title(s) for success/fail states -7. **`strings.py` `ERR`** - add any error messages (banned, cooldown uses `CD_MSG`, jailed uses `CD_MSG["jailed"]`) -8. **`strings.py` `CD_MSG`** - add cooldown message if command has a cooldown -9. **`strings.py` `HELP_CATEGORIES["tipibot"]["fields"]`** - add the command to the help embed +1. **`core/economy/.py`** (e.g. `income.py`, `gambling.py`, `fishing.py`) - add the `do_` async function with cooldown check, logic, `_commit`, and `_txn` logging (`get_user`/`_commit`/`_txn` live in `store.py`) +2. **`core/economy/store.py`** - add the cooldown to `COOLDOWNS` dict if it has one +3. **`core/economy/levels.py`** - add the EXP reward to `EXP_REWARDS` dict +4. **`strings/commands.py` `CMD`** - add the slash command description +5. **`strings/commands.py` `OPT`** - add any parameter descriptions +6. **`strings/common.py` `TITLE`** - add embed title(s) for success/fail states +7. **`strings/common.py` `ERR`** - add any error messages (banned, cooldown uses `CD_MSG`, jailed uses `CD_MSG["jailed"]`) +8. **`strings/common.py` `CD_MSG`** - add cooldown message if command has a cooldown +9. **`strings/commands.py` `HELP_CATEGORIES["tipibot"]["fields"]`** - add the command to the help embed 10. **`commands/economy__commands.py`** - inside `register_*_commands`, add `@tree.command(name="", ...)` `cmd_`; handle all `res["reason"]` cases 11. **`commands/economy__commands.py`** - call `maybe_remind(user_id, "")` if the command has a cooldown and reminders make sense (the helper is passed in via the `register_*` signature) 12. **`commands/economy__commands.py`** - call `await award_exp(interaction, economy.EXP_REWARDS[""])` on success -13. **`strings.py` `REMINDER_OPTS`** - add a reminder option if the command needs one +13. **`strings/common.py` `REMINDER_OPTS`** - add a reminder option if the command needs one 14. **`bot.py` `_maybe_remind`** - if the command has an item-modified cooldown, add an `elif` branch (this helper still lives in `bot.py` and is shared across all command modules) --- @@ -78,13 +78,13 @@ Checklist - do all of these, in order: Checklist: -1. **`core/economy.py` `SHOP`** - add the item dict `{name, emoji, cost, description: strings.ITEM_DESCRIPTIONS["key"]}` -2. **`core/economy.py` `SHOP_TIERS`** - add the key to the correct tier list (1/2/3) -3. **`core/economy.py` `SHOP_LEVEL_REQ`** - add minimum level if it is T2 (≥10) or T3 (≥20) -4. **`strings.py` `ITEM_DESCRIPTIONS`** - add the item description (Estonian flavour + English effect) -5. **`strings.py` `HELP_CATEGORIES["shop"]["fields"]`** - add display entry (sorted by cost) +1. **`core/economy/shop.py` `SHOP`** - add the item dict `{name, emoji, cost, description: strings.ITEM_DESCRIPTIONS["key"]}` +2. **`core/economy/shop.py` `SHOP_TIERS`** - add the key to the correct tier list (1/2/3) +3. **`core/economy/shop.py` `SHOP_LEVEL_REQ`** - add minimum level if it is T2 (≥10) or T3 (≥20) +4. **`strings/economy.py` `ITEM_DESCRIPTIONS`** - add the item description (Estonian flavour + English effect) +5. **`strings/commands.py` `HELP_CATEGORIES["shop"]["fields"]`** - add display entry (sorted by cost) 6. If the item modifies a cooldown: - - **`core/economy.py`** - add the `if "item" in user["items"]` branch in the relevant `do_` function + - **`core/economy/.py`** - add the `if "item" in user["items"]` branch in the relevant `do_` function - **`bot.py` `_maybe_remind`** - add `elif cmd == "" and "" in items:` branch with the new delay - **`commands/economy_profile_commands.py` `cmd_cooldowns`** - add the item annotation to the relevant status line @@ -92,7 +92,7 @@ Checklist: ## Adding a New Level Role -1. **`core/economy.py` `LEVEL_ROLES`** - add `(min_level, "RoleName")` in descending level order (highest first) +1. **`core/economy/levels.py` `LEVEL_ROLES`** - add `(min_level, "RoleName")` in descending level order (highest first) 2. **`bot.py` `_ensure_level_role`** - no changes needed (uses `LEVEL_ROLES` dynamically) 3. Run **`/economysetup`** in the server to create the role and set its position @@ -100,8 +100,8 @@ Checklist: ## Adding a New Admin Command -1. **`strings.py` `CMD`** - add `"[Admin] ..."` description -2. **`strings.py` `HELP_CATEGORIES["admin"]["fields"]`** - add the entry +1. **`strings/commands.py` `CMD`** - add `"[Admin] ..."` description +2. **`strings/commands.py` `HELP_CATEGORIES["admin"]["fields"]`** - add the entry 3. **`commands/economy_admin_commands.py`** (or `commands/ops_admin_commands.py` for non-economy ops) - add the handler with `@app_commands.default_permissions(manage_guild=True)` and `@app_commands.guild_only()` --- @@ -110,7 +110,7 @@ Checklist: ### Storage -All economy state is stored in **PocketBase** (`economy_users` collection). `core/pb_client.py` owns all reads/writes. Each `do_*` function in `core/economy.py` calls `get_user()` → mutates the local dict → calls `_commit()`. `_commit` does a `PATCH` to PocketBase. +All economy state is stored in **PocketBase** (`economy_users` collection). `core/pb_client.py` owns all reads/writes. Each `do_*` function in `core/economy/` calls `get_user()` (from `store.py`) → mutates the local dict → calls `_commit()`. `_commit` does a `PATCH` to PocketBase. ### Currency & Income Sources @@ -141,10 +141,10 @@ Commands that accept a coin amount (`/give`, `/roulette`, `/rps`, `/slots`, `/bl - `/jailbreak`: 3 dice rolls, need doubles to escape free. On fail - bail = 20-30% of balance, min 350⬡. If balance < 350⬡, player stays jailed until timer. - **Blocked while jailed**: `/work`, `/beg`, `/crime`, `/rob`, `/give` (checked in `do_*` functions via `_is_jailed`) -### EXP Rewards (from `EXP_REWARDS` in `core/economy.py`) +### EXP Rewards (from `EXP_REWARDS` in `core/economy/levels.py`) EXP is awarded on every successful command use. Level formula: `level = max(1, floor(sqrt(exp / 6)))` (see `get_level` / `exp_for_level`). Thresholds: Level 5 = 150 EXP, Level 10 = 600, Level 20 = 2 400, Level 30 = 5 400. -Gambling EXP is bet-scaled via `gamble_exp(bet)`; fish EXP is per-species in `FISH` (common 2–3, uncommon 6–7, rare 10, epic 14–15, legendary 25). +Gambling EXP is bet-scaled via `gamble_exp(bet)`; fish EXP is per-species in `FISH_CATALOGUE` (common 2–3, uncommon 6–7, rare 10, epic 14–15, legendary 25). --- @@ -179,49 +179,51 @@ Role assignment: | T3 | 20 | monitor_360, karikas, gaming_tool | Shop display is sorted by cost (ascending) within each tier. -The `SHOP_LEVEL_REQ` dict in `core/economy.py` controls per-item lock thresholds. +The `SHOP_LEVEL_REQ` dict in `core/economy/shop.py` controls per-item lock thresholds. --- -## strings.py Organisation +## strings/ Organisation -Imported as `import strings as S` everywhere. Dicts are read from `bot.py` and from every `commands/*.py` module. +Imported as `import strings as S` everywhere. `strings/` is a package: the names below live in domain submodules and are re-exported from `strings/__init__.py`, so `S.CMD`, `S.ERR`, etc. resolve unchanged regardless of which submodule they live in. Dicts are read from `bot.py` and from every `commands/*.py` module. Edit the submodule shown in the **Module** column. -| Section | Dict | Typical usage | -|---|---|---| -| Flavour text | `WORK_JOBS`, `BEG_LINES`, `CRIME_WIN`, `CRIME_LOSE` | Randomised descriptions | -| Command descriptions | `CMD["key"]` | `@tree.command(description=S.CMD["key"])` | -| Parameter descriptions | `OPT["key"]` | `@app_commands.describe(param=S.OPT["key"])` | -| Help embed | `HELP_CATEGORIES["cat"]` | `cmd_help` (in `bot.py`) | -| Banned message | `MSG_BANNED` | All banned checks | -| Maintenance mode | `MSG_MAINTENANCE` | Shown when `_PAUSED=True` in `bot.py` (toggled by `/pause` in `commands/ops_admin_commands.py`) | -| Reminder options | `REMINDER_OPTS` | `RemindersSelect` dropdown | -| Slots outcomes | `SLOTS_TIERS["tier"]` → `(title, color)` | `cmd_slots` (in `commands/economy_games_commands.py`) | -| Embed titles | `TITLE["key"]` | `discord.Embed(title=S.TITLE["key"])` | -| Error messages | `ERR["key"]` | `send_message(S.ERR["key"])` - use `.format(**kwargs)` for dynamic parts | -| Cooldown messages | `CD_MSG["cmd"].format(ts=cd_ts(...))` | Cooldown responses (`cd_ts` helper passed in by `bot.py`) | -| Shop UI | `SHOP_UI["key"]` | `_shop_embed` (in `commands/economy_support_commands.py`) | -| Item descriptions | `ITEM_DESCRIPTIONS["item_key"]` | `core/economy.py` `SHOP[key]["description"]` | -| Patch notes UI | `PATCHNOTES_UI["key"]` | `commands/info_commands.py` (`/patchnotes`) | +| Section | Dict | Module | Typical usage | +|---|---|---|---| +| Flavour text | `WORK_JOBS`, `BEG_LINES`, `CRIME_WIN`, `CRIME_LOSE` | `economy.py` | Randomised descriptions | +| Command descriptions | `CMD["key"]` | `commands.py` | `@tree.command(description=S.CMD["key"])` | +| Parameter descriptions | `OPT["key"]` | `commands.py` | `@app_commands.describe(param=S.OPT["key"])` | +| Help embed | `HELP_CATEGORIES["cat"]` | `commands.py` | `cmd_help` (in `bot.py`) | +| Banned message | `MSG_BANNED` | `common.py` | All banned checks | +| Maintenance mode | `MSG_MAINTENANCE` | `common.py` | Shown when `_PAUSED=True` in `bot.py` (toggled by `/pause` in `commands/ops_admin_commands.py`) | +| Reminder options | `REMINDER_OPTS` | `common.py` | `RemindersSelect` dropdown | +| Slots outcomes | `SLOTS_TIERS["tier"]` → `(title, color)` | `games.py` | `cmd_slots` (in `commands/economy_games_commands.py`) | +| Embed titles | `TITLE["key"]` | `common.py` | `discord.Embed(title=S.TITLE["key"])` | +| Error messages | `ERR["key"]` | `common.py` | `send_message(S.ERR["key"])` - use `.format(**kwargs)` for dynamic parts | +| Cooldown messages | `CD_MSG["cmd"].format(ts=cd_ts(...))` | `common.py` | Cooldown responses (`cd_ts` helper passed in by `bot.py`) | +| Shop UI | `SHOP_UI["key"]` | `economy.py` | `_shop_embed` (in `commands/economy_support_commands.py`) | +| Item descriptions | `ITEM_DESCRIPTIONS["item_key"]` | `economy.py` | `core/economy/shop.py` `SHOP[key]["description"]` | +| Patch notes UI | `PATCHNOTES_UI["key"]` | `common.py` | `commands/info_commands.py` (`/patchnotes`) | --- ## Constants Location Quick-Reference -| Constant | File | Description | +All are re-exported from `core/economy/__init__.py`, so code reads them as `economy.` regardless of which submodule defines them. Edit the file in the **Defined in** column. + +| Constant | Defined in | Description | |---|---|---| -| `SHOP` | `core/economy.py` | All shop items (name, emoji, cost, description) | -| `SHOP_TIERS` | `core/economy.py` | Which items are in T1/T2/T3 | -| `SHOP_LEVEL_REQ` | `core/economy.py` | Min level per item | -| `COOLDOWNS` | `core/economy.py` | Base cooldown per command | -| `JAIL_DURATION` | `core/economy.py` | How long jail lasts | -| `LEVEL_ROLES` | `core/economy.py` | `[(min_level, "RoleName"), ...]` highest first | -| `ECONOMY_ROLE` | `core/economy.py` | Name of the base economy participation role | -| `EXP_REWARDS` | `core/economy.py` | EXP per command | -| `FISH` | `core/economy.py` | Fish species table (rarity, weight, coins, exp) | -| `HOUSE_ID` | `core/economy.py` | Bot's user ID (house account for /rob) | -| `MIN_BAIL` | `core/economy.py` | Minimum bail payment (350⬡) | -| `COIN` | `core/economy.py` | The coin emoji string | +| `SHOP` | `core/economy/shop.py` | All shop items (name, emoji, cost, description) | +| `SHOP_TIERS` | `core/economy/shop.py` | Which items are in T1/T2/T3 | +| `SHOP_LEVEL_REQ` | `core/economy/shop.py` | Min level per item | +| `COOLDOWNS` | `core/economy/store.py` | Base cooldown per command | +| `JAIL_DURATION` | `core/economy/store.py` | How long jail lasts | +| `LEVEL_ROLES` | `core/economy/levels.py` | `[(min_level, "RoleName"), ...]` highest first | +| `ECONOMY_ROLE` | `core/economy/levels.py` | Name of the base economy participation role | +| `EXP_REWARDS` | `core/economy/levels.py` | EXP per command | +| `FISH_CATALOGUE` | `core/economy/fishing.py` | Fish species table (rarity, weight, coins, exp) | +| `HOUSE_ID` | `core/economy/house.py` | Bot's user ID (house account for /rob) | +| `MIN_BAIL` | `core/economy/jail.py` | Minimum bail payment (350⬡) | +| `COIN` | `core/economy/store.py` | The coin emoji string | | `_PAUSED` | `bot.py` | In-memory maintenance flag; toggled by `/pause`; blocks all non-admin commands | --- diff --git a/strings.py b/strings.py deleted file mode 100644 index 5ef005e..0000000 --- a/strings.py +++ /dev/null @@ -1,1415 +0,0 @@ -"""All user-facing text for TipiLAN Bot. - -Edit this file to change any message, description, or flavour text -without touching any logic code. -""" - -from core.emoji import EMOJI as E - -# --------------------------------------------------------------------------- -# Flavour text -# --------------------------------------------------------------------------- - -WORK_JOBS: list[tuple[str, float]] = [ - ("paigaldasid aulas netikaableid", 1.0), - ("paigaldasid aulas voolukaableid", 1.0), - ("tõid poest korraldajatele pitsat", 1.0), - ("konfigureerisid uue switchi", 1.0), - ("vedasid laudu aulasse", 1.0), - ("vedasid toole aulasse", 1.0), - ("paigaldasid aulasse vahekardinaid", 1.0), - ("aitasid üles seada turniiri lava", 1.0), - ("töötasid baaris", 1.0), - ("testisid helisüsteemi \"Erootikapoodi\" blastides", 1.0), - ("juhendasid külastajaid infolauas", 1.0), - ("seadistasid LAN serverit", 1.0), - ("paigaldasid monitore", 1.0), - ("ühendasid aulas kilpe", 1.0), - ("aitasid LANil osalejat", 1.0), - ("müüsid energiajooke", 1.0), - ("tegid netikaableid", 1.0), - ("lahendasid IP-konflikti", 1.0), - ("parandasid kellegi arvutit", 1.0), - ("tegid korda striimi heli (mitte nagu PGL)", 1.2), - ("kirjutasid koodi miniturniiri jaoks", 1.2), - ("võitsid turniiri", 1.5), -] - -BEG_LINES: list[str] = [ - "istusid kurva näoga oma monitori taga", - "palusid abi kellegi DMis", - "postitasid #abi kanalisse", - "vaatasid kadedusega teiste asju", - "kirjutasid /beg kolmandat korda järjest", - "küsisid oma tiimiliikmelt laenu", - "võtsid kiirlaenu", - "müüsid 3 sendi eest oma CSi skinne", - "korjasid kampuselt taarat", - "tegid TikToki live'i", - "refreshisid pangaäppi lootuses, et raha tekib", - "kirjutasid \"pls donate\" chatti", - "vaatasid oma tühja rahakotti", - "püüdsid kedagi guilt-trippida", - "lubasid exposure'it raha eest", - "mängisid kurba muusikat taustaks", - "teesklesid, et see on sotsiaalne eksperiment", - "kirjutasid emotsionaalse loo oma olukorrast", - "pakkusid vastu future equity't", - "tegite sõbraga koos kerjamisplaani", - "otsisid diivani vahelt sente", - "lubasid boostida kellegi ranki viieka eest", - "küsisid chatist, kas keegi teab kust tasuta V-Buckse saab", - "avastasid, et su krüptoportfell on sügavas miinuses", -] - -BEG_JAIL_LINES: list[str] = [ - "karjusid läbi trellide, et keegi münte läbi lükkaks", - "kirjutasid kongi seina peale oma PayPali aadressi", - "lubasid, et maksad järgmine kord vangi minnes tagasi", - "veensid valvurit, et oled tegelikult hea inimene", - "saatsid vanglast käsitsi kirjutatud kirja oma meeskonnale", - "pakkusid vahile tulevaste vihjete eest raha", - "koputasid morset vastu naaberkongi seina", - "üritasid vangla WiFit häkkida", - "lubasid teha tasuta IT-tööd vabanemise eest", - "üritasid lusikaga tunnelit kaevata", - "kirjutasid bug reporti vangla süsteemile", - "proovisid trellidest läbi pugeda, aga jäid kinni", - "pakkusid vangivalvurile oma Steami kontot vabanemise eest", -] - -CRIME_WIN: list[str] = [ - "häkkisid turniiri tulemuste tabelit", - "varastasid oma vastase hiire", - "varastasid oma vastase klaviatuuri", - "varastasid oma vastase kõrvaklapid", - "varastasid oma vastase monitori", - "varastasid oma vastase mikrofoni", - "müüsid võltsitud LANi pileteid", - "laenatasid kellegi GPUd ja ei tagastanud seda", - "laenatasid Filmiklubilt AUX-kaablit ja ei tagastanud seda", - "käivitasid DDoS rünnaku serverile", - "tegid oma shitcoin'idega pump and dump'i", - "kasutasid aimbotti ja keegi ei märganud", - "exploitisid mängu bugi enda kasuks", - "phishisid kellegi Steami konto", - "varastasid prize pooli raha", - "ühendasid enda krüptokaevandaja serverisse", - "tegid petukõnesid" -] - -CRIME_LOSE: list[str] = [ - "jäid turniiri adminile vahele", - "tõmbasid oma arvuti kaabli pistikust välja", - "kukutasid lahtise Red Bulli omale sülle", - "unustasid VPNi sisse lülitada", - "lagisid kriitilisel momendil", - "said banni otseülekande ajal", - "unustasid logid kustutada", - "sinu skript crashis valel hetkel", - "said reportitud mitme mängija poolt", - "sinu krüptokaevandaja süttis põlema", - "flashisid tervet oma tiimi", - "avastasid, et Windows otsustas keset mängu uuendama hakata", - "jäid politseile petukõnedega vahele" -] - -# --------------------------------------------------------------------------- -# Slash command descriptions (shown in Discord's autocomplete) -# --------------------------------------------------------------------------- - -CMD: dict[str, str] = { - "ping": "Vaata, kas bot on üleval", - "help": "Nimekiri kõikidest käskudest kategooriate kaupa", - "status": "Näita boti staatust ja ressursside kasutust", - "birthdays": "Näita kõigi liikmete sünnipäevi kuu järgi", - "check": "Laadi andmed, täida ID'd ja sünkroniseeri kõik liikmed", - "sync": "Sünkroniseeri käsklused Discordi serveriga", - "member": "Näita liikme andmeid tabelist", - "restart": "Tee taaskäivitus botile", - "shutdown": "Lülita bot välja (ilma taaskäivituseta)", - "pause": "Peata / jätka kõik käsklused (hooldusrežiim)", - "send": "Saada sõnum valitud kanalisse", - "profile": "Vaata oma profiili: saldo, tase, esemed, statistika ja kalakogu", - "balance": "Vaata enda (või kellegi teise) TipiCOINide saldot", - "daily": "Võta enda päevane TipiCOINi boonus", - "work": "Tööta ja teeni TipiCOINe (1h ooteaeg)", - "beg": "Kerja TipiCOINe (5min ooteaeg)", - "crime": "Proovi oma õnne kriminaalse tegevusega (2h ooteaeg)", - "rob": "Proovi kelleltki TipiCOINe varastada", - "heist": "Alusta grupirööv pangahoidlasse (min 2 mängijat, max 8, 4h serveri ooteaeg)", - "roulette": "Panusta TipiCOINe punasele, mustale või rohelisele (1/37 võimalus, 14x payout)", - "give": "Anna TipiCOINe teisele mängijale", - "leaderboard": "TipiBOTi edetabel - kes on kõige rikkam?", - "shop": "Sirvi TipiBOTi poodi", - "buy": "Osta ese TipiBOTi poodist", - "rps": "Kivi-paber-käärid mõne teise mängija vastu", - "slots": "Proovi oma õnne TipiBOTi mänguautomaadiga", - "request": "Kerja TipiCOINe teistelt mängijatelt - nagu crowdfunding, aga halvem", - "reminders": "Halda DM meeldetuletusi - kõik on vaikimisi sees, lülita need siin välja", - "cooldowns": "Vaata kõikide käskude ooteaegu", - "jailed": "Vaata, kes on praegu vanglas", - "rank": "Vaata oma EXP, taset ja edetabeli positsiooni", - "stats": "Vaata oma mängustatistikat", - "jailbreak": "Proovi vanglast põgeneda kasutades täringuid", - "adminseason": "[Admin] Lõpeta võistlus, teavita võitjaid ja lähtesta EXP", - "admincoins": "[Admin] Anna või võta TipiCOINe kasutajale/kasutajalt", - "adminjail": "[Admin] Saada kasutaja vangi", - "adminunjail": "[Admin] Vabasta kasutaja vangist", - "adminban": "[Admin] Keela kasutajal majandussüsteemis osaleda", - "adminunban": "[Admin] Eemalda majandussüsteemi keeld kasutajalt", - "adminreset": "[Admin] Lähtesta kasutaja majandusandmed", - "adminview": "[Admin] Vaata kasutaja majandusandmeid", - "adminexp": "[Admin] Anna v\u00f5i v\u00f5ta EXP kasutajalt", - "adminitem": "[Admin] Anna v\u00f5i eemalda ese kasutajalt (tasuta)", - "allowchannel": "[Admin] Lisa kanal, kus bot võib vastata käsklustele", - "denychannel": "[Admin] Eemalda kanal lubatud kanalite nimekirjast", - "channels": "[Admin] Näita lubatud kanalite nimekirja", - "economysetup": "[Admin] Loo ja sea korda majandussüsteemi rollid", - "blackjack": "Mängi blackjacki TipiBOTi vastu", - "prestige": "Prestiiži (nõuab taset 30) ja teeni Prestiižipunkte", - "prestigeshop": "Vaata prestiižipoodi ja sinu uuenduste taset", - "prestigebuy": "Osta prestiižiuuendus Prestiižipunktide eest", - "fish": "Mine kalastama (interaktiivne mäng, 2min ooteaeg)", - "fishbook": "Vaata oma kalakogu ja kogutud kalaliike", - "fishsell": "Müü kalu oma inventarist", - "patchnotes": "Vaata TipiBOTi viimaseid muudatusi ja uuendusi", - "quests": "Vaata oma päeva- ja nädalaülesandeid ning nõua auhinnad", -} - -# --------------------------------------------------------------------------- -# Option descriptions (shown next to each parameter in Discord) -# --------------------------------------------------------------------------- - -OPT: dict[str, str] = { - "admin_kasutaja": "Kasutaja", - "admin_põhjus": "Põhjus (saadetakse kasutajale DM kaudu)", - "admincoins_kogus": "Positiivne = anna, negatiivne = võta", - "adminjail_minutid": "Vangistamise kestus minutites", - "balance_kasutaja": "Mängija, kelle saldot vaadata (vaikimisi sina)", - "roulette_panus": "Panus TipiCOINides ('all' = kogu saldo)", - "roulette_värv": "Punane, must või roheline", - "give_kasutaja": "Kellele annad?", - "give_summa": "Kui palju annad? ('all' = kogu saldo)", - "buy_ese": "Eseme nimi (vaata /shop)", - "rps_panus": "Valikuline TipiCOINide panus ('all' = kogu saldo)", - "rps_vastane": "Väljakutse teisele mängijale (PvP)", - "slots_panus": "Panus TipiCOINides ('all' = kogu saldo)", - "request_summa": "Kui palju TipiCOINe vajad?", - "request_põhjus": "Miks sa vajad TipiCOINe?", - "request_sihtmärk": "Valikuline: kellelt täpselt palud (teised ei saa toetada)", - "send_kanal": "Kanal, kuhu sõnum saata", - "send_sõnum": "Sõnum, mida saata", - "allowchannel_kanal": "Kanal, kus bot võib vastata käsklustele", - "denychannel_kanal": "Kanal, kus bot ei või vastata käsklustele", - "rob_sihtmärk": "Kellelt röövid?", - "member_user": "Mängija, kelle infot tahad vaadata", - "rank_kasutaja": "Mängija, kelle taset tahad vaadata (vaikimisi sina)", - "stats_kasutaja": "Mängija, kelle statistikat tahad vaadata (vaikimisi sina)", - "adminseason_top_n": "Kui palju mängijaid võitis (vaikimisi 10)", - "blackjack_panus": "Panus TipiCOINides ('all' = kogu saldo)", - "prestigebuy_upgrade": "Uuenduse ID (vaata /prestigeshop)", - "fishbook_kasutaja": "Mängija, kelle kalakogu vaadata (vaikimisi sina)", - "profile_kasutaja": "Mängija, kelle profiili vaadata (vaikimisi sina)", - "adminexp_kogus": "Positiivne = anna, negatiivne = võta", - "adminitem_ese": "Eseme ID (kasutatav sisse, vaata /shop)", - "adminitem_tegevus": "'anna' või 'eemalda'", -} - -# --------------------------------------------------------------------------- -# /help categories -# --------------------------------------------------------------------------- - -HELP_CATEGORIES: dict[str, dict] = { - "üldine": { - "label": "🤖 Üldine", - "description": "Üldised käsklused", - "color": 0x57F287, - "fields": [ - ("/ping", "Vaata, kas bot on üleval"), - ("/status", "Näita boti staatust ja ressursside kasutust"), - ("/help", "Nimekiri kõikidest käskudest kategooriate kaupa"), - ("/birthdays", "Näita kõigi liikmete sünnipäevi kuu järgi"), - ], - }, - "tipibot": { - "label": "🪙 TipiBOT", - "description": "TipiCOIN majandus", - "color": 0xF4C430, - "fields": [ - ("/profile [@user]", "Saldo, tase, EXP progress, prestiiz - kõik ühes kohas. Nupud: Esemed · Statistika · Kalakogu."), - ("/cooldowns", "Vaata kõikide käskude ooteaegu. Näitab ka vangla ooteaega."), - ("/daily", "Võta enda päevane TipiCOINide boonus. 20h ooteaeg. Streak'i boonus: 3d=+50%, 7d=+100%, 14d=+200%."), - ("/work", "Tööta ja teeni TipiCOINe (1h ooteaeg)"), - ("/beg", "Kerja TipiCOINe (5min ooteaeg)"), - ("/crime", "Proovi oma õnne kriminaalse tegevusega. 60% edu, 40% trahv + 30min vanglas. 2h ooteaeg."), - ("/rob @user", "Proovi kelleltki TipiCOINe varastada. 45% edu. Ebaõnnestumisel saad trahvi."), - ("/heist", "Alusta grupiröövi pangahoidlasse. Min 2 mängijat, max 8. 5 min ühinemisaeg. Õnnestumisel jagatakse saak võrdselt - ebaõnnestumisel 1h 30min vangis + trahv. 4h serveri ooteaeg (ei ole isiklik)."), - ("/jailbreak", "Proovi vanglas olles täringuid visata, et duublit saada (3 katset). Duubli korral saad vabaks. Ebaõnnestumisel saad valida: maksa kautsjon (20-30% saldost, min 350 ⬡) või jää vanglasse kuni aja lõpuni."), - ("/give @user ", "Anna TipiCOINe teisele mängijale"), - ("/quests", "Vaata oma päeva- ja nädalaülesandeid ning nõua auhinnad (uueneb iga päev/nädal)."), - ("/leaderboard", "TipiBOTi edetabel - kes on kõige rikkam?"), - ("/shop", "Sirvi TipiBOTi poodi"), - ("/buy ", "Osta ese TipiBOTi poodist"), - ("/request [target]", "Saada crowdfundingu taotlus. Keegi saab 'Toeta' nuppu vajutades raha kanda (taotlus kehtib 5 minutit)."), - ("/reminders", "DM meeldetuletused on vaikimisi sees. Kasuta seda käsku, et lülitada sisse/välja, milliseid käsklusi meelde tuletada."), - ], - }, - "shop": { - "label": "🛍️ Pood", - "description": "TipiBOTi poe esemed ja nende efektid", - "color": 0xF4C430, - "fields": [ - (f"{E['TipiHIIR']} Mängurihiir - 500 ⬡", "Teeni töötades 50% rohkem TipiCOINe."), - (f"{E['TipiMATT']} XL hiirematt - 600 ⬡", "Kerjamise ooteaeg 5min → 3min."), - (f"{E['TipiKLAPID']} Kõrvaklapid - 1200 ⬡", "Päevase boonuse ooteaeg 20h → 18h."), - (f"{E['TipiPILET']} LAN pilet (2025) - 1200 ⬡", "Päevane boonus on duubeldatud."), - (f"{E['TipiVAC']} Anticheat - 750 ⬡", "Röövimine sinu vastu ebaõnnestub. Pärast 2 kasutust pead ostma uue."), - (f"{E['TipiBULL']} Red Bull - 800 ⬡", "30% tõenäosus, et teenid töötades 3x rohkem."), - (f"{E['TipiLAP']} Botikoobas - 1500 ⬡", "RTX 5090 jooksutab botte 24/7. Päevane boonus genereerib 5% intressi sinu saldo pealt."), - (f"{E['TipiLAUD']} Reguleeritav laud - 3500 ⬡ *(T2)*", "/work teenib 25% rohkem (stackib mängurihiirega)."), - (f"{E['TipiSERVER']} Jellyfin server - 4000 ⬡ *(T2)*", "Röövimise edu tõenäosus 45% → 60%."), - (f"{E['TipiMIC']} Mikrofon - 2800 ⬡ *(T2)*", "Teeni 30% rohkem eduka /crime puhul."), - (f"{E['TipiKLAVA']} Mehhaaniline klaviatuur - 1800 ⬡ *(T2)*", "/beg teenib 2x rohkem."), - (f"{E['TipiMONITOR']} Ultralai monitor - 2500 ⬡ *(T2)*", "/work ooteaeg: 1h → 40min."), - (f"{E['TipiCAT']} CAT6 netikaabel - 3500 ⬡ *(T2)*", "/crime edu tõenäosus tõuseb 60% → 75%."), - (f"{E['TipiMONITOR2']} 360hz monitor - 7500 ⬡ *(T3)*", "Mänguautomaadi jackpot 10x → 15x, kolmik 4x → 6x."), - (f"{E['TipiKARIKAS']} TipiLANi trofee - 6000 ⬡ *(T3)*", "Streak ei nulli, kui sa mõne päeva vahele jätad."), - (f"{E['TipiTOOL']} Mänguritool - 9000 ⬡ *(T3)*", "/crime ebaõnnestumine ei saada sind vanglasse."), - ], - }, - "games": { - "label": "🎮 Mängud", - "description": "Lõbusad mängud", - "color": 0x5865F2, - "fields": [ - ("/roulette ", "Panusta TipiCOINe punasele, mustale või rohelisele (1/37 võimalus, 14x payout)"), - ("/rps [bet] [opponent]", "Kivi-paber-käärid mõne teise mängija vastu"), - ("/slots ", "Proovi oma õnne TipiBOTi mänguautomaadiga"), - ("/blackjack ", "Mängi blackjacki TipiBOTi vastu. Blackjack maksab 3:2. Kakskordistamine (double down) on võimalik vaid esimese käigu ajal."), - ], - }, - "admin": { - "label": "🔧 Admin", - "description": "Admin käsklused (peidetud tavaliste kasutajate eest)", - "color": 0xED4245, - "fields": [ - ("/check", "Laadi andmed, täida ID'd ja sünkroniseeri kõik liikmed"), - ("/member @user", "Näita liikme andmeid tabelist"), - ("/sync", "Sünkroniseeri käsklused Discordi serveriga"), - ("/restart", "Tee taaskäivitus botile"), - ("/send #channel message", "Saada sõnum valitud kanalisse"), - ("/admincoins @user ", "Anna või võta TipiCOINe kasutajale/kasutajalt"), - ("/adminjail @user ", "Saada kasutaja vangi"), - ("/adminunjail @user", "Vabasta kasutaja vangist"), - ("/adminban @user ", "Keela kasutajal majandussüsteemis osaleda"), - ("/adminunban @user", "Eemalda majandussüsteemi keeld kasutajalt"), - ("/adminreset @user ", "Lähtesta kasutaja majandusandmed"), - ("/adminview @user", "Vaata kasutaja majandusandmeid"), - ("/allowchannel #channel", "Lisa kanal, kus bot võib vastata käsklustele"), - ("/denychannel #channel", "Eemalda kanal lubatud kanalite nimekirjast"), - ("/channels", "Näita lubatud kanalite nimekirja"), - ("/adminseason [top_n]", "Lõpeta võistlus, teavita võitjaid ja lähtesta EXP"), - ("/economysetup", "Loo ja sea korda majandussüsteemi rollid (ECONOMY + taseme rollid) boti rolli alla"), - ], - }, -} - -# --------------------------------------------------------------------------- -# Repeated system messages -# --------------------------------------------------------------------------- - -MSG_BANNED = "🚫 Sul keelati TipiBOTi majandussüsteemis osaleda." -MSG_SPAM_JAIL = "⚠️ Liiga kiire! Automaatsed skriptid/spam on keelatud. Oled **30 minutit vangis**. Kasuta `/jailbreak`, et varem välja pääseda." -MSG_PONG = "🏓 Pong!" -MSG_RESTART_DONE = "✅ Bot on taaskäivitatud!" -MSG_RESTARTING = "🔄 Taaskäivitan..." -MSG_SHUTTING_DOWN = "⛔ Lülitan boti välja..." -MSG_PAUSED = "⏸️ Bot on hooldusrežiimis - kõik käsklused on peatatud." -MSG_UNPAUSED = "▶️ Hooldusrežiim lõpetatud - käsklused on taas saadaval." -MSG_MAINTENANCE = "🔧 Bot on hetkel hoolduses. Proovi mõne hetke pärast uuesti." -MSG_SYNC_DONE = "✅ Käsud sünkroniseeritud!" -MSG_REMINDER = "⏰ **/{cmd}** on taas kasutamiseks valmis!\n-# Meeldetuletuste haldamiseks kasuta serveris `/reminders`." -MSG_LEVELUP = "⬆️ **{name}** jõudis **{level}. tasemele**!{extra}" -MSG_LEVELUP_ROLE = " 🎊 Uus tiitel: **{role}**!" - -# --------------------------------------------------------------------------- -# /reminders dropdown options (cmd_key, label, description) -# --------------------------------------------------------------------------- - -REMINDER_OPTS: list[tuple[str, str, str]] = [ - ("daily", "📅 /daily", "Päevane boonus (20t ooteaeg)"), - ("work", "💼 /work", "Töö (1t ooteaeg, 40min monitoriga)"), - ("beg", "🙏 /beg", "Kerjamine (5min ooteaeg)"), - ("crime", "🦹 /crime", "Kuritegu (2t ooteaeg)"), - ("rob", "🔫 /rob", "Rööv (2t ooteaeg)"), - ("fish", "🎣 /fish", "Kalapüük (2min ooteaeg)"), -] - -# --------------------------------------------------------------------------- -# /slots outcome strings (title, colour) -# --------------------------------------------------------------------------- - -SLOTS_TIERS: dict[str, tuple[str, int]] = { - "jackpot": (f"{E['TipiFIRE']} JACKPOT!!!", 0xF4C430), - "triple": ("🎰 Kolmik!", 0x57F287), - "pair": ("🎰 Paar", 0x99AAB5), - "miss": (f"{E['TipICRY']} Ei õnnestunud", 0xED4245), -} - -# --------------------------------------------------------------------------- -# /roulette outcome strings -# --------------------------------------------------------------------------- - -ROULETTE: dict = { - "emoji": {"punane": "🔴", "must": "⚫", "roheline": "🟢"}, - "genitive": {"punane": "punase", "must": "musta", "roheline": "rohelise"}, - "win_title": "{emoji} Võitsid!", - "lose_title": "{emoji} Kaotasid!", - "win_desc": "Ratas peatus **{genitive}** peal!{mult}\n+{change}\nSaldo: {balance}", - "lose_desc": "Ratas peatus **{genitive}** peal.\n-{change}\nSaldo: {balance}", - "spin_title": "🎰 Ratas keerleb...", - "spin_stop": "🎰 Ratas peatub...", - "spin_strip": "{s0} {s1} {s2} {s3} {s4}", -} - -# --------------------------------------------------------------------------- -# /heist narrative story lines -# Placeholders: {leader}, {member}, {names}, {vehicle} -# --------------------------------------------------------------------------- - -HEIST_STORY: dict = { - "vehicles": [ - "Škoda", - "BMW", - "Lada", - "Mazda", - ], - "arrival": [ - "{leader} keerab nurga taga {vehicle} mootori kinni. Maskid ette. Keegi ei räägi.", - "{vehicle} peatub ühe kvartali kaugusel sihtmärgist. {leader}: *\"Pank on seal. Tegutseme plaani järgi.\"*", - "Meeskond astub {vehicle}st välja. {leader} kuulab kõrvamonitori. *\"Kaks valvurit, üks pimeala. Liigume nüüd.\"*", - "{leader} jälgib {vehicle}st sissepääsu. *\"Valvurite vahetus 40 sekundi pärast. See on meie ajaaken.\"*", - "Kell 3 öösel. Tänav on tühi. {vehicle} seisab väljas tühikäigul. {leader} tõmbab maski ette.", - "{vehicle} veereb aeglaselt vaiksesse pimedasse vahetänavasse. {leader}: *\"Viimane kontroll. Kõik valmis?\"*", - "{leader} koputab armatuurlauale. *\"Kui midagi läheb valesti, me lahkume kohe.\"* Vaikus vastuseks.", - "Tuul sahiseb mööda tühja tänavat. {vehicle} uksed avanevad korraga.", - "{member} kontrollib relva. {leader} vaatab kella. *\"Me oleme graafikus.\"*", - "{vehicle} tuled kustuvad. Linn jääb vaikseks. Nad liiguvad.", - ], - "entry_sneaky": [ - "{member} tõmbab kloonitud kaarti külgukse juures. Lukk klõpsab hääleta lahti.", - "Meeskond libiseb sisse laadimisestakaadi kaudu, riietatud öisteks koristajateks.", - "{leader} on kaks nädalat valvurite graafikut pähe õppinud. Röövlid kõnnivad sisse vahetuse ajal.", - "Võltsitud alltöövõtja kaardi abil saavad nad fuajeest läbi ilma lisaküsimuseta.", - "{member} lülitab välikaamerad sülearvutist välja. {leader} kõnnib sisse, nagu see oleks tema oma maja.", - "{member} kasutab signaaliblokeerijat. Häired ei jõua kunagi süsteemi.", - "{leader} avab ventilatsiooniluugi. *\"Läheme ülevalt.\"*", - "Turvamees haigutab. Sekund hiljem on ta seotud ja vaikselt nurka lohistatud.", - "{member} süstib lukku mikrokaamera. Mehhanism kaardistatakse sekunditega.", - ], - "entry_loud": [ - "{leader} lööb esiuksed lahti. *\"KÕIK PÕRANDALE - KOHE!\"*", - "Esmalt suitsugranaadid. Selleks ajaks, kui suits vaibub, on meeskond juba sees.", - "{leader} tulistab ühe lasu lakke. Haudvaikus. *\"Oleme siin seifi pärast! Kui teete koostööd, siis pääsete elusana.\"*", - "*\"Kui keegi ei liigu, ei saa keegi ka viga.\"* {leader} omab ruumi täielikku tähelepanu.", - "{member} lükkab kilbist elektri välja. Pimeduses juhib {leader} meeskonna mälu järgi edasi.", - "*\"See on rööv! Kõik pikali!\"* {leader} hääl kajab läbi saali.", - "Alarm hakkab ulguma juba enne, kui nad täielikult sisse jõuavad.", - "Klaas puruneb. Inimesed karjuvad. Täielik kaos.", - ], - "inside": [ - "{names} liiguvad kiiresti läbi fuajee, sidudes turvamehi postide külge kinni.", - "{member} katab väljapääsud. {leader} suundub otse seifi poole.", - "Üks kassapidajatest proovib käivitada vaikset häiret, kuid {member} märkab ta nihelemist ja peatab ta hoiatuslasuga.", - "{leader} hoiab töötajad rahulikuna samal ajal, kui teised suunduvad alumisele korrusele.", - "Turvakaamerad on tsüklil. {names} on korrusel üksi.", - "{member} kontrollib kellaaega. *\"Me oleme 30 sekundit ees.\"*", - "{leader} annab käemärgi. Meeskond jaguneb ilma sõnadeta.", - "Koridor on tühi. Liiga tühi. {leader} peatub hetkeks.", - "{names} liiguvad trepist alla, sammud summutatud.", - "Üks uks on lukus. {member} avab selle sekundiga.", - ], - "vault": [ - "Neljanda taseme ajalukuga seif. {member} tõmbab puuri välja. *\"Anna mulle kolm minutit.\"*", - "{leader} vaatab seifi ust. *\"Dünamiit.\"* Keegi ei vaidle.", - "{member} ühendub seifi juhtpaneeliga. Vana tarkvara. Ülevõtmine võtab 90 sekundit.", - "Seifil on käsikombinatsiooni lukk. Hea, et {leader} veetis kuu aega juhatajaga, teenides tema usaldust.", - "{member} paigutab lõhkeained. Meeskond astub tagasi. Üks kontrollitud plahvatus.", - "{leader} teeb magnetlukule tühistuse. Nagu õpikust võetud. Mehhanism annab järgi.", - "{member} higistab. *\"See pole standardlukk... anna mulle aega.\"*", - "{leader} kuulab vastu seifi ust. *\"Sees on liikumisandur.\"*", - "{member} lõikab läbi metallkihi nagu võid.", - "Ajurünnak. {leader} meenutab skeemi ja leiab nõrga koha.", - "{member} ühendab juhtmed ümber. Säde. Vaikus. Lukk avaneb.", - ], - "vault_open": [ - "Uks avaneb. Kuhi-kuhja järel raha, põrandast laeni. Täpselt nagu plaanitud.", - "*\"...jackpot.\"* {leader} piilub seifi sisse. Meeskond seisab hetkeks vaikuses.", - "{member} hakkab kotte täis laduma. {leader} piilub juba väljapääsu poole.", - "Puhas. Kiire. {names} on seifis ja täidavad kotte enne, kui tolm settib.", - "Seif on lahti. {leader} võtab hinge. *\"Okei. Kottidesse ja liikuma.\"*", - "{leader} naeratab esimest korda. *\"See oli seda väärt.\"*", - "Raha lõhn täidab õhu. {member}: *\"Võtame kõik.\"*", - "{names} töötavad vaikides. Iga liigutus loeb.", - "Kotid täituvad kiiremini kui oodatud.", - "{leader} pilk muutub tõsiseks. *\"Aeg otsas. Liigume.\"*", - ], - "police_inbound": [ - "Raadio krõbiseb. *\"Kõik üksused, relvastatud rööv Keskpangas-\"*", - "Väljas on kuulda eemalt ulguvaid sireene. {leader}: *\"Meil on umbes neli minutit. Liikuma.\"*", - "Punased ja sinised tuled vilguvad ülemistest akendest läbi. Varualarm käivitati.", - "Politsei helikopter skaneerib piirkonda prožektoriga. Aken sulgub kiiresti.", - "{member} kontrollib politsei skännerit. *\"Nad teavad. Kolm üksust, kaks minutit eemal.\"*", - "{member} kuulab raadiosidet. *\"Nad sulgevad kvartaleid.\"*", - "Sireenid lähenevad kiiremini kui plaanitud.", - "Helikopteri valgus libiseb üle akna. Liiga lähedal.", - ], - "getaway_success": [ - "Adrenaliin. {names} jooksevad {vehicle} juurde. Kõik sees. {leader} keerab mootori käima.", - "{member} haarab roolist. {leader} on kõrval. *\"Lähme.\"* Rahulikult.", - "{leader} libistab {vehicle} kõrvalteed pidi minema. Sireen kaugel taga. Nad on kiiremad.", - "Rohelised tuled. {vehicle} sõidab vaikselt mööda parklas ootavast patrullautost. Keegi ei märka.", - "{member} näitab teed. {leader} sõidab vaikselt läbi tagakvartali. Käed lõdvad.", - "{vehicle} rehvid vilisevad, kui nad pööravad kitsasse tänavasse.", - "{leader} sõidab ilma tuledeta. Ainult mälu juhib teda.", - "{member} vaatab kaarti. *\"Vasak, siis kohe parem!\"*", - "Mootor möirgab. Nad kaovad öösse.", - "{vehicle} libiseb läbi viimase rohelise tule.", - ], - "getaway_fail": [ - "{names} jooksevad {vehicle} juurde. Sireenid igalt poolt.", - "{member} haarab roolist. {leader} on kõrval. *\"Mine! MINE!\"*", - "{vehicle} kihutab tänavale, kuid helikopteri valgusvihk osutab neile. Kõik on nähtaval.", - "Kolm patrullautot jõuavad nende taha. {member} vaatab üle õla. *\"Nad on meil kannul.\"*", - "Raadio krõbiseb. *\"Sihtmärk kinnitatud. Blokeeri Liivalaia tänav.\"*", - "{vehicle} ei käivitu. {member}: *\"Päriselt ka või?!\"*", - "{member} komistab teel autoni. Tal oli pael lahti tulnud", - "{leader} avastab, et autot pole kuskil näha. See pukseeriti ära." - ], - "escape_success": [ - "{names} murravad läbi perimeetri enne väravate sulgemist. Puhas põgenemine.", - "{leader} oli planeerinud kolm väljumisteed. Vaja läks ühte. {vehicle} kaob linna.", - "Kahe kvartali kaugusel asuv peibutushäire tõmbab üksused eemale. {names} on kadunud enne, kui keegi seifi kontrollib.", - "Naelribad? Juba eemaldatud. Teeblokk? Vale tänav. {leader} mõtles kõigele.", - "{vehicle} sõidab maanteele nagu poleks midagi juhtunud. {leader} hingab esimest korda tunnis välja.", - "*\"Oleme vabad.\"* {member} piilub kardinate tagant välja. Tühi tänav. Nad tegid ära.", - "{names} kaovad sügavale linna nagu neid poleks kunagi olnud.", - "Raadio jääb vaikseks. Keegi ei jälita enam.", - "{vehicle} jäetakse maha. Uus plaan aktiveerub.", - "{leader}: *\"See oli liiga lihtne...\"*", - ], - "escape_fail": [ - "Patrullauto lõikab {vehicle} teekonna sillal ära. Mõlemalt poolt ümbritsetud. Ongi läbi.", - "{member} kukutab koti. Kolm sekundit kõhklust - ja uksed on ümber piiratud.", - "Helikopter jälgib neid kuni pelgupaigani. Kõik väljapääsud on kaetud.", - "{leader} arvutab võimalusi. *\"Väljapääsu pole.\"* Käed lähevad üles.", - "Naelribad lõhuvad {vehicle} rehvid. Meeskond libiseb liikluse keskele seisma.", - "{vehicle} põrkub vastu teetõket. Mootor sureb. Igast suunast tuled.", - ], -} - -# --------------------------------------------------------------------------- -# /heist UI strings -# --------------------------------------------------------------------------- - -HEIST_UI: dict[str, str] = { - "names_duo": "**{a}** ja **{b}**", - "names_sep": " & ", - "names_crew": "**{leader}** ja meeskond", - "btn_join": "Ühine röövimisega 🔫", - "btn_start": "Alusta kohe ▶", - "already_joined": "Sa oled juba sees!", - "only_organizer": "Ainult heisti algataja saab heisti alustada.", - "lobby_desc": "**Osalejad ({n}/{max}):**\n{names}\n\nÕnnestumise tõenäosus: **{chance}%**\n\n*Ühinemisaken sulgub *", - "cancel_desc": "Ei piisanud osalejaid (vajad vähemalt **{min}**). Heist tühistati.", - "started_title": "🔫 Grupirööv käib...", - "started_desc": "**{n}** osalejat alustasid heisti. Jälgi allpool!", - "story_title": "🔫 Grupirööv", - "win_desc": "**Osalejad:**\n{names}\n\nSaak jagati võrdselt.\n**Igaüks sai: +{payout}**", - "fail_desc": "**Osalejad:**\n{names}\n\nKõik osalejad saavad **1,5 tundi vangi** + trahv ~15% saldost.", -} - -# --------------------------------------------------------------------------- -# Embed titles -# --------------------------------------------------------------------------- - -TITLE: dict[str, str] = { - "daily": "📅 Päevane boonus", - "work": "💼 Töö", - "beg": "🙏 Kerjamine", - "crime_win": f"{E['TipiFIRE']} Kuritegu õnnestus!", - "crime_fail": f"{E['TipiTROLL']} Vahele jäid!", - "rob_win": f"{E['TipiFIRE']} Rööv õnnestus!", - "rob_fail": f"{E['TipiTROLL']} Rööv ebaõnnestus!", - "rob_anticheat": f"{E['TipiVAC']} Anticheat peatas sind!", - "jailbreak": "🎲 Vanglast põgenemine", - "jailbreak_free": f"🎲 {E['TipiFIRE']} DUUBEL! Oled vaba!", - "jailbreak_fail": f"{E['TipICRY']} Kolm katset läbi!", - "jailbreak_miss": "🎲 " + E["TipICRY"] + " Ei saanud duublit ({tries}/{max})", - "jailbreak_bail": "💸 Kautsjon", - "give": f"{E['TipiHEART']} TipiCOINi ülekanne", - "stats": "📊 Mängustatistika", - "leaderboard_coins": "🪙 TipiBOTi edetabel - Mündid", - "leaderboard_exp": "📊 TipiBOTi edetabel - EXP / Tase", - "leaderboard_season": "🏆 TipiBOTi edetabel - Hooaja EXP", - "leaderboard_prestige": f"{E['TipiFIRE']} TipiBOTi edetabel - Prestiiž", - "leaderboard_wagered": "🎲 TipiBOTi edetabel - Hasartmängud", - "leaderboard_fish": "🎣 TipiBOTi edetabel - Kalapüük", - "rps": "⚔️ Kivi, Paber, Käärid", - "rps_duel": "⚔️ KPK duell", - "rps_duel_active": "⚔️ KPK duell - käimas", - "rps_duel_done": "⚔️ KPK duell - lõppenud", - "rps_duel_cancel": "⚔️ KPK duell - tühistatud", - "rps_duel_expire": "⚔️ KPK duell - aegus", - "rps_duel_decline": "⚔️ KPK duell - keelduti", - "heist_lobby": "🔫 Grupirööv - kogunemine", - "heist_win": f"{E['TipiFIRE']} Grupirööv õnnestus!", - "heist_fail": f"{E['TipiSKULL']} Grupirööv ebaõnnestus!", - "heist_cancel": "🔫 Grupirööv tühistatud", - "request": f"{E['TipiHEART']} Rahataotlus", - "reminders": "⏰ Meeldetuletused", - "cooldowns": "⏱️ Sinu ooteajad", - "adminseason": "🏆 Hooaeg lõppes!", - "economysetup": "⚙️ Majanduse seadistamine", - "blackjack": "🃏 Blackjack", - "blackjack_bj": f"🃏 {E['TipiFIRE']} BLACKJACK!", - "blackjack_win": f"{E['TipiFIRE']} Võitsid!", - "blackjack_lose": f"{E['TipiSKULL']} Kaotasid!", - "blackjack_bust": f"{E['TipiSKULL']} Üle 21 - kaotasid!", - "blackjack_push": "🤝 Viik!", - "blackjack_dbust": f"{E['TipiSKULL']} Üle 21 - mõlemad kaotasid!", - "blackjack_dwin": f"{E['TipiFIRE']} Topeltpanus võitis!", - "prestige_confirm": "🔥 Prestiiž - kinnita", - "prestige_success": E["TipiFIRE"] + " Prestiiž {level} saavutatud!", - "prestige_too_low": "❌ Prestiiž pole saadaval", - "prestige_shop": f"{E['TipiFIRE']} Prestiižipood", - "prestige_buy_ok": "✅ Uuendus ostetud!", - "fish_cast": "🎣 Otsid kala...", - "fish_bite": "🐟 KALA NÄKKAB!", - "fish_escape": "🎣 Kala pääses!", - "fish_junk": "🗑️ Ai ai ai...", - "fishbook": "📖 Kalakogu", - "quests": "🎯 Ülesanded", -} - -# --------------------------------------------------------------------------- -# Quest system (/quests) -# --------------------------------------------------------------------------- - -QUEST_UI: dict[str, str] = { - "daily_header": "📅 Päevaülesanded", - "weekly_header": "📆 Nädalaülesanded", - "progress": "⏳ {progress}/{max}", - "ready": "✅ Valmis - nõua auhind!", - "completed": "🏆 Nõutud", - "reward": "🎁 {coins} ⬡ · {exp} EXP", - "empty": "Ühtegi ülesannet pole. Proovi hiljem uuesti!", - "claim_btn": "🎁 Nõua auhinnad", - "claimed_msg": "🏆 Nõudsid {count} ülesande auhinnad: +{coins} · +{exp} EXP!", - "nothing": "Sul pole ühtegi valmis ülesannet, mida nõuda.", - "error": "❌ Ülesannete laadimine ebaõnnestus. Proovi hiljem uuesti.", -} - -# Estonian one-line description per quest id (keys match economy.QUESTS_*). -QUEST_DESCRIPTIONS: dict[str, str] = { - # Daily - "work3": "Tööta 3 korda (/work)", - "beg5": "Kerja 5 korda (/beg)", - "wager500": "Panusta kokku 500 ⬡ hasartmängudes", - "fish2": "Püüa 2 kala (/fish)", - "crime1": "Soorita edukalt 1 kuritegu (/crime)", - "earn1000": "Teeni kokku 1 000 ⬡", - "give200": "Kingi teistele kokku 200 ⬡ (/give)", - # Weekly - "work20": "Tööta 20 korda (/work)", - "fish15": "Püüa 15 kala (/fish)", - "wager5000": "Panusta kokku 5 000 ⬡ hasartmängudes", - "crime5": "Soorita edukalt 5 kuritegu (/crime)", - "heist1": "Osale 1 grupiröövis (/heist)", - "earn10000": "Teeni kokku 10 000 ⬡", -} - -# --------------------------------------------------------------------------- -# Error / validation messages (use .format(**kwargs) for dynamic parts) -# --------------------------------------------------------------------------- - -ERR: dict[str, str] = { - "positive_bet": "❌ Panus peab olema positiivne.", - "positive_amount": "❌ Summa peab olema positiivne.", - "positive_duration": "❌ Aeg peab olema positiivne.", - "admincoins_zero": "Kogus ei tohi olla 0.", - "missing_perms": "❌ Sul on vaja **Rollide haldamise** õigust selle käsu kasutamiseks.", - "generic_error": "❌ Tekkis viga: ```{error}```", - "send_failed": "❌ Sõnumi saatmine ebaõnnestus: ```{error}```", - "rob_self": "❌ Sa ei saa iseennast röövida.", - "rob_bot": "❌ Botti ei saa röövida.", - "rob_no_house": "❌ Kassa pole veel avatud.", - "rob_house_blocked": "❌ Panga seif on liiga hästi kaitstud. Kasuta `/heist` selle rüüstamiseks.", - "rob_too_poor": "❌ **{name}** on liiga vaene röövimiseks.", - "rob_target_jailed": "❌ **{name}** on vanglas - vabad inimesed ei saa vanglas olevaid röövida.", - "heist_active": "❌ Serveris on juba aktiivne grupirööv käimas! Oota, kuni see lõpeb.", - "heist_full": "❌ Grupirööv on täis!", - "heist_min_players": "❌ Grupiröövi alustamiseks on vaja vähemalt **{min}** osalejat.", - "broke": E["TipICRY"] + " Sul pole piisavalt TipiCOINe. Saldo: {bal}", - "broke_need": E["TipICRY"] + " Sul pole piisavalt TipiCOINe. Vajad veel {need}.", - "item_owned": "❌ Sul on see ese juba olemas.", - "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.", - "not_your_game": "❌ See pole sinu mäng!", - "game_in_progress": "❌ Sul on juba mäng käimas! Lõpeta see enne.", - "not_your_challenge":"❌ See väljakutse pole sulle!", - "not_your_menu": "❌ See ei ole sinu menüü.", - "give_self": "❌ Sa ei saa iseendale TipiCOINe anda.", - "give_bot": "❌ Botile ei saa TipiCOINe anda.", - "give_jailed": "❌ Oled vangis - vanglas ei saa TipiCOINe anda. Pääsed välja {ts}.", - "rps_self": "❌ Sa ei saa iseendale väljakutset esitada.", - "rps_bot": "❌ Botid on KPK-is liiga head.", - "not_jailed": "❌ Sa pole praegu vangis.", - "not_in_leaderboard":"❌ Sind pole veel edetabelis.", - "admin_ban_bot": "❌ Botti ei saa bannida.", - "admin_reset_bot": "❌ Kassa andmeid ei saa lähtestada.", - "member_not_found": "❌ **{name}** ei leitud tabelist.", - "request_self_fund": "❌ Sa ei saa oma taotlust ise rahastada.", - "request_self": "❌ Sa ei saa iseendalt anuda.", - "request_bot": "❌ Botid on teatavasti kitsid.", - "request_targeted": "❌ See taotlus on suunatud kasutajale **{name}**.", - "already_in_game": "❌ Sul on juba aktiivne mäng käimas!", - "invalid_amount": "❌ Sisesta kehtiv summa või 'all'.", - "fund_range": "❌ Sisesta summa vahemikus 1-{max}.", - "channel_only": "❌ Boti käske saab kasutada ainult nendes kanalites: {channels}", - "guild_only": "Seda käsku saab kasutada ainult serveris.", - "sheet_error": "❌ Tabeli laadimine ebaõnnestus: ```{error}```", - "gamble_cooldown": "🎰 Oled just mänginud! Saad uuesti mängida {ts}.", -} - -# --------------------------------------------------------------------------- -# Cooldown messages (use .format(ts=...) - ts is a Discord timestamp string) -# --------------------------------------------------------------------------- - -CD_MSG: dict[str, str] = { - "daily": "⏳ Järgmine boonus {ts}.", - "work": "⏳ Saad töötada {ts}.", - "beg": "⏳ Saad kerjata {ts}.", - "crime": "⏳ Saad uuesti proovida {ts}.", - "rob": "⏳ Saad uuesti röövida {ts}.", - "heist": "⏳ Saad uuesti heisti teha {ts}.", - "heist_global": "⏳ Pangahoidla alles kosub eelmisest röövist. Järgmine heist võimalik {ts}.", - "jailed": E["TipiTROLL"] + " Oled vangis! Pääsed välja {ts}. Kasuta `/jailbreak`, et varem välja pääseda.", - "fish": "🎣 Saad uuesti kalastada {ts}.", -} - -# --------------------------------------------------------------------------- -# Shop UI strings -# --------------------------------------------------------------------------- - -SHOP_UI: dict[str, str] = { - "tier_1": "Tier 1 - Algaja", - "tier_2": "Tier 2 - Kogenud", - "tier_3": "Tier 3 - Legend", - "desc": "Saldo: {bal} · Osta käsuga `/buy`", - "owned": "✅ Olemas", - "owned_uses_1": "✅ Olemas ({uses} kasutus järel)", - "owned_uses_n": "✅ Olemas ({uses} kasutust järel)", - "locked": "🔒 Tase {min_lvl} nõutud *(sul on {user_lvl})*", -} - -# --------------------------------------------------------------------------- -# Blackjack in-game strings -# --------------------------------------------------------------------------- - -BJ: dict[str, str] = { - "dealing": "*Jagame kaardid...*", - "result_field": "Tulemus", - "push_result": "±0 (panus tagasi)", - "doubled_label": "💰 *Topeltpanus: {total}*", - "btn_hit": "🃏 Võta kaart", - "btn_stand": "✋ Seisa", - "btn_double": "💰 Kahekordista (+{bet}⬡)", - "btn_split": "✂️ Split (+{bet}⬡)", -} - -# --------------------------------------------------------------------------- -# Shop item descriptions (keyed by SHOP dict key in economy.py) -# --------------------------------------------------------------------------- - -ITEM_DESCRIPTIONS: dict[str, str] = { - "gaming_hiir": "Koolist varastatud hiir? Ei, see on mängurihiir. Teeni töötades 50% rohkem TipiCOINe.", - "hiirematt": "XXL suuruses, ainult parimast materjalist. Kerjamise ooteaeg 5min → 3min.", - "korvaklapid": "Noise-cancelling - kuuled ainult TipiCOINide kõlinat. Päevase boonuse ooteaeg 20h → 18h + 25⬡ boonust.", - "lan_pass": "Ametlik TipiLANi pilet (2025). Päevane boonus on duubeldatud.", - "energiajook": "Kolm Red Bulli järjest. 30% tõenäosus, et teenid töötades 3x rohkem.", - "gaming_laptop": "RTX 5090 jooksutab botte 24/7. Päevane boonus genereerib 5% intressi sinu saldo pealt.", - "anticheat": "VAC, EAC, Faceit AC ja BattlEye korraga. Röövimine sinu vastu ebaõnnestub. **2 kasutust**, siis pead ostma uue.", - "reguleeritav_laud": "Võid nii seista kui istuda - alati võidad. /work teenib 25% rohkem (stackib mängurihiirega).", - "jellyfin": "Self-hosted meediaserver - oled suurfirmadest sõltumatu. Röövimise edu 45% → 60%. Grupiröövi õnnestumisele +5%.", - "mikrofon": "Parem helikvaliteet teeb sind usutavamaks. Teeni 30% rohkem eduka /crime puhul.", - "klaviatuur": "Klõbinad kostuvad üle kogu saali. /beg teenib 2x rohkem.", - "monitor": "240Hz ja 27 tolli. /work ooteaeg: 1h → 40min.", - "cat6": "Gigabitine internet = ideaalne piraatluseks. /crime edu tõenäosus tõuseb 60% → 75%.", - "monitor_360": "360Hz, 1ms. Mänguautomaadi jackpot 10x → 15x, kolmik 4x → 6x. Hasartmängude ooteaeg 30s → 25s.", - "karikas": "Ainult legendidele. Streak ei nulli, kui sa mõne päeva vahele jätad.", - "gaming_tool": "Nii mugav, et isegi admin ei saa sind üles. /crime ebaõnnestumine ei saada sind vanglasse.", - "ussipurk": "Lakkumatu toiduga ussipurk - kalad ei saa vastu. Kalapyygi ooteaeg 2min → 90s.", - "kalavork": "Suurem võrk = suuremad kalad. Kõigi kalade haruldus tõuseb ühe astme võrra.", - "echolood": "Täpne ehholood näitab kala täpset asukohta. Haukamise aken 2s → 3s.", -} - -# --------------------------------------------------------------------------- -# /help UI -# --------------------------------------------------------------------------- - -HELP_UI: dict[str, str] = { - "footer": "TipiBOT • Vali kategooria allmenüüst", - "select_placeholder": "Vali kategooria...", -} - -JAILED_UI: dict[str, str] = { - "title": "🔒 Praegu vanglas", - "empty": "Kõik on vabad! Vanglas pole kedagi.", - "entry": "• {mention} - vabaneb ", - "footer": "{count} vang{plural}", -} - -REMINDERS_UI: dict[str, str] = { - "select_placeholder": "Vali käsud, millest soovid meeldetuletust...", - "saved_on": "✅ Meeldetuletused sisse lülitatud: {names}", - "saved_off": "🔕 Kõik meeldetuletused välja lülitatud.", - "desc_active": "Praegu aktiivne: {status}\n\nMuuda valikut allpool.", - "desc_none": "Hetkel pole ühtegi meeldetuletust sisse lülitatud.\n\nVali allpool, millest soovid DM-i saada.", - "footer": "Bot DM-ib sulle, kui valitud käsk on taas kasutamiseks valmis.", -} - -SHOP_BTN: dict[int, str] = { - 1: "Tier 1", - 2: "Tier 2", - 3: "Tier 3", -} - -# --------------------------------------------------------------------------- -# /send UI strings -# --------------------------------------------------------------------------- - -SEND_UI: dict[str, str] = { - "sent": "✅ Sõnum saadetud kanalisse {channel}!", - "forbidden": "❌ Mul pole õigust kanalisse {channel} kirjutada.", -} - -# --------------------------------------------------------------------------- -# /patchnotes UI strings -# --------------------------------------------------------------------------- - -PATCHNOTES_UI: dict[str, str] = { - "title": "📝 Muudatuste logi — {version}", - "footer": "Versioon {idx}/{total}", - "btn_newer": "◀ Uuem", - "btn_older": "Vanem ▶", - "select_placeholder": "Vali versioon…", - "empty_file": "ℹ️ Muudatuste logi on hetkel tühi.", - "empty_version": "_(selle versiooni kohta märkmeid pole)_", -} - -# --------------------------------------------------------------------------- -# /allowchannel /denychannel /channels UI strings -# --------------------------------------------------------------------------- - -MEMBER_UI: dict[str, str] = { - "title": "👤 {name}", - "age_field": "Vanus", - "age_val": "{age}a", -} - -MEMBER_FIELDS: list[tuple[str, str]] = [ - ("Nimi", "Nimi"), - ("Organisatsioon", "Organisatsioon"), - ("Valdkond", "Valdkond"), - ("Roll", "Roll"), - ("Sünnipäev", "Sünnipäev"), - ("Meil", "Meil"), - ("Telefon", "Telefon"), - ("Discord", "Discord"), - ("User ID", "Kasutaja ID"), - ("Discordis synced?", "Sünkroniseeritud"), - ("Groupi lisatud?", "Grupis"), -] - -ADMINVIEW_UI: dict[str, str] = { - "title": "🔍 {name} - majandusandmed", - "banned_yes": "🚫 JAH", - "banned_no": "✅ Ei", - "f_balance": "💰 Saldo", - "f_exp": "📊 EXP / Tase", - "f_streak": "🔥 Streak", - "f_banned": "🚫 Keelatud", - "f_jailed": "🚔 Vangis kuni", - "f_prestige": "🔥 Prestiiž", - "f_items": "🎒 Esemed", - "f_uses": "🔢 Kasutused", - "f_fish": "🎣 Kala", - "f_last_daily": "⏱️ Viimati daily", - "f_last_work": "⏱️ Viimati work", - "f_last_crime": "⏱️ Viimati crime", - "f_last_fish": "⏱️ Viimati fish", - "footer": "ID: {uid}", - "exp_val": "{exp} EXP (Tase {level})", - "prestige_val": "Prestiiž {level} · {pp} PP", - "fish_val": "{caught} püütud · {inv} inventaris", -} - -ECONOMYSETUP_UI: dict[str, str] = { - "created_field": "✅ Loodud", - "existing_field": "♻️ Juba olemas", - "footer": "Rollid on nüüd boti rolli all õiges järjekorras.", -} - -CHANNEL_UI: dict[str, str] = { - "already_allowed": "ℹ️ {channel} on juba lubatud kanalite nimekirjas.", - "added": "✅ {channel} lisatud. Bot vastab käskudele nüüd ainult lubatud kanalites.", - "not_in_list": "ℹ️ {channel} pole lubatud kanalite nimekirjas.", - "removed": "✅ {channel} eemaldatud lubatud kanalite nimekirjast.", - "removed_last": "✅ {channel} eemaldatud. Lubatud kanalite nimekiri on nüüd tühi - bot vastab kõikides kanalites.", - "list_title": "📋 Lubatud kanalid", - "list_empty": "Lubatud kanalite nimekiri on **tühi** - bot vastab käskudele kõikides kanalites.\n\nKasuta `/allowchannel`, et piirata kindlatele kanalitele.", - "list_filled": "Bot vastab käskudele ainult nendes kanalites:\n\n{lines}\n\n-# Kasuta `/allowchannel` / `/denychannel` nimekirja muutmiseks.", -} - -# --------------------------------------------------------------------------- -# /daily embed strings -# --------------------------------------------------------------------------- - -DAILY_UI: dict[str, str] = { - "earned": "✅ Said {earned}!", - "interest": E["TipiLAP"] + " Bot Farm tootis: +{interest}", - "vip": f"{E['TipiPILET']} LAN pileti boonus rakendus!", - "footer": "Streak: {streak_str} · Saldo: {balance}", -} - -# --------------------------------------------------------------------------- -# /stats embed strings -# --------------------------------------------------------------------------- - -STATS_UI: dict[str, str] = { - "economy_field": "💰 Majandus", - "economy_val": "Tipp-saldo: {peak}\nEluaegne tulu: {earned}\nEluaegne kaotus: {lost}", - "work_field": "🛠️ Töö & Kerja", - "work_val": "Töötanud: **{work}** korda\nKerjanud: **{beg}** korda", - "gamble_field": "🎲 Hasartmängud", - "gamble_val": "Panustatud kokku: {wagered}\nSuurim võit: {win}\nSuurim kaotus: {loss}\nSlotsi jackpotid: **{jackpots}** korda", - "crime_field": "🦹 Kuritegevus", - "crime_val": "Kuriteod: **{crimes}** ({succeeded} õnnestus)\nHeistid: **{heists}** ({heists_won} võideti)\nVangi sattunud: **{jailed}** korda\nKautsjon makstud: {bail}", - "social_field": "🤝 Sotsiaalne", - "social_val": "Kingitud: {given}\nSaadud: {received}", - "records_field": "🔥 Rekordid", - "records_val": "Pikim päevane streak: **{streak}** päeva", -} - -# --------------------------------------------------------------------------- -# /birthdays UI -# --------------------------------------------------------------------------- - -BIRTHDAY_UI: dict[str, str] = { - "no_entries": "Sellel kuul sünnipäevi ei ole.", - "today": "täna 🎉", - "tomorrow": "homme", - "in_days": "{days}p pärast", - "footer": "Leht {month}/12 · {month_name}", -} - -BIRTHDAY_MONTHS: list[str] = [ - "Jaanuar", "Veebruar", "Märts", "Aprill", "Mai", "Juuni", - "Juuli", "August", "September", "Oktoober", "November", "Detsember", -] - -# --------------------------------------------------------------------------- -# /check summary strings -# --------------------------------------------------------------------------- - -CHECK_UI: dict[str, str] = { - "sheet_stats_header": "📊 **Tabeli statistika** - {total} liiget", - "stat_ok": "✅ **{label}**: kõik täidetud", - "stat_warn": "⚠️ **{label}** puudub ({count}): {names}{more}", - "stat_more": " (+{count} veel)", - "stat_uid": "Kasutaja ID", - "stat_discord": "Discordi kasutajanimi", - "stat_bday": "Sünnipäev", - "no_name": "(no name)", - "done": "**Kontroll lõpetatud!**", - "already_ok": "✅ Juba korras: {count}", - "fixed": "🔧 Parandatud: {count}", - "not_found": "❓ Pole tabelis: {count}", - "bday_pings": "🎂 Sünnipäeva teavitused: {count}", - "errors": "⚠️ Vead: {count}", - "details_header": "**Üksikasjad:**", - "details_more": "... ja {count} rohkem", - "detail_error": "⚠️ {error}", - "detail_nickname": "hüüdnimi", - "detail_roles_added": "+rollid: {roles}", - "detail_changed": "🔧 **{name}**: {parts}", - "ids_filled": "\n🔑 Täideti **{count}** puuduvat kasutaja ID-d.", -} - -# --------------------------------------------------------------------------- -# /status UI -# --------------------------------------------------------------------------- - -STATUS_UI: dict[str, str] = { - "title": "🖥️ Boti olek", - "uptime_field": "🕐 Uptime", - "uptime_val": "{hours}t {minutes}m {seconds}s", - "latency_field": "📡 Latency", - "latency_val": "{ms} ms", - "ram_field": "🧠 RAM (RSS)", - "ram_val": "{mb} MB", - "cpu_field": "⚙️ CPU", - "cpu_val": "{percent}%", - "tasks_field": "🔄 Async tasks", - "eco_players_field": "👤 Eco players", - "members_cache_field": "📋 Liikmed (cache)", - "log_files_field": "📂 Log files", - "log_line": "`{name}` - {size_kb} KB", - "none": "-", -} - -# --------------------------------------------------------------------------- -# Admin command responses and DMs -# --------------------------------------------------------------------------- - -ADMIN: dict[str, str] = { - "coins_done": "{emoji} **{name}**: {verb} {coin} → saldo **{balance}**\n📝 Põhjus: {reason}", - "coins_dm": "{emoji} Admin muutis sinu TipiCOINide saldot: **{verb} {coin}**\n📝 Põhjus: *{reason}*\nUus saldo: **{balance} {coin}**", - "jail_done": "🚔 **{name}** on vangistatud {minutes} minutiks (vabaneb {ts}).\n📝 Põhjus: {reason}", - "jail_dm": "🚔 Admin saatis sind vanglasse **{minutes} minutiks**.\n📝 Põhjus: *{reason}*\nVabaneb {ts}.", - "unjail_done": "✅ **{name}** on vanglast vabastatud.", - "unjail_dm": "✅ Admin vabastas sind vanglast.", - "ban_done": "🚫 **{name}** keelati majandussüsteemis osaleda.\n📝 Põhjus: {reason}", - "ban_dm": "🚫 Sul keelati TipiBOTi majandussüsteemis osalemine.\n📝 Põhjus: *{reason}*", - "unban_done": "✅ **{name}** on majandussüsteemi osalemise keelust eemaldatud.", - "unban_dm": "✅ Sinu TipiBOTi majandussüsteemis osalemise keeld on tühistatud. Saad taas käske kasutada.", - "reset_done": "🗑️ **{name}** majandusandmed on lähtestatud.\n📝 Põhjus: {reason}", - "reset_dm": "🗑️ Admin lähtestas sinu TipiBOTi majandusandmed (saldo, esemed, streak).\n📝 Põhjus: *{reason}*", - "exp_done": "{emoji} **{name}**: {verb} EXP → kokku **{exp} EXP** (Tase {level}).\n📝 Põhjus: {reason}", - "exp_dm": "{emoji} Admin muutis sinu EXP-i: **{verb} EXP**\n📝 Põhjus: *{reason}*\nUus EXP: **{exp}** (Tase {level})", - "item_given": "✅ **{item}** antud kasutajale **{name}** (tasuta).", - "item_removed":"🗑️ **{item}** eemaldatud kasutajalt **{name}**.", - "item_invalid":"❌ Tundmatu ese: `{item_id}`. Kontrolli `/shop` eseme ID-d.", - "item_not_owned": "❌ **{name}** ei oma eset `{item_id}`.", - "item_dm_given": "✅ Admin andis sulle eseme: **{item}**.", - "item_dm_removed":"🗑️ Admin eemaldas sult eseme: **{item}**.", -} - -# --------------------------------------------------------------------------- -# /adminseason strings -# --------------------------------------------------------------------------- - -SEASON: dict[str, str] = { - "top_header": "**Top mängijad EXP järgi:**", - "no_players": "Keegi ei teeninud EXP-i.", - "entry": "{prefix} {name} - {exp} EXP *(Tase {level})*", - "footer": "Kõigi EXP, mündid ja esemed lähtestati. Uus hooaeg algab kohe!", - "done": "✅ Hooaeg lõpetatud - EXP, mündid ja esemed lähtestatud.", -} - -# --------------------------------------------------------------------------- -# /profile tabbed view -# --------------------------------------------------------------------------- - -PROFILE_UI: dict[str, str] = { - "btn_profile": "💰 Profiil", - "btn_items": "🎒 Esemed", - "btn_stats": "📊 Statistika", - "btn_fish": "🎣 Kalakogu", - "main_title": "💰 {name}", - "items_title": "🎒 {name} - Esemed", - "stats_title": "📊 {name} - Statistika", - "fish_title": "🎣 {name} - Kalakogu", - "items_empty": "Sul pole ühtegi eset.", - "f_balance": "💰 Saldo", - "f_level": "📊 Tase", - "f_streak": "🔥 Streak", - "f_prestige": "⭐ Prestiiz", - "f_jail": "🚔 Vangis kuni", - "f_progress": "→ Tase {next}", - "progress_bar": "`{bar}` {done}/{needed} EXP", - "level_val": "Tase {level} - {role}", - "prestige_val":"⭐ P{level} · {pp} PP", - "footer_t1": "Tase 10 avab T2 poe · Tase 20 avab T3 poe", - "footer_t2": "T2 pood avatud · Tase 20 avab T3 poe", - "footer_t3": "T2 ja T3 pood avatud", -} - -# --------------------------------------------------------------------------- -# /balance embed strings -# --------------------------------------------------------------------------- - -BALANCE_UI: dict[str, str] = { - "saldo": "Saldo", - "streak": "Päeva streak", - "streak_val": "🔥 {streak}p", - "jailed_until": "🚔 Vangis kuni", - "items": "Esemed", - "uses_one": " *({uses} kasutus järel)*", - "uses_many": " *({uses} kasutust järel)*", -} - -# --------------------------------------------------------------------------- -# /cooldowns embed strings -# --------------------------------------------------------------------------- - -COOLDOWNS_UI: dict[str, str] = { - "ready": "✅ Valmis", - "daily_line": "📅 **/daily** {status}{note}", - "work_line": "💼 **/work** {status}{note}", - "beg_line": "🙏 **/beg** {status}{note}", - "crime_line": "🦹 **/crime** {status}", - "rob_line": "🔫 **/rob** {status}", - "fish_line": "🎣 **/fish** {status}{note}", - "note_korvak": " *(kõrvaklapid: 18t)*", - "note_monitor": " *(monitor: 40min)*", - "note_hiirematt": " *(hiirematt: 3min)*", - "note_ussipurk": " *(ussipurk: 90s)*", - "jailed": "\n� **Vanglas** - vabaneb ", - "jail_expired": "\n🔓 Vangla lõppes", -} - -# --------------------------------------------------------------------------- -# /rank embed strings -# --------------------------------------------------------------------------- - -RANK_UI: dict[str, str] = { - "title": "📊 {name} - Tase {level}", - "field_title": "Tiitel", - "field_exp": "EXP", - "field_progress": "Progress → Tase {next}", - "progress_val": "`{bar}` {progress}/{needed} EXP", - "footer_t1": "Tase 10 avab T2 poe · Tase 20 avab T3 poe", - "footer_t2": "T2 pood avatud · Tase 20 avab T3 poe", - "footer_t3": "T2 ja T3 pood avatud", -} - -# --------------------------------------------------------------------------- -# /work embed strings -# --------------------------------------------------------------------------- - -WORK_UI: dict[str, str] = { - "desc": "Sa {job} ja teenisid {earned}!", - "redbull": f"\n{E['TipiBULL']} Red Bull aktiveerus - 3x boonus!", - "hiir": f"\n{E['TipiHIIR']} Mängurihiir: +50% palk", - "laud": f"\n{E['TipiLAUD']} Reguleeritav laud: +25% palk", - "balance": "\nSaldo: {balance}", -} - -# --------------------------------------------------------------------------- -# /beg embed strings -# --------------------------------------------------------------------------- - -BEG_UI: dict[str, str] = { - "desc": "Sa {text} ja said {earned}.", - "klaviatuur": f"{E['TipiKLAVA']} Mehhaaniline klaviatuur: 2x tulu", - "balance": "Saldo: {balance}", -} - -# --------------------------------------------------------------------------- -# /crime embed strings -# --------------------------------------------------------------------------- - -CRIME_UI: dict[str, str] = { - "win_desc": "Sa {text} ja teenisid {earned}!", - "fail_base": "Sa {text} ja said trahvi {fine}.", - "fail_jailed": "\n\ud83d\udd12 Oled vangis! P\u00e4\u00e4sed {ts}.", - "fail_shield": "\n\ud83d\udee1\ufe0f Gaming Tool hoidis sind vanglast!", - "mikrofon": f"\n{E['TipiMIC']} Mikrofon: +30% saak", - "cat6": f"\n{E['TipiCAT']} CAT6: 75% edu t\u00f5en\u00e4osus", - "balance": "\nSaldo: {balance}", -} - -# --------------------------------------------------------------------------- -# /rob embed strings -# --------------------------------------------------------------------------- - -ROB_UI: dict[str, str] = { - "jackpot_desc": "💥 **JACKPOT!** Murdsid TipiBOTi kassasse sisse ja varastasid {stolen}!\nSaldo: {balance}", - "win_desc": "Varastasid {stolen} kasutajalt **{name}**!\nSaldo: {balance}", - "anticheat_desc": "**{name}** kaitseb end Anticheati'ga - said trahvi {fine}.", - "anticheat_worn": "⚠️ Sinu **Anticheat** on kulunud! Osta uus `/buy` käsuga.", - "victim_dm": "💸 **{robber}** varastas sinult **{stolen}** münti!", - "fail_desc": "Jäid vahele! Trahv: {fine}.\nSaldo: {balance}", -} - -# --------------------------------------------------------------------------- -# /give embed strings -# --------------------------------------------------------------------------- - -GIVE_UI: dict[str, str] = { - "desc": "**{giver}** andis {amount} kasutajale **{receiver}**.", -} - -# --------------------------------------------------------------------------- -# /buy embed strings -# --------------------------------------------------------------------------- - -BUY_UI: dict[str, str] = { - "title": "{emoji} {name} ostetud!", - "desc": "{description}\nUus saldo: {balance}", -} - -# --------------------------------------------------------------------------- -# /jailbreak UI strings -# --------------------------------------------------------------------------- - -JAILBREAK_UI: dict[str, str] = { - "btn_roll": "🎲 Viska täringud ({try_}/{max})", - "rolling_desc": f"{E['TipiDICE']} *Täringud lendavad...*", - "free_desc": "{d1} {d2}\n\n✅ Viskasid duubli - pääsesid vanglast!", - "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 **(20–30% saldost, min 350 ⬡)** või jää vanglasse kuni aja lõpuni.", - "already_bail": "Oled juba täringuid visanud. Ainuke väljapääs on kautsjon.\n\n💰 **Kautsjon: {min} – {max}** (20–30% saldost)\nSaldo: {bal} Väljas: {ts}", - "already_broke": "Oled juba täringuid visanud. Sul pole piisavalt raha kautsjoni maksmiseks.\n\n💰 Kautsjoni miinimum: **{min}** - sul on ainult {bal}\nVäljas: {ts}", - "bail_btn": "💸 Maksa kautsjon", - "bail_broke_desc": "❌ Sul pole piisavalt raha (min {min}).\nJääd vanglasse kuni aja lõpuni! Saldo: {balance}", - "bail_paid_desc": "✅ Kautsjon makstud: **{fine}**\nOled vaba! Saldo: {balance}", - "bail_already_free": "✅ Oled juba vaba - kautsjonit ei võetud. Saldo: {balance}", - "fail_broke_desc": "{d1} {d2} - ei olnud duubel\n\n❌ Sul pole kautsjoni maksmiseks piisavalt raha (min 350 ⬡).\nJääd vanglasse kuni aja lõpuni! Saldo: {balance}", - "fail_bail_desc": "{d1} {d2} - ei olnud duubel\n\nKautsjon makstud: **{fine}**\nSaldo: {balance}", - "fail_bail_offer": "{d1} {d2} - ei olnud duubel\n\n💰 **Kautsjon: {min} - {max}** (20-30% saldost)\nSaldo: {bal}\n\nSaad maksta kautsjoni või jääda vanglasse kuni aja lõpuni.", -} - -# --------------------------------------------------------------------------- -# /leaderboard UI strings -# --------------------------------------------------------------------------- - -LEADERBOARD_UI: dict[str, str] = { - "house_entry": "🤖 {name} *(maja)* - {balance}", - "house_default_name": "TipiBOT", - "no_entries": "Keegi ei ole veel punkte teeninud.", - "footer": "Lehekülg {page}/{total} · {count} mängijat", - "btn_coins": "🪙 Mündid", - "btn_exp": "📊 EXP", - "btn_find_me": "📍 Mina", - "exp_entry": "{prefix} {name} - {exp} EXP *(Tase {level})*", - "unknown_user": "Kasutaja {uid}", - "btn_season": "🏆 Hooaeg", - "btn_prestige": "🔥 Prestiiž", - "btn_wagered": "🎲 Hasartmäng", - "btn_fish": "🎣 Kalapyyk", - "season_entry": "{prefix} {name} - {exp} EXP *(Prestiiž {prestige})*", - "prestige_entry": "{prefix} {name} - Prestiiž **{prestige}** · {pp} PP", - "wagered_entry": "{prefix} {name} - {wagered} panustatud", - "fish_entry": "{prefix} {name} - {caught} kala", -} - -# --------------------------------------------------------------------------- -# /slots additional UI strings (titles/footers per outcome) -# --------------------------------------------------------------------------- - -SLOTS_UI: dict[str, str] = { - "playing": "🎰 Mängimas...", - "jackpot_footer": E["TipiKARIKAS"] + " Kolm karikat! +{change}", - "triple_footer": "✅ Kolm ühesugust! +{change}", - "pair_footer": "Kaks ühesugust! +{change}", - "miss_footer": "-{amount}", - "balance_line": "\nSaldo: {balance}", -} - -# --------------------------------------------------------------------------- -# /rps UI strings -# --------------------------------------------------------------------------- - -RPS_UI: dict[str, str] = { - "vs_bot_desc": "Tee oma valik! ⬇️", - "vs_bot_bet": "\nPanus: {bet}", - "result_tie": "🤝 Viik!", - "result_win": "🎉 Sina võitsid!", - "result_lose": "🤖 Bot võitis!", - "result_desc": "Sina: {player_pick} {player_name}\nBot: {bot_pick} {bot_name}\n\n**{result}**{bet_line}", - "bet_win": "\n+{amount} · Saldo: {balance}", - "bet_lose": "\n-{amount} · Saldo: {balance}", - "bet_tie": "\nViik - panus tagasi · Saldo: {balance}", - "challenge_desc": "{challenger} kutsub välja {opponent}{bet}\n\n{opponent}, kas võtad vastu? ⬇️", - "challenge_bet": " · Panus: {bet}", - "challenge_footer": "Väljakutse aegub 60 sekundi pärast", - "duel_active_desc": "{a} vs {b}{bet}\n\nMõlemad mängijad valivad DM-is. ⏳", - "duel_active_bet": " · Panus: {bet}", - "duel_dm": "⚔️ **KPK vs {opponent}**{bet}\nTee oma valik! ⬇️", - "duel_dm_bet": "\nPanus: {bet}", - "duel_waiting": "Valisid {choice} **{name}**. Ootame vastase valikut... ⏳", - "duel_result_a": "**⚔️ KPK tulemus vs {opponent}**\nSinu valik: {pick_a} {name_a}\nVastase valik: {pick_b} {name_b}\n\n**{result}**{bet_line}\nSaldo: {balance}", - "duel_verdict_win": "🏆 **{name}** võitis!", - "duel_verdict_tie": "🤝 Viik!", - "duel_broke": "\n⚠️ Makse ebaõnnestus (ebapiisav saldo)", - "duel_expire_dm": "⏰ KPK duell aegus - keegi ei teinud valikut õigeaegselt.", - "duel_expire_desc": "{a} vs {b}\n\nMäng aegus - valik jäi tegemata.", - "duel_dm_fail": "Ei saanud DM saata: **{names}**. Kontrolli privaatsussätteid.", - "duel_decline": "**{name}** keeldus väljakutsest.", - "duel_no_answer": "**{name}** ei vastanud väljakutsele.", - "duel_insufficient": "{mention}-l pole piisavalt TipiCOINi panuseks.", - "duel_done_desc": "{a} {pick_a} vs {pick_b} {b}\n\n**{verdict}**\n\n{name_a}: {bal_a}\n{name_b}: {bal_b}", - "server_only": "Seda käsku saab kasutada ainult serveris.", - "btn_accept": "Võta vastu ✅", - "btn_decline": "Keeldu ❌", - "btn_rock": "🪨 Kivi", - "btn_paper": "📄 Paber", - "btn_scissors": "✂️ Käärid", -} - -RPS_CHOICES: dict[str, str] = { - "🪨": "Kivi", - "📄": "Paber", - "✂️": "Käärid", -} - -# --------------------------------------------------------------------------- -# /request UI strings -# --------------------------------------------------------------------------- - -REQUEST_UI: dict[str, str] = { - "modal_title": "Rahasta taotlust", - "modal_label": "Kui palju soovid panustada?", - "btn_fund": "Rahasta 💸", - "btn_funded": "Rahastatud ✅", - "btn_fund_remaining": "Rahasta 💸 ({remaining}⬡ jäänud)", - "funded_line": "✅ **{name}** panustas {amount}", - "funded_full": "\n🎯 Taotlus täielikult täidetud!", - "funded_partial": "\n💰 Jäänud: {remaining}", - "audience_all": "Avatud kõigile rahastajatele 🌍", - "audience_targeted": "Suunatud: **{name}**", - "desc": "**{requester}** palub {amount}\n\n📋 **Põhjus:** {reason}\n\n{audience}", - "footer": "Taotlus aegub 5 minuti pärast", -} - -BJ_UI: dict[str, str] = { - "dealer": "Dealer", - "player": "Sina", - "hand_n": "Käsi {n}", - "hand_active": "▶ **Käsi {n}**", - "hand_pending": "Käsi {n} *...*", - "bust": " 💥", - "balance_line": " · Saldo: {balance}", -} - -# --------------------------------------------------------------------------- -# Prestige system strings -# --------------------------------------------------------------------------- - -PRESTIGE_SHOP_NAMES: dict[str, str] = { - "coin_mult": "Mündiboost", - "exp_mult": "EXP-boost", - "daily_plus": "Päevabonus+", - "work_plus": "Töötaja+", -} - -PRESTIGE_SHOP_DESCRIPTIONS: dict[str, str] = { - "coin_mult": "Kõik TipiCOINide teenimisallikad (daily, töö, kerja, kala) teenivad +8% rohkem iga taseme kohta. Max 5 taset → +40%.", - "exp_mult": "Kõik EXP allikad teenivad +8% rohkem iga taseme kohta. Max 5 taset → +40%.", - "daily_plus": "Päevase boonuse alussumma tõuseb +20% iga taseme kohta. Max 3 taset → +60%.", - "work_plus": "/work teenib +20% rohkem iga taseme kohta. Max 3 taset → +60%.", -} - -PRESTIGE_UI: dict[str, str] = { - "confirm_desc": ( - "Oled tasemel **{level}** ({exp} EXP).\n\n" - "Prestiiži korral saad **{pp}** " + E["TipiFIRE"] + " ja kõik lähtestub:\n" - "• Saldo, EXP, esemed, ooteajad\n\n" - "**Kalakogu jääb alles!**\n\nKas oled kindel?" - ), - "btn_confirm": "🔥 Jah, prestiiži!", - "btn_cancel": "❌ Tühista", - "btn_tab_status": "⭐ Prestiiz", - "btn_tab_shop": "🛍️ Uuendused", - "success_desc": ( - "Said **{pp}** " + E["TipiFIRE"] + "\n" - "Prestiiži tase: **{level}**\n" - "Kogutud PP: **{total_pp}** " + E["TipiFIRE"] + "\n\n" - "*Kõik lähtestati. Alusta otsast!*" - ), - "too_low_desc": "Prestiiži jaoks vajad taset **{required}** (sul on tase {level}).", - "shop_desc": "Sul on **{pp}** " + E["TipiFIRE"] + " · Vajuta nuppu uuenduse ostmiseks", - "shop_maxed": "✅ Max", - "shop_level_fmt": "Tase {cur}/{max}", - "shop_cost_fmt": "{cost} " + E["TipiFIRE"], - "buy_success_desc":"**{name}** uuendatud tasemele **{new_level}/{max_level}**!\nPP alles: **{pp}** " + E["TipiFIRE"], - "buy_no_pp": E["TipICRY"] + " Sul pole piisavalt PP. Sul on **{have}**, vajad **{need}** " + E["TipiFIRE"] + ".", - "buy_maxed": "❌ See uuendus on juba maksimumtasemel.", - "buy_not_found": "❌ Sellist uuendust ei leitud. Vaata `/prestigeshop`.", - "rank_line": E["TipiFIRE"] + " Prestiiž **{level}** · {pp} PP", - "rank_season": "🏆 Hooaja EXP: **{exp}**", - "btn_buy_upgrade": "{emoji} {name} +1 ({cost} PP)", - "status_footer": "⭐ Prestiiž {level} · {pp} PP", -} - -# --------------------------------------------------------------------------- -# Fishing system strings -# --------------------------------------------------------------------------- - -FISH_NAMES: dict[str, str] = { - "sarj": "Särg", - "ahven": "Ahven", - "koger": "Koger", - "viidikas": "Viidikas", - "latikas": "Latikas", - "karpkala": "Karpkala", - "linask": "Linask", - "haug": "Haug", - "angerjas": "Angerjas", - "siig": "Siig", - "forell": "Forell", - "koha": "Koha", - "tougjas": "Tõugjas", - "lohe": "Lõhe", - "vimb": "Vimb", -} - -FISH_RARITY_NAMES: dict[str, str] = { - "common": "Tavaline", - "uncommon": "Ebatavaline", - "rare": "Haruldane", - "epic": "Eepiline", - "legendary": "Legendaarne", -} - -FISH_RARITY_EMOJI: dict[str, str] = { - "common": "🐟", - "uncommon": "🐠", - "rare": "🎣", - "epic": "⭐", - "legendary": "🌟", -} - -FISH_JUNK_LINES: list[str] = [ - "Sa saad... **vana saabas**. Klassika.", - "Õnnitlused, leidsid **kasutatud autorehvi**. Keskkond tänab sind... mitte.", - "Taas üks **klaaspudel** rohkem jões.", - "**Vana poes käimise kott**! Hoidis aega hästi.", - "**Roostes konserv** - ilma sildita. Parem mitte teada, mis sees on.", - "**Ummistunud drenaažitoru**. Keegi oli hoolimatu.", - "**Tühi rahakott**. Kellegi päev läks halvemaks kui sinu oma.", - "**Vana CD-plaat** - Evanescence, 2003. Heas seisukorras.", - "Sa said **kivikese**. Ilus kivikene. Aga siiski kivikene.", - "**Kaotsi läinud droon**. GPS ei tööta, aku tühi.", -] - -FISH_UI: dict[str, str] = { - "btn_wait": "🎣 Oota näkkamist...", - "btn_bite": "🐟 TÕMBA!", - "btn_sell": "💰 Müü", - "btn_keep": "🎒 Hoia", - "cast_desc": "Viskad õnge vette. Oota, kuni kala näkkab...\n\n-# Vajuta nuppu, kui kala näkkab!", - "bite_desc": "**KALA NÄKKAB!** Tõmba kiiresti! ⚡\n\n-# Sul on 2 sekundit!", - "escape_desc": "Liiga hilja - kala lipsas minema. Proovi järgmine kord kiiremini!", - "junk_desc": "{text}\n\n-# Saldo: {balance}", - "catch_desc": "**{name}** · {weight}g · +{exp} EXP\n-# Kas müüd kohe ({value}) või hoiad inventaris?", - "catch_sold": "**{name}** · {weight}g\n\n+{coins} · +{exp} EXP\nSaldo: {balance}", - "catch_kept": "**{name}** · {weight}g lisatud inventarisse. *(+{exp} EXP)*", - "new_fish": "\n✨ **Uus kala kalakogusse lisatud!**", - "too_early": "❌ Kala pole veel näkkanud! Oota...", - "book_caught": "Püütud kalaliike: **{caught}/{total}**", - "book_yes": "✅ {emoji} **{name}** *({rarity})* · {count}×{inv}", - "book_inv": " *(inventaris: {n})*", - "book_no": "❓ **???** *({rarity})*", - "book_footer": "Lehekülg {page}/{total_pages} · {caught}/{total} liiki", - "book_empty": "Sa pole veel ühtegi kala püüdnud! Kasuta `/fish`.", - "inv_empty": "Sinu kalainventaar on tühi! Kasuta `/fish` kala püüdmiseks.", - "inv_header": "Sul on **{count}** kala inventaris *(kokku väärt {total_value})*", - "inv_entry": "{emoji} **{name}** · {weight}g · {value}", - "inv_sold_all": "Müüsid **{count}** kala kokku {coins} eest!\nSaldo: {balance}", - "inv_none": "Inventaaris pole midagi müüa.", -} diff --git a/strings/__init__.py b/strings/__init__.py new file mode 100644 index 0000000..5f34e6c --- /dev/null +++ b/strings/__init__.py @@ -0,0 +1,186 @@ +"""All user-facing text for TipiLAN Bot. + +Strings live in domain submodules (common, commands, member, economy, admin, +games, fishing) and are re-exported here, so ``import strings`` and +``strings.NAME`` keep working unchanged. Edit the relevant submodule to change +any message, description, or flavour text without touching any logic code.""" + +from .common import ( + MSG_BANNED, + MSG_SPAM_JAIL, + MSG_PONG, + MSG_RESTART_DONE, + MSG_RESTARTING, + MSG_SHUTTING_DOWN, + MSG_PAUSED, + MSG_UNPAUSED, + MSG_MAINTENANCE, + MSG_SYNC_DONE, + MSG_REMINDER, + MSG_LEVELUP, + MSG_LEVELUP_ROLE, + REMINDER_OPTS, + TITLE, + ERR, + CD_MSG, + REMINDERS_UI, + SEND_UI, + PATCHNOTES_UI, + STATUS_UI, +) + +from .commands import ( + CMD, + OPT, + HELP_CATEGORIES, + HELP_UI, +) + +from .member import ( + MEMBER_UI, + MEMBER_FIELDS, + ECONOMYSETUP_UI, + CHANNEL_UI, + BIRTHDAY_UI, + BIRTHDAY_MONTHS, + CHECK_UI, +) + +from .economy import ( + WORK_JOBS, + BEG_LINES, + BEG_JAIL_LINES, + CRIME_WIN, + CRIME_LOSE, + QUEST_UI, + QUEST_DESCRIPTIONS, + SHOP_UI, + ITEM_DESCRIPTIONS, + JAILED_UI, + SHOP_BTN, + DAILY_UI, + STATS_UI, + PROFILE_UI, + BALANCE_UI, + COOLDOWNS_UI, + RANK_UI, + WORK_UI, + BEG_UI, + CRIME_UI, + ROB_UI, + GIVE_UI, + BUY_UI, + LEADERBOARD_UI, + REQUEST_UI, +) + +from .admin import ( + ADMINVIEW_UI, + ADMIN, + SEASON, + PRESTIGE_SHOP_NAMES, + PRESTIGE_SHOP_DESCRIPTIONS, + PRESTIGE_UI, +) + +from .games import ( + SLOTS_TIERS, + ROULETTE, + HEIST_STORY, + HEIST_UI, + BJ, + JAILBREAK_UI, + SLOTS_UI, + RPS_UI, + RPS_CHOICES, + BJ_UI, +) + +from .fishing import ( + FISH_NAMES, + FISH_RARITY_NAMES, + FISH_RARITY_EMOJI, + FISH_JUNK_LINES, + FISH_UI, +) + +__all__ = [ + 'MSG_BANNED', + 'MSG_SPAM_JAIL', + 'MSG_PONG', + 'MSG_RESTART_DONE', + 'MSG_RESTARTING', + 'MSG_SHUTTING_DOWN', + 'MSG_PAUSED', + 'MSG_UNPAUSED', + 'MSG_MAINTENANCE', + 'MSG_SYNC_DONE', + 'MSG_REMINDER', + 'MSG_LEVELUP', + 'MSG_LEVELUP_ROLE', + 'REMINDER_OPTS', + 'TITLE', + 'ERR', + 'CD_MSG', + 'REMINDERS_UI', + 'SEND_UI', + 'PATCHNOTES_UI', + 'STATUS_UI', + 'CMD', + 'OPT', + 'HELP_CATEGORIES', + 'HELP_UI', + 'MEMBER_UI', + 'MEMBER_FIELDS', + 'ECONOMYSETUP_UI', + 'CHANNEL_UI', + 'BIRTHDAY_UI', + 'BIRTHDAY_MONTHS', + 'CHECK_UI', + 'WORK_JOBS', + 'BEG_LINES', + 'BEG_JAIL_LINES', + 'CRIME_WIN', + 'CRIME_LOSE', + 'QUEST_UI', + 'QUEST_DESCRIPTIONS', + 'SHOP_UI', + 'ITEM_DESCRIPTIONS', + 'JAILED_UI', + 'SHOP_BTN', + 'DAILY_UI', + 'STATS_UI', + 'PROFILE_UI', + 'BALANCE_UI', + 'COOLDOWNS_UI', + 'RANK_UI', + 'WORK_UI', + 'BEG_UI', + 'CRIME_UI', + 'ROB_UI', + 'GIVE_UI', + 'BUY_UI', + 'LEADERBOARD_UI', + 'REQUEST_UI', + 'ADMINVIEW_UI', + 'ADMIN', + 'SEASON', + 'PRESTIGE_SHOP_NAMES', + 'PRESTIGE_SHOP_DESCRIPTIONS', + 'PRESTIGE_UI', + 'SLOTS_TIERS', + 'ROULETTE', + 'HEIST_STORY', + 'HEIST_UI', + 'BJ', + 'JAILBREAK_UI', + 'SLOTS_UI', + 'RPS_UI', + 'RPS_CHOICES', + 'BJ_UI', + 'FISH_NAMES', + 'FISH_RARITY_NAMES', + 'FISH_RARITY_EMOJI', + 'FISH_JUNK_LINES', + 'FISH_UI', +] diff --git a/strings/admin.py b/strings/admin.py new file mode 100644 index 0000000..7dd90f5 --- /dev/null +++ b/strings/admin.py @@ -0,0 +1,125 @@ +"""Economy admin responses, season reset, and prestige system. + +Auto-split from the original strings.py; edit strings here. +""" + +from core.emoji import EMOJI as E + +__all__ = [ + 'ADMINVIEW_UI', + 'ADMIN', + 'SEASON', + 'PRESTIGE_SHOP_NAMES', + 'PRESTIGE_SHOP_DESCRIPTIONS', + 'PRESTIGE_UI', +] + +ADMINVIEW_UI: dict[str, str] = { + "title": "🔍 {name} - majandusandmed", + "banned_yes": "🚫 JAH", + "banned_no": "✅ Ei", + "f_balance": "💰 Saldo", + "f_exp": "📊 EXP / Tase", + "f_streak": "🔥 Streak", + "f_banned": "🚫 Keelatud", + "f_jailed": "🚔 Vangis kuni", + "f_prestige": "🔥 Prestiiž", + "f_items": "🎒 Esemed", + "f_uses": "🔢 Kasutused", + "f_fish": "🎣 Kala", + "f_last_daily": "⏱️ Viimati daily", + "f_last_work": "⏱️ Viimati work", + "f_last_crime": "⏱️ Viimati crime", + "f_last_fish": "⏱️ Viimati fish", + "footer": "ID: {uid}", + "exp_val": "{exp} EXP (Tase {level})", + "prestige_val": "Prestiiž {level} · {pp} PP", + "fish_val": "{caught} püütud · {inv} inventaris", +} + +# --------------------------------------------------------------------------- +# Admin command responses and DMs +# --------------------------------------------------------------------------- + +ADMIN: dict[str, str] = { + "coins_done": "{emoji} **{name}**: {verb} {coin} → saldo **{balance}**\n📝 Põhjus: {reason}", + "coins_dm": "{emoji} Admin muutis sinu TipiCOINide saldot: **{verb} {coin}**\n📝 Põhjus: *{reason}*\nUus saldo: **{balance} {coin}**", + "jail_done": "🚔 **{name}** on vangistatud {minutes} minutiks (vabaneb {ts}).\n📝 Põhjus: {reason}", + "jail_dm": "🚔 Admin saatis sind vanglasse **{minutes} minutiks**.\n📝 Põhjus: *{reason}*\nVabaneb {ts}.", + "unjail_done": "✅ **{name}** on vanglast vabastatud.", + "unjail_dm": "✅ Admin vabastas sind vanglast.", + "ban_done": "🚫 **{name}** keelati majandussüsteemis osaleda.\n📝 Põhjus: {reason}", + "ban_dm": "🚫 Sul keelati TipiBOTi majandussüsteemis osalemine.\n📝 Põhjus: *{reason}*", + "unban_done": "✅ **{name}** on majandussüsteemi osalemise keelust eemaldatud.", + "unban_dm": "✅ Sinu TipiBOTi majandussüsteemis osalemise keeld on tühistatud. Saad taas käske kasutada.", + "reset_done": "🗑️ **{name}** majandusandmed on lähtestatud.\n📝 Põhjus: {reason}", + "reset_dm": "🗑️ Admin lähtestas sinu TipiBOTi majandusandmed (saldo, esemed, streak).\n📝 Põhjus: *{reason}*", + "exp_done": "{emoji} **{name}**: {verb} EXP → kokku **{exp} EXP** (Tase {level}).\n📝 Põhjus: {reason}", + "exp_dm": "{emoji} Admin muutis sinu EXP-i: **{verb} EXP**\n📝 Põhjus: *{reason}*\nUus EXP: **{exp}** (Tase {level})", + "item_given": "✅ **{item}** antud kasutajale **{name}** (tasuta).", + "item_removed":"🗑️ **{item}** eemaldatud kasutajalt **{name}**.", + "item_invalid":"❌ Tundmatu ese: `{item_id}`. Kontrolli `/shop` eseme ID-d.", + "item_not_owned": "❌ **{name}** ei oma eset `{item_id}`.", + "item_dm_given": "✅ Admin andis sulle eseme: **{item}**.", + "item_dm_removed":"🗑️ Admin eemaldas sult eseme: **{item}**.", +} + +# --------------------------------------------------------------------------- +# /adminseason strings +# --------------------------------------------------------------------------- + +SEASON: dict[str, str] = { + "top_header": "**Top mängijad EXP järgi:**", + "no_players": "Keegi ei teeninud EXP-i.", + "entry": "{prefix} {name} - {exp} EXP *(Tase {level})*", + "footer": "Kõigi EXP, mündid ja esemed lähtestati. Uus hooaeg algab kohe!", + "done": "✅ Hooaeg lõpetatud - EXP, mündid ja esemed lähtestatud.", +} + +# --------------------------------------------------------------------------- +# Prestige system strings +# --------------------------------------------------------------------------- + +PRESTIGE_SHOP_NAMES: dict[str, str] = { + "coin_mult": "Mündiboost", + "exp_mult": "EXP-boost", + "daily_plus": "Päevabonus+", + "work_plus": "Töötaja+", +} +PRESTIGE_SHOP_DESCRIPTIONS: dict[str, str] = { + "coin_mult": "Kõik TipiCOINide teenimisallikad (daily, töö, kerja, kala) teenivad +8% rohkem iga taseme kohta. Max 5 taset → +40%.", + "exp_mult": "Kõik EXP allikad teenivad +8% rohkem iga taseme kohta. Max 5 taset → +40%.", + "daily_plus": "Päevase boonuse alussumma tõuseb +20% iga taseme kohta. Max 3 taset → +60%.", + "work_plus": "/work teenib +20% rohkem iga taseme kohta. Max 3 taset → +60%.", +} +PRESTIGE_UI: dict[str, str] = { + "confirm_desc": ( + "Oled tasemel **{level}** ({exp} EXP).\n\n" + "Prestiiži korral saad **{pp}** " + E["TipiFIRE"] + " ja kõik lähtestub:\n" + "• Saldo, EXP, esemed, ooteajad\n\n" + "**Kalakogu jääb alles!**\n\nKas oled kindel?" + ), + "btn_confirm": "🔥 Jah, prestiiži!", + "btn_cancel": "❌ Tühista", + "btn_tab_status": "⭐ Prestiiz", + "btn_tab_shop": "🛍️ Uuendused", + "success_desc": ( + "Said **{pp}** " + E["TipiFIRE"] + "\n" + "Prestiiži tase: **{level}**\n" + "Kogutud PP: **{total_pp}** " + E["TipiFIRE"] + "\n\n" + "*Kõik lähtestati. Alusta otsast!*" + ), + "too_low_desc": "Prestiiži jaoks vajad taset **{required}** (sul on tase {level}).", + "shop_desc": "Sul on **{pp}** " + E["TipiFIRE"] + " · Vajuta nuppu uuenduse ostmiseks", + "shop_maxed": "✅ Max", + "shop_level_fmt": "Tase {cur}/{max}", + "shop_cost_fmt": "{cost} " + E["TipiFIRE"], + "buy_success_desc":"**{name}** uuendatud tasemele **{new_level}/{max_level}**!\nPP alles: **{pp}** " + E["TipiFIRE"], + "buy_no_pp": E["TipICRY"] + " Sul pole piisavalt PP. Sul on **{have}**, vajad **{need}** " + E["TipiFIRE"] + ".", + "buy_maxed": "❌ See uuendus on juba maksimumtasemel.", + "buy_not_found": "❌ Sellist uuendust ei leitud. Vaata `/prestigeshop`.", + "rank_line": E["TipiFIRE"] + " Prestiiž **{level}** · {pp} PP", + "rank_season": "🏆 Hooaja EXP: **{exp}**", + "btn_buy_upgrade": "{emoji} {name} +1 ({cost} PP)", + "status_footer": "⭐ Prestiiž {level} · {pp} PP", +} diff --git a/strings/commands.py b/strings/commands.py new file mode 100644 index 0000000..7cc66e9 --- /dev/null +++ b/strings/commands.py @@ -0,0 +1,223 @@ +"""Slash-command and /help metadata (descriptions, options, categories). + +Auto-split from the original strings.py; edit strings here. +""" + +from core.emoji import EMOJI as E + +__all__ = [ + 'CMD', + 'OPT', + 'HELP_CATEGORIES', + 'HELP_UI', +] + +# --------------------------------------------------------------------------- +# Slash command descriptions (shown in Discord's autocomplete) +# --------------------------------------------------------------------------- + +CMD: dict[str, str] = { + "ping": "Vaata, kas bot on üleval", + "help": "Nimekiri kõikidest käskudest kategooriate kaupa", + "status": "Näita boti staatust ja ressursside kasutust", + "birthdays": "Näita kõigi liikmete sünnipäevi kuu järgi", + "check": "Laadi andmed, täida ID'd ja sünkroniseeri kõik liikmed", + "sync": "Sünkroniseeri käsklused Discordi serveriga", + "member": "Näita liikme andmeid tabelist", + "restart": "Tee taaskäivitus botile", + "shutdown": "Lülita bot välja (ilma taaskäivituseta)", + "pause": "Peata / jätka kõik käsklused (hooldusrežiim)", + "send": "Saada sõnum valitud kanalisse", + "profile": "Vaata oma profiili: saldo, tase, esemed, statistika ja kalakogu", + "balance": "Vaata enda (või kellegi teise) TipiCOINide saldot", + "daily": "Võta enda päevane TipiCOINi boonus", + "work": "Tööta ja teeni TipiCOINe (1h ooteaeg)", + "beg": "Kerja TipiCOINe (5min ooteaeg)", + "crime": "Proovi oma õnne kriminaalse tegevusega (2h ooteaeg)", + "rob": "Proovi kelleltki TipiCOINe varastada", + "heist": "Alusta grupirööv pangahoidlasse (min 2 mängijat, max 8, 4h serveri ooteaeg)", + "roulette": "Panusta TipiCOINe punasele, mustale või rohelisele (1/37 võimalus, 14x payout)", + "give": "Anna TipiCOINe teisele mängijale", + "leaderboard": "TipiBOTi edetabel - kes on kõige rikkam?", + "shop": "Sirvi TipiBOTi poodi", + "buy": "Osta ese TipiBOTi poodist", + "rps": "Kivi-paber-käärid mõne teise mängija vastu", + "slots": "Proovi oma õnne TipiBOTi mänguautomaadiga", + "request": "Kerja TipiCOINe teistelt mängijatelt - nagu crowdfunding, aga halvem", + "reminders": "Halda DM meeldetuletusi - kõik on vaikimisi sees, lülita need siin välja", + "cooldowns": "Vaata kõikide käskude ooteaegu", + "jailed": "Vaata, kes on praegu vanglas", + "rank": "Vaata oma EXP, taset ja edetabeli positsiooni", + "stats": "Vaata oma mängustatistikat", + "jailbreak": "Proovi vanglast põgeneda kasutades täringuid", + "adminseason": "[Admin] Lõpeta võistlus, teavita võitjaid ja lähtesta EXP", + "admincoins": "[Admin] Anna või võta TipiCOINe kasutajale/kasutajalt", + "adminjail": "[Admin] Saada kasutaja vangi", + "adminunjail": "[Admin] Vabasta kasutaja vangist", + "adminban": "[Admin] Keela kasutajal majandussüsteemis osaleda", + "adminunban": "[Admin] Eemalda majandussüsteemi keeld kasutajalt", + "adminreset": "[Admin] Lähtesta kasutaja majandusandmed", + "adminview": "[Admin] Vaata kasutaja majandusandmeid", + "adminexp": "[Admin] Anna v\u00f5i v\u00f5ta EXP kasutajalt", + "adminitem": "[Admin] Anna v\u00f5i eemalda ese kasutajalt (tasuta)", + "allowchannel": "[Admin] Lisa kanal, kus bot võib vastata käsklustele", + "denychannel": "[Admin] Eemalda kanal lubatud kanalite nimekirjast", + "channels": "[Admin] Näita lubatud kanalite nimekirja", + "economysetup": "[Admin] Loo ja sea korda majandussüsteemi rollid", + "blackjack": "Mängi blackjacki TipiBOTi vastu", + "prestige": "Prestiiži (nõuab taset 30) ja teeni Prestiižipunkte", + "prestigeshop": "Vaata prestiižipoodi ja sinu uuenduste taset", + "prestigebuy": "Osta prestiižiuuendus Prestiižipunktide eest", + "fish": "Mine kalastama (interaktiivne mäng, 2min ooteaeg)", + "fishbook": "Vaata oma kalakogu ja kogutud kalaliike", + "fishsell": "Müü kalu oma inventarist", + "patchnotes": "Vaata TipiBOTi viimaseid muudatusi ja uuendusi", + "quests": "Vaata oma päeva- ja nädalaülesandeid ning nõua auhinnad", +} + +# --------------------------------------------------------------------------- +# Option descriptions (shown next to each parameter in Discord) +# --------------------------------------------------------------------------- + +OPT: dict[str, str] = { + "admin_kasutaja": "Kasutaja", + "admin_põhjus": "Põhjus (saadetakse kasutajale DM kaudu)", + "admincoins_kogus": "Positiivne = anna, negatiivne = võta", + "adminjail_minutid": "Vangistamise kestus minutites", + "balance_kasutaja": "Mängija, kelle saldot vaadata (vaikimisi sina)", + "roulette_panus": "Panus TipiCOINides ('all' = kogu saldo)", + "roulette_värv": "Punane, must või roheline", + "give_kasutaja": "Kellele annad?", + "give_summa": "Kui palju annad? ('all' = kogu saldo)", + "buy_ese": "Eseme nimi (vaata /shop)", + "rps_panus": "Valikuline TipiCOINide panus ('all' = kogu saldo)", + "rps_vastane": "Väljakutse teisele mängijale (PvP)", + "slots_panus": "Panus TipiCOINides ('all' = kogu saldo)", + "request_summa": "Kui palju TipiCOINe vajad?", + "request_põhjus": "Miks sa vajad TipiCOINe?", + "request_sihtmärk": "Valikuline: kellelt täpselt palud (teised ei saa toetada)", + "send_kanal": "Kanal, kuhu sõnum saata", + "send_sõnum": "Sõnum, mida saata", + "allowchannel_kanal": "Kanal, kus bot võib vastata käsklustele", + "denychannel_kanal": "Kanal, kus bot ei või vastata käsklustele", + "rob_sihtmärk": "Kellelt röövid?", + "member_user": "Mängija, kelle infot tahad vaadata", + "rank_kasutaja": "Mängija, kelle taset tahad vaadata (vaikimisi sina)", + "stats_kasutaja": "Mängija, kelle statistikat tahad vaadata (vaikimisi sina)", + "adminseason_top_n": "Kui palju mängijaid võitis (vaikimisi 10)", + "blackjack_panus": "Panus TipiCOINides ('all' = kogu saldo)", + "prestigebuy_upgrade": "Uuenduse ID (vaata /prestigeshop)", + "fishbook_kasutaja": "Mängija, kelle kalakogu vaadata (vaikimisi sina)", + "profile_kasutaja": "Mängija, kelle profiili vaadata (vaikimisi sina)", + "adminexp_kogus": "Positiivne = anna, negatiivne = võta", + "adminitem_ese": "Eseme ID (kasutatav sisse, vaata /shop)", + "adminitem_tegevus": "'anna' või 'eemalda'", +} + +# --------------------------------------------------------------------------- +# /help categories +# --------------------------------------------------------------------------- + +HELP_CATEGORIES: dict[str, dict] = { + "üldine": { + "label": "🤖 Üldine", + "description": "Üldised käsklused", + "color": 0x57F287, + "fields": [ + ("/ping", "Vaata, kas bot on üleval"), + ("/status", "Näita boti staatust ja ressursside kasutust"), + ("/help", "Nimekiri kõikidest käskudest kategooriate kaupa"), + ("/birthdays", "Näita kõigi liikmete sünnipäevi kuu järgi"), + ], + }, + "tipibot": { + "label": "🪙 TipiBOT", + "description": "TipiCOIN majandus", + "color": 0xF4C430, + "fields": [ + ("/profile [@user]", "Saldo, tase, EXP progress, prestiiz - kõik ühes kohas. Nupud: Esemed · Statistika · Kalakogu."), + ("/cooldowns", "Vaata kõikide käskude ooteaegu. Näitab ka vangla ooteaega."), + ("/daily", "Võta enda päevane TipiCOINide boonus. 20h ooteaeg. Streak'i boonus: 3d=+50%, 7d=+100%, 14d=+200%."), + ("/work", "Tööta ja teeni TipiCOINe (1h ooteaeg)"), + ("/beg", "Kerja TipiCOINe (5min ooteaeg)"), + ("/crime", "Proovi oma õnne kriminaalse tegevusega. 60% edu, 40% trahv + 30min vanglas. 2h ooteaeg."), + ("/rob @user", "Proovi kelleltki TipiCOINe varastada. 45% edu. Ebaõnnestumisel saad trahvi."), + ("/heist", "Alusta grupiröövi pangahoidlasse. Min 2 mängijat, max 8. 5 min ühinemisaeg. Õnnestumisel jagatakse saak võrdselt - ebaõnnestumisel 1h 30min vangis + trahv. 4h serveri ooteaeg (ei ole isiklik)."), + ("/jailbreak", "Proovi vanglas olles täringuid visata, et duublit saada (3 katset). Duubli korral saad vabaks. Ebaõnnestumisel saad valida: maksa kautsjon (20-30% saldost, min 350 ⬡) või jää vanglasse kuni aja lõpuni."), + ("/give @user ", "Anna TipiCOINe teisele mängijale"), + ("/quests", "Vaata oma päeva- ja nädalaülesandeid ning nõua auhinnad (uueneb iga päev/nädal)."), + ("/leaderboard", "TipiBOTi edetabel - kes on kõige rikkam?"), + ("/shop", "Sirvi TipiBOTi poodi"), + ("/buy ", "Osta ese TipiBOTi poodist"), + ("/request [target]", "Saada crowdfundingu taotlus. Keegi saab 'Toeta' nuppu vajutades raha kanda (taotlus kehtib 5 minutit)."), + ("/reminders", "DM meeldetuletused on vaikimisi sees. Kasuta seda käsku, et lülitada sisse/välja, milliseid käsklusi meelde tuletada."), + ], + }, + "shop": { + "label": "🛍️ Pood", + "description": "TipiBOTi poe esemed ja nende efektid", + "color": 0xF4C430, + "fields": [ + (f"{E['TipiHIIR']} Mängurihiir - 500 ⬡", "Teeni töötades 50% rohkem TipiCOINe."), + (f"{E['TipiMATT']} XL hiirematt - 600 ⬡", "Kerjamise ooteaeg 5min → 3min."), + (f"{E['TipiKLAPID']} Kõrvaklapid - 1200 ⬡", "Päevase boonuse ooteaeg 20h → 18h."), + (f"{E['TipiPILET']} LAN pilet (2025) - 1200 ⬡", "Päevane boonus on duubeldatud."), + (f"{E['TipiVAC']} Anticheat - 750 ⬡", "Röövimine sinu vastu ebaõnnestub. Pärast 2 kasutust pead ostma uue."), + (f"{E['TipiBULL']} Red Bull - 800 ⬡", "30% tõenäosus, et teenid töötades 3x rohkem."), + (f"{E['TipiLAP']} Botikoobas - 1500 ⬡", "RTX 5090 jooksutab botte 24/7. Päevane boonus genereerib 5% intressi sinu saldo pealt."), + (f"{E['TipiLAUD']} Reguleeritav laud - 3500 ⬡ *(T2)*", "/work teenib 25% rohkem (stackib mängurihiirega)."), + (f"{E['TipiSERVER']} Jellyfin server - 4000 ⬡ *(T2)*", "Röövimise edu tõenäosus 45% → 60%."), + (f"{E['TipiMIC']} Mikrofon - 2800 ⬡ *(T2)*", "Teeni 30% rohkem eduka /crime puhul."), + (f"{E['TipiKLAVA']} Mehhaaniline klaviatuur - 1800 ⬡ *(T2)*", "/beg teenib 2x rohkem."), + (f"{E['TipiMONITOR']} Ultralai monitor - 2500 ⬡ *(T2)*", "/work ooteaeg: 1h → 40min."), + (f"{E['TipiCAT']} CAT6 netikaabel - 3500 ⬡ *(T2)*", "/crime edu tõenäosus tõuseb 60% → 75%."), + (f"{E['TipiMONITOR2']} 360hz monitor - 7500 ⬡ *(T3)*", "Mänguautomaadi jackpot 10x → 15x, kolmik 4x → 6x."), + (f"{E['TipiKARIKAS']} TipiLANi trofee - 6000 ⬡ *(T3)*", "Streak ei nulli, kui sa mõne päeva vahele jätad."), + (f"{E['TipiTOOL']} Mänguritool - 9000 ⬡ *(T3)*", "/crime ebaõnnestumine ei saada sind vanglasse."), + ], + }, + "games": { + "label": "🎮 Mängud", + "description": "Lõbusad mängud", + "color": 0x5865F2, + "fields": [ + ("/roulette ", "Panusta TipiCOINe punasele, mustale või rohelisele (1/37 võimalus, 14x payout)"), + ("/rps [bet] [opponent]", "Kivi-paber-käärid mõne teise mängija vastu"), + ("/slots ", "Proovi oma õnne TipiBOTi mänguautomaadiga"), + ("/blackjack ", "Mängi blackjacki TipiBOTi vastu. Blackjack maksab 3:2. Kakskordistamine (double down) on võimalik vaid esimese käigu ajal."), + ], + }, + "admin": { + "label": "🔧 Admin", + "description": "Admin käsklused (peidetud tavaliste kasutajate eest)", + "color": 0xED4245, + "fields": [ + ("/check", "Laadi andmed, täida ID'd ja sünkroniseeri kõik liikmed"), + ("/member @user", "Näita liikme andmeid tabelist"), + ("/sync", "Sünkroniseeri käsklused Discordi serveriga"), + ("/restart", "Tee taaskäivitus botile"), + ("/send #channel message", "Saada sõnum valitud kanalisse"), + ("/admincoins @user ", "Anna või võta TipiCOINe kasutajale/kasutajalt"), + ("/adminjail @user ", "Saada kasutaja vangi"), + ("/adminunjail @user", "Vabasta kasutaja vangist"), + ("/adminban @user ", "Keela kasutajal majandussüsteemis osaleda"), + ("/adminunban @user", "Eemalda majandussüsteemi keeld kasutajalt"), + ("/adminreset @user ", "Lähtesta kasutaja majandusandmed"), + ("/adminview @user", "Vaata kasutaja majandusandmeid"), + ("/allowchannel #channel", "Lisa kanal, kus bot võib vastata käsklustele"), + ("/denychannel #channel", "Eemalda kanal lubatud kanalite nimekirjast"), + ("/channels", "Näita lubatud kanalite nimekirja"), + ("/adminseason [top_n]", "Lõpeta võistlus, teavita võitjaid ja lähtesta EXP"), + ("/economysetup", "Loo ja sea korda majandussüsteemi rollid (ECONOMY + taseme rollid) boti rolli alla"), + ], + }, +} + +# --------------------------------------------------------------------------- +# /help UI +# --------------------------------------------------------------------------- + +HELP_UI: dict[str, str] = { + "footer": "TipiBOT • Vali kategooria allmenüüst", + "select_placeholder": "Vali kategooria...", +} diff --git a/strings/common.py b/strings/common.py new file mode 100644 index 0000000..965d007 --- /dev/null +++ b/strings/common.py @@ -0,0 +1,247 @@ +"""Shared / system-wide strings (messages, titles, errors, cooldowns). + +Auto-split from the original strings.py; edit strings here. +""" + +from core.emoji import EMOJI as E + +__all__ = [ + 'MSG_BANNED', + 'MSG_SPAM_JAIL', + 'MSG_PONG', + 'MSG_RESTART_DONE', + 'MSG_RESTARTING', + 'MSG_SHUTTING_DOWN', + 'MSG_PAUSED', + 'MSG_UNPAUSED', + 'MSG_MAINTENANCE', + 'MSG_SYNC_DONE', + 'MSG_REMINDER', + 'MSG_LEVELUP', + 'MSG_LEVELUP_ROLE', + 'REMINDER_OPTS', + 'TITLE', + 'ERR', + 'CD_MSG', + 'REMINDERS_UI', + 'SEND_UI', + 'PATCHNOTES_UI', + 'STATUS_UI', +] + +# --------------------------------------------------------------------------- +# Repeated system messages +# --------------------------------------------------------------------------- + +MSG_BANNED = "🚫 Sul keelati TipiBOTi majandussüsteemis osaleda." +MSG_SPAM_JAIL = "⚠️ Liiga kiire! Automaatsed skriptid/spam on keelatud. Oled **30 minutit vangis**. Kasuta `/jailbreak`, et varem välja pääseda." +MSG_PONG = "🏓 Pong!" +MSG_RESTART_DONE = "✅ Bot on taaskäivitatud!" +MSG_RESTARTING = "🔄 Taaskäivitan..." +MSG_SHUTTING_DOWN = "⛔ Lülitan boti välja..." +MSG_PAUSED = "⏸️ Bot on hooldusrežiimis - kõik käsklused on peatatud." +MSG_UNPAUSED = "▶️ Hooldusrežiim lõpetatud - käsklused on taas saadaval." +MSG_MAINTENANCE = "🔧 Bot on hetkel hoolduses. Proovi mõne hetke pärast uuesti." +MSG_SYNC_DONE = "✅ Käsud sünkroniseeritud!" +MSG_REMINDER = "⏰ **/{cmd}** on taas kasutamiseks valmis!\n-# Meeldetuletuste haldamiseks kasuta serveris `/reminders`." +MSG_LEVELUP = "⬆️ **{name}** jõudis **{level}. tasemele**!{extra}" +MSG_LEVELUP_ROLE = " 🎊 Uus tiitel: **{role}**!" + +# --------------------------------------------------------------------------- +# /reminders dropdown options (cmd_key, label, description) +# --------------------------------------------------------------------------- + +REMINDER_OPTS: list[tuple[str, str, str]] = [ + ("daily", "📅 /daily", "Päevane boonus (20t ooteaeg)"), + ("work", "💼 /work", "Töö (1t ooteaeg, 40min monitoriga)"), + ("beg", "🙏 /beg", "Kerjamine (5min ooteaeg)"), + ("crime", "🦹 /crime", "Kuritegu (2t ooteaeg)"), + ("rob", "🔫 /rob", "Rööv (2t ooteaeg)"), + ("fish", "🎣 /fish", "Kalapüük (2min ooteaeg)"), +] + +# --------------------------------------------------------------------------- +# Embed titles +# --------------------------------------------------------------------------- + +TITLE: dict[str, str] = { + "daily": "📅 Päevane boonus", + "work": "💼 Töö", + "beg": "🙏 Kerjamine", + "crime_win": f"{E['TipiFIRE']} Kuritegu õnnestus!", + "crime_fail": f"{E['TipiTROLL']} Vahele jäid!", + "rob_win": f"{E['TipiFIRE']} Rööv õnnestus!", + "rob_fail": f"{E['TipiTROLL']} Rööv ebaõnnestus!", + "rob_anticheat": f"{E['TipiVAC']} Anticheat peatas sind!", + "jailbreak": "🎲 Vanglast põgenemine", + "jailbreak_free": f"🎲 {E['TipiFIRE']} DUUBEL! Oled vaba!", + "jailbreak_fail": f"{E['TipICRY']} Kolm katset läbi!", + "jailbreak_miss": "🎲 " + E["TipICRY"] + " Ei saanud duublit ({tries}/{max})", + "jailbreak_bail": "💸 Kautsjon", + "give": f"{E['TipiHEART']} TipiCOINi ülekanne", + "stats": "📊 Mängustatistika", + "leaderboard_coins": "🪙 TipiBOTi edetabel - Mündid", + "leaderboard_exp": "📊 TipiBOTi edetabel - EXP / Tase", + "leaderboard_season": "🏆 TipiBOTi edetabel - Hooaja EXP", + "leaderboard_prestige": f"{E['TipiFIRE']} TipiBOTi edetabel - Prestiiž", + "leaderboard_wagered": "🎲 TipiBOTi edetabel - Hasartmängud", + "leaderboard_fish": "🎣 TipiBOTi edetabel - Kalapüük", + "rps": "⚔️ Kivi, Paber, Käärid", + "rps_duel": "⚔️ KPK duell", + "rps_duel_active": "⚔️ KPK duell - käimas", + "rps_duel_done": "⚔️ KPK duell - lõppenud", + "rps_duel_cancel": "⚔️ KPK duell - tühistatud", + "rps_duel_expire": "⚔️ KPK duell - aegus", + "rps_duel_decline": "⚔️ KPK duell - keelduti", + "heist_lobby": "🔫 Grupirööv - kogunemine", + "heist_win": f"{E['TipiFIRE']} Grupirööv õnnestus!", + "heist_fail": f"{E['TipiSKULL']} Grupirööv ebaõnnestus!", + "heist_cancel": "🔫 Grupirööv tühistatud", + "request": f"{E['TipiHEART']} Rahataotlus", + "reminders": "⏰ Meeldetuletused", + "cooldowns": "⏱️ Sinu ooteajad", + "adminseason": "🏆 Hooaeg lõppes!", + "economysetup": "⚙️ Majanduse seadistamine", + "blackjack": "🃏 Blackjack", + "blackjack_bj": f"🃏 {E['TipiFIRE']} BLACKJACK!", + "blackjack_win": f"{E['TipiFIRE']} Võitsid!", + "blackjack_lose": f"{E['TipiSKULL']} Kaotasid!", + "blackjack_bust": f"{E['TipiSKULL']} Üle 21 - kaotasid!", + "blackjack_push": "🤝 Viik!", + "blackjack_dbust": f"{E['TipiSKULL']} Üle 21 - mõlemad kaotasid!", + "blackjack_dwin": f"{E['TipiFIRE']} Topeltpanus võitis!", + "prestige_confirm": "🔥 Prestiiž - kinnita", + "prestige_success": E["TipiFIRE"] + " Prestiiž {level} saavutatud!", + "prestige_too_low": "❌ Prestiiž pole saadaval", + "prestige_shop": f"{E['TipiFIRE']} Prestiižipood", + "prestige_buy_ok": "✅ Uuendus ostetud!", + "fish_cast": "🎣 Otsid kala...", + "fish_bite": "🐟 KALA NÄKKAB!", + "fish_escape": "🎣 Kala pääses!", + "fish_junk": "🗑️ Ai ai ai...", + "fishbook": "📖 Kalakogu", + "quests": "🎯 Ülesanded", +} + +# --------------------------------------------------------------------------- +# Error / validation messages (use .format(**kwargs) for dynamic parts) +# --------------------------------------------------------------------------- + +ERR: dict[str, str] = { + "positive_bet": "❌ Panus peab olema positiivne.", + "positive_amount": "❌ Summa peab olema positiivne.", + "positive_duration": "❌ Aeg peab olema positiivne.", + "admincoins_zero": "Kogus ei tohi olla 0.", + "missing_perms": "❌ Sul on vaja **Rollide haldamise** õigust selle käsu kasutamiseks.", + "generic_error": "❌ Tekkis viga: ```{error}```", + "send_failed": "❌ Sõnumi saatmine ebaõnnestus: ```{error}```", + "rob_self": "❌ Sa ei saa iseennast röövida.", + "rob_bot": "❌ Botti ei saa röövida.", + "rob_no_house": "❌ Kassa pole veel avatud.", + "rob_house_blocked": "❌ Panga seif on liiga hästi kaitstud. Kasuta `/heist` selle rüüstamiseks.", + "rob_too_poor": "❌ **{name}** on liiga vaene röövimiseks.", + "rob_target_jailed": "❌ **{name}** on vanglas - vabad inimesed ei saa vanglas olevaid röövida.", + "heist_active": "❌ Serveris on juba aktiivne grupirööv käimas! Oota, kuni see lõpeb.", + "heist_full": "❌ Grupirööv on täis!", + "heist_min_players": "❌ Grupiröövi alustamiseks on vaja vähemalt **{min}** osalejat.", + "broke": E["TipICRY"] + " Sul pole piisavalt TipiCOINe. Saldo: {bal}", + "broke_need": E["TipICRY"] + " Sul pole piisavalt TipiCOINe. Vajad veel {need}.", + "item_owned": "❌ Sul on see ese juba olemas.", + "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.", + "not_your_game": "❌ See pole sinu mäng!", + "game_in_progress": "❌ Sul on juba mäng käimas! Lõpeta see enne.", + "not_your_challenge":"❌ See väljakutse pole sulle!", + "not_your_menu": "❌ See ei ole sinu menüü.", + "give_self": "❌ Sa ei saa iseendale TipiCOINe anda.", + "give_bot": "❌ Botile ei saa TipiCOINe anda.", + "give_jailed": "❌ Oled vangis - vanglas ei saa TipiCOINe anda. Pääsed välja {ts}.", + "rps_self": "❌ Sa ei saa iseendale väljakutset esitada.", + "rps_bot": "❌ Botid on KPK-is liiga head.", + "not_jailed": "❌ Sa pole praegu vangis.", + "not_in_leaderboard":"❌ Sind pole veel edetabelis.", + "admin_ban_bot": "❌ Botti ei saa bannida.", + "admin_reset_bot": "❌ Kassa andmeid ei saa lähtestada.", + "member_not_found": "❌ **{name}** ei leitud tabelist.", + "request_self_fund": "❌ Sa ei saa oma taotlust ise rahastada.", + "request_self": "❌ Sa ei saa iseendalt anuda.", + "request_bot": "❌ Botid on teatavasti kitsid.", + "request_targeted": "❌ See taotlus on suunatud kasutajale **{name}**.", + "request_closed": "❌ See taotlus on juba rahastatud või aegunud.", + "already_in_game": "❌ Sul on juba aktiivne mäng käimas!", + "invalid_amount": "❌ Sisesta kehtiv summa või 'all'.", + "fund_range": "❌ Sisesta summa vahemikus 1-{max}.", + "channel_only": "❌ Boti käske saab kasutada ainult nendes kanalites: {channels}", + "guild_only": "Seda käsku saab kasutada ainult serveris.", + "sheet_error": "❌ Tabeli laadimine ebaõnnestus: ```{error}```", + "gamble_cooldown": "🎰 Oled just mänginud! Saad uuesti mängida {ts}.", +} + +# --------------------------------------------------------------------------- +# Cooldown messages (use .format(ts=...) - ts is a Discord timestamp string) +# --------------------------------------------------------------------------- + +CD_MSG: dict[str, str] = { + "daily": "⏳ Järgmine boonus {ts}.", + "work": "⏳ Saad töötada {ts}.", + "beg": "⏳ Saad kerjata {ts}.", + "crime": "⏳ Saad uuesti proovida {ts}.", + "rob": "⏳ Saad uuesti röövida {ts}.", + "heist": "⏳ Saad uuesti heisti teha {ts}.", + "heist_global": "⏳ Pangahoidla alles kosub eelmisest röövist. Järgmine heist võimalik {ts}.", + "jailed": E["TipiTROLL"] + " Oled vangis! Pääsed välja {ts}. Kasuta `/jailbreak`, et varem välja pääseda.", + "fish": "🎣 Saad uuesti kalastada {ts}.", +} +REMINDERS_UI: dict[str, str] = { + "select_placeholder": "Vali käsud, millest soovid meeldetuletust...", + "saved_on": "✅ Meeldetuletused sisse lülitatud: {names}", + "saved_off": "🔕 Kõik meeldetuletused välja lülitatud.", + "desc_active": "Praegu aktiivne: {status}\n\nMuuda valikut allpool.", + "desc_none": "Hetkel pole ühtegi meeldetuletust sisse lülitatud.\n\nVali allpool, millest soovid DM-i saada.", + "footer": "Bot DM-ib sulle, kui valitud käsk on taas kasutamiseks valmis.", +} + +# --------------------------------------------------------------------------- +# /send UI strings +# --------------------------------------------------------------------------- + +SEND_UI: dict[str, str] = { + "sent": "✅ Sõnum saadetud kanalisse {channel}!", + "forbidden": "❌ Mul pole õigust kanalisse {channel} kirjutada.", +} + +# --------------------------------------------------------------------------- +# /patchnotes UI strings +# --------------------------------------------------------------------------- + +PATCHNOTES_UI: dict[str, str] = { + "title": "📝 Muudatuste logi — {version}", + "footer": "Versioon {idx}/{total}", + "btn_newer": "◀ Uuem", + "btn_older": "Vanem ▶", + "select_placeholder": "Vali versioon…", + "empty_file": "ℹ️ Muudatuste logi on hetkel tühi.", + "empty_version": "_(selle versiooni kohta märkmeid pole)_", +} + +# --------------------------------------------------------------------------- +# /status UI +# --------------------------------------------------------------------------- + +STATUS_UI: dict[str, str] = { + "title": "🖥️ Boti olek", + "uptime_field": "🕐 Uptime", + "uptime_val": "{hours}t {minutes}m {seconds}s", + "latency_field": "📡 Latency", + "latency_val": "{ms} ms", + "ram_field": "🧠 RAM (RSS)", + "ram_val": "{mb} MB", + "cpu_field": "⚙️ CPU", + "cpu_val": "{percent}%", + "tasks_field": "🔄 Async tasks", + "eco_players_field": "👤 Eco players", + "members_cache_field": "📋 Liikmed (cache)", + "log_files_field": "📂 Log files", + "log_line": "`{name}` - {size_kb} KB", + "none": "-", +} diff --git a/strings/economy.py b/strings/economy.py new file mode 100644 index 0000000..1fdb01e --- /dev/null +++ b/strings/economy.py @@ -0,0 +1,443 @@ +"""Core economy: income, profile, shop, quests, leaderboard, requests. + +Auto-split from the original strings.py; edit strings here. +""" + +from core.emoji import EMOJI as E + +__all__ = [ + 'WORK_JOBS', + 'BEG_LINES', + 'BEG_JAIL_LINES', + 'CRIME_WIN', + 'CRIME_LOSE', + 'QUEST_UI', + 'QUEST_DESCRIPTIONS', + 'SHOP_UI', + 'ITEM_DESCRIPTIONS', + 'JAILED_UI', + 'SHOP_BTN', + 'DAILY_UI', + 'STATS_UI', + 'PROFILE_UI', + 'BALANCE_UI', + 'COOLDOWNS_UI', + 'RANK_UI', + 'WORK_UI', + 'BEG_UI', + 'CRIME_UI', + 'ROB_UI', + 'GIVE_UI', + 'BUY_UI', + 'LEADERBOARD_UI', + 'REQUEST_UI', +] + +# --------------------------------------------------------------------------- +# Flavour text +# --------------------------------------------------------------------------- + +WORK_JOBS: list[tuple[str, float]] = [ + ("paigaldasid aulas netikaableid", 1.0), + ("paigaldasid aulas voolukaableid", 1.0), + ("tõid poest korraldajatele pitsat", 1.0), + ("konfigureerisid uue switchi", 1.0), + ("vedasid laudu aulasse", 1.0), + ("vedasid toole aulasse", 1.0), + ("paigaldasid aulasse vahekardinaid", 1.0), + ("aitasid üles seada turniiri lava", 1.0), + ("töötasid baaris", 1.0), + ("testisid helisüsteemi \"Erootikapoodi\" blastides", 1.0), + ("juhendasid külastajaid infolauas", 1.0), + ("seadistasid LAN serverit", 1.0), + ("paigaldasid monitore", 1.0), + ("ühendasid aulas kilpe", 1.0), + ("aitasid LANil osalejat", 1.0), + ("müüsid energiajooke", 1.0), + ("tegid netikaableid", 1.0), + ("lahendasid IP-konflikti", 1.0), + ("parandasid kellegi arvutit", 1.0), + ("tegid korda striimi heli (mitte nagu PGL)", 1.2), + ("kirjutasid koodi miniturniiri jaoks", 1.2), + ("võitsid turniiri", 1.5), +] +BEG_LINES: list[str] = [ + "istusid kurva näoga oma monitori taga", + "palusid abi kellegi DMis", + "postitasid #abi kanalisse", + "vaatasid kadedusega teiste asju", + "kirjutasid /beg kolmandat korda järjest", + "küsisid oma tiimiliikmelt laenu", + "võtsid kiirlaenu", + "müüsid 3 sendi eest oma CSi skinne", + "korjasid kampuselt taarat", + "tegid TikToki live'i", + "refreshisid pangaäppi lootuses, et raha tekib", + "kirjutasid \"pls donate\" chatti", + "vaatasid oma tühja rahakotti", + "püüdsid kedagi guilt-trippida", + "lubasid exposure'it raha eest", + "mängisid kurba muusikat taustaks", + "teesklesid, et see on sotsiaalne eksperiment", + "kirjutasid emotsionaalse loo oma olukorrast", + "pakkusid vastu future equity't", + "tegite sõbraga koos kerjamisplaani", + "otsisid diivani vahelt sente", + "lubasid boostida kellegi ranki viieka eest", + "küsisid chatist, kas keegi teab kust tasuta V-Buckse saab", + "avastasid, et su krüptoportfell on sügavas miinuses", +] +BEG_JAIL_LINES: list[str] = [ + "karjusid läbi trellide, et keegi münte läbi lükkaks", + "kirjutasid kongi seina peale oma PayPali aadressi", + "lubasid, et maksad järgmine kord vangi minnes tagasi", + "veensid valvurit, et oled tegelikult hea inimene", + "saatsid vanglast käsitsi kirjutatud kirja oma meeskonnale", + "pakkusid vahile tulevaste vihjete eest raha", + "koputasid morset vastu naaberkongi seina", + "üritasid vangla WiFit häkkida", + "lubasid teha tasuta IT-tööd vabanemise eest", + "üritasid lusikaga tunnelit kaevata", + "kirjutasid bug reporti vangla süsteemile", + "proovisid trellidest läbi pugeda, aga jäid kinni", + "pakkusid vangivalvurile oma Steami kontot vabanemise eest", +] +CRIME_WIN: list[str] = [ + "häkkisid turniiri tulemuste tabelit", + "varastasid oma vastase hiire", + "varastasid oma vastase klaviatuuri", + "varastasid oma vastase kõrvaklapid", + "varastasid oma vastase monitori", + "varastasid oma vastase mikrofoni", + "müüsid võltsitud LANi pileteid", + "laenatasid kellegi GPUd ja ei tagastanud seda", + "laenatasid Filmiklubilt AUX-kaablit ja ei tagastanud seda", + "käivitasid DDoS rünnaku serverile", + "tegid oma shitcoin'idega pump and dump'i", + "kasutasid aimbotti ja keegi ei märganud", + "exploitisid mängu bugi enda kasuks", + "phishisid kellegi Steami konto", + "varastasid prize pooli raha", + "ühendasid enda krüptokaevandaja serverisse", + "tegid petukõnesid" +] +CRIME_LOSE: list[str] = [ + "jäid turniiri adminile vahele", + "tõmbasid oma arvuti kaabli pistikust välja", + "kukutasid lahtise Red Bulli omale sülle", + "unustasid VPNi sisse lülitada", + "lagisid kriitilisel momendil", + "said banni otseülekande ajal", + "unustasid logid kustutada", + "sinu skript crashis valel hetkel", + "said reportitud mitme mängija poolt", + "sinu krüptokaevandaja süttis põlema", + "flashisid tervet oma tiimi", + "avastasid, et Windows otsustas keset mängu uuendama hakata", + "jäid politseile petukõnedega vahele" +] + +# --------------------------------------------------------------------------- +# Quest system (/quests) +# --------------------------------------------------------------------------- + +QUEST_UI: dict[str, str] = { + "daily_header": "📅 Päevaülesanded", + "weekly_header": "📆 Nädalaülesanded", + "progress": "⏳ {progress}/{max}", + "ready": "✅ Valmis - nõua auhind!", + "completed": "🏆 Nõutud", + "reward": "🎁 {coins} ⬡ · {exp} EXP", + "empty": "Ühtegi ülesannet pole. Proovi hiljem uuesti!", + "claim_btn": "🎁 Nõua auhinnad", + "claimed_msg": "🏆 Nõudsid {count} ülesande auhinnad: +{coins} · +{exp} EXP!", + "nothing": "Sul pole ühtegi valmis ülesannet, mida nõuda.", + "error": "❌ Ülesannete laadimine ebaõnnestus. Proovi hiljem uuesti.", +} + +# Estonian one-line description per quest id (keys match economy.QUESTS_*). +QUEST_DESCRIPTIONS: dict[str, str] = { + # Daily + "work3": "Tööta 3 korda (/work)", + "beg5": "Kerja 5 korda (/beg)", + "wager500": "Panusta kokku 500 ⬡ hasartmängudes", + "fish2": "Püüa 2 kala (/fish)", + "crime1": "Soorita edukalt 1 kuritegu (/crime)", + "earn1000": "Teeni kokku 1 000 ⬡", + "give200": "Kingi teistele kokku 200 ⬡ (/give)", + # Weekly + "work20": "Tööta 20 korda (/work)", + "fish15": "Püüa 15 kala (/fish)", + "wager5000": "Panusta kokku 5 000 ⬡ hasartmängudes", + "crime5": "Soorita edukalt 5 kuritegu (/crime)", + "heist1": "Osale 1 grupiröövis (/heist)", + "earn10000": "Teeni kokku 10 000 ⬡", +} + +# --------------------------------------------------------------------------- +# Shop UI strings +# --------------------------------------------------------------------------- + +SHOP_UI: dict[str, str] = { + "tier_1": "Tier 1 - Algaja", + "tier_2": "Tier 2 - Kogenud", + "tier_3": "Tier 3 - Legend", + "desc": "Saldo: {bal} · Osta käsuga `/buy`", + "owned": "✅ Olemas", + "owned_uses_1": "✅ Olemas ({uses} kasutus järel)", + "owned_uses_n": "✅ Olemas ({uses} kasutust järel)", + "locked": "🔒 Tase {min_lvl} nõutud *(sul on {user_lvl})*", +} + +# --------------------------------------------------------------------------- +# Shop item descriptions (keyed by SHOP dict key in economy.py) +# --------------------------------------------------------------------------- + +ITEM_DESCRIPTIONS: dict[str, str] = { + "gaming_hiir": "Koolist varastatud hiir? Ei, see on mängurihiir. Teeni töötades 50% rohkem TipiCOINe.", + "hiirematt": "XXL suuruses, ainult parimast materjalist. Kerjamise ooteaeg 5min → 3min.", + "korvaklapid": "Noise-cancelling - kuuled ainult TipiCOINide kõlinat. Päevase boonuse ooteaeg 20h → 18h + 25⬡ boonust.", + "lan_pass": "Ametlik TipiLANi pilet (2025). Päevane boonus on duubeldatud.", + "energiajook": "Kolm Red Bulli järjest. 30% tõenäosus, et teenid töötades 3x rohkem.", + "gaming_laptop": "RTX 5090 jooksutab botte 24/7. Päevane boonus genereerib 5% intressi sinu saldo pealt.", + "anticheat": "VAC, EAC, Faceit AC ja BattlEye korraga. Röövimine sinu vastu ebaõnnestub. **2 kasutust**, siis pead ostma uue.", + "reguleeritav_laud": "Võid nii seista kui istuda - alati võidad. /work teenib 25% rohkem (stackib mängurihiirega).", + "jellyfin": "Self-hosted meediaserver - oled suurfirmadest sõltumatu. Röövimise edu 45% → 60%. Grupiröövi õnnestumisele +5%.", + "mikrofon": "Parem helikvaliteet teeb sind usutavamaks. Teeni 30% rohkem eduka /crime puhul.", + "klaviatuur": "Klõbinad kostuvad üle kogu saali. /beg teenib 2x rohkem.", + "monitor": "240Hz ja 27 tolli. /work ooteaeg: 1h → 40min.", + "cat6": "Gigabitine internet = ideaalne piraatluseks. /crime edu tõenäosus tõuseb 60% → 75%.", + "monitor_360": "360Hz, 1ms. Mänguautomaadi jackpot 10x → 15x, kolmik 4x → 6x. Hasartmängude ooteaeg 30s → 25s.", + "karikas": "Ainult legendidele. Streak ei nulli, kui sa mõne päeva vahele jätad.", + "gaming_tool": "Nii mugav, et isegi admin ei saa sind üles. /crime ebaõnnestumine ei saada sind vanglasse.", + "ussipurk": "Lakkumatu toiduga ussipurk - kalad ei saa vastu. Kalapyygi ooteaeg 2min → 90s.", + "kalavork": "Suurem võrk = suuremad kalad. Kõigi kalade haruldus tõuseb ühe astme võrra.", + "echolood": "Täpne ehholood näitab kala täpset asukohta. Haukamise aken 2s → 3s.", +} +JAILED_UI: dict[str, str] = { + "title": "🔒 Praegu vanglas", + "empty": "Kõik on vabad! Vanglas pole kedagi.", + "entry": "• {mention} - vabaneb ", + "footer": "{count} vang{plural}", +} +SHOP_BTN: dict[int, str] = { + 1: "Tier 1", + 2: "Tier 2", + 3: "Tier 3", +} + +# --------------------------------------------------------------------------- +# /daily embed strings +# --------------------------------------------------------------------------- + +DAILY_UI: dict[str, str] = { + "earned": "✅ Said {earned}!", + "interest": E["TipiLAP"] + " Bot Farm tootis: +{interest}", + "vip": f"{E['TipiPILET']} LAN pileti boonus rakendus!", + "footer": "Streak: {streak_str} · Saldo: {balance}", +} + +# --------------------------------------------------------------------------- +# /stats embed strings +# --------------------------------------------------------------------------- + +STATS_UI: dict[str, str] = { + "economy_field": "💰 Majandus", + "economy_val": "Tipp-saldo: {peak}\nEluaegne tulu: {earned}\nEluaegne kaotus: {lost}", + "work_field": "🛠️ Töö & Kerja", + "work_val": "Töötanud: **{work}** korda\nKerjanud: **{beg}** korda", + "gamble_field": "🎲 Hasartmängud", + "gamble_val": "Panustatud kokku: {wagered}\nSuurim võit: {win}\nSuurim kaotus: {loss}\nSlotsi jackpotid: **{jackpots}** korda", + "crime_field": "🦹 Kuritegevus", + "crime_val": "Kuriteod: **{crimes}** ({succeeded} õnnestus)\nHeistid: **{heists}** ({heists_won} võideti)\nVangi sattunud: **{jailed}** korda\nKautsjon makstud: {bail}", + "social_field": "🤝 Sotsiaalne", + "social_val": "Kingitud: {given}\nSaadud: {received}", + "records_field": "🔥 Rekordid", + "records_val": "Pikim päevane streak: **{streak}** päeva", +} + +# --------------------------------------------------------------------------- +# /profile tabbed view +# --------------------------------------------------------------------------- + +PROFILE_UI: dict[str, str] = { + "btn_profile": "💰 Profiil", + "btn_items": "🎒 Esemed", + "btn_stats": "📊 Statistika", + "btn_fish": "🎣 Kalakogu", + "main_title": "💰 {name}", + "items_title": "🎒 {name} - Esemed", + "stats_title": "📊 {name} - Statistika", + "fish_title": "🎣 {name} - Kalakogu", + "items_empty": "Sul pole ühtegi eset.", + "f_balance": "💰 Saldo", + "f_level": "📊 Tase", + "f_streak": "🔥 Streak", + "f_prestige": "⭐ Prestiiz", + "f_jail": "🚔 Vangis kuni", + "f_progress": "→ Tase {next}", + "progress_bar": "`{bar}` {done}/{needed} EXP", + "level_val": "Tase {level} - {role}", + "prestige_val":"⭐ P{level} · {pp} PP", + "footer_t1": "Tase 10 avab T2 poe · Tase 20 avab T3 poe", + "footer_t2": "T2 pood avatud · Tase 20 avab T3 poe", + "footer_t3": "T2 ja T3 pood avatud", +} + +# --------------------------------------------------------------------------- +# /balance embed strings +# --------------------------------------------------------------------------- + +BALANCE_UI: dict[str, str] = { + "saldo": "Saldo", + "streak": "Päeva streak", + "streak_val": "🔥 {streak}p", + "jailed_until": "🚔 Vangis kuni", + "items": "Esemed", + "uses_one": " *({uses} kasutus järel)*", + "uses_many": " *({uses} kasutust järel)*", +} + +# --------------------------------------------------------------------------- +# /cooldowns embed strings +# --------------------------------------------------------------------------- + +COOLDOWNS_UI: dict[str, str] = { + "ready": "✅ Valmis", + "daily_line": "📅 **/daily** {status}{note}", + "work_line": "💼 **/work** {status}{note}", + "beg_line": "🙏 **/beg** {status}{note}", + "crime_line": "🦹 **/crime** {status}", + "rob_line": "🔫 **/rob** {status}", + "fish_line": "🎣 **/fish** {status}{note}", + "note_korvak": " *(kõrvaklapid: 18t)*", + "note_monitor": " *(monitor: 40min)*", + "note_hiirematt": " *(hiirematt: 3min)*", + "note_ussipurk": " *(ussipurk: 90s)*", + "jailed": "\n🔒 **Vanglas** - vabaneb ", + "jail_expired": "\n🔓 Vangla lõppes", +} + +# --------------------------------------------------------------------------- +# /rank embed strings +# --------------------------------------------------------------------------- + +RANK_UI: dict[str, str] = { + "title": "📊 {name} - Tase {level}", + "field_title": "Tiitel", + "field_exp": "EXP", + "field_progress": "Progress → Tase {next}", + "progress_val": "`{bar}` {progress}/{needed} EXP", + "footer_t1": "Tase 10 avab T2 poe · Tase 20 avab T3 poe", + "footer_t2": "T2 pood avatud · Tase 20 avab T3 poe", + "footer_t3": "T2 ja T3 pood avatud", +} + +# --------------------------------------------------------------------------- +# /work embed strings +# --------------------------------------------------------------------------- + +WORK_UI: dict[str, str] = { + "desc": "Sa {job} ja teenisid {earned}!", + "redbull": f"\n{E['TipiBULL']} Red Bull aktiveerus - 3x boonus!", + "hiir": f"\n{E['TipiHIIR']} Mängurihiir: +50% palk", + "laud": f"\n{E['TipiLAUD']} Reguleeritav laud: +25% palk", + "balance": "\nSaldo: {balance}", +} + +# --------------------------------------------------------------------------- +# /beg embed strings +# --------------------------------------------------------------------------- + +BEG_UI: dict[str, str] = { + "desc": "Sa {text} ja said {earned}.", + "klaviatuur": f"{E['TipiKLAVA']} Mehhaaniline klaviatuur: 2x tulu", + "balance": "Saldo: {balance}", +} + +# --------------------------------------------------------------------------- +# /crime embed strings +# --------------------------------------------------------------------------- + +CRIME_UI: dict[str, str] = { + "win_desc": "Sa {text} ja teenisid {earned}!", + "fail_base": "Sa {text} ja said trahvi {fine}.", + "fail_jailed": "\n\ud83d\udd12 Oled vangis! P\u00e4\u00e4sed {ts}.", + "fail_shield": "\n\ud83d\udee1\ufe0f Gaming Tool hoidis sind vanglast!", + "mikrofon": f"\n{E['TipiMIC']} Mikrofon: +30% saak", + "cat6": f"\n{E['TipiCAT']} CAT6: 75% edu t\u00f5en\u00e4osus", + "balance": "\nSaldo: {balance}", +} + +# --------------------------------------------------------------------------- +# /rob embed strings +# --------------------------------------------------------------------------- + +ROB_UI: dict[str, str] = { + "jackpot_desc": "💥 **JACKPOT!** Murdsid TipiBOTi kassasse sisse ja varastasid {stolen}!\nSaldo: {balance}", + "win_desc": "Varastasid {stolen} kasutajalt **{name}**!\nSaldo: {balance}", + "anticheat_desc": "**{name}** kaitseb end Anticheati'ga - said trahvi {fine}.", + "anticheat_worn": "⚠️ Sinu **Anticheat** on kulunud! Osta uus `/buy` käsuga.", + "victim_dm": "💸 **{robber}** varastas sinult **{stolen}** münti!", + "fail_desc": "Jäid vahele! Trahv: {fine}.\nSaldo: {balance}", +} + +# --------------------------------------------------------------------------- +# /give embed strings +# --------------------------------------------------------------------------- + +GIVE_UI: dict[str, str] = { + "desc": "**{giver}** andis {amount} kasutajale **{receiver}**.", +} + +# --------------------------------------------------------------------------- +# /buy embed strings +# --------------------------------------------------------------------------- + +BUY_UI: dict[str, str] = { + "title": "{emoji} {name} ostetud!", + "desc": "{description}\nUus saldo: {balance}", +} + +# --------------------------------------------------------------------------- +# /leaderboard UI strings +# --------------------------------------------------------------------------- + +LEADERBOARD_UI: dict[str, str] = { + "house_entry": "🤖 {name} *(maja)* - {balance}", + "house_default_name": "TipiBOT", + "no_entries": "Keegi ei ole veel punkte teeninud.", + "footer": "Lehekülg {page}/{total} · {count} mängijat", + "btn_coins": "🪙 Mündid", + "btn_exp": "📊 EXP", + "btn_find_me": "📍 Mina", + "exp_entry": "{prefix} {name} - {exp} EXP *(Tase {level})*", + "unknown_user": "Kasutaja {uid}", + "btn_season": "🏆 Hooaeg", + "btn_prestige": "🔥 Prestiiž", + "btn_wagered": "🎲 Hasartmäng", + "btn_fish": "🎣 Kalapyyk", + "season_entry": "{prefix} {name} - {exp} EXP *(Prestiiž {prestige})*", + "prestige_entry": "{prefix} {name} - Prestiiž **{prestige}** · {pp} PP", + "wagered_entry": "{prefix} {name} - {wagered} panustatud", + "fish_entry": "{prefix} {name} - {caught} kala", +} + +# --------------------------------------------------------------------------- +# /request UI strings +# --------------------------------------------------------------------------- + +REQUEST_UI: dict[str, str] = { + "modal_title": "Rahasta taotlust", + "modal_label": "Kui palju soovid panustada?", + "btn_fund": "Rahasta 💸", + "btn_funded": "Rahastatud ✅", + "btn_fund_remaining": "Rahasta 💸 ({remaining}⬡ jäänud)", + "funded_line": "✅ **{name}** panustas {amount}", + "funded_full": "\n🎯 Taotlus täielikult täidetud!", + "funded_partial": "\n💰 Jäänud: {remaining}", + "audience_all": "Avatud kõigile rahastajatele 🌍", + "audience_targeted": "Suunatud: **{name}**", + "desc": "**{requester}** palub {amount}\n\n📋 **Põhjus:** {reason}\n\n{audience}", + "footer": "Taotlus aegub 5 minuti pärast", +} diff --git a/strings/fishing.py b/strings/fishing.py new file mode 100644 index 0000000..850e193 --- /dev/null +++ b/strings/fishing.py @@ -0,0 +1,86 @@ +"""Fishing minigame: fish catalogue, rarities, and /fish UI. + +Auto-split from the original strings.py; edit strings here. +""" + +__all__ = [ + 'FISH_NAMES', + 'FISH_RARITY_NAMES', + 'FISH_RARITY_EMOJI', + 'FISH_JUNK_LINES', + 'FISH_UI', +] + +# --------------------------------------------------------------------------- +# Fishing system strings +# --------------------------------------------------------------------------- + +FISH_NAMES: dict[str, str] = { + "sarj": "Särg", + "ahven": "Ahven", + "koger": "Koger", + "viidikas": "Viidikas", + "latikas": "Latikas", + "karpkala": "Karpkala", + "linask": "Linask", + "haug": "Haug", + "angerjas": "Angerjas", + "siig": "Siig", + "forell": "Forell", + "koha": "Koha", + "tougjas": "Tõugjas", + "lohe": "Lõhe", + "vimb": "Vimb", +} +FISH_RARITY_NAMES: dict[str, str] = { + "common": "Tavaline", + "uncommon": "Ebatavaline", + "rare": "Haruldane", + "epic": "Eepiline", + "legendary": "Legendaarne", +} +FISH_RARITY_EMOJI: dict[str, str] = { + "common": "🐟", + "uncommon": "🐠", + "rare": "🎣", + "epic": "⭐", + "legendary": "🌟", +} +FISH_JUNK_LINES: list[str] = [ + "Sa saad... **vana saabas**. Klassika.", + "Õnnitlused, leidsid **kasutatud autorehvi**. Keskkond tänab sind... mitte.", + "Taas üks **klaaspudel** rohkem jões.", + "**Vana poes käimise kott**! Hoidis aega hästi.", + "**Roostes konserv** - ilma sildita. Parem mitte teada, mis sees on.", + "**Ummistunud drenaažitoru**. Keegi oli hoolimatu.", + "**Tühi rahakott**. Kellegi päev läks halvemaks kui sinu oma.", + "**Vana CD-plaat** - Evanescence, 2003. Heas seisukorras.", + "Sa said **kivikese**. Ilus kivikene. Aga siiski kivikene.", + "**Kaotsi läinud droon**. GPS ei tööta, aku tühi.", +] +FISH_UI: dict[str, str] = { + "btn_wait": "🎣 Oota näkkamist...", + "btn_bite": "🐟 TÕMBA!", + "btn_sell": "💰 Müü", + "btn_keep": "🎒 Hoia", + "cast_desc": "Viskad õnge vette. Oota, kuni kala näkkab...\n\n-# Vajuta nuppu, kui kala näkkab!", + "bite_desc": "**KALA NÄKKAB!** Tõmba kiiresti! ⚡\n\n-# Sul on 2 sekundit!", + "escape_desc": "Liiga hilja - kala lipsas minema. Proovi järgmine kord kiiremini!", + "junk_desc": "{text}\n\n-# Saldo: {balance}", + "catch_desc": "**{name}** · {weight}g · +{exp} EXP\n-# Kas müüd kohe ({value}) või hoiad inventaris?", + "catch_sold": "**{name}** · {weight}g\n\n+{coins} · +{exp} EXP\nSaldo: {balance}", + "catch_kept": "**{name}** · {weight}g lisatud inventarisse. *(+{exp} EXP)*", + "new_fish": "\n✨ **Uus kala kalakogusse lisatud!**", + "too_early": "❌ Kala pole veel näkkanud! Oota...", + "book_caught": "Püütud kalaliike: **{caught}/{total}**", + "book_yes": "✅ {emoji} **{name}** *({rarity})* · {count}×{inv}", + "book_inv": " *(inventaris: {n})*", + "book_no": "❓ **???** *({rarity})*", + "book_footer": "Lehekülg {page}/{total_pages} · {caught}/{total} liiki", + "book_empty": "Sa pole veel ühtegi kala püüdnud! Kasuta `/fish`.", + "inv_empty": "Sinu kalainventaar on tühi! Kasuta `/fish` kala püüdmiseks.", + "inv_header": "Sul on **{count}** kala inventaris *(kokku väärt {total_value})*", + "inv_entry": "{emoji} **{name}** · {weight}g · {value}", + "inv_sold_all": "Müüsid **{count}** kala kokku {coins} eest!\nSaldo: {balance}", + "inv_none": "Inventaaris pole midagi müüa.", +} diff --git a/strings/games.py b/strings/games.py new file mode 100644 index 0000000..1cada4c --- /dev/null +++ b/strings/games.py @@ -0,0 +1,307 @@ +"""Minigames & gambling: slots, roulette, RPS, blackjack, heist, jailbreak. + +Auto-split from the original strings.py; edit strings here. +""" + +from core.emoji import EMOJI as E + +__all__ = [ + 'SLOTS_TIERS', + 'ROULETTE', + 'HEIST_STORY', + 'HEIST_UI', + 'BJ', + 'JAILBREAK_UI', + 'SLOTS_UI', + 'RPS_UI', + 'RPS_CHOICES', + 'BJ_UI', +] + +# --------------------------------------------------------------------------- +# /slots outcome strings (title, colour) +# --------------------------------------------------------------------------- + +SLOTS_TIERS: dict[str, tuple[str, int]] = { + "jackpot": (f"{E['TipiFIRE']} JACKPOT!!!", 0xF4C430), + "triple": ("🎰 Kolmik!", 0x57F287), + "pair": ("🎰 Paar", 0x99AAB5), + "miss": (f"{E['TipICRY']} Ei õnnestunud", 0xED4245), +} + +# --------------------------------------------------------------------------- +# /roulette outcome strings +# --------------------------------------------------------------------------- + +ROULETTE: dict = { + "emoji": {"punane": "🔴", "must": "⚫", "roheline": "🟢"}, + "genitive": {"punane": "punase", "must": "musta", "roheline": "rohelise"}, + "win_title": "{emoji} Võitsid!", + "lose_title": "{emoji} Kaotasid!", + "win_desc": "Ratas peatus **{genitive}** peal!{mult}\n+{change}\nSaldo: {balance}", + "lose_desc": "Ratas peatus **{genitive}** peal.\n-{change}\nSaldo: {balance}", + "spin_title": "🎰 Ratas keerleb...", + "spin_stop": "🎰 Ratas peatub...", + "spin_strip": "{s0} {s1} {s2} {s3} {s4}", +} + +# --------------------------------------------------------------------------- +# /heist narrative story lines +# Placeholders: {leader}, {member}, {names}, {vehicle} +# --------------------------------------------------------------------------- + +HEIST_STORY: dict = { + "vehicles": [ + "Škoda", + "BMW", + "Lada", + "Mazda", + ], + "arrival": [ + "{leader} keerab nurga taga {vehicle} mootori kinni. Maskid ette. Keegi ei räägi.", + "{vehicle} peatub ühe kvartali kaugusel sihtmärgist. {leader}: *\"Pank on seal. Tegutseme plaani järgi.\"*", + "Meeskond astub {vehicle}st välja. {leader} kuulab kõrvamonitori. *\"Kaks valvurit, üks pimeala. Liigume nüüd.\"*", + "{leader} jälgib {vehicle}st sissepääsu. *\"Valvurite vahetus 40 sekundi pärast. See on meie ajaaken.\"*", + "Kell 3 öösel. Tänav on tühi. {vehicle} seisab väljas tühikäigul. {leader} tõmbab maski ette.", + "{vehicle} veereb aeglaselt vaiksesse pimedasse vahetänavasse. {leader}: *\"Viimane kontroll. Kõik valmis?\"*", + "{leader} koputab armatuurlauale. *\"Kui midagi läheb valesti, me lahkume kohe.\"* Vaikus vastuseks.", + "Tuul sahiseb mööda tühja tänavat. {vehicle} uksed avanevad korraga.", + "{member} kontrollib relva. {leader} vaatab kella. *\"Me oleme graafikus.\"*", + "{vehicle} tuled kustuvad. Linn jääb vaikseks. Nad liiguvad.", + ], + "entry_sneaky": [ + "{member} tõmbab kloonitud kaarti külgukse juures. Lukk klõpsab hääleta lahti.", + "Meeskond libiseb sisse laadimisestakaadi kaudu, riietatud öisteks koristajateks.", + "{leader} on kaks nädalat valvurite graafikut pähe õppinud. Röövlid kõnnivad sisse vahetuse ajal.", + "Võltsitud alltöövõtja kaardi abil saavad nad fuajeest läbi ilma lisaküsimuseta.", + "{member} lülitab välikaamerad sülearvutist välja. {leader} kõnnib sisse, nagu see oleks tema oma maja.", + "{member} kasutab signaaliblokeerijat. Häired ei jõua kunagi süsteemi.", + "{leader} avab ventilatsiooniluugi. *\"Läheme ülevalt.\"*", + "Turvamees haigutab. Sekund hiljem on ta seotud ja vaikselt nurka lohistatud.", + "{member} süstib lukku mikrokaamera. Mehhanism kaardistatakse sekunditega.", + ], + "entry_loud": [ + "{leader} lööb esiuksed lahti. *\"KÕIK PÕRANDALE - KOHE!\"*", + "Esmalt suitsugranaadid. Selleks ajaks, kui suits vaibub, on meeskond juba sees.", + "{leader} tulistab ühe lasu lakke. Haudvaikus. *\"Oleme siin seifi pärast! Kui teete koostööd, siis pääsete elusana.\"*", + "*\"Kui keegi ei liigu, ei saa keegi ka viga.\"* {leader} omab ruumi täielikku tähelepanu.", + "{member} lükkab kilbist elektri välja. Pimeduses juhib {leader} meeskonna mälu järgi edasi.", + "*\"See on rööv! Kõik pikali!\"* {leader} hääl kajab läbi saali.", + "Alarm hakkab ulguma juba enne, kui nad täielikult sisse jõuavad.", + "Klaas puruneb. Inimesed karjuvad. Täielik kaos.", + ], + "inside": [ + "{names} liiguvad kiiresti läbi fuajee, sidudes turvamehi postide külge kinni.", + "{member} katab väljapääsud. {leader} suundub otse seifi poole.", + "Üks kassapidajatest proovib käivitada vaikset häiret, kuid {member} märkab ta nihelemist ja peatab ta hoiatuslasuga.", + "{leader} hoiab töötajad rahulikuna samal ajal, kui teised suunduvad alumisele korrusele.", + "Turvakaamerad on tsüklil. {names} on korrusel üksi.", + "{member} kontrollib kellaaega. *\"Me oleme 30 sekundit ees.\"*", + "{leader} annab käemärgi. Meeskond jaguneb ilma sõnadeta.", + "Koridor on tühi. Liiga tühi. {leader} peatub hetkeks.", + "{names} liiguvad trepist alla, sammud summutatud.", + "Üks uks on lukus. {member} avab selle sekundiga.", + ], + "vault": [ + "Neljanda taseme ajalukuga seif. {member} tõmbab puuri välja. *\"Anna mulle kolm minutit.\"*", + "{leader} vaatab seifi ust. *\"Dünamiit.\"* Keegi ei vaidle.", + "{member} ühendub seifi juhtpaneeliga. Vana tarkvara. Ülevõtmine võtab 90 sekundit.", + "Seifil on käsikombinatsiooni lukk. Hea, et {leader} veetis kuu aega juhatajaga, teenides tema usaldust.", + "{member} paigutab lõhkeained. Meeskond astub tagasi. Üks kontrollitud plahvatus.", + "{leader} teeb magnetlukule tühistuse. Nagu õpikust võetud. Mehhanism annab järgi.", + "{member} higistab. *\"See pole standardlukk... anna mulle aega.\"*", + "{leader} kuulab vastu seifi ust. *\"Sees on liikumisandur.\"*", + "{member} lõikab läbi metallkihi nagu võid.", + "Ajurünnak. {leader} meenutab skeemi ja leiab nõrga koha.", + "{member} ühendab juhtmed ümber. Säde. Vaikus. Lukk avaneb.", + ], + "vault_open": [ + "Uks avaneb. Kuhi-kuhja järel raha, põrandast laeni. Täpselt nagu plaanitud.", + "*\"...jackpot.\"* {leader} piilub seifi sisse. Meeskond seisab hetkeks vaikuses.", + "{member} hakkab kotte täis laduma. {leader} piilub juba väljapääsu poole.", + "Puhas. Kiire. {names} on seifis ja täidavad kotte enne, kui tolm settib.", + "Seif on lahti. {leader} võtab hinge. *\"Okei. Kottidesse ja liikuma.\"*", + "{leader} naeratab esimest korda. *\"See oli seda väärt.\"*", + "Raha lõhn täidab õhu. {member}: *\"Võtame kõik.\"*", + "{names} töötavad vaikides. Iga liigutus loeb.", + "Kotid täituvad kiiremini kui oodatud.", + "{leader} pilk muutub tõsiseks. *\"Aeg otsas. Liigume.\"*", + ], + "police_inbound": [ + "Raadio krõbiseb. *\"Kõik üksused, relvastatud rööv Keskpangas-\"*", + "Väljas on kuulda eemalt ulguvaid sireene. {leader}: *\"Meil on umbes neli minutit. Liikuma.\"*", + "Punased ja sinised tuled vilguvad ülemistest akendest läbi. Varualarm käivitati.", + "Politsei helikopter skaneerib piirkonda prožektoriga. Aken sulgub kiiresti.", + "{member} kontrollib politsei skännerit. *\"Nad teavad. Kolm üksust, kaks minutit eemal.\"*", + "{member} kuulab raadiosidet. *\"Nad sulgevad kvartaleid.\"*", + "Sireenid lähenevad kiiremini kui plaanitud.", + "Helikopteri valgus libiseb üle akna. Liiga lähedal.", + ], + "getaway_success": [ + "Adrenaliin. {names} jooksevad {vehicle} juurde. Kõik sees. {leader} keerab mootori käima.", + "{member} haarab roolist. {leader} on kõrval. *\"Lähme.\"* Rahulikult.", + "{leader} libistab {vehicle} kõrvalteed pidi minema. Sireen kaugel taga. Nad on kiiremad.", + "Rohelised tuled. {vehicle} sõidab vaikselt mööda parklas ootavast patrullautost. Keegi ei märka.", + "{member} näitab teed. {leader} sõidab vaikselt läbi tagakvartali. Käed lõdvad.", + "{vehicle} rehvid vilisevad, kui nad pööravad kitsasse tänavasse.", + "{leader} sõidab ilma tuledeta. Ainult mälu juhib teda.", + "{member} vaatab kaarti. *\"Vasak, siis kohe parem!\"*", + "Mootor möirgab. Nad kaovad öösse.", + "{vehicle} libiseb läbi viimase rohelise tule.", + ], + "getaway_fail": [ + "{names} jooksevad {vehicle} juurde. Sireenid igalt poolt.", + "{member} haarab roolist. {leader} on kõrval. *\"Mine! MINE!\"*", + "{vehicle} kihutab tänavale, kuid helikopteri valgusvihk osutab neile. Kõik on nähtaval.", + "Kolm patrullautot jõuavad nende taha. {member} vaatab üle õla. *\"Nad on meil kannul.\"*", + "Raadio krõbiseb. *\"Sihtmärk kinnitatud. Blokeeri Liivalaia tänav.\"*", + "{vehicle} ei käivitu. {member}: *\"Päriselt ka või?!\"*", + "{member} komistab teel autoni. Tal oli pael lahti tulnud", + "{leader} avastab, et autot pole kuskil näha. See pukseeriti ära." + ], + "escape_success": [ + "{names} murravad läbi perimeetri enne väravate sulgemist. Puhas põgenemine.", + "{leader} oli planeerinud kolm väljumisteed. Vaja läks ühte. {vehicle} kaob linna.", + "Kahe kvartali kaugusel asuv peibutushäire tõmbab üksused eemale. {names} on kadunud enne, kui keegi seifi kontrollib.", + "Naelribad? Juba eemaldatud. Teeblokk? Vale tänav. {leader} mõtles kõigele.", + "{vehicle} sõidab maanteele nagu poleks midagi juhtunud. {leader} hingab esimest korda tunnis välja.", + "*\"Oleme vabad.\"* {member} piilub kardinate tagant välja. Tühi tänav. Nad tegid ära.", + "{names} kaovad sügavale linna nagu neid poleks kunagi olnud.", + "Raadio jääb vaikseks. Keegi ei jälita enam.", + "{vehicle} jäetakse maha. Uus plaan aktiveerub.", + "{leader}: *\"See oli liiga lihtne...\"*", + ], + "escape_fail": [ + "Patrullauto lõikab {vehicle} teekonna sillal ära. Mõlemalt poolt ümbritsetud. Ongi läbi.", + "{member} kukutab koti. Kolm sekundit kõhklust - ja uksed on ümber piiratud.", + "Helikopter jälgib neid kuni pelgupaigani. Kõik väljapääsud on kaetud.", + "{leader} arvutab võimalusi. *\"Väljapääsu pole.\"* Käed lähevad üles.", + "Naelribad lõhuvad {vehicle} rehvid. Meeskond libiseb liikluse keskele seisma.", + "{vehicle} põrkub vastu teetõket. Mootor sureb. Igast suunast tuled.", + ], +} + +# --------------------------------------------------------------------------- +# /heist UI strings +# --------------------------------------------------------------------------- + +HEIST_UI: dict[str, str] = { + "names_duo": "**{a}** ja **{b}**", + "names_sep": " & ", + "names_crew": "**{leader}** ja meeskond", + "btn_join": "Ühine röövimisega 🔫", + "btn_start": "Alusta kohe ▶", + "already_joined": "Sa oled juba sees!", + "only_organizer": "Ainult heisti algataja saab heisti alustada.", + "lobby_desc": "**Osalejad ({n}/{max}):**\n{names}\n\nÕnnestumise tõenäosus: **{chance}%**\n\n*Ühinemisaken sulgub *", + "cancel_desc": "Ei piisanud osalejaid (vajad vähemalt **{min}**). Heist tühistati.", + "started_title": "🔫 Grupirööv käib...", + "started_desc": "**{n}** osalejat alustasid heisti. Jälgi allpool!", + "story_title": "🔫 Grupirööv", + "win_desc": "**Osalejad:**\n{names}\n\nSaak jagati võrdselt.\n**Igaüks sai: +{payout}**", + "fail_desc": "**Osalejad:**\n{names}\n\nKõik osalejad saavad **1,5 tundi vangi** + trahv ~15% saldost.", +} + +# --------------------------------------------------------------------------- +# Blackjack in-game strings +# --------------------------------------------------------------------------- + +BJ: dict[str, str] = { + "dealing": "*Jagame kaardid...*", + "result_field": "Tulemus", + "push_result": "±0 (panus tagasi)", + "doubled_label": "💰 *Topeltpanus: {total}*", + "btn_hit": "🃏 Võta kaart", + "btn_stand": "✋ Seisa", + "btn_double": "💰 Kahekordista (+{bet}⬡)", + "btn_split": "✂️ Split (+{bet}⬡)", +} + +# --------------------------------------------------------------------------- +# /jailbreak UI strings +# --------------------------------------------------------------------------- + +JAILBREAK_UI: dict[str, str] = { + "btn_roll": "🎲 Viska täringud ({try_}/{max})", + "rolling_desc": f"{E['TipiDICE']} *Täringud lendavad...*", + "free_desc": "{d1} {d2}\n\n✅ Viskasid duubli - pääsesid vanglast!", + "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 **(20–30% saldost, min 350 ⬡)** või jää vanglasse kuni aja lõpuni.", + "already_bail": "Oled juba täringuid visanud. Ainuke väljapääs on kautsjon.\n\n💰 **Kautsjon: {min} – {max}** (20–30% saldost)\nSaldo: {bal} Väljas: {ts}", + "already_broke": "Oled juba täringuid visanud. Sul pole piisavalt raha kautsjoni maksmiseks.\n\n💰 Kautsjoni miinimum: **{min}** - sul on ainult {bal}\nVäljas: {ts}", + "bail_btn": "💸 Maksa kautsjon", + "bail_broke_desc": "❌ Sul pole piisavalt raha (min {min}).\nJääd vanglasse kuni aja lõpuni! Saldo: {balance}", + "bail_paid_desc": "✅ Kautsjon makstud: **{fine}**\nOled vaba! Saldo: {balance}", + "bail_already_free": "✅ Oled juba vaba - kautsjonit ei võetud. Saldo: {balance}", + "fail_broke_desc": "{d1} {d2} - ei olnud duubel\n\n❌ Sul pole kautsjoni maksmiseks piisavalt raha (min 350 ⬡).\nJääd vanglasse kuni aja lõpuni! Saldo: {balance}", + "fail_bail_desc": "{d1} {d2} - ei olnud duubel\n\nKautsjon makstud: **{fine}**\nSaldo: {balance}", + "fail_bail_offer": "{d1} {d2} - ei olnud duubel\n\n💰 **Kautsjon: {min} - {max}** (20-30% saldost)\nSaldo: {bal}\n\nSaad maksta kautsjoni või jääda vanglasse kuni aja lõpuni.", +} + +# --------------------------------------------------------------------------- +# /slots additional UI strings (titles/footers per outcome) +# --------------------------------------------------------------------------- + +SLOTS_UI: dict[str, str] = { + "playing": "🎰 Mängimas...", + "jackpot_footer": E["TipiKARIKAS"] + " Kolm karikat! +{change}", + "triple_footer": "✅ Kolm ühesugust! +{change}", + "pair_footer": "Kaks ühesugust! +{change}", + "miss_footer": "-{amount}", + "balance_line": "\nSaldo: {balance}", +} + +# --------------------------------------------------------------------------- +# /rps UI strings +# --------------------------------------------------------------------------- + +RPS_UI: dict[str, str] = { + "vs_bot_desc": "Tee oma valik! ⬇️", + "vs_bot_bet": "\nPanus: {bet}", + "result_tie": "🤝 Viik!", + "result_win": "🎉 Sina võitsid!", + "result_lose": "🤖 Bot võitis!", + "result_desc": "Sina: {player_pick} {player_name}\nBot: {bot_pick} {bot_name}\n\n**{result}**{bet_line}", + "bet_win": "\n+{amount} · Saldo: {balance}", + "bet_lose": "\n-{amount} · Saldo: {balance}", + "bet_tie": "\nViik - panus tagasi · Saldo: {balance}", + "challenge_desc": "{challenger} kutsub välja {opponent}{bet}\n\n{opponent}, kas võtad vastu? ⬇️", + "challenge_bet": " · Panus: {bet}", + "challenge_footer": "Väljakutse aegub 60 sekundi pärast", + "duel_active_desc": "{a} vs {b}{bet}\n\nMõlemad mängijad valivad DM-is. ⏳", + "duel_active_bet": " · Panus: {bet}", + "duel_dm": "⚔️ **KPK vs {opponent}**{bet}\nTee oma valik! ⬇️", + "duel_dm_bet": "\nPanus: {bet}", + "duel_waiting": "Valisid {choice} **{name}**. Ootame vastase valikut... ⏳", + "duel_result_a": "**⚔️ KPK tulemus vs {opponent}**\nSinu valik: {pick_a} {name_a}\nVastase valik: {pick_b} {name_b}\n\n**{result}**{bet_line}\nSaldo: {balance}", + "duel_verdict_win": "🏆 **{name}** võitis!", + "duel_verdict_tie": "🤝 Viik!", + "duel_broke": "\n⚠️ Makse ebaõnnestus (ebapiisav saldo)", + "duel_expire_dm": "⏰ KPK duell aegus - keegi ei teinud valikut õigeaegselt.", + "duel_expire_desc": "{a} vs {b}\n\nMäng aegus - valik jäi tegemata.", + "duel_dm_fail": "Ei saanud DM saata: **{names}**. Kontrolli privaatsussätteid.", + "duel_decline": "**{name}** keeldus väljakutsest.", + "duel_no_answer": "**{name}** ei vastanud väljakutsele.", + "duel_insufficient": "{mention}-l pole piisavalt TipiCOINi panuseks.", + "duel_done_desc": "{a} {pick_a} vs {pick_b} {b}\n\n**{verdict}**\n\n{name_a}: {bal_a}\n{name_b}: {bal_b}", + "server_only": "Seda käsku saab kasutada ainult serveris.", + "btn_accept": "Võta vastu ✅", + "btn_decline": "Keeldu ❌", + "btn_rock": "🪨 Kivi", + "btn_paper": "📄 Paber", + "btn_scissors": "✂️ Käärid", +} +RPS_CHOICES: dict[str, str] = { + "🪨": "Kivi", + "📄": "Paber", + "✂️": "Käärid", +} +BJ_UI: dict[str, str] = { + "dealer": "Dealer", + "player": "Sina", + "hand_n": "Käsi {n}", + "hand_active": "▶ **Käsi {n}**", + "hand_pending": "Käsi {n} *...*", + "bust": " 💥", + "balance_line": " · Saldo: {balance}", +} diff --git a/strings/member.py b/strings/member.py new file mode 100644 index 0000000..edcfbbb --- /dev/null +++ b/strings/member.py @@ -0,0 +1,96 @@ +"""Member sync, /check, birthdays, channel + economy-setup admin UI. + +Auto-split from the original strings.py; edit strings here. +""" + +__all__ = [ + 'MEMBER_UI', + 'MEMBER_FIELDS', + 'ECONOMYSETUP_UI', + 'CHANNEL_UI', + 'BIRTHDAY_UI', + 'BIRTHDAY_MONTHS', + 'CHECK_UI', +] + +# --------------------------------------------------------------------------- +# /allowchannel /denychannel /channels UI strings +# --------------------------------------------------------------------------- + +MEMBER_UI: dict[str, str] = { + "title": "👤 {name}", + "age_field": "Vanus", + "age_val": "{age}a", +} +MEMBER_FIELDS: list[tuple[str, str]] = [ + ("Nimi", "Nimi"), + ("Organisatsioon", "Organisatsioon"), + ("Valdkond", "Valdkond"), + ("Roll", "Roll"), + ("Sünnipäev", "Sünnipäev"), + ("Meil", "Meil"), + ("Telefon", "Telefon"), + ("Discord", "Discord"), + ("User ID", "Kasutaja ID"), + ("Discordis synced?", "Sünkroniseeritud"), + ("Groupi lisatud?", "Grupis"), +] +ECONOMYSETUP_UI: dict[str, str] = { + "created_field": "✅ Loodud", + "existing_field": "♻️ Juba olemas", + "footer": "Rollid on nüüd boti rolli all õiges järjekorras.", +} +CHANNEL_UI: dict[str, str] = { + "already_allowed": "ℹ️ {channel} on juba lubatud kanalite nimekirjas.", + "added": "✅ {channel} lisatud. Bot vastab käskudele nüüd ainult lubatud kanalites.", + "not_in_list": "ℹ️ {channel} pole lubatud kanalite nimekirjas.", + "removed": "✅ {channel} eemaldatud lubatud kanalite nimekirjast.", + "removed_last": "✅ {channel} eemaldatud. Lubatud kanalite nimekiri on nüüd tühi - bot vastab kõikides kanalites.", + "list_title": "📋 Lubatud kanalid", + "list_empty": "Lubatud kanalite nimekiri on **tühi** - bot vastab käskudele kõikides kanalites.\n\nKasuta `/allowchannel`, et piirata kindlatele kanalitele.", + "list_filled": "Bot vastab käskudele ainult nendes kanalites:\n\n{lines}\n\n-# Kasuta `/allowchannel` / `/denychannel` nimekirja muutmiseks.", +} + +# --------------------------------------------------------------------------- +# /birthdays UI +# --------------------------------------------------------------------------- + +BIRTHDAY_UI: dict[str, str] = { + "no_entries": "Sellel kuul sünnipäevi ei ole.", + "today": "täna 🎉", + "tomorrow": "homme", + "in_days": "{days}p pärast", + "footer": "Leht {month}/12 · {month_name}", +} +BIRTHDAY_MONTHS: list[str] = [ + "Jaanuar", "Veebruar", "Märts", "Aprill", "Mai", "Juuni", + "Juuli", "August", "September", "Oktoober", "November", "Detsember", +] + +# --------------------------------------------------------------------------- +# /check summary strings +# --------------------------------------------------------------------------- + +CHECK_UI: dict[str, str] = { + "sheet_stats_header": "📊 **Tabeli statistika** - {total} liiget", + "stat_ok": "✅ **{label}**: kõik täidetud", + "stat_warn": "⚠️ **{label}** puudub ({count}): {names}{more}", + "stat_more": " (+{count} veel)", + "stat_uid": "Kasutaja ID", + "stat_discord": "Discordi kasutajanimi", + "stat_bday": "Sünnipäev", + "no_name": "(no name)", + "done": "**Kontroll lõpetatud!**", + "already_ok": "✅ Juba korras: {count}", + "fixed": "🔧 Parandatud: {count}", + "not_found": "❓ Pole tabelis: {count}", + "bday_pings": "🎂 Sünnipäeva teavitused: {count}", + "errors": "⚠️ Vead: {count}", + "details_header": "**Üksikasjad:**", + "details_more": "... ja {count} rohkem", + "detail_error": "⚠️ {error}", + "detail_nickname": "hüüdnimi", + "detail_roles_added": "+rollid: {roles}", + "detail_changed": "🔧 **{name}**: {parts}", + "ids_filled": "\n🔑 Täideti **{count}** puuduvat kasutaja ID-d.", +} diff --git a/tests/test_strings.py b/tests/test_strings.py new file mode 100644 index 0000000..ce8c671 --- /dev/null +++ b/tests/test_strings.py @@ -0,0 +1,77 @@ +"""Guard tests for the strings/ package. + +strings/ is split into domain submodules whose names are re-exported from +strings/__init__.py so callers keep using `strings.NAME`. It's easy to add a +constant to a submodule and forget to re-export it (or to shadow a name across +two submodules) - both would only surface as a runtime crash in a command. +These tests catch that at test time instead. +""" + +import importlib +import pkgutil + +import strings + +# Auto-discover submodules so a newly added one is covered without editing this. +SUBMODULES = sorted(m.name for m in pkgutil.iter_modules(strings.__path__)) + + +def _submodule(name): + return importlib.import_module(f"strings.{name}") + + +class TestStringsPackage: + def test_submodules_discovered(self): + # Sanity: the split actually produced multiple domain modules. + assert len(SUBMODULES) >= 2, SUBMODULES + + def test_every_submodule_declares_all(self): + for name in SUBMODULES: + mod = _submodule(name) + assert hasattr(mod, "__all__"), f"strings.{name} is missing __all__" + + def test_all_entries_exist_in_their_submodule(self): + for name in SUBMODULES: + mod = _submodule(name) + for const in mod.__all__: + assert hasattr(mod, const), ( + f"{const} is listed in strings.{name}.__all__ " + f"but not defined in that module" + ) + + def test_every_name_is_reexported_from_package(self): + for name in SUBMODULES: + mod = _submodule(name) + for const in mod.__all__: + assert hasattr(strings, const), ( + f"{const} is defined in strings.{name} but not re-exported " + f"from strings/__init__.py - add it to the imports there" + ) + assert getattr(strings, const) is getattr(mod, const), ( + f"strings.{const} is not the same object as strings.{name}.{const}" + ) + + def test_no_name_defined_in_two_submodules(self): + origin = {} + for name in SUBMODULES: + for const in _submodule(name).__all__: + assert const not in origin, ( + f"{const} is defined in both strings.{origin[const]} " + f"and strings.{name}" + ) + origin[const] = name + + def test_package_all_matches_submodule_union(self): + union = set() + for name in SUBMODULES: + union |= set(_submodule(name).__all__) + assert set(strings.__all__) == union, { + "missing_from_package_all": sorted(union - set(strings.__all__)), + "extra_in_package_all": sorted(set(strings.__all__) - union), + } + + def test_public_constants_all_declared(self): + # Every UPPER_CASE constant exposed on the package is accounted for in + # __all__ (E, the emoji helper, is an implementation detail, not a string). + public = {n for n in vars(strings) if n.isupper() and n != "E"} + assert public == set(strings.__all__)