diff --git a/module/applications/dialogs/damageReductionDialog.mjs b/module/applications/dialogs/damageReductionDialog.mjs index 0612089d..d97cbaa7 100644 --- a/module/applications/dialogs/damageReductionDialog.mjs +++ b/module/applications/dialogs/damageReductionDialog.mjs @@ -11,7 +11,8 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap this.actor = actor; this.damage = damage; - const canApplyArmor = actor.system.armorApplicableDamageTypes[damageType]; + // const canApplyArmor = actor.system.armorApplicableDamageTypes[damageType]; + const canApplyArmor = damageType.every(t => actor.system.armorApplicableDamageTypes[t] === true); const maxArmorMarks = canApplyArmor ? Math.min( actor.system.armorScore - actor.system.armor.system.marks.value, diff --git a/module/applications/sheets-configs/action-config.mjs b/module/applications/sheets-configs/action-config.mjs index 0beb8d79..03d378f2 100644 --- a/module/applications/sheets-configs/action-config.mjs +++ b/module/applications/sheets-configs/action-config.mjs @@ -56,10 +56,6 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { id: 'effect', template: 'systems/daggerheart/templates/sheets-settings/action-settings/effect.hbs' } - /* form: { - id: 'action', - template: 'systems/daggerheart/templates/config/action.hbs' - } */ }; static TABS = { @@ -148,6 +144,7 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { _prepareSubmitData(event, formData) { const submitData = foundry.utils.expandObject(formData.object); + console.log(formData, submitData) for (const keyPath of this.constructor.CLEAN_ARRAYS) { const data = foundry.utils.getProperty(submitData, keyPath); if (data) foundry.utils.setProperty(submitData, keyPath, Object.values(data)); @@ -161,7 +158,7 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { container = foundry.utils.getProperty(this.action.parent, this.action.systemPath); let newActions; if (Array.isArray(container)) { - newActions = foundry.utils.getProperty(this.action.parent, this.action.systemPath).map(x => x.toObject()); // Find better way + newActions = foundry.utils.getProperty(this.action.parent, this.action.systemPath).map(x => x.toObject()); if (!newActions.findSplice(x => x._id === data._id, data)) newActions.push(data); } else newActions = data; diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 71532733..e8f699e4 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -215,7 +215,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo if (message.system.onSave && message.system.targets.find(t => t.id === target.id)?.saved?.success === true) damage = Math.ceil(damage * (CONFIG.DH.ACTIONS.damageOnSave[message.system.onSave]?.mod ?? 1)); - target.actor.takeDamage(damage, message.system.roll.type); + target.actor.takeDamage(damage, message.system.damage.damageType); } }; diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 282a8c9c..94efec1b 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -59,13 +59,13 @@ export const damageTypes = { id: 'physical', label: 'DAGGERHEART.CONFIG.DamageType.physical.name', abbreviation: 'DAGGERHEART.CONFIG.DamageType.physical.abbreviation', - icon: ['fa-hand-fist'] + icon: 'fa-hand-fist' }, magical: { id: 'magical', label: 'DAGGERHEART.CONFIG.DamageType.magical.name', abbreviation: 'DAGGERHEART.CONFIG.DamageType.magical.abbreviation', - icon: ['fa-wand-sparkles'] + icon: 'fa-wand-sparkles' } }; diff --git a/module/data/action/actionDice.mjs b/module/data/action/actionDice.mjs index 39fc6c92..d61a1206 100644 --- a/module/data/action/actionDice.mjs +++ b/module/data/action/actionDice.mjs @@ -99,13 +99,24 @@ export class DHDamageData extends foundry.abstract.DataModel { return { // ...super.defineSchema(), base: new fields.BooleanField({ initial: false, readonly: true, label: 'Base' }), - type: new fields.StringField({ + /* type: new fields.StringField({ choices: CONFIG.DH.GENERAL.damageTypes, initial: 'physical', label: 'Type', nullable: false, required: true - }), + }), */ + type: new fields.SetField( + new fields.StringField({ + choices: CONFIG.DH.GENERAL.damageTypes, + initial: 'physical', + nullable: false, + required: true + }), + { + label: 'Type' + } + ), resultBased: new fields.BooleanField({ initial: false, label: 'DAGGERHEART.ACTIONS.Settings.resultBased.label' diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index e193aefe..90e83040 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -180,7 +180,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { const actorData = this.actor.getRollData(false); // Remove when included directly in Actor getRollData - actorData.prof = actorData.proficiency?.value ?? 1; + actorData.prof = actorData.proficiency?.total ?? 1; actorData.cast = actorData.spellcast?.value ?? 1; actorData.result = data.roll?.total ?? 1; /* actorData.scale = data.costs?.length diff --git a/module/data/action/damageAction.mjs b/module/data/action/damageAction.mjs index 2dd88af4..05c0bd3b 100644 --- a/module/data/action/damageAction.mjs +++ b/module/data/action/damageAction.mjs @@ -10,8 +10,9 @@ export default class DHDamageAction extends DHBaseAction { } async rollDamage(event, data) { - let formula = this.damage.parts.map(p => this.getFormulaValue(p, data).getFormula(this.actor)).join(' + '); - + let formula = this.damage.parts.map(p => this.getFormulaValue(p, data).getFormula(this.actor)).join(' + '), + damageTypes = [...new Set(this.damage.parts.reduce((a,c) => a.concat([...c.type]), []))]; + if (!formula || formula == '') return; let roll = { formula: formula, total: formula }, bonusDamage = []; @@ -25,6 +26,7 @@ export default class DHDamageAction extends DHBaseAction { hasSave: this.hasSave, isCritical: data.system?.roll?.isCritical ?? false, source: data.system?.source, + damageTypes, event }; if (this.hasSave) config.onSave = this.save.damageMod; @@ -32,7 +34,7 @@ export default class DHDamageAction extends DHBaseAction { config.source.message = data._id; config.directDamage = false; } - + roll = CONFIG.Dice.daggerheart.DamageRoll.build(config); } } diff --git a/module/data/actor/adversary.mjs b/module/data/actor/adversary.mjs index 717c7532..cf3669a1 100644 --- a/module/data/actor/adversary.mjs +++ b/module/data/actor/adversary.mjs @@ -64,6 +64,7 @@ export default class DhpAdversary extends BaseDataActor { damage: { parts: [ { + type: ['physical'], value: { multiplier: 'flat' } diff --git a/module/data/actor/base.mjs b/module/data/actor/base.mjs index e81acc44..d7c7213e 100644 --- a/module/data/actor/base.mjs +++ b/module/data/actor/base.mjs @@ -3,7 +3,8 @@ import DHBaseActorSettings from "../../applications/sheets/api/actor-setting.mjs const resistanceField = () => new foundry.data.fields.SchemaField({ resistance: new foundry.data.fields.BooleanField({ initial: false }), - immunity: new foundry.data.fields.BooleanField({ initial: false }) + immunity: new foundry.data.fields.BooleanField({ initial: false }), + reduction: new foundry.data.fields.NumberField({ integer: true, initial: 0 }) }); /** @@ -41,8 +42,7 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel { if(this.metadata.hasResistances) schema.resistance = new fields.SchemaField({ physical: resistanceField(), - magical: resistanceField(), - resistance: new fields.NumberField({ integer: true, initial: 0 }) + magical: resistanceField() }) return schema; } diff --git a/module/data/actor/companion.mjs b/module/data/actor/companion.mjs index 5ca50df7..21db5809 100644 --- a/module/data/actor/companion.mjs +++ b/module/data/actor/companion.mjs @@ -67,7 +67,7 @@ export default class DhCompanion extends BaseDataActor { damage: { parts: [ { - multiplier: 'flat', + type: ['physical'], value: { dice: 'd6', multiplier: 'flat' diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index e1370395..b999e1e5 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -56,6 +56,7 @@ export default class DHWeapon extends BaseDataItem { damage: { parts: [ { + type: ['physical'], value: { multiplier: 'prof', dice: 'd8' diff --git a/module/dice/damageRoll.mjs b/module/dice/damageRoll.mjs index d9c4a61e..2182d3d0 100644 --- a/module/dice/damageRoll.mjs +++ b/module/dice/damageRoll.mjs @@ -14,6 +14,10 @@ export default class DamageRoll extends DHRoll { super.postEvaluate(roll, config); config.roll.type = config.type; config.roll.modifierTotal = this.calculateTotalModifiers(roll); + } + + static async buildPost(roll, config, message) { + await super.buildPost(roll, config, message); if (config.source?.message) { const chatMessage = ui.chat.collection.get(config.source.message); chatMessage.update({ 'system.damage': config }); diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index 46e7374e..87c9401e 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -56,8 +56,8 @@ export default class DHRoll extends Roll { // Create Chat Message if (config.source?.message) { + if(game.modules.get('dice-so-nice')?.active) await game.dice3d.showForRoll(roll, game.user, true); } else { - const messageData = {}; config.message = await this.toMessage(roll, config); } } diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 2b3d99c9..40ac7bfc 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -462,7 +462,7 @@ export default class DhpActor extends Actor { const canUseArmor = this.system.armor && this.system.armor.system.marks.value < this.system.armorScore && - this.system.armorApplicableDamageTypes[type]; + type.every(t => this.system.armorApplicableDamageTypes[t] === true); const canUseStress = Object.keys(this.system.rules.damageReduction.stressDamageReduction).reduce((acc, x) => { const rule = this.system.rules.damageReduction.stressDamageReduction[x]; if (damageKeyToNumber(x) <= hpDamage) return acc || (rule.enabled && availableStress >= rule.cost); @@ -480,6 +480,8 @@ export default class DhpActor extends Actor { return; } + type = !Array.isArray(type) ? [type] : type; + const hpDamage = this.calculateDamage(baseDamage, type); if (!hpDamage) return; @@ -510,10 +512,13 @@ export default class DhpActor extends Actor { calculateDamage(baseDamage, type) { if (Hooks.call(`${CONFIG.DH.id}.preCalculateDamage`, this, baseDamage, type) === false) return null; - if(this.system.resistance[type]?.immunity) return 0; - if(this.system.resistance[type]?.resistance) baseDamage = Math.ceil(baseDamage / 2); + /* if(this.system.resistance[type]?.immunity) return 0; + if(this.system.resistance[type]?.resistance) baseDamage = Math.ceil(baseDamage / 2); */ + if(this.canResist(type, 'immunity')) return 0; + if(this.canResist(type, 'resistance')) baseDamage = Math.ceil(baseDamage / 2); - const flatReduction = this.system.resistance[type].reduction; + // const flatReduction = this.system.resistance[type].reduction; + const flatReduction = this.getDamageTypeReduction(type); const damage = Math.max(baseDamage - (flatReduction ?? 0), 0); const hpDamage = this.convertDamageToThreshold(damage); @@ -522,6 +527,17 @@ export default class DhpActor extends Actor { return hpDamage; } + canResist(type, resistance) { + if(!type) return 0; + return type.every(t => this.system.resistance[t]?.[resistance] === true); + } + + getDamageTypeReduction(type) { + if(!type) return 0; + const reduction = Object.entries(this.system.resistance).reduce((a, [index, value]) => type.includes(index) ? Math.min(value.reduction, a) : a, Infinity); + return reduction === Infinity ? 0 : reduction; + } + async takeHealing(resources) { resources.forEach(r => (r.value *= -1)); await this.modifyResource(resources); diff --git a/module/documents/chatMessage.mjs b/module/documents/chatMessage.mjs index a9a31073..ef76d18f 100644 --- a/module/documents/chatMessage.mjs +++ b/module/documents/chatMessage.mjs @@ -12,7 +12,6 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { if (this.type === 'dualityRoll') { html.classList.add('duality'); - console.log(this.system) switch (this.system.roll.result.duality) { case 1: html.classList.add('hope'); diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less index 03772bfb..c732f256 100755 --- a/styles/less/global/elements.less +++ b/styles/less/global/elements.less @@ -103,6 +103,40 @@ } } + multi-select { + position: relative; + height: 34px; + .tags { + justify-content: flex-start; + margin: 5px; + height: inherit; + .tag { + box-shadow: 0 0 0 1.1em #E5E5E5 inset; + vertical-align: top; + box-sizing: border-box; + max-width: 100%; + padding: 0.3em 0 0.3em 0.5em; + color: black; + border-radius: 3px; + white-space: nowrap; + transition: .13s ease-out; + height: 22px; + font-size: .9rem; + gap: 0.5em; + z-index: 1; + .remove { + font-size: 10px; + margin-inline: auto 4.6666666667px; + } + } + } + select { + position: absolute; + height: inherit; + outline: initial; + } + } + p { margin: 0; } diff --git a/templates/actionTypes/damage.hbs b/templates/actionTypes/damage.hbs index 59519e6d..3131754c 100644 --- a/templates/actionTypes/damage.hbs +++ b/templates/actionTypes/damage.hbs @@ -46,8 +46,12 @@ {{> formula fields=../../fields.value.fields type=../fields.type dmg=dmg source=dmg.value target="value" realIndex=realIndex}} {{/if}} - {{formField ../../fields.type value=dmg.type name=(concat "damage.parts." realIndex ".type") localize=true}} + {{formField ../../fields.type value=dmg.type name=(concat "damage.parts." realIndex ".type") localize=true}} + {{!-- --}} + {{!-- + + --}} {{#unless dmg.base}}
{{/unless}} diff --git a/templates/sheets/global/partials/inventory-item.hbs b/templates/sheets/global/partials/inventory-item.hbs index 135c3e3c..9e3aced3 100644 --- a/templates/sheets/global/partials/inventory-item.hbs +++ b/templates/sheets/global/partials/inventory-item.hbs @@ -6,7 +6,7 @@ {{else}}
{{item.name}}
{{/if}} - {{#if (eq type 'weapon')}} + {{#if (eq type 'weapon')}}
{{#if isSidebar}}
@@ -16,11 +16,11 @@ - {{item.system.attack.damage.parts.0.value.dice}}{{#if item.system.attack.damage.parts.0.value.bonus}} + {{item.system.attack.damage.parts.0.value.bonus}}{{/if}} {{!-- ({{localize (concat 'DAGGERHEART.CONFIG.DamageType.' item.system.attack.damage.parts.0.type '.abbreviation')}}) --}} - {{#with (lookup @root.config.GENERAL.damageTypes item.system.attack.damage.parts.0.type)}} - {{#each icon}} - - {{/each}} - {{/with}} + {{#each item.system.attack.damage.parts.0.type as | type | }} + {{#with (lookup @root.config.GENERAL.damageTypes type)}} + + {{/with}} + {{/each}}
{{else}} @@ -32,7 +32,11 @@
{{item.system.attack.damage.parts.0.value.dice}}{{#if item.system.attack.damage.parts.0.value.bonus}} + {{item.system.attack.damage.parts.0.value.bonus}}{{/if}} - ({{localize (concat 'DAGGERHEART.CONFIG.DamageType.' item.system.attack.damage.parts.0.type '.abbreviation')}}) + ( + {{#each item.system.attack.damage.parts.0.type}} + {{localize (concat 'DAGGERHEART.CONFIG.DamageType.' this '.abbreviation')}} + {{/each}} + )
{{localize (concat 'DAGGERHEART.CONFIG.Burden.' item.system.burden)}} diff --git a/templates/sheets/items/weapon/header.hbs b/templates/sheets/items/weapon/header.hbs index 74613699..ee0198ba 100644 --- a/templates/sheets/items/weapon/header.hbs +++ b/templates/sheets/items/weapon/header.hbs @@ -15,7 +15,11 @@ {{localize (concat 'DAGGERHEART.CONFIG.Range.' source.system.attack.range '.name')}} - {{source.system.attack.damage.parts.0.value.dice}}{{#if source.system.attack.damage.parts.0.value.bonus}} + {{source.system.attack.damage.parts.0.value.bonus}}{{/if}} - ({{localize (concat 'DAGGERHEART.CONFIG.DamageType.' source.system.attack.damage.parts.0.type '.abbreviation')}}) + ( + {{#each source.system.attack.damage.parts.0.type}} + {{localize (concat 'DAGGERHEART.CONFIG.DamageType.' this '.abbreviation')}} + {{/each}} + ) - {{localize (concat 'DAGGERHEART.CONFIG.Burden.' source.system.burden)}}