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
This commit is contained in:
2026-06-28 19:13:05 +02:00
parent 05c93f9475
commit 3df46b5848
38 changed files with 4686 additions and 4602 deletions
+18
View File
@@ -0,0 +1,18 @@
<div class="grit-luck-dialog">
<div class="combat-status">
<p><strong>{{defenderName}}</strong> uses a shield (not equipped)</p>
<p>{{localize "LETHALFANTASY.Combat.attackRoll"}}: <strong>{{attackRoll}}</strong> — {{localize "LETHALFANTASY.Combat.currentDefense"}}: <strong>{{defenseRoll}}</strong></p>
</div>
<div class="weapon-selection" style="margin-top:8px;">
<label for="shield-dice">{{localize "LETHALFANTASY.Combat.shieldDice"}}:</label>
<select id="shield-dice" name="shieldDice" style="width: 100%; margin-top: 4px;">
{{#each choices}}
<option value="{{this}}">{{this}}</option>
{{/each}}
</select>
</div>
<div class="weapon-selection" style="margin-top:8px;">
<label for="shield-dr">{{localize "LETHALFANTASY.Combat.shieldDR"}}:</label>
<input id="shield-dr" name="shieldDR" type="number" min="0" value="0" style="width: 100%; margin-top: 4px;" />
</div>
</div>
+8
View File
@@ -0,0 +1,8 @@
<div class="grit-luck-dialog">
<div class="combat-status">
<p><strong>{{attackerName}}</strong> currently has <strong>{{currentAttackRollWithBonus}}</strong></p>
<p><strong>{{defenderName}}</strong> rolled <strong>{{defenseRoll}}</strong></p>
{{#if totalBonus}}<p class="bonus-info">Bonus already added: +{{totalBonus}}</p>{{/if}}
</div>
<p class="offer-text">You are losing! Spend Grit to add 1D6 to your attack?</p>
</div>
+8
View File
@@ -0,0 +1,8 @@
<div class="grit-luck-dialog">
<div class="combat-status">
<p><strong>{{attackerName}}</strong> currently has <strong>{{attackRoll}}</strong></p>
<p><strong>{{defenderName}}</strong> rolled <strong>{{defenseRoll}}</strong></p>
{{#if d30message}}<p class="bonus-info">D30 special: {{d30message.description}}</p>{{/if}}
</div>
<p class="offer-text">{{offerText}}</p>
</div>
+14
View File
@@ -0,0 +1,14 @@
<div class="grit-luck-dialog">
<div class="combat-status">
<p><strong>{{actorName}}</strong> currently has <strong>{{currentRoll}}</strong></p>
<p>{{sideLabel}} opposing roll: <strong>{{opposingRoll}}</strong></p>
</div>
<div class="weapon-selection">
<label for="bonus-die">{{localize "LETHALFANTASY.Combat.chooseBonusDie"}}:</label>
<select id="bonus-die" name="bonusDie" style="width: 100%; margin-top: 8px;">
{{#each choices}}
<option value="{{this}}">{{this}}</option>
{{/each}}
</select>
</div>
</div>
@@ -0,0 +1 @@
<p>{{message}}</p>
+16
View File
@@ -0,0 +1,16 @@
<div class="grit-luck-dialog">
<p><strong>D30 DR Multiplier ×{{multiplier}}</strong></p>
<p>Choose which DR types to multiply:</p>
<label style="display:block;margin:0.3rem 0">
<input type="checkbox" id="d30-dr-base" {{#if canBase}}checked{{/if}} {{#unless baseEnabled}}disabled{{/unless}}>
Base DR (Armor/Natural): {{baseDR}}×{{multiplier}} = {{baseDRMultiplied}}
</label>
<label style="display:block;margin:0.3rem 0">
<input type="checkbox" id="d30-dr-shield" {{#if canShield}}checked{{/if}} {{#unless shieldEnabled}}disabled{{/unless}}>
Shield DR: {{shieldDR}}×{{multiplier}} = {{shieldDRMultiplied}}
</label>
<label style="display:block;margin:0.3rem 0">
<input type="checkbox" id="d30-dr-magic" {{#if canMagic}}checked{{/if}} {{#unless magicEnabled}}disabled{{/unless}}>
Magic DR: {{magicDR}}×{{multiplier}} = {{magicDRMultiplied}}
</label>
</div>
+4
View File
@@ -0,0 +1,4 @@
<div class="grit-luck-dialog">
<p><strong>D30 result:</strong> {{description}}</p>
<p>{{localize "LETHALFANTASY.D30.chooseEffect"}}</p>
</div>
+4
View File
@@ -0,0 +1,4 @@
<div class="grit-luck-dialog">
<p><strong>{{itemName}}</strong> has multiple damage tiers.</p>
<p>Choose which damage to use when the attack lands:</p>
</div>
+8
View File
@@ -0,0 +1,8 @@
<div class="grit-luck-dialog">
<div class="combat-status">
<p><strong>{{attackerName}}</strong> {{attackStatus}} <strong>{{attackRoll}}</strong></p>
<p><strong>{{defenderName}}</strong> {{defenseStatus}} <strong>{{defenseRoll}}</strong></p>
{{#if d30message}}<p class="bonus-info">D30 special: {{d30message.description}}</p>{{/if}}
</div>
<p class="offer-text">{{offerText}}</p>
</div>
@@ -0,0 +1,14 @@
<div class="defense-request-dialog">
<div class="attack-info">
<p><strong>{{attackerName}}</strong> attacks <strong>{{defenderName}}</strong> with <strong>{{weaponName}}</strong>!</p>
<p>{{localize "LETHALFANTASY.Combat.attackRoll"}}: <strong>{{attackRoll}}</strong></p>
</div>
<div class="weapon-selection">
<label for="defense-weapon">{{localize "LETHALFANTASY.Combat.chooseWeapon"}}:</label>
<select id="defense-weapon" name="weaponId" style="width: 100%; margin-top: 8px;">
{{#each weapons}}
<option value="{{this.id}}">{{this.name}}</option>
{{/each}}
</select>
</div>
</div>
@@ -0,0 +1,14 @@
<div class="defense-request-dialog">
<div class="attack-info">
<p><strong>{{attackerName}}</strong> attacks <strong>{{defenderName}}</strong> with <strong>{{weaponName}}</strong>!</p>
<p>{{localize "LETHALFANTASY.Combat.attackRoll"}}: <strong>{{attackRoll}}</strong></p>
</div>
<div class="weapon-selection">
<label for="defense-attack">{{localize "LETHALFANTASY.Combat.chooseWeapon"}}:</label>
<select id="defense-attack" name="attackKey" style="width: 100%; margin-top: 8px;">
{{#each attacks}}
<option value="{{this.key}}">{{this.name}}</option>
{{/each}}
</select>
</div>
</div>
@@ -0,0 +1,14 @@
<div class="defense-request-dialog">
<div class="attack-info">
<p><strong>{{attackerName}}</strong> targets <strong>{{defenderName}}</strong> with <strong>{{weaponName}}</strong>!</p>
<p>{{localize "LETHALFANTASY.Combat.attackRoll"}}: <strong>{{attackRoll}}</strong></p>
</div>
<div class="weapon-selection">
<label for="save-type">{{localize "LETHALFANTASY.Combat.chooseSave"}}:</label>
<select id="save-type" name="saveKey" style="width: 100%; margin-top: 8px;">
{{#each saves}}
<option value="{{this.id}}">{{this.label}}</option>
{{/each}}
</select>
</div>
</div>
+1
View File
@@ -0,0 +1 @@
<p>Select the power level for <strong>{{itemName}}</strong>:</p>
+7
View File
@@ -0,0 +1,7 @@
<div style="padding:0.5rem 0">
<p style="margin-bottom:0.6rem">{{msg}}</p>
<div style="display:flex;align-items:center;gap:0.5rem">
<label style="font-weight:bold">{{label}}</label>
<input type="number" name="manualDr" value="0" min="0" style="width:5rem"/>
</div>
</div>