Commit graph

363 commits

Author SHA1 Message Date
dd5286097b
Export safe flag and home_region in zone TOML 2026-02-14 11:54:47 -05:00
68c18572d6
Add readable objects with read command
Implements TDD feature for readable text on Things:
- Added readable_text field to Thing dataclass
- Extended ThingTemplate to parse readable_text from TOML
- Created read command that finds objects by name/alias in inventory or on ground
- Handles edge cases: no target, not found, not readable
2026-02-14 11:51:52 -05:00
5e0ec120c6
Add mob home regions to spawn rules and entity 2026-02-14 11:51:39 -05:00
755d23aa13
Add safe zone flag to prevent combat in peaceful areas 2026-02-14 11:50:49 -05:00
14dc2424ef
Show unlock requirements in help for locked moves
help <move> displays lock status and what's needed to unlock
when the move has an unlock_condition the player hasn't met.
2026-02-14 11:40:46 -05:00
8e9e6f8245
Add unlock conditions to roundhouse and sweep moves
Roundhouse requires 5 total kills, sweep requires defeating
3 goblins. Basic moves (punch, dodge, duck, parry, jump)
remain available from the start.
2026-02-14 11:40:46 -05:00
a2efd16390
Add skill unlock system with TOML conditions and gating
UnlockCondition on CombatMove, parsed from [unlock] TOML section.
check_unlocks evaluates kill_count and mob_kills thresholds.
Locked moves rejected with "You haven't learned that yet." in
do_attack/do_defend. New unlocks announced after kills.
2026-02-14 11:40:46 -05:00
085a19a564
Add score command with stats display
Shows PL, stamina, K/D ratio, time played, and unlocked moves.
Registered as score/stats/profile, available in all modes.
2026-02-14 11:40:45 -05:00
e31af53577
Wire kill/death tracking into combat engine
Increment player.kills and player.mob_kills on mob defeat,
player.deaths on player defeat. Session time accumulation
via accumulate_play_time helper.
2026-02-14 11:40:45 -05:00
a398227814
Add player stats model and persistence
kills, deaths, mob_kills dict, play_time_seconds, unlocked_moves set
on Player. New player_stats SQLite table with save/load functions.
2026-02-14 11:40:45 -05:00
a159de9f86
Add brainstorm note about player safety 2026-02-14 11:13:29 -05:00
21caa099c8
Fix prompt template to show PL as gauge with max value 2026-02-14 10:45:39 -05:00
7ec5ccb87a
Set overworld zone description so "Where:" header displays correctly 2026-02-14 10:45:39 -05:00
0f7f565a2e
Add cleanup world note 2026-02-14 10:45:39 -05:00
9f0db0ffb1
Wire loot tables into corpse creation
Combat engine looks up mob template loot table and passes to
create_corpse. Goblin template now drops crude club (80%) and
1-3 gold coins (50%).
2026-02-14 10:22:53 -05:00
189f8ac273
Add decomposition timer with broadcast and game loop integration 2026-02-14 10:20:22 -05:00
0fbd63a1f7
Add loot table system with LootEntry and roll_loot
LootEntry defines probabilistic item drops with min/max counts.
roll_loot takes a loot table and returns Thing instances.
MobTemplate now has loot field, parsed from TOML [[loot]] sections.
2026-02-14 10:02:38 -05:00
56169a5ed6
Add corpse decomposition system with active_corpses registry
process_decomposing removes expired corpses and broadcasts messages
to entities at the same tile. Registered in game loop.
2026-02-14 10:02:33 -05:00
68f8c64cf3
Show corpses distinctly in look command 2026-02-14 09:59:44 -05:00
487e316629
Wire corpse spawning into combat death handling
When a mob dies in combat, create_corpse is called to spawn a corpse
at the mob's position with the mob's inventory transferred. This
replaces the direct despawn_mob call, making combat deaths leave
lootable corpses behind.

The fallback to despawn_mob is kept if the mob somehow has no zone.
2026-02-14 09:56:37 -05:00
4f487d5178
Add Corpse class and create_corpse factory
Corpse is a non-portable Container subclass that holds a deceased mob's
inventory. The create_corpse factory transfers items from the mob to the
corpse, sets a decompose_at timestamp for eventual cleanup, and calls
despawn_mob to remove the mob from the world.
2026-02-14 09:54:20 -05:00
4878f39124
Add container grammar with get-all and targeting support
- Update _find_container to use targeting module (prefix + ordinal)
- Update cmd_put to use find_in_inventory directly
- Add 'get all from <container>' support with portable item filtering
- Add comprehensive tests for all container grammar features
2026-02-14 01:39:45 -05:00
aca9864881
Wire target resolution into thing commands
Replace local exact-match helpers with targeting module calls for
prefix matching and ordinal disambiguation. Works in get, drop, and
container extraction (get X from Y).
2026-02-14 01:39:45 -05:00
5a0c1b2151
Fix dataclass equality causing duplicate items in move_to
Objects were comparing by value instead of identity, causing
list.remove() to remove the wrong object when moving items with
identical attributes. Set eq=False on all dataclasses to use
identity-based comparison.
2026-02-14 01:39:45 -05:00
a98f340e5a
Wire target resolution into look command 2026-02-14 01:39:45 -05:00
86797c3a82
Wire target resolution into combat commands 2026-02-14 01:39:45 -05:00
3f042de360
Add player alias system with persistence and dispatch
Implements a complete alias system allowing players to create command shortcuts.
Aliases are expanded during dispatch with a recursion guard (max 10 levels).

Changes:
- Add aliases field to Player dataclass (dict[str, str])
- Add player_aliases table to database schema
- Add save_aliases() and load_aliases() persistence functions
- Add alias/unalias commands with built-in command protection
- Integrate alias expansion into dispatch() before command resolution
- Add comprehensive test coverage for all features
2026-02-14 01:39:45 -05:00
4c969d2987
Add target resolution module with ordinal and prefix matching 2026-02-14 01:39:45 -05:00
be63a1cbde
Extract shared test fixtures to conftest.py
Moved common test fixtures (mock_writer, mock_reader, test_zone, player,
nearby_player, clear_state) from individual test files into a shared
conftest.py. This eliminates duplication across test_power.py, test_sleep.py,
test_combat_zaxis.py, test_quit.py, test_stamina_cues.py, and
test_stamina_cue_wiring.py.

Some test files override specific fixtures where they need custom behavior
(e.g., test_quit.py adds a close method to mock_writer, stamina tests use
smaller zones and custom player positions).
2026-02-14 01:00:37 -05:00
8bb87965d7
Wire stamina cues into combat and power loops 2026-02-14 01:00:37 -05:00
894a0b7396
Fix flying dodge template grammar 2026-02-14 01:00:37 -05:00
1dbc3a1c68
Replace magic number with DEATH_PL constant 2026-02-14 01:00:37 -05:00
8d31eeafaf
Extract power-up validation helper 2026-02-14 01:00:37 -05:00
5629f052a4
Add snap neck finisher command
Allows instant kill of unconscious opponents. Only works in combat on targets with unconscious posture. Ends encounter, handles mob despawn, sends dramatic messages to both parties.
2026-02-14 01:00:37 -05:00
b4dea1d349
Add unconscious state with automatic recovery
Players become unconscious when PL or stamina drops to 0. While unconscious, both stats slowly recover at 0.1 per tick (1.0 per second). When both reach above 0, player regains consciousness with a message. Recovery runs in the main game loop via process_unconscious.
2026-02-14 01:00:37 -05:00
d6d62abdb8
Add flying dodge mechanic at resolve time
When altitude differs at resolve time (attacker or defender changed flying state during window phase), attack misses. Treated as successful dodge with zero damage.
2026-02-14 01:00:37 -05:00
4da8d41b45
Add z-axis altitude check for starting combat
Players must be at same altitude (both flying or both grounded) to initiate combat. Attack fails with 'You can't reach them from here!' if altitude differs.
2026-02-14 01:00:37 -05:00
d8cd880b61
Add sleep command for deep rest recovery 2026-02-14 01:00:37 -05:00
36fcbecc12
Block quit command during combat 2026-02-14 01:00:37 -05:00
a4c9f31056
Cancel power-up tasks when combat starts
When combat begins, any active power-up task on either the attacker
or defender should be cancelled to prevent background power changes
during combat. This ensures players can't continue charging while
fighting.

The fix checks both entities for a _power_task attribute and cancels
it if present, then clears the reference.
2026-02-14 01:00:37 -05:00
2a546a3171
Fix operator precedence in POV smart conjugation
The {s} conjugation check had incorrect operator precedence that
evaluated the ch/sh suffix check independently of the prev_text
existence check. This could lead to confusing logic flow even
though it didn't crash due to len() handling empty strings safely.

Fixed by wrapping both suffix conditions in parentheses so they're
both guarded by the prev_text truthiness check.
2026-02-14 01:00:37 -05:00
afe99ceff5
Wire combat move and state into prompt variables 2026-02-13 23:21:53 -05:00
47534b1514
Add visible stamina cue broadcasts 2026-02-13 23:21:53 -05:00
4e8459df5f
Convert combat resolution to POV templates 2026-02-13 23:21:52 -05:00
15cc0d1ae0
Add announce and resolve templates to combat moves 2026-02-13 23:21:50 -05:00
2b21257d26
Add POV template engine for combat messages 2026-02-13 23:05:19 -05:00
292557e5fd
Add power up/down commands
Implements power level management system with tick-based power-up loop.
Players can raise PL toward max_pl (costs stamina per tick), lower PL
instantly, set exact PL targets, and cancel ongoing power-ups.
2026-02-13 23:01:33 -05:00
72b877c5d1
Send GMCP Char.Vitals after each command 2026-02-13 22:48:59 -05:00
593bfd3028
Add prompt command for customization 2026-02-13 22:48:59 -05:00
4930f1408b
Wire render_prompt into server shell loop 2026-02-13 22:48:59 -05:00