Commit Graph

228 Commits

Author SHA1 Message Date
Cal Corum
6b4957ec70 refactor: rename Evolution to Refractor system
All checks were successful
Build Docker Image / build (pull_request) Successful in 1m34s
- cogs/evolution.py → cogs/refractor.py (class, group, command names)
- Tier names: Base Chrome, Refractor, Gold Refractor, Superfractor
- Fix import: helpers.main.get_team_by_owner
- Fix shadowed builtin: type → card_type parameter
- Tests renamed and updated (39/39 pass)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 08:48:31 -05:00
Cal Corum
d12cdb8d97 feat: /evo status slash command and tests (WP-11) (#76)
All checks were successful
Build Docker Image / build (pull_request) Successful in 1m37s
Closes #76

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 09:07:28 -05:00
Cal Corum
33260fd5fa feat: add buy-scout-token option when daily limit exceeded
When a user exceeds their 2/day scout token limit, they are now offered
a button to purchase an extra token for 200₼ instead of being blocked.
Updates /scout-tokens message to mention the purchase option.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 13:12:35 -05:00
Cal Corum
98ec6b2e58 fix: remove db_patch call — no PATCH endpoint for scout_opportunities
All checks were successful
Build Docker Image / build (pull_request) Successful in 1m12s
The database API only has GET/POST/DELETE for scout_opportunities.
The expires_at update is non-critical — the view timeout controls
the actual scout window.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 10:55:22 -05:00
Cal Corum
1e08545bd9 fix: use nested opener_team object from scout_opportunity response
All checks were successful
Build Docker Image / build (pull_request) Successful in 1m17s
The API returns opener_team as a full nested object, not an ID.
No need to fetch it separately.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 10:47:42 -05:00
Cal Corum
5bed0f3164 feat: add /resend_scout admin command and pre-commit hooks
All checks were successful
Build Docker Image / build (pull_request) Successful in 1m20s
Adds /resend_scout slash command to manually re-post a scout opportunity
with a custom timeout window. Updates the scout_opportunity's expires_at
in the database before posting. Also adds ruff pre-commit hook for
staged Python files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 10:39:08 -05:00
Cal Corum
d116680800 fix: remove cogs/players.py.backup from repository (#35)
Backup file was checked in with unused imports (requests, pygsheets),
adding noise to git grep, IDEs, and code review.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 13:22:58 +00:00
Cal Corum
3c0fa133fd refactor: Consolidate scouting utilities, add test suite, use Discord timestamps
- Consolidate SCOUT_TOKENS_PER_DAY and get_scout_tokens_used() into
  helpers/scouting.py (was duplicated across 3 files)
- Add midnight_timestamp() utility to helpers/utils.py
- Remove _build_scouted_ids() wrapper, use self.claims directly
- Fix build_scout_embed return type annotation
- Use Discord <t:UNIX:R> relative timestamps for scout window countdown
- Add 66-test suite covering helpers, ScoutView, and cog

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 13:22:58 +00:00
Cal Corum
2d5bd86d52 feat: Add Scouting feature (Wonder Pick-style social pack opening)
When a player opens a pack, a scout opportunity is posted to #pack-openings
with face-down card buttons. Other players can blind-pick one card using
daily scout tokens (2/day), receiving a copy. The opener keeps all cards.

New files:
- discord_ui/scout_view.py: ScoutView with dynamic buttons and claim logic
- helpers/scouting.py: create_scout_opportunity() and embed builder
- cogs/economy_new/scouting.py: /scout-tokens command and cleanup task

Modified:
- helpers/main.py: Hook into open_st_pr_packs() after display_cards()
- paperdynasty.py: Register scouting cog

Requires new API endpoints in paper-dynasty-database (scout_opportunities).
Tracks #44.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 13:22:58 +00:00
Cal Corum
1a9efa8f7e fix: add locked_play context manager to prevent stuck play locks
Early returns in log_chaos, log_sac_bunt, and log_stealing left play
locks permanently stuck because the lock was acquired but never released.
The new locked_play async context manager wraps checks_log_interaction()
and guarantees lock release on exception, early return, or normal exit.

Migrated all 18 locking commands in gameplay.py and removed redundant
double-locking in end_game_command.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 21:54:44 -06:00
Cal Corum
c4577ed46f fix: validate player positions in lineup before game start
Some checks failed
Build Docker Image / build (pull_request) Failing after 16s
Prevents PositionNotFoundException from crashing mlb-campaign when a
player is placed at a position they cannot play (e.g. an outfielder
listed at Catcher in the Google Sheet). Adds early validation in
get_lineups_from_sheets and proper error handling at all read_lineup
call sites so the user gets a clear message and the game is cleaned up.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 19:32:27 -06:00
Cal Corum
89801e1d42 Fix circular import by moving play lock functions to separate module
HOTFIX: Production bot failed to start due to circular import.

Root cause: utilities/dropdown.py importing from command_logic/logic_gameplay.py
while logic_gameplay.py imports from utilities/dropdown.py.

Solution: Created play_lock.py as standalone module containing:
- release_play_lock()
- safe_play_lock()

Both modules now import from play_lock.py instead of each other.

Error message:
  ImportError: cannot import name 'release_play_lock' from partially
  initialized module 'command_logic.logic_gameplay' (most likely due
  to a circular import)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-04 09:33:37 -06:00
Cal Corum
ebf006e5c6 Fix play lock system to prevent permanent user lockouts
CRITICAL BUG FIX: Play locks were never released on exceptions, causing
permanent user lockouts. Found 13 stuck plays in production.

Changes:
1. Added lock_play parameter to checks_log_interaction() (default True)
2. Removed unnecessary locks from read-only commands:
   - /settings-ingame (game settings, not play state)
   - /show-card defense (read-only display)
   - /substitute commands (just show UI, lock in callback)
3. Added safe_play_lock() context manager for automatic lock release
4. Added play locking to substitution callbacks:
   - SelectBatterSub.callback()
   - SelectReliefPitcher.callback()
5. Global error handler now releases stuck locks automatically

Architecture:
- Commands that display UI or read data: No lock
- Commands that modify play state: Lock at last possible moment
- 3-layer defense: manual release, context manager, global handler

Resolves race condition from concurrent play modifications.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-04 09:21:18 -06:00
Cal Corum
541c5bbc1e Fix pack type grouping logic in packs display
Previously p_group was only set if pack type already existed in p_data,
which would silently skip new pack types. Now properly initializes the
pack type list when encountering a new type.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 14:22:06 -06:00
Cal Corum
565afd0183 Normalize Player.franchise queries to use Team.sname
- Add FRANCHISE_NORMALIZE dict and helper to constants.py
- Update economy.py to normalize team_choice and use sname
- Update helpers/main.py franchise queries to use sname
- Update selectors.py to normalize franchise on player updates

Part of cross-era player matching fix for AI rosters

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 12:01:00 -06:00
Cal Corum
584a8a95ab Fix slash command decorators using wrong prefix command checks
Bug: Several slash commands (@app_commands.command) were using prefix command
decorators (@commands.has_any_role, @commands.check) which don't work with
app_commands. This caused errors caught by the global error handler, resulting
in "Unknown interaction" (404) errors being displayed before the command executed.

Affected commands:
- /comeonmanineedthis: Both role and channel checks were wrong
- /selldupes: Channel check was wrong
- /team: Channel check was wrong

Fix:
- Created app_legal_channel() decorator in helpers.py for slash commands
- Changed @commands.has_any_role to @app_commands.checks.has_any_role
- Changed @commands.check(legal_channel) to @app_legal_channel()

Bumps version to 1.7.5

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 07:29:08 -06:00
Cal Corum
1e75f1baba CLAUDE: Add news-ticker message when gauntlet runs end with 2 losses
Users reported that end-of-run messages to #pd-news-ticker were no longer
appearing when gauntlet teams lost their second game. The news-ticker
announcement was only happening for 10-win completions, not 2-loss endings.

Changes:
- Updated end_run() to accept bot and main_team parameters
- Added send_to_channel() call when losses == 2 (natural run end)
- Skips news-ticker for manual resets (force_end=True)
- Updated post_result() to pass bot and main_team to end_run()
- Updated manual reset calls to explicitly pass force_end=True

Now when a gauntlet team loses their second game, #pd-news-ticker will
show: "The **[Team]** have completed their **[Event]** Gauntlet run
with a final record of [wins]-[losses]."

The draft completion message to news-ticker was already working correctly
at cogs/players_new/gauntlet.py:178-183.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 09:17:55 -06:00
Cal Corum
943dcc9b74 CLAUDE: Add get_context_user() helper for hybrid command compatibility
Created get_context_user() helper function to safely extract the user from
either Context or Interaction objects. This prevents AttributeError issues
when hybrid commands are invoked as slash commands.

Hybrid commands receive commands.Context (with .author) when invoked with
prefix commands, but discord.Interaction (with .user) when invoked as slash
commands. The helper function handles both cases transparently.

Updated all affected hybrid commands:
- /branding-pd (cogs/players.py, cogs/players_new/team_management.py)
- /pullroster (cogs/players.py, cogs/players_new/team_management.py)
- /newsheet (cogs/economy_new/team_setup.py)
- /lastpack (cogs/economy_new/packs.py)

This follows the same pattern as the owner_only() fix and provides a
consistent, maintainable solution for all hybrid commands.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 09:07:09 -06:00
Cal Corum
c043948238 CLAUDE: Fix gauntlet game creation and Event 9 issues
Multiple fixes to resolve PlayNotFoundException and lineup initialization errors:

1. gauntlets.py:
   - Fixed Team object subscriptable errors (use .id instead of ['id'])
   - Added fallback cardsets (24, 25, 26) for Event 9 RP shortage
   - Fixed draft_team type handling (can be Team object or dict)

2. cogs/gameplay.py:
   - Fixed gauntlet game creation flow to read field player lineup from sheets
   - Catches LineupsMissingException when SP not yet selected
   - Instructs user to run /gamestate after SP selection

3. utilities/dropdown.py:
   - Fixed SelectStartingPitcher to create own session instead of using closed session
   - Store game/team IDs instead of objects to avoid detached session issues
   - Added exception handling for failed legality check API calls

These changes fix the issue where gauntlet games would fail to initialize
because the SP lineup entry wasn't being committed to the database.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 18:56:38 -06:00
Cal Corum
0e3b98eb65 S10 Updates + PR Bugfix 2025-11-09 06:12:46 -06:00
Cal Corum
660c6ad904 Added search functionality to /player command 2025-10-08 14:45:41 -05:00
Cal Corum
b1d05309ef Cogs to Packages Groundwork 2025-08-17 08:46:55 -05:00
Cal Corum
3debfd6e82 Catchup commit
Includes discord_ui refactor, testing overhaul, addition of
2025-07-22 09:22:19 -05:00
Cal Corum
65abc8ed55 Remove outdate image links
Add S3 image links
Pull all fielding ratings at game start
2025-06-04 09:54:13 -05:00
Cal Corum
a4adf50ca1 Added discord bot object to complete game function 2025-06-01 09:44:16 -05:00
Cal Corum
b3fa68b80e Bug fixes for uncapped doubles 2025-05-30 21:16:51 -05:00
Cal Corum
17680a2348 Added /substitution defense 2025-05-30 01:19:45 -05:00
Cal Corum
e9c9a3f392 dictionary to object bug fix 2025-05-29 21:54:46 -05:00
Cal Corum
6a355def4b Season 9 Updates 2025-05-03 19:38:29 -05:00
Cal Corum
cffc9380f1 Replacing 1998 Live with 1998 Season 2025-04-14 16:28:14 -05:00
Cal Corum
cb2637086e Live scorecard fix
Gauntlet entry string fix
2025-03-31 13:54:39 -05:00
Cal Corum
9218bd6047 Update cache reset command
Decrease cache limit to 3 days
Add kickstart live scorecard function
2025-03-09 14:20:30 -05:00
Cal Corum
cf4157a59d Increase scorebug timeout to 8 seconds 2025-03-09 00:58:15 -06:00
Cal Corum
8e35812cd3 Increase concurrent db connections
Decrease timeout on Scorebug buttons to reduce open connections
2025-03-03 22:13:40 -06:00
Cal Corum
9d831a9512 Post gamestate publicly if human team GM runs command 2025-02-23 23:20:54 -06:00
Cal Corum
50895fef90 Show charts on SPD checks
Fix gb chart with OBC 5, 7
Add 1998 to player command
2025-02-10 23:44:05 -06:00
Cal Corum
479a335373 Gauntlet evolution fix 2025-02-09 21:38:19 -06:00
Cal Corum
f6bae8c208 Local db to Postgresql 2025-02-08 04:11:04 -06:00
Cal Corum
d5f2978b01 Update new-game flow 2025-02-06 15:12:12 -06:00
Cal Corum
282a7e7ac2 Added live scorecard functionality
Added new pitcher embed highlighting
2025-02-05 11:30:56 -06:00
Cal Corum
fc130e6a98 Update buffer message for ballpark fly
Bolded new pitcher text
2025-02-03 13:58:51 -06:00
Cal Corum
3b6bcfb186 Beta day 1 bug fixes 2025-02-02 22:01:33 -06:00
Cal Corum
7d54d9ea34 Add unlimited new-game
Add pitcher substitution
Add AI pitcher subs
2025-02-01 21:32:40 -06:00
Cal Corum
4a76d59481 Check for AI fatigue 2025-01-26 02:20:29 -06:00
Cal Corum
36dbde848e new_game_checks refactor 2025-01-24 10:08:11 -06:00
Cal Corum
965ceebd35 Add responders check to dropdowns
Add colors and insults to helpers
Finish /set commands with helpers post /new-game
Add POW check for pitchers
2024-12-27 22:33:25 -06:00
Cal Corum
724b8922f2 Update gauntlet get SP for new objects
Handle gamestates without full lineups
Added /set command for lineup and SP
Fixed uncapped hit bugs
Added league_name property to Games
Fix get_team for gauntlets
Fixed SelectSP dropdown bug
2024-12-27 16:12:25 -06:00
Cal Corum
3db25b177a Refactor new game checks
Trail batter-runner on uncapped hits
2024-12-26 14:36:04 -06:00
Cal Corum
9dbd7896c4 Add PB to catcher string
Fix chaos interaction bug
2024-12-25 15:00:22 -06:00
Cal Corum
7015fb3125 Added baserunning ai notes
Added get_batter_card to gameplay_queries
2024-12-24 21:08:00 -06:00