diff --git a/src/module/data/character.mjs b/src/module/data/character.mjs index fc0ed27d..9f4d176a 100644 --- a/src/module/data/character.mjs +++ b/src/module/data/character.mjs @@ -1,8 +1,7 @@ -import {Equipment} from "../documents/equipment.mjs"; - const { SchemaField, NumberField, + ObjectField, StringField, HTMLField, DocumentIdField, @@ -123,6 +122,12 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel { gilde: new StringField(), }), + cooldowns: new ArrayField(new SchemaField({ + start: new NumberField({required: true, integer: true}), + current: new NumberField({required: true, integer: true}), + data: new ObjectField() + })), + kampfwerte: new ArrayField(new SchemaField({ name: new StringField(), at: new NumberField({required: true, integer: true}), diff --git a/src/module/dialog/combatAction.mjs b/src/module/dialog/combatAction.mjs index 8e07001c..5ef5e614 100644 --- a/src/module/dialog/combatAction.mjs +++ b/src/module/dialog/combatAction.mjs @@ -1,4 +1,3 @@ -import {XmlImport} from "../xml-import/xml-import.mjs"; import {ActionManager} from "../sheets/actions/action-manager.mjs"; const {ApplicationV2, HandlebarsApplicationMixin} = foundry.applications.api @@ -81,19 +80,49 @@ export class CombatActionDialog extends HandlebarsApplicationMixin(ApplicationV2 static async #onSubmitForm(event, form, formData) { event.preventDefault() + const maneuver = this.#evaluateManeuvers().find(p => p.id === this._combatManeuverId) const weapon = this._actor.itemTypes["Equipment"].find(p => p._id === this._weaponId) const skill = this._actor.itemTypes["Skill"].find(p => p._id === this._skillId) const target = game.actors.get(game.scenes.current.tokens.find(p => p._id === this._targetId).actorId) - - const roll = new Roll("1d20cs<" + this._targetNumber) - const evaluated1 = (await roll.evaluate()) - - await evaluated1.toMessage({ - speaker: ChatMessage.getSpeaker({actor: this._actor}), - flavor: `Attackiert ${target.name} mit ${weapon.name} (${skill.name})
${this._modDescription}`, - rollMode: "publicroll", - }) - return true + if (maneuver.cost !== ActionManager.CONTINUING) { + this._actor.rollAttack({ + weapon: this._weaponId, + skill: this._skillId, + target: this._targetId, + maneuver, + mod: this._mod, + circumstance: this._circumstance, + penalty: this._penalty, + targetNumber: this._targetNumber, + modDescription: maneuver?.modDescription?.replace("{}", "" + this._mod) ?? "" + }) + return true + } else { // push into cooldown queue + const cooldowns = this._actor.system.cooldowns + const newCooldown = { + start: maneuver.cooldown({weapon, skill, target, mod: this._mod}), + current: maneuver.cooldown({weapon, skill, target, mod: this._mod}), + data: { + weapon: this._weaponId, + skill: this._skillId, + target: this._targetId, + maneuver, + mod: this._mod, + circumstance: this._circumstance, + penalty: this._penalty, + targetNumber: this._targetNumber, + modDescription: maneuver?.modDescription?.replace("{}", "" + this._mod) ?? "" + } + } + cooldowns.push(newCooldown) + await this._actor.update({"system.cooldowns": cooldowns}) + ui.notifications.info(`Neue Aktion für ${maneuver.name} mit Abklingzeit von ${maneuver.cooldown({ + weapon, + skill, + target, + mod: this._mod + })} Aktionen hinzugefügt`) + } } _configureRenderOptions(options) { @@ -214,7 +243,9 @@ export class CombatActionDialog extends HandlebarsApplicationMixin(ApplicationV2 cost: action.cost, penalty: action.eval?.mod ?? 0, mod: action.mod, - modDescription: action.modDescription + modDescription: action.modDescription, + cooldown: action.cooldown, + activate: action.activate, } }).sort((a, b) => (a.isSelected ? 0 : 1) - (b.isSelected ? 0 : 1)) return this._maneuvers diff --git a/src/module/documents/character.mjs b/src/module/documents/character.mjs index 692efdcd..397bff18 100644 --- a/src/module/documents/character.mjs +++ b/src/module/documents/character.mjs @@ -252,6 +252,22 @@ export class Character extends Actor { return false } + async rollAttack(data) { + const maneuver = data.manuever + const weapon = this.itemTypes["Equipment"].find(p => p._id === data.weapon) + const skill = this.itemTypes["Skill"].find(p => p._id === data.skill) + const target = game.actors.get(game.scenes.current.tokens.find(p => p._id === data.target).actorId) + + const roll = new Roll("1d20cs<" + data.targetNumber) + const evaluated1 = (await roll.evaluate()) + + await evaluated1.toMessage({ + speaker: ChatMessage.getSpeaker({actor: this}), + flavor: `Attackiert ${target.name} mit ${weapon.name} (${skill.name})
${data.modDescription}`, + rollMode: "publicroll", + }) + } + /** * * @param amount diff --git a/src/module/sheets/actions/action-manager.mjs b/src/module/sheets/actions/action-manager.mjs index d418236c..26ca3da8 100644 --- a/src/module/sheets/actions/action-manager.mjs +++ b/src/module/sheets/actions/action-manager.mjs @@ -80,8 +80,11 @@ export class ActionManager { { name: "Fernkampfangriff", type: ActionManager.ATTACK, - cost: ActionManager.REGULAR, + cost: ActionManager.CONTINUING, source: ActionManager.DEFAULT, + cooldown: (options) => 1, + activate: (queue, data) => { + }, eval: (options) => this.#hatFernkampfWaffeinHand(options), }, { @@ -89,6 +92,7 @@ export class ActionManager { type: ActionManager.ATTACK, cost: ActionManager.CONTINUING, source: ActionManager.DEFAULT, + cooldown: (options) => options.mod, eval: (options) => { const step1 = this.#hatFernkampfWaffeinHand(options) const step2 = !this.#hatSonderfertigkeit("Scharfschütze", options) @@ -106,6 +110,11 @@ export class ActionManager { type: ActionManager.ATTACK, cost: ActionManager.CONTINUING, source: ActionManager.SF, + cooldown: (options) => options.mod - 2, + activate: (queue, data) => { + data.actor.rollAttack(data) + return true + }, eval: (options) => { const step1 = this.#hatFernkampfWaffeinHand(options) && this.#hatSonderfertigkeit("Scharfschütze", options) const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Scharfschütze", options) @@ -122,6 +131,11 @@ export class ActionManager { type: ActionManager.INTERACTION, cost: ActionManager.CONTINUING, source: ActionManager.DEFAULT, + cooldown: (options) => 1, + activate: (queue) => { + // get earliest rangedAttack and reduce its cooldown by 1 but also increases its difficulty by 2 + return true + }, eval: (options) => this.#hatFernkampfWaffeinHand(options) }, { @@ -129,6 +143,11 @@ export class ActionManager { type: ActionManager.INTERACTION, cost: ActionManager.CONTINUING, source: ActionManager.SF, + cooldown: (options) => 1, + activate: (queue) => { + // get earliest rangedAttack and reduce its cooldown by 1 but also increases its difficulty by 1 + return true + }, eval: (options) => { const step1 = this.#hatFernkampfWaffeinHand(options) && this.#hatSonderfertigkeit("Scharfschütze", options) const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Scharfschütze", options) @@ -209,7 +228,7 @@ export class ActionManager { } }, { - name: "Wuchtschlag", + name: "Wuchtschlag (Sonderfertigkeit)", type: ActionManager.ATTACK, cost: ActionManager.REGULAR, source: ActionManager.SF, @@ -274,6 +293,10 @@ export class ActionManager { type: ActionManager.INTERACTION, cost: ActionManager.CONTINUING, source: ActionManager.SF, + cooldown: (options) => 1, + activate: (queue) => { // find earliest Reload Action and reduce it by 1 + return true + }, eval: (options) => { const step1 = this.#hatMunition() && this.#hatFernkampfWaffeinHand(options) @@ -290,6 +313,10 @@ export class ActionManager { type: ActionManager.INTERACTION, cost: ActionManager.CONTINUING, source: ActionManager.SF, + cooldown: (options) => 1, + activate: (queue) => { + return true // find earliest Reload Action and reduce it by 1 + }, eval: (options) => { const step1 = this.#hatMunition() && this.#hatFernkampfWaffeinHand(options) @@ -306,6 +333,10 @@ export class ActionManager { type: ActionManager.INTERACTION, cost: ActionManager.CONTINUING, source: ActionManager.DEFAULT, + cooldown: (options) => 1, // get reload time of weapon + activate: (queue) => { + return true // get ammunition of actor and reduce the Qty by 1 or if its as magazine, reduce its fill by 1 + }, eval: (options) => this.#hatMunition() }, { @@ -376,7 +407,6 @@ export class ActionManager { evaluate(options) { let actionArray = [...this.#freeActions, ...this.#regularActions, ...this.#continuingActions] return actionArray.filter(action => { - console.log(action.name, action.eval(options)) return action.eval(options) }).map(action => { return { diff --git a/src/module/sheets/character/combat.mjs b/src/module/sheets/character/combat.mjs index 883cc92a..c08d58c9 100644 --- a/src/module/sheets/character/combat.mjs +++ b/src/module/sheets/character/combat.mjs @@ -16,8 +16,7 @@ export default { } const am = new ActionManager(actorData) - context.actions = am.evaluate() - + context.actions = am.evaluate().filter(action => action.type !== ActionManager.ATTACK) context.inidice = actorData.system.ini.wuerfel context.inivalue = actorData.system.ini.aktuell @@ -31,75 +30,75 @@ export default { context.aupcurrent = actorData.system.aup.aktuell ?? 0 - const fernkampf = findEquipmentOnSlot("fernkampf", actorData.system.setEquipped, actorData) - const links = findEquipmentOnSlot("links", actorData.system.setEquipped, actorData) - const rechts = findEquipmentOnSlot("rechts", actorData.system.setEquipped, actorData) + // const fernkampf = findEquipmentOnSlot("fernkampf", actorData.system.setEquipped, actorData) + //const links = findEquipmentOnSlot("links", actorData.system.setEquipped, actorData) + // const rechts = findEquipmentOnSlot("rechts", actorData.system.setEquipped, actorData) context.attacks = []; - - if (fernkampf) { - const fkitems = fernkampf.system.rangedSkills.map((skillInQuestion) => actorData.items.find(p => p.name === skillInQuestion)) - fkitems.forEach(async skill => { - const obj = await skill - context.attacks.push({ - name: obj.name, - using: fernkampf.name, - atroll: `1d20cs<${object.system.fk.aktuell + obj.system.at}`, - at: `${object.system.fk.aktuell + obj.system.at}`, - tproll: `${fernkampf.system.rangedAttackDamage}`, // TODO consider adding TP/KK mod and Range mod - tp: `${fernkampf.system.rangedAttackDamage}`, - iniroll: `(${context.inidice})d6 + ${context.inivalue + fernkampf.system.iniModifier ?? 0}`, - ini: `${context.inidice}w6 + ${context.inivalue + fernkampf.system.iniModifier ?? 0}`, - }) - }) - } - if (links) { - const meitems = [] - links.system.meleeSkills.forEach((skillInQuestion) => { - const item = actorData.items.find(p => p.name === skillInQuestion) - if (item) { - meitems.push(item) + /* + if (fernkampf) { + const fkitems = fernkampf.system.rangedSkills.map((skillInQuestion) => actorData.items.find(p => p.name === skillInQuestion)) + fkitems.forEach(async skill => { + const obj = await skill + context.attacks.push({ + name: obj.name, + using: fernkampf.name, + atroll: `1d20cs<${object.system.fk.aktuell + obj.system.at}`, + at: `${object.system.fk.aktuell + obj.system.at}`, + tproll: `${fernkampf.system.rangedAttackDamage}`, // TODO consider adding TP/KK mod and Range mod + tp: `${fernkampf.system.rangedAttackDamage}`, + iniroll: `(${context.inidice})d6 + ${context.inivalue + fernkampf.system.iniModifier ?? 0}`, + ini: `${context.inidice}w6 + ${context.inivalue + fernkampf.system.iniModifier ?? 0}`, + }) + }) } - }) - meitems.forEach(skill => { - const obj = skill - context.attacks.push({ - name: obj.name, - using: links.name, - atroll: `1d20cs<${object.system.at.links.aktuell + obj.system.at + links.system.attackModifier}`, // TODO consider adding W/M - at: `${object.system.at.links.aktuell + obj.system.at + links.system.attackModifier}`, - paroll: `1d20cs<${object.system.pa.links.aktuell + obj.system.pa + links.system.parryModifier}`, // TODO consider adding W/M - pa: `${object.system.pa.links.aktuell + obj.system.pa + links.system.parryModifier}`, - tproll: `${links.system.meleeAttackDamage}`, // TODO consider adding TP/KK mod - tp: `${links.system.meleeAttackDamage}`, - iniroll: `(${context.inidice})d6 + ${context.inivalue + links.system.iniModifier ?? 0}`, - ini: `${context.inidice}w6 + ${context.inivalue + links.system.iniModifier ?? 0}`, - }) - }) - } - if (rechts) { - const meitems = [] - rechts.system.meleeSkills.forEach((skillInQuestion) => { - const item = actorData.items.find(p => p.name === skillInQuestion) - if (item) { - meitems.push(item) + if (links) { + const meitems = [] + links.system.meleeSkills.forEach((skillInQuestion) => { + const item = actorData.items.find(p => p.name === skillInQuestion) + if (item) { + meitems.push(item) + } + }) + meitems.forEach(skill => { + const obj = skill + context.attacks.push({ + name: obj.name, + using: links.name, + atroll: `1d20cs<${object.system.at.links.aktuell + obj.system.at + links.system.attackModifier}`, // TODO consider adding W/M + at: `${object.system.at.links.aktuell + obj.system.at + links.system.attackModifier}`, + paroll: `1d20cs<${object.system.pa.links.aktuell + obj.system.pa + links.system.parryModifier}`, // TODO consider adding W/M + pa: `${object.system.pa.links.aktuell + obj.system.pa + links.system.parryModifier}`, + tproll: `${links.system.meleeAttackDamage}`, // TODO consider adding TP/KK mod + tp: `${links.system.meleeAttackDamage}`, + iniroll: `(${context.inidice})d6 + ${context.inivalue + links.system.iniModifier ?? 0}`, + ini: `${context.inidice}w6 + ${context.inivalue + links.system.iniModifier ?? 0}`, + }) + }) } - }) - meitems.forEach(skill => { - const obj = skill - context.attacks.push({ - name: obj.name, - using: rechts.name, - atroll: `1d20cs<${object.system.at.rechts.aktuell + obj.system.at + rechts.system.attackModifier}`, // TODO consider adding W/M - at: `${object.system.at.rechts.aktuell + obj.system.at + rechts.system.attackModifier}`, - paroll: `1d20cs<${object.system.pa.rechts.aktuell + obj.system.pa + rechts.system.parryModifier}`, // TODO consider adding W/M - pa: `${object.system.pa.rechts.aktuell + obj.system.pa + rechts.system.parryModifier}`, - tproll: `${rechts.system.meleeAttackDamage}`, // TODO consider adding TP/KK mod - tp: `${rechts.system.meleeAttackDamage}`, - iniroll: `(${context.inidice})d6 + ${context.inivalue + rechts.system.iniModifier ?? 0}`, - ini: `${context.inidice}w6 + ${context.inivalue + rechts.system.iniModifier ?? 0}`, - }) - }) - } + if (rechts) { + const meitems = [] + rechts.system.meleeSkills.forEach((skillInQuestion) => { + const item = actorData.items.find(p => p.name === skillInQuestion) + if (item) { + meitems.push(item) + } + }) + meitems.forEach(skill => { + const obj = skill + context.attacks.push({ + name: obj.name, + using: rechts.name, + atroll: `1d20cs<${object.system.at.rechts.aktuell + obj.system.at + rechts.system.attackModifier}`, // TODO consider adding W/M + at: `${object.system.at.rechts.aktuell + obj.system.at + rechts.system.attackModifier}`, + paroll: `1d20cs<${object.system.pa.rechts.aktuell + obj.system.pa + rechts.system.parryModifier}`, // TODO consider adding W/M + pa: `${object.system.pa.rechts.aktuell + obj.system.pa + rechts.system.parryModifier}`, + tproll: `${rechts.system.meleeAttackDamage}`, // TODO consider adding TP/KK mod + tp: `${rechts.system.meleeAttackDamage}`, + iniroll: `(${context.inidice})d6 + ${context.inivalue + rechts.system.iniModifier ?? 0}`, + ini: `${context.inidice}w6 + ${context.inivalue + rechts.system.iniModifier ?? 0}`, + }) + }) + }*/ return context diff --git a/src/module/sheets/characterSheet.mjs b/src/module/sheets/characterSheet.mjs index 8e5621ec..fa0320ab 100644 --- a/src/module/sheets/characterSheet.mjs +++ b/src/module/sheets/characterSheet.mjs @@ -8,6 +8,7 @@ import Skills from "./character/skills.mjs" import Social from "./character/social.mjs"; import Spells from "./character/spells.mjs" import {CombatActionDialog} from "../dialog/combatAction.mjs"; +import {ActionManager} from "./actions/action-manager.mjs"; const {HandlebarsApplicationMixin} = foundry.applications.api const {ActorSheetV2} = foundry.applications.sheets @@ -38,7 +39,9 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { openCultureDocument: CharacterSheet.#openCultureDocument, openSpeciesDocument: CharacterSheet.#openSpeciesDocument, openCombatAction: CharacterSheet.#openCombatAction, - + progressCooldown: CharacterSheet.#progressCooldown, + cancelCooldown: CharacterSheet.#cancelCooldown, + activateCooldown: CharacterSheet.#activateCooldown, } } @@ -123,6 +126,53 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { } } + static async #progressCooldown(event, target) { + const {cooldownId} = target.dataset + const cooldowns = this.document.system.cooldowns + const cooldown = this.document.system.cooldowns[cooldownId] + cooldowns.splice(cooldownId, 1) + + if (cooldown) { + cooldown.current = cooldown.current - 1 + } + + cooldowns.push(cooldown) + this.document.update({"system.cooldowns": cooldowns.sort((a, b) => a.current - b.current)}) + ui.notifications.info(`Abklingzeit von ${cooldown.data.maneuver.name} um 1 Aktion reduziert`) + } + + static async #cancelCooldown(event, target) { + const {cooldownId} = target.dataset + const cooldown = this.document.system.cooldowns[cooldownId] + const cooldowns = this.document.system.cooldowns + + cooldowns.splice(cooldownId, 1) + + this.document.update({"system.cooldowns": cooldowns.sort((a, b) => a.current - b.current)}) + ui.notifications.info(`${cooldown.data.maneuver.name} abgebrochen`) + } + + static async #activateCooldown(event, target) { + const {cooldownId} = target.dataset + const cooldowns = this.document.system.cooldowns + const cooldown = this.document.system.cooldowns[cooldownId] + + if (cooldown && cooldown.current <= 0) { + const am = new ActionManager(this.document) + const action = am.evaluate().find(action => action.name === cooldown.data.maneuver.id) + console.log(action) + + if (action) { + action.activate(cooldowns, {...cooldown.data, actor: this.document}) + } + } + + cooldowns.splice(cooldownId, 1) + + this.document.update({"system.cooldowns": cooldowns.sort((a, b) => a.current - b.current)}) + ui.notifications.info(`${cooldown.data.maneuver.name} ausgeführt`) + } + /** * * @param {MouseEvent} event @@ -324,6 +374,15 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) { }) } + context.cooldowns = actorData.system.cooldowns ?? [] + context.cooldowns.forEach(cooldown => { + const weapon = this.document.itemTypes["Equipment"].find(p => p._id === cooldown.data.weapon) + const skill = this.document.itemTypes["Skill"].find(p => p._id === cooldown.data.skillId) + const target = game.actors.get(game.scenes.current.tokens.find(p => p._id === cooldown.data.target).actorId) + cooldown.progress = ((cooldown.current / cooldown.start) * 100) + "%" + cooldown.tooltip = `${cooldown.data.maneuver.name}
Waffe:${weapon.name}
Ziel: ${target.name}
Wurfziel: ${cooldown.data.targetNumber}
Aktionen verbleibend: ${cooldown.current}` + }) + context.attributes = [ { eigenschaft: "mu", diff --git a/src/style/molecules/_sidebar-elements.scss b/src/style/molecules/_sidebar-elements.scss index 2e69c5e3..fcbf075c 100644 --- a/src/style/molecules/_sidebar-elements.scss +++ b/src/style/molecules/_sidebar-elements.scss @@ -2,43 +2,14 @@ .head-data { - .sidebar-element { + .resource-bar { height: 24px; width: 100%; - margin-top: 4px; - - &.rollable { - - label { - display: inline-block; - line-height: 24px; - vertical-align: middle; - } - - .formula { - display: inline-block; - line-height: 24px; - vertical-align: middle; - } - - .die { - - } - - - &:hover { - .formula { - text-shadow: 0 0 10px rgb(255 0 0); - } - } - } - - &.resource-bar { - position: relative; border: 1px inset #ccc; background-color: rgba(0, 0, 0, 0.2); + margin: 8px 0; label { position: absolute; @@ -73,7 +44,7 @@ } &.lep::after { - background-color: rgba(0, 192, 96, 0.5); + background-color: rgba(192, 0, 0, 0.5); } &.aup::after { @@ -92,6 +63,151 @@ } + .attack { + + display: grid; + grid-template-columns: 32px 32px 1fr 1fr; + grid-template-rows: 18px 30px; + grid-template-areas: "name name name name" "at pa tp ini"; + height: 64px; + border: 1px inset #ccc; + border-radius: 4px; + background-color: rgba(0, 0, 0, 0.2); + padding: 8px; + margin-bottom: 8px; + gap: 0; + + h3 { + grid-area: name; + text-align: center; + } + + label { + font-size: smaller; + display: block; + text-align: center; + } + + .formula { + font-size: small; + display: block; + text-align: center; + } + + .at { + grid-area: at; + } + + .pa { + grid-area: pa; + } + + .ini { + grid-area: ini; + } + + .tp { + grid-area: tp; + + } + } + + .cooldowns { + + h3 { + text-align: center; + margin: 8px 0; + } + + .cooldown { + display: grid; + position: relative; + height: 24px; + width: 100%; + + grid-template-columns: 24px 1fr 24px; + grid-template-rows: 24px; + grid-template-areas: "btn-left text btn-right"; + border: 1px inset #ccc; + border-radius: 12px; + + background: url('/systems/DSA_4-1/assets/gradient.png'); + + .btn-left { + grid-area: btn-left; + color: white; + + i { + vertical-align: 1px; + } + } + + .btn-right { + grid-area: btn-right; + color: white; + } + + .btn-left, .btn-right { + z-index: 3; + vertical-align: middle; + min-height: 16px; + height: 24px; + width: 24px; + margin: 0; + padding: 0; + background: unset; + background-color: unset; + box-shadow: unset; + border-radius: 12px; + display: block; + border: unset; + } + + span { + grid-area: text; + z-index: 3; + height: 24px; + line-height: 24px; + vertical-align: middle; + color: white; + text-align: center; + text-shadow: 2px 2px 1px rgba(0, 0, 0, 0.3); + } + + .progress { + position: absolute; + background: url('/systems/DSA_4-1/assets/gradient.png'); + background-size: 12px 100%; + left: 0; + bottom: 0; + top: 0; + border-radius: 12px; + z-index: 2; + + &::after { // progress fill + content: ''; + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + border-radius: 12px; + background-color: rgba(128, 0, 192, 0.5); + } + } + + &::after { + position: absolute; + content: ''; + left: 0; + top: 0; + bottom: 0; + right: 0; + border-radius: 12px; + background-color: rgba(0, 0, 0, 0.8); + } + + } } } diff --git a/src/style/organisms/character-tabs/_combat.scss b/src/style/organisms/character-tabs/_combat.scss index d8c667b2..58cf677a 100644 --- a/src/style/organisms/character-tabs/_combat.scss +++ b/src/style/organisms/character-tabs/_combat.scss @@ -4,7 +4,7 @@ grid-template-columns: 1fr 320px; grid-template-rows: 32px 32px 1fr; - grid-template-areas: "res res" "wounds wounds" "actions actions"; + grid-template-areas: "res res" "wounds wounds" "actions actions" "cooldowns cooldowns"; padding: 8px; gap: 8px; @@ -99,9 +99,13 @@ } } + .cooldowns { + grid-area: cooldowns; + } + &.zones { - grid-template-areas: "res res" "wounds wounds" "actions paperdoll"; + grid-template-areas: "res res" "wounds wounds" "actions paperdoll" "cooldowns paperdoll"; .paperdoll { grid-area: paperdoll; diff --git a/src/templates/actor/character/main-sheet.hbs b/src/templates/actor/character/main-sheet.hbs index ec7e1e6a..086a1760 100644 --- a/src/templates/actor/character/main-sheet.hbs +++ b/src/templates/actor/character/main-sheet.hbs @@ -51,36 +51,61 @@ {{/if}} {{#each attacks}} -
+

{{this.using}} ({{this.name}})

-
+ {{#if this.at}} -