Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add duration data model #18

Open
wants to merge 2 commits into
base: packet-2-datamodels
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions system/CONSTANTS.mjs
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import { HELPERS } from "./helpers/HELPERS.mjs";

export const SYSTEM_ID = "black-flag";
export const SYSTEM_NAME = "Black Flag 🏴";

function isDebugging() {
return game.modules.get("_dev-mode")?.api?.getPackageDebugValue(SYSTEM_ID);
}

function log(...args) {
if ( isDebugging() ) console.log(`${SYSTEM_NAME} |`, ...args);
}

/**
* The expected distance units.
* @type {{label: string}}
Expand Down Expand Up @@ -252,10 +246,9 @@ const CHARACTER_BUILDER_MODES = {
* @type {Object}
*/
export const SYSTEM = {
...HELPERS,
id: SYSTEM_ID,
name: SYSTEM_NAME,
log,
isDebugging,
TOOL_TYPES,
SKILL_TYPES,
PROFICIENCY_TYPES,
Expand Down
34 changes: 34 additions & 0 deletions system/datamodels/item/common/duration.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Data model template for a Duration, as may be used by Powers
*
* @property {string} type
* @mixin
*/
export default class DurationDataModel extends foundry.abstract.DataModel {

/** @inheritdoc */
static _enableV10Validation = true;

/** @inheritDoc */
static defineSchema() {
const fields = foundry.data.fields;
return {
// Store duration internally as rounds, translating into human readable on the fly
rounds: new fields.NumberField({
required: false
}),

// Describes when during a round an effect might end
// e.g. "end of target's turn" or "end of caster's turn"
special: new fields.StringField({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can probably do better than special, such as effectEnds. Perhaps we can offer choices? Off the top of my head, I can think of the following options:

  • Start of Round
  • End of Round
  • Start of Target's Turn
  • End of Target's Turn
  • Start of Caster's Turn
  • End of Caster's Turn
  • None (purely time based)

We may also want to have a Concentration choice, or perhaps Concentration is a bool on the duration

required: false
}),

type: new fields.StringField({
required: true,
choices: ["instantaneous", "time", "permanent", "special"],
initial: "instantaneous"
})
};
}
}
9 changes: 9 additions & 0 deletions system/helpers/HELPERS.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {isDebugging, log} from "./debug.mjs";
import {convertToRounds, formatRounds} from "./roundHelpers.mjs";

export const HELPERS = {
convertToRounds,
formatRounds,
isDebugging,
log
};
9 changes: 9 additions & 0 deletions system/helpers/debug.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

export function isDebugging() {
return game.modules.get("_dev-mode")?.api?.getPackageDebugValue(SYSTEM_ID);
}

export function log(...args) {
if ( isDebugging() ) console.log(`${SYSTEM_NAME} |`, ...args);
}

87 changes: 87 additions & 0 deletions system/helpers/roundHelpers.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* Formats rounds for human readable display
*
* 1 round is nominally a "turn"
* 10 rounds is a minute
* 600 rounds is an hour
* 14400 rounds is a day
* 1008000 is a week
* 4032000 is a month
* 48384000 is a year
*
* @param {number} rounds
* @returns {{number: number, unit: string}}
*/
export function formatRounds(rounds) {
if (rounds < 10) {
return {
number: rounds,
unit: "turns"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll want to localize these, probably with a label on top of a machine-friendly unit that we already have

};
}

if (rounds < 600) {
return {
number: Math.floor(rounds / 10),
unit: "minutes"
};
}

if (rounds < 14400) {
return {
number: Math.floor(rounds / 600),
unit: "hours"
};
}

if (rounds < 1008000) {
return {
number: Math.floor(rounds / 14400),
unit: "days"
};
}

if (rounds < 4032000) {
return {
number: Math.floor(rounds / 1008000),
unit: "weeks"
};
}

if (rounds < 48384000) {
return {
number: Math.floor(rounds / 4032000),
unit: "months"
};
}

return {
number: Math.floor(rounds / 48384000),
unit: "years"
};
}

/**
* Converts an object of number and unit into a number of rounds
* @param {number} number
* @param {string} unit
* @returns {number} - a number of rounds
*/
export function convertToRounds(number, unit) {
switch (unit) {
case "turns":
return number;
case "minutes":
return number * 10;
case "hours":
return number * 600;
case "days":
return number * 14400;
case "weeks":
return number * 1008000;
case "months":
return number * 4032000;
case "years":
return number * 48384000;
}
}