Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#3617] Add enchantment effect for modifying damage types #4913

Open
wants to merge 1 commit into
base: 4.2.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 16 additions & 21 deletions module/applications/activity/activity-sheet.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -243,15 +243,15 @@ export default class ActivitySheet extends Application5e {
value,
label: CONFIG.DND5E.activityConsumptionTypes[value].label
}));
context.consumptionTargets = context.source.consumption.targets.map((data, index) => {
context.consumptionTargets = context.activity.consumption.targets.map(data => {
const typeConfig = CONFIG.DND5E.activityConsumptionTypes[data.type] ?? {};
const showTextTarget = typeConfig.targetRequiresEmbedded && !this.item.isEmbedded;
const target = new ConsumptionTargetData(data, { parent: this.activity });
return {
data,
fields: this.activity.schema.fields.consumption.fields.targets.element.fields,
prefix: `consumption.targets.${index}.`,
source: context.source.consumption.targets[index] ?? data,
prefix: `consumption.targets.${data._index}.`,
source: context.source.consumption.targets[data._index] ?? data,
typeOptions: consumptionTypeOptions,
scalingModes: canScale ? [
{ value: "", label: game.i18n.localize("DND5E.CONSUMPTION.Scaling.None") },
Expand Down Expand Up @@ -280,11 +280,11 @@ export default class ActivitySheet extends Application5e {
{ value: "loseAll", label: game.i18n.localize("DND5E.USES.Recovery.Type.LoseAll") },
{ value: "formula", label: game.i18n.localize("DND5E.USES.Recovery.Type.Formula") }
];
context.usesRecovery = context.source.uses.recovery.map((data, index) => ({
context.usesRecovery = context.activity.uses.recovery.map(data => ({
data,
fields: this.activity.schema.fields.uses.fields.recovery.element.fields,
prefix: `uses.recovery.${index}.`,
source: context.source.uses.recovery[index] ?? data,
prefix: `uses.recovery.${data._index}.`,
source: context.source.uses.recovery[data._index] ?? data,
formulaOptions: data.period === "recharge" ? Array.fromRange(5, 2).reverse().map(min => ({
value: min,
label: game.i18n.format("DND5E.USES.Recovery.Recharge.Range", {
Expand Down Expand Up @@ -343,15 +343,15 @@ export default class ActivitySheet extends Application5e {
.map(effect => ({
value: effect.id, label: effect.name, selected: appliedEffects.has(effect.id)
}));
context.appliedEffects = context.activity.effects.reduce((arr, data, index) => {
context.appliedEffects = context.activity.effects.reduce((arr, data) => {
if ( !data.effect ) return arr;
const effect = {
data,
collapsed: this.expandedSections.get(`effects.${data._id}`) ? "" : "collapsed",
effect: data.effect,
fields: this.activity.schema.fields.effects.element.fields,
prefix: `effects.${index}.`,
source: context.source.effects[index] ?? data,
prefix: `effects.${data._index}.`,
source: context.source.effects[data._index] ?? data,
contentLink: data.effect.toAnchor().outerHTML,
additionalSettings: null
};
Expand All @@ -369,20 +369,15 @@ export default class ActivitySheet extends Application5e {
{ value: "", label: game.i18n.localize("DND5E.DAMAGE.Scaling.None") },
...Object.entries(CONFIG.DND5E.damageScalingModes).map(([value, config]) => ({ value, label: config.label }))
];
let indexOffset = 0;
context.damageParts = context.activity.damage.parts.map((data, index) => {
if ( data.base ) indexOffset--;
const typeOptions = Object.entries(CONFIG.DND5E.damageTypes).map(([value, { label }]) => ({ value, label }));
context.damageParts = context.activity.damage.parts.map(data => {
const part = {
data,
data, scalingOptions, typeOptions,
fields: this.activity.schema.fields.damage.fields.parts.element.fields,
index: index + indexOffset,
prefix: `damage.parts.${index + indexOffset}.`,
source: context.source.damage.parts[index + indexOffset] ?? data,
canScale: this.activity.canScaleDamage,
scalingOptions,
typeOptions: Object.entries(CONFIG.DND5E.damageTypes).map(([value, config]) => ({
value, label: config.label, selected: data.types.has(value)
}))
index: data._index,
prefix: `damage.parts.${data._index}.`,
source: context.source.damage.parts[data._index] ?? data,
canScale: this.activity.canScaleDamage
};
return this._prepareDamagePartContext(context, part);
});
Expand Down
11 changes: 11 additions & 0 deletions module/data/active-effect/enchantment.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ export default class EnchantmentData extends foundry.abstract.TypeDataModel {
}
return false;
} catch(err) {}
case "system.damage.types":
const adjust = (damage, keyPath) =>
ActiveEffect.applyField(damage, { ...change, key: "types", value: change.value });
if ( item.system.damage?.base ) {
changes["system.damage.base.types"] = adjust(item.system.damage.base, "system.damage.base");
}
for ( const activity of item.system.activities?.getByTypes("attack", "damage", "save") ?? [] ) {
for ( const part of activity.damage.parts ) adjust(part);
changes[`system.activities.${activity.id}.damage.parts`] = activity.damage.parts;
}
return false;
case "system.save.dc":
case "system.save.scaling":
let value = change.value;
Expand Down
5 changes: 5 additions & 0 deletions module/data/activity/base-activity.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,11 @@ export default class BaseActivityData extends foundry.abstract.DataModel {
this.name = this.name || game.i18n.localize(this.metadata?.title);
this.img = this.img || this.metadata?.img;
this.labels ??= {};
const addBaseIndices = data => data?.forEach((d, idx) => Object.defineProperty(d, "_index", { value: idx }));
addBaseIndices(this.consumption?.targets);
addBaseIndices(this.damage?.parts);
addBaseIndices(this.effects);
addBaseIndices(this.uses?.recovery);
}

/* -------------------------------------------- */
Expand Down
32 changes: 16 additions & 16 deletions templates/activity/parts/damage-part.hbs
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
<div class="field-group">
{{ formInput fields.custom.fields.enabled name=(concat prefix "custom.enabled") value=data.custom.enabled
{{ formInput fields.custom.fields.enabled name=(concat prefix "custom.enabled") value=source.custom.enabled
[email protected] classes="singleton"
dataset=(dnd5e-object tooltip="DND5E.DAMAGE.FIELDS.damage.parts.FIELDS.custom.enabled.hint")
ariaLabel=(localize "DND5E.DAMAGE.FIELDS.damage.parts.FIELDS.custom.enabled.hint")}}
{{#if data.custom.enabled}}
{{#if source.custom.enabled}}

{{ formField fields.custom.fields.formula name=(concat prefix "custom.formula") value=data.custom.formula
{{ formField fields.custom.fields.formula name=(concat prefix "custom.formula") value=source.custom.formula
label="DND5E.Formula" hint=false localize=true classes="label-top" }}
<input type="hidden" name="{{ prefix }}number" value="{{ data.number }}" data-dtype="Number">
<input type="hidden" name="{{ prefix }}denomination" value="{{ data.denomination }}" data-dtype="Number">
<input type="hidden" name="{{ prefix }}bonus" value="{{ data.bonus }}">
<input type="hidden" name="{{ prefix }}number" value="{{ source.number }}" data-dtype="Number">
<input type="hidden" name="{{ prefix }}denomination" value="{{ source.denomination }}" data-dtype="Number">
<input type="hidden" name="{{ prefix }}bonus" value="{{ source.bonus }}">

{{else}}

{{ formField fields.number name=(concat prefix "number") value=data.number label="DND5E.Number" hint=false
{{ formField fields.number name=(concat prefix "number") value=source.number label="DND5E.Number" hint=false
localize=true classes="label-top" }}

{{ formField fields.denomination name=(concat prefix "denomination") value=data.denomination
{{ formField fields.denomination name=(concat prefix "denomination") value=source.denomination
[email protected] label="DND5E.Die" hint=false localize=true classes="label-top" }}

{{ formField fields.bonus name=(concat prefix "bonus") value=data.bonus label="DND5E.Bonus" hint=false localize=true
{{ formField fields.bonus name=(concat prefix "bonus") value=source.bonus label="DND5E.Bonus" hint=false localize=true
classes="label-top" }}

<input type="hidden" name="{{ prefix }}custom.formula" value="{{ data.custom.formula }}">
<input type="hidden" name="{{ prefix }}custom.formula" value="{{ source.custom.formula }}">

{{/if}}
{{#unless data.locked}}
Expand All @@ -34,23 +34,23 @@
{{/unless}}
</div>

<div class="field-group">
{{ formField fields.types name=(concat prefix "types") value=data.types options=typeOptions hint=false
<div class="field-group">{{ log source.types }}
{{ formField fields.types name=(concat prefix "types") value=source.types options=typeOptions hint=false
disabled=data.locked label="DND5E.Type" localize=true classes="label-top multi-select" }}
<!-- TODO: This disabled is only necessary because of https://github.com/foundryvtt/foundryvtt/issues/11564 -->
</div>

{{#if canScale}}
{{#with fields.scaling.fields as |fields|}}
<div class="field-group">
{{ formField fields.mode name=(concat ../prefix "scaling.mode") value=../data.scaling.mode
{{ formField fields.mode name=(concat ../prefix "scaling.mode") value=../source.scaling.mode
options=../scalingOptions label="DND5E.DAMAGE.FIELDS.damage.parts.FIELDS.scaling.abbr" hint=false
localize=true classes="label-top" }}
{{#if ../data.scaling.mode}}
{{ formField fields.number name=(concat ../prefix "scaling.number") value=../data.scaling.number
{{#if ../source.scaling.mode}}
{{ formField fields.number name=(concat ../prefix "scaling.number") value=../source.scaling.number
label="DND5E.DAMAGE.FIELDS.damage.parts.FIELDS.scaling.number.abbr" hint=false localize=true
classes="label-top" }}
{{ formField fields.formula name=(concat ../prefix "scaling.formula") value=../data.scaling.formula
{{ formField fields.formula name=(concat ../prefix "scaling.formula") value=../source.scaling.formula
label="DND5E.Formula" hint=false localize=true classes="label-top" }}
{{/if}}
</div>
Expand Down