Coop lockout fix, holidays full list, !fx convert, lottery cleanup

- Co-op: when a run wipes or completes, clear the 99-sentinel combat
  lock for participants and pin combat_actions_used to maxCombatActions.
  Previously the lock only released on the next midnight reset, so
  members were stuck unable to combat for the rest of the day after
  their run ended.
- Holidays: !holidays now prints the full list. Previously it called
  the same featured-only formatter as TwinBee's morning auto-post,
  so users saw the same truncated message twice with a misleading
  "Use !holidays for the full list" hint that pointed at itself.
- Forex: add currency conversion. Auto-detects when the first arg is
  numeric (`!fx 1500 USD EUR`) and also accepts an explicit `convert`
  subcommand. Tolerant parsing: "to"/"into"/"in"/"=" filters, comma
  and k/m suffix support, and any of `1500 USD EUR`, `1500 USD/EUR`,
  `USD/EUR 1500` orderings. Includes parser + comma-formatter tests.
- Lottery: drop 2-match prize tier. At 1/16 odds × €25 it was +EV per
  ticket on its own and bled the community pot (~€775/wk recently),
  preventing jackpot rollover from accumulating. Removed from scoring,
  payout loops, draw announcement, !lottery odds, and !lottery history.
  Match2Winners DB column kept (history rows preserved); always written
  as 0 going forward.
- Lottery: shift week boundary so Sat/Sun return next Monday. Friday's
  23:59 draw used to leave players locked at their 100-ticket cap until
  next Monday rolled in; now the cap resets immediately after the draw.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
prosolis
2026-05-01 16:11:01 -07:00
parent 4a4ef95d65
commit a00987e75c
10 changed files with 337 additions and 26 deletions

View File

@@ -201,7 +201,6 @@ func (p *LotteryPlugin) handleLotteryOdds(ctx MessageContext) error {
| 5 of 5 | Jackpot (split among winners) | 1 in 142,506 |
| 4 of 5 | €5,000 (fixed) | 1 in 3,062 |
| 3 of 5 | €500 (fixed) | 1 in 141 |
| 2 of 5 | €25 (fixed) | 1 in 16 |
Tickets: €1 each. Max 100 per week. 5 numbers from 130.
Minimum €500 pot required for jackpot payout.`
@@ -227,8 +226,8 @@ func (p *LotteryPlugin) handleLotteryHistory(ctx MessageContext) error {
if h.RolledOver > 0 {
sb.WriteString(fmt.Sprintf(" | Rolled over: €%d", h.RolledOver))
}
sb.WriteString(fmt.Sprintf("\n 4-match: %d | 3-match: %d | 2-match: %d\n\n",
h.Match4Winners, h.Match3Winners, h.Match2Winners))
sb.WriteString(fmt.Sprintf("\n 4-match: %d | 3-match: %d\n\n",
h.Match4Winners, h.Match3Winners))
}
return p.SendReply(ctx.RoomID, ctx.EventID, sb.String())