ENH: Party sheet v2
							parent
							
								
									a14bd9fd42
								
							
						
					
					
						commit
						853225545d
					
				|  | @ -47,89 +47,11 @@ export class OseActorSheetCharacter extends OseActorSheet { | |||
|     ); | ||||
|     data.config.ascendingAC = game.settings.get("ose", "ascendingAC"); | ||||
|     data.config.individualInit = game.settings.get("ose", "individualInit"); | ||||
| 
 | ||||
|     // Compute treasure
 | ||||
|     let total = 0; | ||||
|     data.owned.items.forEach((item) => { | ||||
|       if (item.data.treasure) { | ||||
|         total += item.data.quantity.value * item.data.cost; | ||||
|       } | ||||
|     }); | ||||
|     data.treasure = total; | ||||
| 
 | ||||
|     data.config.encumbrance = game.settings.get("ose", "encumbranceOption"); | ||||
|     let basic = data.config.encumbrance == "basic"; | ||||
|     // Compute encumbrance
 | ||||
|     let totalWeight = 0; | ||||
|     Object.values(data.owned).forEach((cat) => { | ||||
|       cat.forEach((item) => { | ||||
|         if (item.type == "item" && (!basic || item.data.treasure)) { | ||||
|           totalWeight += item.data.quantity.value * item.data.weight; | ||||
|         } else if (!basic) { | ||||
|           totalWeight += item.data.weight; | ||||
|         } | ||||
|       }); | ||||
|     }); | ||||
|     data.encumbrance = { | ||||
|       pct: Math.clamped( | ||||
|         (100 * parseFloat(totalWeight)) / data.data.encumbrance.max, | ||||
|         0, | ||||
|         100 | ||||
|       ), | ||||
|       max: data.data.encumbrance.max, | ||||
|       encumbered: totalWeight > data.data.encumbrance.max, | ||||
|       value: totalWeight, | ||||
|     }; | ||||
| 
 | ||||
|     if (data.data.config.movementAuto) { | ||||
|       this._calculateMovement(data, totalWeight); | ||||
|     } | ||||
| 
 | ||||
|     return data; | ||||
|   } | ||||
| 
 | ||||
|   _calculateMovement(data, weight) { | ||||
|     if (data.config.encumbrance == "disabled") return; | ||||
|     let delta = data.encumbrance.max - 1600; | ||||
|     if (data.config.encumbrance == "detailed") { | ||||
|       if (weight > data.encumbrance.max) { | ||||
|         data.data.movement.base = 0; | ||||
|       } else if (weight > 800 + delta) { | ||||
|         data.data.movement.base = 30; | ||||
|       } else if (weight > 600 + delta) { | ||||
|         data.data.movement.base = 60; | ||||
|       } else if (weight > 400 + delta) { | ||||
|         data.data.movement.base = 90; | ||||
|       } else { | ||||
|         data.data.movement.base = 120; | ||||
|       } | ||||
|     } else if (data.config.encumbrance == "basic") { | ||||
|       let heaviest = 0; | ||||
|       data.owned.armors.forEach((a) => { | ||||
|         if (a.data.equipped) { | ||||
|           if (a.data.type == "light" && heaviest == 0) { | ||||
|             heaviest = 1; | ||||
|           } else if (a.data.type == "heavy") { | ||||
|             heaviest = 2; | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
|       switch (heaviest) { | ||||
|         case 0: | ||||
|           data.data.movement.base = 120; | ||||
|           break; | ||||
|         case 1: | ||||
|           data.data.movement.base = 90; | ||||
|           break; | ||||
|         case 2: | ||||
|           data.data.movement.base = 60; | ||||
|           break; | ||||
|       } | ||||
|       if (weight > game.settings.get("ose", "significantTreasure")) { | ||||
|         data.data.movement.base -= 30; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   async _chooseLang() { | ||||
|     let choices = CONFIG.OSE.languages; | ||||
|  |  | |||
|  | @ -13,6 +13,8 @@ export class OseActor extends Actor { | |||
|     this.computeModifiers(); | ||||
|     this._isSlow(); | ||||
|     this.computeAC(); | ||||
|     this.computeEncumbrance(); | ||||
|     this.computeTreasure(); | ||||
| 
 | ||||
|     // Determine Initiative
 | ||||
|     if (game.settings.get("ose", "individualInit")) { | ||||
|  | @ -24,7 +26,6 @@ export class OseActor extends Actor { | |||
|       data.initiative.value = 0; | ||||
|     } | ||||
|     data.movement.encounter = data.movement.base / 3; | ||||
| 
 | ||||
|   } | ||||
|   /* -------------------------------------------- */ | ||||
|   /*  Socket Listeners and Handlers | ||||
|  | @ -216,8 +217,8 @@ export class OseActor extends Actor { | |||
|       data: data, | ||||
|       skipDialog: skip, | ||||
|       speaker: ChatMessage.getSpeaker({ actor: this }), | ||||
|       flavor: game.i18n.format("OSE.roll.attribute", {attribute: label}), | ||||
|       title: game.i18n.format("OSE.roll.attribute", {attribute: label}), | ||||
|       flavor: game.i18n.format("OSE.roll.attribute", { attribute: label }), | ||||
|       title: game.i18n.format("OSE.roll.attribute", { attribute: label }), | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|  | @ -272,8 +273,8 @@ export class OseActor extends Actor { | |||
|       data: data, | ||||
|       skipDialog: true, | ||||
|       speaker: ChatMessage.getSpeaker({ actor: this }), | ||||
|       flavor: game.i18n.localize('OSE.roll.appearing'), | ||||
|       title: game.i18n.localize('OSE.roll.appearing'), | ||||
|       flavor: game.i18n.localize("OSE.roll.appearing"), | ||||
|       title: game.i18n.localize("OSE.roll.appearing"), | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|  | @ -303,8 +304,8 @@ export class OseActor extends Actor { | |||
|       data: data, | ||||
|       skipDialog: skip, | ||||
|       speaker: ChatMessage.getSpeaker({ actor: this }), | ||||
|       flavor: game.i18n.format("OSE.roll.exploration", {exploration: label}), | ||||
|       title: game.i18n.format("OSE.roll.exploration", {exploration: label}), | ||||
|       flavor: game.i18n.format("OSE.roll.exploration", { exploration: label }), | ||||
|       title: game.i18n.format("OSE.roll.exploration", { exploration: label }), | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|  | @ -353,7 +354,7 @@ export class OseActor extends Actor { | |||
|     const data = this.data.data; | ||||
|     const rollParts = ["1d20"]; | ||||
|     const dmgParts = []; | ||||
|     let label = game.i18n.format('OSE.roll.attacks', {name: this.data.name}) | ||||
|     let label = game.i18n.format("OSE.roll.attacks", { name: this.data.name }); | ||||
|     if ( | ||||
|       !attData.dmg || | ||||
|       (!game.settings.get("ose", "variableWeaponDamage") && | ||||
|  | @ -361,7 +362,7 @@ export class OseActor extends Actor { | |||
|     ) { | ||||
|       dmgParts.push("1d6"); | ||||
|     } else { | ||||
|       label = game.i18n.format('OSE.roll.attacksWith', {name: attData.label}) | ||||
|       label = game.i18n.format("OSE.roll.attacksWith", { name: attData.label }); | ||||
|       dmgParts.push(attData.dmg); | ||||
|     } | ||||
| 
 | ||||
|  | @ -450,6 +451,101 @@ export class OseActor extends Actor { | |||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   computeEncumbrance() { | ||||
|     if (this.data.type != "character") { | ||||
|       return; | ||||
|     } | ||||
|     const data = this.data.data; | ||||
|     let option = game.settings.get("ose", "encumbranceOption"); | ||||
|     let basic = option == "basic"; | ||||
| 
 | ||||
|     // Compute encumbrance
 | ||||
|     let owned = ["weapon", "armor", "item"]; | ||||
|     let totalWeight = 0; | ||||
|     Object.values(this.data.items).forEach((item) => { | ||||
|       if (item.type == "item" && (!basic || item.data.treasure)) { | ||||
|         totalWeight += item.data.quantity.value * item.data.weight; | ||||
|       } else if (!basic && owned.includes(item.type)) { | ||||
|         totalWeight += item.data.weight; | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     data.encumbrance = { | ||||
|       pct: Math.clamped( | ||||
|         (100 * parseFloat(totalWeight)) / data.encumbrance.max, | ||||
|         0, | ||||
|         100 | ||||
|       ), | ||||
|       max: data.encumbrance.max, | ||||
|       encumbered: totalWeight > data.encumbrance.max, | ||||
|       value: totalWeight, | ||||
|     }; | ||||
| 
 | ||||
|     if (data.config.movementAuto && option != 'disabled') { | ||||
|       this._calculateMovement(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   _calculateMovement() { | ||||
|     const data = this.data.data; | ||||
|     let option = game.settings.get("ose", "encumbranceOption"); | ||||
|     let weight = data.encumbrance.value; | ||||
|     let delta = data.encumbrance.max - 1600; | ||||
|     if (option == "detailed") { | ||||
|       if (weight > data.encumbrance.max) { | ||||
|         data.movement.base = 0; | ||||
|       } else if (weight > 800 + delta) { | ||||
|         data.movement.base = 30; | ||||
|       } else if (weight > 600 + delta) { | ||||
|         data.movement.base = 60; | ||||
|       } else if (weight > 400 + delta) { | ||||
|         data.movement.base = 90; | ||||
|       } else { | ||||
|         data.movement.base = 120; | ||||
|       } | ||||
|     } else if (option == "basic") { | ||||
|       const armors = this.data.items.filter(i => i.type == "armor"); | ||||
|       let heaviest = 0; | ||||
|       armors.forEach((a) => { | ||||
|         if (a.data.equipped) { | ||||
|           if (a.data.type == "light" && heaviest == 0) { | ||||
|             heaviest = 1; | ||||
|           } else if (a.data.type == "heavy") { | ||||
|             heaviest = 2; | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
|       switch (heaviest) { | ||||
|         case 0: | ||||
|           data.movement.base = 120; | ||||
|           break; | ||||
|         case 1: | ||||
|           data.movement.base = 90; | ||||
|           break; | ||||
|         case 2: | ||||
|           data.movement.base = 60; | ||||
|           break; | ||||
|       } | ||||
|       if (weight > game.settings.get("ose", "significantTreasure")) { | ||||
|         data.movement.base -= 30; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   computeTreasure() { | ||||
|     if (this.data.type != "character") { | ||||
|       return; | ||||
|     } | ||||
|     const data = this.data.data; | ||||
|     // Compute treasure
 | ||||
|     let total = 0; | ||||
|     let treasure = this.data.items.filter(i => (i.type == "item" && i.data.treasure)) | ||||
|     treasure.forEach((item) => { | ||||
|        total += item.data.quantity.value * item.data.cost; | ||||
|     }); | ||||
|     data.treasure = total; | ||||
|   } | ||||
| 
 | ||||
|   computeAC() { | ||||
|     if (this.data.type != "character") { | ||||
|       return; | ||||
|  | @ -461,7 +557,7 @@ export class OseActor extends Actor { | |||
|     const data = this.data.data; | ||||
|     data.aac.naked = baseAc + data.scores.dex.mod; | ||||
|     data.ac.naked = baseAc - data.scores.dex.mod; | ||||
|     const armors = this.data.items.filter(i => i.type == 'armor'); | ||||
|     const armors = this.data.items.filter((i) => i.type == "armor"); | ||||
|     armors.forEach((a) => { | ||||
|       if (a.data.equipped && a.data.type != "shield") { | ||||
|         baseAc = a.data.ac.value; | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ export class OsePartySheet extends FormApplication { | |||
|     (options.classes = ["ose", "dialog", "party-sheet"]), | ||||
|       (options.id = "party-sheet"); | ||||
|     options.template = "systems/ose/templates/apps/party-sheet.html"; | ||||
|     options.width = 700; | ||||
|     options.width = 280; | ||||
|     return options; | ||||
|   } | ||||
| 
 | ||||
|  | @ -25,10 +25,14 @@ export class OsePartySheet extends FormApplication { | |||
|    * @return {Object} | ||||
|    */ | ||||
|   getData() { | ||||
|     const settings = { | ||||
|       ascending: game.settings.get('ose', 'ascendingAC') | ||||
|     }; | ||||
|     let data = { | ||||
|       data: this.object, | ||||
|       config: CONFIG.OSE, | ||||
|       user: game.user | ||||
|       user: game.user, | ||||
|       settings: settings | ||||
|     }; | ||||
|     return data; | ||||
|   } | ||||
|  | @ -115,5 +119,9 @@ export class OsePartySheet extends FormApplication { | |||
|       .click(this._selectActors.bind(this)); | ||||
|     html.find("button[data-action='deal-xp']").click(this._dealXP.bind(this)); | ||||
|     html.find("a.resync").click(() => this.render(true)); | ||||
|     html.find(".field-img").click((ev) => { | ||||
|       let actorId = ev.currentTarget.parentElement.dataset.actorId; | ||||
|       game.actors.get(actorId).sheet.render(true); | ||||
|     }) | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import { OsePartySheet } from "./dialog/party-sheet.js"; | ||||
| 
 | ||||
| export const addControl = (object, html) => { | ||||
|     let control = `<a class='ose-party-sheet' title='${game.i18n.localize('OSE.dialog.partysheet')}'><i class='fas fa-users'></i></a>`; | ||||
|     let control = `<button class='ose-party-sheet' type="button" title='${game.i18n.localize('OSE.dialog.partysheet')}'><i class='fas fa-users'></i></button>`; | ||||
|     html.find(".fas.fa-search").replaceWith($(control)) | ||||
|     html.find('.ose-party-sheet').click(ev => { | ||||
|         showPartySheet(object); | ||||
|  | @ -11,7 +11,17 @@ export const addControl = (object, html) => { | |||
| export const showPartySheet = (object) => { | ||||
|     event.preventDefault(); | ||||
|     new OsePartySheet(object, { | ||||
|       top: window.screen.height / 2, | ||||
|       left:window.screen.width / 2, | ||||
|       top: window.screen.height / 2 - 180, | ||||
|       left:window.screen.width / 2 - 140, | ||||
|     }).render(true); | ||||
| } | ||||
| 
 | ||||
| export const update = (actor, data) => { | ||||
|     if (actor.getFlag('ose', 'party')) { | ||||
|         Object.values(ui.windows).forEach(w => { | ||||
|             if (w instanceof OsePartySheet) { | ||||
|                 w.render(true); | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
| } | ||||
|  | @ -49,6 +49,7 @@ export const registerSettings = function () { | |||
|       basic: "OSE.Setting.EncumbranceBasic", | ||||
|       detailed: "OSE.Setting.EncumbranceDetailed", | ||||
|     }, | ||||
|     onChange: _ => window.location.reload() | ||||
|   }); | ||||
| 
 | ||||
|   game.settings.register("ose", "significantTreasure", { | ||||
|  | @ -58,5 +59,6 @@ export const registerSettings = function () { | |||
|     scope: "world", | ||||
|     type: Number, | ||||
|     config: true, | ||||
|     onChange: _ => window.location.reload() | ||||
|   }); | ||||
| }; | ||||
|  |  | |||
|  | @ -124,5 +124,5 @@ Hooks.on("preUpdateCombat", async (combat, data, diff, id) => { | |||
| Hooks.on("renderChatLog", (app, html, data) => OseItem.chatListeners(html)); | ||||
| Hooks.on("getChatLogEntryContext", chat.addChatMessageContextOptions); | ||||
| Hooks.on("renderChatMessage", chat.addChatMessageButtons); | ||||
| 
 | ||||
| Hooks.on("renderRollTableConfig", treasure.augmentTable); | ||||
| Hooks.on("renderRollTableConfig", treasure.augmentTable); | ||||
| Hooks.on("updateActor", party.update); | ||||
|  | @ -8,7 +8,7 @@ | |||
| .ose.dialog.party-sheet { | ||||
|   .window-content { | ||||
|     padding: 0; | ||||
|     height: 200px; | ||||
|     height: 400px; | ||||
|   } | ||||
|   .header { | ||||
|     color: whitesmoke; | ||||
|  | @ -19,24 +19,25 @@ | |||
|   .actor-list { | ||||
|     margin: 0; | ||||
|     overflow: auto; | ||||
|     height: 180px; | ||||
|     height: 350px; | ||||
|     list-style: none; | ||||
|     padding: 0; | ||||
|     .actor { | ||||
|       &:nth-child(even) { | ||||
|         background-color: rgba(0, 0, 0, 0.1); | ||||
|       } | ||||
|       padding: 2px; | ||||
|       .fas { | ||||
|         padding: 0 2px; | ||||
|       } | ||||
|       padding: 4px; | ||||
|       font-size: 12px; | ||||
|       height: 35px; | ||||
|       text-align: center; | ||||
|       line-height: 35px; | ||||
|       .field-img { | ||||
|         flex: 0 0 32px; | ||||
|         flex: 0 0 50px; | ||||
|         img { | ||||
|           border: none; | ||||
|           width: 32px; | ||||
|           height: 32px; | ||||
|           width: 50px; | ||||
|           height: 50px; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | @ -45,24 +46,16 @@ | |||
|     text-align: left; | ||||
|     text-indent: 10px; | ||||
|   } | ||||
|   .field-short { | ||||
|     flex: 0 0 45px; | ||||
|   } | ||||
|   .field-long { | ||||
|     flex: 0 0 80px; | ||||
|   } | ||||
|   .field-longer { | ||||
|     flex: 0 0 180px; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| #sidebar #actors .directory-header .header-search { | ||||
|   .ose-party-sheet { | ||||
|     width: 30px; | ||||
|     width: 32px; | ||||
|     text-align: center;  | ||||
|     line-height: 20px; | ||||
|   } | ||||
|   input { | ||||
|     width: calc(100% - 30px); | ||||
|     width: calc(100% - 45px); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -36,7 +36,7 @@ | |||
|         .modifiers-btn { | ||||
|           position: absolute; | ||||
|           left: 0; | ||||
|           top: -5px; | ||||
|           top: -8px; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  |  | |||
|  | @ -146,7 +146,7 @@ | |||
|     <li class="item-titles flexrow"> | ||||
|       <div class="item-caret"><i class="fas fa-caret-down"></i></div> | ||||
|       <div class="item-name">{{localize "OSE.items.Treasure"}}</div> | ||||
|       <div class="field-long">{{treasure}} <i class="fas fa-circle"></i></div> | ||||
|       <div class="field-long">{{data.treasure}} <i class="fas fa-circle"></i></div> | ||||
|       <div class="field-short"><i class="fas fa-hashtag"></i></div> | ||||
|       <div class="field-short"><i class="fas fa-weight-hanging"></i></div> | ||||
|       <div class="item-controls"> | ||||
|  | @ -189,7 +189,7 @@ | |||
|   </div> | ||||
| </section> | ||||
| <section> | ||||
|   {{#with encumbrance}} | ||||
|   {{#with data.encumbrance}} | ||||
|   <div class="encumbrance {{#if encumbered}}encumbered{{/if}}"> | ||||
|     <span class="encumbrance-bar" style="width:{{pct}}%"></span> | ||||
|     <span class="encumbrance-label">{{value}} / {{max}}</span> | ||||
|  |  | |||
|  | @ -1,62 +1,71 @@ | |||
| <form autocomplete="off"> | ||||
|   <header class="flexrow"> | ||||
|     {{#if user.isGM}} | ||||
|     <button data-action="select-actors" type="button">{{localize  "OSE.dialog.selectActors"}}</button> | ||||
|     <button data-action="deal-xp" type="button">{{localize  "OSE.dialog.dealXP"}}</button> | ||||
|     <button data-action="select-actors" type="button"> | ||||
|       {{localize "OSE.dialog.selectActors"}} | ||||
|     </button> | ||||
|     <button data-action="deal-xp" type="button"> | ||||
|       {{localize "OSE.dialog.dealXP"}} | ||||
|     </button> | ||||
|     {{/if}} | ||||
|   </header> | ||||
|   <div class="actor header flexrow"> | ||||
|     <div class="field-name"> | ||||
|       <a class="resync"><i class="fas fa-sync"></i></a>   | ||||
|     </div> | ||||
|     <div class="field-long"> | ||||
|       {{localize 'OSE.Health'}} | ||||
|     </div> | ||||
|     <div class="field-short"> | ||||
|       {{localize 'OSE.ArmorClassShort'}} | ||||
|     </div> | ||||
|     <div class="field-short"> | ||||
|       {{localize 'OSE.Thac0'}} | ||||
|     </div> | ||||
|     <div class="field-short"> | ||||
|       {{localize 'OSE.movement.encounter.short'}} | ||||
|     </div> | ||||
|     <div class="field-longer"> | ||||
|       {{localize 'OSE.category.saves'}} | ||||
|       <a class="resync"><i class="fas fa-sync"></i></a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <ol class="actor-list"> | ||||
|     {{#each data.entities as |e|}} | ||||
|     {{#if e.data.flags.ose.party}} | ||||
|     {{#each data.entities as |e|}} {{#if e.data.flags.ose.party}} | ||||
|     <li class="actor flexrow" data-actor-id="{{e.id}}"> | ||||
|       <div class="field-img"> | ||||
|         <img src="{{e.img}}"/> | ||||
|         <a><img src="{{e.img}}" /></a> | ||||
|       </div> | ||||
|       <div class="field-name"> | ||||
|         {{e.name}} | ||||
|       </div> | ||||
|       <div class="item-controls field-long"> | ||||
|         <div class="item-control reaction-roll" title="Reaction Roll"><a><i class="fas fa-user"></i></a></div> | ||||
|       </div> | ||||
|       <div class="field-long"> | ||||
|         {{e.data.data.hp.value}}/{{e.data.data.hp.max}} | ||||
|       </div> | ||||
|       <div class="field-short"> | ||||
|         <strong>{{e.data.data.ac.value}}</strong> <sub>{{e.data.data.ac.naked}}</sub> | ||||
|       </div> | ||||
|       <div class="field-short"> | ||||
|         <sub>{{e.data.data.thac0.mod.melee}}</sub> <strong>{{e.data.data.thac0.value}}</strong> <sub>{{e.data.data.thac0.mod.missile}}</sub> | ||||
|       </div> | ||||
|       <div class="field-short"> | ||||
|         {{e.data.data.movement.encounter}} | ||||
|       </div> | ||||
|       <div class="field-longer flexrow"> | ||||
|         {{#each e.data.data.saves as |s i|}} | ||||
|         <span>{{lookup @root.config.saves_short i}} {{s.value}}</span> | ||||
|         {{/each}} | ||||
|       <div> | ||||
|         <div class="flexrow"> | ||||
|           <div class="field-name flex2"> | ||||
|             <strong>{{e.name}}</strong> | ||||
|           </div> | ||||
|           <div class="field-long"> | ||||
|             <i class="fas fa-heart"></i> | ||||
|             {{e.data.data.hp.value}}/{{e.data.data.hp.max}} | ||||
|           </div> | ||||
|           <div class="field-short"> | ||||
|             <i class="fas fa-shield-alt"></i> | ||||
|             {{#if @root.settings.ascending}}<strong>{{e.data.data.aac.value}}</strong> <sub>{{e.data.data.aac.naked}}</sub> | ||||
|             {{else}}<strong>{{e.data.data.ac.value}}</strong> <sub>{{e.data.data.ac.naked}}</sub> | ||||
|             {{/if}} | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="flexrow"> | ||||
|           <div class="field-short"> | ||||
|             <i class="fas fa-fist-raised"></i> | ||||
|             <sub>{{e.data.data.thac0.mod.melee}}</sub> <strong>{{e.data.data.thac0.value}}</strong> <sub>{{e.data.data.thac0.mod.missile}}</sub> | ||||
|           </div> | ||||
|           <div class="field-short"> | ||||
|             <i class="fas fa-shoe-prints"></i> | ||||
|             {{e.data.data.movement.encounter}} | ||||
|           </div> | ||||
|           {{#if (eq e.data.type 'character')}} | ||||
|           <div class="field-short"> | ||||
|             <i class="fas fa-weight-hanging"></i> | ||||
|             {{e.data.data.encumbrance.value}} | ||||
|           </div> | ||||
|           <div class="field-short"> | ||||
|             <i class="fas fa-circle"></i> | ||||
|             {{e.data.data.treasure}} | ||||
|           </div> | ||||
|           {{/if}} | ||||
|         </div> | ||||
|         <div class="flexrow"> | ||||
|           <div class="field-longer flexrow"> | ||||
|             {{#each e.data.data.saves as |s i|}} | ||||
|             <span>{{lookup @root.config.saves_short i}} {{s.value}}</span> | ||||
|             {{/each}} | ||||
|             {{#if (eq e.data.type 'character')}}<i class="fas fa-magic"></i>{{mod e.data.data.scores.wis.mod}}{{/if}} | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </li> | ||||
|     {{/if}} | ||||
|     {{/each}} | ||||
|     {{/if}} {{/each}} | ||||
|   </ol> | ||||
| </form> | ||||
		Loading…
	
		Reference in New Issue