mirror of
https://github.com/RoY7x/worldbuilding.git
synced 2025-04-30 02:31:41 -04:00
Merge branch '0.6.x' into 'master'
Release 0.6.3 See merge request foundrynet/worldbuilding!23
This commit is contained in:
commit
5446680d9f
8 changed files with 113 additions and 20 deletions
|
@ -11,6 +11,7 @@ export class SimpleActor extends Actor {
|
|||
super.prepareDerivedData();
|
||||
this.data.data.groups = this.data.data.groups || {};
|
||||
this.data.data.attributes = this.data.data.attributes || {};
|
||||
EntitySheetHelper.clampResourceValues(this.data.data.attributes);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -20,6 +21,16 @@ export class SimpleActor extends Actor {
|
|||
return EntitySheetHelper.createDialog.call(this, data, options);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Is this Actor used as a template for other Actors?
|
||||
* @type {boolean}
|
||||
*/
|
||||
get isTemplate() {
|
||||
return !!this.getFlag("worldbuilding", "isTemplate");
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Roll Data Preparation */
|
||||
/* -------------------------------------------- */
|
||||
|
@ -236,4 +247,17 @@ export class SimpleActor extends Actor {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/** @inheritdoc */
|
||||
async modifyTokenAttribute(attribute, value, isDelta = false, isBar = true) {
|
||||
const current = foundry.utils.getProperty(this.data.data, attribute);
|
||||
if ( !isBar || !isDelta || (current?.dtype !== "Resource") ) {
|
||||
return super.modifyTokenAttribute(attribute, value, isDelta, isBar);
|
||||
}
|
||||
const updates = {[`data.${attribute}.value`]: Math.clamped(current.value + value, current.min, current.max)};
|
||||
const allowed = Hooks.call("modifyTokenAttribute", {attribute, value, isDelta, isBar}, updates);
|
||||
return allowed !== false ? this.update(updates) : this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -587,4 +587,21 @@ export class EntitySheetHelper {
|
|||
options: options
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Ensure the resource values are within the specified min and max.
|
||||
* @param {object} attrs The Document's attributes.
|
||||
*/
|
||||
static clampResourceValues(attrs) {
|
||||
const flat = foundry.utils.flattenObject(attrs);
|
||||
for ( const [attr, value] of Object.entries(flat) ) {
|
||||
const parts = attr.split(".");
|
||||
if ( parts.pop() !== "value" ) continue;
|
||||
const current = foundry.utils.getProperty(attrs, parts.join("."));
|
||||
if ( current?.dtype !== "Resource" ) continue;
|
||||
foundry.utils.setProperty(attrs, attr, Math.clamped(value, current.min || 0, current.max || 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ export class SimpleItem extends Item {
|
|||
super.prepareDerivedData();
|
||||
this.data.data.groups = this.data.data.groups || {};
|
||||
this.data.data.attributes = this.data.data.attributes || {};
|
||||
EntitySheetHelper.clampResourceValues(this.data.data.attributes);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -19,4 +20,14 @@ export class SimpleItem extends Item {
|
|||
static async createDialog(data={}, options={}) {
|
||||
return EntitySheetHelper.createDialog.call(this, data, options);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Is this Item used as a template for other Items?
|
||||
* @type {boolean}
|
||||
*/
|
||||
get isTemplate() {
|
||||
return !!this.getFlag("worldbuilding", "isTemplate");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* @returns {Promise}
|
||||
*/
|
||||
export async function createWorldbuildingMacro(data, slot) {
|
||||
if ( !data.roll || !data.label ) return false;
|
||||
const command = `const roll = new Roll("${data.roll}", actor ? actor.getRollData() : {});
|
||||
roll.toMessage({speaker, flavor: "${data.label}"});`;
|
||||
let macro = game.macros.find(m => (m.name === data.label) && (m.command === command));
|
||||
|
|
|
@ -10,7 +10,7 @@ import { SimpleItemSheet } from "./item-sheet.js";
|
|||
import { SimpleActorSheet } from "./actor-sheet.js";
|
||||
import { preloadHandlebarsTemplates } from "./templates.js";
|
||||
import { createWorldbuildingMacro } from "./macro.js";
|
||||
import { SimpleTokenDocument } from "./simpletokendocument.js";
|
||||
import { SimpleToken, SimpleTokenDocument } from "./token.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Initialization */
|
||||
|
@ -40,9 +40,8 @@ Hooks.once("init", async function() {
|
|||
// Define custom Document classes
|
||||
CONFIG.Actor.documentClass = SimpleActor;
|
||||
CONFIG.Item.documentClass = SimpleItem;
|
||||
|
||||
// Update TokenDocument with overrided getBarAttribute method
|
||||
CONFIG.Token.documentClass = SimpleTokenDocument;
|
||||
CONFIG.Token.objectClass = SimpleToken;
|
||||
|
||||
// Register sheet application classes
|
||||
Actors.unregisterSheet("core", ActorSheet);
|
||||
|
@ -116,7 +115,7 @@ Hooks.on("getActorDirectoryEntryContext", (html, options) => {
|
|||
icon: '<i class="fas fa-stamp"></i>',
|
||||
condition: li => {
|
||||
const actor = game.actors.get(li.data(idAttr));
|
||||
return !actor.getFlag("worldbuilding", "isTemplate");
|
||||
return !actor.isTemplate;
|
||||
},
|
||||
callback: li => {
|
||||
const actor = game.actors.get(li.data(idAttr));
|
||||
|
@ -130,7 +129,7 @@ Hooks.on("getActorDirectoryEntryContext", (html, options) => {
|
|||
icon: '<i class="fas fa-times"></i>',
|
||||
condition: li => {
|
||||
const actor = game.actors.get(li.data(idAttr));
|
||||
return actor.getFlag("worldbuilding", "isTemplate");
|
||||
return actor.isTemplate;
|
||||
},
|
||||
callback: li => {
|
||||
const actor = game.actors.get(li.data(idAttr));
|
||||
|
@ -150,7 +149,7 @@ Hooks.on("getItemDirectoryEntryContext", (html, options) => {
|
|||
icon: '<i class="fas fa-stamp"></i>',
|
||||
condition: li => {
|
||||
const item = game.items.get(li.data(idAttr));
|
||||
return !item.getFlag("worldbuilding", "isTemplate");
|
||||
return !item.isTemplate;
|
||||
},
|
||||
callback: li => {
|
||||
const item = game.items.get(li.data(idAttr));
|
||||
|
@ -164,7 +163,7 @@ Hooks.on("getItemDirectoryEntryContext", (html, options) => {
|
|||
icon: '<i class="fas fa-times"></i>',
|
||||
condition: li => {
|
||||
const item = game.items.get(li.data(idAttr));
|
||||
return item.getFlag("worldbuilding", "isTemplate");
|
||||
return item.isTemplate;
|
||||
},
|
||||
callback: li => {
|
||||
const item = game.items.get(li.data(idAttr));
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
export class SimpleTokenDocument extends TokenDocument {
|
||||
|
||||
/** @inheritdoc */
|
||||
getBarAttribute(barName, {alternative}={}) {
|
||||
const attr = super.getBarAttribute(barName, {alternative});
|
||||
if ( attr === null ) return null;
|
||||
attr.editable = true; // Attribute always editable, super requires attr to exist in actor template
|
||||
return attr;
|
||||
}
|
||||
|
||||
}
|
52
module/token.js
Normal file
52
module/token.js
Normal file
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* Extend the base TokenDocument to support resource type attributes.
|
||||
* @extends {TokenDocument}
|
||||
*/
|
||||
export class SimpleTokenDocument extends TokenDocument {
|
||||
/** @inheritdoc */
|
||||
getBarAttribute(barName, {alternative}={}) {
|
||||
const data = super.getBarAttribute(barName, {alternative});
|
||||
const attr = alternative || this.data[barName]?.attribute;
|
||||
if ( !data || !attr || !this.actor ) return data;
|
||||
const current = foundry.utils.getProperty(this.actor.data.data, attr);
|
||||
if ( "min" in current ) data.min = parseInt(current.min || 0);
|
||||
data.editable = true;
|
||||
return data;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
static getTrackedAttributes(data, _path=[]) {
|
||||
if ( data || _path.length ) return super.getTrackedAttributes(data, _path);
|
||||
data = {};
|
||||
for ( const model of Object.values(game.system.model.Actor) ) {
|
||||
foundry.utils.mergeObject(data, model);
|
||||
}
|
||||
for ( const actor of game.actors ) {
|
||||
if ( actor.isTemplate ) foundry.utils.mergeObject(data, actor.toObject().data);
|
||||
}
|
||||
return super.getTrackedAttributes(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* Extend the base Token class to implement additional system-specific logic.
|
||||
* @extends {Token}
|
||||
*/
|
||||
export class SimpleToken extends Token {
|
||||
_drawBar(number, bar, data) {
|
||||
if ( "min" in data ) {
|
||||
// Copy the data to avoid mutating what the caller gave us.
|
||||
data = {...data};
|
||||
// Shift the value and max by the min to ensure that the bar's percentage is drawn accurately if this resource has
|
||||
// a non-zero min.
|
||||
data.value -= data.min;
|
||||
data.max -= data.min;
|
||||
}
|
||||
return super._drawBar(number, bar, data);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
"name": "worldbuilding",
|
||||
"title": "Simple World-Building",
|
||||
"description": "A minimalist game system which provides configurable Actor and Item templates to support free-form system agnostic game-play.",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"minimumCoreVersion": "0.8.9",
|
||||
"compatibleCoreVersion": "9",
|
||||
"author": "Atropos",
|
||||
|
@ -22,6 +22,6 @@
|
|||
"secondaryTokenAttribute": "power",
|
||||
"url": "https://gitlab.com/foundrynet/worldbuilding/",
|
||||
"manifest": "https://gitlab.com/foundrynet/worldbuilding/raw/0.6.x/system.json",
|
||||
"download": "https://gitlab.com/foundrynet/worldbuilding/-/archive/release-062/worldbuilding-release-062.zip",
|
||||
"download": "https://gitlab.com/foundrynet/worldbuilding/-/archive/release-063/worldbuilding-release-063.zip",
|
||||
"license": "LICENSE.txt"
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue