feat: update for v10
This commit is contained in:
parent
6277e27056
commit
f25b46a226
63 changed files with 41349 additions and 24332 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -34,5 +34,5 @@ junit.xml
|
|||
.pnp.*
|
||||
|
||||
# foundry
|
||||
client
|
||||
common
|
||||
/client
|
||||
/common
|
||||
|
|
42127
packs/creatures.json
42127
packs/creatures.json
File diff suppressed because it is too large
Load diff
14224
packs/items.json
14224
packs/items.json
File diff suppressed because it is too large
Load diff
|
@ -4,175 +4,263 @@
|
|||
"name": "Gormanische Schrift",
|
||||
"type": "alphabet",
|
||||
"img": "icons/svg/book.svg",
|
||||
"data": {
|
||||
"description": ""
|
||||
},
|
||||
"effects": [],
|
||||
"folder": null,
|
||||
"sort": 0,
|
||||
"permission": {
|
||||
"flags": {},
|
||||
"system": {
|
||||
"description": ""
|
||||
},
|
||||
"ownership": {
|
||||
"default": 0
|
||||
},
|
||||
"flags": {}
|
||||
"_stats": {
|
||||
"systemId": "ds4",
|
||||
"systemVersion": "1.18.1",
|
||||
"coreVersion": "10.290",
|
||||
"createdTime": 1668995342357,
|
||||
"modifiedTime": 1668995456385,
|
||||
"lastModifiedBy": "DS4BuildSystem00"
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "GQNpFENXcjJGeYr2",
|
||||
"name": "Freiwort",
|
||||
"type": "language",
|
||||
"img": "systems/ds4/assets/icons/game-icons/lorc/conversation.svg",
|
||||
"data": {
|
||||
"description": "<p>Freiwort ist die Gemeinsprache der Freien Lande.</p>"
|
||||
},
|
||||
"effects": [],
|
||||
"folder": null,
|
||||
"sort": 0,
|
||||
"permission": {
|
||||
"flags": {},
|
||||
"system": {
|
||||
"description": "<p>Freiwort ist die Gemeinsprache der Freien Lande.</p>"
|
||||
},
|
||||
"ownership": {
|
||||
"default": 0
|
||||
},
|
||||
"flags": {}
|
||||
"_stats": {
|
||||
"systemId": "ds4",
|
||||
"systemVersion": "1.18.1",
|
||||
"coreVersion": "10.290",
|
||||
"createdTime": 1668995342358,
|
||||
"modifiedTime": 1668995456386,
|
||||
"lastModifiedBy": "DS4BuildSystem00"
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "O1U9jd0yJoydHwT8",
|
||||
"name": "Zasarische Schrift",
|
||||
"type": "alphabet",
|
||||
"img": "icons/svg/book.svg",
|
||||
"data": {
|
||||
"description": ""
|
||||
},
|
||||
"effects": [],
|
||||
"folder": null,
|
||||
"sort": 0,
|
||||
"permission": {
|
||||
"flags": {},
|
||||
"system": {
|
||||
"description": ""
|
||||
},
|
||||
"ownership": {
|
||||
"default": 0
|
||||
},
|
||||
"flags": {}
|
||||
"_stats": {
|
||||
"systemId": "ds4",
|
||||
"systemVersion": "1.18.1",
|
||||
"coreVersion": "10.290",
|
||||
"createdTime": 1668995342359,
|
||||
"modifiedTime": 1668995456388,
|
||||
"lastModifiedBy": "DS4BuildSystem00"
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "PzkVTViII6ungWyp",
|
||||
"name": "Zwergisch",
|
||||
"type": "language",
|
||||
"img": "systems/ds4/assets/icons/game-icons/lorc/conversation.svg",
|
||||
"data": {
|
||||
"description": ""
|
||||
},
|
||||
"effects": [],
|
||||
"folder": null,
|
||||
"sort": 0,
|
||||
"permission": {
|
||||
"flags": {},
|
||||
"system": {
|
||||
"description": ""
|
||||
},
|
||||
"ownership": {
|
||||
"default": 0
|
||||
},
|
||||
"flags": {}
|
||||
"_stats": {
|
||||
"systemId": "ds4",
|
||||
"systemVersion": "1.18.1",
|
||||
"coreVersion": "10.290",
|
||||
"createdTime": 1668995342360,
|
||||
"modifiedTime": 1668995456389,
|
||||
"lastModifiedBy": "DS4BuildSystem00"
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "josgKzD9UmDOvTup",
|
||||
"name": "Ornamentschrift",
|
||||
"type": "alphabet",
|
||||
"img": "icons/svg/book.svg",
|
||||
"data": {
|
||||
"description": ""
|
||||
},
|
||||
"effects": [],
|
||||
"folder": null,
|
||||
"sort": 0,
|
||||
"permission": {
|
||||
"flags": {},
|
||||
"system": {
|
||||
"description": ""
|
||||
},
|
||||
"ownership": {
|
||||
"default": 0
|
||||
},
|
||||
"flags": {}
|
||||
"_stats": {
|
||||
"systemId": "ds4",
|
||||
"systemVersion": "1.18.1",
|
||||
"coreVersion": "10.290",
|
||||
"createdTime": 1668995342361,
|
||||
"modifiedTime": 1668995456390,
|
||||
"lastModifiedBy": "DS4BuildSystem00"
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "k8FSxBda9CoLOJqZ",
|
||||
"name": "Kaitanische Schrift",
|
||||
"type": "alphabet",
|
||||
"img": "icons/svg/book.svg",
|
||||
"data": {
|
||||
"description": ""
|
||||
},
|
||||
"effects": [],
|
||||
"folder": null,
|
||||
"sort": 0,
|
||||
"permission": {
|
||||
"flags": {},
|
||||
"system": {
|
||||
"description": ""
|
||||
},
|
||||
"ownership": {
|
||||
"default": 0
|
||||
},
|
||||
"flags": {}
|
||||
"_stats": {
|
||||
"systemId": "ds4",
|
||||
"systemVersion": "1.18.1",
|
||||
"coreVersion": "10.290",
|
||||
"createdTime": 1668995342362,
|
||||
"modifiedTime": 1668995456391,
|
||||
"lastModifiedBy": "DS4BuildSystem00"
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "n2Nbg0ttFzcMxp7T",
|
||||
"name": "Keilschrift",
|
||||
"type": "alphabet",
|
||||
"img": "icons/svg/book.svg",
|
||||
"data": {
|
||||
"description": ""
|
||||
},
|
||||
"effects": [],
|
||||
"folder": null,
|
||||
"sort": 0,
|
||||
"permission": {
|
||||
"flags": {},
|
||||
"system": {
|
||||
"description": ""
|
||||
},
|
||||
"ownership": {
|
||||
"default": 0
|
||||
},
|
||||
"flags": {}
|
||||
"_stats": {
|
||||
"systemId": "ds4",
|
||||
"systemVersion": "1.18.1",
|
||||
"coreVersion": "10.290",
|
||||
"createdTime": 1668995342364,
|
||||
"modifiedTime": 1668995456392,
|
||||
"lastModifiedBy": "DS4BuildSystem00"
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "n6KU1XIzbPWups0D",
|
||||
"name": "Kaitanisch",
|
||||
"type": "language",
|
||||
"img": "systems/ds4/assets/icons/game-icons/lorc/conversation.svg",
|
||||
"data": {
|
||||
"description": ""
|
||||
},
|
||||
"effects": [],
|
||||
"folder": null,
|
||||
"sort": 0,
|
||||
"permission": {
|
||||
"flags": {},
|
||||
"system": {
|
||||
"description": ""
|
||||
},
|
||||
"ownership": {
|
||||
"default": 0
|
||||
},
|
||||
"flags": {}
|
||||
"_stats": {
|
||||
"systemId": "ds4",
|
||||
"systemVersion": "1.18.1",
|
||||
"coreVersion": "10.290",
|
||||
"createdTime": 1668995342365,
|
||||
"modifiedTime": 1668995456393,
|
||||
"lastModifiedBy": "DS4BuildSystem00"
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "usEWD48iYnMHO3Ty",
|
||||
"name": "Zasarisch",
|
||||
"type": "language",
|
||||
"img": "systems/ds4/assets/icons/game-icons/lorc/conversation.svg",
|
||||
"data": {
|
||||
"description": ""
|
||||
},
|
||||
"effects": [],
|
||||
"folder": null,
|
||||
"sort": 0,
|
||||
"permission": {
|
||||
"flags": {},
|
||||
"system": {
|
||||
"description": ""
|
||||
},
|
||||
"ownership": {
|
||||
"default": 0
|
||||
},
|
||||
"flags": {}
|
||||
"_stats": {
|
||||
"systemId": "ds4",
|
||||
"systemVersion": "1.18.1",
|
||||
"coreVersion": "10.290",
|
||||
"createdTime": 1668995342366,
|
||||
"modifiedTime": 1668995456394,
|
||||
"lastModifiedBy": "DS4BuildSystem00"
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "xpvHuSywc8lJa2UN",
|
||||
"name": "Elfisch",
|
||||
"type": "language",
|
||||
"img": "systems/ds4/assets/icons/game-icons/lorc/conversation.svg",
|
||||
"data": {
|
||||
"description": ""
|
||||
},
|
||||
"effects": [],
|
||||
"folder": null,
|
||||
"sort": 0,
|
||||
"permission": {
|
||||
"flags": {},
|
||||
"system": {
|
||||
"description": ""
|
||||
},
|
||||
"ownership": {
|
||||
"default": 0
|
||||
},
|
||||
"flags": {}
|
||||
"_stats": {
|
||||
"systemId": "ds4",
|
||||
"systemVersion": "1.18.1",
|
||||
"coreVersion": "10.290",
|
||||
"createdTime": 1668995342367,
|
||||
"modifiedTime": 1668995456395,
|
||||
"lastModifiedBy": "DS4BuildSystem00"
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "ylqXcZHRbIBeV20Z",
|
||||
"name": "Ahnenrunen",
|
||||
"type": "alphabet",
|
||||
"img": "icons/svg/book.svg",
|
||||
"data": {
|
||||
"description": ""
|
||||
},
|
||||
"effects": [],
|
||||
"folder": null,
|
||||
"sort": 0,
|
||||
"permission": {
|
||||
"flags": {},
|
||||
"system": {
|
||||
"description": ""
|
||||
},
|
||||
"ownership": {
|
||||
"default": 0
|
||||
},
|
||||
"flags": {}
|
||||
"_stats": {
|
||||
"systemId": "ds4",
|
||||
"systemVersion": "1.18.1",
|
||||
"coreVersion": "10.290",
|
||||
"createdTime": 1668995342375,
|
||||
"modifiedTime": 1668995456396,
|
||||
"lastModifiedBy": "DS4BuildSystem00"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
2640
packs/spells.json
2640
packs/spells.json
File diff suppressed because one or more lines are too long
3498
packs/talents.json
3498
packs/talents.json
File diff suppressed because it is too large
Load diff
|
@ -37,14 +37,14 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
get template() {
|
||||
const basePath = "systems/ds4/templates/sheets/actor";
|
||||
if (!getGame().user?.isGM && this.actor.limited) return `${basePath}/limited-sheet.hbs`;
|
||||
return `${basePath}/${this.actor.data.type}-sheet.hbs`;
|
||||
return `${basePath}/${this.actor.type}-sheet.hbs`;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async getData(options) {
|
||||
async getData(options = {}) {
|
||||
const itemsByType = Object.fromEntries(
|
||||
Object.entries(this.actor.itemTypes).map(([itemType, items]) => {
|
||||
return [itemType, items.map((item) => item.data).sort((a, b) => (a.sort || 0) - (b.sort || 0))];
|
||||
return [itemType, [...items].sort((a, b) => (a.sort || 0) - (b.sort || 0))];
|
||||
}),
|
||||
);
|
||||
|
||||
|
@ -53,35 +53,39 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
...effect.toObject(),
|
||||
sourceName: await effect.getCurrentSourceName(),
|
||||
factor: effect.factor,
|
||||
isEffectivelyEnabled: !effect.data.disabled && !effect.isSurpressed,
|
||||
isEffectivelyEnabled: !effect.disabled && !effect.isSurpressed,
|
||||
};
|
||||
});
|
||||
const enrichedEffects = await Promise.all(enrichedEffectPromises);
|
||||
|
||||
const data = {
|
||||
const context = {
|
||||
...this.addTooltipsToData(await super.getData(options)),
|
||||
config: DS4,
|
||||
itemsByType,
|
||||
enrichedEffects,
|
||||
settings: getDS4Settings(),
|
||||
};
|
||||
return data;
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds tooltips to the attributes, traits, and combatValues of the actor data of the given {@link ActorSheet.Data}.
|
||||
* @param {object} data
|
||||
* Adds tooltips to the attributes, traits, and combatValues of the given context object.
|
||||
* @param {object} context
|
||||
* @protected
|
||||
*/
|
||||
addTooltipsToData(data) {
|
||||
const valueGroups = [data.data.data.attributes, data.data.data.traits, data.data.data.combatValues];
|
||||
addTooltipsToData(context) {
|
||||
const valueGroups = [
|
||||
context.data.system.attributes,
|
||||
context.data.system.traits,
|
||||
context.data.system.combatValues,
|
||||
];
|
||||
|
||||
valueGroups.forEach((valueGroup) => {
|
||||
Object.values(valueGroup).forEach((attribute) => {
|
||||
attribute.tooltip = this.getTooltipForValue(attribute);
|
||||
});
|
||||
});
|
||||
return data;
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -154,13 +158,9 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
* @protected
|
||||
*/
|
||||
onCreateItem(event) {
|
||||
const { type, ...data } = foundry.utils.deepClone(event.currentTarget.dataset);
|
||||
const { type } = foundry.utils.deepClone(event.currentTarget.dataset);
|
||||
const name = getGame().i18n.localize(`DS4.New${type.capitalize()}Name`);
|
||||
const itemData = {
|
||||
name: name,
|
||||
type: type,
|
||||
data: data,
|
||||
};
|
||||
const itemData = { name, type };
|
||||
Item.create(itemData, { parent: this.actor, pack: this.actor.pack ?? undefined });
|
||||
}
|
||||
|
||||
|
@ -394,24 +394,25 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
const dataPath = target.dataset["dataPath"];
|
||||
enforce(dataPath !== undefined, `Could not find property 'dataPath' in the dataset of ${target}`);
|
||||
const dataPath2 = target.dataset["dataPath2"];
|
||||
/** @type {import("../../documents/item/item").DS4Item[]}*/
|
||||
const items = this.actor.items.filter((item) => item.type === type);
|
||||
items.sort((a, b) => a.data.sort - b.data.sort);
|
||||
items.sort((a, b) => a.sort - b.sort);
|
||||
|
||||
/**
|
||||
* @param {boolean} invert Whether or not to inverse the sort order
|
||||
* @returns {(a: import("../../documents/item/item").DS4Item, b: import("../../documents/item/item").DS4Item) => number} A function for sorting items
|
||||
*/
|
||||
const sortFunction = (invert) => (a, b) => {
|
||||
const propertyA = getProperty(a.data, dataPath);
|
||||
const propertyB = getProperty(b.data, dataPath);
|
||||
const propertyA = getProperty(a, dataPath);
|
||||
const propertyB = getProperty(b, dataPath);
|
||||
const comparison =
|
||||
typeof propertyA === "string" || typeof propertyB === "string"
|
||||
? compareAsStrings(propertyA, propertyB, invert)
|
||||
: compareAsNumbers(propertyA, propertyB, invert);
|
||||
|
||||
if (comparison === 0 && dataPath2 !== undefined) {
|
||||
const propertyA = getProperty(a.data, dataPath);
|
||||
const propertyB = getProperty(b.data, dataPath);
|
||||
const propertyA = getProperty(a, dataPath);
|
||||
const propertyB = getProperty(b, dataPath);
|
||||
return typeof propertyA === "string" || typeof propertyB === "string"
|
||||
? compareAsStrings(propertyA, propertyB, invert)
|
||||
: compareAsNumbers(propertyA, propertyB, invert);
|
||||
|
@ -441,14 +442,14 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
* @override
|
||||
*/
|
||||
async _onDropItem(event, data) {
|
||||
const item = await Item.fromDropData(data);
|
||||
if (item && !this.actor.canOwnItemType(item.data.type)) {
|
||||
const item = await Item.implementation.fromDropData(data);
|
||||
if (item && !this.actor.canOwnItemType(item.type)) {
|
||||
notifications.warn(
|
||||
getGame().i18n.format("DS4.WarningActorCannotOwnItem", {
|
||||
actorName: this.actor.name,
|
||||
actorType: this.actor.data.type,
|
||||
actorType: this.actor.type,
|
||||
itemName: item.name,
|
||||
itemType: item.data.type,
|
||||
itemType: item.type,
|
||||
}),
|
||||
);
|
||||
return false;
|
||||
|
|
|
@ -13,4 +13,13 @@ export class DS4CharacterActorSheet extends DS4ActorSheet {
|
|||
classes: ["sheet", "ds4-actor-sheet", "ds4-character-sheet"],
|
||||
});
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async getData(options = {}) {
|
||||
const context = await super.getData(options);
|
||||
context.data.system.profile.biography = await TextEditor.enrichHTML(context.data.system.profile.biography, {
|
||||
async: true,
|
||||
});
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,4 +13,14 @@ export class DS4CreatureActorSheet extends DS4ActorSheet {
|
|||
classes: ["sheet", "ds4-actor-sheet", "ds4-creature-sheet"],
|
||||
});
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async getData(options = {}) {
|
||||
const context = await super.getData(options);
|
||||
context.data.system.baseInfo.description = await TextEditor.enrichHTML(
|
||||
context.data.system.baseInfo.description,
|
||||
{ async: true },
|
||||
);
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
import { DS4 } from "../config";
|
||||
import { DS4ActiveEffect } from "../documents/active-effect";
|
||||
import { isDS4ItemDataTypePhysical } from "../documents/item/item-data-source-base";
|
||||
import { notifications } from "../ui/notifications";
|
||||
import { enforce, getGame } from "../utils/utils";
|
||||
import { disableOverriddenFields } from "./sheet-helpers";
|
||||
|
@ -29,19 +28,22 @@ export class DS4ItemSheet extends ItemSheet {
|
|||
/** @override */
|
||||
get template() {
|
||||
const basePath = "systems/ds4/templates/sheets/item";
|
||||
return `${basePath}/${this.item.data.type}-sheet.hbs`;
|
||||
return `${basePath}/${this.item.type}-sheet.hbs`;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async getData() {
|
||||
const data = {
|
||||
...(await super.getData()),
|
||||
async getData(options = {}) {
|
||||
const superContext = await super.getData(options);
|
||||
superContext.data.system.description = await TextEditor.enrichHTML(superContext.data.system.description, {
|
||||
async: true,
|
||||
});
|
||||
const context = {
|
||||
...superContext,
|
||||
config: DS4,
|
||||
isOwned: this.item.isOwned,
|
||||
actor: this.item.actor,
|
||||
isPhysical: isDS4ItemDataTypePhysical(this.item.data.data),
|
||||
};
|
||||
return data;
|
||||
return context;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
|
|
|
@ -56,7 +56,7 @@ export class DS4ActiveEffect extends ActiveEffect {
|
|||
return;
|
||||
}
|
||||
const itemIdRegex = /Item\.([a-zA-Z0-9]+)/;
|
||||
const itemId = this.data.origin?.match(itemIdRegex)?.[1];
|
||||
const itemId = this.origin?.match(itemIdRegex)?.[1];
|
||||
if (!itemId) {
|
||||
return;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ export class DS4ActiveEffect extends ActiveEffect {
|
|||
|
||||
/** @override */
|
||||
apply(document, change) {
|
||||
change.value = Roll.replaceFormulaData(change.value, document.data);
|
||||
change.value = Roll.replaceFormulaData(change.value, document);
|
||||
try {
|
||||
change.value = DS4ActiveEffect.safeEval(change.value).toString();
|
||||
} catch (e) {
|
||||
|
@ -101,16 +101,17 @@ export class DS4ActiveEffect extends ActiveEffect {
|
|||
*/
|
||||
async getSource() {
|
||||
if (this.source === undefined) {
|
||||
this.source = this.data.origin !== undefined ? await fromUuid(this.data.origin) : null;
|
||||
this.source = this.origin != null ? await fromUuid(this.origin) : null;
|
||||
}
|
||||
return this.source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link DS4ActiveEffect} using default data.
|
||||
* Create a new {@link DS4ActiveEffect} using default values.
|
||||
*
|
||||
* @param {import("./item/item").DS4Item | import("./actor/actor").DS4Actor} parent The parent of the effect.
|
||||
* @returns {Promise<DS4ActiveEffect | undefined>}A promise that resolved to the created effect or udifined of the creation was prevented.
|
||||
* @returns {Promise<DS4ActiveEffect | undefined>} A promise that resolved to the created effect or udifined of the
|
||||
* creation was prevented.
|
||||
*/
|
||||
static async createDefault(parent) {
|
||||
const createData = {
|
||||
|
@ -169,23 +170,27 @@ export class DS4ActiveEffect extends ActiveEffect {
|
|||
* @protected
|
||||
*/
|
||||
getFactoredChangesWithEffect(predicate = () => true) {
|
||||
if (this.data.disabled || this.isSurpressed) {
|
||||
if (this.disabled || this.isSurpressed) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return this.data.changes.filter(predicate).flatMap((change) => {
|
||||
return this.changes.filter(predicate).flatMap((change) => {
|
||||
change.priority = change.priority ?? change.mode * 10;
|
||||
return Array(this.factor).fill({ effect: this, change });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {foundry.data.ActiveEffectData["changes"][number]} EffectChangeData
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} EffectChangeDataWithEffect
|
||||
* @property {DS4ActiveEffect} effect
|
||||
* @property {EffectChangeData} change
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} EffectChangeData
|
||||
* @property {string} key The attribute path in the Actor or Item data which the change modifies
|
||||
* @property {string} value The value of the change effect
|
||||
* @property {number} mode The modification mode with which the change is applied
|
||||
* @property {number} priority The priority level with which this change is applied
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,6 @@ import { isAttribute, isTrait } from "./actor-data-source-base";
|
|||
export class DS4Actor extends Actor {
|
||||
/** @override */
|
||||
prepareData() {
|
||||
this.data.reset();
|
||||
this.prepareBaseData();
|
||||
this.prepareEmbeddedDocuments();
|
||||
this.prepareIntermediateData();
|
||||
|
@ -29,18 +28,16 @@ export class DS4Actor extends Actor {
|
|||
|
||||
/** @override */
|
||||
prepareBaseData() {
|
||||
const data = this.data;
|
||||
|
||||
data.data.rolling = {
|
||||
this.system.rolling = {
|
||||
minimumFumbleResult: 20,
|
||||
maximumCoupResult: 1,
|
||||
};
|
||||
|
||||
const attributes = data.data.attributes;
|
||||
Object.values(attributes).forEach((attribute) => (attribute.total = attribute.base + attribute.mod));
|
||||
Object.values(this.system.attributes).forEach(
|
||||
(attribute) => (attribute.total = attribute.base + attribute.mod),
|
||||
);
|
||||
|
||||
const traits = data.data.traits;
|
||||
Object.values(traits).forEach((trait) => (trait.total = trait.base + trait.mod));
|
||||
Object.values(this.system.traits).forEach((trait) => (trait.total = trait.base + trait.mod));
|
||||
}
|
||||
|
||||
/** @override */
|
||||
|
@ -54,26 +51,26 @@ export class DS4Actor extends Actor {
|
|||
* applied to the Actor.
|
||||
*/
|
||||
prepareIntermediateData() {
|
||||
this.data.data.armorValueSpellMalus = this.armorValueSpellMalusOfEquippedItems;
|
||||
this.system.armorValueSpellMalus = this.armorValueSpellMalusOfEquippedItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* The effects that should be applioed to this actor.
|
||||
* @type {this["effects"]}
|
||||
* @type {import("../active-effect").DS4ActiveEffect[]}
|
||||
* @protected
|
||||
*/
|
||||
get actorEffects() {
|
||||
return this.effects.filter((effect) => !effect.data.flags.ds4?.itemEffectConfig?.applyToItems);
|
||||
return this.effects.filter((effect) => !effect.flags.ds4?.itemEffectConfig?.applyToItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the effects of this actor that should be applied to the given item.
|
||||
* @param {import("../item/item").DS4Item} item The item for which to get effects
|
||||
* @returns The array of effects that are candidates to be applied to the item
|
||||
* @returns {import("../active-effect").DS4ActiveEffect[]} The array of effects that are candidates to be applied to the item
|
||||
*/
|
||||
itemEffects(item) {
|
||||
return this.effects.filter((effect) => {
|
||||
const { applyToItems, itemName, condition } = effect.data.flags.ds4?.itemEffectConfig ?? {};
|
||||
const { applyToItems, itemName, condition } = effect.flags.ds4?.itemEffectConfig ?? {};
|
||||
|
||||
if (!applyToItems || (itemName !== undefined && itemName !== "" && itemName !== item.name)) {
|
||||
return false;
|
||||
|
@ -82,9 +79,9 @@ export class DS4Actor extends Actor {
|
|||
if (condition !== undefined && condition !== "") {
|
||||
try {
|
||||
const replacedCondition = DS4Actor.replaceFormulaData(condition, {
|
||||
item: item.data,
|
||||
actor: this.data,
|
||||
effect: effect.data,
|
||||
item,
|
||||
actor: this,
|
||||
effect,
|
||||
});
|
||||
return replacedCondition !== undefined ? Boolean(mathEvaluator.evaluate(replacedCondition)) : false;
|
||||
} catch (error) {
|
||||
|
@ -189,7 +186,7 @@ export class DS4Actor extends Actor {
|
|||
* @override
|
||||
*/
|
||||
prepareDerivedData() {
|
||||
this.data.data.armorValueSpellMalus = Math.max(this.data.data.armorValueSpellMalus, 0);
|
||||
this.system.armorValueSpellMalus = Math.max(this.system.armorValueSpellMalus, 0);
|
||||
this.prepareCombatValues();
|
||||
this.prepareChecks();
|
||||
}
|
||||
|
@ -200,11 +197,11 @@ export class DS4Actor extends Actor {
|
|||
*/
|
||||
get derivedDataProperties() {
|
||||
const combatValueProperties = Object.keys(DS4.i18n.combatValues).map(
|
||||
(combatValue) => `data.combatValues.${combatValue}.total`,
|
||||
(combatValue) => `system.combatValues.${combatValue}.total`,
|
||||
);
|
||||
const checkProperties = Object.keys(DS4.i18n.checks)
|
||||
.filter((check) => check !== "defend")
|
||||
.map((check) => `data.checks.${check}`);
|
||||
.map((check) => `system.checks.${check}`);
|
||||
return combatValueProperties.concat(checkProperties);
|
||||
}
|
||||
|
||||
|
@ -212,18 +209,17 @@ export class DS4Actor extends Actor {
|
|||
* Apply final transformations to the Actor data after all effects have been applied.
|
||||
*/
|
||||
prepareFinalDerivedData() {
|
||||
Object.values(this.data.data.attributes).forEach((attribute) => (attribute.total = Math.ceil(attribute.total)));
|
||||
Object.values(this.data.data.traits).forEach((trait) => (trait.total = Math.ceil(trait.total)));
|
||||
Object.entries(this.data.data.combatValues)
|
||||
Object.values(this.system.attributes).forEach((attribute) => (attribute.total = Math.ceil(attribute.total)));
|
||||
Object.values(this.system.traits).forEach((trait) => (trait.total = Math.ceil(trait.total)));
|
||||
Object.entries(this.system.combatValues)
|
||||
.filter(([key]) => key !== "movement")
|
||||
.map(([, value]) => value)
|
||||
.forEach((combatValue) => (combatValue.total = Math.ceil(combatValue.total)));
|
||||
Object.keys(this.data.data.checks).forEach((key) => {
|
||||
this.data.data.checks[key] = Math.ceil(this.data.data.checks[key]);
|
||||
.forEach(([, combatValue]) => (combatValue.total = Math.ceil(combatValue.total)));
|
||||
Object.keys(this.system.checks).forEach((key) => {
|
||||
this.system.checks[key] = Math.ceil(this.system.checks[key]);
|
||||
});
|
||||
|
||||
this.data.data.combatValues.hitPoints.max = this.data.data.combatValues.hitPoints.total;
|
||||
this.data.data.checks.defend = this.data.data.combatValues.defense.total;
|
||||
this.system.combatValues.hitPoints.max = this.system.combatValues.hitPoints.total;
|
||||
this.system.checks.defend = this.system.combatValues.defense.total;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -232,7 +228,7 @@ export class DS4Actor extends Actor {
|
|||
* @type {string[]}
|
||||
*/
|
||||
get finalDerivedDataProperties() {
|
||||
return ["data.combatValues.hitPoints.max", "data.checks.defend"];
|
||||
return ["system.combatValues.hitPoints.max", "system.checks.defend"];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -257,21 +253,21 @@ export class DS4Actor extends Actor {
|
|||
* @protected
|
||||
*/
|
||||
prepareCombatValues() {
|
||||
const data = this.data.data;
|
||||
const system = this.system;
|
||||
|
||||
data.combatValues.hitPoints.base = data.attributes.body.total + data.traits.constitution.total + 10;
|
||||
data.combatValues.defense.base =
|
||||
data.attributes.body.total + data.traits.constitution.total + this.armorValueOfEquippedItems;
|
||||
data.combatValues.initiative.base = data.attributes.mobility.total + data.traits.agility.total;
|
||||
data.combatValues.movement.base = data.attributes.mobility.total / 2 + 1;
|
||||
data.combatValues.meleeAttack.base = data.attributes.body.total + data.traits.strength.total;
|
||||
data.combatValues.rangedAttack.base = data.attributes.mobility.total + data.traits.dexterity.total;
|
||||
data.combatValues.spellcasting.base =
|
||||
data.attributes.mind.total + data.traits.aura.total - data.armorValueSpellMalus;
|
||||
data.combatValues.targetedSpellcasting.base =
|
||||
data.attributes.mind.total + data.traits.dexterity.total - data.armorValueSpellMalus;
|
||||
system.combatValues.hitPoints.base = system.attributes.body.total + system.traits.constitution.total + 10;
|
||||
system.combatValues.defense.base =
|
||||
system.attributes.body.total + system.traits.constitution.total + this.armorValueOfEquippedItems;
|
||||
system.combatValues.initiative.base = system.attributes.mobility.total + system.traits.agility.total;
|
||||
system.combatValues.movement.base = system.attributes.mobility.total / 2 + 1;
|
||||
system.combatValues.meleeAttack.base = system.attributes.body.total + system.traits.strength.total;
|
||||
system.combatValues.rangedAttack.base = system.attributes.mobility.total + system.traits.dexterity.total;
|
||||
system.combatValues.spellcasting.base =
|
||||
system.attributes.mind.total + system.traits.aura.total - system.armorValueSpellMalus;
|
||||
system.combatValues.targetedSpellcasting.base =
|
||||
system.attributes.mind.total + system.traits.dexterity.total - system.armorValueSpellMalus;
|
||||
|
||||
Object.values(data.combatValues).forEach(
|
||||
Object.values(system.combatValues).forEach(
|
||||
(combatValue) => (combatValue.total = combatValue.base + combatValue.mod),
|
||||
);
|
||||
}
|
||||
|
@ -282,7 +278,7 @@ export class DS4Actor extends Actor {
|
|||
* @protected
|
||||
*/
|
||||
get armorValueOfEquippedItems() {
|
||||
return this.equippedItemsWithArmor.map((item) => item.data.data.armorValue).reduce((a, b) => a + b, 0);
|
||||
return this.equippedItemsWithArmor.map((item) => item.system.armorValue).reduce((a, b) => a + b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -292,12 +288,8 @@ export class DS4Actor extends Actor {
|
|||
*/
|
||||
get armorValueSpellMalusOfEquippedItems() {
|
||||
return this.equippedItemsWithArmor
|
||||
.filter(
|
||||
(item) =>
|
||||
!(item.data.type === "armor" && ["cloth", "natural"].includes(item.data.data.armorMaterialType)),
|
||||
)
|
||||
.map((item) => item.data.data.armorValue)
|
||||
.reduce((a, b) => a + b, 0);
|
||||
.filter((item) => !(item.type === "armor" && ["cloth", "natural"].includes(item.system.armorMaterialType)))
|
||||
.reduce((sum, item) => sum + item.system.armorValue, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -306,9 +298,7 @@ export class DS4Actor extends Actor {
|
|||
* @protected
|
||||
*/
|
||||
get equippedItemsWithArmor() {
|
||||
return this.items
|
||||
.filter((item) => item.data.type === "armor" || item.data.type === "shield")
|
||||
.filter((item) => item.data.data.equipped);
|
||||
return this.items.filter((item) => (item.type === "armor" || item.type === "shield") && item.system.equipped);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -316,57 +306,63 @@ export class DS4Actor extends Actor {
|
|||
* @protected
|
||||
*/
|
||||
prepareChecks() {
|
||||
const data = this.data.data;
|
||||
data.checks = {
|
||||
appraise: data.attributes.mind.total + data.traits.intellect.total,
|
||||
changeSpell: data.attributes.mind.total + data.traits.intellect.total,
|
||||
climb: data.attributes.mobility.total + data.traits.strength.total,
|
||||
communicate: data.attributes.mind.total + data.traits.dexterity.total + this.itemTypes.language.length,
|
||||
decipherScript: data.attributes.mind.total + data.traits.intellect.total,
|
||||
const system = this.system;
|
||||
system.checks = {
|
||||
appraise: system.attributes.mind.total + system.traits.intellect.total,
|
||||
changeSpell: system.attributes.mind.total + system.traits.intellect.total,
|
||||
climb: system.attributes.mobility.total + system.traits.strength.total,
|
||||
communicate: system.attributes.mind.total + system.traits.dexterity.total + this.itemTypes.language.length,
|
||||
decipherScript: system.attributes.mind.total + system.traits.intellect.total,
|
||||
defend: 0, // assigned in prepareFinalDerivedData as it must always match data.combatValues.defense.total and is not changeable by effects
|
||||
defyPoison: data.attributes.body.total + data.traits.constitution.total,
|
||||
disableTraps: data.attributes.mind.total + data.traits.dexterity.total,
|
||||
featOfStrength: data.attributes.body.total + data.traits.strength.total,
|
||||
flirt: data.attributes.mind.total + data.traits.aura.total,
|
||||
haggle: data.attributes.mind.total + Math.max(data.traits.intellect.total, data.traits.intellect.total),
|
||||
hide: data.attributes.mobility.total + data.traits.agility.total,
|
||||
identifyMagic: data.attributes.mind.total + data.traits.intellect.total,
|
||||
jump: data.attributes.mobility.total + data.traits.agility.total,
|
||||
knowledge: data.attributes.mind.total + data.traits.intellect.total,
|
||||
openLock: data.attributes.mind.total + data.traits.dexterity.total,
|
||||
perception: Math.max(data.attributes.mind.total + data.traits.intellect.total, 8),
|
||||
pickPocket: data.attributes.mobility.total + data.traits.dexterity.total,
|
||||
readTracks: data.attributes.mind.total + data.traits.intellect.total,
|
||||
resistDisease: data.attributes.body.total + data.traits.constitution.total,
|
||||
ride: data.attributes.mobility.total + Math.max(data.traits.agility.total, data.traits.aura.total),
|
||||
search: Math.max(data.attributes.mind.total + data.traits.intellect.total, 8),
|
||||
senseMagic: data.attributes.mind.total + data.traits.aura.total,
|
||||
sneak: data.attributes.mobility.total + data.traits.agility.total,
|
||||
startFire: data.attributes.mind.total + data.traits.dexterity.total,
|
||||
swim: data.attributes.mobility.total + data.traits.strength.total,
|
||||
wakeUp: data.attributes.mind.total + data.traits.intellect.total,
|
||||
defyPoison: system.attributes.body.total + system.traits.constitution.total,
|
||||
disableTraps: system.attributes.mind.total + system.traits.dexterity.total,
|
||||
featOfStrength: system.attributes.body.total + system.traits.strength.total,
|
||||
flirt: system.attributes.mind.total + system.traits.aura.total,
|
||||
haggle:
|
||||
system.attributes.mind.total + Math.max(system.traits.intellect.total, system.traits.intellect.total),
|
||||
hide: system.attributes.mobility.total + system.traits.agility.total,
|
||||
identifyMagic: system.attributes.mind.total + system.traits.intellect.total,
|
||||
jump: system.attributes.mobility.total + system.traits.agility.total,
|
||||
knowledge: system.attributes.mind.total + system.traits.intellect.total,
|
||||
openLock: system.attributes.mind.total + system.traits.dexterity.total,
|
||||
perception: Math.max(system.attributes.mind.total + system.traits.intellect.total, 8),
|
||||
pickPocket: system.attributes.mobility.total + system.traits.dexterity.total,
|
||||
readTracks: system.attributes.mind.total + system.traits.intellect.total,
|
||||
resistDisease: system.attributes.body.total + system.traits.constitution.total,
|
||||
ride: system.attributes.mobility.total + Math.max(system.traits.agility.total, system.traits.aura.total),
|
||||
search: Math.max(system.attributes.mind.total + system.traits.intellect.total, 8),
|
||||
senseMagic: system.attributes.mind.total + system.traits.aura.total,
|
||||
sneak: system.attributes.mobility.total + system.traits.agility.total,
|
||||
startFire: system.attributes.mind.total + system.traits.dexterity.total,
|
||||
swim: system.attributes.mobility.total + system.traits.strength.total,
|
||||
wakeUp: system.attributes.mind.total + system.traits.intellect.total,
|
||||
workMechanism:
|
||||
data.attributes.mind.total + Math.max(data.traits.dexterity.total, data.traits.intellect.total),
|
||||
system.attributes.mind.total + Math.max(system.traits.dexterity.total, system.traits.intellect.total),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle how changes to a Token attribute bar are applied to the Actor.
|
||||
* This only differs from the base implementation by also allowing negative values.
|
||||
* @param {string} attribute The attribute path
|
||||
* @param {number} value The target attribute value
|
||||
* @param {boolean} [isDelta=false] Whether the number represents a relative change (true) or an absolute change (false)
|
||||
* @param {boolean} [isBar=true] Whether the new value is part of an attribute bar, or just a direct value
|
||||
* @returns {Promise<DS4Actor>} The updated Actor document
|
||||
* @override
|
||||
*/
|
||||
async modifyTokenAttribute(attribute, value, isDelta = false, isBar = true) {
|
||||
const current = foundry.utils.getProperty(this.data.data, attribute);
|
||||
const current = foundry.utils.getProperty(this.system, attribute);
|
||||
|
||||
// Determine the updates to make to the actor data
|
||||
/** @type {Record<string, number>} */
|
||||
let updates;
|
||||
if (isBar) {
|
||||
if (isDelta) value = Math.min(Number(current.value) + value, current.max);
|
||||
updates = { [`data.${attribute}.value`]: value };
|
||||
updates = { [`system.${attribute}.value`]: value };
|
||||
} else {
|
||||
if (isDelta) value = Number(current) + value;
|
||||
updates = { [`data.${attribute}`]: value };
|
||||
updates = { [`system.${attribute}`]: value };
|
||||
}
|
||||
|
||||
// Call a hook to handle token resource bar updates
|
||||
|
@ -382,10 +378,10 @@ export class DS4Actor extends Actor {
|
|||
*/
|
||||
async rollCheck(check, options = {}) {
|
||||
const speaker = ChatMessage.getSpeaker({ actor: this, ...options.speaker });
|
||||
await createCheckRoll(this.data.data.checks[check], {
|
||||
await createCheckRoll(this.system.checks[check], {
|
||||
rollMode: getGame().settings.get("core", "rollMode"),
|
||||
maximumCoupResult: this.data.data.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: this.data.data.rolling.minimumFumbleResult,
|
||||
maximumCoupResult: this.system.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: this.system.rolling.minimumFumbleResult,
|
||||
flavor: "DS4.ActorCheckFlavor",
|
||||
flavorData: { actor: speaker.alias ?? this.name, check: DS4.i18nKeys.checks[check] },
|
||||
speaker,
|
||||
|
@ -404,12 +400,12 @@ export class DS4Actor extends Actor {
|
|||
return;
|
||||
}
|
||||
const { attribute, trait } = attributeAndTrait;
|
||||
const checkTargetNumber = this.data.data.attributes[attribute].total + this.data.data.traits[trait].total;
|
||||
const checkTargetNumber = this.system.attributes[attribute].total + this.system.traits[trait].total;
|
||||
const speaker = ChatMessage.getSpeaker({ actor: this, ...options.speaker });
|
||||
await createCheckRoll(checkTargetNumber, {
|
||||
rollMode: getGame().settings.get("core", "rollMode"),
|
||||
maximumCoupResult: this.data.data.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: this.data.data.rolling.minimumFumbleResult,
|
||||
maximumCoupResult: this.system.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: this.system.rolling.minimumFumbleResult,
|
||||
flavor: "DS4.ActorGenericCheckFlavor",
|
||||
flavorData: {
|
||||
actor: speaker.alias ?? this.name,
|
||||
|
@ -438,7 +434,7 @@ export class DS4Actor extends Actor {
|
|||
options: Object.fromEntries(
|
||||
Object.entries(DS4.i18n.attributes).map(([attribute, translation]) => [
|
||||
attribute,
|
||||
`${translation} (${this.data.data.attributes[attribute].total})`,
|
||||
`${translation} (${this.system.attributes[attribute].total})`,
|
||||
]),
|
||||
),
|
||||
},
|
||||
|
@ -448,7 +444,7 @@ export class DS4Actor extends Actor {
|
|||
options: Object.fromEntries(
|
||||
Object.entries(DS4.i18n.traits).map(([trait, translation]) => [
|
||||
trait,
|
||||
`${translation} (${this.data.data.traits[trait].total})`,
|
||||
`${translation} (${this.system.traits[trait].total})`,
|
||||
]),
|
||||
),
|
||||
},
|
||||
|
|
|
@ -8,12 +8,12 @@ export class DS4Character extends DS4Actor {
|
|||
/** @override */
|
||||
prepareFinalDerivedData() {
|
||||
super.prepareFinalDerivedData();
|
||||
this.data.data.slayerPoints.max = 3;
|
||||
this.system.slayerPoints.max = 3;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get finalDerivedDataProperties() {
|
||||
return [...super.finalDerivedDataProperties, "data.slayerPoints.max"];
|
||||
return [...super.finalDerivedDataProperties, "system.slayerPoints.max"];
|
||||
}
|
||||
|
||||
/** @override */
|
||||
|
|
|
@ -17,15 +17,15 @@ import { getGame } from "../utils/utils";
|
|||
export class DS4ChatMessage extends ChatMessage {
|
||||
prepareData() {
|
||||
super.prepareData();
|
||||
if (this.data.flavor) {
|
||||
if (this.flavor) {
|
||||
const game = getGame();
|
||||
const flavorData = Object.fromEntries(
|
||||
Object.entries(this.data.flags.ds4?.flavorData ?? {}).map(([key, value]) => [
|
||||
Object.entries(this.flags.ds4?.flavorData ?? {}).map(([key, value]) => [
|
||||
key,
|
||||
typeof value === "string" ? game.i18n.localize(value) : value,
|
||||
]),
|
||||
);
|
||||
this.data.flavor = game.i18n.format(this.data.flavor, flavorData);
|
||||
this.flavor = game.i18n.format(this.flavor, flavorData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
16
src/documents/common/roll-options.js
Normal file
16
src/documents/common/roll-options.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/**
|
||||
* @typedef {object} RollOptions
|
||||
* @property {Speaker} speaker
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} Speaker
|
||||
* @property {TokenDocument} [token]
|
||||
* @property {string} [alias]
|
||||
*/
|
||||
|
||||
export {}
|
|
@ -17,10 +17,6 @@ export interface DS4ItemDataSourceDataPhysical {
|
|||
storageLocation: string;
|
||||
}
|
||||
|
||||
export function isDS4ItemDataTypePhysical(input: object): boolean {
|
||||
return "quantity" in input && "price" in input && "availability" in input && "storageLocation" in input;
|
||||
}
|
||||
|
||||
export interface DS4ItemDataSourceDataEquipable {
|
||||
equipped: boolean;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ export class DS4Item extends Item {
|
|||
|
||||
/** @override */
|
||||
prepareDerivedData() {
|
||||
this.data.data.rollable = false;
|
||||
this.system.rollable = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,7 @@ export class DS4Item extends Item {
|
|||
* @returns {boolean} Whether the item is a non-equpped equibale or not
|
||||
*/
|
||||
isNonEquippedEuipable() {
|
||||
return "equipped" in this.data.data && !this.data.data.equipped;
|
||||
return "equipped" in this.system && !this.system.equipped;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,6 +52,6 @@ export class DS4Item extends Item {
|
|||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
async roll(options = {}) {
|
||||
throw new Error(getGame().i18n.format("DS4.ErrorRollingForItemTypeNotPossible", { type: this.data.type }));
|
||||
throw new Error(getGame().i18n.format("DS4.ErrorRollingForItemTypeNotPossible", { type: this.type }));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@ import { calculateSpellPrice } from "./calculate-spell-price";
|
|||
export class DS4Spell extends DS4Item {
|
||||
/** @override */
|
||||
prepareDerivedData() {
|
||||
this.data.data.rollable = this.data.data.equipped;
|
||||
this.data.data.price = calculateSpellPrice(this.data.data);
|
||||
if (this.data.data.allowsDefense) {
|
||||
this.data.data.opponentDefense = 0;
|
||||
this.system.rollable = this.system.equipped;
|
||||
this.system.price = calculateSpellPrice(this.system);
|
||||
if (this.system.allowsDefense) {
|
||||
this.system.opponentDefense = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,12 +22,12 @@ export class DS4Spell extends DS4Item {
|
|||
async roll(options = {}) {
|
||||
const game = getGame();
|
||||
|
||||
if (!this.data.data.equipped) {
|
||||
if (!this.system.equipped) {
|
||||
return notifications.warn(
|
||||
game.i18n.format("DS4.WarningItemMustBeEquippedToBeRolled", {
|
||||
name: this.name,
|
||||
id: this.id,
|
||||
type: this.data.type,
|
||||
type: this.type,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -36,21 +36,21 @@ export class DS4Spell extends DS4Item {
|
|||
throw new Error(game.i18n.format("DS4.ErrorCannotRollUnownedItem", { name: this.name, id: this.id }));
|
||||
}
|
||||
|
||||
const ownerDataData = this.actor.data.data;
|
||||
const hasComplexModifier = this.data.data.spellModifier.complex !== "";
|
||||
const ownerSystemData = this.actor.system;
|
||||
const hasComplexModifier = this.system.spellModifier.complex !== "";
|
||||
if (hasComplexModifier === undefined) {
|
||||
notifications.info(
|
||||
game.i18n.format("DS4.InfoManuallyEnterSpellModifier", {
|
||||
name: this.name,
|
||||
spellModifier: this.data.data.spellModifier.complex,
|
||||
spellModifier: this.system.spellModifier.complex,
|
||||
}),
|
||||
);
|
||||
}
|
||||
const spellType = this.data.data.spellType;
|
||||
const opponentDefense = this.data.data.opponentDefense;
|
||||
const spellType = this.system.spellType;
|
||||
const opponentDefense = this.system.opponentDefense;
|
||||
const checkTargetNumber =
|
||||
ownerDataData.combatValues[spellType].total +
|
||||
(hasComplexModifier ? 0 : this.data.data.spellModifier.numerical);
|
||||
ownerSystemData.combatValues[spellType].total +
|
||||
(hasComplexModifier ? 0 : this.system.spellModifier.numerical);
|
||||
const speaker = ChatMessage.getSpeaker({ actor: this.actor, ...options.speaker });
|
||||
const flavor =
|
||||
opponentDefense !== undefined && opponentDefense !== 0
|
||||
|
@ -67,8 +67,8 @@ export class DS4Spell extends DS4Item {
|
|||
|
||||
await createCheckRoll(checkTargetNumber, {
|
||||
rollMode: game.settings.get("core", "rollMode"),
|
||||
maximumCoupResult: ownerDataData.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: ownerDataData.rolling.minimumFumbleResult,
|
||||
maximumCoupResult: ownerSystemData.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: ownerSystemData.rolling.minimumFumbleResult,
|
||||
flavor: flavor,
|
||||
flavorData: flavorData,
|
||||
speaker,
|
||||
|
|
|
@ -8,12 +8,11 @@ export class DS4Talent extends DS4Item {
|
|||
/** @override */
|
||||
prepareDerivedData() {
|
||||
super.prepareDerivedData();
|
||||
const data = this.data.data;
|
||||
data.rank.total = data.rank.base + data.rank.mod;
|
||||
this.system.rank.total = this.system.rank.base + this.system.rank.mod;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get activeEffectFactor() {
|
||||
return this.data.data.rank.total;
|
||||
return this.system.rank.total;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,26 +11,26 @@ import { DS4Item } from "../item";
|
|||
export class DS4Weapon extends DS4Item {
|
||||
/** @override */
|
||||
prepareDerivedData() {
|
||||
const data = this.data.data;
|
||||
data.rollable = data.equipped;
|
||||
data.opponentDefenseForAttackType = {};
|
||||
if (data.attackType === "melee" || data.attackType === "meleeRanged") {
|
||||
data.opponentDefenseForAttackType.melee = data.opponentDefense;
|
||||
const system = this.system;
|
||||
system.rollable = system.equipped;
|
||||
system.opponentDefenseForAttackType = {};
|
||||
if (system.attackType === "melee" || system.attackType === "meleeRanged") {
|
||||
system.opponentDefenseForAttackType.melee = system.opponentDefense;
|
||||
}
|
||||
if (data.attackType === "ranged" || data.attackType === "meleeRanged") {
|
||||
data.opponentDefenseForAttackType.ranged = data.opponentDefense;
|
||||
if (system.attackType === "ranged" || system.attackType === "meleeRanged") {
|
||||
system.opponentDefenseForAttackType.ranged = system.opponentDefense;
|
||||
}
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async roll(options = {}) {
|
||||
const game = getGame();
|
||||
if (!this.data.data.equipped) {
|
||||
if (!this.system.equipped) {
|
||||
return notifications.warn(
|
||||
game.i18n.format("DS4.WarningItemMustBeEquippedToBeRolled", {
|
||||
name: this.name,
|
||||
id: this.id,
|
||||
type: this.data.type,
|
||||
type: this.type,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -39,12 +39,12 @@ export class DS4Weapon extends DS4Item {
|
|||
throw new Error(game.i18n.format("DS4.ErrorCannotRollUnownedItem", { name: this.name, id: this.id }));
|
||||
}
|
||||
|
||||
const ownerDataData = this.actor.data.data;
|
||||
const weaponBonus = this.data.data.weaponBonus;
|
||||
const ownerSystemData = this.actor.system;
|
||||
const weaponBonus = this.system.weaponBonus;
|
||||
const attackType = await this.getPerformedAttackType();
|
||||
const opponentDefense = this.data.data.opponentDefenseForAttackType[attackType];
|
||||
const opponentDefense = this.system.opponentDefenseForAttackType[attackType];
|
||||
const combatValue = `${attackType}Attack`;
|
||||
const checkTargetNumber = ownerDataData.combatValues[combatValue].total + weaponBonus;
|
||||
const checkTargetNumber = ownerSystemData.combatValues[combatValue].total + weaponBonus;
|
||||
const speaker = ChatMessage.getSpeaker({ actor: this.actor, ...options.speaker });
|
||||
const flavor =
|
||||
opponentDefense !== undefined && opponentDefense !== 0
|
||||
|
@ -61,8 +61,8 @@ export class DS4Weapon extends DS4Item {
|
|||
|
||||
await createCheckRoll(checkTargetNumber, {
|
||||
rollMode: getGame().settings.get("core", "rollMode"),
|
||||
maximumCoupResult: ownerDataData.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: ownerDataData.rolling.minimumFumbleResult,
|
||||
maximumCoupResult: ownerSystemData.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: ownerSystemData.rolling.minimumFumbleResult,
|
||||
speaker,
|
||||
flavor,
|
||||
flavorData,
|
||||
|
@ -77,8 +77,8 @@ export class DS4Weapon extends DS4Item {
|
|||
* @protected
|
||||
*/
|
||||
async getPerformedAttackType() {
|
||||
if (this.data.data.attackType !== "meleeRanged") {
|
||||
return this.data.data.attackType;
|
||||
if (this.system.attackType !== "meleeRanged") {
|
||||
return this.system.attackType;
|
||||
}
|
||||
|
||||
const { melee, ranged } = { ...DS4.i18n.attackTypes };
|
||||
|
|
|
@ -12,7 +12,7 @@ function getFallbackData() {
|
|||
if (!fallbackData) {
|
||||
fallbackData = {};
|
||||
for (const type of getGame().system.template.Actor?.types ?? []) {
|
||||
foundry.utils.mergeObject(fallbackData, new DS4ActorProxy({ type, name: "temporary" }).data.data);
|
||||
foundry.utils.mergeObject(fallbackData, new DS4ActorProxy({ type, name: "temporary" }).system);
|
||||
}
|
||||
}
|
||||
return fallbackData;
|
||||
|
|
|
@ -2,12 +2,8 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { isCheck } from "../documents/actor/actor-data-properties-base";
|
||||
import { DS4Item } from "../documents/item/item";
|
||||
import { createRollCheckMacro } from "../macros/roll-check";
|
||||
import { createRollItemMacro } from "../macros/roll-item";
|
||||
import { notifications } from "../ui/notifications";
|
||||
import { getGame } from "../utils/utils";
|
||||
|
||||
export function registerForHotbarDropHook() {
|
||||
Hooks.on("hotbarDrop", onHotbarDrop);
|
||||
|
@ -23,32 +19,17 @@ export function registerForHotbarDropHook() {
|
|||
* @param {Hotbar} hotbar The hotbar on which something wqas
|
||||
* @param {DropData} data The drop data associated to the drop event
|
||||
* @param {string} slot The slot on the hotbar that somethingwas dropped on
|
||||
* @returns {Promise<void>}
|
||||
* @returns {void | false}
|
||||
*/
|
||||
async function onHotbarDrop(hotbar, data, slot) {
|
||||
function onHotbarDrop(hotbar, data, slot) {
|
||||
switch (data.type) {
|
||||
case "Item": {
|
||||
if (!("data" in data)) {
|
||||
return notifications.warn(getGame().i18n.localize("DS4.WarningMacrosCanOnlyBeCreatedForOwnedItems"));
|
||||
}
|
||||
const itemData = data.data;
|
||||
|
||||
if (!DS4Item.rollableItemTypes.includes(itemData.type)) {
|
||||
return notifications.warn(
|
||||
getGame().i18n.format("DS4.WarningItemIsNotRollable", {
|
||||
name: itemData.name,
|
||||
id: itemData._id,
|
||||
type: itemData.type,
|
||||
}),
|
||||
);
|
||||
}
|
||||
return createRollItemMacro(itemData, slot);
|
||||
createRollItemMacro(data, slot);
|
||||
return false;
|
||||
}
|
||||
case "Check": {
|
||||
if (!("data" in data) || typeof data.data !== "string" || !isCheck(data.data)) {
|
||||
return notifications.warn(getGame().i18n.localize("DS4.WarningInvalidCheckDropped"));
|
||||
}
|
||||
return createRollCheckMacro(data.data, slot);
|
||||
createRollCheckMacro(data, slot);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4 } from "../config";
|
||||
import { isCheck } from "../documents/actor/actor-data-properties-base";
|
||||
import { notifications } from "../ui/notifications";
|
||||
import { getGame } from "../utils/utils";
|
||||
import { getActiveActorAndToken } from "./helpers";
|
||||
|
@ -10,12 +11,15 @@ import { getActiveActorAndToken } from "./helpers";
|
|||
/**
|
||||
* Creates a macro from a check drop.
|
||||
* Get an existing roll check macro if one exists, otherwise create a new one.
|
||||
* @param {import("../documents/actor/actor-data-properties-base").Check} check The name of the check to perform
|
||||
* @param {string} slot The hotbar slot to use
|
||||
* @returns {Promise<void>} A promise that resoolves when the macro has been created.
|
||||
* @param {object} data The check drop data
|
||||
* @param {string} slot The hotbar slot to use
|
||||
* @returns {Promise<void>} A promise that resolves when the macro has been created.
|
||||
*/
|
||||
export async function createRollCheckMacro(check, slot) {
|
||||
const macro = await getOrCreateRollCheckMacro(check);
|
||||
export async function createRollCheckMacro(data, slot) {
|
||||
if (!("data" in data) || typeof data.data !== "string" || !isCheck(data.data)) {
|
||||
return notifications.warn(getGame().i18n.localize("DS4.WarningInvalidCheckDropped"));
|
||||
}
|
||||
const macro = await getOrCreateRollCheckMacro(data.data);
|
||||
await getGame().user?.assignHotbarMacro(macro ?? null, slot);
|
||||
}
|
||||
|
||||
|
@ -26,9 +30,7 @@ export async function createRollCheckMacro(check, slot) {
|
|||
async function getOrCreateRollCheckMacro(check) {
|
||||
const command = `game.ds4.macros.rollCheck("${check}");`;
|
||||
|
||||
const existingMacro = getGame().macros?.find(
|
||||
(m) => m.name === DS4.i18n.checks[check] && m.data.command === command,
|
||||
);
|
||||
const existingMacro = getGame().macros?.find((m) => m.name === DS4.i18n.checks[check] && m.command === command);
|
||||
if (existingMacro) {
|
||||
return existingMacro;
|
||||
}
|
||||
|
|
|
@ -2,18 +2,33 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../documents/item/item";
|
||||
import { notifications } from "../ui/notifications";
|
||||
import { getGame } from "../utils/utils";
|
||||
import { getActiveActorAndToken } from "./helpers";
|
||||
|
||||
/**
|
||||
* Creates a macro from an item drop.
|
||||
* Create a macro from an item drop.
|
||||
* Get an existing roll item macro if one exists, otherwise create a new one.
|
||||
* @param {object} itemData The item data
|
||||
* @param {string} slot The hotbar slot to use
|
||||
* @param {object} data The item drop data
|
||||
* @param {string} slot The hotbar slot to use
|
||||
* @returns {Promise<void>} A promise that resolves once the macro has been created.
|
||||
*/
|
||||
export async function createRollItemMacro(itemData, slot) {
|
||||
export async function createRollItemMacro(data, slot) {
|
||||
const item = await Item.implementation.fromDropData(data);
|
||||
if (!item.parent) {
|
||||
return notifications.warn(getGame().i18n.localize("DS4.WarningMacrosCanOnlyBeCreatedForOwnedItems"));
|
||||
}
|
||||
if (!DS4Item.rollableItemTypes.includes(item.type)) {
|
||||
return notifications.warn(
|
||||
getGame().i18n.format("DS4.WarningItemIsNotRollable", {
|
||||
name: item.name,
|
||||
id: item.id,
|
||||
type: item.type,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
const macro = await getOrCreateRollItemMacro(itemData);
|
||||
await getGame().user?.assignHotbarMacro(macro ?? null, slot);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ async function migrate() {
|
|||
/** @type {import("./migrationHelpers").ActorUpdateDataGetter} */
|
||||
function getActorUpdateData() {
|
||||
const updateData = {
|
||||
data: {
|
||||
system: {
|
||||
combatValues: [
|
||||
"hitPoints",
|
||||
"defense",
|
||||
|
|
|
@ -24,7 +24,7 @@ async function migrate() {
|
|||
function getItemUpdateData(itemData) {
|
||||
if (!["loot"].includes(itemData.type ?? "")) return undefined;
|
||||
return {
|
||||
data: {
|
||||
system: {
|
||||
"-=equipped": null,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -23,10 +23,10 @@ async function migrate() {
|
|||
/** @type {import("./migrationHelpers").ItemUpdateDataGetter} */
|
||||
function getItemUpdateData(itemData) {
|
||||
if (itemData.type !== "spell") return;
|
||||
const cooldownDurationUnit = itemData.data?.cooldownDuration.unit;
|
||||
const cooldownDurationUnit = itemData.system?.cooldownDuration.unit;
|
||||
|
||||
const updateData = {
|
||||
data: {
|
||||
system: {
|
||||
"-=scrollPrice": null,
|
||||
minimumLevels: { healer: null, wizard: null, sorcerer: null },
|
||||
cooldownDuration: {
|
||||
|
|
|
@ -32,12 +32,12 @@ async function migrate() {
|
|||
/** @type {import("./migrationHelpers").ItemUpdateDataGetter} */
|
||||
function getItemUpdateData(itemData) {
|
||||
if (itemData.type !== "spell") return;
|
||||
const cooldownDurationUnit = itemData.data?.cooldownDuration.unit;
|
||||
const cooldownDurationValue = itemData.data?.cooldownDuration.value;
|
||||
const cooldownDurationUnit = itemData.system?.cooldownDuration.unit;
|
||||
const cooldownDurationValue = itemData.system?.cooldownDuration.value;
|
||||
const cooldownDuration = migrateCooldownDuration(cooldownDurationValue, cooldownDurationUnit);
|
||||
|
||||
const updateData = {
|
||||
data: {
|
||||
system: {
|
||||
cooldownDuration,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -23,15 +23,15 @@ async function migrate() {
|
|||
/** @type {import("./migrationHelpers").ItemUpdateDataGetter} */
|
||||
function getItemUpdateData(itemData) {
|
||||
if (itemData.type !== "spell") return;
|
||||
const spellCategory = itemData.data?.spellCategory;
|
||||
const spellCategory = itemData.system?.spellCategory;
|
||||
const spellGroups = migrateSpellCategory(spellCategory);
|
||||
|
||||
// @ts-expect-error bonus is removed with this migration
|
||||
const bonus = itemData.data?.bonus;
|
||||
const bonus = itemData.system?.bonus;
|
||||
const spellModifier = migrateBonus(bonus);
|
||||
|
||||
const updateData = {
|
||||
data: {
|
||||
system: {
|
||||
spellGroups,
|
||||
"-=spellCategory": null,
|
||||
spellModifier,
|
||||
|
|
|
@ -25,7 +25,7 @@ function getItemUpdateData(itemData) {
|
|||
if (itemData.type !== "spell") return;
|
||||
|
||||
return {
|
||||
data: {
|
||||
system: {
|
||||
allowsDefense: false,
|
||||
},
|
||||
};
|
||||
|
|
61
src/migration/008.js
Normal file
61
src/migration/008.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import {
|
||||
getActorUpdateDataGetter,
|
||||
getCompendiumMigrator,
|
||||
getItemUpdateDataGetter,
|
||||
getSceneUpdateDataGetter,
|
||||
migrateActors,
|
||||
migrateCompendiums,
|
||||
migrateItems,
|
||||
migrateScenes,
|
||||
} from "./migrationHelpers";
|
||||
|
||||
/** @type {import("./migration").Migration["migrate"]} */
|
||||
async function migrate() {
|
||||
await migrateItems(getItemUpdateData);
|
||||
await migrateActors(getActorUpdateData);
|
||||
await migrateScenes(getSceneUpdateData);
|
||||
await migrateCompendiums(migrateCompendium);
|
||||
}
|
||||
|
||||
/** @type {import("./migrationHelpers").EffectUpdateDataGetter} */
|
||||
function getEffectUpdateData(effectData) {
|
||||
const data = foundry.utils.deepClone(effectData);
|
||||
let hasUpdates = false;
|
||||
if ("changes" in data) {
|
||||
for (const change of data.changes) {
|
||||
const newValue = change.value.replaceAll(/@data\./g, "@system.");
|
||||
if (newValue !== change.value) {
|
||||
hasUpdates = true;
|
||||
change.value = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {string | undefined} */
|
||||
const condition = data.flags?.ds4?.itemEffectConfig?.condition;
|
||||
if (condition !== undefined) {
|
||||
const newCondition = condition.replaceAll(/(@actor|@item|@effect)\.data/g, "$1.system");
|
||||
if (newCondition !== condition) {
|
||||
hasUpdates = true;
|
||||
data.flags.ds4.itemEffectConfig.condition = newCondition;
|
||||
}
|
||||
}
|
||||
if (hasUpdates) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
const getItemUpdateData = getItemUpdateDataGetter(getEffectUpdateData);
|
||||
const getActorUpdateData = getActorUpdateDataGetter(getItemUpdateData, getEffectUpdateData);
|
||||
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
|
||||
const migrateCompendium = getCompendiumMigrator({ getItemUpdateData, getActorUpdateData, getSceneUpdateData });
|
||||
|
||||
/** @type {import("./migration").Migration} */
|
||||
export const migration = {
|
||||
migrate,
|
||||
migrateCompendium,
|
||||
};
|
|
@ -12,6 +12,7 @@ import { migration as migration004 } from "./004";
|
|||
import { migration as migration005 } from "./005";
|
||||
import { migration as migration006 } from "./006";
|
||||
import { migration as migration007 } from "./007";
|
||||
import { migration as migration008 } from "./008";
|
||||
|
||||
/**
|
||||
* Perform migrations.
|
||||
|
@ -166,7 +167,16 @@ function getTargetMigrationVersion() {
|
|||
/**
|
||||
* @type {Migration[]}
|
||||
*/
|
||||
const migrations = [migration001, migration002, migration003, migration004, migration005, migration006, migration007];
|
||||
const migrations = [
|
||||
migration001,
|
||||
migration002,
|
||||
migration003,
|
||||
migration004,
|
||||
migration005,
|
||||
migration006,
|
||||
migration007,
|
||||
migration008,
|
||||
];
|
||||
|
||||
/**
|
||||
* DOes the migration version indicate the world is being started for the first time?
|
||||
|
|
|
@ -7,7 +7,9 @@ import { DS4Item } from "../documents/item/item";
|
|||
import { logger } from "../utils/logger";
|
||||
import { getGame } from "../utils/utils";
|
||||
|
||||
/** @typedef {(itemData: Partial<foundry.data.ItemData["_source"]>) => DeepPartial<foundry.data.ItemData["_source"]> | Record<string, unknown> | undefined} ItemUpdateDataGetter */
|
||||
/** @typedef {(effectData: object) => Record<string, unknown> | undefined} EffectUpdateDataGetter */
|
||||
|
||||
/** @typedef {(itemData: object) => Record<string, unknown> | undefined} ItemUpdateDataGetter */
|
||||
|
||||
/**
|
||||
* Migrate world items.
|
||||
|
@ -28,7 +30,7 @@ export async function migrateItems(getItemUpdateData) {
|
|||
}
|
||||
}
|
||||
|
||||
/** @typedef {(actorData: Partial<foundry.data.ActorData["_source"]>) => DeepPartial<foundry.data.ActorData["_source"]> | undefined} ActorUpdateDataGetter */
|
||||
/** @typedef {(actorData: object>) => Record<string, unknown> | undefined} ActorUpdateDataGetter */
|
||||
|
||||
/**
|
||||
* Migrate world actors.
|
||||
|
@ -52,7 +54,7 @@ export async function migrateActors(getActorUpdateData) {
|
|||
}
|
||||
}
|
||||
|
||||
/** @typedef {(aceneData: foundry.data.SceneData) => DeepPartial<foundry.data.SceneData["_source"]> | undefined} SceneUpdateDataGetter */
|
||||
/** @typedef {(scene: Scene) => Record<string, unknown> | undefined} SceneUpdateDataGetter */
|
||||
|
||||
/**
|
||||
* Migrate world scenes.
|
||||
|
@ -62,10 +64,12 @@ export async function migrateActors(getActorUpdateData) {
|
|||
export async function migrateScenes(getSceneUpdateData) {
|
||||
for (const scene of getGame().scenes ?? []) {
|
||||
try {
|
||||
const updateData = getSceneUpdateData(scene.data);
|
||||
const updateData = getSceneUpdateData(scene);
|
||||
if (updateData) {
|
||||
logger.info(`Migrating Scene document ${scene.name} (${scene.id})`);
|
||||
await scene.update(updateData);
|
||||
// We need to clear the old syntehtic actors from the cache
|
||||
scene.tokens.forEach((t) => (t._actor = null));
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error(
|
||||
|
@ -76,7 +80,7 @@ export async function migrateScenes(getSceneUpdateData) {
|
|||
}
|
||||
}
|
||||
|
||||
/** @typedef {(pack: CompendiumCollection) => Promise<void>} CompendiumMigrator*/
|
||||
/** @typedef {(pack: CompendiumCollection) => Promise<void>} CompendiumMigrator */
|
||||
|
||||
/**
|
||||
* Migrate world compendium packs.
|
||||
|
@ -92,34 +96,70 @@ export async function migrateCompendiums(migrateCompendium) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get a function to create actor update data that adjusts the owned items of the actor according to the given function.
|
||||
* @param {ItemUpdateDataGetter} getItemUpdateData The function to generate item update data
|
||||
* Get a function to create item update data based on the given function to update embedded documents.
|
||||
* @param {EffectUpdateDataGetter} [getEffectUpdateData] A function to generate effect update data
|
||||
* @returns {ItemUpdateDataGetter} A function to get item update data
|
||||
*/
|
||||
export function getItemUpdateDataGetter(getEffectUpdateData) {
|
||||
return (itemData) => {
|
||||
let hasEffectUpdates = false;
|
||||
const effects = itemData.effects?.map((effectData) => {
|
||||
const update = getEffectUpdateData(effectData);
|
||||
if (update) {
|
||||
hasEffectUpdates = true;
|
||||
return foundry.utils.mergeObject(effectData, update, { inplace: false, performDeletions: true });
|
||||
} else {
|
||||
return effectData;
|
||||
}
|
||||
});
|
||||
return hasEffectUpdates ? { effects } : undefined;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a function to create actor update data based on the given function to update embedded documents.
|
||||
* @param {ItemUpdateDataGetter} [getItemUpdateData] A function to generate item update data
|
||||
* @param {EffectUpdateDataGetter} [getEffectUpdateData] A function to generate effect update data
|
||||
* @returns {ActorUpdateDataGetter} A function to get actor update data
|
||||
*/
|
||||
export function getActorUpdateDataGetter(getItemUpdateData) {
|
||||
export function getActorUpdateDataGetter(getItemUpdateData, getEffectUpdateData) {
|
||||
return (actorData) => {
|
||||
let hasItemUpdates = false;
|
||||
const items = actorData.items?.map((itemData) => {
|
||||
const update = getItemUpdateData(itemData);
|
||||
const update = getItemUpdateData?.(itemData);
|
||||
if (update) {
|
||||
hasItemUpdates = true;
|
||||
return { ...itemData, ...update };
|
||||
return foundry.utils.mergeObject(itemData, update, { inplace: false, performDeletions: true });
|
||||
} else {
|
||||
return itemData;
|
||||
}
|
||||
});
|
||||
return hasItemUpdates ? { items } : undefined;
|
||||
let hasEffectUpdates = false;
|
||||
const effects = actorData.effects?.map((effectData) => {
|
||||
const update = getEffectUpdateData?.(effectData);
|
||||
if (update) {
|
||||
hasEffectUpdates = true;
|
||||
return foundry.utils.mergeObject(effectData, update, { inplace: false, performDeletions: true });
|
||||
} else {
|
||||
return effectData;
|
||||
}
|
||||
});
|
||||
const result = {
|
||||
items: hasItemUpdates ? items : undefined,
|
||||
effects: hasEffectUpdates ? effects : undefined,
|
||||
};
|
||||
return hasItemUpdates | hasEffectUpdates ? result : undefined;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a function to create scene update data that adjusts the actors of the tokens of the scene according to the given function.
|
||||
* @param {ActorUpdateDataGetter} getItemUpdateData The function to generate actor update data
|
||||
* @param {ActorUpdateDataGetter} [getItemUpdateData] The function to generate actor update data
|
||||
* @returns {SceneUpdateDataGetter} A function to get scene update data
|
||||
*/
|
||||
export function getSceneUpdateDataGetter(getActorUpdateData) {
|
||||
return (sceneData) => {
|
||||
const tokens = sceneData.tokens.map((token) => {
|
||||
return (scene) => {
|
||||
const tokens = scene.tokens.map((token) => {
|
||||
const t = token.toObject();
|
||||
if (!t.actorId || t.actorLink) {
|
||||
t.actorData = {};
|
||||
|
@ -129,18 +169,18 @@ export function getSceneUpdateDataGetter(getActorUpdateData) {
|
|||
} else if (!t.actorLink) {
|
||||
const actorData = foundry.utils.deepClone(t.actorData);
|
||||
actorData.type = token.actor?.type;
|
||||
const update = getActorUpdateData(actorData);
|
||||
const update = getActorUpdateData?.(actorData);
|
||||
if (update !== undefined) {
|
||||
["items", "effects"].forEach((embeddedName) => {
|
||||
const embeddedUpdates = update[embeddedName];
|
||||
if (embeddedUpdates === undefined || !embeddedUpdates.length) return;
|
||||
if (!embeddedUpdates?.length) return;
|
||||
const updates = new Map(embeddedUpdates.flatMap((u) => (u && u._id ? [[u._id, u]] : [])));
|
||||
const originals = t.actorData[embeddedName];
|
||||
if (!originals) return;
|
||||
originals.forEach((original) => {
|
||||
if (!original._id) return;
|
||||
const update = updates.get(original._id);
|
||||
if (update) foundry.utils.mergeObject(original, update);
|
||||
if (update) foundry.utils.mergeObject(original, update, { performDeletions: true });
|
||||
});
|
||||
delete update[embeddedName];
|
||||
});
|
||||
|
@ -191,7 +231,7 @@ export function getCompendiumMigrator(
|
|||
const updateData = getActorUpdateData(doc.toObject());
|
||||
updateData && (await doc.update(updateData));
|
||||
} else if (doc instanceof Scene && getSceneUpdateData) {
|
||||
const updateData = getSceneUpdateData(doc.data);
|
||||
const updateData = getSceneUpdateData(doc);
|
||||
updateData && (await doc.update(updateData));
|
||||
}
|
||||
} catch (err) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "ds4",
|
||||
"id": "ds4",
|
||||
"title": "Dungeonslayers 4",
|
||||
"description": "An implementation of the <a href='https://www.dungeonslayers.net'>Dungeonslayers</a> 4 game system for Foundry Virtual Tabletop.",
|
||||
"authors": [
|
||||
|
@ -34,8 +34,10 @@
|
|||
"bugs": "https://git.f3l.de/dungeonslayers/ds4/-/issues",
|
||||
"changelog": "https://git.f3l.de/dungeonslayers/ds4/-/releases/v1.18.2",
|
||||
"version": "1.18.2",
|
||||
"minimumCoreVersion": "9.238",
|
||||
"compatibleCoreVersion": "9",
|
||||
"compatibility": {
|
||||
"minimum": "10.290",
|
||||
"verified": "10"
|
||||
},
|
||||
"esmodules": ["ds4.js"],
|
||||
"styles": ["css/ds4.css"],
|
||||
"languages": [
|
||||
|
|
|
@ -8,40 +8,41 @@ SPDX-License-Identifier: MIT
|
|||
|
||||
<div class="ds4-actor-progression">
|
||||
<div class="ds4-actor-progression__entry">
|
||||
<h2 class="ds4-actor-progression__label"><label for="data.combatValues.hitPoints.value-{{data._id}}"
|
||||
<h2 class="ds4-actor-progression__label"><label for="system.combatValues.hitPoints.value-{{data._id}}"
|
||||
title="{{localize 'DS4.CombatValuesHitPointsCurrent'}}">{{localize
|
||||
"DS4.CombatValuesHitPointsCurrentAbbr"}}</label>
|
||||
</h2>
|
||||
<input class="ds4-actor-progression__input" type="number" name="data.combatValues.hitPoints.value"
|
||||
id="data.combatValues.hitPoints.value-{{data._id}}" value="{{data.data.combatValues.hitPoints.value}}"
|
||||
<input class="ds4-actor-progression__input" type="number" name="system.combatValues.hitPoints.value"
|
||||
id="system.combatValues.hitPoints.value-{{data._id}}" value="{{data.system.combatValues.hitPoints.value}}"
|
||||
data-dtype="Number" />
|
||||
</div>
|
||||
{{#if (eq data.type "character")}}
|
||||
{{#if settings.showSlayerPoints}}
|
||||
<div class="ds4-actor-progression__entry">
|
||||
<h2 class="ds4-actor-progression__label"><label for="data.slayersPoints.value-{{data._id}}"
|
||||
<h2 class="ds4-actor-progression__label"><label for="system.slayersPoints.value-{{data._id}}"
|
||||
title="{{localize 'DS4.CharacterSlayerPoints'}}">{{localize "DS4.CharacterSlayerPointsAbbr"}}</label>
|
||||
</h2>
|
||||
<input class="ds4-actor-progression__input ds4-actor-progression__input--slayer-points" type="number"
|
||||
max="{{data.data.slayerPoints.max}}" min="0" step="1" name="data.slayerPoints.value"
|
||||
id="data.slayersPoints.value-{{data._id}}" value="{{data.data.slayerPoints.value}}" data-dtype="Number" />
|
||||
max="{{data.system.slayerPoints.max}}" min="0" step="1" name="system.slayerPoints.value"
|
||||
id="system.slayersPoints.value-{{data._id}}" value="{{data.system.slayerPoints.value}}"
|
||||
data-dtype="Number" />
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="ds4-actor-progression__entry">
|
||||
<h2 class="ds4-actor-progression__label"><label for="data.progression.level-{{data._id}}"
|
||||
<h2 class="ds4-actor-progression__label"><label for="system.progression.level-{{data._id}}"
|
||||
title="{{localize 'DS4.CharacterProgressionLevel'}}">{{localize
|
||||
"DS4.CharacterProgressionLevelAbbr"}}</label>
|
||||
</h2>
|
||||
<input class="ds4-actor-progression__input" type="number" min="0" name="data.progression.level"
|
||||
id="data.progression.level-{{data._id}}" value="{{data.data.progression.level}}" data-dtype="Number" />
|
||||
<input class="ds4-actor-progression__input" type="number" min="0" name="system.progression.level"
|
||||
id="system.progression.level-{{data._id}}" value="{{data.system.progression.level}}" data-dtype="Number" />
|
||||
</div>
|
||||
<div class="ds4-actor-progression__entry">
|
||||
<h2 class="ds4-actor-progression__label"><label for="data.progression.experiencePoints-{{data._id}}"
|
||||
<h2 class="ds4-actor-progression__label"><label for="system.progression.experiencePoints-{{data._id}}"
|
||||
title="{{localize 'DS4.CharacterProgressionExperiencePoints'}}">{{localize
|
||||
"DS4.CharacterProgressionExperiencePointsAbbr"}}</label>
|
||||
</h2>
|
||||
<input class="ds4-actor-progression__input" type="number" min="0" name="data.progression.experiencePoints"
|
||||
id="data.progression.experiencePoints-{{data._id}}" value="{{data.data.progression.experiencePoints}}"
|
||||
<input class="ds4-actor-progression__input" type="number" min="0" name="system.progression.experiencePoints"
|
||||
id="system.progression.experiencePoints-{{data._id}}" value="{{data.system.progression.experiencePoints}}"
|
||||
data-dtype="Number" />
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -5,6 +5,6 @@ SPDX-License-Identifier: MIT
|
|||
--}}
|
||||
|
||||
<div class="ds4-biography">
|
||||
{{editor content=data.data.profile.biography target="data.profile.biography" button=true owner=owner
|
||||
editable=editable}}
|
||||
{{editor data.system.profile.biography target="system.profile.biography" button=true owner=owner
|
||||
editable=editable engine="prosemirror"}}
|
||||
</div>
|
||||
|
|
|
@ -9,55 +9,56 @@ SPDX-License-Identifier: MIT
|
|||
<div class="ds4-actor-properties">
|
||||
<div class="ds4-actor-properties__property">
|
||||
<label class="ds4-actor-properties__property-label"
|
||||
for="data.baseInfo.race-{{data._id}}">{{config.i18n.characterBaseInfo.race}}</label>
|
||||
<input type="text" name="data.baseInfo.race" id="data.baseInfo.race-{{data._id}}"
|
||||
value="{{data.data.baseInfo.race}}" data-dtype="String" />
|
||||
for="system.baseInfo.race-{{data._id}}">{{config.i18n.characterBaseInfo.race}}</label>
|
||||
<input type="text" name="system.baseInfo.race" id="system.baseInfo.race-{{data._id}}"
|
||||
value="{{data.system.baseInfo.race}}" data-dtype="String" />
|
||||
</div>
|
||||
<div class="ds4-actor-properties__property">
|
||||
<label class="ds4-actor-properties__property-label"
|
||||
for="data.baseInfo.culture-{{data._id}}">{{config.i18n.characterBaseInfo.culture}}</label>
|
||||
<input id="data.baseInfo.culture-{{data._id}}" type="text" name="data.baseInfo.culture"
|
||||
value="{{data.data.baseInfo.culture}}" data-dtype="String" />
|
||||
for="system.baseInfo.culture-{{data._id}}">{{config.i18n.characterBaseInfo.culture}}</label>
|
||||
<input id="system.baseInfo.culture-{{data._id}}" type="text" name="system.baseInfo.culture"
|
||||
value="{{data.system.baseInfo.culture}}" data-dtype="String" />
|
||||
</div>
|
||||
<div class="ds4-actor-properties__property">
|
||||
<label class="ds4-actor-properties__property-label"
|
||||
for="data.progression.progressPoints.used-{{data._id}}">{{config.i18n.characterProgression.progressPoints}}</label>
|
||||
for="system.progression.progressPoints.used-{{data._id}}">{{config.i18n.characterProgression.progressPoints}}</label>
|
||||
<div class="ds4-actor-properties__property-multi-input">
|
||||
<input id="data.progression.progressPoints.used-{{data._id}}" type="number"
|
||||
name="data.progression.progressPoints.used" value="{{data.data.progression.progressPoints.used}}"
|
||||
<input id="system.progression.progressPoints.used-{{data._id}}" type="number"
|
||||
name="system.progression.progressPoints.used" value="{{data.system.progression.progressPoints.used}}"
|
||||
data-dtype="Number" />
|
||||
<span class="input-divider"> / </span>
|
||||
<label class="ds4-hidden" for="data.progression.progressPoints.total-{{data._id}}">Total
|
||||
<label class="ds4-hidden" for="system.progression.progressPoints.total-{{data._id}}">Total
|
||||
Progression Points</label>
|
||||
<input type="number" id="data.progression.progressPoints.total-{{data._id}}"
|
||||
name="data.progression.progressPoints.total" value="{{data.data.progression.progressPoints.total}}"
|
||||
<input type="number" id="system.progression.progressPoints.total-{{data._id}}"
|
||||
name="system.progression.progressPoints.total" value="{{data.system.progression.progressPoints.total}}"
|
||||
data-dtype="Number" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="ds4-actor-properties__property">
|
||||
<label class="ds4-actor-properties__property-label"
|
||||
for="data.progression.talentPoints.used-{{data._id}}">{{config.i18n.characterProgression.talentPoints}}</label>
|
||||
for="system.progression.talentPoints.used-{{data._id}}">{{config.i18n.characterProgression.talentPoints}}</label>
|
||||
<div class="ds4-actor-properties__property-multi-input">
|
||||
<input type="number" name="data.progression.talentPoints.used"
|
||||
id="data.progression.talentPoints.used-{{data._id}}" value="{{data.data.progression.talentPoints.used}}"
|
||||
data-dtype="Number" />
|
||||
<input type="number" name="system.progression.talentPoints.used"
|
||||
id="system.progression.talentPoints.used-{{data._id}}"
|
||||
value="{{data.system.progression.talentPoints.used}}" data-dtype="Number" />
|
||||
<span class="input-divider"> / </span>
|
||||
<label for="data.progression.talentPoints.total-{{data._id}}" class="ds4-hidden">Total Talent Points</label>
|
||||
<input type="number" name="data.progression.talentPoints.total"
|
||||
id="data.progression.talentPoints.total-{{data._id}}"
|
||||
value="{{data.data.progression.talentPoints.total}}" data-dtype="Number" />
|
||||
<label for="system.progression.talentPoints.total-{{data._id}}" class="ds4-hidden">Total Talent
|
||||
Points</label>
|
||||
<input type="number" name="system.progression.talentPoints.total"
|
||||
id="system.progression.talentPoints.total-{{data._id}}"
|
||||
value="{{data.system.progression.talentPoints.total}}" data-dtype="Number" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="ds4-actor-properties__property">
|
||||
<label class="ds4-actor-properties__property-label"
|
||||
for="data.baseInfo.class-{{data._id}}">{{config.i18n.characterBaseInfo.class}}</label>
|
||||
<input type="text" id="data.baseInfo.class-{{data._id}}" name="data.baseInfo.class"
|
||||
value="{{data.data.baseInfo.class}}" data-dtype="String" />
|
||||
for="system.baseInfo.class-{{data._id}}">{{config.i18n.characterBaseInfo.class}}</label>
|
||||
<input type="text" id="system.baseInfo.class-{{data._id}}" name="system.baseInfo.class"
|
||||
value="{{data.system.baseInfo.class}}" data-dtype="String" />
|
||||
</div>
|
||||
<div class="ds4-actor-properties__property">
|
||||
<label class="ds4-actor-properties__property-label"
|
||||
for="data.baseInfo.heroClass-{{data._id}}">{{config.i18n.characterBaseInfo.heroClass}}</label>
|
||||
<input type="text" id="data.baseInfo.heroClass-{{data._id}}" name="data.baseInfo.heroClass"
|
||||
value="{{data.data.baseInfo.heroClass}}" data-dtype="String" />
|
||||
for="system.baseInfo.heroClass-{{data._id}}">{{config.i18n.characterBaseInfo.heroClass}}</label>
|
||||
<input type="text" id="system.baseInfo.heroClass-{{data._id}}" name="system.baseInfo.heroClass"
|
||||
value="{{data.system.baseInfo.heroClass}}" data-dtype="String" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,6 +7,6 @@ SPDX-License-Identifier: MIT
|
|||
<div class="ds4-checks">
|
||||
{{#each config.i18n.checks as |check-label check-key|}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/check.hbs check-key=check-key check-target-number=(lookup
|
||||
../data.data.checks check-key) check-label=check-label}}
|
||||
../data.system.checks check-key) check-label=check-label}}
|
||||
{{/each}}
|
||||
</div>
|
||||
|
|
|
@ -25,8 +25,8 @@ SPDX-License-Identifier: MIT
|
|||
title="{{combat-value-title}} {{localize 'DS4.TooltipBaseValue'}}">{{combat-value-data.base}}</span>
|
||||
<span>+</span>
|
||||
<input class="ds4-combat-value__formula-modifier" type="number"
|
||||
id="data.combatValues.{{combat-value-key}}.mod-{{actor-id}}"
|
||||
name="data.combatValues.{{combat-value-key}}.mod" value='{{combat-value-data.mod}}' data-dtype="Number"
|
||||
id="system.combatValues.{{combat-value-key}}.mod-{{actor-id}}"
|
||||
name="system.combatValues.{{combat-value-key}}.mod" value='{{combat-value-data.mod}}' data-dtype="Number"
|
||||
title="{{combat-value-title}} {{localize 'DS4.TooltipModifier'}}" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -8,7 +8,7 @@ SPDX-License-Identifier: MIT
|
|||
<div class="ds4-combat-values">
|
||||
{{#each config.i18n.combatValues as |combat-value-title combat-value-key|}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/combat-value.hbs combat-value-key=combat-value-key
|
||||
combat-value-data=(lookup ../data.data.combatValues combat-value-key) combat-value-label=(lookup
|
||||
combat-value-data=(lookup ../data.system.combatValues combat-value-key) combat-value-label=(lookup
|
||||
../config.i18n.combatValuesSheet combat-value-key) combat-value-title=combat-value-title
|
||||
actor-id=../data._id}}
|
||||
{{/each}}
|
||||
|
|
|
@ -15,17 +15,17 @@ SPDX-License-Identifier: MIT
|
|||
--}}
|
||||
|
||||
<div class="ds4-core-value ds4-core-value--{{core-value-variant}}">
|
||||
<label for="data.{{core-value-variant}}s.{{core-value-key}}.base-{{actor-id}}"
|
||||
<label for="system.{{core-value-variant}}s.{{core-value-key}}.base-{{actor-id}}"
|
||||
class="ds4-core-value__label">{{core-value-label}}</label>
|
||||
<div class="ds4-core-value__value">
|
||||
<input class="ds4-core-value__value-input" type="number"
|
||||
name="data.{{core-value-variant}}s.{{core-value-key}}.base"
|
||||
id="data.{{core-value-variant}}s.{{core-value-key}}.base-{{actor-id}}" value='{{core-value-data.base}}'
|
||||
name="system.{{core-value-variant}}s.{{core-value-key}}.base"
|
||||
id="system.{{core-value-variant}}s.{{core-value-key}}.base-{{actor-id}}" value='{{core-value-data.base}}'
|
||||
data-dtype="Number" title="{{core-value-label}} {{localize 'DS4.TooltipBaseValue'}}" />
|
||||
<span>+</span>
|
||||
<input class="ds4-core-value__value-input" type="number"
|
||||
name="data.{{core-value-variant}}s.{{core-value-key}}.mod"
|
||||
id="data.{{core-value-variant}}s.{{core-value-key}}.mod-{{actor-id}}" value='{{core-value-data.mod}}'
|
||||
name="system.{{core-value-variant}}s.{{core-value-key}}.mod"
|
||||
id="system.{{core-value-variant}}s.{{core-value-key}}.mod-{{actor-id}}" value='{{core-value-data.mod}}'
|
||||
data-dtype="Number" title="{{core-value-label}} {{localize 'DS4.TooltipModifier'}}" />
|
||||
<span class="ds4-core-value__value-arrow">➞</span>
|
||||
<span class="ds4-core-value__value-total"
|
||||
|
|
|
@ -8,12 +8,12 @@ SPDX-License-Identifier: MIT
|
|||
<div class="ds4-core-values">
|
||||
{{#each config.i18n.attributes as |attribute-label attribute-key|}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/core-value.hbs core-value-label=attribute-label
|
||||
core-value-key=attribute-key core-value-data=(lookup ../data.data.attributes
|
||||
core-value-key=attribute-key core-value-data=(lookup ../data.system.attributes
|
||||
attribute-key) core-value-variant="attribute" actor-id=../data._id}}
|
||||
{{/each}}
|
||||
{{#each config.i18n.traits as |trait-label trait-key|}}
|
||||
{{> systems/ds4/templates/sheets/actor/components/core-value.hbs core-value-label=trait-label
|
||||
core-value-key=trait-key
|
||||
core-value-data=(lookup ../data.data.traits trait-key) core-value-variant="trait" actor-id=../data._id}}
|
||||
core-value-data=(lookup ../data.system.traits trait-key) core-value-variant="trait" actor-id=../data._id}}
|
||||
{{/each}}
|
||||
</div>
|
||||
|
|
|
@ -9,10 +9,10 @@ SPDX-License-Identifier: MIT
|
|||
<div class="ds4-actor-properties">
|
||||
<div class="ds4-actor-properties__property">
|
||||
<label class="ds4-actor-properties__property-label"
|
||||
for="data.baseInfo.creatureType-{{data._id}}">{{config.i18n.creatureBaseInfo.creatureType}}</label>
|
||||
<select class="ds4-actor-properties__property-select" id="data.baseInfo.creatureType-{{data._id}}"
|
||||
name="data.baseInfo.creatureType" data-dtype="String">
|
||||
{{#select data.data.baseInfo.creatureType}}
|
||||
for="system.baseInfo.creatureType-{{data._id}}">{{config.i18n.creatureBaseInfo.creatureType}}</label>
|
||||
<select class="ds4-actor-properties__property-select" id="system.baseInfo.creatureType-{{data._id}}"
|
||||
name="system.baseInfo.creatureType" data-dtype="String">
|
||||
{{#select data.system.baseInfo.creatureType}}
|
||||
{{#each config.i18n.creatureTypes as |value key|}}
|
||||
<option value="{{key}}">{{value}}</option>
|
||||
{{/each}}
|
||||
|
@ -21,22 +21,22 @@ SPDX-License-Identifier: MIT
|
|||
</div>
|
||||
<div class="ds4-actor-properties__property">
|
||||
<label class="ds4-actor-properties__property-label"
|
||||
for="data.baseInfo.loot-{{data._id}}">{{config.i18n.creatureBaseInfo.loot}}</label>
|
||||
<input type="text" id="data.baseInfo.loot-{{data._id}}" name="data.baseInfo.loot"
|
||||
value="{{data.data.baseInfo.loot}}" data-dtype="String" />
|
||||
for="system.baseInfo.loot-{{data._id}}">{{config.i18n.creatureBaseInfo.loot}}</label>
|
||||
<input type="text" id="system.baseInfo.loot-{{data._id}}" name="system.baseInfo.loot"
|
||||
value="{{data.system.baseInfo.loot}}" data-dtype="String" />
|
||||
</div>
|
||||
<div class="ds4-actor-properties__property">
|
||||
<label class="ds4-actor-properties__property-label"
|
||||
for="data.baseInfo.foeFactor-{{data._id}}">{{config.i18n.creatureBaseInfo.foeFactor}}</label>
|
||||
<input type="text" id="data.baseInfo.foeFactor-{{data._id}}" name="data.baseInfo.foeFactor"
|
||||
value="{{data.data.baseInfo.foeFactor}}" data-dtype="Number" />
|
||||
for="system.baseInfo.foeFactor-{{data._id}}">{{config.i18n.creatureBaseInfo.foeFactor}}</label>
|
||||
<input type="text" id="system.baseInfo.foeFactor-{{data._id}}" name="system.baseInfo.foeFactor"
|
||||
value="{{data.system.baseInfo.foeFactor}}" data-dtype="Number" />
|
||||
</div>
|
||||
<div class="ds4-actor-properties__property">
|
||||
<label class="ds4-actor-properties__property-label"
|
||||
for="data.baseInfo.sizeCategory-{{data._id}}">{{config.i18n.creatureBaseInfo.sizeCategory}}</label>
|
||||
<select class="ds4-actor-properties__property-select" id="data.baseInfo.sizeCategory-{{data._id}}"
|
||||
name="data.baseInfo.sizeCategory" data-dtype="String">
|
||||
{{#select data.data.baseInfo.sizeCategory}}
|
||||
for="system.baseInfo.sizeCategory-{{data._id}}">{{config.i18n.creatureBaseInfo.sizeCategory}}</label>
|
||||
<select class="ds4-actor-properties__property-select" id="system.baseInfo.sizeCategory-{{data._id}}"
|
||||
name="system.baseInfo.sizeCategory" data-dtype="String">
|
||||
{{#select data.system.baseInfo.sizeCategory}}
|
||||
{{#each config.i18n.creatureSizeCategories as |value key|}}
|
||||
<option value="{{key}}">{{value}}</option>
|
||||
{{/each}}
|
||||
|
@ -45,8 +45,8 @@ SPDX-License-Identifier: MIT
|
|||
</div>
|
||||
<div class="ds4-actor-properties__property">
|
||||
<label class="ds4-actor-properties__property-label"
|
||||
for="data.baseInfo.experiencePoints-{{data._id}}">{{config.i18n.creatureBaseInfo.experiencePoints}}</label>
|
||||
<input type="text" id="data.baseInfo.experiencePoints-{{data._id}}" name="data.baseInfo.experiencePoints"
|
||||
value="{{data.data.baseInfo.experiencePoints}}" data-dtype="Number" />
|
||||
for="system.baseInfo.experiencePoints-{{data._id}}">{{config.i18n.creatureBaseInfo.experiencePoints}}</label>
|
||||
<input type="text" id="system.baseInfo.experiencePoints-{{data._id}}" name="system.baseInfo.experiencePoints"
|
||||
value="{{data.system.baseInfo.experiencePoints}}" data-dtype="Number" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -8,9 +8,9 @@ SPDX-License-Identifier: MIT
|
|||
|
||||
<h4 class="ds4-currency-title">{{localize 'DS4.CharacterCurrency'}}</h4>
|
||||
<div class="ds4-currency">
|
||||
{{#each data.data.currency as |value key|}}
|
||||
<label for="data.currency.{{key}}" class="flex05">{{lookup ../config.i18n.characterCurrency key}}</label>
|
||||
{{#each data.system.currency as |value key|}}
|
||||
<label for="system.currency.{{key}}" class="flex05">{{lookup ../config.i18n.characterCurrency key}}</label>
|
||||
<input class="ds4-currency__value ds4-currency__value--{{key}}" type="number" min="0" step="1"
|
||||
name="data.currency.{{key}}" id="data.currency.{{key}}" value="{{value}}" data-dtype="Number" />
|
||||
name="system.currency.{{key}}" id="system.currency.{{key}}" value="{{value}}" data-dtype="Number" />
|
||||
{{/each}}
|
||||
</div>
|
||||
|
|
|
@ -5,6 +5,6 @@ SPDX-License-Identifier: MIT
|
|||
--}}
|
||||
|
||||
<div class="ds4-description">
|
||||
{{editor content=data.data.baseInfo.description target="data.baseInfo.description" button=true owner=owner
|
||||
editable=editable}}
|
||||
{{editor data.system.baseInfo.description target="system.baseInfo.description" button=true owner=owner
|
||||
editable=editable engine="prosemirror"}}
|
||||
</div>
|
||||
|
|
|
@ -19,24 +19,24 @@ SPDX-License-Identifier: MIT
|
|||
{{!-- equipped --}}
|
||||
{{#if isEquipable}}
|
||||
<input class="ds4-embedded-document-list__editable ds4-embedded-document-list__editable--checkbox change-item" type="checkbox" {{checked
|
||||
itemData.data.equipped}} data-dtype="Boolean" data-property="data.equipped"
|
||||
itemData.system.equipped}} data-dtype="Boolean" data-property="system.equipped"
|
||||
title="{{localize 'DS4.ItemEquipped'}}">
|
||||
{{/if}}
|
||||
|
||||
{{!-- image --}}
|
||||
{{> systems/ds4/templates/sheets/shared/components/rollable-image.hbs rollable=(and itemData.data.rollable @root/editable)
|
||||
{{> systems/ds4/templates/sheets/shared/components/rollable-image.hbs rollable=(and itemData.system.rollable @root/editable)
|
||||
src=itemData.img alt=(localize "DS4.DocumentImageAltText" name=itemData.name) title=itemData.name
|
||||
rollableTitle=(localize "DS4.RollableImageRollableTitle" name=itemData.name) rollableClass="rollable-item"}}
|
||||
|
||||
{{!-- amount --}}
|
||||
{{#if hasQuantity}}
|
||||
<input class="ds4-embedded-document-list__editable change-item" type="number" min="0" step="1" value="{{itemData.data.quantity}}"
|
||||
data-dtype="Number" data-property="data.quantity" title="{{localize 'DS4.Quantity'}}" />
|
||||
<input class="ds4-embedded-document-list__editable change-item" type="number" min="0" step="1" value="{{itemData.system.quantity}}"
|
||||
data-dtype="Number" data-property="system.quantity" title="{{localize 'DS4.Quantity'}}" />
|
||||
{{/if}}
|
||||
|
||||
{{!-- name --}}
|
||||
<input class="ds4-embedded-document-list__editable change-item" type="text" value="{{itemData.name}}" data-dtype="String"
|
||||
data-property="name" title="{{htmlToPlainText itemData.data.description}}" />
|
||||
data-property="name" title="{{htmlToPlainText itemData.system.description}}" />
|
||||
|
||||
{{!-- item type specifics --}}
|
||||
{{#if @partial-block }}
|
||||
|
@ -45,8 +45,8 @@ SPDX-License-Identifier: MIT
|
|||
|
||||
{{!-- description --}}
|
||||
{{#unless hideDescription}}
|
||||
<div class="ds4-embedded-document-list__description" title="{{htmlToPlainText itemData.data.description}}">
|
||||
{{{itemData.data.description}}}</div>
|
||||
<div class="ds4-embedded-document-list__description" title="{{htmlToPlainText itemData.system.description}}">
|
||||
{{{itemData.system.description}}}</div>
|
||||
{{/unless}}
|
||||
|
||||
{{!-- control button group --}}
|
||||
|
|
|
@ -18,7 +18,7 @@ SPDX-License-Identifier: MIT
|
|||
<li class="ds4-embedded-document-list__row ds4-embedded-document-list__row--header" data-type={{type}}>
|
||||
{{!-- equipped --}}
|
||||
{{#if isEquipable}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="data.equipped"
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.equipped"
|
||||
title="{{localize 'DS4.SortByItemEquipped'}}">
|
||||
{{localize 'DS4.ItemEquippedAbbr'}}</div>
|
||||
{{/if}}
|
||||
|
@ -28,7 +28,7 @@ SPDX-License-Identifier: MIT
|
|||
|
||||
{{!-- amount --}}
|
||||
{{#if hasQuantity}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="data.quantity"
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.quantity"
|
||||
title="{{localize 'DS4.SortByQuantity'}}">#</div>
|
||||
{{/if}}
|
||||
|
||||
|
@ -44,7 +44,7 @@ SPDX-License-Identifier: MIT
|
|||
|
||||
{{!-- description --}}
|
||||
{{#unless hideDescription}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="data.description"
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.description"
|
||||
title="{{localize 'DS4.SortByDescription'}}">{{localize
|
||||
'DS4.Description'}}</div>
|
||||
{{/unless}}
|
||||
|
|
|
@ -13,19 +13,19 @@ SPDX-License-Identifier: MIT
|
|||
{{#> systems/ds4/templates/sheets/actor/components/item-list-header.hbs isEquipable=true hasQuantity=true
|
||||
type='weapon'}}
|
||||
{{!-- attack type --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="data.attackType"
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.attackType"
|
||||
title="{{localize 'DS4.SortByAttackType'}}">
|
||||
{{localize
|
||||
'DS4.AttackTypeAbbr'}}</div>
|
||||
|
||||
{{!-- weapon bonus --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="data.weaponBonus"
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.weaponBonus"
|
||||
title="{{localize 'DS4.SortByWeaponBonus'}}">
|
||||
{{localize 'DS4.WeaponBonusAbbr'}}
|
||||
</div>
|
||||
|
||||
{{!-- opponent defense --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="data.opponentDefense"
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.opponentDefense"
|
||||
title="{{localize 'DS4.SortByOpponentDefense'}}">
|
||||
{{localize 'DS4.OpponentDefenseAbbr'}}
|
||||
</div>
|
||||
|
@ -36,24 +36,24 @@ SPDX-License-Identifier: MIT
|
|||
hasQuantity=true}}
|
||||
{{!-- attack type --}}
|
||||
<img class="ds4-embedded-document-list__image"
|
||||
src="{{lookup @root/config.icons.attackTypes itemData.data.attackType}}"
|
||||
title="{{lookup @root/config.i18n.attackTypes itemData.data.attackType}}" />
|
||||
src="{{lookup @root/config.icons.attackTypes itemData.system.attackType}}"
|
||||
title="{{lookup @root/config.i18n.attackTypes itemData.system.attackType}}" />
|
||||
|
||||
{{!-- weapon bonus --}}
|
||||
<div>{{ itemData.data.weaponBonus}}</div>
|
||||
<div>{{ itemData.system.weaponBonus}}</div>
|
||||
|
||||
{{!-- opponent defense --}}
|
||||
<div>
|
||||
{{#if itemData.data.opponentDefenseForAttackType.melee includeZero=true}}
|
||||
{{#if itemData.data.opponentDefenseForAttackType.ranged includeZero=true}}
|
||||
{{#if itemData.system.opponentDefenseForAttackType.melee includeZero=true}}
|
||||
{{#if itemData.system.opponentDefenseForAttackType.ranged includeZero=true}}
|
||||
<span
|
||||
title="{{localize 'DS4.OpponentDefenseMelee'}}">{{itemData.data.opponentDefenseForAttackType.melee}}</span>/<span
|
||||
title="{{localize 'DS4.OpponentDefenseRanged'}}">{{itemData.data.opponentDefenseForAttackType.ranged}}</span>
|
||||
title="{{localize 'DS4.OpponentDefenseMelee'}}">{{itemData.system.opponentDefenseForAttackType.melee}}</span>/<span
|
||||
title="{{localize 'DS4.OpponentDefenseRanged'}}">{{itemData.system.opponentDefenseForAttackType.ranged}}</span>
|
||||
{{else}}
|
||||
{{itemData.data.opponentDefenseForAttackType.melee}}
|
||||
{{itemData.system.opponentDefenseForAttackType.melee}}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
{{itemData.data.opponentDefenseForAttackType.ranged}}
|
||||
{{itemData.system.opponentDefenseForAttackType.ranged}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/systems/ds4/templates/sheets/actor/components/item-list-entry.hbs}}
|
||||
|
@ -70,15 +70,15 @@ documentType='item' type='weapon'}}
|
|||
{{#> systems/ds4/templates/sheets/actor/components/item-list-header.hbs isEquipable=true hasQuantity=true
|
||||
type="armor"}}
|
||||
{{!-- armor material type --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="data.armorMaterialType"
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.armorMaterialType"
|
||||
title="{{localize 'DS4.SortByArmorMaterialType'}}">{{localize 'DS4.ArmorMaterialTypeAbbr'}}</div>
|
||||
|
||||
{{!-- armor type --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="data.armorType"
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.armorType"
|
||||
title="{{localize 'DS4.SortByArmorType'}}">{{localize 'DS4.ArmorTypeAbbr'}}</div>
|
||||
|
||||
{{!-- armor value --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="data.armorValue"
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.armorValue"
|
||||
title="{{localize 'DS4.SortByArmorValue'}}">
|
||||
{{localize 'DS4.ArmorValueAbbr'}}
|
||||
</div>
|
||||
|
@ -88,17 +88,17 @@ documentType='item' type='weapon'}}
|
|||
{{#> systems/ds4/templates/sheets/actor/components/item-list-entry.hbs itemData=itemData isEquipable=true
|
||||
hasQuantity=true}}
|
||||
{{!-- armor material type --}}
|
||||
<div title="{{lookup @root/config.i18n.armorMaterialTypes itemData.data.armorMaterialType}}">
|
||||
{{lookup @root/config.i18n.armorMaterialTypesAbbr itemData.data.armorMaterialType}}
|
||||
<div title="{{lookup @root/config.i18n.armorMaterialTypes itemData.system.armorMaterialType}}">
|
||||
{{lookup @root/config.i18n.armorMaterialTypesAbbr itemData.system.armorMaterialType}}
|
||||
</div>
|
||||
|
||||
{{!-- armor type --}}
|
||||
<div title="{{lookup @root/config.i18n.armorTypes itemData.data.armorType}}">
|
||||
{{lookup @root/config.i18n.armorTypesAbbr itemData.data.armorType}}
|
||||
<div title="{{lookup @root/config.i18n.armorTypes itemData.system.armorType}}">
|
||||
{{lookup @root/config.i18n.armorTypesAbbr itemData.system.armorType}}
|
||||
</div>
|
||||
|
||||
{{!-- armor value --}}
|
||||
<div>{{ itemData.data.armorValue}}</div>
|
||||
<div>{{ itemData.system.armorValue}}</div>
|
||||
{{/systems/ds4/templates/sheets/actor/components/item-list-entry.hbs}}
|
||||
{{/each}}
|
||||
</ol>
|
||||
|
@ -113,7 +113,7 @@ documentType='item' type='armor'}}
|
|||
{{#> systems/ds4/templates/sheets/actor/components/item-list-header.hbs isEquipable=true hasQuantity=true
|
||||
type='shield'}}
|
||||
{{!-- armor value --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="data.armorValue"
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.armorValue"
|
||||
title="{{localize 'DS4.SortByArmorValue'}}">
|
||||
{{localize 'DS4.ArmorValueAbbr'}}
|
||||
</div>
|
||||
|
@ -122,7 +122,7 @@ documentType='item' type='armor'}}
|
|||
{{#> systems/ds4/templates/sheets/actor/components/item-list-entry.hbs itemData=itemData isEquipable=true
|
||||
hasQuantity=true}}
|
||||
{{!-- armor value --}}
|
||||
<div>{{itemData.data.armorValue}}</div>
|
||||
<div>{{itemData.system.armorValue}}</div>
|
||||
{{/systems/ds4/templates/sheets/actor/components/item-list-entry.hbs}}
|
||||
{{/each}}
|
||||
</ol>
|
||||
|
@ -137,7 +137,7 @@ documentType='item' type='shield'}}
|
|||
{{#> systems/ds4/templates/sheets/actor/components/item-list-header.hbs isEquipable=true hasQuantity=true
|
||||
type='equipment'}}
|
||||
{{!-- storage location --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="data.storageLocation"
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.storageLocation"
|
||||
title="{{localize 'DS4.SortByStorageLocation'}}">{{localize 'DS4.StorageLocation'}}</div>
|
||||
{{/systems/ds4/templates/sheets/actor/components/item-list-header.hbs}}
|
||||
{{#each itemsByType.equipment as |itemData id|}}
|
||||
|
@ -145,7 +145,7 @@ documentType='item' type='shield'}}
|
|||
hasQuantity=true}}
|
||||
{{!-- storage location --}}
|
||||
<input class="ds4-embedded-document-list__editable change-item" type="text"
|
||||
value="{{itemData.data.storageLocation}}" data-dtype="String" data-property="data.storageLocation"
|
||||
value="{{itemData.system.storageLocation}}" data-dtype="String" data-property="system.storageLocation"
|
||||
title="{{localize 'DS4.StorageLocation'}}">
|
||||
{{/systems/ds4/templates/sheets/actor/components/item-list-entry.hbs}}
|
||||
{{/each}}
|
||||
|
@ -160,14 +160,14 @@ documentType='item' type='equipment'}}
|
|||
<ol class="ds4-embedded-document-list ds4-embedded-document-list--loot item-list">
|
||||
{{#> systems/ds4/templates/sheets/actor/components/item-list-header.hbs hasQuantity=true type='loot'}}
|
||||
{{!-- storage location --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="data.storageLocation"
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.storageLocation"
|
||||
title="{{localize 'DS4.SortByStorageLocation'}}">{{localize 'DS4.StorageLocation'}}</div>
|
||||
{{/systems/ds4/templates/sheets/actor/components/item-list-header.hbs}}
|
||||
{{#each itemsByType.loot as |itemData id|}}
|
||||
{{#> systems/ds4/templates/sheets/actor/components/item-list-entry.hbs itemData=itemData hasQuantity=true}}
|
||||
{{!-- storage location --}}
|
||||
<input class="ds4-embedded-document-list__editable change-item" type="text"
|
||||
value="{{itemData.data.storageLocation}}" data-dtype="String" data-property="data.storageLocation"
|
||||
value="{{itemData.system.storageLocation}}" data-dtype="String" data-property="system.storageLocation"
|
||||
title="{{localize 'DS4.StorageLocation'}}">
|
||||
{{/systems/ds4/templates/sheets/actor/components/item-list-entry.hbs}}
|
||||
{{/each}}
|
||||
|
|
|
@ -6,24 +6,24 @@ SPDX-License-Identifier: MIT
|
|||
--}}
|
||||
|
||||
<div class="ds4-profile">
|
||||
{{#each data.data.profile as |profile-data-value profile-data-key|}}
|
||||
{{#each data.system.profile as |profile-data-value profile-data-key|}}
|
||||
{{#if (and (ne profile-data-key 'biography') (ne profile-data-key 'specialCharacteristics'))}}
|
||||
<div class="ds4-profile__entry">
|
||||
<label class="ds4-profile__entry-label" for="data.profile.{{profile-data-key}}">
|
||||
<label class="ds4-profile__entry-label" for="system.profile.{{profile-data-key}}">
|
||||
{{lookup ../config.i18n.characterProfile profile-data-key}}
|
||||
</label>
|
||||
<input class="ds4-profile__entry-input" type="text" name="data.profile.{{profile-data-key}}"
|
||||
<input class="ds4-profile__entry-input" type="text" name="system.profile.{{profile-data-key}}"
|
||||
value="{{profile-data-value}}"
|
||||
data-dtype="{{lookup ../config.i18n.characterProfileDTypes profile-data-key}}" />
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
<div class="ds4-profile__entry">
|
||||
<label class="ds4-profile__entry-label" for="data.profile.specialCharacteristics">
|
||||
<label class="ds4-profile__entry-label" for="system.profile.specialCharacteristics">
|
||||
{{lookup config.i18n.characterProfile 'specialCharacteristics'}}
|
||||
</label>
|
||||
<textarea class="ds4-profile__entry-input ds4-profile__entry-input--multiline"
|
||||
name="data.profile.specialCharacteristics" data-dtype="String"
|
||||
rows="4">{{data.data.profile.specialCharacteristics}}</textarea>
|
||||
name="system.profile.specialCharacteristics" data-dtype="String"
|
||||
rows="4">{{data.system.profile.specialCharacteristics}}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -12,13 +12,13 @@ SPDX-License-Identifier: MIT
|
|||
<ol class="ds4-embedded-document-list ds4-embedded-document-list--talent item-list">
|
||||
{{#> systems/ds4/templates/sheets/actor/components/item-list-header.hbs type='talent'}}
|
||||
{{!-- rank --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="data.rank.total"
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.rank.total"
|
||||
title="{{localize 'DS4.SortByTalentRank'}}">{{localize 'DS4.TalentRank'}}</div>
|
||||
{{/systems/ds4/templates/sheets/actor/components/item-list-header.hbs}}
|
||||
{{#each itemsByType.talent as |itemData id|}}
|
||||
{{#> systems/ds4/templates/sheets/actor/components/item-list-entry.hbs itemData=itemData}}
|
||||
{{!-- rank --}}
|
||||
<div>{{toRomanNumerals itemData.data.rank.total}}</div>
|
||||
<div>{{toRomanNumerals itemData.system.rank.total}}</div>
|
||||
{{/systems/ds4/templates/sheets/actor/components/item-list-entry.hbs}}
|
||||
{{/each}}
|
||||
</ol>
|
||||
|
|
|
@ -50,12 +50,12 @@ titleKey=titleKey}}
|
|||
{{#> systems/ds4/templates/sheets/actor/components/item-list-header.hbs isEquipable=true hideDescription=true
|
||||
type='spell'}}
|
||||
{{!-- spell type --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="data.spellType"
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.spellType"
|
||||
title="{{localize 'DS4.SortBySpellType'}}">{{localize 'DS4.SpellTypeAbbr'}}</div>
|
||||
|
||||
{{!-- spell modifier --}}
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="data.spellModifier.complex"
|
||||
data-data-path2="data.spellModifier.numerical" title="{{localize 'DS4.SortBySpellModifier'}}">{{localize
|
||||
<div class="ds4-embedded-document-list__clickable sort-items" data-data-path="system.spellModifier.complex"
|
||||
data-data-path2="system.spellModifier.numerical" title="{{localize 'DS4.SortBySpellModifier'}}">{{localize
|
||||
'DS4.SpellModifierAbbr'}}</div>
|
||||
|
||||
{{!-- max. distance --}}
|
||||
|
@ -73,23 +73,23 @@ titleKey=titleKey}}
|
|||
hideDescription=true}}
|
||||
{{!-- spell type --}}
|
||||
<img class="ds4-embedded-document-list__image"
|
||||
src="{{lookup @root/config.icons.spellTypes itemData.data.spellType}}"
|
||||
title="{{lookup @root/config.i18n.spellTypes itemData.data.spellType}}" />
|
||||
src="{{lookup @root/config.icons.spellTypes itemData.system.spellType}}"
|
||||
title="{{lookup @root/config.i18n.spellTypes itemData.system.spellType}}" />
|
||||
|
||||
{{!-- spell modifier --}}
|
||||
<div title="{{localize 'DS4.SpellModifier'}}">{{#if (eq itemData.data.spellModifier.complex
|
||||
'')}}{{itemData.data.spellModifier.numerical}}{{else}}{{itemData.data.spellModifier.complex}}{{/if}}</div>
|
||||
<div title="{{localize 'DS4.SpellModifier'}}">{{#if (eq itemData.system.spellModifier.complex
|
||||
'')}}{{itemData.system.spellModifier.numerical}}{{else}}{{itemData.system.spellModifier.complex}}{{/if}}</div>
|
||||
|
||||
{{!-- max. distance --}}
|
||||
{{> distanceUnit titleKey='DS4.SpellDistance' unitDatum=itemData.data.maxDistance
|
||||
{{> distanceUnit titleKey='DS4.SpellDistance' unitDatum=itemData.system.maxDistance
|
||||
config=@root/config}}
|
||||
|
||||
{{!-- duration --}}
|
||||
{{> temporalUnit titleKey='DS4.SpellDuration' unitDatum=itemData.data.duration config=@root/config}}
|
||||
{{> temporalUnit titleKey='DS4.SpellDuration' unitDatum=itemData.system.duration config=@root/config}}
|
||||
|
||||
{{!-- cooldown duration --}}
|
||||
<div title="{{localize 'DS4.CooldownDuration'}}">{{lookup @root/config.i18n.cooldownDurations
|
||||
itemData.data.cooldownDuration}}</div>
|
||||
itemData.system.cooldownDuration}}</div>
|
||||
|
||||
{{/systems/ds4/templates/sheets/actor/components/item-list-entry.hbs}}
|
||||
{{/each}}
|
||||
|
|
|
@ -7,10 +7,10 @@ SPDX-License-Identifier: MIT
|
|||
<div class="ds4-item-properties ds4-item-properties--armor">
|
||||
<h4 class="ds4-item-properties__title">{{localize 'DS4.ItemPropertiesArmor'}}</h4>
|
||||
<div class="form-group">
|
||||
<label for="data.armorType-{{data._id}}">{{localize "DS4.ArmorType"}}</label>
|
||||
<label for="system.armorType-{{data._id}}">{{localize "DS4.ArmorType"}}</label>
|
||||
<div class="form-fields">
|
||||
<select id="data.armorType-{{data._id}}" name="data.armorType" data-dtype="String">
|
||||
{{#select data.data.armorType}}
|
||||
<select id="system.armorType-{{data._id}}" name="system.armorType" data-dtype="String">
|
||||
{{#select data.system.armorType}}
|
||||
{{#each config.i18n.armorTypes as |value key|}}
|
||||
<option value="{{key}}">{{value}}</option>
|
||||
{{/each}}
|
||||
|
@ -19,10 +19,10 @@ SPDX-License-Identifier: MIT
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="data.armorMaterialType-{{data._id}}">{{localize "DS4.ArmorMaterialType"}}</label>
|
||||
<label for="system.armorMaterialType-{{data._id}}">{{localize "DS4.ArmorMaterialType"}}</label>
|
||||
<div class="form-fields">
|
||||
<select id="data.armorMaterialType-{{data._id}}" name="data.armorMaterialType" data-dtype="String">
|
||||
{{#select data.data.armorMaterialType}}
|
||||
<select id="system.armorMaterialType-{{data._id}}" name="system.armorMaterialType" data-dtype="String">
|
||||
{{#select data.system.armorMaterialType}}
|
||||
{{#each config.i18n.armorMaterialTypes as |value key|}}
|
||||
<option value="{{key}}">{{value}}</option>
|
||||
{{/each}}
|
||||
|
|
|
@ -7,8 +7,8 @@ SPDX-License-Identifier: MIT
|
|||
<div class="ds4-item-properties ds4-item-properties--equipable">
|
||||
<h4 class="ds4-item-properties__title">{{localize 'DS4.ItemPropertiesEquipable'}}</h4>
|
||||
<div class="form-group">
|
||||
<label for="data.equipped-{{data._id}}">{{localize "DS4.ItemEquipped"}}</label>
|
||||
<input id="data.equipped-{{data._id}}" data-dtype="Boolean" type="checkbox" name="data.equipped" {{checked
|
||||
data.data.equipped}} />
|
||||
<label for="system.equipped-{{data._id}}">{{localize "DS4.ItemEquipped"}}</label>
|
||||
<input id="system.equipped-{{data._id}}" data-dtype="Boolean" type="checkbox" name="system.equipped" {{checked
|
||||
data.system.equipped}} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,15 +7,15 @@ SPDX-License-Identifier: MIT
|
|||
<div class="ds4-item-properties ds4-item-properties--physical">
|
||||
<h4 class="ds4-item-properties__title">{{localize 'DS4.ItemPropertiesPhysical'}}</h4>
|
||||
<div class="form-group">
|
||||
<label for="data.price-{{data._id}}">{{localize "DS4.PriceGold"}}</label>
|
||||
<input id="data.price-{{data._id}}" data-dtype="Number" type="number" min="0" max="99999" step="0.01"
|
||||
placeholder="0" name="data.price" value="{{data.data.price}}" />
|
||||
<label for="system.price-{{data._id}}">{{localize "DS4.PriceGold"}}</label>
|
||||
<input id="system.price-{{data._id}}" data-dtype="Number" type="number" min="0" max="99999" step="0.01"
|
||||
placeholder="0" name="system.price" value="{{data.system.price}}" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="data.availability-{{data._id}}">{{localize "DS4.ItemAvailability"}}</label>
|
||||
<label for="system.availability-{{data._id}}">{{localize "DS4.ItemAvailability"}}</label>
|
||||
<div class="form-fields">
|
||||
<select id="data.availability-{{data._id}}" name="data.availability" data-dtype="String">
|
||||
{{#select data.data.availability}}
|
||||
<select id="system.availability-{{data._id}}" name="system.availability" data-dtype="String">
|
||||
{{#select data.system.availability}}
|
||||
{{#each config.i18n.itemAvailabilities as |value key|}}
|
||||
<option value="{{key}}">{{value}}</option>
|
||||
{{/each}}
|
||||
|
@ -25,14 +25,14 @@ SPDX-License-Identifier: MIT
|
|||
</div>
|
||||
{{#if isOwned}}
|
||||
<div class="form-group">
|
||||
<label for="data.quantity-{{data._id}}">{{localize "DS4.Quantity"}}</label>
|
||||
<input id="data.quantity-{{data._id}}" data-dtype="Number" type="number" name="data.quantity" placeholder="0"
|
||||
value="{{data.data.quantity}}" />
|
||||
<label for="system.quantity-{{data._id}}">{{localize "DS4.Quantity"}}</label>
|
||||
<input id="system.quantity-{{data._id}}" data-dtype="Number" type="number" name="system.quantity" placeholder="0"
|
||||
value="{{data.system.quantity}}" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="data.storageLocation-{{data._id}}">{{localize "DS4.StorageLocation"}}</label>
|
||||
<input id="data.storageLocation-{{data._id}}" data-dtype="String" type="text" name="data.storageLocation"
|
||||
value="{{data.data.storageLocation}}" />
|
||||
<label for="system.storageLocation-{{data._id}}">{{localize "DS4.StorageLocation"}}</label>
|
||||
<input id="system.storageLocation-{{data._id}}" data-dtype="String" type="text" name="system.storageLocation"
|
||||
value="{{data.system.storageLocation}}" />
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -7,8 +7,8 @@ SPDX-License-Identifier: MIT
|
|||
<div class="ds4-item-properties ds4-item-properties--protective">
|
||||
<h4 class="ds4-item-properties__title">{{localize 'DS4.ItemPropertiesProtective'}}</h4>
|
||||
<div class="form-group">
|
||||
<label for="data.armorValue-{{data._id}}">{{localize "DS4.ArmorValue"}}</label>
|
||||
<input id="data.armorValue-{{data._id}}" data-dtype="Number" type="number" min="0" step="1" placeholder="0"
|
||||
name="data.armorValue" value="{{data.data.armorValue}}" />
|
||||
<label for="system.armorValue-{{data._id}}">{{localize "DS4.ArmorValue"}}</label>
|
||||
<input id="system.armorValue-{{data._id}}" data-dtype="Number" type="number" min="0" step="1" placeholder="0"
|
||||
name="system.armorValue" value="{{data.system.armorValue}}" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,9 +7,9 @@ SPDX-License-Identifier: MIT
|
|||
<div class="ds4-item-properties ds4-item-properties--special-creature-ability">
|
||||
<h4 class="ds4-item-properties__title">{{localize 'DS4.ItemPropertiesSpecialCreatureAbility'}}</h4>
|
||||
<div class="form-group">
|
||||
<label for="data.experiencePoints-{{data._id}}">{{localize
|
||||
<label for="system.experiencePoints-{{data._id}}">{{localize
|
||||
"DS4.SpecialCreatureAbilityExperiencePoints"}}</label>
|
||||
<input id="data.experiencePoints-{{data._id}}" data-dtype="Number" type="number" min="0" step="1"
|
||||
placeholder="0" name="data.experiencePoints" value="{{data.data.experiencePoints}}" />
|
||||
<input id="system.experiencePoints-{{data._id}}" data-dtype="Number" type="number" min="0" step="1"
|
||||
placeholder="0" name="system.experiencePoints" value="{{data.system.experiencePoints}}" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,29 +7,29 @@ SPDX-License-Identifier: MIT
|
|||
<div class="ds4-item-properties ds4-item-properties--spell">
|
||||
<h4 class="ds4-item-properties__title">{{localize 'DS4.ItemPropertiesSpell'}}</h4>
|
||||
<div class="form-group">
|
||||
<label for="data.spellModifier.numerical-{{data._id}}"
|
||||
<label for="system.spellModifier.numerical-{{data._id}}"
|
||||
title="{{localize 'DS4.SpellModifierNumericalDescription'}}">{{localize
|
||||
"DS4.SpellModifierNumerical"}}</label>
|
||||
<div class="form-fields">
|
||||
<input id="data.spellModifier.numerical-{{data._id}}" data-dtype="Number" type="number"
|
||||
name="data.spellModifier.numerical" placeholder="0" value="{{data.data.spellModifier.numerical}}" />
|
||||
<input id="system.spellModifier.numerical-{{data._id}}" data-dtype="Number" type="number"
|
||||
name="system.spellModifier.numerical" placeholder="0" value="{{data.system.spellModifier.numerical}}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="data.spellModifier.complex-{{data._id}}"
|
||||
<label for="system.spellModifier.complex-{{data._id}}"
|
||||
title="{{localize 'DS4.SpellModifierComplexDescription'}}">{{localize
|
||||
"DS4.SpellModifierComplex"}}</label>
|
||||
<div class="form-fields">
|
||||
<input id="data.spellModifier.complex-{{data._id}}" data-dtype="String" type="text"
|
||||
name="data.spellModifier.complex" value="{{data.data.spellModifier.complex}}" />
|
||||
<input id="system.spellModifier.complex-{{data._id}}" data-dtype="String" type="text"
|
||||
name="system.spellModifier.complex" value="{{data.system.spellModifier.complex}}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="data.spellType-{{data._id}}" title="{{localize 'DS4.SpellTypeDescription'}}">{{localize
|
||||
<label for="system.spellType-{{data._id}}" title="{{localize 'DS4.SpellTypeDescription'}}">{{localize
|
||||
"DS4.SpellType"}}</label>
|
||||
<div class="form-fields">
|
||||
<select id="data.spellType-{{data._id}}" name="data.spellType" data-dtype="String">
|
||||
{{#select data.data.spellType}}
|
||||
<select id="system.spellType-{{data._id}}" name="system.spellType" data-dtype="String">
|
||||
{{#select data.system.spellType}}
|
||||
{{#each config.i18n.spellTypes as |value key|}}
|
||||
<option value="{{key}}">{{value}}</option>
|
||||
{{/each}}
|
||||
|
@ -40,10 +40,10 @@ SPDX-License-Identifier: MIT
|
|||
<div class="form-group slim">
|
||||
<label title="{{localize 'DS4.SpellDistanceDescription'}}">{{localize "DS4.SpellDistance"}}</label>
|
||||
<div class="form-fields">
|
||||
<input data-dtype="String" type="text" name="data.maxDistance.value"
|
||||
value="{{data.data.maxDistance.value}}" />
|
||||
<select name="data.maxDistance.unit" data-dtype="String">
|
||||
{{#select data.data.maxDistance.unit}}
|
||||
<input data-dtype="String" type="text" name="system.maxDistance.value"
|
||||
value="{{data.system.maxDistance.value}}" />
|
||||
<select name="system.maxDistance.unit" data-dtype="String">
|
||||
{{#select data.system.maxDistance.unit}}
|
||||
{{#each config.i18n.distanceUnits as |value key|}}
|
||||
<option value="{{key}}">{{value}}</option>
|
||||
{{/each}}
|
||||
|
@ -54,10 +54,10 @@ SPDX-License-Identifier: MIT
|
|||
<div class="form-group slim">
|
||||
<label title="{{localize 'DS4.SpellEffectRadiusDescription'}}">{{localize "DS4.SpellEffectRadius"}}</label>
|
||||
<div class="form-fields">
|
||||
<input data-dtype="String" type="text" name="data.effectRadius.value"
|
||||
value="{{data.data.effectRadius.value}}" />
|
||||
<select name="data.effectRadius.unit" data-dtype="String">
|
||||
{{#select data.data.effectRadius.unit}}
|
||||
<input data-dtype="String" type="text" name="system.effectRadius.value"
|
||||
value="{{data.system.effectRadius.value}}" />
|
||||
<select name="system.effectRadius.unit" data-dtype="String">
|
||||
{{#select data.system.effectRadius.unit}}
|
||||
{{#each config.i18n.distanceUnits as |value key|}}
|
||||
<option value="{{key}}">{{value}}</option>
|
||||
{{/each}}
|
||||
|
@ -68,9 +68,9 @@ SPDX-License-Identifier: MIT
|
|||
<div class="form-group slim">
|
||||
<label title="{{localize 'DS4.SpellDurationDescription'}}">{{localize "DS4.SpellDuration"}}</label>
|
||||
<div class="form-fields">
|
||||
<input data-dtype="String" type="text" name="data.duration.value" value="{{data.data.duration.value}}" />
|
||||
<select name="data.duration.unit" data-dtype="String">
|
||||
{{#select data.data.duration.unit}}
|
||||
<input data-dtype="String" type="text" name="system.duration.value" value="{{data.system.duration.value}}" />
|
||||
<select name="system.duration.unit" data-dtype="String">
|
||||
{{#select data.system.duration.unit}}
|
||||
{{#each config.i18n.temporalUnits as |value key|}}
|
||||
<option value="{{key}}">{{value}}</option>
|
||||
{{/each}}
|
||||
|
@ -79,11 +79,11 @@ SPDX-License-Identifier: MIT
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="data.cooldownDuration-{{data._id}}"
|
||||
<label for="system.cooldownDuration-{{data._id}}"
|
||||
title="{{localize 'DS4.CooldownDurationDescription'}}">{{localize "DS4.CooldownDuration"}}</label>
|
||||
<div class="form-fields">
|
||||
<select id="data.cooldownDuration-{{data._id}}" name="data.cooldownDuration" data-dtype="String">
|
||||
{{#select data.data.cooldownDuration}}
|
||||
<select id="system.cooldownDuration-{{data._id}}" name="system.cooldownDuration" data-dtype="String">
|
||||
{{#select data.system.cooldownDuration}}
|
||||
{{#each config.i18n.cooldownDurations as |value key|}}
|
||||
<option value="{{key}}">{{value}}</option>
|
||||
{{/each}}
|
||||
|
@ -97,42 +97,42 @@ SPDX-License-Identifier: MIT
|
|||
<div class="ds4-checkbox-grid">
|
||||
{{#each config.i18n.spellGroups as |value key|}}
|
||||
<div class="ds4-checkbox-grid__item">
|
||||
<input class="ds4-checkbox-grid__checkbox" id="data.spellGroups.{{key}}-{{../data._id}}"
|
||||
name="data.spellGroups.{{key}}" data-dtype="Boolean" type="checkbox" {{checked (lookup
|
||||
../data.data.spellGroups key)}} />
|
||||
<label for="data.spellGroups.{{key}}-{{../data._id}}">{{value}}</label>
|
||||
<input class="ds4-checkbox-grid__checkbox" id="system.spellGroups.{{key}}-{{../data._id}}"
|
||||
name="system.spellGroups.{{key}}" data-dtype="Boolean" type="checkbox" {{checked (lookup
|
||||
../data.system.spellGroups key)}} />
|
||||
<label for="system.spellGroups.{{key}}-{{../data._id}}">{{value}}</label>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="data.allowsDefense-{{data._id}}" title="{{localize 'DS4.SpellAllowsDefenseDescription'}}">{{localize
|
||||
<label for="system.allowsDefense-{{data._id}}" title="{{localize 'DS4.SpellAllowsDefenseDescription'}}">{{localize
|
||||
"DS4.SpellAllowsDefense"}}</label>
|
||||
<div class="form-fields">
|
||||
<input id="data.allowsDefense-{{data._id}}" data-dtype="Boolean" type="checkbox" name="data.allowsDefense"
|
||||
{{checked data.data.allowsDefense}} />
|
||||
<input id="system.allowsDefense-{{data._id}}" data-dtype="Boolean" type="checkbox" name="system.allowsDefense"
|
||||
{{checked data.system.allowsDefense}} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group slim">
|
||||
<label title="{{localize 'DS4.SpellMinimumLevelDescription'}}">{{localize "DS4.SpellMinimumLevel"}}</label>
|
||||
<div class="form-fields">
|
||||
<label for="data.minimumLevels.healer-{{data._id}}">{{localize "DS4.SpellCasterClassHealer"}}</label>
|
||||
<input id="data.minimumLevels.healer-{{data._id}}" data-dtype="Number" type="number" min="0" step="1"
|
||||
name="data.minimumLevels.healer" placeholder="–" value="{{data.data.minimumLevels.healer}}" />
|
||||
<label for="data.minimumLevels.wizard-{{data._id}}">{{localize "DS4.SpellCasterClassWizard"}}</label>
|
||||
<input id="data.minimumLevels.wizard-{{data._id}}" data-dtype="Number" type="number" min="0" step="1"
|
||||
name="data.minimumLevels.wizard" placeholder="–" value="{{data.data.minimumLevels.wizard}}" />
|
||||
<label for="data.minimumLevels.sorcerer-{{data._id}}">{{localize
|
||||
<label for="system.minimumLevels.healer-{{data._id}}">{{localize "DS4.SpellCasterClassHealer"}}</label>
|
||||
<input id="system.minimumLevels.healer-{{data._id}}" data-dtype="Number" type="number" min="0" step="1"
|
||||
name="system.minimumLevels.healer" placeholder="–" value="{{data.system.minimumLevels.healer}}" />
|
||||
<label for="system.minimumLevels.wizard-{{data._id}}">{{localize "DS4.SpellCasterClassWizard"}}</label>
|
||||
<input id="system.minimumLevels.wizard-{{data._id}}" data-dtype="Number" type="number" min="0" step="1"
|
||||
name="system.minimumLevels.wizard" placeholder="–" value="{{data.system.minimumLevels.wizard}}" />
|
||||
<label for="system.minimumLevels.sorcerer-{{data._id}}">{{localize
|
||||
"DS4.SpellCasterClassSorcerer"}}</label>
|
||||
<input id="data.minimumLevels.sorcerer-{{data._id}}" data-dtype="Number" type="number" min="0" step="1"
|
||||
name="data.minimumLevels.sorcerer" placeholder="–" value="{{data.data.minimumLevels.sorcerer}}" />
|
||||
<input id="system.minimumLevels.sorcerer-{{data._id}}" data-dtype="Number" type="number" min="0" step="1"
|
||||
name="system.minimumLevels.sorcerer" placeholder="–" value="{{data.system.minimumLevels.sorcerer}}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="data.price-{{data._id}}" title="{{localize 'DS4.SpellPriceDescription'}}">{{localize
|
||||
<label for="system.price-{{data._id}}" title="{{localize 'DS4.SpellPriceDescription'}}">{{localize
|
||||
"DS4.SpellPrice"}}</label>
|
||||
<div class="form-fields">
|
||||
<span id="data.price-{{data._id}}">{{data.data.price}}</span>
|
||||
<span id="system.price-{{data._id}}">{{data.system.price}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -9,18 +9,18 @@ SPDX-License-Identifier: MIT
|
|||
<div class="form-group slim">
|
||||
<label>{{localize "DS4.TalentRank"}}</label>
|
||||
<div class="form-fields">
|
||||
<label for="data.rank.base-{{data._id}}">{{localize "DS4.TalentRankBase"}}</label>
|
||||
<input id="data.rank.base-{{data._id}}" data-dtype="Number" type="number" min="0"
|
||||
max="{{data.data.rank.max}}" step="1" name="data.rank.base" value="{{data.data.rank.base}}" />
|
||||
<label for="data.rank.max-{{data._id}}">{{localize "DS4.TalentRankMax"}}</label>
|
||||
<input id="data.rank.max-{{data._id}}" data-dtype="Number" type="number" min="0" step="1"
|
||||
name="data.rank.max" value="{{data.data.rank.max}}" />
|
||||
<label for="system.rank.base-{{data._id}}">{{localize "DS4.TalentRankBase"}}</label>
|
||||
<input id="system.rank.base-{{data._id}}" data-dtype="Number" type="number" min="0"
|
||||
max="{{data.system.rank.max}}" step="1" name="system.rank.base" value="{{data.system.rank.base}}" />
|
||||
<label for="system.rank.max-{{data._id}}">{{localize "DS4.TalentRankMax"}}</label>
|
||||
<input id="system.rank.max-{{data._id}}" data-dtype="Number" type="number" min="0" step="1"
|
||||
name="system.rank.max" value="{{data.system.rank.max}}" />
|
||||
<br />
|
||||
<label for="data.rank.mod-{{data._id}}">{{localize "DS4.TalentRankMod"}}</label>
|
||||
<input id="data.rank.mod-{{data._id}}" data-dtype="Number" type="number" min="0" step="1"
|
||||
name="data.rank.mod" value="{{data.data.rank.mod}}" />
|
||||
<label for="data.rank.total-{{data._id}}">{{localize "DS4.TalentRankTotal"}}</label>
|
||||
<span id="data.rank.total-{{data._id}}">{{data.data.rank.total}}</span>
|
||||
<label for="system.rank.mod-{{data._id}}">{{localize "DS4.TalentRankMod"}}</label>
|
||||
<input id="system.rank.mod-{{data._id}}" data-dtype="Number" type="number" min="0" step="1"
|
||||
name="system.rank.mod" value="{{data.system.rank.mod}}" />
|
||||
<label for="system.rank.total-{{data._id}}">{{localize "DS4.TalentRankTotal"}}</label>
|
||||
<span id="system.rank.total-{{data._id}}">{{data.system.rank.total}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,10 +7,10 @@ SPDX-License-Identifier: MIT
|
|||
<div class="ds4-item-properties ds4-item-properties--weapon">
|
||||
<h4 class="ds4-item-properties__title">{{localize 'DS4.ItemPropertiesWeapon'}}</h4>
|
||||
<div class="form-group">
|
||||
<label for="data.attackType-{{data._id}}">{{localize "DS4.AttackType"}}</label>
|
||||
<label for="system.attackType-{{data._id}}">{{localize "DS4.AttackType"}}</label>
|
||||
<div class="form-fields">
|
||||
<select id="data.attackType-{{data._id}}" name="data.attackType" data-dtype="String">
|
||||
{{#select data.data.attackType}}
|
||||
<select id="system.attackType-{{data._id}}" name="system.attackType" data-dtype="String">
|
||||
{{#select data.system.attackType}}
|
||||
{{#each config.i18n.attackTypes as |value key|}}
|
||||
<option value="{{key}}">{{value}}</option>
|
||||
{{/each}}
|
||||
|
@ -19,13 +19,13 @@ SPDX-License-Identifier: MIT
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="data.weaponBonus-{{data._id}}">{{localize "DS4.WeaponBonus"}}</label>
|
||||
<input id="data.weaponBonus-{{data._id}}" data-dtype="Number" type="number" name="data.weaponBonus"
|
||||
placeholder="0" value="{{data.data.weaponBonus}}" />
|
||||
<label for="system.weaponBonus-{{data._id}}">{{localize "DS4.WeaponBonus"}}</label>
|
||||
<input id="system.weaponBonus-{{data._id}}" data-dtype="Number" type="number" name="system.weaponBonus"
|
||||
placeholder="0" value="{{data.system.weaponBonus}}" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="data.opponentDefense-{{data._id}}">{{localize "DS4.OpponentDefense"}}</label>
|
||||
<input id="data.opponentDefense-{{data._id}}" data-dtype="Number" type="number" name="data.opponentDefense"
|
||||
placeholder="0" value="{{data.data.opponentDefense}}" />
|
||||
<label for="system.opponentDefense-{{data._id}}">{{localize "DS4.OpponentDefense"}}</label>
|
||||
<input id="system.opponentDefense-{{data._id}}" data-dtype="Number" type="number" name="system.opponentDefense"
|
||||
placeholder="0" value="{{data.system.opponentDefense}}" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -5,6 +5,6 @@ SPDX-License-Identifier: MIT
|
|||
--}}
|
||||
|
||||
<div class="ds4-sheet-tab tab description" data-group="primary" data-tab="description">
|
||||
{{editor content=data.data.description target="data.description" button=true owner=owner
|
||||
editable=editable}}
|
||||
{{editor data.system.description target="system.description" button=true owner=owner
|
||||
editable=editable engine="prosemirror"}}
|
||||
</div>
|
||||
|
|
|
@ -18,6 +18,7 @@ function cleanPackEntry(entry, cleanSourceId = true) {
|
|||
}
|
||||
});
|
||||
if (entry.permission) entry.permission = { default: 0 };
|
||||
if (entry._stats?.lastModifiedBy) entry._stats.lastModifiedBy = "DS4BuildSystem00";
|
||||
|
||||
const embeddedDocumentCollections = [
|
||||
"drawings",
|
||||
|
|
Loading…
Reference in a new issue