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}}
-