Skip to content

Commit

Permalink
Merge pull request foundryvtt#3934 from foundryvtt/activity/damage
Browse files Browse the repository at this point in the history
[foundryvtt#3912] Add `DamageActivity` & `HealingActivity` data & sheets
  • Loading branch information
arbron authored Aug 5, 2024
2 parents 4ffdc45 + f96141c commit 9c01943
Show file tree
Hide file tree
Showing 27 changed files with 377 additions and 96 deletions.
2 changes: 2 additions & 0 deletions icons/LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ The dnd5e system for Foundry Virtual Tabletop includes icon artwork licensed fro
/svg/vehicle.svg - "Ship's wheel" by Delapouite under CC BY 3.0
/svg/versatile.svg - "Swiss army knife" by Delapouite under CC BY 3.0
/svg/activity/attack.svg - "Sword clash" by Lorc under CC BY 3.0
/svg/activity/damage.svg - "Earth spit" by Lorc under CC BY 3.0
/svg/activity/healing.svg - "Health increase" by sbed under CC BY 3.0
/svg/activity/save.svg - "Shield reflect" by Lorc under CC BY 3.0
/svg/activity/summon.svg - "Pentagram rose" by Lorc under CC BY 3.0
/svg/activity/utility.svg - "Spanner" by Lorc under CC BY 3.0
Expand Down
6 changes: 6 additions & 0 deletions icons/svg/activity/damage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions icons/svg/activity/healing.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
150 changes: 111 additions & 39 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -936,48 +936,63 @@
"Half": "Half"
}
},

"DND5E.DAMAGE": {
"Title": "Damage",
"FIELDS": {
"number": {
"label": "Die Number",
"hint": "Number of dice to roll."
},
"denomination": {
"label": "Die Denomination",
"hint": "Denomination of the dice to roll."
},
"bonus": {
"label": "Damage Bonus",
"hint": "Bonus added to the damage roll."
},
"types": {
"label": "Damage Types",
"hint": "Type of damage inflicted or multiple for the user to select from."
},
"custom": {
"label": "Custom Damage Formula",
"enabled": {
"label": "Enable Custom Formula",
"hint": "Should the custom formula be used rather than the default dice."
},
"formula": {
"label": "Damage Formula",
"hint": "Custom damage formula."
}
},
"scaling": {
"label": "Damage Scaling",
"mode": {
"label": "Scaling Mode",
"hint": "Method by which the scaling increase is calculated."
},
"number": {
"label": "Dice Scaling",
"hint": "Number of dice to increase for each scaling step. Will be applied to the first die found in the damage formula if more than one is present."
"damage": {
"label": "Damage",
"allowCritical": {
"label": "Allow Critical",
"hint": "Should the use be able to roll critical damage?"
},
"formula": {
"label": "Scaling Formula",
"hint": "Arbitrary scaling formula that will be multiplied for each scaling step and added to the original formula."
"parts": {
"label": "Damage Parts",
"hint": "Individual damage parts to include with the roll.",
"FIELDS": {
"bonus": {
"label": "Damage Bonus",
"hint": "Bonus added to the damage roll."
},
"custom": {
"label": "Custom Damage Formula",
"enabled": {
"label": "Enable Custom Formula",
"hint": "Should the custom formula be used rather than the default dice."
},
"formula": {
"label": "Damage Formula",
"hint": "Custom damage formula."
}
},
"denomination": {
"label": "Die Denomination",
"hint": "Denomination of the dice to roll."
},
"number": {
"label": "Die Number",
"hint": "Number of dice to roll."
},
"scaling": {
"label": "Damage Scaling",
"mode": {
"label": "Scaling Mode",
"hint": "Method by which the scaling increase is calculated."
},
"number": {
"label": "Dice Scaling",
"hint": "Number of dice to increase for each scaling step. Will be applied to the first die found in the damage formula if more than one is present."
},
"formula": {
"label": "Scaling Formula",
"hint": "Arbitrary scaling formula that will be multiplied for each scaling step and added to the original formula."
}
},
"types": {
"label": "Damage Types",
"hint": "Type of damage inflicted or multiple for the user to select from."
}
}
}
}
},
Expand All @@ -993,6 +1008,7 @@
"Whole": "Every Level"
}
},

"DND5E.DamImm": "Damage Immunities",
"DND5E.DamMod": "Damage Modification",
"DND5E.DamRes": "Damage Resistances",
Expand Down Expand Up @@ -1401,6 +1417,58 @@
},
"DND5E.Hair": "Hair",
"DND5E.HalfProficient": "Half Proficient",

"DND5E.HEALING": {
"Title": "Healing",
"FIELDS": {
"healing": {
"label": "Healing",
"bonus": {
"label": "Healing Bonus",
"hint": "Bonus added to the healing roll."
},
"custom": {
"label": "Custom Healing Formula",
"enabled": {
"label": "Enable Custom Formula",
"hint": "Should the custom formula be used rather than the default dice."
},
"formula": {
"label": "Healing Formula",
"hint": "Custom healing formula."
}
},
"denomination": {
"label": "Die Denomination",
"hint": "Denomination of the dice to roll."
},
"number": {
"label": "Die Number",
"hint": "Number of dice to roll."
},
"scaling": {
"label": "Healing Scaling",
"mode": {
"label": "Scaling Mode",
"hint": "Method by which the scaling increase is calculated."
},
"number": {
"label": "Dice Scaling",
"hint": "Number of dice to increase for each scaling step. Will be applied to the first die found in the healing formula if more than one is present."
},
"formula": {
"label": "Scaling Formula",
"hint": "Arbitrary scaling formula that will be multiplied for each scaling step and added to the original formula."
}
},
"types": {
"label": "Healing Types",
"hint": "Type of healing inflicted or multiple for the user to select from."
}
}
}
},

"DND5E.Healing": "Healing",
"DND5E.HealingRoll": "Healing Roll",
"DND5E.HealingTemp": "Healing (Temporary)",
Expand Down Expand Up @@ -1813,6 +1881,10 @@
"Full": "Full Damage",
"Half": "Half Damage",
"None": "No Damage"
},
"parts": {
"label": "Damage Parts",
"hint": "Individual damage parts to include with the roll."
}
},
"save": {
Expand Down
2 changes: 2 additions & 0 deletions module/applications/activity/_module.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export {default as ActivitySheet} from "./activity-sheet.mjs";
export {default as AttackSheet} from "./attack-sheet.mjs";
export {default as DamageSheet} from "./damage-sheet.mjs";
export {default as EnchantSheet} from "./enchant-sheet.mjs";
export {default as HealingSheet} from "./healing-sheet.mjs";
export {default as SummonSheet} from "./summon-sheet.mjs";
export {default as UtilitySheet} from "./utility-sheet.mjs";

Expand Down
2 changes: 2 additions & 0 deletions module/applications/activity/activity-sheet.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ export default class ActivitySheet extends Application5e {
* @param {HTMLElement} target Button that was clicked.
*/
static async #addEffect(event, target) {
if ( !this.activity.effects ) return;
const effectData = this._addEffectData();
const [created] = await this.item.createEmbeddedDocuments("ActiveEffect", [effectData]);
this.activity.update({ effects: [...this.activity.toObject().effects, { _id: created.id }] });
Expand Down Expand Up @@ -629,6 +630,7 @@ export default class ActivitySheet extends Application5e {
* @param {HTMLElement} target Button that was clicked.
*/
static async #deleteEffect(event, target) {
if ( !this.activity.effects ) return;
const effectId = target.closest("[data-effect-id]")?.dataset.effectId;
const result = await this.item.effects.get(effectId)?.deleteDialog();
if ( result instanceof ActiveEffect ) {
Expand Down
1 change: 1 addition & 0 deletions module/applications/activity/attack-sheet.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default class AttackSheet extends ActivitySheet {
...super.PARTS.effect.templates,
"systems/dnd5e/templates/activity/parts/attack-damage.hbs",
"systems/dnd5e/templates/activity/parts/attack-details.hbs",
"systems/dnd5e/templates/activity/parts/damage-part.hbs",
"systems/dnd5e/templates/activity/parts/damage-parts.hbs"
]
}
Expand Down
28 changes: 28 additions & 0 deletions module/applications/activity/damage-sheet.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import ActivitySheet from "./activity-sheet.mjs";

/**
* Sheet for the damage activity.
*/
export default class DamageSheet extends ActivitySheet {

/** @inheritDoc */
static DEFAULT_OPTIONS = {
classes: ["damage-activity"]
};

/* -------------------------------------------- */

/** @inheritDoc */
static PARTS = {
...super.PARTS,
effect: {
template: "systems/dnd5e/templates/activity/damage-effect.hbs",
templates: [
...super.PARTS.effect.templates,
"systems/dnd5e/templates/activity/parts/damage-damage.hbs",
"systems/dnd5e/templates/activity/parts/damage-part.hbs",
"systems/dnd5e/templates/activity/parts/damage-parts.hbs"
]
}
};
}
40 changes: 40 additions & 0 deletions module/applications/activity/healing-sheet.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import ActivitySheet from "./activity-sheet.mjs";

/**
* Sheet for the healing activity.
*/
export default class HealingSheet extends ActivitySheet {

/** @inheritDoc */
static DEFAULT_OPTIONS = {
classes: ["healing-activity"]
};

/* -------------------------------------------- */

/** @inheritDoc */
static PARTS = {
...super.PARTS,
effect: {
template: "systems/dnd5e/templates/activity/healing-effect.hbs",
templates: [
...super.PARTS.effect.templates,
"systems/dnd5e/templates/activity/parts/damage-part.hbs",
"systems/dnd5e/templates/activity/parts/healing-damage.hbs"
]
}
};

/* -------------------------------------------- */
/* Rendering */
/* -------------------------------------------- */

/** @inheritDoc */
async _prepareEffectContext(context) {
context = await super._prepareEffectContext(context);
context.typeOptions = Object.entries(CONFIG.DND5E.healingTypes).map(([value, config]) => ({
value, label: config.label, selected: context.activity.healing.types.has(value)
}));
return context;
}
}
1 change: 1 addition & 0 deletions module/applications/activity/save-sheet.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default class AttackSheet extends ActivitySheet {
template: "systems/dnd5e/templates/activity/save-effect.hbs",
templates: [
...super.PARTS.effect.templates,
"systems/dnd5e/templates/activity/parts/damage-part.hbs",
"systems/dnd5e/templates/activity/parts/damage-parts.hbs",
"systems/dnd5e/templates/activity/parts/save-damage.hbs",
"systems/dnd5e/templates/activity/parts/save-details.hbs",
Expand Down
6 changes: 6 additions & 0 deletions module/config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3236,9 +3236,15 @@ DND5E.activityTypes = {
attack: {
documentClass: activities.AttackActivity
},
damage: {
documentClass: activities.DamageActivity
},
enchant: {
documentClass: activities.EnchantActivity
},
healing: {
documentClass: activities.HealingActivity
},
save: {
documentClass: activities.SaveActivity
},
Expand Down
2 changes: 2 additions & 0 deletions module/data/activity/_module.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export {default as BaseActivityData} from "./base-activity.mjs";

export {default as AttackActivityData} from "./attack-data.mjs";
export {default as DamageActivityData} from "./damage-data.mjs";
export {default as EnchantActivityData} from "./enchant-data.mjs";
export {default as HealingActivityData} from "./healing-data.mjs";
export {default as SaveActivityData} from "./save-data.mjs";
export {default as SummonActivityData} from "./summon-data.mjs";
export {default as UtilityActivityData} from "./utility-data.mjs";
Expand Down
24 changes: 24 additions & 0 deletions module/data/activity/damage-data.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import DamageField from "../shared/damage-field.mjs";
import BaseActivityData from "./base-activity.mjs";

const { ArrayField, BooleanField, SchemaField } = foundry.data.fields;

/**
* Data model for an damage activity.
*
* @property {object} damage
* @property {boolean} damage.allowCritical Can this damage be critical?
* @property {DamageData[]} damage.parts Parts of damage to inflict.
*/
export default class DamageActivityData extends BaseActivityData {
/** @inheritDoc */
static defineSchema() {
return {
...super.defineSchema(),
damage: new SchemaField({
allowCritical: new BooleanField(),
parts: new ArrayField(new DamageField())
})
};
}
}
17 changes: 17 additions & 0 deletions module/data/activity/healing-data.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import DamageField from "../shared/damage-field.mjs";
import BaseActivityData from "./base-activity.mjs";

/**
* Data model for an healing activity.
*
* @property {DamageData} healing
*/
export default class HealingActivityData extends BaseActivityData {
/** @inheritDoc */
static defineSchema() {
return {
...super.defineSchema(),
healing: new DamageField()
};
}
}
5 changes: 0 additions & 5 deletions module/data/shared/damage-field.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ export class DamageData extends foundry.abstract.DataModel {
/* Model Configuration */
/* -------------------------------------------- */

/** @override */
static LOCALIZATION_PREFIXES = ["DND5E.DAMAGE"];

/* -------------------------------------------- */

/** @override */
static defineSchema() {
return {
Expand Down
Loading

0 comments on commit 9c01943

Please sign in to comment.