forked from sass/tipibot
feat(economy): add /lottery - daily draw, weighted winner takes the pot
Buy tickets (200 coins each, max 100/draw); one winner is drawn daily at 21:00 Tallinn time weighted by ticket count and credited the whole pot. Coin-conserving by design: each ticket's cost is deducted at purchase and the winner is minted exactly the sum of all ticket spend - no shared pot record, so no cross-period race. Ticket state lives per-user keyed by draw period (full scan only at draw time and for the pot view). - New lottery.py: TICKET_COST/MAX_TICKETS/DRAW_HOUR, pure period_for, and do_buy_ticket / get_lottery_state / do_lottery_draw. New lottery_tickets + lottery_period schema fields (period added to _TEXT_FIELDS). - /lottery [kogus] command (view or buy) with full failure handling. - Scheduled lottery_draw_daily loop in bot.py (both profiles; each draws its own collection), announcing to the optional LOTTERY_CHANNEL_ID (config + .env). 14 tests: period boundary, buy/accumulate/reset/caps/guards, pot state, draw payout with coin conservation, and the more-tickets-wins-more weighting. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013VbAVsrZuYesea99mPMmPT
This commit is contained in:
@@ -62,6 +62,7 @@ from .economy import (
|
||||
LOOTBOX_UI,
|
||||
BANK_UI,
|
||||
ACHIEVEMENTS_UI,
|
||||
LOTTERY_UI,
|
||||
JAILED_UI,
|
||||
SHOP_BTN,
|
||||
DAILY_UI,
|
||||
@@ -158,6 +159,7 @@ __all__ = [
|
||||
'LOOTBOX_UI',
|
||||
'BANK_UI',
|
||||
'ACHIEVEMENTS_UI',
|
||||
'LOTTERY_UI',
|
||||
'JAILED_UI',
|
||||
'SHOP_BTN',
|
||||
'DAILY_UI',
|
||||
|
||||
@@ -80,6 +80,7 @@ CMD: dict[str, str] = {
|
||||
"bank": "Vaata oma panka - röövikindel hoius",
|
||||
"deposit": "Pane münte panka (röövikindel, aga ei teeni intressi)",
|
||||
"withdraw": "Võta münte pangast rahakotti",
|
||||
"lottery": "Vaata TipiLOTO potti või osta pileteid (tühjaks jättes näeb infot)",
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -99,6 +100,7 @@ OPT: dict[str, str] = {
|
||||
"buy_ese": "Eseme nimi (vaata /shop)",
|
||||
"deposit_summa": "Kui palju panna panka? ('all' = kogu vaba raha)",
|
||||
"withdraw_summa": "Kui palju pangast välja võtta? ('all' = kogu pangas)",
|
||||
"lottery_kogus": "Mitu piletit osta (tühjaks jättes näeb potti)",
|
||||
"consumable_ese": "Turgutus, mida osta (tühjaks jättes näeb menüüd)",
|
||||
"vanity_ese": "Tiitel, mida osta või kanda (tühjaks jättes näeb poodi)",
|
||||
"rps_panus": "Valikuline TipiCOINide panus ('all' = kogu saldo)",
|
||||
@@ -161,6 +163,7 @@ HELP_CATEGORIES: dict[str, dict] = {
|
||||
("/withdraw <amount>", "Võta münte pangast rahakotti."),
|
||||
("/quests", "Vaata oma päeva- ja nädalaülesandeid ning nõua auhinnad (uueneb iga päev/nädal)."),
|
||||
("/achievements", "Vaata oma saavutusi. Iga lukust lahti saanud märk annab ühekordse müntipreemia."),
|
||||
("/lottery [kogus]", "Vaata TipiLOTO potti või osta pileteid. Loosimine iga päev - üks võitja saab kogu poti (rohkem pileteid = suurem võiduvõimalus)."),
|
||||
("/leaderboard", "TipiBOTi edetabel - kes on kõige rikkam?"),
|
||||
("/shop", "Sirvi TipiBOTi poodi"),
|
||||
("/buy <item>", "Osta ese TipiBOTi poodist"),
|
||||
|
||||
@@ -21,6 +21,7 @@ __all__ = [
|
||||
'LOOTBOX_UI',
|
||||
'BANK_UI',
|
||||
'ACHIEVEMENTS_UI',
|
||||
'LOTTERY_UI',
|
||||
'JAILED_UI',
|
||||
'SHOP_BTN',
|
||||
'DAILY_UI',
|
||||
@@ -302,6 +303,26 @@ ACHIEVEMENTS_UI: dict[str, str] = {
|
||||
"unlocked_note": "🎉 **Uued saavutused avatud:** {names}\n💰 Preemia: +{reward}",
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Lottery (daily draw; one weighted winner takes the pot)
|
||||
# ---------------------------------------------------------------------------
|
||||
LOTTERY_UI: dict[str, str] = {
|
||||
"title": "🎟️ TipiLOTO",
|
||||
"desc": "Osta pileteid ja võida kogu pott! Loosimine iga päev **{draw_time}**. Iga pilet = **{cost}**, rohkem pileteid = suurem võiduvõimalus.",
|
||||
"f_pot": "💰 Praegune pott",
|
||||
"f_players": "👥 Osalejaid",
|
||||
"f_your": "🎟️ Sinu piletid",
|
||||
"your_val": "{tickets} tk · võiduvõimalus **{chance}%**",
|
||||
"your_none": "Sul pole veel pileteid. Osta käsuga `/lottery <kogus>`.",
|
||||
"bought": "🎟️ Ostsid **{count}** piletit ({cost}).\nSul on nüüd **{tickets}** piletit selle päeva loosimises.\nSaldo: {balance}",
|
||||
"max_tickets": "❌ Maksimaalne piletite arv ühes loosimises on {cap} (sul on {held}).",
|
||||
"empty_pot": "🎟️ Pott on tühi - ole esimene, kes piletit ostab!",
|
||||
# Draw announcement
|
||||
"draw_title": "🎟️ TipiLOTO loosimine!",
|
||||
"draw_win": "🎉 Võitja: {winner}\n💰 Võit: **{pot}**\n🎟️ {tickets}/{total} piletit ({chance}%)\n👥 {players} osalejat",
|
||||
"draw_none": "🎟️ Täna keegi pileteid ei ostnud - loosimist ei toimunud.",
|
||||
}
|
||||
|
||||
JAILED_UI: dict[str, str] = {
|
||||
"title": "🔒 Praegu vanglas",
|
||||
"empty": "Kõik on vabad! Vanglas pole kedagi.",
|
||||
|
||||
Reference in New Issue
Block a user