Repository navigation
Let a member close and attack in one round, and dry-run a planned round - #217
Merged
Merged
Conversation
…declares An attack can now set move="close". The member closes in the party's movement step and attacks in the missile or the melee step of the same round. So a thief can close and back-stab in the free round after a surprise, and a fighter can close and swing in one round. The pre-phase now projects every declared move before it judges any declaration: each member's close, each fall-back a member makes alone with its trade of marching-order places, a formation move, and the move of the party line. It judges each attack at the member's projected distance, chooses the default weapon there, and judges each melee attack against the front rank those moves produce. So a member who steps into the place another member leaves can strike in the same round. The movement step carries out the same plan, which _plan_member_moves builds for both. preview_battle_round runs the same pre-phase as the round, through _judge_round, on any subset of the declarers, and leaves out the roster check. It returns each declaration's rejections, each living member's projected advance, and each group's projected front rank. It changes nothing and takes no draw. A cast that sets a move gets battle.declaration.cast_cannot_move. A turn_undead, use_item, or hold that sets one, and an attack with a fighting_withdrawal or a retreat, get battle.declaration.move_not_combinable. The session checks them after the back-stab checks and before the action's own. An attack that closes, by a member who can't move, gets battle.declaration.cannot_move. tools/docs/rejection_codes.json describes the two new codes. A melee attack that can't resolve where the member stands at the melee step now reports a player-visible DeclarationFizzledEvent at battle.melee.fizzled, with the group's id. An attack that closes from beyond 5' to within 5' stays a melee attack. So when the group runs first and the close falls short, the attack fizzles instead of turning into a throw. The ResolveBattleRound.declarations docstring no longer says the party closes on the group of the first close. In a battle where no member moves, the projection is the battle as it stands, so the default weapons and the judgements are the same as before, and no attack closes. The phase 2, 3, and 11 to 15 goldens pass unchanged. Claude-Session: https://claude.ai/code/session_01V7ErtnsmhaP7aLwcfmzohD
_cast_targets returned the group's distance from the party line as the distance a spell's range is checked against. With members at their own places on the range track, that's wrong for a caster who stands forward of the line or behind it. It now returns the caster's own distance to the group, or to the farthest group a targeted monster belongs to. So a magic-user who closed 40' alone can cast magic missile at goblins 190' from the line, which stand 150' from them. The pre-phase, a scroll read, and the magic phase all read the distance this way. A caster can't move in the round they cast, so the battle as it stands gives the same distance as the pre-phase's projection. In a battle where no member moves, every advance is zero and the distance is the group's distance, as before. Claude-Session: https://claude.ai/code/session_01V7ErtnsmhaP7aLwcfmzohD
The tests for closing and attacking in one round, the dry run, the new rejection codes, and the ResolveBattleRound example pass, so their expected-to-fail markers come off. Claude-Session: https://claude.ai/code/session_01V7ErtnsmhaP7aLwcfmzohD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is the move-and-attack chunk of issue #209. An
attackdeclaration can setmove="close", so the member closes in the movement step and attacks in the same round, as the OSE SRD allows: "Movement and attacking may be combined in the same round." A thief can close and back-stab in the free round after a surprise. Acastwith any move is refused withbattle.declaration.cast_cannot_move, and another action with a move is refused withbattle.declaration.move_not_combinable.Each round is now judged against the positions that all its declared moves produce, so a member who steps into a place another member left can attack in that round.
preview_battle_roundruns the same judgement on a partial or complete plan, with no draw and no change, so a battle screen can grey out a choice the round would refuse. A melee attack that position stops reports aDeclarationFizzledEventwith the codebattle.melee.fizzled. A spell's range is measured from the caster's own place.A battle in which nobody moves draws as before: the phase 2, 3, and 11 to 15 goldens are unchanged. Monster reach and the view fields are later chunks.
https://claude.ai/code/session_01V7ErtnsmhaP7aLwcfmzohD