diff --git a/.gitignore b/.gitignore index 4beb05c..a5dbdbe 100644 --- a/.gitignore +++ b/.gitignore @@ -2,13 +2,8 @@ node_modules/ *.tmp *.bak.* references.txt -references/ -/.*/ -!/.vscode/ -!/.github/ -/*.ref.* -*.lock -*.zip +.styles/ +/foundry.js # Ignore all of the binaries and stuff that gets built for Foundry from the raw # JSON data because it's annoying seeing it in my git changes when it isn't actually diff --git a/.vscode/components.html-data.json b/.vscode/components.html-data.json deleted file mode 100644 index e1c3ebd..0000000 --- a/.vscode/components.html-data.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "dd-incrementer", - "description": "A number input that allows more flexible increase/decrease buttons", - "attributes": [ - { "name": "value", "description": "The initial value to put in the input" }, - { "name": "name", "description": "The form name to use when this input is used to submit data" }, - { "name": "min", "description": "The minimum value that this input can contain" }, - { "name": "max", "description": "The maximum value that this input can contain" }, - { "name": "smallStep", "description": "The value that the input is changed by when clicking a delta button or using the up/down arrow key" }, - { "name": "largeStep", "description": "The value that the input is changed by when clicking a delta button with control held or using the page up/ page down arrow key" } - ] - }, - { - "name": "dd-icon", - "description": "Loads an icon asynchronously, caching the result for future uses", - "attributes": [ - { "name": "name", "description": "The name of the icon, this is relative to the assets folder of the dotdungeon system" }, - { "name": "path", "description": "The full path of the icon, this will only be used if `name` isn't provided or fails to fetch." } - ] - } - ], - "globalAttributes": [], - "valueSets": [] -} diff --git a/.vscode/settings.json b/.vscode/settings.json index 9cd44b8..82812b8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,19 +1,11 @@ { "files.autoSave": "onWindowChange", "editor.tabSize": 2, + "[javascript]": { + "editor.tabSize": 4 + }, "[yaml,yml]": { "editor.insertSpaces": true, "editor.tabSize": 2 - }, - "git.branchProtection": [], - "files.exclude": { - "dotdungeon.lock": true, - ".styles": true, - "node_modules": true, - "packs": true, - ".gitattributes": true, - }, - "html.customData": [ - "./.vscode/components.html-data.json" - ] -} + } +} \ No newline at end of file diff --git a/assets/caret-right.svg b/assets/caret-right.svg new file mode 100644 index 0000000..7d1d59b --- /dev/null +++ b/assets/caret-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/chat-bubble.svg b/assets/chat-bubble.svg new file mode 100644 index 0000000..8dde604 --- /dev/null +++ b/assets/chat-bubble.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/close.svg b/assets/close.svg new file mode 100644 index 0000000..f6c80ed --- /dev/null +++ b/assets/close.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/ui/plus.svg b/assets/create.svg similarity index 100% rename from assets/ui/plus.svg rename to assets/create.svg diff --git a/assets/dice/d10.svg b/assets/dice/d10.svg index 3debc8e..96a39a1 100644 --- a/assets/dice/d10.svg +++ b/assets/dice/d10.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/assets/dice/d12.svg b/assets/dice/d12.svg index df2787c..dac2e4c 100644 --- a/assets/dice/d12.svg +++ b/assets/dice/d12.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/assets/dice/d20.svg b/assets/dice/d20.svg index a829cdf..82cf8b3 100644 --- a/assets/dice/d20.svg +++ b/assets/dice/d20.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/assets/dice/d4.svg b/assets/dice/d4.svg index f31809b..3388bda 100644 --- a/assets/dice/d4.svg +++ b/assets/dice/d4.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/assets/dice/d6.svg b/assets/dice/d6.svg index 00dfed7..bea7528 100644 --- a/assets/dice/d6.svg +++ b/assets/dice/d6.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/assets/dice/d8.svg b/assets/dice/d8.svg index 7731f96..ca3b00b 100644 --- a/assets/dice/d8.svg +++ b/assets/dice/d8.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/assets/edit.svg b/assets/edit.svg new file mode 100644 index 0000000..7cc344b --- /dev/null +++ b/assets/edit.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/garbage-bin.svg b/assets/garbage-bin.svg new file mode 100644 index 0000000..b9268a5 --- /dev/null +++ b/assets/garbage-bin.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/minus.svg b/assets/minus.svg new file mode 100644 index 0000000..171613e --- /dev/null +++ b/assets/minus.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/sheet.svg b/assets/sheet.svg new file mode 100644 index 0000000..eaf555b --- /dev/null +++ b/assets/sheet.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/assets/sources.txt b/assets/sources.txt index 2896d5f..eb52587 100644 --- a/assets/sources.txt +++ b/assets/sources.txt @@ -1,15 +1,11 @@ -Disclaimer: - All icons included in this repo have been scaled and optimized as needed. - Amer Alamer - ui/caret/right.svg (https://thenounproject.com/icon/arrow-caret-right-1143917/) - ui/caret/down.svg (https://thenounproject.com/icon/arrow-caret-down-1143911/) + caret-right.svg (https://thenounproject.com/icon/arrow-caret-right-1143917/) Alice Design: - ui/garbage-bin.svg (https://thenounproject.com/icon/garbage-2025492/) + garbage-bin.svg (https://thenounproject.com/icon/garbage-2025492/) zapesicon: - ui/chat-bubble.svg (https://thenounproject.com/icon/chat-6423186/) + chat-bubble.svg (https://thenounproject.com/icon/chat-6423186/) Fritz Duggan: dice/d4.svg (https://thenounproject.com/icon/d4-4570604/) @@ -20,19 +16,21 @@ Fritz Duggan: dice/d20.svg (https://thenounproject.com/icon/d20-4570607/) Landan Lloyd: - ui/plus.svg (https://thenounproject.com/icon/create-1447560/) + create.svg (https://thenounproject.com/icon/create-1447560/) Bismillah - ui/minus.svg (https://thenounproject.com/icon/minus-1727966/) + minus.svg (https://thenounproject.com/icon/minus-1727966/) Rokhman Kharis: - ui/close.svg (https://thenounproject.com/icon/close-4996834/) + close.svg (https://thenounproject.com/icon/close-4996834/) Athok: - ui/sheet.svg (https://thenounproject.com/icon/sheet-5939348/) + sheet.svg (https://thenounproject.com/icon/sheet-5939348/) Icon Depot: - ui/pencil.svg (https://thenounproject.com/icon/edit-1489252/) + edit.svg (https://thenounproject.com/icon/edit-1489252/) -Muhammad Ahsanu Nadia: - ui/help.svg (https://thenounproject.com/icon/help-6778522/) +Oliver Akins: + chat-bubble.svg : Scaling + create.svg : Scaling, Optimization + sheet.svg : Scaling \ No newline at end of file diff --git a/assets/ui/caret/down.svg b/assets/ui/caret/down.svg deleted file mode 100644 index 5c15836..0000000 --- a/assets/ui/caret/down.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/ui/caret/right.svg b/assets/ui/caret/right.svg deleted file mode 100644 index 3b19a49..0000000 --- a/assets/ui/caret/right.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/ui/chat-bubble.svg b/assets/ui/chat-bubble.svg deleted file mode 100644 index a9182c1..0000000 --- a/assets/ui/chat-bubble.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/ui/close.svg b/assets/ui/close.svg deleted file mode 100644 index 3082802..0000000 --- a/assets/ui/close.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/ui/garbage-bin.svg b/assets/ui/garbage-bin.svg deleted file mode 100644 index dd96a44..0000000 --- a/assets/ui/garbage-bin.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/ui/help.svg b/assets/ui/help.svg deleted file mode 100644 index bd06071..0000000 --- a/assets/ui/help.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/ui/minus.svg b/assets/ui/minus.svg deleted file mode 100644 index d1d3e94..0000000 --- a/assets/ui/minus.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/ui/pencil.svg b/assets/ui/pencil.svg deleted file mode 100644 index 455379f..0000000 --- a/assets/ui/pencil.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/ui/sheet.svg b/assets/ui/sheet.svg deleted file mode 100644 index 32a3268..0000000 --- a/assets/ui/sheet.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/augments.d.ts b/augments.d.ts deleted file mode 100644 index df16590..0000000 --- a/augments.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -interface Actor { - /** The system-specific data */ - system: any; -}; - -interface Item { - /** The system-specific data */ - system: any; -}; diff --git a/jsconfig.json b/jsconfig.json deleted file mode 100644 index 2304d94..0000000 --- a/jsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "compilerOptions": { - "types": [ - "./augments.d.ts" - ] - } -} \ No newline at end of file diff --git a/langs/en-ca.2.json b/langs/en-ca.2.json deleted file mode 100644 index dce0efa..0000000 --- a/langs/en-ca.2.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "dotdungeon": { - "stat": { - "build": "Build", - "meta": "Meta", - "presence": "Presence", - "hands": "Hands", - "tilt": "Tilt", - "rng": "RNG" - }, - "skills": { - "defense": "Defense", - "magic": "Magic", - "melee": "Melee", - "platforming": "Platforming", - "strength": "Strength", - "alchemy": "Alchemy", - "arcanum": "Arcanum", - "dreams": "Dreams", - "lore": "Lore", - "navigation": "Navigation", - "animal_handling": "Animal Handling", - "perception": "Perception", - "sneak": "Sneak", - "speech": "Speech", - "vibes": "Vibes", - "accuracy": "Accuracy", - "crafting": "Crafting", - "engineering": "Engineering", - "explosives": "Explosives", - "piloting": "Piloting" - }, - "trainingLevel": { - "untrained": "Untrained", - "trained": "Trained", - "expert": "Expert", - "locked": "Locked" - }, - "die": { - "d4": "d4", - "d6": "d6", - "d8": "d8", - "d10": "d10", - "d12": "d12", - "d20": "d20" - }, - "sheet": { - "actor": { - "v2": { - "stat-not-chosen": "Select a dice to see the {name} skills", - "skill-roll-locked": "@dotdungeon.trainingLevel.locked", - "toggle-item-information": "Toggle the item's extra information visibility", - "create-item": "Create @TYPES.Item.{type}" - } - }, - "item": { - "untyped": { - "quantity": "Quantity", - "usage": "Usage Cost", - "rarity": "Tier", - "no-description": "This item hasn't been described yet..." - } - } - }, - "rarity": { - "simple": "Simple", - "greater": "Greater", - "rare": "Rare", - "legendary": "Legendary" - }, - "location": { - "unknown": "@dotdungeon.common.empty", - "inventory": "Inventory", - "equipped": "Equipped", - "storage": "Storage" - }, - "default": { - "name": "(Unnamed @TYPES.{document}.{type})" - }, - "common": { - "send-to-chat": "Send to Chat", - "edit": "Edit", - "delete": "Delete", - "reset": "Reset", - "empty": "---", - "help": "Help", - "gm": "Server", - "view-larger": "View Larger" - }, - "sheet-names": { - "*DataSheet": "Data Sheet" - }, - "help-tooltips": { - "calculated-capacity": { - "title": "What is Calculated Capacity?", - "content": "

The calculated capacity is how much space in your inventory that the item will take up, the way it is calculated is determined by the item. Usually the main thing that affects the capacity is the item's quantity, but this can be turned off by the @dotdungeon.common.gm, which means that no matter the quantity it will only use up one capacity. The @dotdungeon.common.gm can also entirely disable capacity usage which will make the used capacity always be zero.

" - } - }, - "delete": { - "ActiveEffect": { - "title": "Delete Effect", - "content": "

Are you sure you would like to delete the active effect: {name}

" - } - } - }, - "TYPES": { - "Actor": { - "player": "Player", - "sync": "Sync" - }, - "Item": { - "aspect": "Aspect", - "weapon": "Weapon", - "armour": "Armour", - "equipment": "Equipment", - "foil": "Foil", - "pet": "Pet", - "structure": "Structure", - "service": "Service", - "material": "Materials", - "legendaryItem": "Legendary Item", - "spell": "Spell", - "untyped": "Custom" - }, - "ActiveEffect": { - "base": "Effect" - } - } -} \ No newline at end of file diff --git a/langs/en-ca.json b/langs/en-ca.json index f2c7ceb..1c1f3cb 100644 --- a/langs/en-ca.json +++ b/langs/en-ca.json @@ -78,10 +78,7 @@ } }, "sheet-names": { - "PlayerSheet": { - "MVP": "MVP PC Sheet", - "v2": "PC Sheet" - }, + "PlayerSheet": "PC/PUG Sheet", "SyncSheet": { "basic": "Theme: Basic" }, diff --git a/module/components/icon.mjs b/module/components/icon.mjs deleted file mode 100644 index 8c70d40..0000000 --- a/module/components/icon.mjs +++ /dev/null @@ -1,125 +0,0 @@ -import { StyledShadowElement } from "./mixins/Styles.mjs"; - -/** -Attributes: -@property {string} name - The name of the icon, takes precedence over the path -@property {string} path - The path of the icon file -*/ -export class DotDungeonIcon extends StyledShadowElement(HTMLElement) { - static elementName = `dd-icon`; - static formAssociated = false; - - /* Stuff for the mixin to use */ - static _stylePath = `v3/components/icon.css`; - - - static _cache = new Map(); - #container; - /** @type {null | string} */ - _name; - /** @type {null | string} */ - _path; - - /* Stored IDs for all of the hooks that are in this component */ - #svgHmr; - - constructor() { - super(); - // this._shadow = this.attachShadow({ mode: `open`, delegatesFocus: true }); - - this.#container = document.createElement(`div`); - this._shadow.appendChild(this.#container); - }; - - _mounted = false; - async connectedCallback() { - super.connectedCallback(); - if (this._mounted) return; - - this._name = this.getAttribute(`name`); - this._path = this.getAttribute(`path`); - - /* - This converts all of the double-dash prefixed properties on the element to - CSS variables so that they don't all need to be provided by doing style="" - */ - for (const attrVar of this.attributes) { - if (attrVar.name?.startsWith(`var:`)) { - const prop = attrVar.name.replace(`var:`, ``); - this.style.setProperty(`--` + prop, attrVar.value); - }; - }; - - /* - Try to retrieve the icon if it isn't present, try the path then default to - the slot content, as then we can have a default per-icon usage - */ - let content; - if (this._name) { - content = await this.#getIcon(`./systems/dotdungeon/assets/${this._name}.svg`); - }; - - if (this._path && !content) { - content = await this.#getIcon(this._path); - }; - - if (content) { - this.#container.appendChild(content.cloneNode(true)); - }; - - /* - This is so that when we get an HMR event from Foundry we can appropriately - handle it using our logic to update the component and the icon cache. - */ - if (game.settings.get(`dotdungeon`, `devMode`)) { - this.#svgHmr = Hooks.on(`dd-hmr:svg`, (iconName, data) => { - if (this._name === iconName || this._path?.endsWith(data.path)) { - const svg = this.#parseSVG(data.content); - this.constructor._cache.set(iconName, svg); - this.#container.replaceChildren(svg.cloneNode(true)); - }; - }); - }; - - this._mounted = true; - }; - - disconnectedCallback() { - super.disconnectedCallback(); - if (!this._mounted) return; - - Hooks.off(`dd-hmr:svg`, this.#svgHmr); - - this._mounted = false; - }; - - async #getIcon(path) { - // Cache hit! - if (this.constructor._cache.has(path)) { - console.debug(`.dungeon | Icon ${path} cache hit`); - return this.constructor._cache.get(path); - }; - - const r = await fetch(path); - switch (r.status) { - case 200: - case 201: - break; - default: - console.error(`.dungeon | Failed to fetch icon: ${path}`); - return; - }; - - console.debug(`.dungeon | Adding icon ${path} to the cache`); - const svg = this.#parseSVG(await r.text()); - this.constructor._cache.set(path, svg); - return svg; - }; - - /** Takes an SVG string and returns it as a DOM node */ - #parseSVG(content) { - const temp = document.createElement(`div`); - temp.innerHTML = content; - return temp.querySelector(`svg`); - }; -}; diff --git a/module/components/incrementer.mjs b/module/components/incrementer.mjs deleted file mode 100644 index 68e426a..0000000 --- a/module/components/incrementer.mjs +++ /dev/null @@ -1,149 +0,0 @@ -import { DotDungeonIcon } from "./icon.mjs"; -import { StyledShadowElement } from "./mixins/Styles.mjs"; - -/** -Attributes: -@property {string} name - The path to the value to update -@property {number} value - The actual value of the input -@property {number} min - The minimum value of the input -@property {number} max - The maximum value of the input -@property {number?} smallStep - The step size used for the buttons and arrow keys -@property {number?} largeStep - The step size used for the buttons + Ctrl and page up / down - -Styling: -- `--height`: Controls the height of the element + the width of the buttons (default: 1.25rem) -- `--width`: Controls the width of the number input (default 50px) -*/ -export class DotDungeonIncrementer extends StyledShadowElement(HTMLElement) { - static elementName = `dd-incrementer`; - static formAssociated = true; - - static _stylePath = `v3/components/incrementer.css`; - - _internals; - #input; - - _min; - _max; - _smallStep; - _largeStep; - - constructor() { - super(); - - // Form internals - this._internals = this.attachInternals(); - this._internals.role = `spinbutton`; - }; - - get form() { - return this._internals.form; - } - - get name() { - return this.getAttribute(`name`); - } - set name(value) { - this.setAttribute(`name`, value); - } - - get value() { - return this.getAttribute(`value`); - }; - set value(value) { - this.setAttribute(`value`, value); - }; - - get type() { - return `number`; - } - - connectedCallback() { - super.connectedCallback(); - this.replaceChildren(); - - // Attribute parsing / registration - const value = this.getAttribute(`value`); - this._min = parseInt(this.getAttribute(`min`) ?? 0); - this._max = parseInt(this.getAttribute(`max`) ?? 0); - this._smallStep = parseInt(this.getAttribute(`smallStep`) ?? 1); - this._largeStep = parseInt(this.getAttribute(`largeStep`) ?? 5); - - this._internals.ariaValueMin = this._min; - this._internals.ariaValueMax = this._max; - - const container = document.createElement(`div`); - - // The input that the user can see / modify - const input = document.createElement(`input`); - this.#input = input; - input.type = `number`; - input.ariaHidden = true; - input.min = this.getAttribute(`min`); - input.max = this.getAttribute(`max`); - input.addEventListener(`change`, this.#updateValue.bind(this)); - input.value = value; - - // plus button - const increment = document.createElement(DotDungeonIcon.elementName); - increment.setAttribute(`name`, `ui/plus`); - increment.setAttribute(`var:size`, `0.75rem`); - increment.setAttribute(`var:fill`, `currentColor`); - increment.ariaHidden = true; - increment.classList.value = `increment`; - increment.addEventListener(`mousedown`, this.#increment.bind(this)); - - // minus button - const decrement = document.createElement(DotDungeonIcon.elementName); - decrement.setAttribute(`name`, `ui/minus`); - decrement.setAttribute(`var:size`, `0.75rem`); - decrement.setAttribute(`var:fill`, `currentColor`); - decrement.ariaHidden = true; - decrement.classList.value = `decrement`; - decrement.addEventListener(`mousedown`, this.#decrement.bind(this)); - - // Construct the DOM - container.appendChild(decrement); - container.appendChild(input); - container.appendChild(increment); - this._shadow.appendChild(container); - - /* - This converts all of the namespace prefixed properties on the element to - CSS variables so that they don't all need to be provided by doing style="" - */ - for (const attrVar of this.attributes) { - if (attrVar.name?.startsWith(`var:`)) { - const prop = attrVar.name.replace(`var:`, ``); - this.style.setProperty(`--` + prop, attrVar.value); - }; - }; - }; - - #updateValue() { - let value = parseInt(this.#input.value); - if (this.getAttribute(`min`)) value = Math.max(this._min, value); - if (this.getAttribute(`max`)) value = Math.min(this._max, value); - this.#input.value = value; - this.value = value; - this.dispatchEvent(new Event(`change`, { bubbles: true })); - }; - - /** @param {Event} $e */ - #increment($e) { - $e.preventDefault(); - let value = parseInt(this.#input.value); - value += $e.ctrlKey ? this._largeStep : this._smallStep; - this.#input.value = value; - this.#updateValue(); - }; - - /** @param {Event} $e */ - #decrement($e) { - $e.preventDefault(); - let value = parseInt(this.#input.value); - value -= $e.ctrlKey ? this._largeStep : this._smallStep; - this.#input.value = value; - this.#updateValue(); - }; -}; diff --git a/module/components/index.mjs b/module/components/index.mjs deleted file mode 100644 index f4d39e9..0000000 --- a/module/components/index.mjs +++ /dev/null @@ -1,23 +0,0 @@ -import { DotDungeonIncrementer } from "./incrementer.mjs"; -import { DotDungeonIcon } from "./icon.mjs"; - -const components = [ - DotDungeonIcon, - DotDungeonIncrementer, -]; - -export function registerCustomComponents() { - (CONFIG.CACHE ??= {}).componentListeners ??= []; - for (const component of components) { - if (!window.customElements.get(component.elementName)) { - console.debug(`.dungeon | Registering component "${component.elementName}"`); - window.customElements.define( - component.elementName, - component - ); - if (component.formAssociated) { - CONFIG.CACHE.componentListeners.push(component.elementName); - } - }; - } -}; diff --git a/module/components/mixins/Styles.mjs b/module/components/mixins/Styles.mjs deleted file mode 100644 index 33d5eb5..0000000 --- a/module/components/mixins/Styles.mjs +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @param {HTMLElement} Base - */ -export function StyledShadowElement(Base) { - return class extends Base { - /** - * The path to the CSS that is loaded - * @type {string} - */ - static _stylePath; - - /** - * The stringified CSS to use - * @type {string} - */ - static _styles; - - /** - * The HTML element of the stylesheet - * @type {HTMLStyleElement} - */ - _style; - - /** @type {ShadowRoot} */ - _shadow; - - /** - * The hook ID for this element's CSS hot reload - * @type {number} - */ - #cssHmr; - - constructor() { - super(); - - this._shadow = this.attachShadow({ mode: `open` }); - this._style = document.createElement(`style`); - this._shadow.appendChild(this._style); - }; - - #mounted = false; - connectedCallback() { - if (this.#mounted) return; - - this._getStyles(); - - if (game.settings.get(`dotdungeon`, `devMode`)) { - this.#cssHmr = Hooks.on(`dd-hmr:css`, (data) => { - if (data.path.endsWith(this.constructor._stylePath)) { - this._style.innerHTML = data.content; - }; - }); - }; - - this.#mounted = true; - }; - - disconnectedCallback() { - if (!this.#mounted) return; - if (this.#cssHmr != null) { - Hooks.off(`dd-hmr:css`, this.#cssHmr); - this.#cssHmr = null; - }; - this.#mounted = false; - }; - - _getStyles() { - if (this.constructor._styles) { - this._style.innerHTML = this.constructor._styles; - } else { - fetch(`./systems/dotdungeon/.styles/${this.constructor._stylePath}`) - .then(r => r.text()) - .then(t => { - this.constructor._styles = t; - this._style.innerHTML = t; - }); - } - }; - }; -}; diff --git a/module/config.mjs b/module/config.mjs index 56a0fb4..37b7adb 100644 --- a/module/config.mjs +++ b/module/config.mjs @@ -1,11 +1,6 @@ export const statDice = [ `d4`, `d6`, `d8`, `d10`, `d12`, `d20` ]; -export const trainingLevels = [ - { key: "locked", label: "dotdungeon.trainingLevel.locked", value: -1 }, - { key: "untrained", label: "dotdungeon.trainingLevel.untrained", value: 0 }, - { key: "trained", label: "dotdungeon.trainingLevel.trained", value: 2 }, - { key: "expert", label: "dotdungeon.trainingLevel.expert", value: 4 }, -]; +export const trainingLevels = [``, `locked`, `+2`, `+4`]; export const damageTypes = [ `slashing`, `piercing`, `smashing`, `gun`, `neon`, `shadow`, `solar` ]; @@ -32,12 +27,9 @@ export const skills = { hands: handsSkills, }; -export const defaultItemTier = `simple`; export const itemTiers = [ - { value: `simple`, label: `dotdungeon.rarity.simple` }, - { value: `greater`, label: `dotdungeon.rarity.greater` }, - { value: `rare`, label: `dotdungeon.rarity.rare` }, - { value: `legendary`, label: `dotdungeon.rarity.legendary` }, + `simple`, `greater`, + `rare`, `legendary` ]; export const syncMilestones = [ @@ -50,24 +42,6 @@ export const syncMilestones = [ export const syncDice = `1d20`; -export const localizerConfig = { - subKeyPattern: /@(?[a-zA-Z\.]+)/gm, - maxDepth: 10, -}; - -export const itemFilters = [ - `material`, - `untyped`, - `aspect`, - `weapon`, - `armour`, - `equipment`, - `foil`, - `pet`, - `structure`, - `service`, -]; - export default { stats, statDice, @@ -80,10 +54,7 @@ export default { handsSkills, allSkills, skills, - defaultItemTier, itemTiers, syncMilestones, syncDice, - localizerConfig, - itemFilters, }; diff --git a/module/dialogs/DiceList.mjs b/module/dialogs/DiceList.mjs index 3c305c8..f9793de 100644 --- a/module/dialogs/DiceList.mjs +++ b/module/dialogs/DiceList.mjs @@ -12,7 +12,7 @@ export class DiceList extends GenericDialog { }; static get defaultOptions() { - const opts = foundry.utils.mergeObject({ + const opts = mergeObject({ ...super.defaultOptions, template: `systems/dotdungeon/templates/dialogs/diceList.hbs`, width: 275, diff --git a/module/documents/ActiveEffect/GenericActiveEffect.mjs b/module/documents/ActiveEffect/GenericActiveEffect.mjs deleted file mode 100644 index 8ee70f3..0000000 --- a/module/documents/ActiveEffect/GenericActiveEffect.mjs +++ /dev/null @@ -1,7 +0,0 @@ -export class DotDungeonActiveEffect extends ActiveEffect { - - // Invert the logic of the disabled property so it's easier to modify via - // embedded controls - get enabled() { return !this.disabled }; - set enabled(newValue) { this.disabled = !newValue }; -}; diff --git a/module/documents/ActiveEffect/_proxy.mjs b/module/documents/ActiveEffect/_proxy.mjs deleted file mode 100644 index 4b51b54..0000000 --- a/module/documents/ActiveEffect/_proxy.mjs +++ /dev/null @@ -1,42 +0,0 @@ -import { DotDungeonActiveEffect } from "./GenericActiveEffect.mjs"; - -const classes = {}; - -const defaultClass = DotDungeonActiveEffect; - -export const ActiveEffectProxy = new Proxy(function () {}, { - construct(target, args) { - const [data] = args; - - if (!classes.hasOwnProperty(data.type)) { - return new defaultClass(...args); - } - - return new classes[data.type](...args); - }, - get(target, prop, receiver) { - - if (["create", "createDocuments"].includes(prop)) { - return function (data, options) { - if (data.constructor === Array) { - return data.map(i => ActiveEffectProxy.create(i, options)) - } - - if (!classes.hasOwnProperty(data.type)) { - return defaultClass.create(data, options); - } - - return classes[data.type].create(data, options); - }; - }; - - if (prop == Symbol.hasInstance) { - return function (instance) { - if (instance instanceof defaultClass) return true; - return Object.values(classes).some(i => instance instanceof i); - }; - }; - - return defaultClass[prop]; - }, -}); diff --git a/module/documents/Actor/GenericActor.mjs b/module/documents/Actor/GenericActor.mjs deleted file mode 100644 index 171af63..0000000 --- a/module/documents/Actor/GenericActor.mjs +++ /dev/null @@ -1,49 +0,0 @@ -export class DotDungeonActor extends Actor { - - /* - Using this to take a "snapshot" of the system data prior to applying AE's so - that the inputs can still have the non-modified value in them, while we still - provide all that data to AE's without needing to disable any inputs. - */ - prepareEmbeddedDocuments() { - this.preAE = foundry.utils.deepClone(this.system); - super.prepareEmbeddedDocuments(); - }; - - async createEmbeddedItem(defaults, opts = {}) { - let items = await this.createEmbeddedDocuments(`Item`, defaults); - if (!Array.isArray(items)) items = items ? [items] : []; - if (items.length == 0) { - throw new Error(`Failed to create any items`); - }; - this.sheet.render(); - if ( - game.settings.get(`dotdungeon`, `openEmbeddedOnCreate`) - && !opts.overrideSheetOpen - ) { - for (const item of items) { - item.sheet.render(true); - }; - }; - }; - - async preItemEmbed(item) { - - // Increases the quantity of already present items if they match via source - let embedded = this.itemTypes[item.type].find(i => { - return i.getFlag(`core`, `sourceId`) === `Item.${item.id}` - }); - if (embedded) { - await embedded.update({"system.quantity": embedded.system.quantity + 1}); - ui.notifications.info( - game.i18n.format( - `dotdungeon.notification.info.increased-item-quantity`, - { name: embedded.name, quantity: embedded.system.quantity } - ), - { console: false } - ); - return false; - }; - return true; - }; -}; diff --git a/module/documents/Actor/Handler.mjs b/module/documents/Actor/Handler.mjs new file mode 100644 index 0000000..06df8fe --- /dev/null +++ b/module/documents/Actor/Handler.mjs @@ -0,0 +1,104 @@ +import PlayerActor from "./Player.mjs"; +import MobActor from "./Mob.mjs"; +import SyncActor from "./Sync.mjs"; + +/** @extends {Actor} */ +export class ActorHandler extends Actor { + proxyTargets = { + player: PlayerActor, + mob: MobActor, + sync: SyncActor, + }; + + constructor(data, ctx) { + super(data, ctx); + }; + + /** @type {class|undefined} */ + get fn() { + return this.proxyTargets[this.type]; + }; + + async proxyFunction(funcName, ...args) { + if (!this.fn?.[funcName]) return; + return await this.fn?.[funcName].bind(this)(...args); + }; + + async openEmbeddedSheet($event) { + if (this.fn?.openEmbeddedSheet) { + this.fn.openEmbeddedSheet.bind(this)($event); + } else { + const data = $event.target.dataset; + let item = await fromUuid(data.embeddedEdit); + item?.sheet.render(true); + }; + }; + + async genericEmbeddedUpdate($event) { + if (this.fn?.genericEmbeddedUpdate) { + return this.fn.genericEmbeddedUpdate.bind(this)($event); + }; + const target = $event.delegateTarget; + const data = target.dataset; + const item = await fromUuid(data.embeddedId); + + let value = target.value; + switch (target.type) { + case "checkbox": value = target.checked; break; + }; + + await item?.update({ [data.embeddedUpdate]: value }); + }; + + async genericEmbeddedDelete($event) { + if (!this.fn?.genericEmbeddedDelete) return; + this.fn.genericEmbeddedDelete.bind(this)($event); + }; + + async genericEmbeddedCreate($event) { + const data = $event.currentTarget.dataset; + if (!this.fn?.[`createCustom${data.embeddedCreate}`]) return; + this.fn?.[`createCustom${data.embeddedCreate}`].bind(this)($event); + }; + + async genericSendToChat($event) { + const data = $event.currentTarget.dataset; + const type = data.messageType; + if (this.fn?.[`send${type}ToChat`]) { + return await this.fn?.[`send${type}ToChat`].bind(this)($event); + }; + if (!data.messageContent) { + console.warn(`.dungeon | Tried to send a chat message with no content`); + return; + }; + let message = await ChatMessage.create({ + content: data.messageContent, + flavor: data.messageFlavor, + speaker: { actor: this.actor } + }); + message.render(); + }; + + /** + * @param {ItemHandler} item + * @returns {boolean} true to allow the document to be embedded + */ + async preItemEmbed(item) { + let type = item.type[0].toUpperCase() + item.type.slice(1); + if (this.fn?.[`pre${type}Embed`]) { + return await this.fn?.[`pre${type}Embed`].bind(this)(item); + }; + return true; + }; + + _preUpdate(...args) { + return this.proxyFunction("_preUpdate", ...args); + }; + + getRollData() { + if (!this.fn?.getRollData) return {}; + return this.fn?.getRollData.bind(this)(); + }; + + useRestDie() {return this.proxyFunction("useRestDie")}; +}; diff --git a/module/documents/Actor/Mob.mjs b/module/documents/Actor/Mob.mjs index cca7e96..16f397f 100644 --- a/module/documents/Actor/Mob.mjs +++ b/module/documents/Actor/Mob.mjs @@ -1,10 +1,11 @@ -import { DotDungeonActor } from "./GenericActor.mjs"; - -export class Mob extends DotDungeonActor { - getRollData() { - const data = { - initiative: this.system.initiative ?? 0, - }; - return data; +/** @this {Actor} */ +function getRollData() { + const data = { + initiative: this.system.initiative ?? 0, }; + return data; +}; + +export default { + getRollData, }; diff --git a/module/documents/Actor/Player.mjs b/module/documents/Actor/Player.mjs index 2c5840d..0cafed5 100644 --- a/module/documents/Actor/Player.mjs +++ b/module/documents/Actor/Player.mjs @@ -1,51 +1,155 @@ -import { DotDungeonActor } from "./GenericActor.mjs"; +import { ItemHandler } from "../Item/Handler.mjs"; -export class Player extends DotDungeonActor { +/** @this {Actor} */ +async function genericEmbeddedDelete($event) { + let data = $event.currentTarget.dataset; + let item = await fromUuid(data.embeddedId); - applyActiveEffects() { - super.applyActiveEffects(); - - /* - These are the (groups of) fields that ActiveEffects may modify safely and - remain editable in the sheet. This needs to be done because of default - Foundry behaviour that otherwise prevents these fields from being edited. - The deletes must use optional chaining otherwise they can cause issues - during the document preparation lifecycle as an actor with no AE's affecting - anything in one of these areas will result in these paths being undefined. - */ - delete this.overrides.system?.stats; - delete this.overrides.system?.skills; - }; - - async createCustomPet() { - const body = new URLSearchParams({ - number: 1, - animal: `Cat`, - "X-Requested-With": "fetch" - }); - const r = await fetch( - `https://randommer.io/pet-names`, - { - method: "POST", - body - } + if (!item) { + ui.notifications.error( + `dotdungeon.notification.error.item-not-found`, + { console: false } ); - await this.createEmbeddedItem([{ - type: `pet`, - name: (await r.json())[0] ?? game.i18n.localize(`dotdungeon.defaults.pet.name`), - }]); + return; }; - get atAspectLimit() { - let limit = game.settings.get(`dotdungeon`, `aspectLimit`); - return this.itemTypes.aspect.length >= limit; - }; + Dialog.confirm({ + title: game.i18n.format( + `dotdungeon.dialogs.${item.type}.delete.title`, + item + ), + content: game.i18n.format( + `dotdungeon.dialogs.${item.type}.delete.content`, + item + ), + yes: () => { + item.delete(); + }, + defaultYes: false, + }); +}; - getRollData() { - const data = { - initiative: this.system.stats.hands ?? 0, - stats: this.system.stats, +/** @this {Actor} */ +async function createCustomItem(defaults, opts = {}) { + let items = await this.createEmbeddedDocuments(`Item`, defaults); + if (items.length == 0) { + throw new Error(); + }; + this.sheet.render(); + if ( + game.settings.get(`dotdungeon`, `openEmbeddedOnCreate`) + && !opts.overrideSheetOpen + ) { + for (const item of items) { + item.sheet.render(true); }; - return data; }; }; + +/** @this {Actor} */ +async function createCustomUntyped() { + await createCustomItem.bind(this)([{ + type: `untyped`, + name: game.i18n.format(`dotdungeon.defaults.untyped.name`), + }]); +}; + +/** @this {Actor} */ +async function createCustomAspect() { + await createCustomItem.bind(this)([{ + type: `aspect`, + name: game.i18n.format(`dotdungeon.defaults.aspect.name`), + }]); +}; + +/** @this {Actor} */ +async function createCustomSpell() { + await createCustomItem.bind(this)([{ + type: `spell`, + name: game.i18n.format(`dotdungeon.defaults.spell.name`), + }]); +}; + +/** @this {Actor} */ +async function createCustomPet() { + const body = new URLSearchParams({ + number: 1, + animal: `Cat`, + "X-Requested-With": "fetch" + }) + const r = await fetch( + `https://randommer.io/pet-names`, + { + method: "POST", + body + } + ); + await createCustomItem.bind(this)([{ + type: `pet`, + name: (await r.json())[0] ?? game.i18n.localize(`dotdungeon.defaults.pet.name`), + }]); +}; + +/** @this {Actor} */ +async function atAspectLimit() { + let limit = game.settings.get(`dotdungeon`, `aspectLimit`); + return this.itemTypes.aspect.length >= limit; +}; + +/** + * @param {ItemHandler} item + * @this {Actor} + */ +async function preAspectEmbed(item) { + if (await atAspectLimit.bind(this)()) { + ui.notifications.error( + game.i18n.format( + `dotdungeon.notification.error.aspect-limit-reached`, + { limit: game.settings.get(`dotdungeon`, `aspectLimit`) } + ), + { console: false } + ); + return false; + }; +}; + +/** + * @param {ItemHandler} item + * @this {Actor} + */ +async function preUntypedEmbed(item) { + let inventoryItem = this.itemTypes.untyped.find(i => i.name === item.name); + if (inventoryItem) { + inventoryItem.update({"system.quantity": inventoryItem.system.quantity + 1}); + ui.notifications.info( + game.i18n.format( + `dotdungeon.notification.info.increased-item-quantity`, + { name: inventoryItem.name } + ), + { console: false } + ); + return false; + }; +}; + +/** @this {Actor} */ +function getRollData() { + const data = { + initiative: this.system.stats.hands ?? 0, + stats: this.system.stats, + }; + return data; +}; + +export default { + atAspectLimit, + createCustomItem, + createCustomUntyped, + createCustomAspect, + createCustomSpell, + createCustomPet, + genericEmbeddedDelete, + preAspectEmbed, + preUntypedEmbed, + getRollData, +}; diff --git a/module/documents/Actor/Sync.mjs b/module/documents/Actor/Sync.mjs index 171a67c..caa5a5d 100644 --- a/module/documents/Actor/Sync.mjs +++ b/module/documents/Actor/Sync.mjs @@ -1,56 +1,60 @@ -import { DotDungeonActor } from "./GenericActor.mjs"; -import { syncMilestones } from "../../config.mjs"; +import { syncMilestones, syncDice } from "../../config.mjs"; -export class Sync extends DotDungeonActor { - async useRestDie() { - let addToSync = await (new Roll(syncDice)).evaluate(); - await addToSync.toMessage({ - speaker: ChatMessage.getSpeaker({ actor: this.actor }), - flavor: `Sync Restoration`, - }); - this.update({ - "system.rest_dice": this.system.rest_dice - 1, - "system.value": this.system.value + addToSync.total, - }); - }; +/** @this {Actor} */ +async function useRestDie() { + let addToSync = await (new Roll(syncDice)).evaluate(); + await addToSync.toMessage({ + speaker: ChatMessage.getSpeaker({ actor: this.actor }), + flavor: `Sync Restoration`, + }); + this.update({ + "system.rest_dice": this.system.rest_dice - 1, + "system.value": this.system.value + addToSync.total, + }); +}; - async _preUpdate(data, options) { - if (options.diff) { - if (data.system?.value != null) { - let currentSync = this.system.value; - let newSync = data.system.value; +/** @this {Actor} */ +async function _preUpdate(data, options) { + if (options.diff) { + if (data.system?.value != null) { + let currentSync = this.system.value; + let newSync = data.system.value; - let minSync = Math.min(currentSync, newSync); - let maxSync = Math.max(currentSync, newSync); - let milestones = syncMilestones.filter( - m => minSync < m.value && m.value <= maxSync - ); + let minSync = Math.min(currentSync, newSync); + let maxSync = Math.max(currentSync, newSync); + let milestones = syncMilestones.filter( + m => minSync < m.value && m.value <= maxSync + ); - if (milestones.length > 0) data.system.rest_dice ??= this.system.rest_dice; + if (milestones.length > 0) data.system.rest_dice ??= this.system.rest_dice; - for (const milestone of milestones) { - // Damage - if (newSync < currentSync) { - if (!this.system.milestones_hit.has(milestone.value)) { - data.system.rest_dice += 1; - this.system.milestones_hit.add(milestone.value); - }; - } + for (const milestone of milestones) { + // Damage + if (newSync < currentSync) { + if (!this.system.milestones_hit.has(milestone.value)) { + data.system.rest_dice += 1; + this.system.milestones_hit.add(milestone.value); + }; + } - // Healing - else if (newSync > currentSync) { - if ( - this.system.milestones_hit.has(milestone.value) - && milestone.andReturn - && milestone.value <= newSync - ) { - this.system.milestones_hit.delete(milestone.value); - }; + // Healing + else if (newSync > currentSync) { + if ( + this.system.milestones_hit.has(milestone.value) + && milestone.andReturn + && milestone.value <= newSync + ) { + this.system.milestones_hit.delete(milestone.value); }; }; - - data.system.milestones_hit = [ ...this.system.milestones_hit ]; }; + + data.system.milestones_hit = [ ...this.system.milestones_hit ]; }; }; }; + +export default { + _preUpdate, + useRestDie, +}; diff --git a/module/documents/Actor/_proxy.mjs b/module/documents/Actor/_proxy.mjs deleted file mode 100644 index dd6cf6c..0000000 --- a/module/documents/Actor/_proxy.mjs +++ /dev/null @@ -1,49 +0,0 @@ -import { DotDungeonActor } from "./GenericActor.mjs"; -import { Player } from "./Player.mjs"; -import { Sync } from "./Sync.mjs"; -import { Mob } from "./Mob.mjs"; - -const classes = { - player: Player, - mob: Mob, - sync: Sync, -}; - -const defaultClass = DotDungeonActor; - -export const ActorProxy = new Proxy(function () {}, { - construct(target, args) { - const [data] = args; - - if (!classes.hasOwnProperty(data.type)) { - return new defaultClass(...args); - } - - return new classes[data.type](...args); - }, - get(target, prop, receiver) { - - if (["create", "createDocuments"].includes(prop)) { - return function (data, options) { - if (data.constructor === Array) { - return data.map(i => ActorProxy.create(i, options)) - } - - if (!classes.hasOwnProperty(data.type)) { - return defaultClass.create(data, options); - } - - return classes[data.type].create(data, options); - }; - }; - - if (prop == Symbol.hasInstance) { - return function (instance) { - if (instance instanceof defaultClass) return true; - return Object.values(classes).some(i => instance instanceof i); - }; - }; - - return defaultClass[prop]; - }, -}); diff --git a/module/documents/Item/Aspect.mjs b/module/documents/Item/Aspect.mjs index ea66b6c..bf6e764 100644 --- a/module/documents/Item/Aspect.mjs +++ b/module/documents/Item/Aspect.mjs @@ -1,42 +1,10 @@ -import { DotDungeonItem } from "./GenericItem.mjs"; - -const secondsInAMinute = 60; -const secondsInAnHour = 60 * secondsInAMinute; - -export class Aspect extends DotDungeonItem { - async _preCreate() { - if (this.isEmbedded) { - if (this.actor.atAspectLimit) { - ui.notifications.error( - game.i18n.format( - `dotdungeon.notification.error.aspect-limit-reached`, - { limit: game.settings.get(`dotdungeon`, `aspectLimit`) } - ), - { console: false } - ); - return false; - }; - - return await this.actor?.preItemEmbed(this); - }; - }; - - get friendlyDuration() { - let friendly = ``; - let duration = this.system.deactivateAfter; - if (duration >= secondsInAnHour) { - let hours = Math.floor(duration / secondsInAnHour); - friendly += `${hours}h`; - duration -= hours * secondsInAnHour; - }; - if (duration >= secondsInAMinute) { - let minutes = Math.floor(duration / secondsInAMinute); - friendly += `${minutes}m`; - duration -= minutes * secondsInAMinute; - }; - if (duration > 0) { - friendly += `${duration}s`; - }; - return friendly; +/** @this {ItemHandler} */ +async function _preCreate(_data, _options, _user) { + if (this.isEmbedded) { + return await this.actor?.preItemEmbed(this); }; }; + +export default { + _preCreate, +}; diff --git a/module/documents/Item/GenericItem.mjs b/module/documents/Item/GenericItem.mjs deleted file mode 100644 index 786824e..0000000 --- a/module/documents/Item/GenericItem.mjs +++ /dev/null @@ -1,24 +0,0 @@ -export class DotDungeonItem extends Item { - async _preCreate() { - if (this.isEmbedded) { - return await this.actor?.preItemEmbed(this); - }; - }; - - get usedCapacity() { - if (!this.system.uses_inventory_slot) return 0; - if (!this.system.quantity_affects_used_capacity) { - return 1; - }; - return this.system.quantity; - }; - - get availableLocations() { - return [ - { value: null, label: `dotdungeon.location.unknown` }, - { value: `inventory`, label: `dotdungeon.location.inventory` }, - { value: `equipped`, label: `dotdungeon.location.equipped` }, - { value: `storage`, label: `dotdungeon.location.storage` }, - ]; - }; -}; diff --git a/module/documents/Item/Handler.mjs b/module/documents/Item/Handler.mjs new file mode 100644 index 0000000..dbb6903 --- /dev/null +++ b/module/documents/Item/Handler.mjs @@ -0,0 +1,30 @@ +import AspectItem from "./Aspect.mjs"; +import SpellItem from "./Spell.mjs"; + +/** @extends {Item} */ +export class ItemHandler extends Item { + proxyTargets = { + aspect: AspectItem, + spell: SpellItem, + }; + + constructor(data, ctx) { + super(data, ctx); + }; + + /** @type {class|undefined} */ + get fn() { + return this.proxyTargets[this.type]; + }; + + async proxyFunction(funcName, ...args) { + if (!this.fn?.[funcName]) return; + return await this.fn?.[funcName].bind(this)(...args); + }; + + async _preCreate(...args) { + if (this.fn?._preCreate) return this.fn?._preCreate.bind(this)(...args); + if (this.isEmbedded) return await this.actor?.preItemEmbed(this); + return; + }; +}; diff --git a/module/documents/Item/Material.mjs b/module/documents/Item/Material.mjs deleted file mode 100644 index c6c5b72..0000000 --- a/module/documents/Item/Material.mjs +++ /dev/null @@ -1,15 +0,0 @@ -import { DotDungeonItem } from "./GenericItem.mjs"; - -export class Material extends DotDungeonItem { - get usedCapacity() { - let affects = game.settings.get(`dotdungeon`, `materialsAffectCapacity`); - return affects ? super.usedCapacity : 0; - }; - - get availableLocations() { - return [ - { value: null, label: `dotdungeon.location.unknown` }, - { value: `inventory`, label: `dotdungeon.location.inventory` }, - ]; - }; -}; diff --git a/module/documents/Item/Spell.mjs b/module/documents/Item/Spell.mjs new file mode 100644 index 0000000..ff8b4c5 --- /dev/null +++ b/module/documents/Item/Spell.mjs @@ -0,0 +1 @@ +export default {}; diff --git a/module/documents/Item/_proxy.mjs b/module/documents/Item/_proxy.mjs deleted file mode 100644 index b579136..0000000 --- a/module/documents/Item/_proxy.mjs +++ /dev/null @@ -1,47 +0,0 @@ -import { DotDungeonItem } from "./GenericItem.mjs"; -import { Aspect } from "./Aspect.mjs"; -import { Material } from "./Material.mjs"; - -const classes = { - aspect: Aspect, - material: Material, -}; - -const defaultClass = DotDungeonItem; - -export const ItemProxy = new Proxy(function () {}, { - construct(target, args) { - const [data] = args; - - if (!classes.hasOwnProperty(data.type)) { - return new defaultClass(...args); - } - - return new classes[data.type](...args); - }, - get(target, prop, receiver) { - - if (["create", "createDocuments"].includes(prop)) { - return function (data, options) { - if (data.constructor === Array) { - return data.map(i => ItemProxy.create(i, options)) - } - - if (!classes.hasOwnProperty(data.type)) { - return defaultClass.create(data, options); - } - - return classes[data.type].create(data, options); - }; - }; - - if (prop == Symbol.hasInstance) { - return function (instance) { - if (instance instanceof defaultClass) return true; - return Object.values(classes).some(i => instance instanceof i); - }; - }; - - return defaultClass[prop]; - }, -}); diff --git a/module/dotdungeon.mjs b/module/dotdungeon.mjs index 8731314..d29492f 100644 --- a/module/dotdungeon.mjs +++ b/module/dotdungeon.mjs @@ -1,7 +1,5 @@ // Data Models import { DescribedItemData } from "./models/Item/DescribedItemData.mjs"; -import { CommonItemData } from "./models/Item/CommonItemData.mjs"; -import { WeaponItemData } from "./models/Item/Weapon.mjs"; import { AspectItemData } from "./models/Item/Aspect.mjs"; import { SpellItemData } from "./models/Item/Spell.mjs"; import { PlayerData } from "./models/Actor/Player.mjs"; @@ -10,9 +8,8 @@ import { SyncData } from "./models/Actor/Sync.mjs"; import { MobData } from "./models/Actor/Mob.mjs"; // Main Documents -import { ActiveEffectProxy } from "./documents/ActiveEffect/_proxy.mjs"; -import { ActorProxy } from "./documents/Actor/_proxy.mjs"; -import { ItemProxy } from "./documents/Item/_proxy.mjs"; +import { ActorHandler } from "./documents/Actor/Handler.mjs"; +import { ItemHandler } from "./documents/Item/Handler.mjs"; // Item Sheets import { UntypedItemSheet } from "./sheets/Items/UntypedItemSheet.mjs"; @@ -22,8 +19,7 @@ import { PetSheet } from "./sheets/Items/PetSheet.mjs"; // Actor Sheets import { BasicSyncSheet } from "./sheets/SyncVariations/BasicSyncSheet.mjs"; -import { PlayerSheetv2 } from "./sheets/Actors/PC/PlayerSheetV2.mjs"; -import { MVPPCSheet } from "./sheets/MVPPCSheet.mjs"; +import { PlayerSheet } from "./sheets/PlayerSheet.mjs"; import { MobSheet } from "./sheets/MobSheet.mjs"; // Utility imports @@ -33,15 +29,12 @@ import * as hbs from "./handlebars.mjs"; import "./hooks/hotReload.mjs"; // Misc Imports -import { registerCustomComponents } from "./components/index.mjs"; import loadSettings from "./settings/index.mjs"; -import { devInit } from "./hooks/devInit.mjs"; import DOTDUNGEON from "./config.mjs"; Hooks.once(`init`, async () => { console.debug(`.dungeon | Initializing`); - CONFIG.ActiveEffect.legacyTransferral = false; loadSettings(); @@ -49,28 +42,19 @@ Hooks.once(`init`, async () => { CONFIG.Actor.dataModels.sync = SyncData; CONFIG.Actor.dataModels.mob = MobData; CONFIG.Item.dataModels.untyped = DescribedItemData; - CONFIG.Item.dataModels.material = CommonItemData; - CONFIG.Item.dataModels.foil = DescribedItemData; - CONFIG.Item.dataModels.weapon = WeaponItemData; CONFIG.Item.dataModels.aspect = AspectItemData; CONFIG.Item.dataModels.spell = SpellItemData; CONFIG.Item.dataModels.pet = PetItemData; - CONFIG.Actor.documentClass = ActorProxy; - CONFIG.Item.documentClass = ItemProxy; - CONFIG.ActiveEffect.documentClass = ActiveEffectProxy; + CONFIG.Actor.documentClass = ActorHandler; + CONFIG.Item.documentClass = ItemHandler; CONFIG.DOTDUNGEON = DOTDUNGEON; - Actors.registerSheet("dotdungeon", MVPPCSheet, { + Actors.registerSheet("dotdungeon", PlayerSheet, { makeDefault: true, types: ["player"], - label: "dotdungeon.sheet-names.PlayerSheet.MVP" - }); - Actors.registerSheet("dotdungeon", PlayerSheetv2, { - makeDefault: false, - types: ["player"], - label: "dotdungeon.sheet-names.PlayerSheet.v2" + label: "dotdungeon.sheet-names.PlayerSheet" }); Actors.registerSheet("dotdungeon", MobSheet, { makeDefault: true, @@ -106,13 +90,12 @@ Hooks.once(`init`, async () => { label: "dotdungeon.sheet-names.PetSheet" }); - if (true || game.settings.get(`dotdungeon`, `devMode`)) { - devInit(); - }; hbs.registerHandlebarsHelpers(); hbs.preloadHandlebarsTemplates(); - registerCustomComponents(); + + CONFIG.CACHE = {}; + CONFIG.CACHE.icons = await hbs.preloadIcons(); }); diff --git a/module/handlebars.mjs b/module/handlebars.mjs index cdaa1b7..ff1c80d 100644 --- a/module/handlebars.mjs +++ b/module/handlebars.mjs @@ -7,7 +7,7 @@ export const partials = [ `partials/panel.hbs`, `items/aspect.hbs`, - // All of the partials for the PC MVP sheet panels + // All of the partials for the PC sheet panels `actors/char-sheet-mvp/panels/aspect.pc.hbs`, `actors/char-sheet-mvp/panels/backpack.pc.hbs`, `actors/char-sheet-mvp/panels/mounts.pc.hbs`, @@ -18,30 +18,25 @@ export const partials = [ `actors/char-sheet-mvp/panels/pets.pc.hbs`, `actors/char-sheet-mvp/panels/sync.pc.hbs`, `actors/char-sheet-mvp/panels/weapons.pc.hbs`, - - // The v2 PC sheet partials - `actors/char-sheet/v2/partials/stats.v2.pc.hbs`, - `actors/char-sheet/v2/partials/effects.v2.pc.hbs`, - `actors/char-sheet/v2/partials/inventory/inventory.v2.pc.hbs`, - `actors/char-sheet/v2/partials/inventory/player.v2.pc.hbs`, - `actors/char-sheet/v2/partials/inventory/item-list.v2.pc.hbs`, - `actors/char-sheet/v2/partials/inventory/storage.v2.pc.hbs`, - `actors/char-sheet/v2/partials/inventory/items/material.v2.pc.hbs`, - `actors/char-sheet/v2/partials/inventory/items/untyped.v2.pc.hbs`, - `actors/char-sheet/v2/partials/inventory/items/aspect.v2.pc.hbs`, - `actors/char-sheet/v2/partials/inventory/items/weapon.v2.pc.hbs`, - `actors/char-sheet/v2/partials/inventory/items/pet.v2.pc.hbs`, - - // The v2 Untyped sheet partials - `items/untyped/v2/tabs/general.v2.untyped.hbs`, - `items/untyped/v2/tabs/details.v2.untyped.hbs`, - `items/untyped/v2/tabs/effects.v2.untyped.hbs`, - `items/untyped/v2/tabs/settings.v2.untyped.hbs`, ]; -export const preAliasedPartials = { - "dotdungeon.pc.v2.foil": "actors/char-sheet/v2/partials/inventory/items/untyped.v2.pc.hbs", -}; +export const icons = [ + `caret-right.svg`, + `garbage-bin.svg`, + `chat-bubble.svg`, + `dice/d4.svg`, + `dice/d6.svg`, + `dice/d8.svg`, + `dice/d10.svg`, + `dice/d12.svg`, + `dice/d20.svg`, + `create.svg`, + `close.svg`, + `edit.svg`, + `sheet.svg`, + `minus.svg`, +]; + export async function registerHandlebarsHelpers() { Handlebars.registerHelper(helpers); @@ -53,10 +48,6 @@ export async function preloadHandlebarsTemplates() { const paths = {}; - for (const alias in preAliasedPartials) { - paths[alias] = `${pathPrefix}${preAliasedPartials[alias]}`; - }; - for ( const partial of partials ) { console.debug(`Loading partial: ${partial}`); const path = `${pathPrefix}${partial}`; @@ -78,3 +69,38 @@ export async function preloadHandlebarsTemplates() { console.groupEnd(); return loadTemplates(paths); }; + +/** + * Loads all of the icons that are needed in the handlebars templating to make + * the sheet look nicer. + * + * @returns An object containing icon names to the corresponding HTML data for + * displaying the icon + */ +export async function preloadIcons() { + const pathPrefix = `systems/dotdungeon/assets/` + const parsedIcons = {}; + + for (const icon of icons) { + const iconName = icon.split(`/`).slice(-1)[0].slice(0, -4); + if (icon.endsWith(`.svg`)) { + try { + const response = await fetchWithTimeout(`${pathPrefix}${icon}`); + if (response.status !== 200) { continue }; + const svgData = await response.text(); + parsedIcons[iconName] = svgData; + } catch { + console.error(`.dungeon | Failed to fetch/parse icon: ${icon}`); + continue; + }; + } + else if (icon.endsWith(`.png`)) { + parsedIcons[iconName] = ``; + } + else { + console.warn(`.dungeon | Icon "${icon}" failed to be handled by a loader`) + }; + }; + + return parsedIcons; +}; diff --git a/module/helpers/index.mjs b/module/helpers/index.mjs index b48baa3..246c04d 100644 --- a/module/helpers/index.mjs +++ b/module/helpers/index.mjs @@ -2,24 +2,20 @@ import { schemaOptions } from "./schemaOptions.mjs"; import { createArray } from "./createArray.mjs"; import { detailsExpanded } from "./detailsExpanded.mjs"; import { objectValue } from "./objectValue.mjs"; -import { handlebarsLocalizer, localizer } from "../utils/localizer.mjs"; -import { options } from "./options.mjs"; +import { toFriendlyDuration } from "./toFriendlyDuration.mjs"; export default { // Complex helpers "dd-schemaOptions": schemaOptions, "dd-array": createArray, + "dd-toFriendlyDuration": toFriendlyDuration, "dd-objectValue": objectValue, "dd-expanded": detailsExpanded, - "dd-i18n": handlebarsLocalizer, - "dd-options": options, // Simple helpers "dd-stringify": v => JSON.stringify(v, null, ` `), "dd-empty": v => v.length == 0, - "dd-set-has": (s, k) => s.has(k), - "dd-empty-state": (v) => v ?? localizer(`dotdungeon.common.empty`), // Logic helpers "eq": (a, b) => a == b, diff --git a/module/helpers/options.mjs b/module/helpers/options.mjs deleted file mode 100644 index 97a2d62..0000000 --- a/module/helpers/options.mjs +++ /dev/null @@ -1,35 +0,0 @@ -import { localizer } from "../utils/localizer.mjs"; - -/** - * @typedef {object} Option - * @property {string} [label] - * @property {string|number} value - * @property {boolean} [disabled] - */ - -/** - * @param {string | number} selected - * @param {Array` - ); - }; - return htmlOptions.join(`\n`); -}; diff --git a/module/helpers/toFriendlyDuration.mjs b/module/helpers/toFriendlyDuration.mjs new file mode 100644 index 0000000..92fb346 --- /dev/null +++ b/module/helpers/toFriendlyDuration.mjs @@ -0,0 +1,26 @@ +const secondsInAMinute = 60; +const secondsInAnHour = 60 * secondsInAMinute; + + +/** + * Converts a duration into a more human-friendly format + * @param {number} duration The length of time in seconds + * @returns The human-friendly time string + */ +export function toFriendlyDuration(duration) { + let friendly = ``; + if (duration >= secondsInAnHour) { + let hours = Math.floor(duration / secondsInAnHour); + friendly += `${hours}h`; + duration -= hours * secondsInAnHour; + }; + if (duration >= secondsInAMinute) { + let minutes = Math.floor(duration / secondsInAMinute); + friendly += `${minutes}m`; + duration -= minutes * secondsInAMinute; + }; + if (duration > 0) { + friendly += `${duration}s`; + }; + return friendly; +}; diff --git a/module/hooks/devInit.mjs b/module/hooks/devInit.mjs deleted file mode 100644 index b7ef326..0000000 --- a/module/hooks/devInit.mjs +++ /dev/null @@ -1,27 +0,0 @@ -/* -Initialization of dev-specific features for the init hook, this is primarily -used to register all of the data sheets of various entity types. -*/ - -import { GroupDataSheet } from "../sheets/Datasheets/GroupDataSheet.mjs"; -import { UntypedDataSheet } from "../sheets/Datasheets/UntypedDataSheet.mjs"; - -export function devInit() { - Items.registerSheet( - `dotdungeon`, - UntypedDataSheet, - { - types: [`untyped`, `foil`], - label: `dotdungeon.sheet-names.*DataSheet`, - } - ); - - Actors.registerSheet( - `dotdungeon`, - GroupDataSheet, - { - types: [`sync`], - label: `dotdungeon.sheet-names.*DataSheet`, - } - ); -}; diff --git a/module/hooks/hotReload.mjs b/module/hooks/hotReload.mjs index 8c44a46..d3d1495 100644 --- a/module/hooks/hotReload.mjs +++ b/module/hooks/hotReload.mjs @@ -3,8 +3,8 @@ import * as hbs from "../handlebars.mjs"; const loaders = { svg(data) { const iconName = data.path.split(`/`).slice(-1)[0].slice(0, -4); - console.debug(`.dungeon | hot-reloading icon: ${iconName}`); - Hooks.call(`dd-hmr:svg`, iconName, data); + console.log(`.dungeon | hot-reloading icon: ${iconName}`); + CONFIG.CACHE.icons[iconName] = data.content; }, hbs(data) { if (!hbs.partials.some(p => data.path.endsWith(p))) { @@ -33,12 +33,6 @@ const loaders = { return false; }, - js() {window.location.reload()}, - mjs() {window.location.reload()}, - css(data) { - console.debug(`.dungeon | Hot-reloading CSS: ${data.path}`); - Hooks.call(`dd-hmr:css`, data); - }, }; Hooks.on(`hotReload`, async (data) => { diff --git a/module/models/Actor/Player.mjs b/module/models/Actor/Player.mjs index 244c887..bd554ad 100644 --- a/module/models/Actor/Player.mjs +++ b/module/models/Actor/Player.mjs @@ -1,4 +1,4 @@ -import DOTDUNGEON from "../../config.mjs"; +import { MappingField } from "../fields/MappingField.mjs"; function diceChoiceField() { return new foundry.data.fields.StringField({ @@ -6,17 +6,33 @@ function diceChoiceField() { blank: true, trim: true, options() { - return DOTDUNGEON.statDice; + return CONFIG.DOTDUNGEON.statDice; }, }); }; function trainingLevelField() { - return new foundry.data.fields.NumberField({ - initial: 0, - min: -1, - integer: true, - options: Object.values(DOTDUNGEON.trainingLevels), + return new foundry.data.fields.StringField({ + initial: ``, + blank: true, + trim: true, + options: CONFIG.DOTDUNGEON.trainingLevels, + }); +}; + +function weaponDamageTypeField() { + return new foundry.data.fields.StringField({ + initial: ``, + blank: true, + options: [ ``, ...CONFIG.DOTDUNGEON.damageTypes ], + }); +}; + +function ammoTypeField() { + return new foundry.data.fields.StringField({ + initial: ``, + blank: true, + options: [ ``, ...CONFIG.DOTDUNGEON.ammoTypes ], }); }; @@ -24,14 +40,6 @@ export class PlayerData extends foundry.abstract.TypeDataModel { static defineSchema() { const fields = foundry.data.fields; return { - /* - These are special data properties that will be used by ActiveEffects - to modify certain limits within the actor, allowing for neat hacks - that change these - */ - weapon_slots: new fields.NumberField({ initial: 2 }), - inventory_slots: new fields.NumberField({ initial: 0 }), - bytes: new fields.NumberField({ initial: 0, min: 0, @@ -75,18 +83,65 @@ export class PlayerData extends foundry.abstract.TypeDataModel { piloting: trainingLevelField(), }) }), - // ! Delete + aspect: new fields.SchemaField({ + name: new fields.StringField({ blank: true, trim: true }), + description: new fields.StringField({ blank: true, trim: true }), + deactivateAfter: new fields.NumberField({ min: 0, integer: true}), + used: new fields.BooleanField(), + }), roles: new fields.SchemaField({ r1: new fields.StringField({ blank: true, trim: true }), r2: new fields.StringField({ blank: true, trim: true }), r3: new fields.StringField({ blank: true, trim: true }), r4: new fields.StringField({ blank: true, trim: true }), }), + weapon: new fields.SchemaField({ + mainHand: new fields.SchemaField({ + name: new fields.StringField({ initial: ``, blank: true, trim: true }), + damage: weaponDamageTypeField(), + ranged: new fields.BooleanField({ initial: false }), + scope: new fields.BooleanField({ initial: false }), + ammo: ammoTypeField(), + }), + offHand: new fields.SchemaField({ + name: new fields.StringField({ initial: ``, blank: true, trim: true }), + damage: weaponDamageTypeField(), + ranged: new fields.BooleanField({ initial: false }), + scope: new fields.BooleanField({ initial: false }), + ammo: ammoTypeField(), + }), + ammo: new fields.SchemaField({ + quivers: new fields.NumberField({ min: 0, max: 10, integer: true }), + mags: new fields.NumberField({ min: 0, max: 10, integer: true }), + cells: new fields.NumberField({ min: 0, max: 10, integer: true }), + }), + }), supplies: new fields.NumberField({ initial: 0, min: 0, integer: true }), + materials: new fields.NumberField({ + initial: 0, + min: 0, + integer: true + }), + pet: new fields.SchemaField({ + name: new fields.StringField(), + info: new fields.StringField(), + }), + transport: new fields.SchemaField({ + name: new fields.StringField(), + upkeep: new fields.NumberField({ min: 0, integer: true }), + info: new fields.StringField(), + }), + spells: new MappingField( + new fields.SchemaField({ + name: new fields.StringField({ initial: ``, blank: true, trim: true }), + cost: new fields.NumberField({ initial: 0, min: 0 }), + info: new fields.StringField({ initial: ``, blank: true, trim: true }), + }) + ), respawns: new fields.SchemaField({ r1: new fields.BooleanField(), r2: new fields.BooleanField(), @@ -97,6 +152,7 @@ export class PlayerData extends foundry.abstract.TypeDataModel { integer: true, initial: 0, }), + inventoryString: new fields.StringField({ blank: true, trim: true }), }; }; }; diff --git a/module/models/Item/Aspect.mjs b/module/models/Item/Aspect.mjs index 92b3eac..5890588 100644 --- a/module/models/Item/Aspect.mjs +++ b/module/models/Item/Aspect.mjs @@ -1,19 +1,11 @@ -import { DescribedItemData } from "./DescribedItemData.mjs"; - -export class AspectItemData extends DescribedItemData { +export class AspectItemData extends foundry.abstract.TypeDataModel { static defineSchema() { const fields = foundry.data.fields; - const parentSchema = super.defineSchema(); - - // Purge fields that I don't want in this schema - delete parentSchema.quantity; - delete parentSchema.quantity_affects_used_capacity; - delete parentSchema.usage_cost; - - return foundry.utils.mergeObject(parentSchema, { + return { used: new fields.BooleanField({ initial: false }), /** The number of seconds that the effect of the aspect stays */ deactivateAfter: new fields.NumberField({ nullable: true }), - }); + info: new fields.HTMLField({ nullable: true, blank: false, trim: true }), + }; }; }; diff --git a/module/models/Item/CommonItemData.mjs b/module/models/Item/CommonItemData.mjs index 9e11800..fb32dc7 100644 --- a/module/models/Item/CommonItemData.mjs +++ b/module/models/Item/CommonItemData.mjs @@ -10,14 +10,6 @@ export class CommonItemData extends foundry.abstract.TypeDataModel { nullable: false, integer: true, }), - uses_inventory_slot: new fields.BooleanField({ - initial: true, - nullable: false, - }), - quantity_affects_used_capacity: new fields.BooleanField({ - initial: true, - nullable: false, - }), buy: new fields.NumberField({ initial: null, nullable: true, @@ -29,21 +21,9 @@ export class CommonItemData extends foundry.abstract.TypeDataModel { integer: true, }), tier: new fields.StringField({ - initial: DOTDUNGEON.defaultItemTier, - nullable: false, - choices: DOTDUNGEON.itemTiers.map(tier => tier.value), - }), - /* - If this property is set to true, the item will be shown in the combat tab - list of items. This is shown whether or not the item is marked as "equipped". - */ - combat_relevant: new fields.BooleanField({ - initial: false, - nullable: false, - }), - location: new fields.StringField({ - initial: "", + initial: `simple`, nullable: false, + choices: DOTDUNGEON.itemTiers, }), }; }; diff --git a/module/models/Item/DescribedItemData.mjs b/module/models/Item/DescribedItemData.mjs index eb913a0..ebfce48 100644 --- a/module/models/Item/DescribedItemData.mjs +++ b/module/models/Item/DescribedItemData.mjs @@ -3,7 +3,7 @@ import { CommonItemData } from "./CommonItemData.mjs"; export class DescribedItemData extends CommonItemData { static defineSchema() { const fields = foundry.data.fields; - return foundry.utils.mergeObject(super.defineSchema(), { + return mergeObject(super.defineSchema(), { description: new fields.StringField({ initial: ``, blank: true, diff --git a/module/models/Item/Equipment.mjs b/module/models/Item/Equipment.mjs index 309fd3b..6e9d7f9 100644 --- a/module/models/Item/Equipment.mjs +++ b/module/models/Item/Equipment.mjs @@ -3,6 +3,12 @@ import { DescribedItemData } from "./DescribedItemData.mjs"; export class EquipmentItemData extends DescribedItemData { static defineSchema() { const fields = foundry.data.fields; - return foundry.utils.mergeObject(super.defineSchema(), {}); + return mergeObject(super.defineSchema(), { + extra_inventory: new fields.NumberField({ + initial: null, + nullable: true, + required: false, + }), + }); }; }; diff --git a/module/models/Item/Pet.mjs b/module/models/Item/Pet.mjs index 34c6de5..7d46e94 100644 --- a/module/models/Item/Pet.mjs +++ b/module/models/Item/Pet.mjs @@ -3,13 +3,7 @@ import { DescribedItemData } from "./DescribedItemData.mjs"; export class PetItemData extends DescribedItemData { static defineSchema() { const fields = foundry.data.fields; - const parentSchema = super.defineSchema(); - - delete parentSchema.quantity; - delete parentSchema.quantity_affects_used_capacity; - delete parentSchema.usage_cost; - - return foundry.utils.mergeObject(parentSchema, { + return mergeObject(super.defineSchema(), { upkeep: new fields.NumberField({ initial: null, nullable: true }), pokeballd: new fields.BooleanField({ initial: true }), }); diff --git a/module/models/Item/Spell.mjs b/module/models/Item/Spell.mjs index f96381f..6bd90f6 100644 --- a/module/models/Item/Spell.mjs +++ b/module/models/Item/Spell.mjs @@ -4,7 +4,7 @@ import DOTDUNGEON from "../../config.mjs"; export class SpellItemData extends DescribedItemData { static defineSchema() { const fields = foundry.data.fields; - return foundry.utils.mergeObject(super.defineSchema(), { + return mergeObject(super.defineSchema(), { skill: new fields.StringField({ initial: ``, blank: true, diff --git a/module/models/Item/Transportation.mjs b/module/models/Item/Transportation.mjs new file mode 100644 index 0000000..fd1f427 --- /dev/null +++ b/module/models/Item/Transportation.mjs @@ -0,0 +1,28 @@ +import { DescribedItemData } from "./DescribedItemData.mjs"; + +export class TransportationItemData extends DescribedItemData { + static defineSchema() { + const fields = foundry.data.fields; + return mergeObject(super.defineSchema(), { + single_trip: new fields.NumberField({ + initial: null, + nullable: true, + }), + upkeep: new fields.NumberField({ + initial: null, + nullable: true, + }), + can_be_in_inventory: new fields.BooleanField({ + initial: false, + }), + inventory_slots: new fields.NumberField({ + initial: 0, + min: 0, + }), + logon_bonus: new fields.NumberField({ + initial: null, + nullable: true, + }) + }); + }; +}; diff --git a/module/models/Item/Weapon.mjs b/module/models/Item/Weapon.mjs deleted file mode 100644 index 20db6b7..0000000 --- a/module/models/Item/Weapon.mjs +++ /dev/null @@ -1,24 +0,0 @@ -import { DescribedItemData } from "./DescribedItemData.mjs"; -import DOTDUNGEON from "../../config.mjs"; - -export class WeaponItemData extends DescribedItemData { - static defineSchema() { - const fields = foundry.data.fields; - return foundry.utils.mergeObject(super.defineSchema(), { - damage: new fields.StringField({ - initial: null, - nullable: true, - blank: true, - options: DOTDUNGEON.damageTypes, - }), - ranged: new fields.BooleanField({ initial: false, }), - scoped: new fields.BooleanField({ initial: false, }), - ammo: new fields.StringField({ - initial: null, - nullable: true, - blank: true, - options: DOTDUNGEON.ammoTypes, - }), - }); - }; -}; diff --git a/module/models/template.mjs b/module/models/template.mjs index 77340ee..f3cea2a 100644 --- a/module/models/template.mjs +++ b/module/models/template.mjs @@ -3,7 +3,7 @@ import { DescribedItemData } from "./DescribedItemData.mjs"; export class TemplateData extends DescribedItemData { static defineSchema() { const fields = foundry.data.fields; - return foundry.utils.mergeObject(super.defineSchema(), { + return mergeObject(super.defineSchema(), { }); }; }; diff --git a/module/settings/world_settings.mjs b/module/settings/world_settings.mjs index cac1757..a8a3e02 100644 --- a/module/settings/world_settings.mjs +++ b/module/settings/world_settings.mjs @@ -9,16 +9,6 @@ export default function() { requiresReload: false, }); - game.settings.register(`dotdungeon`, `materialsAffectCapacity`, { - name: `dotdungeon.settings.materialsAffectCapacity.name`, - hint: `dotdungeon.settings.materialsAffectCapacity.description`, - scope: `world`, - config: true, - type: Boolean, - default: true, - requiresReload: false, - }); - game.settings.register(`dotdungeon`, `resourcesOrSupplies`, { name: `dotdungeon.settings.resourcesOrSupplies.name`, hint: `dotdungeon.settings.resourcesOrSupplies.description`, diff --git a/module/sheets/Actors/PC/PlayerSheetV2.mjs b/module/sheets/Actors/PC/PlayerSheetV2.mjs deleted file mode 100644 index ac1a378..0000000 --- a/module/sheets/Actors/PC/PlayerSheetV2.mjs +++ /dev/null @@ -1,172 +0,0 @@ -import { GenericActorSheet } from "../../GenericActorSheet.mjs"; -import DOTDUNGEON from "../../../config.mjs"; -import { localizer } from "../../../utils/localizer.mjs"; -import { modifierToString } from "../../../utils/modifierToString.mjs"; -import { GenericContextMenu } from "../../../utils/GenericContextMenu.mjs"; - -export class PlayerSheetv2 extends GenericActorSheet { - static get defaultOptions() { - let opts = foundry.utils.mergeObject( - super.defaultOptions, - { - template: `systems/dotdungeon/templates/actors/char-sheet/v2/sheet.hbs`, - tabs: [ - { - group: `page`, - navSelector: `nav.page`, - contentSelector: `.page-content`, - initial: `inventory`, - }, - { - group: `inventory`, - navSelector: `nav.inventory`, - contentSelector: `.tab[data-tab="inventory"]`, - initial: `player`, - } - ], - } - ); - opts.classes.push(`style-v3`); - return opts; - }; - - activateListeners(html) { - super.activateListeners(html); - - if (this.document.isEmbedded) return; - if (!this.isEditable) return; - console.debug(`.dungeon | Adding event listeners for Actor: ${this.id}`); - - html.find(`.create-ae`).on(`click`, async ($e) => { - console.debug(`Creating an ActiveEffect?`); - const ae = this.actor.createEmbeddedDocuments(`ActiveEffect`, [{name: "Default AE"}]); - ae.sheet.render(true); - }); - html.find(`[data-filter-toggle]`).on(`change`, ($e) => { - const target = $e.delegateTarget; - const filter = target.dataset.filterToggle; - this.toggleItemFilter(filter); - this._renderInner(); - }); - - // Make materials be able to be edited/deleted - new GenericContextMenu(html, `.material`, [ - { - name: localizer(`dotdungeon.common.edit`), - callback: (html) => { - const data = html[0].dataset; - this.openEmbeddedSheet.bind(this)(data.embeddedId); - }, - }, - { - name: localizer(`dotdungeon.common.delete`), - callback: (html) => { - const data = html[0].dataset; - this.genericEmbeddedDelete.bind(this)(data.embeddedId); - }, - }, - ]); - }; - - async getData() { - const ctx = await super.getData(); - /** @type {ActorHandler} */ - const actor = this.actor; - - ctx.preAE = actor.preAE; - ctx.system = actor.system; - ctx.flags = actor.flags; - ctx.items = this.actor.itemTypes; - - ctx.computed = { - canChangeGroup: ctx.settings.playersCanChangeGroup || ctx.isGM, - canAddAspect: !this.actor.atAspectLimit, - stats: this.#statData, - itemFilters: this.#itemFilters, - noItemTypesVisible: this._itemTypesHidden.size === DOTDUNGEON.itemFilters.length, - capacity: this.#inventoryCapacity, - }; - console.log(ctx) - return ctx; - }; - - get #statData() { - const stats = []; - const usedDice = new Set(Object.values(this.actor.system.stats)); - for (const statName in this.actor.system.stats) { - const stat = { - key: statName, - name: localizer(`dotdungeon.stat.${statName}`), - original: this.actor.preAE.stats[statName], - value: this.actor.system.stats[statName], - }; - - /* - Determine what dice are available to the user in the dropdown - selector. Disables all dice options that are selected, but not used - by this stat. - */ - stat.dieOptions = [ - { label: `---`, value: `` }, - ...DOTDUNGEON.statDice.map(die => { - return { - value: die, - label: localizer(`dotdungeon.die.${die}`, { stat: statName }), - disabled: usedDice.has(die) && this.actor.preAE.stats[statName] !== die, - }; - }) - ]; - - /* - Calculating the data needed in order to display all of the skills - for this character. - */ - stat.skills = []; - for (const skill in this.actor.system.skills[statName]) { - const value = this.actor.system.skills[statName][skill]; - stat.skills.push({ - key: skill, - name: game.i18n.format(`dotdungeon.skills.${skill}`), - value, - original: this.actor.preAE.skills[statName][skill], - formula: `1` + stat.value + modifierToString(value, { spaces: true }), - rollDisabled: this.actor.preAE.skills[statName][skill] === -1, - }); - }; - - stats.push(stat); - }; - return stats; - }; - - _itemTypesHidden = new Set([`armour`, `equipment`, `structure`, `service`]); - toggleItemFilter(filterName) { - if (this._itemTypesHidden.has(filterName)) { - this._itemTypesHidden.delete(filterName); - } else { - this._itemTypesHidden.add(filterName); - }; - this.render(); - }; - - get #itemFilters() { - const types = DOTDUNGEON.itemFilters; - const filters = {}; - for (const type of types) { - filters[type] = { - label: localizer(`TYPES.Item.${type}`), - active: !this._itemTypesHidden.has(type), - createLabel: localizer(`dotdungeon.sheet.actor.v2.create-item`, {type}), - }; - }; - return filters; - }; - - get #inventoryCapacity() { - return { - used: this.actor.items - .reduce((sum, i) => sum + i.usedCapacity, 0), - max: this.actor.system.inventory_slots, - }; - }; -} diff --git a/module/sheets/Datasheets/GroupDataSheet.mjs b/module/sheets/Datasheets/GroupDataSheet.mjs deleted file mode 100644 index 6c9527a..0000000 --- a/module/sheets/Datasheets/GroupDataSheet.mjs +++ /dev/null @@ -1,31 +0,0 @@ -export class GroupDataSheet extends ActorSheet { - static get defaultOptions() { - let opts = foundry.utils.mergeObject( - super.defaultOptions, - { - template: `systems/dotdungeon/templates/datasheets/actor/group.hbs`, - width: 200, - height: 275 - }, - ); - opts.classes.push(`dotdungeon`, `style-v3`); - return opts; - }; - - async getData() { - const ctx = {}; - - ctx.actor = this.actor; - ctx.system = this.actor.system; - - ctx.computed = { - milestones_hit_viewable: [...this.actor.system.milestones_hit.values()].join(`, `) - } - - ctx.meta = { - idp: this.actor.uuid, - }; - - return ctx; - }; -}; diff --git a/module/sheets/Datasheets/UntypedDataSheet.mjs b/module/sheets/Datasheets/UntypedDataSheet.mjs deleted file mode 100644 index c3d7702..0000000 --- a/module/sheets/Datasheets/UntypedDataSheet.mjs +++ /dev/null @@ -1,27 +0,0 @@ -export class UntypedDataSheet extends ItemSheet { - static get defaultOptions() { - let opts = foundry.utils.mergeObject( - super.defaultOptions, - { - template: `systems/dotdungeon/templates/datasheets/untyped.hbs`, - width: 650, - height: 700 - }, - ); - opts.classes.push(`dotdungeon`, `style-v3`); - return opts; - }; - - async getData() { - const ctx = {}; - - ctx.item = this.item; - ctx.system = this.item.system; - - ctx.meta = { - idp: this.item.uuid, - }; - - return ctx; - }; -}; diff --git a/module/sheets/GenericActorSheet.mjs b/module/sheets/GenericActorSheet.mjs index 2010304..3e01fcd 100644 --- a/module/sheets/GenericActorSheet.mjs +++ b/module/sheets/GenericActorSheet.mjs @@ -1,18 +1,6 @@ -import { localizer } from "../utils/localizer.mjs"; import DOTDUNGEON from "../config.mjs"; export class GenericActorSheet extends ActorSheet { - static get defaultOptions() { - let opts = foundry.utils.mergeObject( - super.defaultOptions, - { - scrollY: [`.scrollable`], - } - ); - opts.classes.push(`dotdungeon`); - return opts; - }; - _expanded = new Set(); #propogatedSettings = [ @@ -40,7 +28,7 @@ export class GenericActorSheet extends ActorSheet { ctx.actor = this.actor; ctx.config = DOTDUNGEON; - ctx.icons = {}; + ctx.icons = CONFIG.CACHE.icons; return ctx; }; @@ -52,45 +40,24 @@ export class GenericActorSheet extends ActorSheet { if (!this.isEditable) return; console.debug(`.dungeon | Generic sheet adding listeners`); - /* - Custom element event listeners because Foundry doesn't listen to them by - default. - */ - html.find( - CONFIG.CACHE.componentListeners.map(n => `${n}[name]`).join(`,`) - ).on(`change`, () => this._onChangeInput.bind(this)); - - /* - Utility event listeners that apply - */ - html.find(`[data-collapse-id]`).on(`click`, this._handleSummaryToggle.bind(this)); + html.find(`summary`).on(`click`, this._handleSummaryToggle.bind(this)); html.find(`[data-roll-formula]`).on(`click`, this._handleRoll.bind(this)); html.find(`[data-embedded-update-on="change"]`) - .on(`change`, this.genericEmbeddedUpdate.bind(this)); + .on(`change`, this.actor.genericEmbeddedUpdate.bind(this.actor)); html.find(`[data-embedded-update-on="blur"]`) - .on(`blur`, this.genericEmbeddedUpdate.bind(this)); + .on(`blur`, this.actor.genericEmbeddedUpdate.bind(this.actor)); html.find(`[data-embedded-delete]`) - .on(`click`, ($e) => { - const id = $e.currentTarget.dataset.embeddedDelete; - this.genericEmbeddedDelete.bind(this)(id); - }); + .on(`click`, this.actor.genericEmbeddedDelete.bind(this.actor)); html.find(`[data-embedded-create]`) - .on(`click`, this.genericEmbeddedCreate.bind(this)); + .on(`click`, this.actor.genericEmbeddedCreate.bind(this.actor)); html.find(`[data-message-type]`) - .on(`click`, this.genericSendToChat.bind(this)); + .on(`click`, this.actor.genericSendToChat.bind(this.actor)); html.find(`[data-embedded-edit]`) - .on(`click`, ($e) => { - const id = $e.currentTarget.dataset.embeddedEdit; - this.openEmbeddedSheet.bind(this)(id); - }) + .on(`click`, this.actor.openEmbeddedSheet.bind(this.actor)); html.find(`button[data-increment]`) .on(`click`, this._incrementValue.bind(this)); html.find(`button[data-decrement]`) .on(`click`, this._decrementValue.bind(this)); - html.find(`button[data-embedded-increment]`) - .on(`click`, this.genericEmbeddedIncrement.bind(this)); - html.find(`button[data-embedded-decrement]`) - .on(`click`, this.genericEmbeddedDecrement.bind(this)); }; async _handleRoll($e) { @@ -131,118 +98,20 @@ export class GenericActorSheet extends ActorSheet { }; async _handleSummaryToggle($e) { - $e.stopPropagation(); - let target = $e.currentTarget; - let parent = target.closest(`.collapse`); - let data = target.dataset; - console.debug(`.dungeon | Collapse ID: ${data.collapseId}`); + let data = $e.currentTarget.dataset; + let open = $e.currentTarget.parentNode.open; + console.debug(`.dungeon | Collapse ID: ${data.collapseId} (open: ${open})`); - if (!this._expanded.has(data.collapseId)) { + /* + This seeming inversion of logic is due to the fact that this handler + gets called before the element is updated to include/reflect the + change, so if the parentNode doesn't actually have it, then we're + opening it and vice-versa. + */ + if (!open) { this._expanded.add(data.collapseId); - parent.setAttribute(`open`, ``); } else { this._expanded.delete(data.collapseId); - parent.removeAttribute(`open`, ``); }; }; - - async openEmbeddedSheet(item_id) { - let item = await fromUuid(item_id); - item?.sheet.render(true); - }; - - async genericEmbeddedCreate($event) { - const data = $event.currentTarget.dataset; - if (!this[`createCustom${data.embeddedCreate}`]) { - this.actor.createEmbeddedItem({ - type: data.embeddedCreate, - name: localizer( - `dotdungeon.default.name`, - { document: `Item`, type: data.embeddedCreate } - ), - }); - } else { - this[`createCustom${data.embeddedCreate}`]($event); - }; - }; - - async genericEmbeddedUpdate($event) { - const target = $event.currentTarget; - const data = target.dataset; - const item = await fromUuid(data.embeddedId); - - let value = target.value; - switch (target.type) { - case "checkbox": value = target.checked; break; - }; - - await item?.update({ [data.embeddedUpdate]: value }); - }; - - async genericEmbeddedIncrement($event) { - const target = $event.currentTarget; - const data = target.dataset; - const item = await fromUuid(data.embeddedId); - const value = getProperty(item, data.embeddedIncrement); - if (typeof value != "number") { - return; - }; - await item?.update({ [data.embeddedIncrement]: value + 1 }); - }; - - async genericEmbeddedDecrement($event) { - const target = $event.currentTarget; - const data = target.dataset; - const item = await fromUuid(data.embeddedId); - const value = getProperty(item, data.embeddedDecrement); - if (typeof value != "number") { - return; - }; - await item?.update({ [data.embeddedDecrement]: value - 1 }); - }; - - async genericEmbeddedDelete(item_uuid) { - let item = await fromUuid(item_uuid); - - if (!item) { - ui.notifications.error( - `dotdungeon.notification.error.item-not-found`, - { console: false } - ); - return; - }; - - Dialog.confirm({ - title: game.i18n.format( - `dotdungeon.dialogs.${item.type}.delete.title`, - item - ), - content: game.i18n.format( - `dotdungeon.dialogs.${item.type}.delete.content`, - item - ), - yes: () => { - item.delete(); - }, - defaultYes: false, - }); - }; - - async genericSendToChat($event) { - const data = $event.currentTarget.dataset; - const type = data.messageType; - if (this[`send${type}ToChat`]) { - return await this[`send${type}ToChat`]($event); - }; - if (!data.messageContent) { - console.warn(`.dungeon | Tried to send a chat message with no content`); - return; - }; - let message = await ChatMessage.create({ - content: data.messageContent, - flavor: data.messageFlavor, - speaker: { actor: this.actor }, - }); - message.render(); - }; }; diff --git a/module/sheets/Items/AspectSheet.mjs b/module/sheets/Items/AspectSheet.mjs index 2bf8638..6eeb4d7 100644 --- a/module/sheets/Items/AspectSheet.mjs +++ b/module/sheets/Items/AspectSheet.mjs @@ -2,7 +2,7 @@ import { GenericItemSheet } from "./GenericItemSheet.mjs"; export class AspectSheet extends GenericItemSheet { static get defaultOptions() { - let opts = foundry.utils.mergeObject( + let opts = mergeObject( super.defaultOptions, { template: `systems/dotdungeon/templates/items/aspect.hbs`, @@ -22,7 +22,7 @@ export class AspectSheet extends GenericItemSheet { }; async getData() { - const ctx = await super.getData(); + const ctx = {}; return ctx; }; }; diff --git a/module/sheets/Items/GenericItemSheet.mjs b/module/sheets/Items/GenericItemSheet.mjs index 936bd6c..ab67779 100644 --- a/module/sheets/Items/GenericItemSheet.mjs +++ b/module/sheets/Items/GenericItemSheet.mjs @@ -1,4 +1,3 @@ -import { DialogManager } from "../../utils/DialogManager.mjs"; import DOTDUNGEON from "../../config.mjs"; export class GenericItemSheet extends ItemSheet { @@ -11,6 +10,13 @@ export class GenericItemSheet extends ItemSheet { `resourcesOrSupplies`, ]; + activateListeners(html) { + super.activateListeners(html); + + if (!this.isEditable) return; + console.debug(`.dungeon | Adding event listeners for Generic Item: ${this.id}`); + }; + async getData() { const ctx = {}; @@ -30,57 +36,10 @@ export class GenericItemSheet extends ItemSheet { ctx.item = this.item; ctx.system = this.item.system; ctx.flags = this.item.flags; - ctx.effects = this.item.effects; ctx.config = DOTDUNGEON; - ctx.icons = {}; + ctx.icons = CONFIG.CACHE.icons; return ctx; }; - - activateListeners(html) { - super.activateListeners(html); - - if (!this.isEditable) return; - console.debug(`.dungeon | Adding event listeners for Generic Item: ${this.id}`); - html.find(`button[data-increment]`) - .on(`click`, this._incrementValue.bind(this)); - html.find(`button[data-decrement]`) - .on(`click`, this._decrementValue.bind(this)); - - - html.find(`[data-help-id]`) - .on(`click`, this._helpPopup.bind(this)); - }; - - async _incrementValue($e) { - const target = $e.currentTarget; - const data = target.dataset; - const value = getProperty(this.actor, data.increment); - if (typeof value != "number") { - return; - }; - this.actor.update({ [data.increment]: value + 1 }); - }; - - async _decrementValue($e) { - const target = $e.currentTarget; - const data = target.dataset; - const value = getProperty(this.actor, data.decrement); - if (typeof value != "number") { - return; - }; - this.actor.update({ [data.decrement]: value - 1 }); - }; - - async _helpPopup($e) { - const target = $e.currentTarget; - const data = target.dataset; - if (!data.helpId) return; - DialogManager.helpDialog( - data.helpId, - data.helpContent, - data.helpTitle - ); - }; }; diff --git a/module/sheets/Items/PetSheet.mjs b/module/sheets/Items/PetSheet.mjs index a2db3b9..169516c 100644 --- a/module/sheets/Items/PetSheet.mjs +++ b/module/sheets/Items/PetSheet.mjs @@ -2,7 +2,7 @@ import { GenericItemSheet } from "./GenericItemSheet.mjs"; export class PetSheet extends GenericItemSheet { static get defaultOptions() { - let opts = foundry.utils.mergeObject( + let opts = mergeObject( super.defaultOptions, { template: `systems/dotdungeon/templates/items/pet.hbs`, diff --git a/module/sheets/Items/SpellSheet.mjs b/module/sheets/Items/SpellSheet.mjs index 8e92831..cabf2db 100644 --- a/module/sheets/Items/SpellSheet.mjs +++ b/module/sheets/Items/SpellSheet.mjs @@ -2,7 +2,7 @@ import { GenericItemSheet } from "./GenericItemSheet.mjs"; export class SpellSheet extends GenericItemSheet { static get defaultOptions() { - let opts = foundry.utils.mergeObject( + let opts = mergeObject( super.defaultOptions, { template: `systems/dotdungeon/templates/items/spell.hbs`, diff --git a/module/sheets/Items/UntypedItemSheet.mjs b/module/sheets/Items/UntypedItemSheet.mjs index 5ae0f24..f1562c9 100644 --- a/module/sheets/Items/UntypedItemSheet.mjs +++ b/module/sheets/Items/UntypedItemSheet.mjs @@ -1,116 +1,21 @@ -import { GenericContextMenu } from "../../utils/GenericContextMenu.mjs"; -import { DialogManager } from "../../utils/DialogManager.mjs"; import { GenericItemSheet } from "./GenericItemSheet.mjs"; -import { localizer } from "../../utils/localizer.mjs"; export class UntypedItemSheet extends GenericItemSheet { static get defaultOptions() { - let opts = foundry.utils.mergeObject( + let opts = mergeObject( super.defaultOptions, { - template: `systems/dotdungeon/templates/items/untyped/v2/index.hbs`, - width: 300, + template: `systems/dotdungeon/templates/items/custom.hbs`, + width: 280, height: 340, - tabs: [ - { - group: `page`, - navSelector: `nav.page`, - contentSelector: `.page-content`, - initial: `general`, - }, - ], } ); - opts.classes.push(`dotdungeon`, `style-v3`); + opts.classes.push(`dotdungeon`); return opts; }; - activateListeners(html) { - super.activateListeners(html); - - new GenericContextMenu(html, `.photo.panel`, [ - { - name: localizer(`dotdungeon.common.view-larger`), - callback: () => { - (new ImagePopout(this.item.img)).render(true); - }, - }, - { - name: localizer(`dotdungeon.common.edit`), - condition: () => this.isEditable, - callback: () => { - const fp = new FilePicker({ - callback: (path) => { - this.item.update({"img": path}); - }, - }); - fp.render(true); - }, - }, - { - name: localizer(`dotdungeon.common.reset`), - condition: () => this.isEditable, - callback: () => { - console.log(`.dungeon | Reset Item Image`) - }, - } - ]); - - if (!this.isEditable) return; - console.debug(`.dungeon | Adding event listeners for Untyped Item: ${this.item.id}`); - - html.find(`.create-ae`).on(`click`, async () => { - await this.item.createEmbeddedDocuments( - `ActiveEffect`, - [{name: localizer(`dotdungeon.default.name`, { document: `ActiveEffect`, type: `base` })}], - { renderSheet: true } - ); - }); - - new GenericContextMenu(html, `.effect.panel`, [ - { - name: localizer(`dotdungeon.common.edit`), - callback: async (html) => { - (await fromUuid(html.closest(`.effect`)[0].dataset.embeddedId))?.sheet.render(true); - }, - }, - { - name: localizer(`dotdungeon.common.delete`), - callback: async (html) => { - const target = html.closest(`.effect`)[0]; - const data = target.dataset; - const id = data.embeddedId; - const doc = await fromUuid(id); - DialogManager.createOrFocus( - `${doc.uuid}-delete`, - { - title: localizer(`dotdungeon.delete.ActiveEffect.title`, doc), - content: localizer(`dotdungeon.delete.ActiveEffect.content`, doc), - buttons: { - yes: { - label: localizer(`Yes`), - callback() { - doc.delete(); - }, - }, - no: { - label: localizer(`No`), - } - } - } - ); - }, - } - ]); - }; - async getData() { const ctx = await super.getData(); - - ctx.meta.showSettingsTab = ctx.isGM || this.item.isOwned; - ctx.meta.isEmbedded = this.item.isOwned; - ctx.meta.isEditable = this.isEditable; - return ctx; }; }; diff --git a/module/sheets/MobSheet.mjs b/module/sheets/MobSheet.mjs index b2f2213..960a885 100644 --- a/module/sheets/MobSheet.mjs +++ b/module/sheets/MobSheet.mjs @@ -1,9 +1,10 @@ +import { ActorHandler } from "../documents/Actor/Handler.mjs"; import { GenericActorSheet } from "./GenericActorSheet.mjs"; import { DiceList } from "../dialogs/DiceList.mjs"; export class MobSheet extends GenericActorSheet { static get defaultOptions() { - let opts = foundry.utils.mergeObject( + let opts = mergeObject( super.defaultOptions, { template: `systems/dotdungeon/templates/actors/mobs/main.hbs`, diff --git a/module/sheets/MVPPCSheet.mjs b/module/sheets/PlayerSheet.mjs similarity index 79% rename from module/sheets/MVPPCSheet.mjs rename to module/sheets/PlayerSheet.mjs index a5f05f5..3cc65ca 100644 --- a/module/sheets/MVPPCSheet.mjs +++ b/module/sheets/PlayerSheet.mjs @@ -1,11 +1,12 @@ +import { ActorHandler } from "../documents/Actor/Handler.mjs"; import { GenericActorSheet } from "./GenericActorSheet.mjs"; -export class MVPPCSheet extends GenericActorSheet { +export class PlayerSheet extends GenericActorSheet { /** @override {ActorHandler} actor */ static get defaultOptions() { - let opts = foundry.utils.mergeObject( + let opts = mergeObject( super.defaultOptions, { template: `systems/dotdungeon/templates/actors/char-sheet-mvp/sheet.hbs` @@ -34,7 +35,7 @@ export class MVPPCSheet extends GenericActorSheet { ctx.computed = { canChangeGroup: ctx.settings.playersCanChangeGroup || ctx.isGM, - canAddAspect: !this.actor.atAspectLimit, + canAddAspect: !await actor.proxyFunction.bind(actor)(`atAspectLimit`), }; return ctx; diff --git a/module/sheets/SyncVariations/AbstractSyncSheet.mjs b/module/sheets/SyncVariations/AbstractSyncSheet.mjs index 80e372b..53bfdf1 100644 --- a/module/sheets/SyncVariations/AbstractSyncSheet.mjs +++ b/module/sheets/SyncVariations/AbstractSyncSheet.mjs @@ -2,7 +2,7 @@ import { GenericActorSheet } from "../GenericActorSheet.mjs"; export class AbstractSyncSheet extends GenericActorSheet { static get defaultOptions() { - let opts = foundry.utils.mergeObject( + let opts = mergeObject( super.defaultOptions, { width: 200, diff --git a/module/utils/DialogManager.mjs b/module/utils/DialogManager.mjs deleted file mode 100644 index 7c40407..0000000 --- a/module/utils/DialogManager.mjs +++ /dev/null @@ -1,83 +0,0 @@ -import { localizer } from "./localizer.mjs"; - -/** - * A utility class that allows managing Dialogs that are created for various - * purposes such as deleting items, help popups, etc. This is a singleton class - * that upon instantiating after the first time will just return the first instance - */ -export class DialogManager { - - /** @type {Map} */ - static #dialogs = new Map(); - - /** - * Focuses a dialog if it already exists, or creates a new one and renders it. - * - * @param {string} dialogId The ID to associate with the dialog, should be unique - * @param {object} data The data to pass to the Dialog constructor - * @param {DialogOptions} opts The options to pass to the Dialog constructor - * @returns {Dialog} The Dialog instance - */ - static async createOrFocus(dialogId, data, opts = {}) { - if (DialogManager.#dialogs.has(dialogId)) { - const dialog = DialogManager.#dialogs.get(dialogId); - dialog.bringToTop(); - return dialog; - }; - - /* - This makes sure that if I provide a close function as a part of the data, - that the dialog still gets removed from the set once it's closed, otherwise - it could lead to dangling references that I don't care to keep. Or if I don't - provide the close function, it just sets the function as there isn't anything - extra that's needed to be called. - */ - if (data?.close) { - const provided = data.close; - data.close = () => { - DialogManager.#dialogs.delete(dialogId); - provided(); - }; - } - else { - data.close = () => DialogManager.#dialogs.delete(dialogId); - }; - - // Create the Dialog with the modified data - const dialog = new Dialog(data, opts); - DialogManager.#dialogs.set(dialogId, dialog); - dialog.render(true); - return dialog; - }; - - /** - * Closes a dialog if it is rendered - * - * @param {string} dialogId The ID of the dialog to close - */ - static async close(dialogId) { - const dialog = DialogManager.#dialogs.get(dialogId); - dialog?.close(); - }; - - static async helpDialog( - helpId, - helpContent, - helpTitle = `dotdungeon.common.help`, - localizationData = {}, - ) { - DialogManager.createOrFocus( - helpId, - { - title: localizer(helpTitle, localizationData), - content: localizer(helpContent, localizationData), - buttons: {}, - }, - { resizable: true, } - ); - }; - - static get size() { - return DialogManager.#dialogs.size; - } -}; diff --git a/module/utils/GenericContextMenu.mjs b/module/utils/GenericContextMenu.mjs deleted file mode 100644 index 9749b4f..0000000 --- a/module/utils/GenericContextMenu.mjs +++ /dev/null @@ -1,6 +0,0 @@ -export class GenericContextMenu extends ContextMenu { - constructor(element, selector, menuItems, opts = {}) { - super(element, selector, menuItems, opts); - this.menuItems.forEach(i => i.icon ??= ``); - }; -}; diff --git a/module/utils/localizer.mjs b/module/utils/localizer.mjs deleted file mode 100644 index 7cfebb0..0000000 --- a/module/utils/localizer.mjs +++ /dev/null @@ -1,37 +0,0 @@ -import { localizerConfig } from "../config.mjs"; - -export function handlebarsLocalizer(key, ...args) { - let data = args[0] - if (args.length === 1) data = args[0].hash; - if (key instanceof Handlebars.SafeString) key = key.toString(); - const localized = localizer(key, data); - return localized; -}; - -export function localizer(key, args = {}, depth = 0) { - /** @type {string} */ - let localized = game.i18n.format(key, args); - const subkeys = localized.matchAll(localizerConfig.subKeyPattern); - - // Short-cut to help prevent infinite recursion - if (depth > localizerConfig.maxDepth) { - return localized; - }; - - /* - Helps prevent recursion on the same key so that we aren't doing excess work. - */ - const localizedSubkeys = new Map(); - for (const match of subkeys) { - const subkey = match.groups.key; - if (localizedSubkeys.has(subkey)) continue; - localizedSubkeys.set(subkey, localizer(subkey, args, depth + 1)); - }; - - return localized.replace( - localizerConfig.subKeyPattern, - (_fullMatch, subkey) => { - return localizedSubkeys.get(subkey); - } - ); -}; diff --git a/module/utils/modifierToString.mjs b/module/utils/modifierToString.mjs deleted file mode 100644 index 2d1c59c..0000000 --- a/module/utils/modifierToString.mjs +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Takes in an integer and converts it into a string format that can be used in - * roll formulas or for displaying to the user. - * - * @param {number} mod The modifier to stringify - * @param {object} opts - * @param {boolean} opts.spaces Puts spaces on either side of the operand - * @returns {string} - */ -export function modifierToString(mod, opts = {}) { - if (mod == 0) return ``; - - let value = [``, `+`, mod] - if (mod < 0) { - value = [``, `-`, Math.abs(mod)] - }; - return value.join(opts.spaces ? ` ` : ``); -}; diff --git a/new-pc-sheet.md b/new-pc-sheet.md deleted file mode 100644 index f43ce4c..0000000 --- a/new-pc-sheet.md +++ /dev/null @@ -1,80 +0,0 @@ -## Tabs: -- Main - - Stats - - Skills -- Inventory - - Player - - Containers - - Inventory (divided into category of items) - - This is the items that the player will have "on them" - - Storage (divided into category of items) - - This is all of the items that the players owns and has put into storage *somewhere* - - Transportation -- Combat - - Easy skill buttons: - - Melee - - Accuracy - - Weapons - - Sync / Respawns -- Info - - Account name - - PFP - - Group name - - Aspects - - Roles -- Spells - -====== - -## Requirements: - -Stats: - - Needs to list all 6 of the primary stats - - Needs to have a dropdown for to select a die - - Nice to have: disables dice that have been selected in other stats - - Needs to have a button to roll the stat (when a die is selected) - - Foundry v12: ActiveEffect - Die needs to be able to be affected by ActiveEffects - -Skills: - - Each of the 25 skills needs to be grouped under a header of what stat it's - associated with - - Each skill must have a dropdown to indicate training level (null, trained, - expert, locked) - - Every skill must have a button to roll the dice that is labelled with the - correct formula for that skill (or "Locked" if the skill is locked) - - ActiveEffect - Increase Modifier - - Foundry v12: ActiveEffect - Increase Training Level - -Combat: - - Two weapon slots for the equipped weapon(s) - - A single armor slot - - Quick-access to the Melee / Accuracy skills - -Inventory: - - Needs three sub-tabs: - - Player - - Storage - - Transportation - - Player Subtab: - - Needs to have a section for container items, and indicating how many slots - each one has. - - List all of the items that the player has with the "inventory" location - - Show the total number of items the player on their character and how many - total slots are available - - Needs some way to move items to a different storage area (embedded-only - item sheet field maybe) - - Storage Subtab: - - List all of the items that the player has marked as in-storage - - Transportation: - - This is currently just a placeholder tab, no functionality needed other - than existing - -Spells: - - Lists all spells on a page (sortable by: alphabetical, cost, etc.) - -Info: - - Needs a place to edit the actor's name - - Needs a place to edit the actor's image - - Needs a place to edit the group name (if enabled by the GM, or is the GM) - - Needs a place to see and manage all equipped aspects - - Needs a place to see and manage all equipped roles \ No newline at end of file diff --git a/scripts/buildCompendia.mjs b/scripts/buildCompendia.mjs index 2b39aa3..41b8eac 100644 --- a/scripts/buildCompendia.mjs +++ b/scripts/buildCompendia.mjs @@ -29,4 +29,4 @@ async function main() { console.log(`Finished packing compendia`) }; -main(); +main(); \ No newline at end of file diff --git a/scripts/extractCompendia.mjs b/scripts/extractCompendia.mjs index 32935c9..9e58a7f 100644 --- a/scripts/extractCompendia.mjs +++ b/scripts/extractCompendia.mjs @@ -24,4 +24,4 @@ async function main() { console.log(`Finished unpacking compendia`); }; -main(); +main(); \ No newline at end of file diff --git a/scripts/macros/deleteInvalidActors.mjs b/scripts/macros/deleteInvalidActors.mjs deleted file mode 100644 index c8f09e6..0000000 --- a/scripts/macros/deleteInvalidActors.mjs +++ /dev/null @@ -1,4 +0,0 @@ -const invalids = game.actors.invalidDocumentIds; -invalids.forEach(id => { - game.actors.getInvalid(id).delete(); -}); diff --git a/scripts/macros/deleteInvalidItems.mjs b/scripts/macros/deleteInvalidItems.mjs deleted file mode 100644 index 6fcbdc9..0000000 --- a/scripts/macros/deleteInvalidItems.mjs +++ /dev/null @@ -1,4 +0,0 @@ -const invalids = game.items.invalidDocumentIds; -invalids.forEach(id => { - game.items.getInvalid(id).delete(); -}); diff --git a/scripts/preventLocalizationCycles.mjs b/scripts/preventLocalizationCycles.mjs deleted file mode 100644 index 0271122..0000000 --- a/scripts/preventLocalizationCycles.mjs +++ /dev/null @@ -1,76 +0,0 @@ -/* -The purpose of this script is to validate all of the language files to ensure -that there are no cycles in them to prevent infinite recursion. This must pull -the pattern to match subkeys on via the config, otherwise this could result in -inconsistencies with the localizer logic. -*/ - -import { readFile } from "fs/promises"; - -class Node { - /** @type {Array} */ - connectsTo = []; - - /** @type {boolean} */ - visited = false; - - /** @type {boolean} */ - finished = false; - - id; - constructor(data) { this.id = data; }; -}; - -/** - * @param {object | string} lang The localization object to convert into a graph - * @returns {Promise | Node>} - */ -async function createGraph(data) { - throw new Error(`createGraph not Implemented Yet`); -}; - -/** - * @param {Node} from - * @returns {Promise} - */ -async function depthFirstSearch(from) { - if (from.finished) return false; - if (from.visited) return true; - from.visited = true; - for (const neighbour of from.connectsTo) { - if (depthFirstSearch(neighbour)) return true; - }; - from.finished = true; - return false; -}; - -/** - * @param {Array} graph - */ -async function checkForCycles(graph) { - for (const node of graph) { - if (node.finished) { - console.log(`skipping node: ${node.id}`); - continue; - } - if (depthFirstSearch(node)) { - console.log(`cycle found in node: ${node.id}`); - }; - }; -}; - -async function main() { - /* - Process: - - Load the system.json to identify all lang files - - Iterate through defined languages - - Construct a graph from the language file - - Iterate through nodes checking for a cycle - */ - const lang = JSON.parse(await readFile("test.lang") ?? "{}"); - const graph = await createGraph(lang); - console.log(graph) - // await checkForCycles(graph); -}; - -main(); diff --git a/scripts/updateSystem.mjs b/scripts/updateSystem.mjs deleted file mode 100644 index 9670675..0000000 --- a/scripts/updateSystem.mjs +++ /dev/null @@ -1,13 +0,0 @@ -/* -Takes the system.json and updates all the release-specific properties in it to -help prevent erroneous updates from being made when using the local package for -development. - ---- - -Set the "manifest" property to: - "url" property + "/releases/latest/download/system.json" - -Set the "download" property to: - "url" property + "/releases/download/{version number}/{zip_name}.zip" -*/ diff --git a/styles/dialog/DiceList.scss b/styles/dialog/DiceList.scss index c7833bc..469539e 100644 --- a/styles/dialog/DiceList.scss +++ b/styles/dialog/DiceList.scss @@ -1,9 +1,9 @@ -.dotdungeon:not(.style-v3):has(.dialog--dice-list) { +.dotdungeon:has(.dialog--dice-list) { max-width: 275px; min-width: 275px; } -.dotdungeon:not(.style-v3) .dialog--dice-list { +.dotdungeon .dialog--dice-list { padding: 8px; .dice { diff --git a/styles/generic.scss b/styles/generic.scss index 92cfb3e..6769ebc 100644 --- a/styles/generic.scss +++ b/styles/generic.scss @@ -4,31 +4,18 @@ @import url('https://fonts.googleapis.com/css2?family=Pixelify+Sans&display=swap'); -/* -Enabling scrollbar customization on a per-sheet basis, with a relatively low -specificity to allow easier overriding without artificially increasing it. -*/ -.dotdungeon:not(.style-v3) { - --scrollbar-width: 5px; - --scrollbar-handle-color: #782e22; - --scrollbar-handle-border-color: var(--color-border-highlight); - --color-checkbox-checked: inherit; +// Reset the parts of Foundry's styling which gets in the way of what I want +.dotdungeon > .window-content { + ::-webkit-scrollbar { - width: var(--scrollbar-width); + width: 10px; } ::-webkit-scrollbar-thumb { - background: var(--scrollbar-handle-color); - border-color: var(--scrollbar-handle-border-color); border-radius: 5px; } -} - -// Reset the parts of Foundry's styling which gets in the way of what I want -.dotdungeon:not(.style-v3) > .window-content { h2, h3, h4, h5, h6 { @include fvtt_reset; - color: inherit; font-family: $title-font; margin: 0; } @@ -50,8 +37,8 @@ specificity to allow easier overriding without artificially increasing it. input[type="text"], input[type="number"], textarea { - @include fvtt_reset; padding: 5px 7px; + @include input-generic; } textarea { @@ -74,7 +61,7 @@ specificity to allow easier overriding without artificially increasing it. } // Styling that doesn't belong to any particular part of my sheet -.dotdungeon.dotdungeon.dotdungeon.dotdungeon:not(.style-v3) { +.dotdungeon.dotdungeon.dotdungeon.dotdungeon { container-type: size; > .window-content { diff --git a/styles/global/buttons.scss b/styles/global/buttons.scss index 77531b3..ced06f9 100644 --- a/styles/global/buttons.scss +++ b/styles/global/buttons.scss @@ -2,7 +2,7 @@ @use "sass:color" as color; -.dotdungeon.dotdungeon:not(.style-v3) > .window-content { +.dotdungeon.dotdungeon.dotdungeon.dotdungeon > .window-content { button { border-radius: 4px; box-sizing: border-box; diff --git a/styles/global/design-v2.scss b/styles/global/design-v2.scss index 5c22fe1..e9985a1 100644 --- a/styles/global/design-v2.scss +++ b/styles/global/design-v2.scss @@ -1,5 +1,5 @@ -.item--custom:not(.style-v3), -.actor--mob:not(.style-v3) { +.item--custom, +.actor--mob { input { border: 2px solid black; background: none; diff --git a/styles/global/icons.scss b/styles/global/icons.scss index 3d62ada..500ebca 100644 --- a/styles/global/icons.scss +++ b/styles/global/icons.scss @@ -1,6 +1,6 @@ $iconSizes: 12, 14, 16, 18, 20, 22, 24; -.dotdungeon.dotdungeon.dotdungeon.dotdungeon:not(.style-v3) { +.dotdungeon.dotdungeon.dotdungeon.dotdungeon { .icon { display: inline-flex; justify-content: center; @@ -14,4 +14,4 @@ $iconSizes: 12, 14, 16, 18, 20, 22, 24; }; } } -} +} \ No newline at end of file diff --git a/styles/mixins/_material.scss b/styles/mixins/_material.scss deleted file mode 100644 index 2eb9bec..0000000 --- a/styles/mixins/_material.scss +++ /dev/null @@ -1,6 +0,0 @@ -@mixin elevate($height) { - background-color: var(--elevation-#{$height}dp-bg); - -webkit-box-shadow: 0px 0px #{$height * 1.75}px 0px rgba(0,0,0,0.75); - -moz-box-shadow: 0px 0px #{$height * 1.75}px 0px rgba(0,0,0,0.75); - box-shadow: 0px 0px #{$height * 1.75}px 0px rgba(0,0,0,0.75); -} \ No newline at end of file diff --git a/styles/mixins/_partials.scss b/styles/mixins/_partials.scss index e006802..bc8e5e7 100644 --- a/styles/mixins/_partials.scss +++ b/styles/mixins/_partials.scss @@ -1,5 +1,4 @@ @use "../vars" as *; -@use "./material" as material; @mixin input-generic { border-width: 2px; @@ -13,14 +12,4 @@ &:active { transform: scale(103%); } -} - -@mixin sub-nav($parent, $group, $display) { - nav.#{$group} { - @include material.elevate(1); - display: none !important; - } - &:has(nav.#{$parent} .active[data-tab="#{$group}"]) nav.#{$group} { - display: #{$display} !important; - } -} +} \ No newline at end of file diff --git a/styles/root.scss b/styles/root.scss index 8ff6cdf..385f0a1 100644 --- a/styles/root.scss +++ b/styles/root.scss @@ -15,14 +15,9 @@ @use "./sheets/partials/panel.scss"; @use "./sheets/actor/mvp.scss"; -@use "./sheets/actor/char-sheet/v2/v2.scss"; @use "./sheets/actor/mob/mob.scss"; @use "./sheets/actor/sync/basic.scss"; @use "./sheets/items/custom.scss"; @use "./sheets/items/aspect.scss"; @use "./sheets/items/spell.scss"; -@use "./sheets/items/pet.scss"; - -/* NEW BETTER SCOPED CSS ONLY BELOW HERE */ - -@use "./v3/index.scss"; \ No newline at end of file +@use "./sheets/items/pet.scss"; \ No newline at end of file diff --git a/styles/sheets/actor/char-sheet/v2/material/inputs.scss b/styles/sheets/actor/char-sheet/v2/material/inputs.scss deleted file mode 100644 index 5726307..0000000 --- a/styles/sheets/actor/char-sheet/v2/material/inputs.scss +++ /dev/null @@ -1,15 +0,0 @@ -.dotdungeon.material { - button { - padding: 8px 16px; - - &.outline { - border-style: solid; - border-color: var(--outline-button-border); - } - - &:disabled { - opacity: 37%; - cursor: default; - } - } -} \ No newline at end of file diff --git a/styles/sheets/actor/char-sheet/v2/pages/inventory.scss b/styles/sheets/actor/char-sheet/v2/pages/inventory.scss deleted file mode 100644 index 57626fd..0000000 --- a/styles/sheets/actor/char-sheet/v2/pages/inventory.scss +++ /dev/null @@ -1,315 +0,0 @@ -@use "../../../../../mixins/material" as material; - -.dotdungeon .actor--pc-v2 .active.inventory-page { - padding-bottom: 50px; - height: 100%; -} - -.dotdungeon .actor--pc-v2 .inventory-page .active.tab[data-tab="player"] { - display: grid; - gap: 16px; - grid-template-columns: 1fr 2fr; - grid-template-rows: 1fr repeat(4, min-content); - height: 100%; - color: white; - - .item-list { - grid-row: 1 / -1; - grid-column: 2; - display: flex; - flex-direction: column; - gap: 16px; - - &__group { - @include material.elevate(1); - padding: 8px; - border-radius: 4px; - } - } - - .item-group { - &__header { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center - } - - &__create-item { - @include material.elevate(2); - color: var(--inventory-create-item-font-color); - &:hover { - @include material.elevate(4); - } - &:focus-visible, &:active { - @include material.elevate(8); - } - } - - &__list { - &--material { - display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 8px; - } - - &--untyped, &--aspect, &--foil, &--weapon, &--pet { - display: flex; - gap: 8px; - flex-direction: column; - } - } - } - - .panel { - padding: 8px; - border-radius: 4px; - } - - .bytes-panel { - display: grid; - grid-template-columns: 1fr auto; - gap: 8px; - align-items: center; - - label { - justify-self: left; - } - - input { - @include material.elevate(3); - border: none; - border-radius: 4px; - text-align: center; - color: white; - - &:hover { - @include material.elevate(6); - background: hsl( from currentColor / 50% ); // probably gonna need color-mix - } - - &:focus-visible, &:active { - border-width: 2px; - border-color: currentColor; - background: var(--elevation-8dp-bg); - } - - } - } - - .capacity-panel { - display: grid; - grid-template-columns: 1fr 30px min-content 30px; - - .used, .total { - text-align: center; - } - } - - .filter-panel { - display: grid; - grid-template-columns: 1fr 1fr; - grid-template-rows: repeat(6, 1fr); - gap: 8px; - - label { - display: flex; - align-items: center; - gap: 4px; - - &:nth-of-type(2n) { - flex-direction: row-reverse; - justify-content: right; - } - } - - input[type="checkbox"] { - margin: 0; - } - } - - .collapse { - &__header { - display: flex; - gap: 8px; - align-items: center; - justify-content: space-between; - - &:hover { - cursor: pointer; - } - - } - &__toggle { - color: var(--inventory-material-color); - transition: transform 200ms ease-in-out; - &:focus-visible { - box-shadow: 0 0 10px var(--color-shadow-highlight); - } - } - - &__content { display: none; visibility: hidden; } - &[open] .collapse{ - &__toggle { - transform: rotate(90deg); - } - &__content { - display: unset; - visibility: visible; - } - } - } - - .material { - @include material.elevate(1); - padding: 8px; - gap: 8px; - display: flex; - justify-content: space-between; - align-items: center; - border-radius: 4px; - - &__label { - font-family: var(--inventory-item-name-font); - font-size: var(--inventory-item-name-font-size); - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - justify-self: left; - max-width: 100%; - } - - &__button { - --size: 28px; - @include material.elevate(2); - transition: all 400ms ease-in-out; - color: var(--inventory-material-color); - border-width: 0; - width: var(--size); - height: var(--size); - - &:hover { - @include material.elevate(4); - color: var(--inventory-material-hover-color); - } - - &:focus-visible { - box-shadow: 0 0 10px var(--color-shadow-highlight); - } - } - - &__input { - @include material.elevate(2); - font-family: var(--input-font); - text-align: center; - border-radius: 4px; - transition: all 400ms ease-in-out; - color: var(--inventory-material-color); - - &:hover { - @include material.elevate(4); - color: var(--inventory-material-hover-color); - } - - &:focus { - @include material.elevate(8); - color: var(--inventory-material-focus-color); - } - } - } - - .untyped, .aspect, .weapon, .pet { - @include material.elevate(1); - padding: 8px; - border-radius: 4px; - color: var(--inventory-material-color); - - &__name { - flex-grow: 1; - cursor: inherit; - font-family: var(--inventory-item-name-font); - font-size: var(--inventory-item-name-font-size); - } - - &__content { - display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)) 2.25rem; - grid-template-rows: repeat(3, 2.25rem) auto; - gap: 8px; - } - - &__button { - @include material.elevate(2); - padding: 0px; - - &:hover { - @include material.elevate(4); - } - &:focus-visible { - box-shadow: 0 0 10px var(--color-shadow-highlight); - } - - &--send-to-chat { - @extend .untyped__button; - color: var(--inventory-untyped-send-to-chat-color); - } - &--edit { - @extend .untyped__button; - color: var(--inventory-untyped-edit-color); - } - &--delete { - @extend .untyped__button; - color: var(--inventory-untyped-delete-color); - background: var(--inventory-untyped-delete-bg); - &:hover { - background: var(--inventory-untyped-delete-bg-hover); - } - } - } - - &__field { - @include material.elevate(1); - color: var(--inventory-untyped-card-color); - padding: 8px; - display: flex; - align-items: center; - justify-content: space-between; - border-radius: 4px; - - > :first-child { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - } - - &.editable { - input[type="text"], input[type="number"] { - @include material.elevate(1); - font-family: var(--input-font); - font-size: var(--inventory-untyped-quantity-font-size); - width: 50px; - text-align: center; - border-radius: 4px; - padding: 5px 7px; - color: inherit; - } - } - } - - &__description { - @include material.elevate(1); - color: var(--inventory-untyped-description-color); - margin: 0; - grid-row: span 3; - grid-column: span 3; - padding: 8px; - border-radius: 4px; - } - } - - .weapon { - &__description { - grid-row: span 2; - } - } -} diff --git a/styles/sheets/actor/char-sheet/v2/pages/stats.scss b/styles/sheets/actor/char-sheet/v2/pages/stats.scss deleted file mode 100644 index a4f9dee..0000000 --- a/styles/sheets/actor/char-sheet/v2/pages/stats.scss +++ /dev/null @@ -1,79 +0,0 @@ -.dotdungeon .actor--pc-v2 .active.stats-page { - display: grid; - gap: 16px; - grid-template-columns: 1fr 1fr; - grid-template-rows: auto auto auto; - - .stat { - border-radius: 8px; - display: flex; - flex-direction: column; - - select { - height: 100%; - outline: none; - border: none; - text-align: center; - } - - &__header { - padding: 8px; - display: flex; - align-items: center; - flex-direction: row; - color: var(--stat-divider-text-color); - gap: 8px; - > h2 { - flex-grow: 1; - color: var(--stat-header-text-color); - } - .dice-select { - color: var(--stat-dice-select-text-color); - option { - background: var(--stat-dice-select-bg); - } - } - .roll-stat { - color: var(--stat-roll-button-text-color); - } - - &:not(:only-child) { - border-bottom: 1px solid var(--stat-divider-color); - } - } - - &__empty { - display: flex; - justify-content: center; - align-items: center; - flex-grow: 1; - } - - &__skills { - align-items: center; - box-sizing: border-box; - display: grid; - gap: 8px; - grid-template-columns: repeat(3, 1fr); - padding: 8px; - - .skill { - &__label { - text-align: end; - justify-self: right; - color: var(--skill-name-text-color); - } - &__training { - color: var(--skill-training-select-text-color); - option { - background: var(--skill-training-select-bg); - } - } - &__roll { - margin-right: 25%; - color: var(--skill-roll-button-text-color); - } - } - } - } -} \ No newline at end of file diff --git a/styles/sheets/actor/char-sheet/v2/themes/dark.scss b/styles/sheets/actor/char-sheet/v2/themes/dark.scss deleted file mode 100644 index f32ffce..0000000 --- a/styles/sheets/actor/char-sheet/v2/themes/dark.scss +++ /dev/null @@ -1,78 +0,0 @@ -@use "sass:color"; - -$t: transparent; - -$background: #0a0a0a; -$surface: #121212; -$primary: #005300; -$secondary: #6c056c; -$danger: red; -$on-background: $t; -$on-surface: white; -$on-primary: $t; -$on-secondary: $t; -$on-danger: black; - -$title-font: 'Pixelify Sans', sans-serif; -$body-font: sans-serif; - -.actor--pc-v2 { - --sheet-bg: #{$background}; - --nav-bg: #{$surface}; - --nav-button-text: #{$on-surface}; - - --tab-font: #{$title-font}; - --input-font: #{$body-font}; - - // Foundry overrides - --scrollbar-handle-color: #{$primary}; - --scrollbar-handle-border-color: color-mix(in lab, white 40%, var(--scrollbar-handle-color)); - --color-checkbox-checked: #{color.adjust($primary, $lightness: 25%)}; - - /* Elevation backgrounds to following Material design */ - --elevation-0dp-bg: #{$surface}; - --elevation-1dp-bg: color-mix(in lab, transparent, white 5%); - --elevation-2dp-bg: color-mix(in lab, transparent, white 7%); - --elevation-3dp-bg: color-mix(in lab, transparent, white 8%); - --elevation-4dp-bg: color-mix(in lab, transparent, white 9%); - --elevation-6dp-bg: color-mix(in lab, transparent, white 11%); - --elevation-8dp-bg: color-mix(in lab, transparent, white 12%); - --elevation-12dp-bg: color-mix(in lab, transparent, white 14%); - --elevation-16dp-bg: color-mix(in lab, transparent, white 15%); - --elevation-24dp-bg: color-mix(in lab, transparent, white 16%); - - --stat-header-text-color: #{$on-surface}; - --stat-dice-select-text-color: #{$on-surface}; - --stat-dice-select-bg: #{$surface}; - --stat-roll-button-text-color: #{$on-surface}; - --stat-divider-color: #{$secondary}; - --stat-not-chosen-placeholder-text-color: #{$on-surface}; - --skill-name-text-color: #{$on-surface}; - --skill-training-select-bg: #{$surface}; - --skill-training-select-text-color: #{$on-surface}; - --skill-roll-button-text-color: #{$on-surface}; - - /* General variables for inventory tab */ - --inventory-create-item-font-color: white; - - /* Common Inventory Item Variables */ - --inventory-item-name-font: #{$body-font}; - --inventory-item-name-font-size: 0.875rem; - - /* Material inventory item details */ - --inventory-material-color: white; - --inventory-material-hover-color: white; - --inventory-material-focus-color: white; - - /* Untyped (custom) inventory item details */ - --inventory-untyped-description-color: white; - --inventory-untyped-card-color: white; - --inventory-untyped-send-to-chat-color: white; - --inventory-untyped-edit-color: white; - --inventory-untyped-delete-color: white; - --inventory-untyped-delete-bg: color-mix(in lab, #{$danger} 30%, #{$surface}); - --inventory-untyped-delete-bg-hover: color-mix(in lab, #{$danger} 37%, #{$surface});; - --inventory-untyped-quantity-font-size: 14px; - --inventory-untyped-quantity-color: white; - --inventory-untyped-quantity-input-color: white; -} diff --git a/styles/sheets/actor/char-sheet/v2/themes/material-design.scss b/styles/sheets/actor/char-sheet/v2/themes/material-design.scss deleted file mode 100644 index aad072a..0000000 --- a/styles/sheets/actor/char-sheet/v2/themes/material-design.scss +++ /dev/null @@ -1,167 +0,0 @@ -:root { - --md-source: #005500; - /* primary */ - --md-ref-palette-primary0: #000000; - --md-ref-palette-primary10: #002200; - --md-ref-palette-primary20: #003a00; - --md-ref-palette-primary25: #004600; - --md-ref-palette-primary30: #005300; - --md-ref-palette-primary35: #12600b; - --md-ref-palette-primary40: #226d19; - --md-ref-palette-primary50: #3d8730; - --md-ref-palette-primary60: #56a248; - --md-ref-palette-primary70: #70bd5f; - --md-ref-palette-primary80: #8bd978; - --md-ref-palette-primary90: #a6f691; - --md-ref-palette-primary95: #caffb9; - --md-ref-palette-primary98: #edffe1; - --md-ref-palette-primary99: #f7ffee; - --md-ref-palette-primary100: #ffffff; - /* secondary */ - --md-ref-palette-secondary0: #000000; - --md-ref-palette-secondary10: #380038; - --md-ref-palette-secondary20: #5b005b; - --md-ref-palette-secondary25: #6c056c; - --md-ref-palette-secondary30: #7a1979; - --md-ref-palette-secondary35: #892886; - --md-ref-palette-secondary40: #973693; - --md-ref-palette-secondary50: #b450ae; - --md-ref-palette-secondary60: #d26ac9; - --md-ref-palette-secondary70: #f084e6; - --md-ref-palette-secondary80: #ffaaf3; - --md-ref-palette-secondary90: #ffd7f5; - --md-ref-palette-secondary95: #ffebf8; - --md-ref-palette-secondary98: #fff7f9; - --md-ref-palette-secondary99: #fffbff; - --md-ref-palette-secondary100: #ffffff; - /* tertiary */ - --md-ref-palette-tertiary0: #000000; - --md-ref-palette-tertiary10: #002022; - --md-ref-palette-tertiary20: #003739; - --md-ref-palette-tertiary25: #104245; - --md-ref-palette-tertiary30: #1e4d50; - --md-ref-palette-tertiary35: #2b595c; - --md-ref-palette-tertiary40: #386568; - --md-ref-palette-tertiary50: #517f82; - --md-ref-palette-tertiary60: #6b989c; - --md-ref-palette-tertiary70: #85b3b6; - --md-ref-palette-tertiary80: #a0cfd2; - --md-ref-palette-tertiary90: #bcebee; - --md-ref-palette-tertiary95: #caf9fd; - --md-ref-palette-tertiary98: #e7feff; - --md-ref-palette-tertiary99: #f3ffff; - --md-ref-palette-tertiary100: #ffffff; - /* neutral */ - --md-ref-palette-neutral0: #000000; - --md-ref-palette-neutral10: #1a1c18; - --md-ref-palette-neutral20: #2f312d; - --md-ref-palette-neutral25: #3a3c38; - --md-ref-palette-neutral30: #454743; - --md-ref-palette-neutral35: #51534e; - --md-ref-palette-neutral40: #5d5f5a; - --md-ref-palette-neutral50: #767872; - --md-ref-palette-neutral60: #90918c; - --md-ref-palette-neutral70: #abaca6; - --md-ref-palette-neutral80: #c6c7c1; - --md-ref-palette-neutral90: #e2e3dc; - --md-ref-palette-neutral95: #f1f1eb; - --md-ref-palette-neutral98: #f9faf3; - --md-ref-palette-neutral99: #fcfdf6; - --md-ref-palette-neutral100: #ffffff; - /* neutral-variant */ - --md-ref-palette-neutral-variant0: #000000; - --md-ref-palette-neutral-variant10: #181d15; - --md-ref-palette-neutral-variant20: #2c3229; - --md-ref-palette-neutral-variant25: #373d34; - --md-ref-palette-neutral-variant30: #43483f; - --md-ref-palette-neutral-variant35: #4e544a; - --md-ref-palette-neutral-variant40: #5a6056; - --md-ref-palette-neutral-variant50: #73796e; - --md-ref-palette-neutral-variant60: #8d9387; - --md-ref-palette-neutral-variant70: #a7ada1; - --md-ref-palette-neutral-variant80: #c3c8bc; - --md-ref-palette-neutral-variant90: #dfe4d7; - --md-ref-palette-neutral-variant95: #edf3e5; - --md-ref-palette-neutral-variant98: #f6fbee; - --md-ref-palette-neutral-variant99: #f9fef1; - --md-ref-palette-neutral-variant100: #ffffff; - /* error */ - --md-ref-palette-error0: #000000; - --md-ref-palette-error10: #410002; - --md-ref-palette-error20: #690005; - --md-ref-palette-error25: #7e0007; - --md-ref-palette-error30: #93000a; - --md-ref-palette-error35: #a80710; - --md-ref-palette-error40: #ba1a1a; - --md-ref-palette-error50: #de3730; - --md-ref-palette-error60: #ff5449; - --md-ref-palette-error70: #ff897d; - --md-ref-palette-error80: #ffb4ab; - --md-ref-palette-error90: #ffdad6; - --md-ref-palette-error95: #ffedea; - --md-ref-palette-error98: #fff8f7; - --md-ref-palette-error99: #fffbff; - --md-ref-palette-error100: #ffffff; - /* light */ - --md-sys-color-primary-light: #226d19; - --md-sys-color-on-primary-light: #ffffff; - --md-sys-color-primary-container-light: #a6f691; - --md-sys-color-on-primary-container-light: #002200; - --md-sys-color-secondary-light: #973693; - --md-sys-color-on-secondary-light: #ffffff; - --md-sys-color-secondary-container-light: #ffd7f5; - --md-sys-color-on-secondary-container-light: #380038; - --md-sys-color-tertiary-light: #386568; - --md-sys-color-on-tertiary-light: #ffffff; - --md-sys-color-tertiary-container-light: #bcebee; - --md-sys-color-on-tertiary-container-light: #002022; - --md-sys-color-error-light: #ba1a1a; - --md-sys-color-error-container-light: #ffdad6; - --md-sys-color-on-error-light: #ffffff; - --md-sys-color-on-error-container-light: #410002; - --md-sys-color-background-light: #fcfdf6; - --md-sys-color-on-background-light: #1a1c18; - --md-sys-color-surface-light: #fcfdf6; - --md-sys-color-on-surface-light: #1a1c18; - --md-sys-color-surface-variant-light: #dfe4d7; - --md-sys-color-on-surface-variant-light: #43483f; - --md-sys-color-outline-light: #73796e; - --md-sys-color-inverse-on-surface-light: #f1f1eb; - --md-sys-color-inverse-surface-light: #2f312d; - --md-sys-color-inverse-primary-light: #8bd978; - --md-sys-color-shadow-light: #000000; - --md-sys-color-surface-tint-light: #226d19; - --md-sys-color-outline-variant-light: #c3c8bc; - --md-sys-color-scrim-light: #000000; - /* dark */ - --md-sys-color-primary-dark: #8bd978; - --md-sys-color-on-primary-dark: #003a00; - --md-sys-color-primary-container-dark: #005300; - --md-sys-color-on-primary-container-dark: #a6f691; - --md-sys-color-secondary-dark: #ffaaf3; - --md-sys-color-on-secondary-dark: #5b005b; - --md-sys-color-secondary-container-dark: #7a1979; - --md-sys-color-on-secondary-container-dark: #ffd7f5; - --md-sys-color-tertiary-dark: #a0cfd2; - --md-sys-color-on-tertiary-dark: #003739; - --md-sys-color-tertiary-container-dark: #1e4d50; - --md-sys-color-on-tertiary-container-dark: #bcebee; - --md-sys-color-error-dark: #ffb4ab; - --md-sys-color-error-container-dark: #93000a; - --md-sys-color-on-error-dark: #690005; - --md-sys-color-on-error-container-dark: #ffdad6; - --md-sys-color-background-dark: #1a1c18; - --md-sys-color-on-background-dark: #e2e3dc; - --md-sys-color-surface-dark: #1a1c18; - --md-sys-color-on-surface-dark: #e2e3dc; - --md-sys-color-surface-variant-dark: #43483f; - --md-sys-color-on-surface-variant-dark: #c3c8bc; - --md-sys-color-outline-dark: #8d9387; - --md-sys-color-inverse-on-surface-dark: #1a1c18; - --md-sys-color-inverse-surface-dark: #e2e3dc; - --md-sys-color-inverse-primary-dark: #226d19; - --md-sys-color-shadow-dark: #000000; - --md-sys-color-surface-tint-dark: #8bd978; - --md-sys-color-outline-variant-dark: #43483f; - --md-sys-color-scrim-dark: #000000; -} \ No newline at end of file diff --git a/styles/sheets/actor/char-sheet/v2/v2.scss b/styles/sheets/actor/char-sheet/v2/v2.scss deleted file mode 100644 index 4f18741..0000000 --- a/styles/sheets/actor/char-sheet/v2/v2.scss +++ /dev/null @@ -1,97 +0,0 @@ -@use "./themes/dark.scss"; -@use "../../../../mixins/material" as material; -@use "../../../../mixins/partials" as partials; - -@use "./pages/stats.scss"; -@use "./pages/inventory.scss"; - -.dotdungeon .actor--pc-v2 { - background-color: var(--sheet-bg); - - .e-0dp { @include material.elevate(0); } - .e-1dp { @include material.elevate(1); } - .e-2dp { @include material.elevate(2); } - .e-3dp { @include material.elevate(3); } - .e-4dp { @include material.elevate(4); } - .e-6dp { @include material.elevate(6); } - .e-8dp { @include material.elevate(8); } - .e-12dp { @include material.elevate(12); } - .e-16dp { @include material.elevate(16); } - .e-24dp { @include material.elevate(24); } - - .scrollable { - container-type: size; - overflow: auto; - scrollbar-gutter: stable; - } - - .nav-bar { - @include material.elevate(8); - background: color-mix(in lab, var(--nav-bg), white 5%); - position: absolute; - bottom: 0; - width: calc(100% - 6px); - - nav { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 8px; - padding: 8px; - } - - @include partials.sub-nav("page", "inventory", flex); - - button { - @include material.elevate(2); - height: 36px; - box-sizing: border-box; - color: var(--nav-button-text); - - &:focus-visible { - border-style: solid; - border-width: 2px; - border-color: currentColor; - background: var(--elevation-8dp-bg); - } - - &:hover { - @include material.elevate(6); - background: hsl( from currentColor / 50% ); // probably gonna need color-mix - } - } - } - - span.placeholder { - opacity: 60%; - } - - input[type="checkbox"] { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-radius: 2px; - margin: 0; - cursor: pointer; - - background: var(--elevation-8dp-bg); - position: relative; - &:checked::before { - content: ""; - background: var(--color-checkbox-checked); - border-radius: 3px; - $margin: 4px; - top: $margin; - bottom: $margin; - left: $margin; - right: $margin; - position: absolute; - } - } - - .page-content { - padding: 16px; - padding-bottom: 69px; - height: 100%; - } -} \ No newline at end of file diff --git a/styles/sheets/actor/mob/mob.scss b/styles/sheets/actor/mob/mob.scss index 11634b2..fd3e063 100644 --- a/styles/sheets/actor/mob/mob.scss +++ b/styles/sheets/actor/mob/mob.scss @@ -1,7 +1,7 @@ @use "../../../vars" as *; @use "avatar" as *; -.dotdungeon:not(.style-v3) .actor--mob { +.dotdungeon .actor--mob { --gap: 8px; --avatar-size: 100px; --row-height: calc((var(--avatar-size) - var(--gap)) / 2); diff --git a/styles/sheets/actor/mob/v2.scss b/styles/sheets/actor/mob/v2.scss deleted file mode 100644 index d7f0a5c..0000000 --- a/styles/sheets/actor/mob/v2.scss +++ /dev/null @@ -1,123 +0,0 @@ -@use "../../../vars" as *; -@use "avatar" as *; - -.dotdungeon:not(.style-v3) .actor--mob2 { - --gap: 8px; - --avatar-size: 100px; - --row-height: calc((var(--avatar-size) - var(--gap)) / 2); - padding: var(--gap); - display: grid; - grid-template-columns: var(--avatar-size) repeat(2, minmax(0, 1fr)); - grid-template-rows: repeat(5, var(--row-height)) minmax(var(--row-height), 1fr); - gap: var(--gap); - grid-template-areas: - "avatar . ." - "avatar . ." - "dice tabs tabs" - "dice tabs tabs" - "dice tabs tabs" - "dice tabs tabs"; - - label, .dice { - border: 2px solid black; - border-radius: 4px; - gap: 4px; - padding: 4px; - } - - input.masked { - border: 2px solid black; - background: none; - box-shadow: none; - &:focus { - transform: scale(102%); - } - } - - label.mask-input { - display: flex; - flex-direction: row; - align-items: center; - transition: all ease-in-out 50ms; - - &:focus-within { - transform: scale(102%); - } - - input { - text-align: right; - border: none; - background: none; - border-radius: 0; - border-bottom: 1px solid black; - &:focus, &:focus-visible { - box-shadow: none; - } - } - - input.left { - text-align: left; - } - } - - .wide { - grid-column: span 2; - } - - .mask-textarea { - display: flex; - flex-direction: column; - transition: all ease-in-out 50ms; - - &:focus-within { - transform: scale(102%); - } - - textarea { - flex-grow: 1; - resize: none; - border: none; - box-shadow: none; - background: none; - } - } - .name { - height: 100%; - font-size: 1.5rem; - input { - height: 100%; - } - } - - .dice { - grid-area: dice; - display: flex; - flex-direction: column; - - .die { - display: flex; - flex-direction: row; - width: 100%; - border: 2px solid black; - border-radius: 4px; - - .formula { - flex-grow: 1; - align-self: center; - } - } - } - - .tabs { grid-area: tabs; } - .stunts { - grid-area: stunts; - } - .description { - grid-area: description; - } - - .avatar { - @include avatar; - border-radius: 4px; - } -} \ No newline at end of file diff --git a/styles/sheets/actor/mvp.scss b/styles/sheets/actor/mvp.scss index 4193a24..28fafaf 100644 --- a/styles/sheets/actor/mvp.scss +++ b/styles/sheets/actor/mvp.scss @@ -1,7 +1,7 @@ @use "../../vars.scss" as *; @use "../../mixins/breakpoints" as *; -.dotdungeon:not(.style-v3) .actor--pc-mvp { +.dotdungeon .actor--pc { display: grid; grid-template-areas: "profile stats stats" @@ -270,8 +270,8 @@ @include bp-m { - .dotdungeon:not(.style-v3) { - .actor--pc-mvp { + .dotdungeon { + .actor--pc { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: repeat(15, min-content); grid-template-areas: @@ -310,8 +310,8 @@ } @include bp-s { - .dotdungeon:not(.style-v3) { - .actor--pc-mvp { + .dotdungeon { + .actor--pc { grid-template-columns: 1fr; grid-template-rows: repeat(12, min-content); grid-template-areas: diff --git a/styles/sheets/actor/sync/basic.scss b/styles/sheets/actor/sync/basic.scss index 904d093..6f412be 100644 --- a/styles/sheets/actor/sync/basic.scss +++ b/styles/sheets/actor/sync/basic.scss @@ -1,6 +1,6 @@ @use "../../../mixins/breakpoints" as *; -:not(.style-v3).dotdungeon { +.dotdungeon { .actor--basic-sync { display: flex; justify-content: center; @@ -52,7 +52,7 @@ } @include bp-xs { - :not(.style-v3).dotdungeon { + .dotdungeon { &--sync-sheet { header { .configure-sheet { diff --git a/styles/sheets/items/aspect.scss b/styles/sheets/items/aspect.scss index 8f355fe..2461b9b 100644 --- a/styles/sheets/items/aspect.scss +++ b/styles/sheets/items/aspect.scss @@ -1,6 +1,6 @@ @use "../../vars" as *; -.dotdungeon:not(.style-v3) .item--aspect { +.dotdungeon .item--aspect { padding: 4px; input[type=text] { diff --git a/styles/sheets/items/custom.scss b/styles/sheets/items/custom.scss index 9c5bc96..0899a91 100644 --- a/styles/sheets/items/custom.scss +++ b/styles/sheets/items/custom.scss @@ -1,4 +1,4 @@ -.item--custom:not(.style-v3) { +.item--custom { padding: 8px; display: grid; grid-template-columns: 1fr 1fr; diff --git a/styles/sheets/items/pet.scss b/styles/sheets/items/pet.scss index 10e4d51..8cfc8e5 100644 --- a/styles/sheets/items/pet.scss +++ b/styles/sheets/items/pet.scss @@ -1,6 +1,6 @@ @use "../../vars" as *; -.dotdungeon:not(.style-v3) .item--pet { +.dotdungeon .item--pet { padding: 4px; input[type=text] { diff --git a/styles/sheets/items/spell.scss b/styles/sheets/items/spell.scss index 8d4405f..21ba81b 100644 --- a/styles/sheets/items/spell.scss +++ b/styles/sheets/items/spell.scss @@ -1,6 +1,6 @@ @use "../../vars" as *; -.dotdungeon:not(.style-v3) .item--spell { +.dotdungeon .item--spell { padding: 4px; input[type=text] { diff --git a/styles/sheets/partials/panel.scss b/styles/sheets/partials/panel.scss index 2ebf74c..7d0b910 100644 --- a/styles/sheets/partials/panel.scss +++ b/styles/sheets/partials/panel.scss @@ -2,7 +2,7 @@ @use "../../mixins/foundry" as *; @use "../../vars" as *; -.dotdungeon:not(.style-v3) .actor--pc-mvp .panel { +.dotdungeon .panel { display: grid; grid-template-rows: min-content 1fr; @@ -39,7 +39,7 @@ } @include bp-s { - .dotdungeon:not(.style-v3) .panel__header .icon { + .dotdungeon .panel__header .icon { display: none; visibility: hidden; } diff --git a/styles/sheets/partials/skill.scss b/styles/sheets/partials/skill.scss index 6034e86..40b43de 100644 --- a/styles/sheets/partials/skill.scss +++ b/styles/sheets/partials/skill.scss @@ -1,4 +1,4 @@ -.dotdungeon:not(.style-v3) .skill { +.dotdungeon .skill { display: flex; flex-direction: row; justify-content: center; diff --git a/styles/sheets/partials/stat.scss b/styles/sheets/partials/stat.scss index 0cfbe76..1875cf3 100644 --- a/styles/sheets/partials/stat.scss +++ b/styles/sheets/partials/stat.scss @@ -1,4 +1,4 @@ -.dotdungeon:not(.style-v3) .actor--pc-mvp .stat { +.dotdungeon .stat { display: flex; flex-direction: column; align-items: center; diff --git a/styles/v3/components/common.scss b/styles/v3/components/common.scss deleted file mode 100644 index 59f812d..0000000 --- a/styles/v3/components/common.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Disclaimer: This CSS is used by a custom web component and is scoped to JUST -// the corresponding web component. This should only be imported by web component -// style files. - -:host { - display: inline-block; -} diff --git a/styles/v3/components/icon.scss b/styles/v3/components/icon.scss deleted file mode 100644 index 012593f..0000000 --- a/styles/v3/components/icon.scss +++ /dev/null @@ -1,23 +0,0 @@ -/* -Disclaimer: This CSS is used by a custom web component and is scoped to JUST -the corresponding web component. Importing this into other files is forbidden -*/ - -$default-size: 1rem; - -@use "./common.scss"; - -div { - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; -} - -svg { - width: var(--size, $default-size); - height: var(--size, $default-size); - fill: var(--fill); - stroke: var(--stroke); -} diff --git a/styles/v3/components/incrementer.scss b/styles/v3/components/incrementer.scss deleted file mode 100644 index abe9478..0000000 --- a/styles/v3/components/incrementer.scss +++ /dev/null @@ -1,63 +0,0 @@ -/* -Disclaimer: This CSS is used by a custom web component and is scoped to JUST -the corresponding web component. Importing this into other files is forbidden -*/ - -$default-border-radius: 4px; -$default-height: 1.5rem; - -@use "../mixins/material"; -@use "./common.scss"; - -div { - display: grid; - grid-template-columns: var(--height, $default-height) var(--width, 50px) var(--height, $default-height); - grid-template-rows: var(--height, 1fr); - border-radius: var(--border-radius, $default-border-radius); - @include material.elevate(2); - - &:hover { - @include material.elevate(4); - } - - &:focus-within { - @include material.elevate(6); - } -} - -span, input { - border: none; - outline: none; - background: none; - color: inherit; -} - -input { - font-family: var(--font-family, inherit); - text-align: center; - font-size: var(--font-size, inherit); - padding: 2px 4px; - - &::-webkit-inner-spin-button, &::-webkit-outer-spin-button { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - margin: 0 - } -} - -.increment, .decrement { - aspect-ratio: 1 / 1; - padding: 0; - display: flex; - justify-content: center; - align-items: center; - cursor: pointer; -} - -.increment { - border-radius: 0 var(--border-radius, $default-border-radius) var(--border-radius, 4px) 0; -} -.decrement { - border-radius: var(--border-radius, $default-border-radius) 0 0 var(--border-radius, $default-border-radius); -} diff --git a/styles/v3/elements/button.scss b/styles/v3/elements/button.scss deleted file mode 100644 index 33ad097..0000000 --- a/styles/v3/elements/button.scss +++ /dev/null @@ -1,46 +0,0 @@ -@use "../mixins/material" as material; - -.dotdungeon.style-v3 > .window-content { - button, a.button { - @include material.elevate(2); - align-items: center; - border-radius: 4px; - border: none; - box-sizing: border-box; - color: inherit; - cursor: pointer; - display: inline-flex; - font-family: sans-serif; - gap: 4px; - justify-content: center; - margin: 0; - outline: none; - padding: 4px 8px; - transition: all 200ms ease-in-out; - width: initial; - - &:hover, &:focus-visible { - @include material.elevate(4); - text-shadow: none; - } - &:active { - @include material.elevate(6); - } - - &:disabled { - opacity: 50%; - cursor: default; - } - - /* Icon buttons don't use Material styling */ - &.icon { - @include material.undo; - padding: 4px; - - &:focus-visible { - @include material.undo; - // TODO : Accessible focus state - } - } - } -} diff --git a/styles/v3/elements/checkbox.scss b/styles/v3/elements/checkbox.scss deleted file mode 100644 index d3bae5f..0000000 --- a/styles/v3/elements/checkbox.scss +++ /dev/null @@ -1,24 +0,0 @@ -.dotdungeon.style-v3 { - input[type="checkbox"] { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-radius: 2px; - margin: 0; - cursor: pointer; - - background: var(--elevation-8dp-bg); - position: relative; - &:checked::before { - content: ""; - background: var(--checkbox-checked); - border-radius: 3px; - $margin: 4px; - top: $margin; - bottom: $margin; - left: $margin; - right: $margin; - position: absolute; - } - } -} diff --git a/styles/v3/elements/headers.scss b/styles/v3/elements/headers.scss deleted file mode 100644 index 0174901..0000000 --- a/styles/v3/elements/headers.scss +++ /dev/null @@ -1,10 +0,0 @@ -.dotdungeon.style-v3 > .window-content { - h1, h2, h3, h4, h5, h6 { - border: none; - font-size: 1rem; - margin: 0; - } - h1, .h1 { - font-size: 1.5rem; - } -} diff --git a/styles/v3/elements/hr.scss b/styles/v3/elements/hr.scss deleted file mode 100644 index 3f23a68..0000000 --- a/styles/v3/elements/hr.scss +++ /dev/null @@ -1,6 +0,0 @@ -.dotdungeon.style-v3 > .window-content hr { - border-color: black; - opacity: 25%; - width: 100%; - grid-column: 1 / -1; -} diff --git a/styles/v3/elements/icons.scss b/styles/v3/elements/icons.scss deleted file mode 100644 index 0a44997..0000000 --- a/styles/v3/elements/icons.scss +++ /dev/null @@ -1,17 +0,0 @@ -$iconSizes: 12, 14, 16, 18, 20, 22, 24; - -.dotdungeon.style-v3 > .window-content { - .icon { - display: inline-flex; - justify-content: center; - align-items: center; - - // The various icon sizes - @each $size in $iconSizes { - &--#{$size} { - height: #{$size}px; - width: #{$size}px; - }; - } - } -} diff --git a/styles/v3/elements/label.scss b/styles/v3/elements/label.scss deleted file mode 100644 index 12e3afb..0000000 --- a/styles/v3/elements/label.scss +++ /dev/null @@ -1,9 +0,0 @@ -@use "../mixins/material"; - -.dotdungeon.style-v3 > .window-content label { - cursor: pointer; - - &.justify-start { - justify-self: start; - } -} diff --git a/styles/v3/elements/nav.scss b/styles/v3/elements/nav.scss deleted file mode 100644 index 6046e41..0000000 --- a/styles/v3/elements/nav.scss +++ /dev/null @@ -1,11 +0,0 @@ -@use "../mixins/material" as material; - -.dotdungeon.style-v3 > .window-content { - nav:not(#context-menu) { - display: flex; - flex-direction: row; - overflow-x: auto; - gap: 8px; - padding: 8px; - } -} diff --git a/styles/v3/elements/number-input.scss b/styles/v3/elements/number-input.scss deleted file mode 100644 index ad9ce74..0000000 --- a/styles/v3/elements/number-input.scss +++ /dev/null @@ -1,20 +0,0 @@ -@use "../mixins/material"; - -.dotdungeon.style-v3 > .window-content input[type=number] { - outline: none; - border: none; - @include material.elevate(3); - padding: 4px 8px; - color: white; - transition: all 200ms ease-in-out; - text-align: center; - line-height: 1rem; - - &:hover { - @include material.elevate(4); - } - - &:focus-visible { - @include material.elevate(6); - } -} diff --git a/styles/v3/elements/panel.scss b/styles/v3/elements/panel.scss deleted file mode 100644 index de7cf9f..0000000 --- a/styles/v3/elements/panel.scss +++ /dev/null @@ -1,21 +0,0 @@ -@use "../mixins/material" as material; - -.dotdungeon.style-v3 > .window-content { - .panel { - @include material.elevate(2); - border-radius: 4px; - padding: var(--gap); - - &--row { - @extend .panel; - display: flex; - flex-direction: row; - gap: var(--gap); - align-items: center; - - &.space-between { - justify-content: space-between; - } - } - } -} diff --git a/styles/v3/elements/select.scss b/styles/v3/elements/select.scss deleted file mode 100644 index 55125ac..0000000 --- a/styles/v3/elements/select.scss +++ /dev/null @@ -1,26 +0,0 @@ -@use "../mixins/material"; - -.dotdungeon.style-v3 > .window-content { - select { - outline: none; - border: none; - @include material.elevate(3); - padding: 4px 8px; - color: white; - transition: all 200ms ease-in-out; - width: 6.25rem; - - &:hover { - @include material.elevate(4); - } - - &:focus-visible { - @include material.elevate(6); - } - } - - option { - background: var(--surface); - color: var(--on-surface); - } -} diff --git a/styles/v3/elements/text-input.scss b/styles/v3/elements/text-input.scss deleted file mode 100644 index 4c066ed..0000000 --- a/styles/v3/elements/text-input.scss +++ /dev/null @@ -1,20 +0,0 @@ -@use "../mixins/material"; - -.dotdungeon.style-v3 > .window-content input[type=text] { - outline: none; - border: none; - @include material.elevate(3); - padding: 4px 8px; - color: white; - transition: all 200ms ease-in-out; - width: auto; - height: auto; - - &:hover { - @include material.elevate(4); - } - - &:focus-visible { - @include material.elevate(6); - } -} diff --git a/styles/v3/elements/textarea.scss b/styles/v3/elements/textarea.scss deleted file mode 100644 index bc8adcd..0000000 --- a/styles/v3/elements/textarea.scss +++ /dev/null @@ -1,24 +0,0 @@ -@use "../mixins/material" as material; - -.dotdungeon.style-v3 > .window-content textarea { - outline: none; - border: none; - @include material.elevate(3); - color: white; - transition: all 200ms ease-in-out; - font-family: inherit; - font-size: 0.9rem; - - &:hover { - @include material.elevate(4); - } - - &:focus-visible { - @include material.elevate(6); - } - - &.no-resize { - @extend textarea; - resize: none; - } -} diff --git a/styles/v3/elements/utilities.scss b/styles/v3/elements/utilities.scss deleted file mode 100644 index 32cc792..0000000 --- a/styles/v3/elements/utilities.scss +++ /dev/null @@ -1,12 +0,0 @@ -.dotdungeon.style-v3 > .window-content { - .grow { - flex-grow: 1; - } - - .text-center { - text-align: center; - } - .text-right { - text-align: right; - } -} diff --git a/styles/v3/index.scss b/styles/v3/index.scss deleted file mode 100644 index 85ec4bf..0000000 --- a/styles/v3/index.scss +++ /dev/null @@ -1,52 +0,0 @@ -/* Themes */ -@use "./themes/material.css"; -@use "./themes/dark.css"; - -/* Element-Styling */ -@use "./elements/utilities.scss"; -@use "./elements/button.scss"; -@use "./elements/checkbox.scss"; -@use "./elements/select.scss"; -@use "./elements/text-input.scss"; -@use "./elements/number-input.scss"; -@use "./elements/textarea.scss"; -@use "./elements/headers.scss"; -@use "./elements/hr.scss"; -@use "./elements/icons.scss"; -@use "./elements/nav.scss"; -@use "./elements/panel.scss"; -@use "./elements/label.scss"; - -/* Sheet Layouts */ -@use "./layouts/datasheet.scss"; -@use "./layouts/items/untyped/v2.scss"; - -/* Sheet Options */ -.dotdungeon.style-v3 { - --scrollbar-width: 5px; - --scrollbar-handle-color: #782e22; - --scrollbar-handle-border-color: var(--color-border-highlight); - --color-checkbox-checked: inherit; - ::-webkit-scrollbar { - width: var(--scrollbar-width); - } - ::-webkit-scrollbar-thumb { - background: var(--scrollbar-handle-color); - border-color: var(--scrollbar-handle-border-color); - border-radius: 5px; - } - - container-type: size; - - > .window-content { - padding: 0; - background: var(--sheet); - color: var(--on-sheet); - - .debug-data { - opacity: 60%; - font-family: sans-serif; - word-break: break-all; - } - } -} diff --git a/styles/v3/layouts/datasheet.scss b/styles/v3/layouts/datasheet.scss deleted file mode 100644 index aa91e4d..0000000 --- a/styles/v3/layouts/datasheet.scss +++ /dev/null @@ -1,6 +0,0 @@ -.dotdungeon.style-v3 .datasheet { - display: flex; - flex-direction: column; - gap: 8px; - margin: 8px; -} diff --git a/styles/v3/layouts/items/untyped/v2.scss b/styles/v3/layouts/items/untyped/v2.scss deleted file mode 100644 index d94bf49..0000000 --- a/styles/v3/layouts/items/untyped/v2.scss +++ /dev/null @@ -1,81 +0,0 @@ -@use "../../../mixins/material"; -@use "../../../mixins/utils"; - -.dotdungeon.style-v3 .item--untyped { - --gap: 8px; - - .nav-bar { - @include material.elevate(8); - position: absolute; - bottom: 0; - left: 0; - right: 6px; - - nav { - display: flex; - flex-direction: row; - gap: var(--gap); - padding: var(--gap); - } - } - - .page-content { - padding: calc(var(--gap) * 1); - padding-bottom: 60px; - height: 100%; - - > .tab { - height: 100%; - gap: var(--gap); - } - } - - @include utils.tab("general") { - display: grid; - --height: 50px; - grid-template-columns: var(--height) 1fr; - grid-template-rows: var(--height) 1fr; - - .description { - grid-column: 1 / -1; - } - } - - %flex-col { - display: flex; - flex-direction: column; - gap: 8px; - } - - @include utils.tab("details") { - @extend %flex-col; - - .number { - display: grid; - grid-template-columns: 1fr 55px; - align-items: center; - } - } - - @include utils.tab("effects") { - @extend %flex-col; - } - - @include utils.tab("settings") { - @extend %flex-col; - - .capacity-usage, .quantity-capacity, .combat-relevant { - display: flex; - align-items: center; - } - - .capacity { - &--calculated { - display: flex; - flex-direction: row; - align-items: center; - gap: 8px; - } - } - } -} diff --git a/styles/v3/mixins/_material.scss b/styles/v3/mixins/_material.scss deleted file mode 100644 index a869640..0000000 --- a/styles/v3/mixins/_material.scss +++ /dev/null @@ -1,13 +0,0 @@ -@mixin elevate($height) { - background-color: var(--elevation-#{$height}dp-bg); - -webkit-box-shadow: 0px 0px #{$height * 1.75}px 0px rgba(0,0,0,0.75); - -moz-box-shadow: 0px 0px #{$height * 1.75}px 0px rgba(0,0,0,0.75); - box-shadow: 0px 0px #{$height * 1.75}px 0px rgba(0,0,0,0.75); -} - -@mixin undo { - background-color: transparent; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} diff --git a/styles/v3/mixins/_utils.scss b/styles/v3/mixins/_utils.scss deleted file mode 100644 index 02818c0..0000000 --- a/styles/v3/mixins/_utils.scss +++ /dev/null @@ -1,5 +0,0 @@ -@mixin tab($name) { - .tab.active[data-tab="#{$name}"] { - @content; - } -} diff --git a/styles/v3/themes/dark.css b/styles/v3/themes/dark.css deleted file mode 100644 index 374056f..0000000 --- a/styles/v3/themes/dark.css +++ /dev/null @@ -1,9 +0,0 @@ -.dotdungeon.style-v3 { - --sheet: #0a0a0a; - --on-sheet: white; - - --surface: #121212; - --on-surface: white; - - --checkbox-checked: #00d300; -} diff --git a/styles/v3/themes/material.css b/styles/v3/themes/material.css deleted file mode 100644 index 7c934dc..0000000 --- a/styles/v3/themes/material.css +++ /dev/null @@ -1,27 +0,0 @@ -/* -These CSS variables are all used in order to try following Material design as -best as I can. -*/ - -.dotdungeon.style-v3 { - --elevation-0dp-bg: var(--surface); - --elevation-0dp-text: var(--on-surface); - --elevation-1dp-bg: color-mix(in lab, transparent, white 5%); - --elevation-1dp-text: white; - --elevation-2dp-bg: color-mix(in lab, transparent, white 7%); - --elevation-2dp-text: white; - --elevation-3dp-bg: color-mix(in lab, transparent, white 8%); - --elevation-3dp-text: white; - --elevation-4dp-bg: color-mix(in lab, transparent, white 9%); - --elevation-4dp-text: white; - --elevation-6dp-bg: color-mix(in lab, transparent, white 11%); - --elevation-6dp-text: white; - --elevation-8dp-bg: color-mix(in lab, transparent, white 12%); - --elevation-8dp-text: white; - --elevation-12dp-bg: color-mix(in lab, transparent, white 14%); - --elevation-12dp-text: white; - --elevation-16dp-bg: color-mix(in lab, transparent, white 15%); - --elevation-16dp-text: white; - --elevation-24dp-bg: color-mix(in lab, transparent, white 16%); - --elevation-24dp-text: white; -} \ No newline at end of file diff --git a/system.json b/system.json index 5d3387c..d545557 100644 --- a/system.json +++ b/system.json @@ -2,7 +2,7 @@ "id": "dotdungeon", "title": ".dungeon", "description": "", - "version": "0.0.9", + "version": "0.0.5", "download": "https://github.com/Oliver-Akins/foundry.dungeon/releases/latest/download/dotdungeon.zip", "manifest": "https://github.com/Oliver-Akins/foundry.dungeon/releases/latest/download/system.json", "url": "https://github.com/Oliver-Akins/foundry.dungeon", @@ -27,7 +27,7 @@ { "lang": "en", "name": "English (Canadian)", - "path": "langs/en-ca.2.json" + "path": "langs/en-ca.json" } ], "packs": [ diff --git a/template.json b/template.json index 2954976..f8aefd5 100644 --- a/template.json +++ b/template.json @@ -9,13 +9,13 @@ "Item": { "types": [ "untyped", - "material", "aspect", "weapon", "armour", "equipment", "foil", "pet", + "transportation", "structure", "service", "legendaryItem", diff --git a/templates/actors/char-sheet-mvp/sheet.hbs b/templates/actors/char-sheet-mvp/sheet.hbs index 7497352..98e9dcc 100644 --- a/templates/actors/char-sheet-mvp/sheet.hbs +++ b/templates/actors/char-sheet-mvp/sheet.hbs @@ -1,4 +1,4 @@ -
+ {{> dotdungeon.pc.profile }} diff --git a/templates/actors/char-sheet/v2/partials/effects.v2.pc.hbs b/templates/actors/char-sheet/v2/partials/effects.v2.pc.hbs deleted file mode 100644 index 78d7635..0000000 --- a/templates/actors/char-sheet/v2/partials/effects.v2.pc.hbs +++ /dev/null @@ -1,10 +0,0 @@ -
- Effects - {{!-- - Things to list: - Name - Source - Toggle to activate - Edit button - --}} -
diff --git a/templates/actors/char-sheet/v2/partials/inventory/inventory.v2.pc.hbs b/templates/actors/char-sheet/v2/partials/inventory/inventory.v2.pc.hbs deleted file mode 100644 index f4e2bd5..0000000 --- a/templates/actors/char-sheet/v2/partials/inventory/inventory.v2.pc.hbs +++ /dev/null @@ -1,4 +0,0 @@ -
- {{> dotdungeon.pc.v2.storage }} - {{> dotdungeon.pc.v2.player }} -
diff --git a/templates/actors/char-sheet/v2/partials/inventory/item-list.v2.pc.hbs b/templates/actors/char-sheet/v2/partials/inventory/item-list.v2.pc.hbs deleted file mode 100644 index 73926f9..0000000 --- a/templates/actors/char-sheet/v2/partials/inventory/item-list.v2.pc.hbs +++ /dev/null @@ -1,34 +0,0 @@ -
- {{#if computed.noItemTypesVisible}} -

- Enable a filter to show items of that type! -

- {{/if}} - {{#each computed.itemFilters as | filter |}} - {{#if filter.active}} -
-
-

{{filter.label}}

- -
-
-
- {{#each (lookup @root.items @key) as | item |}} - {{> (concat "dotdungeon.pc.v2." @../key) @root item=item}} - {{else}} - No items found - {{/each}} -
-
- {{/if}} - {{/each}} -
diff --git a/templates/actors/char-sheet/v2/partials/inventory/items/aspect.v2.pc.hbs b/templates/actors/char-sheet/v2/partials/inventory/items/aspect.v2.pc.hbs deleted file mode 100644 index ff106e6..0000000 --- a/templates/actors/char-sheet/v2/partials/inventory/items/aspect.v2.pc.hbs +++ /dev/null @@ -1,94 +0,0 @@ -
-
- -

- {{item.name}} -

-
-
-
-
-
- - -
-
- Duration: - - {{dd-empty-state item.friendlyDuration}} - -
-
- Tier: - {{dd-i18n (concat "dotdungeon.rarity." item.system.tier)}} -
- -

- {{#if item.system.description}} - {{item.system.description}} - {{else}} - - This item hasn't been described yet... - - {{/if}} -

- - -
-
-
diff --git a/templates/actors/char-sheet/v2/partials/inventory/items/material.v2.pc.hbs b/templates/actors/char-sheet/v2/partials/inventory/items/material.v2.pc.hbs deleted file mode 100644 index ea0a8b3..0000000 --- a/templates/actors/char-sheet/v2/partials/inventory/items/material.v2.pc.hbs +++ /dev/null @@ -1,17 +0,0 @@ -
- - -
diff --git a/templates/actors/char-sheet/v2/partials/inventory/items/pet.v2.pc.hbs b/templates/actors/char-sheet/v2/partials/inventory/items/pet.v2.pc.hbs deleted file mode 100644 index dc0e1a8..0000000 --- a/templates/actors/char-sheet/v2/partials/inventory/items/pet.v2.pc.hbs +++ /dev/null @@ -1,94 +0,0 @@ -
-
- -

- {{item.name}} -

-
-
-
-
-
- - -
-
- Upkeep: - - {{dd-empty-state item.system.upkeep}} - -
-
- Tier: - {{dd-i18n (concat "dotdungeon.rarity." item.system.tier)}} -
- -

- {{#if item.system.description}} - {{item.system.description}} - {{else}} - - This pet hasn't been described yet... - - {{/if}} -

- - -
-
-
diff --git a/templates/actors/char-sheet/v2/partials/inventory/items/untyped.v2.pc.hbs b/templates/actors/char-sheet/v2/partials/inventory/items/untyped.v2.pc.hbs deleted file mode 100644 index de3abdc..0000000 --- a/templates/actors/char-sheet/v2/partials/inventory/items/untyped.v2.pc.hbs +++ /dev/null @@ -1,98 +0,0 @@ -
-
- -

- {{item.name}} -

-
- (x {{item.system.quantity}}) -
-
-
-
-
-
- - -
-
- Usage Cost: - - {{dd-empty-state item.system.usage_cost}} - -
-
- Tier: - {{dd-i18n (concat "dotdungeon.rarity." item.system.tier)}} -
- -

- {{#if item.system.description}} - {{item.system.description}} - {{else}} - - This item hasn't been described yet... - - {{/if}} -

- - -
-
-
diff --git a/templates/actors/char-sheet/v2/partials/inventory/items/weapon.v2.pc.hbs b/templates/actors/char-sheet/v2/partials/inventory/items/weapon.v2.pc.hbs deleted file mode 100644 index 6b0fe0f..0000000 --- a/templates/actors/char-sheet/v2/partials/inventory/items/weapon.v2.pc.hbs +++ /dev/null @@ -1,113 +0,0 @@ -
-
- -

- {{item.name}} -

-
- (x {{item.system.quantity}}) -
-
-
-
-
-
- - -
-
- Type: - - {{ifThen item.system.ranged "Ranged" "Melee"}} - -
-
- Damage: - - {{dd-empty-state item.system.damage}} - -
- -
- Tier: - {{dd-i18n (concat "dotdungeon.rarity." item.system.tier)}} -
-
- {{ifThen item.system.scoped "Scoped" "No Scope"}} -
-
- Ammo: - - {{dd-empty-state item.system.ammo}} - -
- -

- {{#if item.system.description}} - {{item.system.description}} - {{else}} - - This item hasn't been described yet... - - {{/if}} -

- -
-
-
diff --git a/templates/actors/char-sheet/v2/partials/inventory/player.v2.pc.hbs b/templates/actors/char-sheet/v2/partials/inventory/player.v2.pc.hbs deleted file mode 100644 index 900af1f..0000000 --- a/templates/actors/char-sheet/v2/partials/inventory/player.v2.pc.hbs +++ /dev/null @@ -1,57 +0,0 @@ -
-
-

Containers

-
- {{> dotdungeon.pc.v2.item-list }} -
-

Capacity

- {{computed.capacity.used}} - / - {{computed.capacity.max}} -
-
- - -
-
- - -
-
-

Show

- - {{#each computed.itemFilters as | filter |}} - - {{/each}} -
-
diff --git a/templates/actors/char-sheet/v2/partials/inventory/storage.v2.pc.hbs b/templates/actors/char-sheet/v2/partials/inventory/storage.v2.pc.hbs deleted file mode 100644 index d20d2de..0000000 --- a/templates/actors/char-sheet/v2/partials/inventory/storage.v2.pc.hbs +++ /dev/null @@ -1 +0,0 @@ -
Storage
diff --git a/templates/actors/char-sheet/v2/partials/stats.v2.pc.hbs b/templates/actors/char-sheet/v2/partials/stats.v2.pc.hbs deleted file mode 100644 index 6353120..0000000 --- a/templates/actors/char-sheet/v2/partials/stats.v2.pc.hbs +++ /dev/null @@ -1,68 +0,0 @@ -
- {{#each computed.stats as | stat |}} -
-
-

{{stat.name}}

- - -
- {{#if stat.skills}} - {{#if stat.value}} -
- {{#each stat.skills as | skill |}} - - - - {{/each}} -
- {{else}} -
-

- {{dd-i18n "dotdungeon.sheet.actor.v2.stat-not-chosen" stat}} -

-
- {{/if}} - {{/if}} -
- {{/each}} -
diff --git a/templates/actors/char-sheet/v2/sheet.hbs b/templates/actors/char-sheet/v2/sheet.hbs deleted file mode 100644 index b32fac7..0000000 --- a/templates/actors/char-sheet/v2/sheet.hbs +++ /dev/null @@ -1,30 +0,0 @@ - - {{!-- All panels here --}} -
-
Avatar
- {{> dotdungeon.pc.v2.stats }} -
Combat
- {{> dotdungeon.pc.v2.inventory }} -
Spells
-
Settings
- {{> dotdungeon.pc.v2.effects }} -
- - - {{!-- Tab list here --}} - -
diff --git a/templates/actors/mobs/main.v2.hbs b/templates/actors/mobs/main.v2.hbs deleted file mode 100644 index 3e701f2..0000000 --- a/templates/actors/mobs/main.v2.hbs +++ /dev/null @@ -1,32 +0,0 @@ -
-
- -
- Dice: - - - -
- -
-
-
-
Combat
-
About
-
-
- Combat Tab -
-
-
\ No newline at end of file diff --git a/templates/actors/sync/basic.hbs b/templates/actors/sync/basic.hbs index 209e064..93a0e84 100644 --- a/templates/actors/sync/basic.hbs +++ b/templates/actors/sync/basic.hbs @@ -1,6 +1,6 @@