forked from GitHub-Mirrors/foundry-sw5e
Finish core upgrade to 1.3.5
Filled in some missing pieces in html for core upgrades. Looked mostly good on both Cyr and Jacob's accounts. I had a few questions about differences that were added from DND5e, they are as follows: less\original\npc.less line 34 - is the "li" before .creature-type necessary, not in dnd5e module\item\entity.js line 685 - dnd is game.user._id, we have game.user.data._id module\pixi\ability-template.js line 22- dnd is game.user._id, we have game.user.data._id templates\chat\item-card.html line 1- dnd has actor._id, we have actor.data._id
This commit is contained in:
parent
e2f002292b
commit
9a86bf7857
42 changed files with 270 additions and 193 deletions
|
@ -696,10 +696,10 @@ export default class Actor5e extends Actor {
|
|||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Event Handlers
|
||||
/* Event Handlers */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/** @inheritDoc */
|
||||
/** @inheritdoc */
|
||||
async _preCreate(data, options, user) {
|
||||
await super._preCreate(data, options, user);
|
||||
|
||||
|
@ -1688,11 +1688,13 @@ export default class Actor5e extends Actor {
|
|||
// Get the Tokens which represent this actor
|
||||
if ( canvas.ready ) {
|
||||
const tokens = this.getActiveTokens(true);
|
||||
const tokenData = await original.getTokenData();
|
||||
const tokenUpdates = tokens.map(t => {
|
||||
const tokenData = original.data.token.toJSON();
|
||||
tokenData._id = t.id;
|
||||
tokenData.actorId = original.id;
|
||||
return tokenData;
|
||||
const update = duplicate(tokenData);
|
||||
update._id = t.id;
|
||||
delete update.x;
|
||||
delete update.y;
|
||||
return update;
|
||||
});
|
||||
canvas.scene.updateEmbeddedDocuments("Token", tokenUpdates);
|
||||
}
|
||||
|
|
|
@ -75,10 +75,10 @@ export default class ActorSheet5e extends ActorSheet {
|
|||
options: this.options,
|
||||
editable: this.isEditable,
|
||||
cssClass: isOwner ? "editable" : "locked",
|
||||
isCharacter: this.actor.data.type === "character",
|
||||
isNPC: this.actor.data.type === "npc",
|
||||
isStarship: this.actor.data.type === "starship",
|
||||
isVehicle: this.actor.data.type === 'vehicle',
|
||||
isCharacter: this.actor.type === "character",
|
||||
isNPC: this.actor.type === "npc",
|
||||
isStarship: this.actor.type === "starship",
|
||||
isVehicle: this.actor.type === 'vehicle',
|
||||
config: CONFIG.SW5E,
|
||||
rollData: this.actor.getRollData.bind(this.actor)
|
||||
};
|
||||
|
@ -109,7 +109,7 @@ export default class ActorSheet5e extends ActorSheet {
|
|||
|
||||
// Skills
|
||||
if (actorData.data.skills) {
|
||||
for ( let [s, skl] of Object.entries(actorData.data.skills)) {
|
||||
for (let [s, skl] of Object.entries(actorData.data.skills)) {
|
||||
skl.ability = CONFIG.SW5E.abilityAbbreviations[skl.ability];
|
||||
skl.icon = this._getProficiencyIcon(skl.value);
|
||||
skl.hover = CONFIG.SW5E.proficiencyLevels[skl.value];
|
||||
|
@ -781,7 +781,7 @@ export default class ActorSheet5e extends ActorSheet {
|
|||
const header = event.currentTarget;
|
||||
const type = header.dataset.type;
|
||||
const itemData = {
|
||||
name: game.i18n.format("SW5E.ItemNew", {type: type.capitalize()}),
|
||||
name: game.i18n.format("SW5E.ItemNew", {type: game.i18n.localize(`SW5E.ItemType${type.capitalize()}`)}),
|
||||
type: type,
|
||||
data: foundry.utils.deepClone(header.dataset)
|
||||
};
|
||||
|
|
|
@ -112,7 +112,7 @@ export default class ActorSheet5eCharacterNew extends ActorSheet5e {
|
|||
this._prepareItemToggleState(item);
|
||||
|
||||
// Primary Class
|
||||
if ( item.type === "class" ) item.isOriginalClass = ( item.data._id === this.actor.data.data.details.originalClass );
|
||||
if ( item.type === "class" ) item.isOriginalClass = ( item._id === this.actor.data.data.details.originalClass );
|
||||
|
||||
// Classify items into types
|
||||
if ( item.type === "power" && ["lgt", "drk", "uni"].includes(item.data.school) ) arr[1].push(item);
|
||||
|
@ -143,7 +143,7 @@ export default class ActorSheet5eCharacterNew extends ActorSheet5e {
|
|||
for ( let i of items ) {
|
||||
i.data.quantity = i.data.quantity || 0;
|
||||
i.data.weight = i.data.weight || 0;
|
||||
i.totalWeight = Math.round(i.data.quantity * i.data.weight * 10) / 10;
|
||||
i.totalWeight = (i.data.quantity * i.data.weight).toNearest(0.1);
|
||||
inventory[i.type].items.push(i);
|
||||
}
|
||||
|
||||
|
@ -156,9 +156,9 @@ export default class ActorSheet5eCharacterNew extends ActorSheet5e {
|
|||
classes: { label: "SW5E.ItemTypeClassPl", items: [], hasActions: false, dataset: {type: "class"}, isClass: true },
|
||||
classfeatures: { label: "SW5E.ItemTypeClassFeats", items: [], hasActions: true, dataset: {type: "classfeature"}, isClassfeature: true },
|
||||
archetype: { label: "SW5E.ItemTypeArchetype", items: [], hasActions: false, dataset: {type: "archetype"}, isArchetype: true },
|
||||
deployments: { label: "SW5E.ItemTypeDeploymentPl", items: [], hasActions: false, dataset: {type: "deployment"}, isDeployment: true },
|
||||
deploymentfeatures: { label: "SW5E.ItemTypeDeploymentFeaturePl", items: [], hasActions: true, dataset: {type: "deploymentfeature"}, isDeploymentfeature: true },
|
||||
ventures: { label: "SW5E.ItemTypeVenturePl", items: [], hasActions: false, dataset: {type: "venture"}, isVenture: true },
|
||||
deployments: { label: "SW5E.ItemTypeDeploymentPl", items: [], hasActions: false, dataset: {type: "deployment"}, isDeployment: true },
|
||||
deploymentfeatures: { label: "SW5E.ItemTypeDeploymentFeaturePl", items: [], hasActions: true, dataset: {type: "deploymentfeature"}, isDeploymentfeature: true },
|
||||
ventures: { label: "SW5E.ItemTypeVenturePl", items: [], hasActions: false, dataset: {type: "venture"}, isVenture: true },
|
||||
species: { label: "SW5E.ItemTypeSpecies", items: [], hasActions: false, dataset: {type: "species"}, isSpecies: true },
|
||||
background: { label: "SW5E.ItemTypeBackground", items: [], hasActions: false, dataset: {type: "background"}, isBackground: true },
|
||||
fightingstyles: { label: "SW5E.ItemTypeFightingStylePl", items: [], hasActions: false, dataset: {type: "fightingstyle"}, isFightingstyle: true },
|
||||
|
@ -175,9 +175,9 @@ export default class ActorSheet5eCharacterNew extends ActorSheet5e {
|
|||
features.classes.items = classes;
|
||||
features.classfeatures.items = classfeatures;
|
||||
features.archetype.items = archetypes;
|
||||
features.deployments.items = deployments;
|
||||
features.deploymentfeatures.items = deploymentfeatures;
|
||||
features.ventures.items = ventures;
|
||||
features.deployments.items = deployments;
|
||||
features.deploymentfeatures.items = deploymentfeatures;
|
||||
features.ventures.items = ventures;
|
||||
features.species.items = species;
|
||||
features.background.items = backgrounds;
|
||||
features.fightingstyles.items = fightingstyles;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Actor5e from "../../entity.js";
|
||||
import Actor5e from "../entity.js";
|
||||
import ActorSheet5e from "./base.js";
|
||||
|
||||
/**
|
||||
|
@ -88,7 +88,7 @@ export default class ActorSheet5eNPCNew extends ActorSheet5e {
|
|||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/** @override */
|
||||
/** @inheritdoc */
|
||||
getData(options) {
|
||||
const data = super.getData(options);
|
||||
|
||||
|
|
|
@ -222,7 +222,7 @@ export default class ActorSheet5eVehicle extends ActorSheet5e {
|
|||
if ( isCargo ) {
|
||||
totalWeight += (item.data.weight || 0) * item.data.quantity;
|
||||
cargo.cargo.items.push(item);
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle non-cargo item types
|
||||
|
@ -371,6 +371,8 @@ export default class ActorSheet5eVehicle extends ActorSheet5e {
|
|||
return super._onItemDelete(event);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/** @override */
|
||||
async _onDropItemCreate(itemData) {
|
||||
const cargoTypes = ["weapon", "equipment", "consumable", "tool", "loot", "backpack"];
|
||||
|
|
|
@ -789,7 +789,7 @@ export default class ActorSheet5e extends ActorSheet {
|
|||
const header = event.currentTarget;
|
||||
const type = header.dataset.type;
|
||||
const itemData = {
|
||||
name: game.i18n.format("SW5E.ItemNew", {type: type.capitalize()}),
|
||||
name: game.i18n.format("SW5E.ItemNew", {type: game.i18n.localize(`SW5E.ItemType${type.capitalize()}`)}),
|
||||
type: type,
|
||||
data: foundry.utils.deepClone(header.dataset)
|
||||
};
|
||||
|
@ -820,6 +820,7 @@ export default class ActorSheet5e extends ActorSheet {
|
|||
*/
|
||||
_onItemDelete(event) {
|
||||
event.preventDefault();
|
||||
const li = event.currentTarget.closest(".item");
|
||||
const item = this.actor.items.get(li.dataset.itemId);
|
||||
if ( item ) return item.delete();
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ export default class ActorSheet5eCharacter extends ActorSheet5e {
|
|||
this._prepareItemToggleState(item);
|
||||
|
||||
// Primary Class
|
||||
if ( item.type === "class" ) item.isOriginalClass = ( item.data._id === this.actor.data.data.details.originalClass );
|
||||
if ( item.type === "class" ) item.isOriginalClass = ( item._id === this.actor.data.data.details.originalClass );
|
||||
|
||||
// Classify items into types
|
||||
if ( item.type === "power" ) arr[1].push(item);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import Actor5e from "../entity.js";
|
||||
import ActorSheet5e from "./base.js";
|
||||
|
||||
/**
|
||||
|
|
|
@ -39,7 +39,7 @@ export default class AbilityUseDialog extends Dialog {
|
|||
// Prepare dialog form data
|
||||
const data = {
|
||||
item: item.data,
|
||||
title: game.i18n.format("SW5E.AbilityUseHint", item.data),
|
||||
title: game.i18n.format("SW5E.AbilityUseHint", {type: game.i18n.localize(`SW5E.ItemType${item.type.capitalize()}`), name: item.name}),
|
||||
note: this._getAbilityUseNote(item.data, uses, recharge),
|
||||
consumePowerSlot: false,
|
||||
consumeRecharge: recharges,
|
||||
|
@ -59,7 +59,7 @@ export default class AbilityUseDialog extends Dialog {
|
|||
const label = game.i18n.localize("SW5E.AbilityUse" + (data.isPower ? "Cast" : "Use"));
|
||||
return new Promise((resolve) => {
|
||||
const dlg = new this(item, {
|
||||
title: `${item.name}: Usage Configuration`,
|
||||
title: `${item.name}: ${game.i18n.localize("SW5E.AbilityUseConfig")}`,
|
||||
content: html,
|
||||
buttons: {
|
||||
use: {
|
||||
|
@ -187,7 +187,7 @@ export default class AbilityUseDialog extends Dialog {
|
|||
// Abilities which use Recharge
|
||||
if ( !!recharge.value ) {
|
||||
return game.i18n.format(recharge.charged ? "SW5E.AbilityUseChargedHint" : "SW5E.AbilityUseRechargeHint", {
|
||||
type: item.type,
|
||||
type: game.i18n.localize(`SW5E.ItemType${item.type.capitalize()}`),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ export default class AbilityUseDialog extends Dialog {
|
|||
else if ( item.data.quantity === 1 && uses.autoDestroy ) str = "SW5E.AbilityUseConsumableDestroyHint";
|
||||
else if ( item.data.quantity > 1 ) str = "SW5E.AbilityUseConsumableQuantityHint";
|
||||
return game.i18n.format(str, {
|
||||
type: item.data.consumableType,
|
||||
type: game.i18n.localize(`SW5E.Consumable${item.data.consumableType.capitalize()}`),
|
||||
value: uses.value,
|
||||
quantity: item.data.quantity,
|
||||
max: uses.max,
|
||||
|
@ -212,7 +212,7 @@ export default class AbilityUseDialog extends Dialog {
|
|||
// Other Items
|
||||
else {
|
||||
return game.i18n.format("SW5E.AbilityUseNormalHint", {
|
||||
type: item.type,
|
||||
type: game.i18n.localize(`SW5E.ItemType${item.type.capitalize()}`),
|
||||
value: uses.value,
|
||||
max: uses.max,
|
||||
per: CONFIG.SW5E.limitedUsePeriods[uses.per]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* An application class which provides advanced configuration for special character flags which modify an Actor
|
||||
* @extends {DocumentSheet}
|
||||
* @implements {DocumentSheet}
|
||||
*/
|
||||
export default class ActorSheetFlags extends DocumentSheet {
|
||||
static get defaultOptions() {
|
||||
|
|
|
@ -40,11 +40,11 @@ export default class LongRestDialog extends Dialog {
|
|||
static async longRestDialog({ actor } = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const dlg = new this(actor, {
|
||||
title: "Long Rest",
|
||||
title: game.i18n.localize("SW5E.LongRest"),
|
||||
buttons: {
|
||||
rest: {
|
||||
icon: '<i class="fas fa-bed"></i>',
|
||||
label: "Rest",
|
||||
label: game.i18n.localize("SW5E.Rest"),
|
||||
callback: html => {
|
||||
let newDay = true;
|
||||
if (game.settings.get("sw5e", "restVariant") !== "gritty")
|
||||
|
@ -54,7 +54,7 @@ export default class LongRestDialog extends Dialog {
|
|||
},
|
||||
cancel: {
|
||||
icon: '<i class="fas fa-times"></i>',
|
||||
label: "Cancel",
|
||||
label: game.i18n.localize("Cancel"),
|
||||
callback: reject
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* A simple form to set actor movement speeds
|
||||
* A simple form to set Actor movement speeds.
|
||||
* @extends {DocumentSheet}
|
||||
*/
|
||||
export default class ActorSensesConfig extends DocumentSheet {
|
||||
|
|
|
@ -93,11 +93,11 @@ export default class ShortRestDialog extends Dialog {
|
|||
static async shortRestDialog({actor}={}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const dlg = new this(actor, {
|
||||
title: "Short Rest",
|
||||
title: game.i18n.localize("SW5E.ShortRest"),
|
||||
buttons: {
|
||||
rest: {
|
||||
icon: '<i class="fas fa-bed"></i>',
|
||||
label: "Rest",
|
||||
label: game.i18n.localize("SW5E.Rest"),
|
||||
callback: html => {
|
||||
let newDay = false;
|
||||
if (game.settings.get("sw5e", "restVariant") === "gritty")
|
||||
|
@ -107,7 +107,7 @@ export default class ShortRestDialog extends Dialog {
|
|||
},
|
||||
cancel: {
|
||||
icon: '<i class="fas fa-times"></i>',
|
||||
label: "Cancel",
|
||||
label: game.i18n.localize("Cancel"),
|
||||
callback: reject
|
||||
}
|
||||
},
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
export default class TraitSelector extends DocumentSheet {
|
||||
|
||||
/** @inheritDoc */
|
||||
/** @inheritdoc */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
id: "trait-selector",
|
||||
|
|
|
@ -103,6 +103,21 @@ SW5E.weaponProficiencies = {
|
|||
"vbw": "SW5E.WeaponVibrowhipProficiency"
|
||||
};
|
||||
|
||||
/**
|
||||
* A map of weapon item proficiency to actor item proficiency
|
||||
* Used when a new player owned item is created
|
||||
* @type {Object}
|
||||
*/
|
||||
SW5E.weaponProficienciesMap = {
|
||||
"natural": true,
|
||||
"simpleVW": "sim",
|
||||
"simpleB": "sim",
|
||||
"simpleLW": "sim",
|
||||
"martialVW": "mar",
|
||||
"martialB": "mar",
|
||||
"martialLW": "mar"
|
||||
};
|
||||
|
||||
// TODO: Check to see if this can be used
|
||||
// It's not actually been used anywhere in DND5e 1.3.2
|
||||
// Note name mapped to ID in compendium
|
||||
|
@ -270,8 +285,8 @@ SW5E.abilityActivationTypes = {
|
|||
"hour": SW5E.timePeriods.hour,
|
||||
"day": SW5E.timePeriods.day,
|
||||
"special": SW5E.timePeriods.spec,
|
||||
"legendary": "SW5E.LegAct",
|
||||
"lair": "SW5E.LairAct",
|
||||
"legendary": "SW5E.LegendaryActionLabel",
|
||||
"lair": "SW5E.LairActionLabel",
|
||||
"crew": "SW5E.VehicleCrewAction"
|
||||
};
|
||||
|
||||
|
@ -413,6 +428,20 @@ SW5E.armorProficiencies = {
|
|||
"shl": "SW5E.EquipmentShieldProficiency"
|
||||
};
|
||||
|
||||
/**
|
||||
* A map of armor item proficiency to actor item proficiency
|
||||
* Used when a new player owned item is created
|
||||
* @type {Object}
|
||||
*/
|
||||
SW5E.armorProficienciesMap = {
|
||||
"natural": true,
|
||||
"clothing": true,
|
||||
"light": "lgt",
|
||||
"medium": "med",
|
||||
"heavy": "hvy",
|
||||
"shield": "shl"
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
|
@ -746,7 +775,7 @@ SW5E.starshipRolesgrg = {
|
|||
|
||||
/**
|
||||
* The set of possible sensory perception types which an Actor may have
|
||||
* @type {object}
|
||||
* @enum {string}
|
||||
*/
|
||||
SW5E.senses = {
|
||||
"blindsight": "SW5E.SenseBlindsight",
|
||||
|
|
|
@ -42,7 +42,14 @@ export function simplifyRollFormula(formula, data, {constantFirst = false} = {})
|
|||
const rollableFormula = Roll.getFormula(rollableTerms); // Cleans up the non-constant terms and produces a new formula string
|
||||
|
||||
// Mathematically evaluate the constant formula to produce a single constant term
|
||||
const constantPart = constantFormula ? Roll.safeEval(constantFormula) : undefined;
|
||||
let constantPart = undefined;
|
||||
if ( constantFormula ) {
|
||||
try {
|
||||
constantPart = Roll.safeEval(constantFormula)
|
||||
} catch (err) {
|
||||
console.warn(`Unable to evaluate constant term ${constantFormula} in simplifyRollFormula`);
|
||||
}
|
||||
}
|
||||
|
||||
// Order the rollable and constant terms, either constant first or second depending on the optional argument
|
||||
const parts = constantFirst ? [constantPart, rollableFormula] : [rollableFormula, constantPart];
|
||||
|
|
8
module/effects.js
vendored
8
module/effects.js
vendored
|
@ -11,7 +11,7 @@ export function onManageActiveEffect(event, owner) {
|
|||
switch ( a.dataset.action ) {
|
||||
case "create":
|
||||
return owner.createEmbeddedDocuments("ActiveEffect", [{
|
||||
label: "New Effect",
|
||||
label: game.i18n.localize("SW5E.EffectNew"),
|
||||
icon: "icons/svg/aura.svg",
|
||||
origin: owner.uuid,
|
||||
"duration.rounds": li.dataset.effectType === "temporary" ? 1 : undefined,
|
||||
|
@ -37,17 +37,17 @@ export function prepareActiveEffectCategories(effects) {
|
|||
const categories = {
|
||||
temporary: {
|
||||
type: "temporary",
|
||||
label: "SW5E.EffectsCategoryTemporary",
|
||||
label: game.i18n.localize("SW5E.EffectTemporary"),
|
||||
effects: []
|
||||
},
|
||||
passive: {
|
||||
type: "passive",
|
||||
label: "SW5E.EffectsCategoryPassive",
|
||||
label: game.i18n.localize("SW5E.EffectPassive"),
|
||||
effects: []
|
||||
},
|
||||
inactive: {
|
||||
type: "inactive",
|
||||
label: "SW5E.EffectsCategoryInactive",
|
||||
label: game.i18n.localize("SW5E.EffectInactive"),
|
||||
effects: []
|
||||
}
|
||||
};
|
||||
|
|
|
@ -255,7 +255,7 @@ export default class Item5e extends Item {
|
|||
|
||||
// Range Label
|
||||
let rng = data.range || {};
|
||||
if (["none", "touch", "self"].includes(rng.units) || (rng.value === 0)) {
|
||||
if ( ["none", "touch", "self"].includes(rng.units) ) {
|
||||
rng.value = null;
|
||||
rng.long = null;
|
||||
}
|
||||
|
@ -1295,7 +1295,10 @@ export default class Item5e extends Item {
|
|||
const abl = this.abilityMod;
|
||||
if ( abl ) {
|
||||
const ability = rollData.abilities[abl];
|
||||
rollData["mod"] = ability.mod || 0;
|
||||
if ( !ability ) {
|
||||
console.warn(`Item ${this.name} in Actor ${this.actor.name} has an invalid item ability modifier of ${abl} defined`);
|
||||
}
|
||||
rollData["mod"] = ability?.mod || 0;
|
||||
}
|
||||
|
||||
// Include a proficiency score
|
||||
|
@ -1536,14 +1539,7 @@ export default class Item5e extends Item {
|
|||
if ( isNPC ) {
|
||||
updates["data.proficient"] = true; // NPCs automatically have equipment proficiency
|
||||
} else {
|
||||
const armorProf = {
|
||||
"natural": true,
|
||||
"clothing": true,
|
||||
"light": "lgt",
|
||||
"medium": "med",
|
||||
"heavy": "hvy",
|
||||
"shield": "shl"
|
||||
}[data.data?.armor?.type]; // Player characters check proficiency
|
||||
const armorProf = CONFIG.SW5E.armorProficienciesMap[data.data?.armor?.type]; // Player characters check proficiency
|
||||
const actorArmorProfs = actorData.data.traits?.armorProf?.value || [];
|
||||
updates["data.proficient"] = (armorProf === true) || actorArmorProfs.includes(armorProf);
|
||||
}
|
||||
|
@ -1579,15 +1575,7 @@ export default class Item5e extends Item {
|
|||
updates["data.proficient"] = true; // NPCs automatically have equipment proficiency
|
||||
} else {
|
||||
// TODO: With the changes to make weapon proficiencies more verbose, this may need revising
|
||||
const weaponProf = {
|
||||
"natural": true,
|
||||
"simpleVW": "sim",
|
||||
"simpleB": "sim",
|
||||
"simpleLW": "sim",
|
||||
"martialVW": "mar",
|
||||
"martialB": "mar",
|
||||
"martialLW": "mar"
|
||||
}[data.data?.weaponType]; // Player characters check proficiency
|
||||
const weaponProf = CONFIG.SW5E.weaponProficienciesMap[data.data?.weaponType]; // Player characters check proficiency
|
||||
const actorWeaponProfs = actorData.data.traits?.weaponProf?.value || [];
|
||||
updates["data.proficient"] = (weaponProf === true) || actorWeaponProfs.includes(weaponProf);
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ export default class ItemSheet5e extends ItemSheet {
|
|||
// Potential consumption targets
|
||||
data.abilityConsumptionTargets = this._getItemConsumptionTargets(itemData);
|
||||
|
||||
// Action Detail
|
||||
// Action Details
|
||||
data.hasAttackRoll = this.item.hasAttack;
|
||||
data.isHealing = itemData.data.actionType === "heal";
|
||||
data.isFlatDC = getProperty(itemData, "data.save.scaling") === "flat";
|
||||
|
|
|
@ -142,7 +142,7 @@ export const migrateActorData = async function(actor) {
|
|||
const results = await memo;
|
||||
|
||||
// Migrate the Owned Item
|
||||
const itemData = i instanceof CONFIG.Item.documentClass ? i.toObject() : i
|
||||
const itemData = i instanceof CONFIG.Item.documentClass ? i.toObject() : i;
|
||||
let itemUpdate = await migrateActorItemData(itemData, actor);
|
||||
|
||||
// Prepared, Equipped, and Proficient for NPC actors
|
||||
|
@ -154,7 +154,7 @@ export const migrateActorData = async function(actor) {
|
|||
|
||||
// Update the Owned Item
|
||||
if ( !isObjectEmpty(itemUpdate) ) {
|
||||
itemUpdate._id = itemData.id;
|
||||
itemUpdate._id = itemData._id;
|
||||
console.log(`Migrating Actor ${actor.name}'s ${i.name}`);
|
||||
results.push(expandObject(itemUpdate));
|
||||
}
|
||||
|
@ -208,12 +208,15 @@ function cleanActorData(actorData) {
|
|||
|
||||
/**
|
||||
* Migrate a single Item entity to incorporate latest data model changes
|
||||
* @param item
|
||||
*
|
||||
* @param {object} item Item data to migrate
|
||||
* @return {object} The updateData to apply
|
||||
*/
|
||||
export const migrateItemData = function(item) {
|
||||
const updateData = {};
|
||||
_migrateItemClassPowerCasting(item, updateData);
|
||||
_migrateItemAttunement(item, updateData);
|
||||
_migrateItemPowercasting(item, updateData);
|
||||
return updateData;
|
||||
};
|
||||
|
||||
|
@ -228,6 +231,7 @@ export const migrateActorItemData = async function(item, actor) {
|
|||
const updateData = {};
|
||||
_migrateItemClassPowerCasting(item, updateData);
|
||||
_migrateItemAttunement(item, updateData);
|
||||
_migrateItemPowercasting(item, updateData);
|
||||
await _migrateItemPower(item, actor, updateData);
|
||||
return updateData;
|
||||
};
|
||||
|
@ -464,6 +468,8 @@ function _migrateActorSenses(actor, updateData) {
|
|||
return updateData;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Migrate the actor details.type string to object
|
||||
* @private
|
||||
|
@ -643,12 +649,32 @@ async function _migrateItemPower(item, actor, updateData) {
|
|||
* @private
|
||||
*/
|
||||
function _migrateItemAttunement(item, updateData) {
|
||||
if ( item.data.data.attuned === undefined ) return updateData;
|
||||
if ( item.data?.attuned === undefined ) return updateData;
|
||||
updateData["data.attunement"] = CONFIG.SW5E.attunementTypes.NONE;
|
||||
updateData["data.-=attuned"] = null;
|
||||
return updateData;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Replace class powercasting string to object.
|
||||
*
|
||||
* @param {object} item Item data to migrate
|
||||
* @param {object} updateData Existing update to expand upon
|
||||
* @return {object} The updateData to apply
|
||||
* @private
|
||||
*/
|
||||
function _migrateItemPowercasting(item, updateData) {
|
||||
if ( item.type !== "class" || (foundry.utils.getType(item.data.powercasting) === "Object") ) return updateData;
|
||||
updateData["data.powercasting"] = {
|
||||
progression: item.data.powercasting,
|
||||
ability: ""
|
||||
};
|
||||
return updateData;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
|
|
|
@ -90,8 +90,7 @@ export default class AbilityTemplate extends MeasuredTemplate {
|
|||
if ( now - moveTime <= 20 ) return;
|
||||
const center = event.data.getLocalPosition(this.layer);
|
||||
const snapped = canvas.grid.getSnappedPosition(center.x, center.y, 2);
|
||||
this.data.x = snapped.x;
|
||||
this.data.y = snapped.y;
|
||||
this.data.update({x: snapped.x, y: snapped.y});
|
||||
this.refresh();
|
||||
moveTime = now;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue