Commit Graph

34 Commits

Author SHA1 Message Date
Rene Arumetsa
d48a436e26 feat(teams): resolve team dividers by role ID instead of name
Divider placement matched the divider role by its exact Discord name, so
renaming the role in Discord silently broke positioning. Switch the
TEAM_DIVIDER_<SUFFIX> config to hold a role ID; resolve the ID to the
role's current name in apply_team_role_positions and keep the existing
name-based ordering maths downstream unchanged.

- config._parse_team_dividers now parses values as ints (rejects non-ints)
- resolve_divider / _team_divider cache / get_team_dividers return IDs
- apply_team_role_positions resolves each ID via guild.get_role once
- .env.example documents IDs and ships the CS2/LoL divider role IDs
- resolve_divider tests updated to assert IDs

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XPRsW4tazVtYi2jNzVQkre
2026-09-03 22:34:34 +03:00
Rene Arumetsa
deab0f7a55 CS2 team dividers. 2026-09-03 21:36:41 +03:00
Rene Arumetsa
ce1ed28904 refactor(teams): move team-role sync to the economy/community bot
The team-role feature was aimed at the wrong bot. Tournament participants
live in the economy/community guild, but team-role sync had been bolted onto
the dev bot's roster sync (sync_member), which bails out for anyone missing
from the internal member sheet - so it could never reach its actual audience.

Decouple it: keep the (roster-independent) team-sheet parsing, pull the team
wiring off the dev/member-sync path, and re-home it on the economy bot.

- core/member_sync: revert sync_member to add-only (drop team block +
  SyncResult.roles_removed); add roster-independent sync_team_role and a
  whole-guild sync_all_team_roles returning a reporting summary. Still only
  ever touches role NAMES present in the team sheet.
- commands/economy_team_commands: new admin-only /teamsync command.
- bot.py: hourly team_sync_hourly task (economy-only, no-op unless
  TEAM_SHEET_ID is set; first tick at boot covers startup load); register
  /teamsync under the economy profile; drop the dev-side startup load.
- commands/dev_member_commands: /check no longer refreshes teams or reports
  removed roles.
- strings + .env.example: TEAMSYNC_UI, CMD[teamsync], document TEAM_SHEET_ID.
- tests: retarget sync tests to sync_team_role; add sync_all_team_roles case.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R6JZkyszyDFuFtk25WBbcR
2026-08-28 15:04:23 +03:00
Rene Arumetsa
52002c37fc feat(members): assign team roles from the tournament registration sheet
Match members by Discord username against the lineup nicknames in the
separate registration spreadsheet (TEAM_SHEET_ID) and give each their
team's role. One team per person: switching teams removes the old team
role, and a team with no Discord role yet is auto-created. Only role
names present in the sheet are ever touched, so organisation/field/base
roles are never at risk; the feature is a no-op when TEAM_SHEET_ID is
unset.

The sheet is not a single table (merged rows, stacked CS2/LoL sections
with different layouts), so it is parsed via raw-row scanning rather than
get_all_records. Citizenship markers like "(EST)" are used only as
player delimiters and discarded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-28 14:01:22 +03:00
567a82b9f2 Merge pull request 'feat(economy): add /consumables shop of repeatable, expiring boosts' (#5) from fix/economy-money-safety into master
Reviewed-on: renkar/tipibot#5
2026-08-19 17:53:12 +00:00
f3c69738ef Merge pull request 'fix/economy-money-safety' (#4) from fix/economy-money-safety into master
Reviewed-on: renkar/tipibot#4
2026-08-19 17:36:16 +00:00
Rene Arumetsa
a2e1601d0e feat(economy): add /consumables shop of repeatable, expiring boosts
The economy had many coin faucets but almost no sinks: the /shop is
one-time ownership, and gambling/rob fines route to the house (which
players drain back via jackpots and heists), so they recirculate rather
than destroy coins. Result: steady inflation.

Add a consumables shop as a true recurring sink - buying destroys the
coins and grants a temporary boost, so there's always something to spend
on after gear is maxed:

  - Energiajook XL (500) - 1h of 2x earnings on /work, /beg, /crime
  - XP jook (500)        - 1h of 2x EXP
  - Kohv (300)           - instantly clears all cooldowns

Timed buffs live in a new active_buffs field ({kind: expiry_iso}), pruned
on read; rebuying extends the timer. Effects hook where they belong:
earn_mult in income.do_work/do_beg/do_crime, exp_buff_mult in
levels.award_exp; kohv is self-contained. New /consumables command browses
the menu (with active buffs) or buys a boost. Covered by 9 tests.

Note: active_buffs is a new PocketBase field - run
scripts/sync_pb_schema.py before deploying or buffs won't persist.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-19 20:32:36 +03:00
Rene Arumetsa
0ea5580e15 Refactor strings.py into modules 2026-08-19 19:12:48 +03:00
Rene Arumetsa
cec5ac01a0 Fix give coins, now actually gives rewards 2026-08-17 19:29:15 +03:00
Rene Arumetsa
968356f925 Fix money-safety bugs in economy (heist, blackjack, bail)
Multi-agent audit of the money-moving economy modules surfaced three
confirmed correctness bugs. All three are fixed here with regression tests.

heist (core/economy/heist.py):
- `house = await get_user(house.HOUSE_ID)` shadowed the imported `house`
  module for the whole function, so `house.HOUSE_ID` raised UnboundLocalError
  on every successful heist (win payout was entirely dead) and on the
  fail-path compensation branch. Rename the local to `house_rec`.
- Un-shadowing exposed a latent mint: the pot was floored at 300 but the
  house was debited only min(total, balance), so a poor house paid out more
  than it lost. Cap the pot at the balance and debit exactly what is paid
  (house debit == sum of payouts). No mint, no leak.
- Add the missing `_is_jailed` import (do_heist_check referenced it unimported).

blackjack (commands/economy_games_commands.py):
- Button callbacks had no reentrancy guard; discord.py dispatches each click
  as its own task, so double-clicking Stand within the dealer-reveal window
  paid out twice (mint), and double-clicking Double/Split deducted the extra
  bet twice. Add a synchronous `_busy` guard (matching the existing RpsGame
  idiom) on all four callbacks plus a `_resolved` idempotency flag on
  settlement, so a game can only pay out once.

bail (core/economy/jail.py, commands/economy_extra_commands.py):
- do_bail only checked balance, never jail state; a double-click or a stale
  BailView from a re-run /jailbreak charged bail twice, destroying coins (bail
  is a pure sink). Make do_bail a no-op when the user is not jailed, and add a
  UI reentrancy guard + "already free" message.

Tests: 47 passed (4 new regression tests covering heist coin-conservation and
bail idempotency).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-10 18:31:46 +03:00
Rene Arumetsa
83a60cda55 Refator eco code. Split into modules 2026-07-27 00:49:34 +03:00
Rene Arumetsa
94fe57a596 Add startup scheme 2026-07-26 21:36:26 +03:00
Rene Arumetsa
5ba5642694 Added tests, fix README. 2026-07-26 20:32:13 +03:00
Rene Arumetsa
cb18d9b882 Added quests 2026-07-26 20:11:14 +03:00
Rene Arumetsa
6101a278e7 Admin check now a dict 2026-06-21 22:40:57 +03:00
Rene Arumetsa
1e9ec56761 Update tipidice emoij to be animated 2026-06-03 18:50:06 +03:00
Rene Arumetsa
a96488fe9e Added eco server emoij ID 2026-06-03 18:45:46 +03:00
Rene Arumetsa
25cf60d2e1 Fix conflict 2026-06-03 18:38:40 +03:00
Rene Arumetsa
3939c879c9 Refacor emoijs to use application emoijs 2026-06-03 18:34:29 +03:00
Rene Arumetsa
42f7bae681 Edit discord role rights 2026-06-01 22:19:12 +03:00
Rene Arumetsa
b0e23c1a17 Change admin command permissions 2026-06-01 22:11:44 +03:00
Rene Arumetsa
8d7ac504ca Change exp leveling system 2026-05-13 22:43:34 +03:00
Rene Arumetsa
15e3121d55 Fix birthday bug 2026-05-11 22:28:21 +03:00
Rene Arumetsa
0e617d87a2 Merge branch 'master' of ssh://git.lapikud.ee:202/renkar/tipibot 2026-05-04 20:18:31 +03:00
Rene Arumetsa
2c2621d24e Make exp gains less grindy 2026-05-04 17:48:55 +03:00
Rene Arumetsa
192888625e Refactor db error catch to one helper 2026-05-04 17:31:16 +03:00
Rene Arumetsa
6d344a47f4 Fix 403 auth error 2026-05-04 17:14:21 +03:00
Rene Arumetsa
07e7f5e0b2 More bug fixes 2026-05-03 15:11:32 +03:00
Rene Arumetsa
d65173fbe9 Some bug updates 2026-05-03 14:45:42 +03:00
Rene Arumetsa
173e2564f1 Add missing import 2026-05-01 10:52:48 +03:00
Rene Arumetsa
93f4d471dc Add db error in functions 2026-04-29 00:04:24 +03:00
Rene Arumetsa
de7cfce833 Lower pb token timeout 2026-04-29 00:00:18 +03:00
Rene Arumetsa
9ae26049c5 Fix fishing sell bug 2026-04-26 20:37:07 +03:00
Rene Arumetsa
77a3badd41 Feature: Clean up the codebase 2026-04-20 23:01:51 +03:00