foundry-dsa41-game/src/module/data/specialAbility.mjs

188 lines
7.6 KiB
JavaScript

import BaseItem from "./baseItem.mjs";
const {
BooleanField,
NumberField,
SchemaField,
ArrayField,
StringField,
HTMLField,
} = foundry.data.fields;
export class SpecialAbilityDataModel extends BaseItem {
static defineSchema() {
return {
name: new StringField(),
value: new StringField(),
auswahl: new ArrayField(
new SchemaField({
name: new StringField(),
requirement: new ArrayField(
new SchemaField({
attribute: new StringField(),
minValue: new NumberField(),
maxValue: new NumberField(),
sonderfertigkeit: new StringField(),
talent: new StringField(),
})
),
mod: new ArrayField(new SchemaField({
name: new StringField(),
value: new NumberField(),
}))
}),
),
gruppe: new StringField(),
seite: new NumberField(),
aktionsText: new HTMLField(),
text: new HTMLField(),
requirement: new ArrayField(
new SchemaField({
attribute: new StringField(),
minValue: new NumberField(),
maxValue: new NumberField(),
sonderfertigkeit: new StringField(),
talent: new StringField(),
compare: new SchemaField({
ownAttribute: new StringField(),
targetAttribute: new StringField(),
operation: new StringField(),
}, {required: false}),
})
),
waffenLimit: new ArrayField(
new SchemaField({
waffe: new StringField(),
gruppe: new StringField(),
mod: new NumberField(),
})
),
mod: new ArrayField(new SchemaField({
name: new StringField(),
value: new NumberField(),
})),
mehrereAktionen: new BooleanField(),
}
}
#getRequirements() {
if (this.value && this.auswahl?.find(p => p.name === this.value)) {
const auswahl = this.auswahl?.find(p => p.name === this.value)
return auswahl.requirement
} else {
return this.requirement
}
}
getActiveMod(options) {
if (this.isActive(options)) {
if (this.value && this.auswahl?.find(p => p.name === this.value)) {
const auswahl = this.auswahl?.find(p => p.name === this.value)
return auswahl.mod
} else {
return this.mod
}
} else {
return []
}
}
isActive(options) {
const requirements = this.#getRequirements()
let passes = true
let mod = 0
if (this.parent?.actor) {
const flatActor = foundry.utils.flattenObject(this.parent.actor.system)
if (requirements) for (let requirement of requirements) {
let targetField = null
if (requirement.attribute) {
targetField = flatActor?.[requirement.attribute.toLocaleLowerCase()]
}
if (requirement.talent) {
targetField = this.parent.actor.itemTypes["Skill"].find(p => p.name.toLocaleLowerCase() === requirement.talent.toLocaleLowerCase())?.taw ?? Number.NaN
}
if (requirement.minValue) {
passes = requirement.minValue <= targetField
if (!passes) console.debug(`fails requirement ${requirement.attribute ?? requirement.talent} (${requirement.minValue} <= ${targetField})`)
}
if (requirement.maxValue) {
passes = targetField <= requirement.maxValue
if (!passes) console.debug(`fails requirement ${requirement.attribute ?? requirement.talent} (${targetField} <= ${requirement.maxValue})`)
}
if (requirement.sonderfertigkeit) { // FIXME fails when it tries to self reference itself e.g. Ausweichen II has Ausweichen I as requirement
const regexp = /(\w*)\W?(\w*)?/
const [variantName, baseAbility, level] = regexp.exec(requirement.sonderfertigkeit)
passes = this.parent.actor.itemTypes["SpecialAbility"].find(p => p.name === baseAbility) != undefined
if (!passes) console.debug(`fails requirement ${requirement.sonderfertigkeit} (not in possession)`)
}
if (requirement["compare"]) {
const {ownAttribute, operation, targetAttribute} = requirement["compare"]
if (options.target) {
const flatTarget = foundry.utils.flattenObject(options.target.system)
const foreignTargetField = flatTarget[targetAttribute]
const ourTargetField = flatActor[ownAttribute]
switch (operation) {
case "lt":
passes = ourTargetField < foreignTargetField;
break;
case "lte":
passes = ourTargetField <= foreignTargetField;
break;
case "eq":
passes = ourTargetField == foreignTargetField;
break;
case "neq":
passes = ourTargetField != foreignTargetField;
break;
case "gte":
passes = ourTargetField >= foreignTargetField;
break;
case "gt":
passes = ourTargetField > foreignTargetField;
break;
}
if (!passes) {
console.debug(`fails compare requirement ${ownAttribute} ${operation} ${targetAttribute}`)
}
} else {
console.debug(`fails compare requirement as no target has been selected`)
return false // cant pass as we dont have a target
}
}
if (!passes) {
console.debug("fails atleast 1 requirement of ", this)
break
}
}
if (passes) {
if (options?.weapon) {
for (const waff of this.waffenLimit) {
if (waff.waffe) {
passes = options?.weapon?.name === waff.waffe ?? false
if (waff.mod) mod = waff.mod
if (passes)
break
}
if (waff.gruppe) {
passes = options?.skill?.name === waff.gruppe ?? false
if (waff.mod) mod = waff.mod
if (passes)
break
}
}
}
}
}
return {passes, mod}
}
}