Initial styling config and auto-format of files

This commit is contained in:
TJ 2021-03-24 19:41:50 -05:00
parent e8d4153333
commit 42ddf4b0d0
33 changed files with 2965 additions and 2566 deletions

View file

@ -3,7 +3,7 @@
* @type {Dialog}
*/
export default class AbilityUseDialog extends Dialog {
constructor(item, dialogData={}, options={}) {
constructor(item, dialogData = {}, options = {}) {
super(dialogData, options);
this.options.classes = ["sw5e", "dialog"];
@ -25,7 +25,7 @@ export default class AbilityUseDialog extends Dialog {
* @return {Promise}
*/
static async create(item) {
if ( !item.isOwned ) throw new Error("You cannot display an ability usage dialog for an unowned item");
if (!item.isOwned) throw new Error("You cannot display an ability usage dialog for an unowned item");
// Prepare data
const actorData = item.actor.data.data;
@ -34,7 +34,7 @@ export default class AbilityUseDialog extends Dialog {
const quantity = itemData.quantity || 0;
const recharge = itemData.recharge || {};
const recharges = !!recharge.value;
const sufficientUses = (quantity > 0 && !uses.value) || uses.value > 0;
const sufficientUses = (quantity > 0 && !uses.value) || uses.value > 0;
// Prepare dialog form data
const data = {
@ -49,7 +49,7 @@ export default class AbilityUseDialog extends Dialog {
createTemplate: game.user.can("TEMPLATE_CREATE") && item.hasAreaTarget,
errors: []
};
if ( item.data.type === "power" ) this._getPowerData(actorData, itemData, data);
if (item.data.type === "power") this._getPowerData(actorData, itemData, data);
// Render the ability usage template
const html = await renderTemplate("systems/sw5e/templates/apps/ability-use.html", data);
@ -57,7 +57,7 @@ export default class AbilityUseDialog extends Dialog {
// Create the Dialog and return data as a Promise
const icon = data.isPower ? "fa-magic" : "fa-fist-raised";
const label = game.i18n.localize("SW5E.AbilityUse" + (data.isPower ? "Cast" : "Use"));
return new Promise((resolve) => {
return new Promise(resolve => {
const dlg = new this(item, {
title: `${item.name}: Usage Configuration`,
content: html,
@ -87,14 +87,13 @@ export default class AbilityUseDialog extends Dialog {
* @private
*/
static _getPowerData(actorData, itemData, data) {
// Determine whether the power may be up-cast
const lvl = itemData.level;
const consumePowerSlot = (lvl > 0) && CONFIG.SW5E.powerUpcastModes.includes(itemData.preparation.mode);
const consumePowerSlot = lvl > 0 && CONFIG.SW5E.powerUpcastModes.includes(itemData.preparation.mode);
// If can't upcast, return early and don't bother calculating available power slots
if (!consumePowerSlot) {
mergeObject(data, { isPower: true, consumePowerSlot });
mergeObject(data, {isPower: true, consumePowerSlot});
return;
}
@ -102,74 +101,78 @@ export default class AbilityUseDialog extends Dialog {
let lmax = 0;
let points;
let powerType;
switch (itemData.school){
switch (itemData.school) {
case "lgt":
case "uni":
case "drk": {
powerType = "force"
powerType = "force";
points = actorData.attributes.force.points.value + actorData.attributes.force.points.temp;
break;
}
case "tec": {
powerType = "tech"
powerType = "tech";
points = actorData.attributes.tech.points.value + actorData.attributes.tech.points.temp;
break;
}
}
// eliminate point usage for innate casters
if (actorData.attributes.powercasting === 'innate') points = 999;
if (actorData.attributes.powercasting === "innate") points = 999;
let powerLevels
if (powerType === "force"){
powerLevels = Array.fromRange(10).reduce((arr, i) => {
if ( i < lvl ) return arr;
const label = CONFIG.SW5E.powerLevels[i];
const l = actorData.powers["power"+i] || {fmax: 0, foverride: null};
let max = parseInt(l.foverride || l.fmax || 0);
let slots = Math.clamped(parseInt(l.fvalue || 0), 0, max);
if ( max > 0 ) lmax = i;
if ((max > 0) && (slots > 0) && (points > i)){
arr.push({
level: i,
label: i > 0 ? game.i18n.format('SW5E.PowerLevelSlot', {level: label, n: slots}) : label,
canCast: max > 0,
hasSlots: slots > 0
});
}
return arr;
}, []).filter(sl => sl.level <= lmax);
}else if (powerType === "tech"){
powerLevels = Array.fromRange(10).reduce((arr, i) => {
if ( i < lvl ) return arr;
const label = CONFIG.SW5E.powerLevels[i];
const l = actorData.powers["power"+i] || {tmax: 0, toverride: null};
let max = parseInt(l.override || l.tmax || 0);
let slots = Math.clamped(parseInt(l.tvalue || 0), 0, max);
if ( max > 0 ) lmax = i;
if ((max > 0) && (slots > 0) && (points > i)){
arr.push({
level: i,
label: i > 0 ? game.i18n.format('SW5E.PowerLevelSlot', {level: label, n: slots}) : label,
canCast: max > 0,
hasSlots: slots > 0
});
}
return arr;
}, []).filter(sl => sl.level <= lmax);
let powerLevels;
if (powerType === "force") {
powerLevels = Array.fromRange(10)
.reduce((arr, i) => {
if (i < lvl) return arr;
const label = CONFIG.SW5E.powerLevels[i];
const l = actorData.powers["power" + i] || {fmax: 0, foverride: null};
let max = parseInt(l.foverride || l.fmax || 0);
let slots = Math.clamped(parseInt(l.fvalue || 0), 0, max);
if (max > 0) lmax = i;
if (max > 0 && slots > 0 && points > i) {
arr.push({
level: i,
label: i > 0 ? game.i18n.format("SW5E.PowerLevelSlot", {level: label, n: slots}) : label,
canCast: max > 0,
hasSlots: slots > 0
});
}
return arr;
}, [])
.filter(sl => sl.level <= lmax);
} else if (powerType === "tech") {
powerLevels = Array.fromRange(10)
.reduce((arr, i) => {
if (i < lvl) return arr;
const label = CONFIG.SW5E.powerLevels[i];
const l = actorData.powers["power" + i] || {tmax: 0, toverride: null};
let max = parseInt(l.override || l.tmax || 0);
let slots = Math.clamped(parseInt(l.tvalue || 0), 0, max);
if (max > 0) lmax = i;
if (max > 0 && slots > 0 && points > i) {
arr.push({
level: i,
label: i > 0 ? game.i18n.format("SW5E.PowerLevelSlot", {level: label, n: slots}) : label,
canCast: max > 0,
hasSlots: slots > 0
});
}
return arr;
}, [])
.filter(sl => sl.level <= lmax);
}
const canCast = powerLevels.some(l => l.hasSlots);
if ( !canCast ) data.errors.push(game.i18n.format("SW5E.PowerCastNoSlots", {
level: CONFIG.SW5E.powerLevels[lvl],
name: data.item.name
}));
if (!canCast)
data.errors.push(
game.i18n.format("SW5E.PowerCastNoSlots", {
level: CONFIG.SW5E.powerLevels[lvl],
name: data.item.name
})
);
// Merge power casting data
return mergeObject(data, { isPower: true, consumePowerSlot, powerLevels });
return mergeObject(data, {isPower: true, consumePowerSlot, powerLevels});
}
/* -------------------------------------------- */
@ -179,27 +182,26 @@ export default class AbilityUseDialog extends Dialog {
* @private
*/
static _getAbilityUseNote(item, uses, recharge) {
// Zero quantity
const quantity = item.data.quantity;
if ( quantity <= 0 ) return game.i18n.localize("SW5E.AbilityUseUnavailableHint");
if (quantity <= 0) return game.i18n.localize("SW5E.AbilityUseUnavailableHint");
// Abilities which use Recharge
if ( !!recharge.value ) {
if (!!recharge.value) {
return game.i18n.format(recharge.charged ? "SW5E.AbilityUseChargedHint" : "SW5E.AbilityUseRechargeHint", {
type: item.type,
})
type: item.type
});
}
// Does not use any resource
if ( !uses.per || !uses.max ) return "";
if (!uses.per || !uses.max) return "";
// Consumables
if ( item.type === "consumable" ) {
if (item.type === "consumable") {
let str = "SW5E.AbilityUseNormalHint";
if ( uses.value > 1 ) str = "SW5E.AbilityUseConsumableChargeHint";
else if ( item.data.quantity === 1 && uses.autoDestroy ) str = "SW5E.AbilityUseConsumableDestroyHint";
else if ( item.data.quantity > 1 ) str = "SW5E.AbilityUseConsumableQuantityHint";
if (uses.value > 1) str = "SW5E.AbilityUseConsumableChargeHint";
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,
value: uses.value,
@ -222,7 +224,5 @@ export default class AbilityUseDialog extends Dialog {
/* -------------------------------------------- */
static _handleSubmit(formData, item) {
}
static _handleSubmit(formData, item) {}
}

View file

@ -7,7 +7,7 @@ export default class ActorSheetFlags extends BaseEntitySheet {
const options = super.defaultOptions;
return mergeObject(options, {
id: "actor-flags",
classes: ["sw5e"],
classes: ["sw5e"],
template: "systems/sw5e/templates/apps/actor-flags.html",
width: 500,
closeOnSubmit: true
@ -18,7 +18,7 @@ export default class ActorSheetFlags extends BaseEntitySheet {
/** @override */
get title() {
return `${game.i18n.localize('SW5E.FlagsTitle')}: ${this.object.name}`;
return `${game.i18n.localize("SW5E.FlagsTitle")}: ${this.object.name}`;
}
/* -------------------------------------------- */
@ -42,12 +42,12 @@ export default class ActorSheetFlags extends BaseEntitySheet {
_getFlags() {
const flags = {};
const baseData = this.entity._data;
for ( let [k, v] of Object.entries(CONFIG.SW5E.characterFlags) ) {
if ( !flags.hasOwnProperty(v.section) ) flags[v.section] = {};
for (let [k, v] of Object.entries(CONFIG.SW5E.characterFlags)) {
if (!flags.hasOwnProperty(v.section)) flags[v.section] = {};
let flag = duplicate(v);
flag.type = v.type.name;
flag.isCheckbox = v.type === Boolean;
flag.isSelect = v.hasOwnProperty('choices');
flag.isSelect = v.hasOwnProperty("choices");
flag.value = getProperty(baseData.flags, `sw5e.${k}`);
flags[v.section][`flags.sw5e.${k}`] = flag;
}
@ -80,7 +80,7 @@ export default class ActorSheetFlags extends BaseEntitySheet {
{name: "data.bonuses.power.forceUnivDC", label: "SW5E.BonusForceUnivPowerDC"},
{name: "data.bonuses.power.techDC", label: "SW5E.BonusTechPowerDC"}
];
for ( let b of bonuses ) {
for (let b of bonuses) {
b.value = getProperty(this.object._data, b.name) || "";
}
return bonuses;
@ -97,11 +97,11 @@ export default class ActorSheetFlags extends BaseEntitySheet {
let unset = false;
const flags = updateData.flags.sw5e;
//clone flags to dnd5e for module compatability
updateData.flags.dnd5e = updateData.flags.sw5e
for ( let [k, v] of Object.entries(flags) ) {
if ( [undefined, null, "", false, 0].includes(v) ) {
updateData.flags.dnd5e = updateData.flags.sw5e;
for (let [k, v] of Object.entries(flags)) {
if ([undefined, null, "", false, 0].includes(v)) {
delete flags[k];
if ( hasProperty(actor._data.flags, `sw5e.${k}`) ) {
if (hasProperty(actor._data.flags, `sw5e.${k}`)) {
unset = true;
flags[`-=${k}`] = null;
}
@ -109,8 +109,8 @@ export default class ActorSheetFlags extends BaseEntitySheet {
}
// Clear any bonuses which are whitespace only
for ( let b of Object.values(updateData.data.bonuses ) ) {
for ( let [k, v] of Object.entries(b) ) {
for (let b of Object.values(updateData.data.bonuses)) {
for (let [k, v] of Object.entries(b)) {
b[k] = v.trim();
}
}

View file

@ -24,8 +24,8 @@ export default class LongRestDialog extends Dialog {
getData() {
const data = super.getData();
const variant = game.settings.get("sw5e", "restVariant");
data.promptNewDay = variant !== "gritty"; // It's always a new day when resting 1 week
data.newDay = variant === "normal"; // It's probably a new day when resting normally (8 hours)
data.promptNewDay = variant !== "gritty"; // It's always a new day when resting 1 week
data.newDay = variant === "normal"; // It's probably a new day when resting normally (8 hours)
return data;
}
@ -37,7 +37,7 @@ export default class LongRestDialog extends Dialog {
* @param {Actor5e} actor
* @return {Promise}
*/
static async longRestDialog({ actor } = {}) {
static async longRestDialog({actor} = {}) {
return new Promise((resolve, reject) => {
const dlg = new this(actor, {
title: "Long Rest",
@ -49,8 +49,7 @@ export default class LongRestDialog extends Dialog {
let newDay = false;
if (game.settings.get("sw5e", "restVariant") === "normal")
newDay = html.find('input[name="newDay"]')[0].checked;
else if(game.settings.get("sw5e", "restVariant") === "gritty")
newDay = true;
else if (game.settings.get("sw5e", "restVariant") === "gritty") newDay = true;
resolve(newDay);
}
},
@ -60,10 +59,10 @@ export default class LongRestDialog extends Dialog {
callback: reject
}
},
default: 'rest',
default: "rest",
close: reject
});
dlg.render(true);
});
}
}
}

View file

@ -3,10 +3,9 @@
* @implements {BaseEntitySheet}
*/
export default class ActorMovementConfig extends BaseEntitySheet {
/** @override */
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
classes: ["sw5e"],
template: "systems/sw5e/templates/apps/movement-config.html",
width: 300,
@ -28,9 +27,9 @@ export default class ActorMovementConfig extends BaseEntitySheet {
const data = {
movement: duplicate(this.entity._data.data.attributes.movement),
units: CONFIG.SW5E.movementUnits
}
for ( let [k, v] of Object.entries(data.movement) ) {
if ( ["units", "hover"].includes(k) ) continue;
};
for (let [k, v] of Object.entries(data.movement)) {
if (["units", "hover"].includes(k)) continue;
data.movement[k] = Number.isNumeric(v) ? v.toNearest(0.1) : 0;
}
return data;

View file

@ -3,10 +3,9 @@
* @implements {BaseEntitySheet}
*/
export default class ActorSensesConfig extends BaseEntitySheet {
/** @override */
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
classes: ["sw5e"],
template: "systems/sw5e/templates/apps/senses-config.html",
width: 300,
@ -29,14 +28,15 @@ export default class ActorSensesConfig extends BaseEntitySheet {
const data = {
senses: {},
special: senses.special ?? "",
units: senses.units, movementUnits: CONFIG.SW5E.movementUnits
units: senses.units,
movementUnits: CONFIG.SW5E.movementUnits
};
for ( let [name, label] of Object.entries(CONFIG.SW5E.senses) ) {
for (let [name, label] of Object.entries(CONFIG.SW5E.senses)) {
const v = senses[name];
data.senses[name] = {
label: game.i18n.localize(label),
value: Number.isNumeric(v) ? v.toNearest(0.1) : 0
}
};
}
return data;
}

View file

@ -5,7 +5,7 @@ import LongRestDialog from "./long-rest.js";
* @extends {Dialog}
*/
export default class ShortRestDialog extends Dialog {
constructor(actor, dialogData={}, options={}) {
constructor(actor, dialogData = {}, options = {}) {
super(dialogData, options);
/**
@ -24,9 +24,9 @@ export default class ShortRestDialog extends Dialog {
/* -------------------------------------------- */
/** @override */
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
template: "systems/sw5e/templates/apps/short-rest.html",
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
template: "systems/sw5e/templates/apps/short-rest.html",
classes: ["sw5e", "dialog"]
});
}
@ -39,7 +39,7 @@ export default class ShortRestDialog extends Dialog {
// Determine Hit Dice
data.availableHD = this.actor.data.items.reduce((hd, item) => {
if ( item.type === "class" ) {
if (item.type === "class") {
const d = item.data;
const denom = d.hitDice || "d6";
const available = parseInt(d.levels || 1) - parseInt(d.hitDiceUsed || 0);
@ -52,14 +52,13 @@ export default class ShortRestDialog extends Dialog {
// Determine rest type
const variant = game.settings.get("sw5e", "restVariant");
data.promptNewDay = variant !== "epic"; // It's never a new day when only resting 1 minute
data.newDay = false; // It may be a new day, but not by default
data.promptNewDay = variant !== "epic"; // It's never a new day when only resting 1 minute
data.newDay = false; // It may be a new day, but not by default
return data;
}
/* -------------------------------------------- */
/** @override */
activateListeners(html) {
super.activateListeners(html);
@ -90,7 +89,7 @@ export default class ShortRestDialog extends Dialog {
* @param {Actor5e} actor
* @return {Promise}
*/
static async shortRestDialog({actor}={}) {
static async shortRestDialog({actor} = {}) {
return new Promise((resolve, reject) => {
const dlg = new this(actor, {
title: "Short Rest",
@ -126,8 +125,10 @@ export default class ShortRestDialog extends Dialog {
* @param {Actor5e} actor
* @return {Promise}
*/
static async longRestDialog({actor}={}) {
console.warn("WARNING! ShortRestDialog.longRestDialog has been deprecated, use LongRestDialog.longRestDialog instead.");
static async longRestDialog({actor} = {}) {
console.warn(
"WARNING! ShortRestDialog.longRestDialog has been deprecated, use LongRestDialog.longRestDialog instead."
);
return LongRestDialog.longRestDialog(...arguments);
}
}

View file

@ -3,11 +3,10 @@
* @implements {FormApplication}
*/
export default class TraitSelector extends FormApplication {
/** @override */
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
id: "trait-selector",
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
id: "trait-selector",
classes: ["sw5e"],
title: "Actor Trait Selection",
template: "systems/sw5e/templates/apps/trait-selector.html",
@ -27,33 +26,32 @@ export default class TraitSelector extends FormApplication {
* @type {String}
*/
get attribute() {
return this.options.name;
return this.options.name;
}
/* -------------------------------------------- */
/** @override */
getData() {
// Get current values
let attr = getProperty(this.object._data, this.attribute);
if ( getType(attr) !== "Object" ) attr = {value: [], custom: ""};
if (getType(attr) !== "Object") attr = {value: [], custom: ""};
// Populate choices
// Populate choices
const choices = duplicate(this.options.choices);
for ( let [k, v] of Object.entries(choices) ) {
for (let [k, v] of Object.entries(choices)) {
choices[k] = {
label: v,
chosen: attr ? attr.value.includes(k) : false
}
};
}
// Return data
return {
allowCustom: this.options.allowCustom,
choices: choices,
choices: choices,
custom: attr ? attr.custom : ""
}
};
}
/* -------------------------------------------- */
@ -64,21 +62,21 @@ export default class TraitSelector extends FormApplication {
// Obtain choices
const chosen = [];
for ( let [k, v] of Object.entries(formData) ) {
if ( (k !== "custom") && v ) chosen.push(k);
for (let [k, v] of Object.entries(formData)) {
if (k !== "custom" && v) chosen.push(k);
}
updateData[`${this.attribute}.value`] = chosen;
// Validate the number chosen
if ( this.options.minimum && (chosen.length < this.options.minimum) ) {
if (this.options.minimum && chosen.length < this.options.minimum) {
return ui.notifications.error(`You must choose at least ${this.options.minimum} options`);
}
if ( this.options.maximum && (chosen.length > this.options.maximum) ) {
if (this.options.maximum && chosen.length > this.options.maximum) {
return ui.notifications.error(`You may choose no more than ${this.options.maximum} options`);
}
// Include custom
if ( this.options.allowCustom ) {
if (this.options.allowCustom) {
updateData[`${this.attribute}.custom`] = formData.custom;
}