implements cooldowntracker for ongoing actions
parent
3c7426bf56
commit
7d23af8902
|
|
@ -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}),
|
||||
|
|
|
|||
|
|
@ -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})<br/>${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
|
||||
|
|
|
|||
|
|
@ -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})<br/>${data.modDescription}`,
|
||||
rollMode: "publicroll",
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param amount
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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}<br/>Waffe:${weapon.name}<br/>Ziel: ${target.name}<br/>Wurfziel: ${cooldown.data.targetNumber}<br/>Aktionen verbleibend: ${cooldown.current}`
|
||||
})
|
||||
|
||||
context.attributes = [
|
||||
{
|
||||
eigenschaft: "mu",
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -51,36 +51,61 @@
|
|||
{{/if}}
|
||||
|
||||
{{#each attacks}}
|
||||
<div>
|
||||
<div class="attack">
|
||||
<h3>{{this.using}} ({{this.name}})</h3>
|
||||
<div class="combined">
|
||||
|
||||
{{#if this.at}}
|
||||
<div class="sidebar-element rollable" data-roll="{{this.atroll}}" data-label="Attacke">
|
||||
<div class="at sidebar-element rollable" data-mode="attack" data-action="openCombatAction">
|
||||
<label>AT</label>
|
||||
<div class="formula">{{this.at}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if this.pa}}
|
||||
<div class="sidebar-element rollable" data-roll="{{this.paroll}}" data-label="Parade">
|
||||
<div class="pa sidebar-element rollable" data-mode="defense" data-action="openCombatAction">
|
||||
<label>PA</label>
|
||||
<div class="formula">{{this.pa}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#if this.at}}
|
||||
<div class="sidebar-element rollable" data-roll="{{this.tproll}}" data-label="Schaden">
|
||||
<label>Schaden</label>
|
||||
<div class="tp sidebar-element rollable" data-roll="{{this.tproll}}" data-label="Schaden">
|
||||
<label>TP</label>
|
||||
<div class="formula">{{this.tp}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if this.ini}}
|
||||
<div class="sidebar-element rollable" data-label="Initiative" data-roll="{{this.iniroll}}"><label>Initiative</label>
|
||||
<div class="ini sidebar-element rollable" data-action="openInitiative"><label>INI</label>
|
||||
<div class="formula">{{this.ini}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
</div>
|
||||
{{/each}}
|
||||
|
||||
<section class="cooldowns">
|
||||
<h3>Abklingzeiten</h3>
|
||||
{{#each this.cooldowns}}
|
||||
<div class="cooldown">
|
||||
<div class="progress" style="width: {{this.progress}}"></div>
|
||||
{{#if (gt this.current 0)}}
|
||||
<button class="btn-left" data-action="progressCooldown" data-cooldown-id="{{@key}}">
|
||||
<i class="fa fa-timer"></i>
|
||||
</button>
|
||||
<span data-tooltip="{{this.tooltip}}">{{this.data.maneuver.name}}</span>
|
||||
<button class="btn-right" data-action="cancelCooldown" data-cooldown-id="{{@key}}">
|
||||
<i class="fa fa-xmark"></i>
|
||||
</button>
|
||||
{{else}}
|
||||
<button class="btn-left" data-action="activateCooldown" data-cooldown-id="{{@key}}">
|
||||
<i class="fa fa-person-running"></i>
|
||||
</button>
|
||||
<span data-tooltip="{{this.tooltip}}">{{this.data.maneuver.name}}</span>
|
||||
<button class="btn-right" data-action="cancelCooldown" data-cooldown-id="{{@key}}">
|
||||
<i class="fa fa-xmark"></i>
|
||||
</button>
|
||||
{{/if}}</div>
|
||||
{{/each}}
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
{{!-- Sheet Tab Navigation --}}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,16 @@
|
|||
<div class="actions">
|
||||
<h3>Aktionen im Kampf</h3>
|
||||
<div class="grid-of-actions">
|
||||
{{#each this.actions}}
|
||||
<div class="player-action attack-action" data-mode="attack" data-action="openCombatAction">
|
||||
<span class="name">Angriff</span>
|
||||
<span class="time">variabel</span>
|
||||
</div>
|
||||
<div class="player-action defense-action" data-mode="defense" data-action="openCombatAction">
|
||||
<span class="name">Verteidigen</span>
|
||||
<span class="time">variabel</span>
|
||||
</div>
|
||||
|
||||
{{#each this.actions}}
|
||||
{{> "systems/DSA_4-1/templates/ui/partial-action-button.hbs" this}}
|
||||
{{/each}}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue