Commit Graph

204 Commits

Author SHA1 Message Date
uberwald 570ca6c953 fix(d30): text cleanup — OR→AND for bonus dice, mulligan gets (players only)
Release Creation / build (release) Successful in 59s
D30=30 and D30=20 bonus dice descriptions now say 'and' instead of 'or'
to reflect auto-roll behavior (no dialog choice). Mulligan D30=8 entries
appended with '(players only)' as GM reminder.
14.1.0
2026-07-15 23:18:44 +02:00
uberwald 4fd997d169 Renable compendiums 2026-07-07 18:44:59 +02:00
uberwald 28d6143f87 Renable compendiums
Release Creation / build (release) Successful in 1m3s
14.0.36
2026-07-07 18:13:46 +02:00
uberwald 7e5fb0baa7 Renable compendiums 2026-07-07 18:13:30 +02:00
uberwald 5734f3a5e3 Fix layperson skills ate character creation
Release Creation / build (release) Successful in 53s
14.0.35
2026-07-07 08:30:23 +02:00
uberwald 7675c47ff9 fix: persist rollType/actorId on rollBase.options, re-evaluate canReroll after mulligan
Release Creation / build (release) Failing after 2m9s
- roll-prompt.mjs: explicitly save rollType, actorId, actorName, actorImage
  to rollBase.options so mulligan reroll context reads valid values
- chat-reaction.mjs: replace canRerollDefense/canRerollAttack = false with
  recomputation from updated D30 message — aligns same-client with
  cross-client behavior (new D30 always takes effect, mulligan chain loops)
2026-07-06 08:56:58 +02:00
uberwald 90fde23ebc docs: update AGENTS.md with partial registration and try/catch fixes
Release Creation / build (release) Successful in 45s
14.0.34
2026-07-05 21:12:20 +02:00
uberwald d17c9cba49 fix: wrap do-while loop body in try/catch to protect against exceptions
Any exception from createReactionMessage or renderTemplate inside the
defense/attack reaction loops would silently abort the handler, preventing
combat result creation. The try/catch logs the error and continues safely.
2026-07-05 20:55:29 +02:00
uberwald bfbce9557b fix: wrap mulligan message creation in try/catch to prevent handler abort
Even with the partial correctly registered, a template rendering failure
should not abort the entire reroll handler. Without try/catch, the
exception propagates out of the do-while loop and prevents combat result
creation. The reroll value was applied but nothing else happened.
2026-07-05 20:51:26 +02:00
uberwald 881cecf5b7 chore: remove DevTools session artifacts 2026-07-05 20:45:29 +02:00
uberwald de31c397fa fix: use object key for partial ID to match template reference
loadTemplates with an array registers the partial using the full file
path as its Handlebars ID (e.g.
'systems/fvtt-lethal-fantasy/templates/chat/_dice-breakdown.hbs'), but
the template references it by the short name 'chat/dice-breakdown'.
Using an object with explicit keys ensures the partial ID matches.
2026-07-05 20:45:24 +02:00
uberwald fe346f46bf fix: register _dice-breakdown.hbs partial, await ready hook promises
Release Creation / build (release) Successful in 56s
Mulligan reroll reaction message creation was failing silently because
the chat/dice-breakdown Handlebars partial was never registered via
loadTemplates. This caused an unhandled promise rejection that aborted
the entire reroll handler chain — no mulligan message, no combat result.
14.0.33
2026-07-04 09:22:38 +02:00
uberwald 96e5bd5b4d fix: pre-process D30 attack bonus at source for cross-client agreement
Release Creation / build (release) Successful in 48s
D30 bonus dice now rolled at defense request time, not in defense handler.
Sends boosted attackRoll + d30AttackEffects in socket/nextDefenseData
so both clients agree on the value. Adds stale flag for mulligan rerolls
to bypass stale pre-computed effects and process the new D30 fresh.
14.0.32
2026-07-03 22:39:10 +02:00
uberwald 1ea1a4b4b7 FIx mulligan rolls
Release Creation / build (release) Successful in 2m19s
14.0.31
2026-07-01 10:38:19 +02:00
uberwald 25648aa2a3 refactor: remove D30 choice dialog, extract defense reaction buttons, fix bugs
Release Creation / build (release) Successful in 45s
- Remove D30 choice dialog — auto-roll bonus dice, flag special effects
- Fix d30ChangedAttack infinite loop in defense do-while (missing reset)
- Fix chat button dataset attributes (rollType/rollTarget/rollAvantage)
- Extract buildDefenseReactionButtons from both defense loops
- Merge Aether/Grace deduction via _deductResourceOnCast helper
- Extract HP HUD toggling (_toggleHudWraps/_disableHudWraps)
- Fix SYSTEM.EQUIPMENT_CATEGORIES typo in equipment model
- Add missing imports to combat.mjs
- Remove dead d30Auto branches, _buildSpecialLabel, d30-special-choice.hbs
14.0.30
2026-06-29 11:44:46 +02:00
uberwald 41b1199704 fix: cross-client sync of D30 attack bonus so defense dialog shows
When monster (GM) rolls D30 natural 30 and applies bonus dice
(eg +D20), the boosted attackRollFinal was only applied on GM's
client. Defender (player) saw stale unboosted values — defense
dialog never appeared.

Add d30RequiresSocket flag (GM side): always send attackBoosted
socket when GM-owned attacker has D30 data, because the D30
choice/dice result is only known on GM's client.

Add d30PendingFromGM flag (player side): suppress hook-based
defense dialog and comparison message creation when D30 data
needs GM-side processing. Socket handler (handleAttackBoosted)
shows dialog with correct values.

Track d30ChangedAttack for same-client restart logic.
2026-06-29 07:55:28 +02:00
uberwald 3df46b5848 refactor: extract inline HTML to templates, split oversized files, fix bugs
- Extract all inline HTML from JS into 21 Handlebars templates (chat/, dialogs/, ui/)
- Split utils.mjs (1507) into barrel + helpers.mjs, combat.mjs, d30.mjs
- Split roll.mjs (1632) into barrel + roll-base.mjs, roll-prompt.mjs, roll-combat.mjs, roll-damage.mjs
- Split lethal-fantasy.mjs (1426) into bootstrap + chat-reaction.mjs
- Fix: missing async on injectDiceTray (free-roll.mjs:29 SyntaxError)
- Fix: weapon._id fallback for deserialized chat-message weapon objects
- Fix: missing await on rollModifier.evaluate() calls in roll-combat.mjs
- Fix: choices→choicesList ReferenceError in utils.mjs
- Fix: add 12 missing i18n keys (chooseWeapon, chooseSave, attackRoll, etc.)
- Fix: restore sideLabel in bonus-die-select.hbs
- Clean: remove dead messageContent param, console.log→log()
- Style: barrel files preserve existing import paths
2026-06-28 19:13:05 +02:00
uberwald 05c93f9475 Full reroll management
Release Creation / build (release) Successful in 43s
14.0.29
2026-06-28 08:39:55 +02:00
uberwald bb005ee9fc feat: full reroll includes D30 + shows dice breakdown in chat
- Remove forceNoD30 from rerollConfiguredRoll so mulligan
  rerolls the D30 along with the d20 and modifier
- Reset defenseD30Processed/attackD30Processed after mulligan
  so the new D30's effects (bonus dice, specials) are applied
- Render reroll dice breakdown (diceResults + D30 result) as
  inline HTML in the reaction chat message using existing
  CSS classes so players see what was rolled
2026-06-28 08:04:20 +02:00
uberwald fa5c4cc9ce debug: log favor/disfavor dice totals and results for RNG investigation
9/12 identical d20 results under disfavor suggests RNG issue.
Add structured logging of both roll totals, per-die results,
and baseFormula. Enable debug mode in system settings to see
output in browser console.
2026-06-22 22:33:00 +02:00
uberwald 3b0d4e032e fix: cache results.length before explosion loop to prevent double-count
Release Creation / build (release) Successful in 50s
Pushing explosion dice to DieTerm.results made the for loop
condition (j < results.length) grow mid-iteration, re-processing
the explosion result as a normal die. This produced spurious
entries like `1D6 → 4` alongside the correct `1D6-1 → 3`.

Fixes prompt() (for loop) and rollSpellDamageToMessage()
(for...of) by caching result count / snapshotting the array
before iterating.
14.0.28
2026-06-16 19:34:13 +02:00
uberwald 539841c4ff fix: push explosion dice to DieTerm results so DSN displays them
Explosion rolls were evaluated as separate Roll instances but never
added to the original DieTerm's results array. Dice So Nice reads
DieTerm.results to render 3D dice, so explosions were invisible.

Now each explosion result is pushed into the DieTerm's results array
({result, active:true}), letting DSN render explosion dice in the
correct chronological order alongside the main die.

Applies to prompt(), promptRangedDefense(), promptRangedAttack(),
and rollSpellDamageToMessage().
2026-06-16 19:29:07 +02:00
uberwald ffba37b59e Fix D30 management, again 2026-06-14 23:00:39 +02:00
uberwald 1a7585e1f6 fix: merge saving_throws D30 table into arcane_spell_defense
Release Creation / build (release) Successful in 49s
saving_throws was redundant — all saves in this system are
vs spells. Removed SAVING_THROWS constant; all save rollType
lookups use ARCANE_SPELL_DEFENSE. D30=1 arcane_spell_defense
blank (no special result). Added miracle types to ARCANE_SPELL_ATTACK
mapping so they get D30 results instead of null.
14.0.27
2026-06-14 22:57:41 +02:00
uberwald b567c8bbea Fix D30 management, again
Release Creation / build (release) Successful in 48s
14.0.26
2026-06-13 23:15:22 +02:00
uberwald 60b351f50d Fix spell save/defense again
Release Creation / build (release) Successful in 45s
14.0.25
2026-06-13 21:06:18 +02:00
uberwald ace726a1fc fix: use try/finally for spellDefense cleanup instead of delete
Release Creation / build (release) Successful in 47s
delete on game.lethalFantasy.spellDefense was breaking roll flow
on Foundry's proxied game object.  Use try/finally with
assignment to false instead, which is safe on any object type.

Initialize saveSpell local var from one-shot flag so D30
chart lookup correctly uses arcane_spell_defense for spell saves
without requiring user to click the pre-checked checkbox.
2026-06-13 16:51:52 +02:00
uberwald 67499bc199 fix: add missing arcane_spell_defense entry for D30=1
Release Creation / build (release) Successful in 49s
User spec lists D30=1 as 'Possible Spell Calamity or Catastrophe'
for Arcane Spell Defense but it was missing from the table.
2026-06-13 16:29:54 +02:00
uberwald 7eae95cbbd fix: use arcane spell defense D30 chart for spell saves
Release Creation / build (release) Successful in 43s
Bug: saveSpell local var initialized to false (line 142), while
dialog checkbox was pre-checked via dialogContext.saveSpell =
game.lethalFantasy.spellDefense.  If user didn't click the checkbox,
D30 call used SAVING_THROWS chart instead of ARCANE_SPELL_DEFENSE.

Also: game.lethalFantasy.spellDefense was set true before spell
defense rolls but never cleared, leaking to subsequent non-spell saves.

Fix: initialize saveSpell from the one-shot flag and delete it
immediately.  Dialog context now uses the local saveSpell variable
instead of re-reading the deleted flag.
2026-06-13 15:22:34 +02:00
uberwald 1b53bf9152 fix: resolve hud actor from hud.token not render context param
Release Creation / build (release) Successful in 41s
V2 renderTokenHUD passes (hud, html, data) where data is a render
context object — not a TokenDocument.  data.actor was undefined,
and data?.token?.actor was also undefined.  Use hud.token.actor
(or hud.object.actor) instead, which is the real PlaceableObject
with proper actor resolution.

Also fix html.find() → html.querySelector() for V2 HTMLElement.
2026-06-12 19:01:54 +02:00
uberwald 2570bf707e fix: prevent duplicate cross-client defense dialog, clear bleed on heal
- Only send attackBoosted socket when attackerHandledBonus || attackerHasNonGMOwner
  (GM→player: hook handles it, no socket needed; PC→PC: socket needed)
- Clear bleeding wounds when HP restored via token HUD heal buttons
2026-06-12 17:23:39 +02:00
uberwald cbeaaeec99 Final fixes and code review checks
Release Creation / build (release) Successful in 39s
2026-06-12 08:19:42 +02:00
uberwald 37badf2619 fix: attack/defense cross-client reaction flow
- C1: Stop D30 auto-roll on non-primary clients (caused divergence)
- C2: defenderOwner fallback to GM for monster defenders
- C3: Fix tie outcome in handleAttackBoosted (>= not >)
- C5: Convert handleAttackBoosted to while-loop (multi-reaction)
- C4/C6: shouldCreateMessage cross-client guard
- M2: Coordinate main flow defender dialog vs socket handler
- M3: Fresh grit/luck reads each socket handler iteration
- M4: Include defenseD30message in socket payload + re-process
- M5: Communicate attackerHandledBonus in socket payload
- i18n: Add missing COMBAT.* keys, fix weapon.hbs label localize
- d30_results_tables: Fix string typo
2026-06-12 02:51:59 +02:00
uberwald 5839616863 chore: add pushLDBtoYML/pullYMLtoLDB scripts, gitignore packs_src 2026-06-12 01:56:19 +02:00
uberwald 89298490ef fix: pre-check 'Save against spell' checkbox in template when saveSpell is true 2026-06-12 01:56:03 +02:00
uberwald bb42de19bd REmove unused file 2026-06-11 23:05:55 +02:00
uberwald 53f9c33419 chore: gitignore LevelDB internal files, stop tracking auto-generated LDB bookkeeping
Release Creation / build (release) Successful in 46s
2026-06-11 23:00:45 +02:00
uberwald 06eba5f835 fix: show spell tier dialog on character sheet cast; duplicate rollTarget to prevent Item mutation 2026-06-11 22:56:54 +02:00
uberwald 46fa2d15a3 fix: allow defender to react when attacker boosts past defense via cross-client socket 2026-06-11 22:41:54 +02:00
uberwald 8aae7bada0 fix: pre-check 'Save against spell' checkbox when defense originates from spell attack 2026-06-11 22:17:37 +02:00
uberwald ceb62bca3f fix: add missing class lethal-luck-grit-hud to template so JS selector matches 2026-06-11 22:03:56 +02:00
uberwald 110ac65ba5 fix: replace hardcoded French bleeding notifications with i18n keys 2026-06-11 21:50:19 +02:00
uberwald 9b75fd4d96 feat: combat-tracker-driven bleeding (HP loss per wound per round) 2026-06-11 21:49:35 +02:00
uberwald 141d6048e0 Fix triple damage issue 2026-06-11 21:32:26 +02:00
uberwald ea7acf6bf8 Fix hp < 0 and D30 with D20 bonus roll 2026-06-11 20:48:46 +02:00
uberwald c20750caa7 Minor fixes regarding rolls and chat messages
Release Creation / build (release) Successful in 48s
2026-06-10 20:17:45 +02:00
uberwald ce630feb51 feat: D30 combat effects, spell tiers, small damage removal, token HUD luck/grit
- Replace Knockback with Internal Injury on D30 (5, 10, 15); remove Shield Bash from D30 counter-attacks
- Eliminate small weapon damage: keep only medium damage labelled Damage in sheets, rolls, and chat
- D30 bonus dice (20, 27, 30) auto-resolved before grit/luck/shield decisions; choice dialogs for special strikes
- D30 combat effects: bleeding wounds, damage ×2/×3 before DR, DR ×2/×3 with component picker dialog
- Add hp.wounds to monster schema for bleeding support
- Show Save against spell? checkbox for all save rolls (not just magic users)
- Fix mulligan restart: persistent D30 process flags prevent double-application and allow both sides to react
- For Dice So Nice, show main roll animation before explosion dice for correct ordering
- Spell tier selection: force Standard/Overpowered choice at cast time, tier-specific aether cost, only chosen damage button shown
- Add +1/−1 luck and grit controls to Token HUD
- Fix inconsistent indentation, remove duplicate i18n key, remove unused includesShield return
2026-06-10 07:53:51 +02:00
uberwald b35b684d50 NEgative values for HP and weapon bonuses 2026-06-06 16:11:36 +02:00
uberwald f6fb0b68b8 Fix spell rolls again
Release Creation / build (release) Successful in 47s
2026-05-25 20:41:00 +02:00
uberwald e45edd60c4 FIx spell order and dual rollll for spell damages
Release Creation / build (release) Successful in 1m6s
2026-05-25 12:29:39 +02:00