export class ActionManager { static FREE = "free-action"; static REGULAR = "regular-action"; static CONTINUING = "continuing-action"; static MOVEMENT = "movement-action" static DEFENSE = "defense-action" static ATTACK = "attack-action" static INTERACTION = "interaction"; static TALENT = "talent-action" static SPELL = "spell"; static DEFAULT = "default" static SF = "special-ability" constructor(actor) { this.actor = actor } #freeActions = [ { name: "Ausweichen", cost: ActionManager.FREE, type: ActionManager.DEFENSE, source: ActionManager.DEFAULT, eval: (options) => { if (options?.weapon && options.weapon === "Ausweichen") { return true } return false } }, { name: "Rufen", cost: ActionManager.FREE, type: ActionManager.INTERACTION, source: ActionManager.DEFAULT, eval: (options) => true }, { name: "Sich zu Boden fallen lassen", cost: ActionManager.FREE, type: ActionManager.MOVEMENT, source: ActionManager.DEFAULT, eval: (options) => true }, { name: "Waffe oder Gegenstand fallen lassen", cost: ActionManager.FREE, type: ActionManager.INTERACTION, source: ActionManager.DEFAULT, eval: (options) => true }, { name: "getragenes Artefakt aktivieren", cost: ActionManager.FREE, type: ActionManager.INTERACTION, source: ActionManager.DEFAULT, eval: (options) => true }, { name: "Schnellziehen", cost: ActionManager.FREE, type: ActionManager.INTERACTION, source: ActionManager.SF, eval: (options) => { const step1 = this.#hatSonderfertigkeit("Schnellziehen", options) const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Schnellziehen", options) if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) { return step2WithBenefits } else return false }, } ] #regularActions = [ { name: "Nahkampfangriff", type: ActionManager.ATTACK, cost: ActionManager.REGULAR, source: ActionManager.DEFAULT, activate: (queue, data) => { data.actor.rollAttack(data) return true }, eval: (options) => this.#hatWaffeinHand(options), }, { name: "Fernkampfangriff", type: ActionManager.ATTACK, cost: ActionManager.CONTINUING, source: ActionManager.DEFAULT, cooldown: (options) => 1, activate: (queue, data) => { data.actor.rollAttack(data) return true }, eval: (options) => this.#hatFernkampfWaffeinHand(options), }, { name: "Angesagter Fernkampfangriff", // wird durch Scharfer Schuss aus SF ersetzt type: ActionManager.ATTACK, cost: ActionManager.CONTINUING, source: ActionManager.DEFAULT, cooldown: (options) => options.mod, activate: (queue, data) => { data.actor.rollAttack(data) return true }, eval: (options) => { const step1 = this.#hatFernkampfWaffeinHand(options) const step2 = !this.#hatSonderfertigkeit("Scharfschütze", options) const step3 = this.#hatSonderfertigkeit("Scharfschütze", options) && !this.#evalSonderfertigkeitRequirements("Scharfschütze", options) if (step1 && (step2 || step3)) { return true } else return false }, modDescription: "erhöht TP vom Angriff um {}", mod: (value) => -value * 2 }, { name: "Scharfer Schuss", 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) if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) { return step2WithBenefits } else return false }, modDescription: "erhöht TP vom Angriff um {}", mod: (value) => -value }, { name: "Schnellschuss", 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) }, { name: "Schnellschuss (Scharfschütze)", 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) if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) { return step2WithBenefits } else return false } }, { name: "Parade", type: ActionManager.DEFENSE, cost: ActionManager.REGULAR, source: ActionManager.DEFAULT, eval: (options) => { if (options?.weapon && options.weapon !== "Ausweichen") { return true } return false } }, { name: "Meisterparade", type: ActionManager.DEFENSE, cost: ActionManager.REGULAR, source: ActionManager.SF, modDescription: "erschwert nächste AT vom Ziel um {}", mod: (value) => -value, eval: (options) => { const step1 = this.#hatWaffeinHand(options) && this.#hatSonderfertigkeit("Meisterparade", options) const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Meisterparade", options) if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) { return step2WithBenefits } else return false } }, { name: "Bewegen", type: ActionManager.MOVEMENT, cost: ActionManager.REGULAR, source: ActionManager.DEFAULT, eval: (options) => true }, { name: "Position", type: ActionManager.MOVEMENT, cost: ActionManager.REGULAR, source: ActionManager.DEFAULT, eval: (options) => true }, { name: "Finte", type: ActionManager.ATTACK, cost: ActionManager.REGULAR, source: ActionManager.SF, modDescription: "verringert PA des Ziels um {}", mod: (value) => value, activate: (queue, data) => { data.actor.rollAttack(data) return true }, eval: (options) => { const step1 = this.#hatWaffeinHand(options) && this.#hatSonderfertigkeit("Finte", options) const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Finte", options) if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) { return step2WithBenefits } else return false } }, { name: "Wuchtschlag", // wird durch Wuchtschlag aus SF ersetzt type: ActionManager.ATTACK, cost: ActionManager.REGULAR, source: ActionManager.DEFAULT, modDescription: "erhöht TP vom Angriff um {}", mod: (value) => -(value * 2), activate: (queue, data) => { data.actor.rollAttack(data) return true }, eval: (options) => { const step1 = !this.#hatFernkampfWaffeinHand(options) const step2 = !this.#hatSonderfertigkeit("Wuchtschlag", options) const step3 = this.#hatSonderfertigkeit("Wuchtschlag", options) && !this.#evalSonderfertigkeitRequirements("Wuchtschlag", options) if (step1 && (step2 || step3)) { return true } else return false } }, { name: "Wuchtschlag (Sonderfertigkeit)", type: ActionManager.ATTACK, cost: ActionManager.REGULAR, source: ActionManager.SF, modDescription: "erhöht TP vom Angriff um {}", mod: (value) => -(value), activate: (queue, data) => { data.actor.rollAttack(data) return true }, eval: (options) => { const step1 = !this.#hatFernkampfWaffeinHand(options) && this.#hatSonderfertigkeit("Wuchtschlag", options) const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Wuchtschlag", options) if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) { return step2WithBenefits } else return false } }, { name: "Betäubungsschlag", type: ActionManager.ATTACK, cost: ActionManager.REGULAR, source: ActionManager.SF, activate: (queue, data) => { data.actor.rollAttack(data) return true }, eval: (options) => { const step1 = !this.#hatFernkampfWaffeinHand(options) && this.#hatSonderfertigkeit("Betäubungsschlag", options) const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Betäubungsschlag", options) if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) { return step2WithBenefits } else return false } } ] #continuingActions = [ { name: "Orientieren", type: ActionManager.TALENT, cost: ActionManager.CONTINUING, source: ActionManager.DEFAULT, eval: (options) => true }, { name: "Waffe ziehen", type: ActionManager.INTERACTION, cost: ActionManager.CONTINUING, source: ActionManager.DEFAULT, eval: (options) => true }, { name: "Sprinten", type: ActionManager.MOVEMENT, cost: ActionManager.CONTINUING, source: ActionManager.DEFAULT, eval: (options) => true }, { name: "Gegenstand benutzen", type: ActionManager.INTERACTION, cost: ActionManager.CONTINUING, source: ActionManager.DEFAULT, eval: (options) => true }, { name: "Schnellladen (Bogen)", 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) && this.#hatSonderfertigkeit("Schnellladen (Bogen)", options) const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Schnellladen (Bogen)", options) if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) { return step2WithBenefits } else return false } }, { name: "Schnellladen (Armbrust)", 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) && this.#hatSonderfertigkeit("Schnellladen (Armbrust)", options) const step2WithBenefits = this.#evalSonderfertigkeitRequirements("Schnellladen (Armbrust)", options) if (step1 && step2WithBenefits ? step2WithBenefits.passes : false) { return step2WithBenefits } else return false } }, { name: "Nachladen", 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() }, { name: "Talenteinsatz", type: ActionManager.TALENT, cost: ActionManager.CONTINUING, source: ActionManager.DEFAULT, eval: (options) => true }, { name: "Zaubern", type: ActionManager.SPELL, cost: ActionManager.CONTINUING, source: ActionManager.SF, eval: (options) => this.#hatSonderfertigkeitBeginnendMit("Repräsentation:", options) }, { name: "Liturgie wirken", type: ActionManager.SPELL, cost: ActionManager.CONTINUING, source: ActionManager.SF, eval: (options) => this.#hatSonderfertigkeitBeginnendMit("Liturgiekenntnis", options) } ] #hatWaffeinHand(options) { if (options) { const item = this.actor.findEquipmentOnSlot("links") ?? this.actor.findEquipmentOnSlot("rechts") return item == options.weapon } else { return this.actor.findEquipmentOnSlot("links") != null || this.actor.findEquipmentOnSlot("rechts") != null } } #hatMunition() { const item = this.actor.findEquipmentOnSlot("munition") return item != null } #hatFernkampfWaffeinHand(options) { if (options) { const item = this.actor.findEquipmentOnSlot("fernkampf") return item == options.weapon } else { return this.actor.findEquipmentOnSlot("fernkampf") != null } } #hatSonderfertigkeitBeginnendMit(name, options) { return this.actor.itemTypes["SpecialAbility"]?.find(p => p.name.startsWith(name)) != null } #hatSonderfertigkeit(name, options) { return this.actor.itemTypes["SpecialAbility"]?.find(p => p.name === name) != null } #evalSonderfertigkeitRequirements(nameOfSF, options) { const sf = this.actor.itemTypes["SpecialAbility"].find(p => p.name === nameOfSF) return sf?.system.isActive(options) ?? false } /** * * @param {{target: String?}} options */ evaluate(options) { let actionArray = [...this.#freeActions, ...this.#regularActions, ...this.#continuingActions] return actionArray.filter(action => { return action.eval(options) }).map(action => { return { ...action, eval: action.eval(options) } }) } }