Compare commits
1 commit
045991073b
...
3bc7c7819b
Author | SHA1 | Date | |
---|---|---|---|
3bc7c7819b |
1590 changed files with 70381 additions and 70413 deletions
|
@ -3,13 +3,13 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
module.exports = {
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: { ecmaVersion: 2020, sourceType: "module" },
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: { ecmaVersion: 2020, sourceType: 'module' },
|
||||
env: { browser: true },
|
||||
extends: ["plugin:@typescript-eslint/recommended", "prettier"],
|
||||
plugins: ["@typescript-eslint"],
|
||||
extends: ['plugin:@typescript-eslint/recommended', 'prettier'],
|
||||
plugins: ['@typescript-eslint'],
|
||||
overrides: [
|
||||
{ files: ["./*.cjs"], rules: { "@typescript-eslint/no-var-requires": "off" } },
|
||||
{ files: ["./spec/**/*"], env: { browser: false } },
|
||||
{ files: ['./*.cjs'], rules: { '@typescript-eslint/no-var-requires': 'off' } },
|
||||
{ files: ['./spec/**/*'], env: { browser: false } },
|
||||
],
|
||||
};
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: "all",
|
||||
singleQuote: false,
|
||||
printWidth: 120,
|
||||
tabWidth: 4,
|
||||
};
|
11
.prettierrc.js
Normal file
11
.prettierrc.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
export default {
|
||||
semi: true,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
printWidth: 120,
|
||||
tabWidth: 2,
|
||||
};
|
|
@ -2,4 +2,4 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
module.exports = { extends: ["@commitlint/config-conventional"] };
|
||||
module.exports = { extends: ['@commitlint/config-conventional'] };
|
||||
|
|
|
@ -2,29 +2,29 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import styles from "@ironkinoko/rollup-plugin-styles";
|
||||
import { swc } from "rollup-plugin-swc3";
|
||||
import styles from '@ironkinoko/rollup-plugin-styles';
|
||||
import { swc } from 'rollup-plugin-swc3';
|
||||
|
||||
import { copy } from "@guanghechen/rollup-plugin-copy";
|
||||
import { copy } from '@guanghechen/rollup-plugin-copy';
|
||||
|
||||
import { distDirectory, name, sourceDirectory } from "./tools/const.js";
|
||||
import { distDirectory, name, sourceDirectory } from './tools/const.js';
|
||||
|
||||
const staticFiles = [
|
||||
".reuse",
|
||||
"assets",
|
||||
"ATTRIBUTION.md",
|
||||
"fonts",
|
||||
"lang",
|
||||
"LICENSE.md",
|
||||
"LICENSES",
|
||||
"README.md",
|
||||
"system.json.license",
|
||||
"system.json",
|
||||
"template.json.license",
|
||||
"template.json",
|
||||
"templates",
|
||||
'.reuse',
|
||||
'assets',
|
||||
'ATTRIBUTION.md',
|
||||
'fonts',
|
||||
'lang',
|
||||
'LICENSE.md',
|
||||
'LICENSES',
|
||||
'README.md',
|
||||
'system.json.license',
|
||||
'system.json',
|
||||
'template.json.license',
|
||||
'template.json',
|
||||
'templates',
|
||||
];
|
||||
const isProduction = process.env.NODE_ENV === "production";
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
/**
|
||||
* @type {import('rollup').RollupOptions}
|
||||
|
@ -33,9 +33,9 @@ const config = {
|
|||
input: { [name]: `${sourceDirectory}/${name}.ts` },
|
||||
output: {
|
||||
dir: distDirectory,
|
||||
format: "es",
|
||||
format: 'es',
|
||||
sourcemap: true,
|
||||
assetFileNames: "[name].[ext]",
|
||||
assetFileNames: '[name].[ext]',
|
||||
},
|
||||
plugins: [
|
||||
swc({
|
||||
|
@ -51,7 +51,7 @@ const config = {
|
|||
sourceMaps: true,
|
||||
}),
|
||||
styles({
|
||||
mode: ["extract", `css/${name}.css`],
|
||||
mode: ['extract', `css/${name}.css`],
|
||||
url: false,
|
||||
sourceMap: true,
|
||||
minimize: isProduction,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "../../utils/mixins";
|
||||
@use '../../utils/mixins';
|
||||
|
||||
.ds4-actor-header {
|
||||
display: flex;
|
||||
|
@ -44,7 +44,7 @@
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
&__name-input[type="text"] {
|
||||
&__name-input[type='text'] {
|
||||
@include mixins.font-heading-upper;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "../../utils/colors";
|
||||
@use "../../utils/mixins";
|
||||
@use "../../utils/variables";
|
||||
@use '../../utils/colors';
|
||||
@use '../../utils/mixins';
|
||||
@use '../../utils/variables';
|
||||
|
||||
.ds4-actor-progression {
|
||||
@include mixins.mark-invalid-or-disabled-input;
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "../../utils/mixins";
|
||||
@use "../../utils/variables";
|
||||
@use '../../utils/mixins';
|
||||
@use '../../utils/variables';
|
||||
|
||||
.ds4-actor-properties {
|
||||
@include mixins.mark-invalid-or-disabled-input;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "../../utils/mixins";
|
||||
@use '../../utils/mixins';
|
||||
|
||||
.ds4-check {
|
||||
background: transparent;
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "../../utils/mixins";
|
||||
@use "../../utils/variables";
|
||||
@use '../../utils/mixins';
|
||||
@use '../../utils/variables';
|
||||
|
||||
.ds4-combat-value {
|
||||
$size: 3.75rem;
|
||||
|
@ -15,7 +15,7 @@
|
|||
row-gap: 0.125em;
|
||||
|
||||
&__value {
|
||||
$combat-values-icons-path: "#{variables.$official-icons-path}/combat-values";
|
||||
$combat-values-icons-path: '#{variables.$official-icons-path}/combat-values';
|
||||
@include mixins.centered-content;
|
||||
|
||||
background-position: center;
|
||||
|
@ -26,28 +26,28 @@
|
|||
width: $size;
|
||||
|
||||
&--hitPoints {
|
||||
background-image: url("#{$combat-values-icons-path}/hit-points.png");
|
||||
background-image: url('#{$combat-values-icons-path}/hit-points.png');
|
||||
}
|
||||
&--defense {
|
||||
background-image: url("#{$combat-values-icons-path}/defense.png");
|
||||
background-image: url('#{$combat-values-icons-path}/defense.png');
|
||||
}
|
||||
&--initiative {
|
||||
background-image: url("#{$combat-values-icons-path}/initiative.png");
|
||||
background-image: url('#{$combat-values-icons-path}/initiative.png');
|
||||
}
|
||||
&--movement {
|
||||
background-image: url("#{$combat-values-icons-path}/movement-rate.png");
|
||||
background-image: url('#{$combat-values-icons-path}/movement-rate.png');
|
||||
}
|
||||
&--meleeAttack {
|
||||
background-image: url("#{$combat-values-icons-path}/melee-attack.png");
|
||||
background-image: url('#{$combat-values-icons-path}/melee-attack.png');
|
||||
}
|
||||
&--rangedAttack {
|
||||
background-image: url("#{$combat-values-icons-path}/ranged-attack.png");
|
||||
background-image: url('#{$combat-values-icons-path}/ranged-attack.png');
|
||||
}
|
||||
&--spellcasting {
|
||||
background-image: url("#{$combat-values-icons-path}/spellcasting.png");
|
||||
background-image: url('#{$combat-values-icons-path}/spellcasting.png');
|
||||
}
|
||||
&--targetedSpellcasting {
|
||||
background-image: url("#{$combat-values-icons-path}/targeted-spellcasting.png");
|
||||
background-image: url('#{$combat-values-icons-path}/targeted-spellcasting.png');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "../../utils/variables";
|
||||
@use '../../utils/variables';
|
||||
|
||||
.ds4-combat-values {
|
||||
border-bottom: variables.$border-groove;
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "../../utils/colors";
|
||||
@use "../../utils/mixins";
|
||||
@use "../../utils/variables";
|
||||
@use '../../utils/colors';
|
||||
@use '../../utils/mixins';
|
||||
@use '../../utils/variables';
|
||||
|
||||
.ds4-core-value {
|
||||
align-items: center;
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "../../utils/colors";
|
||||
@use "../../utils/variables";
|
||||
@use '../../utils/colors';
|
||||
@use '../../utils/variables';
|
||||
|
||||
.ds4-core-values {
|
||||
column-gap: 0.5em;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "../../utils/variables";
|
||||
@use '../../utils/variables';
|
||||
|
||||
.ds4-currency {
|
||||
align-items: center;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "../../utils/colors";
|
||||
@use '../../utils/colors';
|
||||
|
||||
// Needs to be nested in .dice-roll to win against foundry's style.css with respect to specificity
|
||||
.dice-roll .ds4-dice-total {
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "../../utils/colors";
|
||||
@use "../../utils/mixins";
|
||||
@use '../../utils/colors';
|
||||
@use '../../utils/mixins';
|
||||
|
||||
.ds4-item-header {
|
||||
align-items: center;
|
||||
|
@ -39,7 +39,7 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
&__name-input[type="text"] {
|
||||
&__name-input[type='text'] {
|
||||
@include mixins.font-heading-upper;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "../../utils/mixins";
|
||||
@use "../../utils/variables";
|
||||
@use '../../utils/mixins';
|
||||
@use '../../utils/variables';
|
||||
|
||||
.ds4-item-properties {
|
||||
@include mixins.mark-invalid-or-disabled-input;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
&__checkbox[type="checkbox"] {
|
||||
&__checkbox[type='checkbox'] {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "../../utils/mixins";
|
||||
@use "../../utils/variables";
|
||||
@use '../../utils/mixins';
|
||||
@use '../../utils/variables';
|
||||
|
||||
.ds4-embedded-document-list {
|
||||
@include mixins.mark-invalid-or-disabled-input;
|
||||
|
@ -105,8 +105,8 @@
|
|||
}
|
||||
|
||||
&__editable {
|
||||
&[type="text"],
|
||||
&[type="number"] {
|
||||
&[type='text'],
|
||||
&[type='number'] {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
|
@ -114,7 +114,7 @@
|
|||
}
|
||||
|
||||
&--checkbox {
|
||||
&[type="checkbox"] {
|
||||
&[type='checkbox'] {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "../../utils/variables";
|
||||
@use '../../utils/variables';
|
||||
|
||||
.ds4-sheet-tab-nav {
|
||||
border-bottom: variables.$border-groove;
|
||||
|
|
|
@ -7,43 +7,43 @@
|
|||
*/
|
||||
|
||||
// global
|
||||
@use "global/accessibility";
|
||||
@use "global/fonts";
|
||||
@use "global/utils";
|
||||
@use 'global/accessibility';
|
||||
@use 'global/fonts';
|
||||
@use 'global/utils';
|
||||
|
||||
// shared
|
||||
@use "components/shared/add_button";
|
||||
@use "components/shared/control_button_group";
|
||||
@use "components/shared/checkbox_grid";
|
||||
@use "components/shared/editor";
|
||||
@use "components/shared/embedded_document_list";
|
||||
@use "components/shared/form_group";
|
||||
@use "components/shared/rollable_image";
|
||||
@use "components/shared/sheet_body";
|
||||
@use "components/shared/sheet_form";
|
||||
@use "components/shared/sheet_tab_nav";
|
||||
@use "components/shared/sheet_tab";
|
||||
@use 'components/shared/add_button';
|
||||
@use 'components/shared/control_button_group';
|
||||
@use 'components/shared/checkbox_grid';
|
||||
@use 'components/shared/editor';
|
||||
@use 'components/shared/embedded_document_list';
|
||||
@use 'components/shared/form_group';
|
||||
@use 'components/shared/rollable_image';
|
||||
@use 'components/shared/sheet_body';
|
||||
@use 'components/shared/sheet_form';
|
||||
@use 'components/shared/sheet_tab_nav';
|
||||
@use 'components/shared/sheet_tab';
|
||||
|
||||
// actor
|
||||
@use "components/actor/actor_header";
|
||||
@use "components/actor/actor_progression";
|
||||
@use "components/actor/actor_properties";
|
||||
@use "components/actor/actor_sheet";
|
||||
@use "components/actor/biography";
|
||||
@use "components/actor/check";
|
||||
@use "components/actor/checks";
|
||||
@use "components/actor/combat_value";
|
||||
@use "components/actor/combat_values";
|
||||
@use "components/actor/core_value";
|
||||
@use "components/actor/core_values";
|
||||
@use "components/actor/currency";
|
||||
@use "components/actor/description";
|
||||
@use "components/actor/profile";
|
||||
@use 'components/actor/actor_header';
|
||||
@use 'components/actor/actor_progression';
|
||||
@use 'components/actor/actor_properties';
|
||||
@use 'components/actor/actor_sheet';
|
||||
@use 'components/actor/biography';
|
||||
@use 'components/actor/check';
|
||||
@use 'components/actor/checks';
|
||||
@use 'components/actor/combat_value';
|
||||
@use 'components/actor/combat_values';
|
||||
@use 'components/actor/core_value';
|
||||
@use 'components/actor/core_values';
|
||||
@use 'components/actor/currency';
|
||||
@use 'components/actor/description';
|
||||
@use 'components/actor/profile';
|
||||
|
||||
// item
|
||||
@use "components/item/item_header";
|
||||
@use "components/item/item_properties";
|
||||
@use "components/item/item_sheet";
|
||||
@use 'components/item/item_header';
|
||||
@use 'components/item/item_properties';
|
||||
@use 'components/item/item_sheet';
|
||||
|
||||
// dice
|
||||
@use "components/dice/dice_total";
|
||||
@use 'components/dice/dice_total';
|
||||
|
|
|
@ -6,55 +6,55 @@
|
|||
|
||||
@font-face {
|
||||
font-display: swap;
|
||||
font-family: "Lora";
|
||||
font-family: 'Lora';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src:
|
||||
local("Lora"),
|
||||
url("../fonts/Lora/Lora.woff") format("woff");
|
||||
local('Lora'),
|
||||
url('../fonts/Lora/Lora.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-display: swap;
|
||||
font-family: "Lora";
|
||||
font-family: 'Lora';
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
src:
|
||||
local("Lora"),
|
||||
url("../fonts/Lora/Lora-Bold.woff") format("woff");
|
||||
local('Lora'),
|
||||
url('../fonts/Lora/Lora-Bold.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-display: swap;
|
||||
font-family: "Lora";
|
||||
font-family: 'Lora';
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
src:
|
||||
local("Lora"),
|
||||
url("../fonts/Lora/Lora-Italic.woff") format("woff");
|
||||
local('Lora'),
|
||||
url('../fonts/Lora/Lora-Italic.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-display: swap;
|
||||
font-family: "Lora";
|
||||
font-family: 'Lora';
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
src:
|
||||
local("Lora"),
|
||||
url("../fonts/Lora/Lora-BoldItalic.woff") format("woff");
|
||||
local('Lora'),
|
||||
url('../fonts/Lora/Lora-BoldItalic.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-display: swap;
|
||||
font-family: "Wood Stamp";
|
||||
font-family: 'Wood Stamp';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src:
|
||||
local("Wood Stamp"),
|
||||
url("../fonts/Woodstamp/Woodstamp.woff") format("woff");
|
||||
local('Wood Stamp'),
|
||||
url('../fonts/Woodstamp/Woodstamp.woff') format('woff');
|
||||
}
|
||||
|
||||
:root {
|
||||
--ds4-font-primary: Lora, serif;
|
||||
--ds4-font-heading: "Wood Stamp", sans-serif;
|
||||
--ds4-font-heading: 'Wood Stamp', sans-serif;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "./colors";
|
||||
@use './colors';
|
||||
|
||||
@mixin centered-content {
|
||||
display: grid;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
@use "./colors";
|
||||
@use './colors';
|
||||
|
||||
$padding-sm: 5px;
|
||||
$padding-md: 10px;
|
||||
|
@ -13,6 +13,6 @@ $margin-sm: $padding-sm;
|
|||
$margin-md: $padding-md;
|
||||
$margin-lg: $padding-lg;
|
||||
|
||||
$official-icons-path: "../assets/icons/official";
|
||||
$official-icons-path: '../assets/icons/official';
|
||||
|
||||
$border-groove: 2px groove colors.$c-border-groove;
|
||||
|
|
|
@ -3,38 +3,38 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { evaluateCheck } from "../../src/dice/check-evaluation";
|
||||
import { evaluateCheck } from '../../src/dice/check-evaluation';
|
||||
|
||||
describe("evaluateCheck with no dice", () => {
|
||||
it("should throw an error.", () => {
|
||||
expect(() => evaluateCheck([], 10)).toThrow("Invalid number of dice.");
|
||||
describe('evaluateCheck with no dice', () => {
|
||||
it('should throw an error.', () => {
|
||||
expect(() => evaluateCheck([], 10)).toThrow('Invalid number of dice.');
|
||||
});
|
||||
});
|
||||
|
||||
describe("evaluateCheck with more dice than required by the checkTargetNumber", () => {
|
||||
it("should throw an error.", () => {
|
||||
expect(() => evaluateCheck([10, 10], 10)).toThrow("Invalid number of dice.");
|
||||
describe('evaluateCheck with more dice than required by the checkTargetNumber', () => {
|
||||
it('should throw an error.', () => {
|
||||
expect(() => evaluateCheck([10, 10], 10)).toThrow('Invalid number of dice.');
|
||||
});
|
||||
});
|
||||
|
||||
describe("evaluateCheck with less dice than required by the checkTargetNumber", () => {
|
||||
it("should throw an error.", () => {
|
||||
expect(() => evaluateCheck([10], 21)).toThrow("Invalid number of dice.");
|
||||
describe('evaluateCheck with less dice than required by the checkTargetNumber', () => {
|
||||
it('should throw an error.', () => {
|
||||
expect(() => evaluateCheck([10], 21)).toThrow('Invalid number of dice.');
|
||||
});
|
||||
});
|
||||
|
||||
describe("evaluateCheck with a single die", () => {
|
||||
it("should assign the checkTargetNumber to the single die and be successful.", () => {
|
||||
describe('evaluateCheck with a single die', () => {
|
||||
it('should assign the checkTargetNumber to the single die and be successful.', () => {
|
||||
expect(evaluateCheck([4], 12)).toEqual([{ result: 4, checkTargetNumber: 12, active: true, discarded: false }]);
|
||||
});
|
||||
|
||||
it("should assign the checkTargetNumber to the single die on upper edge case and be successful.", () => {
|
||||
it('should assign the checkTargetNumber to the single die on upper edge case and be successful.', () => {
|
||||
expect(evaluateCheck([4], 4)).toEqual([{ result: 4, checkTargetNumber: 4, active: true, discarded: false }]);
|
||||
});
|
||||
|
||||
it("should assign the checkTargetNumber to the single die on lower edge case not be successful.", () => {
|
||||
it('should assign the checkTargetNumber to the single die on lower edge case not be successful.', () => {
|
||||
expect(evaluateCheck([5], 4)).toEqual([{ result: 5, checkTargetNumber: 4, active: false, discarded: true }]);
|
||||
});
|
||||
|
||||
|
@ -54,48 +54,44 @@ describe("evaluateCheck with a single die", () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it("should roll a die even when the checkTargetNumber is 0 and coup on 1", () => {
|
||||
it('should roll a die even when the checkTargetNumber is 0 and coup on 1', () => {
|
||||
expect(evaluateCheck([1], 0)).toEqual([
|
||||
{ result: 1, checkTargetNumber: 0, active: true, discarded: false, success: true, count: 0 },
|
||||
]);
|
||||
});
|
||||
|
||||
it("should roll a die even when the checkTargetNumber is 0 and fail on values > 1 and < 20", () => {
|
||||
it('should roll a die even when the checkTargetNumber is 0 and fail on values > 1 and < 20', () => {
|
||||
for (let i = 2; i < 20; i++) {
|
||||
expect(evaluateCheck([i], 0)).toEqual([
|
||||
{ result: i, checkTargetNumber: 0, active: false, discarded: true },
|
||||
]);
|
||||
expect(evaluateCheck([i], 0)).toEqual([{ result: i, checkTargetNumber: 0, active: false, discarded: true }]);
|
||||
}
|
||||
});
|
||||
|
||||
it("should roll a die even when the checkTargetNumber is 0 and fumble on 20", () => {
|
||||
it('should roll a die even when the checkTargetNumber is 0 and fumble on 20', () => {
|
||||
expect(evaluateCheck([20], 0)).toEqual([
|
||||
{ result: 20, checkTargetNumber: 0, active: false, discarded: true, failure: true },
|
||||
]);
|
||||
});
|
||||
|
||||
it("should roll a die even when the checkTargetNumber is < 0 and coup on 1", () => {
|
||||
it('should roll a die even when the checkTargetNumber is < 0 and coup on 1', () => {
|
||||
expect(evaluateCheck([1], -1)).toEqual([
|
||||
{ result: 1, checkTargetNumber: -1, active: true, discarded: false, success: true, count: -1 },
|
||||
]);
|
||||
});
|
||||
|
||||
it("should roll a die even when the checkTargetNumber is < 0 and fail on values > 1 and < 20", () => {
|
||||
it('should roll a die even when the checkTargetNumber is < 0 and fail on values > 1 and < 20', () => {
|
||||
for (let i = 2; i < 20; i++) {
|
||||
expect(evaluateCheck([i], -1)).toEqual([
|
||||
{ result: i, checkTargetNumber: -1, active: false, discarded: true },
|
||||
]);
|
||||
expect(evaluateCheck([i], -1)).toEqual([{ result: i, checkTargetNumber: -1, active: false, discarded: true }]);
|
||||
}
|
||||
});
|
||||
|
||||
it("should roll a die even when the checkTargetNumber is < 0 and fumble on 20", () => {
|
||||
it('should roll a die even when the checkTargetNumber is < 0 and fumble on 20', () => {
|
||||
expect(evaluateCheck([20], -1)).toEqual([
|
||||
{ result: 20, checkTargetNumber: -1, active: false, discarded: true, failure: true },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("evaluateCheck with a single die and coup / fumble modification", () => {
|
||||
describe('evaluateCheck with a single die and coup / fumble modification', () => {
|
||||
const maximumCoupResult = 2;
|
||||
const minimumFumbleResult = 19;
|
||||
|
||||
|
@ -185,7 +181,7 @@ describe("evaluateCheck with a single die and coup / fumble modification", () =>
|
|||
});
|
||||
});
|
||||
|
||||
describe("evaluateCheck with multiple dice", () => {
|
||||
describe('evaluateCheck with multiple dice', () => {
|
||||
it("should assign the checkTargetNumber for the last sub check to the lowest non coup, even if the first is '20'.", () => {
|
||||
expect(evaluateCheck([20, 6, 15], 48)).toEqual([
|
||||
{ result: 20, checkTargetNumber: 20, active: true, discarded: false, failure: true },
|
||||
|
@ -194,7 +190,7 @@ describe("evaluateCheck with multiple dice", () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it("should assign the checkTargetNumber for the last sub check to the first coup if there are only coups.", () => {
|
||||
it('should assign the checkTargetNumber for the last sub check to the first coup if there are only coups.', () => {
|
||||
expect(evaluateCheck([1, 1, 1], 48)).toEqual([
|
||||
{ result: 1, checkTargetNumber: 8, active: true, discarded: false, success: true, count: 8 },
|
||||
{ result: 1, checkTargetNumber: 20, active: true, discarded: false, success: true, count: 20 },
|
||||
|
@ -202,7 +198,7 @@ describe("evaluateCheck with multiple dice", () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it("should assign the checkTargetNumber for the last sub check to the first lowest die, even if it is higher than that value.", () => {
|
||||
it('should assign the checkTargetNumber for the last sub check to the first lowest die, even if it is higher than that value.', () => {
|
||||
expect(evaluateCheck([15, 15, 15], 48)).toEqual([
|
||||
{ result: 15, checkTargetNumber: 8, active: false, discarded: true },
|
||||
{ result: 15, checkTargetNumber: 20, active: true, discarded: false },
|
||||
|
@ -210,7 +206,7 @@ describe("evaluateCheck with multiple dice", () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it("should assign the checkTargetNumber for the last sub check to the first coup if its sum with the lowest non coup is high enough.", () => {
|
||||
it('should assign the checkTargetNumber for the last sub check to the first coup if its sum with the lowest non coup is high enough.', () => {
|
||||
expect(evaluateCheck([15, 15, 1], 48)).toEqual([
|
||||
{ result: 15, checkTargetNumber: 20, active: true, discarded: false },
|
||||
{ result: 15, checkTargetNumber: 20, active: true, discarded: false },
|
||||
|
@ -226,7 +222,7 @@ describe("evaluateCheck with multiple dice", () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it("should assign the checkTargetNumber for the last sub check to properly maximize the result when all dice are successes.", () => {
|
||||
it('should assign the checkTargetNumber for the last sub check to properly maximize the result when all dice are successes.', () => {
|
||||
expect(evaluateCheck([15, 4, 12], 46)).toEqual([
|
||||
{ result: 15, checkTargetNumber: 20, active: true, discarded: false },
|
||||
{ result: 4, checkTargetNumber: 6, active: true, discarded: false },
|
||||
|
@ -234,7 +230,7 @@ describe("evaluateCheck with multiple dice", () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it("should assign the checkTargetNumber for the last sub check to properly maximize the result when one dice is a failure.", () => {
|
||||
it('should assign the checkTargetNumber for the last sub check to properly maximize the result when one dice is a failure.', () => {
|
||||
expect(evaluateCheck([15, 8, 12], 46)).toEqual([
|
||||
{ result: 15, checkTargetNumber: 20, active: true, discarded: false },
|
||||
{ result: 8, checkTargetNumber: 6, active: false, discarded: true },
|
||||
|
@ -264,7 +260,7 @@ describe("evaluateCheck with multiple dice", () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it("should assign the checkTargetNumber for the last sub check to properly maximize the result when there is more than one coup and a coup is used for the last sub CTN", () => {
|
||||
it('should assign the checkTargetNumber for the last sub check to properly maximize the result when there is more than one coup and a coup is used for the last sub CTN', () => {
|
||||
expect(evaluateCheck([1, 1, 15], 48)).toEqual([
|
||||
{ result: 1, checkTargetNumber: 8, active: true, discarded: false, success: true, count: 8 },
|
||||
{ result: 1, checkTargetNumber: 20, active: true, discarded: false, success: true, count: 20 },
|
||||
|
@ -273,7 +269,7 @@ describe("evaluateCheck with multiple dice", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("evaluateCheck with multiple dice and coup / fumble modification", () => {
|
||||
describe('evaluateCheck with multiple dice and coup / fumble modification', () => {
|
||||
it("should assign the checkTargetNumber for the last sub check to the lowest non coup and fumble if the first is '19'.", () => {
|
||||
expect(evaluateCheck([19, 15, 6], 48, { maximumCoupResult: 2, minimumFumbleResult: 19 })).toEqual([
|
||||
{ result: 19, checkTargetNumber: 20, active: true, discarded: false, failure: true },
|
||||
|
@ -290,7 +286,7 @@ describe("evaluateCheck with multiple dice and coup / fumble modification", () =
|
|||
]);
|
||||
});
|
||||
|
||||
it("should assign the checkTargetNumber for the last sub check to the first lowest die, even if it is higher than that value.", () => {
|
||||
it('should assign the checkTargetNumber for the last sub check to the first lowest die, even if it is higher than that value.', () => {
|
||||
expect(evaluateCheck([15, 15, 15], 48, { maximumCoupResult: 2, minimumFumbleResult: 19 })).toEqual([
|
||||
{ result: 15, checkTargetNumber: 8, active: false, discarded: true },
|
||||
{ result: 15, checkTargetNumber: 20, active: true, discarded: false },
|
||||
|
@ -322,7 +318,7 @@ describe("evaluateCheck with multiple dice and coup / fumble modification", () =
|
|||
]);
|
||||
});
|
||||
|
||||
it("should assign the checkTargetNumber for the last sub check to properly maximize the result when all dice are successes.", () => {
|
||||
it('should assign the checkTargetNumber for the last sub check to properly maximize the result when all dice are successes.', () => {
|
||||
expect(evaluateCheck([15, 4, 12], 46, { maximumCoupResult: 2, minimumFumbleResult: 19 })).toEqual([
|
||||
{ result: 15, checkTargetNumber: 20, active: true, discarded: false },
|
||||
{ result: 4, checkTargetNumber: 6, active: true, discarded: false },
|
||||
|
@ -330,7 +326,7 @@ describe("evaluateCheck with multiple dice and coup / fumble modification", () =
|
|||
]);
|
||||
});
|
||||
|
||||
it("should assign the checkTargetNumber for the last sub check to properly maximize the result when one dice is a failure.", () => {
|
||||
it('should assign the checkTargetNumber for the last sub check to properly maximize the result when one dice is a failure.', () => {
|
||||
expect(evaluateCheck([15, 8, 12], 46, { maximumCoupResult: 2, minimumFumbleResult: 19 })).toEqual([
|
||||
{ result: 15, checkTargetNumber: 20, active: true, discarded: false },
|
||||
{ result: 8, checkTargetNumber: 6, active: false, discarded: true },
|
||||
|
@ -368,7 +364,7 @@ describe("evaluateCheck with multiple dice and coup / fumble modification", () =
|
|||
]);
|
||||
});
|
||||
|
||||
it("should use all the dice if they are coups, even if they are higher than the checkTargetNumber", () => {
|
||||
it('should use all the dice if they are coups, even if they are higher than the checkTargetNumber', () => {
|
||||
expect(evaluateCheck([18, 19, 17], 48, { maximumCoupResult: 19 })).toEqual([
|
||||
{ result: 18, checkTargetNumber: 8, active: true, discarded: false, success: true, count: 8 },
|
||||
{ result: 19, checkTargetNumber: 20, active: true, discarded: false, success: true, count: 20 },
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { calculateSpellPrice } from "../../../../src/documents/item/spell/calculate-spell-price";
|
||||
import { calculateSpellPrice } from '../../../../src/documents/item/spell/calculate-spell-price';
|
||||
|
||||
import type { CooldownDuration, DS4SpellDataSourceData } from "../../../../src/documents/item/spell/spell-data-source";
|
||||
import type { CooldownDuration, DS4SpellDataSourceData } from '../../../../src/documents/item/spell/spell-data-source';
|
||||
|
||||
const defaultData: DS4SpellDataSourceData = {
|
||||
description: "",
|
||||
description: '',
|
||||
equipped: false,
|
||||
spellType: "spellcasting",
|
||||
spellType: 'spellcasting',
|
||||
spellModifier: {
|
||||
numerical: 0,
|
||||
complex: "",
|
||||
complex: '',
|
||||
},
|
||||
allowsDefense: false,
|
||||
spellGroups: {
|
||||
|
@ -37,18 +37,18 @@ const defaultData: DS4SpellDataSourceData = {
|
|||
area: false,
|
||||
},
|
||||
maxDistance: {
|
||||
value: "",
|
||||
unit: "meter",
|
||||
value: '',
|
||||
unit: 'meter',
|
||||
},
|
||||
effectRadius: {
|
||||
value: "",
|
||||
unit: "meter",
|
||||
value: '',
|
||||
unit: 'meter',
|
||||
},
|
||||
duration: {
|
||||
value: "",
|
||||
unit: "custom",
|
||||
value: '',
|
||||
unit: 'custom',
|
||||
},
|
||||
cooldownDuration: "0r",
|
||||
cooldownDuration: '0r',
|
||||
minimumLevels: {
|
||||
healer: null,
|
||||
wizard: null,
|
||||
|
@ -62,12 +62,12 @@ type TestCase = {
|
|||
};
|
||||
|
||||
type CombinedTestCase = {
|
||||
minimumLevels: DS4SpellDataSourceData["minimumLevels"];
|
||||
minimumLevels: DS4SpellDataSourceData['minimumLevels'];
|
||||
expected: number | null;
|
||||
description: string;
|
||||
};
|
||||
|
||||
const testCases: Record<keyof DS4SpellDataSourceData["minimumLevels"], TestCase[]> = {
|
||||
const testCases: Record<keyof DS4SpellDataSourceData['minimumLevels'], TestCase[]> = {
|
||||
healer: [
|
||||
{ minimumLevel: null, expected: null },
|
||||
{ minimumLevel: 1, expected: 10 },
|
||||
|
@ -150,9 +150,7 @@ function buildCombinedTestCases(): CombinedTestCase[] {
|
|||
for (const sorcererTestCase of testCases.sorcerer.filter(isRelevantPermutationTestCase)) {
|
||||
for (const wizardTestCase of testCases.wizard.filter(isRelevantPermutationTestCase)) {
|
||||
const expected =
|
||||
healerTestCase.expected !== null ||
|
||||
sorcererTestCase.expected !== null ||
|
||||
wizardTestCase.expected !== null
|
||||
healerTestCase.expected !== null || sorcererTestCase.expected !== null || wizardTestCase.expected !== null
|
||||
? Math.min(
|
||||
healerTestCase.expected ?? Infinity,
|
||||
sorcererTestCase.expected ?? Infinity,
|
||||
|
@ -177,7 +175,7 @@ function buildCombinedTestCases(): CombinedTestCase[] {
|
|||
// single test cases
|
||||
const isRelevantSingleTestCase = (t: TestCase) => t.minimumLevel !== null;
|
||||
|
||||
for (const spellCasterClass of ["healer", "sorcerer", "wizard"] as const) {
|
||||
for (const spellCasterClass of ['healer', 'sorcerer', 'wizard'] as const) {
|
||||
for (const testCase of testCases[spellCasterClass].filter(isRelevantSingleTestCase)) {
|
||||
const minimumLevels = {
|
||||
...defaultData.minimumLevels,
|
||||
|
@ -195,20 +193,20 @@ function buildCombinedTestCases(): CombinedTestCase[] {
|
|||
return combinedTestCases;
|
||||
}
|
||||
|
||||
describe("calculateSpellPrice", () => {
|
||||
describe('calculateSpellPrice', () => {
|
||||
const cooldownDurations: { cooldownDuration: CooldownDuration; factor: number }[] = [
|
||||
{ cooldownDuration: "0r", factor: 1 },
|
||||
{ cooldownDuration: "1r", factor: 1 },
|
||||
{ cooldownDuration: "2r", factor: 1 },
|
||||
{ cooldownDuration: "5r", factor: 1 },
|
||||
{ cooldownDuration: "10r", factor: 1 },
|
||||
{ cooldownDuration: "100r", factor: 1 },
|
||||
{ cooldownDuration: "1d", factor: 2 },
|
||||
{ cooldownDuration: "d20d", factor: 3 },
|
||||
{ cooldownDuration: '0r', factor: 1 },
|
||||
{ cooldownDuration: '1r', factor: 1 },
|
||||
{ cooldownDuration: '2r', factor: 1 },
|
||||
{ cooldownDuration: '5r', factor: 1 },
|
||||
{ cooldownDuration: '10r', factor: 1 },
|
||||
{ cooldownDuration: '100r', factor: 1 },
|
||||
{ cooldownDuration: '1d', factor: 2 },
|
||||
{ cooldownDuration: 'd20d', factor: 3 },
|
||||
];
|
||||
|
||||
describe.each(cooldownDurations)(
|
||||
"with cooldown duration set to $cooldownDuration",
|
||||
'with cooldown duration set to $cooldownDuration',
|
||||
({ cooldownDuration, factor }) => {
|
||||
const dataWithCooldownDuration = {
|
||||
...defaultData,
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { defaultEvaluator, Evaluator, mathEvaluator } from "../../src/expression-evaluation/evaluator";
|
||||
import { defaultEvaluator, Evaluator, mathEvaluator } from '../../src/expression-evaluation/evaluator';
|
||||
|
||||
describe("Evaluator", () => {
|
||||
it("evaluates expressions that only use identifiers according to the given predicate", () => {
|
||||
describe('Evaluator', () => {
|
||||
it('evaluates expressions that only use identifiers according to the given predicate', () => {
|
||||
// given
|
||||
const expression = "typeof 'foo' === 'string' ? 42 : null";
|
||||
|
||||
|
@ -18,7 +18,7 @@ describe("Evaluator", () => {
|
|||
expect(result).toEqual(42);
|
||||
});
|
||||
|
||||
it("fails to evaluate expressions that contain identifiers that are not allowed by the predicate", () => {
|
||||
it('fails to evaluate expressions that contain identifiers that are not allowed by the predicate', () => {
|
||||
// given
|
||||
const expression = "typeof 'foo' === 'string' ? 42 : function (){}";
|
||||
|
||||
|
@ -29,33 +29,33 @@ describe("Evaluator", () => {
|
|||
expect(evaluate).toThrowError("'function' is not an allowed identifier.");
|
||||
});
|
||||
|
||||
it("fails to evaluate expressions that contain invalid tokens", () => {
|
||||
it('fails to evaluate expressions that contain invalid tokens', () => {
|
||||
// given
|
||||
const expression = "1;";
|
||||
const expression = '1;';
|
||||
|
||||
// when
|
||||
const evaluate = () => defaultEvaluator.evaluate(expression);
|
||||
|
||||
// then
|
||||
expect(evaluate).toThrowError("Invalid or unexpected token (1)");
|
||||
expect(evaluate).toThrowError('Invalid or unexpected token (1)');
|
||||
});
|
||||
|
||||
it("fails to evaluate expressions that contain arrow functions", () => {
|
||||
it('fails to evaluate expressions that contain arrow functions', () => {
|
||||
// given
|
||||
const expression = "(() => 1)()";
|
||||
const expression = '(() => 1)()';
|
||||
|
||||
// when
|
||||
const evaluate = () => defaultEvaluator.evaluate(expression);
|
||||
|
||||
// then
|
||||
expect(evaluate).toThrowError("Invalid or unexpected token (4)");
|
||||
expect(evaluate).toThrowError('Invalid or unexpected token (4)');
|
||||
});
|
||||
|
||||
it("makes the given context available", () => {
|
||||
it('makes the given context available', () => {
|
||||
// given
|
||||
const context = { floor: Math.floor };
|
||||
const evaluator = new Evaluator({ context });
|
||||
const expression = "floor(0.5)";
|
||||
const expression = 'floor(0.5)';
|
||||
|
||||
// when
|
||||
const result = evaluator.evaluate(expression);
|
||||
|
@ -64,10 +64,10 @@ describe("Evaluator", () => {
|
|||
expect(result).toEqual(0);
|
||||
});
|
||||
|
||||
describe("mathEvaluator", () => {
|
||||
it("makes the given context available", () => {
|
||||
describe('mathEvaluator', () => {
|
||||
it('makes the given context available', () => {
|
||||
// given
|
||||
const expression = "sqrt(sin(PI))";
|
||||
const expression = 'sqrt(sin(PI))';
|
||||
|
||||
// when
|
||||
const result = mathEvaluator.evaluate(expression);
|
||||
|
@ -76,9 +76,9 @@ describe("Evaluator", () => {
|
|||
expect(result).toEqual(Math.sqrt(Math.sin(Math.PI)));
|
||||
});
|
||||
|
||||
it("does not give acces to the function constructor", () => {
|
||||
it('does not give acces to the function constructor', () => {
|
||||
// given
|
||||
const expression = "sqrt.constructor";
|
||||
const expression = 'sqrt.constructor';
|
||||
|
||||
// when
|
||||
const evaluate = () => mathEvaluator.evaluate(expression);
|
||||
|
|
|
@ -2,574 +2,574 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { Lexer } from "../../src/expression-evaluation/lexer";
|
||||
import { Lexer } from '../../src/expression-evaluation/lexer';
|
||||
|
||||
import type { Token } from "../../src/expression-evaluation/grammar";
|
||||
import type { Token } from '../../src/expression-evaluation/grammar';
|
||||
|
||||
describe("Lexer", () => {
|
||||
describe('Lexer', () => {
|
||||
const singleOperatorTestCases: { input: string; expected: Token[] }[] = [
|
||||
{
|
||||
input: "+",
|
||||
input: '+',
|
||||
expected: [
|
||||
{ type: "+", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: '+', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "-",
|
||||
input: '-',
|
||||
expected: [
|
||||
{ type: "-", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: '-', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "*",
|
||||
input: '*',
|
||||
expected: [
|
||||
{ type: "*", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: '*', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "**",
|
||||
input: '**',
|
||||
expected: [
|
||||
{ type: "**", pos: 0 },
|
||||
{ type: "eof", pos: 2 },
|
||||
{ type: '**', pos: 0 },
|
||||
{ type: 'eof', pos: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "/",
|
||||
input: '/',
|
||||
expected: [
|
||||
{ type: "/", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: '/', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "%",
|
||||
input: '%',
|
||||
expected: [
|
||||
{ type: "%", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: '%', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "===",
|
||||
input: '===',
|
||||
expected: [
|
||||
{ type: "===", pos: 0 },
|
||||
{ type: "eof", pos: 3 },
|
||||
{ type: '===', pos: 0 },
|
||||
{ type: 'eof', pos: 3 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "!==",
|
||||
input: '!==',
|
||||
expected: [
|
||||
{ type: "!==", pos: 0 },
|
||||
{ type: "eof", pos: 3 },
|
||||
{ type: '!==', pos: 0 },
|
||||
{ type: 'eof', pos: 3 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "==",
|
||||
input: '==',
|
||||
expected: [
|
||||
{ type: "==", pos: 0 },
|
||||
{ type: "eof", pos: 2 },
|
||||
{ type: '==', pos: 0 },
|
||||
{ type: 'eof', pos: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "<",
|
||||
input: '<',
|
||||
expected: [
|
||||
{ type: "<", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: '<', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "<=",
|
||||
input: '<=',
|
||||
expected: [
|
||||
{ type: "<=", pos: 0 },
|
||||
{ type: "eof", pos: 2 },
|
||||
{ type: '<=', pos: 0 },
|
||||
{ type: 'eof', pos: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: ">",
|
||||
input: '>',
|
||||
expected: [
|
||||
{ type: ">", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: '>', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: ">=",
|
||||
input: '>=',
|
||||
expected: [
|
||||
{ type: ">=", pos: 0 },
|
||||
{ type: "eof", pos: 2 },
|
||||
{ type: '>=', pos: 0 },
|
||||
{ type: 'eof', pos: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "&&",
|
||||
input: '&&',
|
||||
expected: [
|
||||
{ type: "&&", pos: 0 },
|
||||
{ type: "eof", pos: 2 },
|
||||
{ type: '&&', pos: 0 },
|
||||
{ type: 'eof', pos: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "||",
|
||||
input: '||',
|
||||
expected: [
|
||||
{ type: "||", pos: 0 },
|
||||
{ type: "eof", pos: 2 },
|
||||
{ type: '||', pos: 0 },
|
||||
{ type: 'eof', pos: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "&",
|
||||
input: '&',
|
||||
expected: [
|
||||
{ type: "&", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: '&', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "|",
|
||||
input: '|',
|
||||
expected: [
|
||||
{ type: "|", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: '|', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "<<",
|
||||
input: '<<',
|
||||
expected: [
|
||||
{ type: "<<", pos: 0 },
|
||||
{ type: "eof", pos: 2 },
|
||||
{ type: '<<', pos: 0 },
|
||||
{ type: 'eof', pos: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: ">>>",
|
||||
input: '>>>',
|
||||
expected: [
|
||||
{ type: ">>>", pos: 0 },
|
||||
{ type: "eof", pos: 3 },
|
||||
{ type: '>>>', pos: 0 },
|
||||
{ type: 'eof', pos: 3 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: ".",
|
||||
input: '.',
|
||||
expected: [
|
||||
{ type: ".", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: '.', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "?.",
|
||||
input: '?.',
|
||||
expected: [
|
||||
{ type: "?.", pos: 0 },
|
||||
{ type: "eof", pos: 2 },
|
||||
{ type: '?.', pos: 0 },
|
||||
{ type: 'eof', pos: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "??",
|
||||
input: '??',
|
||||
expected: [
|
||||
{ type: "??", pos: 0 },
|
||||
{ type: "eof", pos: 2 },
|
||||
{ type: '??', pos: 0 },
|
||||
{ type: 'eof', pos: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "?",
|
||||
input: '?',
|
||||
expected: [
|
||||
{ type: "?", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: '?', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: ":",
|
||||
input: ':',
|
||||
expected: [
|
||||
{ type: ":", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: ':', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "(",
|
||||
input: '(',
|
||||
expected: [
|
||||
{ type: "(", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: '(', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: ")",
|
||||
input: ')',
|
||||
expected: [
|
||||
{ type: ")", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: ')', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "[",
|
||||
input: '[',
|
||||
expected: [
|
||||
{ type: "[", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: '[', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "]",
|
||||
input: ']',
|
||||
expected: [
|
||||
{ type: "]", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: ']', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: ",",
|
||||
input: ',',
|
||||
expected: [
|
||||
{ type: ",", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: ',', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "{",
|
||||
input: '{',
|
||||
expected: [
|
||||
{ type: "{", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: '{', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "}",
|
||||
input: '}',
|
||||
expected: [
|
||||
{ type: "}", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: '}', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const singleNumberTestCases: { input: string; expected: Token[] }[] = [
|
||||
{
|
||||
input: "1",
|
||||
input: '1',
|
||||
expected: [
|
||||
{ type: "number", symbol: "1", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: 'number', symbol: '1', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "42",
|
||||
input: '42',
|
||||
expected: [
|
||||
{ type: "number", symbol: "42", pos: 0 },
|
||||
{ type: "eof", pos: 2 },
|
||||
{ type: 'number', symbol: '42', pos: 0 },
|
||||
{ type: 'eof', pos: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "42.9",
|
||||
input: '42.9',
|
||||
expected: [
|
||||
{ type: "number", symbol: "42.9", pos: 0 },
|
||||
{ type: "eof", pos: 4 },
|
||||
{ type: 'number', symbol: '42.9', pos: 0 },
|
||||
{ type: 'eof', pos: 4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: ".9",
|
||||
input: '.9',
|
||||
expected: [
|
||||
{ type: "number", symbol: ".9", pos: 0 },
|
||||
{ type: "eof", pos: 2 },
|
||||
{ type: 'number', symbol: '.9', pos: 0 },
|
||||
{ type: 'eof', pos: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "1_1",
|
||||
input: '1_1',
|
||||
expected: [
|
||||
{ type: "number", symbol: "1_1", pos: 0 },
|
||||
{ type: "eof", pos: 3 },
|
||||
{ type: 'number', symbol: '1_1', pos: 0 },
|
||||
{ type: 'eof', pos: 3 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "10_1",
|
||||
input: '10_1',
|
||||
expected: [
|
||||
{ type: "number", symbol: "10_1", pos: 0 },
|
||||
{ type: "eof", pos: 4 },
|
||||
{ type: 'number', symbol: '10_1', pos: 0 },
|
||||
{ type: 'eof', pos: 4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "1_1_1",
|
||||
input: '1_1_1',
|
||||
expected: [
|
||||
{ type: "number", symbol: "1_1_1", pos: 0 },
|
||||
{ type: "eof", pos: 5 },
|
||||
{ type: 'number', symbol: '1_1_1', pos: 0 },
|
||||
{ type: 'eof', pos: 5 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: ".1_1",
|
||||
input: '.1_1',
|
||||
expected: [
|
||||
{ type: "number", symbol: ".1_1", pos: 0 },
|
||||
{ type: "eof", pos: 4 },
|
||||
{ type: 'number', symbol: '.1_1', pos: 0 },
|
||||
{ type: 'eof', pos: 4 },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const invalidNumberTestCases: { input: string; expected: Token[] }[] = [
|
||||
{ input: "1.1.1", expected: [{ type: "invalid", pos: 0 }] },
|
||||
{ input: "1__1", expected: [{ type: "invalid", pos: 0 }] },
|
||||
{ input: "1_", expected: [{ type: "invalid", pos: 0 }] },
|
||||
{ input: "1._1", expected: [{ type: "invalid", pos: 0 }] },
|
||||
{ input: "0_1", expected: [{ type: "invalid", pos: 0 }] },
|
||||
{ input: "00_1", expected: [{ type: "invalid", pos: 0 }] },
|
||||
{ input: '1.1.1', expected: [{ type: 'invalid', pos: 0 }] },
|
||||
{ input: '1__1', expected: [{ type: 'invalid', pos: 0 }] },
|
||||
{ input: '1_', expected: [{ type: 'invalid', pos: 0 }] },
|
||||
{ input: '1._1', expected: [{ type: 'invalid', pos: 0 }] },
|
||||
{ input: '0_1', expected: [{ type: 'invalid', pos: 0 }] },
|
||||
{ input: '00_1', expected: [{ type: 'invalid', pos: 0 }] },
|
||||
];
|
||||
|
||||
const singleIdentifierTestCases: { input: string; expected: Token[] }[] = [
|
||||
{
|
||||
input: "foo",
|
||||
input: 'foo',
|
||||
expected: [
|
||||
{ type: "iden", symbol: "foo", pos: 0 },
|
||||
{ type: "eof", pos: 3 },
|
||||
{ type: 'iden', symbol: 'foo', pos: 0 },
|
||||
{ type: 'eof', pos: 3 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "_foo",
|
||||
input: '_foo',
|
||||
expected: [
|
||||
{ type: "iden", symbol: "_foo", pos: 0 },
|
||||
{ type: "eof", pos: 4 },
|
||||
{ type: 'iden', symbol: '_foo', pos: 0 },
|
||||
{ type: 'eof', pos: 4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "$foo",
|
||||
input: '$foo',
|
||||
expected: [
|
||||
{ type: "iden", symbol: "$foo", pos: 0 },
|
||||
{ type: "eof", pos: 4 },
|
||||
{ type: 'iden', symbol: '$foo', pos: 0 },
|
||||
{ type: 'eof', pos: 4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "foo1",
|
||||
input: 'foo1',
|
||||
expected: [
|
||||
{ type: "iden", symbol: "foo1", pos: 0 },
|
||||
{ type: "eof", pos: 4 },
|
||||
{ type: 'iden', symbol: 'foo1', pos: 0 },
|
||||
{ type: 'eof', pos: 4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "_foo1_",
|
||||
input: '_foo1_',
|
||||
expected: [
|
||||
{ type: "iden", symbol: "_foo1_", pos: 0 },
|
||||
{ type: "eof", pos: 6 },
|
||||
{ type: 'iden', symbol: '_foo1_', pos: 0 },
|
||||
{ type: 'eof', pos: 6 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "μ",
|
||||
input: 'μ',
|
||||
expected: [
|
||||
{ type: "iden", symbol: "μ", pos: 0 },
|
||||
{ type: "eof", pos: 1 },
|
||||
{ type: 'iden', symbol: 'μ', pos: 0 },
|
||||
{ type: 'eof', pos: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "._1",
|
||||
input: '._1',
|
||||
expected: [
|
||||
{ type: ".", pos: 0 },
|
||||
{ type: "iden", symbol: "_1", pos: 1 },
|
||||
{ type: "eof", pos: 3 },
|
||||
{ type: '.', pos: 0 },
|
||||
{ type: 'iden', symbol: '_1', pos: 1 },
|
||||
{ type: 'eof', pos: 3 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "true",
|
||||
input: 'true',
|
||||
expected: [
|
||||
{ type: "iden", symbol: "true", pos: 0 },
|
||||
{ type: "eof", pos: 4 },
|
||||
{ type: 'iden', symbol: 'true', pos: 0 },
|
||||
{ type: 'eof', pos: 4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "false",
|
||||
input: 'false',
|
||||
expected: [
|
||||
{ type: "iden", symbol: "false", pos: 0 },
|
||||
{ type: "eof", pos: 5 },
|
||||
{ type: 'iden', symbol: 'false', pos: 0 },
|
||||
{ type: 'eof', pos: 5 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "null",
|
||||
input: 'null',
|
||||
expected: [
|
||||
{ type: "iden", symbol: "null", pos: 0 },
|
||||
{ type: "eof", pos: 4 },
|
||||
{ type: 'iden', symbol: 'null', pos: 0 },
|
||||
{ type: 'eof', pos: 4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "undefined",
|
||||
input: 'undefined',
|
||||
expected: [
|
||||
{ type: "iden", symbol: "undefined", pos: 0 },
|
||||
{ type: "eof", pos: 9 },
|
||||
{ type: 'iden', symbol: 'undefined', pos: 0 },
|
||||
{ type: 'eof', pos: 9 },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const invalidIdentifierTestCases: { input: string; expected: Token[] }[] = [
|
||||
{
|
||||
input: "1foo",
|
||||
input: '1foo',
|
||||
expected: [
|
||||
{ type: "number", symbol: "1", pos: 0 },
|
||||
{ type: "iden", symbol: "foo", pos: 1 },
|
||||
{ type: "eof", pos: 4 },
|
||||
{ type: 'number', symbol: '1', pos: 0 },
|
||||
{ type: 'iden', symbol: 'foo', pos: 1 },
|
||||
{ type: 'eof', pos: 4 },
|
||||
],
|
||||
},
|
||||
{ input: "↓", expected: [{ type: "invalid", pos: 0 }] },
|
||||
{ input: '"', expected: [{ type: "invalid", pos: 0 }] },
|
||||
{ input: '↓', expected: [{ type: 'invalid', pos: 0 }] },
|
||||
{ input: '"', expected: [{ type: 'invalid', pos: 0 }] },
|
||||
];
|
||||
|
||||
const singleStringTestCases: { input: string; expected: Token[] }[] = [
|
||||
{
|
||||
input: '""',
|
||||
expected: [
|
||||
{ type: "string", symbol: '""', pos: 0 },
|
||||
{ type: "eof", pos: 2 },
|
||||
{ type: 'string', symbol: '""', pos: 0 },
|
||||
{ type: 'eof', pos: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: '"foo"',
|
||||
expected: [
|
||||
{ type: "string", symbol: '"foo"', pos: 0 },
|
||||
{ type: "eof", pos: 5 },
|
||||
{ type: 'string', symbol: '"foo"', pos: 0 },
|
||||
{ type: 'eof', pos: 5 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: '"\\""',
|
||||
expected: [
|
||||
{ type: "string", symbol: '"\\""', pos: 0 },
|
||||
{ type: "eof", pos: 4 },
|
||||
{ type: 'string', symbol: '"\\""', pos: 0 },
|
||||
{ type: 'eof', pos: 4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: '"\\\'"',
|
||||
expected: [
|
||||
{ type: "string", symbol: '"\\\'"', pos: 0 },
|
||||
{ type: "eof", pos: 4 },
|
||||
{ type: 'string', symbol: '"\\\'"', pos: 0 },
|
||||
{ type: 'eof', pos: 4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "''",
|
||||
expected: [
|
||||
{ type: "string", symbol: "''", pos: 0 },
|
||||
{ type: "eof", pos: 2 },
|
||||
{ type: 'string', symbol: "''", pos: 0 },
|
||||
{ type: 'eof', pos: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "'foo'",
|
||||
expected: [
|
||||
{ type: "string", symbol: "'foo'", pos: 0 },
|
||||
{ type: "eof", pos: 5 },
|
||||
{ type: 'string', symbol: "'foo'", pos: 0 },
|
||||
{ type: 'eof', pos: 5 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "'\\''",
|
||||
expected: [
|
||||
{ type: "string", symbol: "'\\''", pos: 0 },
|
||||
{ type: "eof", pos: 4 },
|
||||
{ type: 'string', symbol: "'\\''", pos: 0 },
|
||||
{ type: 'eof', pos: 4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "'\\\"'",
|
||||
expected: [
|
||||
{ type: "string", symbol: "'\\\"'", pos: 0 },
|
||||
{ type: "eof", pos: 4 },
|
||||
{ type: 'string', symbol: "'\\\"'", pos: 0 },
|
||||
{ type: 'eof', pos: 4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "``",
|
||||
input: '``',
|
||||
expected: [
|
||||
{ type: "string", symbol: "``", pos: 0 },
|
||||
{ type: "eof", pos: 2 },
|
||||
{ type: 'string', symbol: '``', pos: 0 },
|
||||
{ type: 'eof', pos: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "`foo`",
|
||||
input: '`foo`',
|
||||
expected: [
|
||||
{ type: "string", symbol: "`foo`", pos: 0 },
|
||||
{ type: "eof", pos: 5 },
|
||||
{ type: 'string', symbol: '`foo`', pos: 0 },
|
||||
{ type: 'eof', pos: 5 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "`\\``",
|
||||
input: '`\\``',
|
||||
expected: [
|
||||
{ type: "string", symbol: "`\\``", pos: 0 },
|
||||
{ type: "eof", pos: 4 },
|
||||
{ type: 'string', symbol: '`\\``', pos: 0 },
|
||||
{ type: 'eof', pos: 4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: '`\\"`',
|
||||
expected: [
|
||||
{ type: "string", symbol: '`\\"`', pos: 0 },
|
||||
{ type: "eof", pos: 4 },
|
||||
{ type: 'string', symbol: '`\\"`', pos: 0 },
|
||||
{ type: 'eof', pos: 4 },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const invalidStringTestCases: { input: string; expected: Token[] }[] = [
|
||||
{ input: '"', expected: [{ type: "invalid", pos: 0 }] },
|
||||
{ input: '"\\"', expected: [{ type: "invalid", pos: 0 }] },
|
||||
{ input: "'", expected: [{ type: "invalid", pos: 0 }] },
|
||||
{ input: "'\\'", expected: [{ type: "invalid", pos: 0 }] },
|
||||
{ input: '"', expected: [{ type: 'invalid', pos: 0 }] },
|
||||
{ input: '"\\"', expected: [{ type: 'invalid', pos: 0 }] },
|
||||
{ input: "'", expected: [{ type: 'invalid', pos: 0 }] },
|
||||
{ input: "'\\'", expected: [{ type: 'invalid', pos: 0 }] },
|
||||
];
|
||||
|
||||
const whiteSpaceTestCases: { input: string; expected: Token[] }[] = [
|
||||
{ input: " ", expected: [{ type: "eof", pos: 1 }] },
|
||||
{ input: " ", expected: [{ type: "eof", pos: 3 }] },
|
||||
{ input: "\n", expected: [{ type: "eof", pos: 1 }] },
|
||||
{ input: " \n", expected: [{ type: "eof", pos: 2 }] },
|
||||
{ input: " ", expected: [{ type: "eof", pos: 1 }] },
|
||||
{ input: ' ', expected: [{ type: 'eof', pos: 1 }] },
|
||||
{ input: ' ', expected: [{ type: 'eof', pos: 3 }] },
|
||||
{ input: '\n', expected: [{ type: 'eof', pos: 1 }] },
|
||||
{ input: ' \n', expected: [{ type: 'eof', pos: 2 }] },
|
||||
{ input: ' ', expected: [{ type: 'eof', pos: 1 }] },
|
||||
];
|
||||
|
||||
const complicatedTermTestCases: { input: string; expected: Token[] }[] = [
|
||||
{
|
||||
input: "5x",
|
||||
input: '5x',
|
||||
expected: [
|
||||
{ type: "number", symbol: "5", pos: 0 },
|
||||
{ type: "iden", symbol: "x", pos: 1 },
|
||||
{ type: "eof", pos: 2 },
|
||||
{ type: 'number', symbol: '5', pos: 0 },
|
||||
{ type: 'iden', symbol: 'x', pos: 1 },
|
||||
{ type: 'eof', pos: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "5*x",
|
||||
input: '5*x',
|
||||
expected: [
|
||||
{ type: "number", symbol: "5", pos: 0 },
|
||||
{ type: "*", pos: 1 },
|
||||
{ type: "iden", symbol: "x", pos: 2 },
|
||||
{ type: "eof", pos: 3 },
|
||||
{ type: 'number', symbol: '5', pos: 0 },
|
||||
{ type: '*', pos: 1 },
|
||||
{ type: 'iden', symbol: 'x', pos: 2 },
|
||||
{ type: 'eof', pos: 3 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "5 * x",
|
||||
input: '5 * x',
|
||||
expected: [
|
||||
{ type: "number", symbol: "5", pos: 0 },
|
||||
{ type: "*", pos: 2 },
|
||||
{ type: "iden", symbol: "x", pos: 4 },
|
||||
{ type: "eof", pos: 5 },
|
||||
{ type: 'number', symbol: '5', pos: 0 },
|
||||
{ type: '*', pos: 2 },
|
||||
{ type: 'iden', symbol: 'x', pos: 4 },
|
||||
{ type: 'eof', pos: 5 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "(5 * 5 + 2) / 1.2 === 'foo'",
|
||||
expected: [
|
||||
{ type: "(", pos: 0 },
|
||||
{ type: "number", symbol: "5", pos: 1 },
|
||||
{ type: "*", pos: 3 },
|
||||
{ type: "number", symbol: "5", pos: 5 },
|
||||
{ type: "+", pos: 7 },
|
||||
{ type: "number", symbol: "2", pos: 9 },
|
||||
{ type: ")", pos: 10 },
|
||||
{ type: "/", pos: 12 },
|
||||
{ type: "number", symbol: "1.2", pos: 14 },
|
||||
{ type: "===", pos: 18 },
|
||||
{ type: "string", symbol: "'foo'", pos: 22 },
|
||||
{ type: "eof", pos: 27 },
|
||||
{ type: '(', pos: 0 },
|
||||
{ type: 'number', symbol: '5', pos: 1 },
|
||||
{ type: '*', pos: 3 },
|
||||
{ type: 'number', symbol: '5', pos: 5 },
|
||||
{ type: '+', pos: 7 },
|
||||
{ type: 'number', symbol: '2', pos: 9 },
|
||||
{ type: ')', pos: 10 },
|
||||
{ type: '/', pos: 12 },
|
||||
{ type: 'number', symbol: '1.2', pos: 14 },
|
||||
{ type: '===', pos: 18 },
|
||||
{ type: 'string', symbol: "'foo'", pos: 22 },
|
||||
{ type: 'eof', pos: 27 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "(() => {console.log('foo'); return 1;})()",
|
||||
expected: [
|
||||
{ type: "(", pos: 0 },
|
||||
{ type: "(", pos: 1 },
|
||||
{ type: ")", pos: 2 },
|
||||
{ type: "invalid", pos: 4 },
|
||||
{ type: '(', pos: 0 },
|
||||
{ type: '(', pos: 1 },
|
||||
{ type: ')', pos: 2 },
|
||||
{ type: 'invalid', pos: 4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "(function() {console.log('foo'); return 1;})()",
|
||||
expected: [
|
||||
{ type: "(", pos: 0 },
|
||||
{ type: "iden", symbol: "function", pos: 1 },
|
||||
{ type: "(", pos: 9 },
|
||||
{ type: ")", pos: 10 },
|
||||
{ type: "{", pos: 12 },
|
||||
{ type: "iden", symbol: "console", pos: 13 },
|
||||
{ type: ".", pos: 20 },
|
||||
{ type: "iden", symbol: "log", pos: 21 },
|
||||
{ type: "(", pos: 24 },
|
||||
{ type: "string", symbol: "'foo'", pos: 25 },
|
||||
{ type: ")", pos: 30 },
|
||||
{ type: "invalid", pos: 31 },
|
||||
{ type: '(', pos: 0 },
|
||||
{ type: 'iden', symbol: 'function', pos: 1 },
|
||||
{ type: '(', pos: 9 },
|
||||
{ type: ')', pos: 10 },
|
||||
{ type: '{', pos: 12 },
|
||||
{ type: 'iden', symbol: 'console', pos: 13 },
|
||||
{ type: '.', pos: 20 },
|
||||
{ type: 'iden', symbol: 'log', pos: 21 },
|
||||
{ type: '(', pos: 24 },
|
||||
{ type: 'string', symbol: "'foo'", pos: 25 },
|
||||
{ type: ')', pos: 30 },
|
||||
{ type: 'invalid', pos: 31 },
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "'ranged' === 'ranged'",
|
||||
expected: [
|
||||
{ type: "string", symbol: "'ranged'", pos: 0 },
|
||||
{ type: "===", pos: 9 },
|
||||
{ type: "string", symbol: "'ranged'", pos: 13 },
|
||||
{ type: "eof", pos: 21 },
|
||||
{ type: 'string', symbol: "'ranged'", pos: 0 },
|
||||
{ type: '===', pos: 9 },
|
||||
{ type: 'string', symbol: "'ranged'", pos: 13 },
|
||||
{ type: 'eof', pos: 21 },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
@ -584,7 +584,7 @@ describe("Lexer", () => {
|
|||
...invalidStringTestCases,
|
||||
...whiteSpaceTestCases,
|
||||
...complicatedTermTestCases,
|
||||
])("lexes $input correctly", ({ input, expected }) => {
|
||||
])('lexes $input correctly', ({ input, expected }) => {
|
||||
// when
|
||||
const result = consume(new Lexer(input));
|
||||
|
||||
|
|
|
@ -2,17 +2,17 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { literals, safeOperators } from "../../src/expression-evaluation/grammar";
|
||||
import { Validator } from "../../src/expression-evaluation/validator";
|
||||
import { literals, safeOperators } from '../../src/expression-evaluation/grammar';
|
||||
import { Validator } from '../../src/expression-evaluation/validator';
|
||||
|
||||
describe("Validator", () => {
|
||||
it("allows identifier according to the given predicate", () => {
|
||||
describe('Validator', () => {
|
||||
it('allows identifier according to the given predicate', () => {
|
||||
// given
|
||||
const predicate = (identifier: string) => identifier === "true";
|
||||
const predicate = (identifier: string) => identifier === 'true';
|
||||
const validator = new Validator(predicate);
|
||||
const input = "true";
|
||||
const input = 'true';
|
||||
|
||||
// when
|
||||
const validate = () => validator.validate(input);
|
||||
|
@ -21,11 +21,11 @@ describe("Validator", () => {
|
|||
expect(validate).not.toThrow();
|
||||
});
|
||||
|
||||
it("disallows identifier according to the given predicate", () => {
|
||||
it('disallows identifier according to the given predicate', () => {
|
||||
// given
|
||||
const predicate = (identifier: string) => identifier === "false";
|
||||
const predicate = (identifier: string) => identifier === 'false';
|
||||
const validator = new Validator(predicate);
|
||||
const input = "true";
|
||||
const input = 'true';
|
||||
|
||||
// when
|
||||
const validate = () => validator.validate(input);
|
||||
|
@ -34,11 +34,11 @@ describe("Validator", () => {
|
|||
expect(validate).toThrowError("'true' is not an allowed identifier");
|
||||
});
|
||||
|
||||
it("allows multiple identifiers according to the given predicate", () => {
|
||||
it('allows multiple identifiers according to the given predicate', () => {
|
||||
// given
|
||||
const predicate = (identifier: string) => identifier === "true" || identifier === "null";
|
||||
const predicate = (identifier: string) => identifier === 'true' || identifier === 'null';
|
||||
const validator = new Validator(predicate);
|
||||
const input = "true null";
|
||||
const input = 'true null';
|
||||
|
||||
// when
|
||||
const validate = () => validator.validate(input);
|
||||
|
@ -47,11 +47,11 @@ describe("Validator", () => {
|
|||
expect(validate).not.toThrow();
|
||||
});
|
||||
|
||||
it("allows multiple identifiers in a more complex expression according to the given rule", () => {
|
||||
it('allows multiple identifiers in a more complex expression according to the given rule', () => {
|
||||
// given
|
||||
const predicate = (identifier: string) => identifier === "true" || identifier === "null";
|
||||
const predicate = (identifier: string) => identifier === 'true' || identifier === 'null';
|
||||
const validator = new Validator(predicate);
|
||||
const input = "true === null";
|
||||
const input = 'true === null';
|
||||
|
||||
// when
|
||||
const validate = () => validator.validate(input);
|
||||
|
@ -60,11 +60,11 @@ describe("Validator", () => {
|
|||
expect(validate).not.toThrow();
|
||||
});
|
||||
|
||||
it("mentions the first not allowed identifier in the thrown errror", () => {
|
||||
it('mentions the first not allowed identifier in the thrown errror', () => {
|
||||
// given
|
||||
const predicate = (identifier: string) => identifier === "true" || identifier === "null";
|
||||
const predicate = (identifier: string) => identifier === 'true' || identifier === 'null';
|
||||
const validator = new Validator(predicate);
|
||||
const input = "true === null && undefined === false";
|
||||
const input = 'true === null && undefined === false';
|
||||
|
||||
// when
|
||||
const validate = () => validator.validate(input);
|
||||
|
@ -73,22 +73,21 @@ describe("Validator", () => {
|
|||
expect(validate).toThrowError("'undefined' is not an allowed identifier.");
|
||||
});
|
||||
|
||||
it("disallows invalid invalid tokens", () => {
|
||||
it('disallows invalid invalid tokens', () => {
|
||||
// given
|
||||
const validator = new Validator();
|
||||
const input = ";";
|
||||
const input = ';';
|
||||
|
||||
// when
|
||||
const validate = () => validator.validate(input);
|
||||
|
||||
// then
|
||||
expect(validate).toThrowError("Invalid or unexpected token (0)");
|
||||
expect(validate).toThrowError('Invalid or unexpected token (0)');
|
||||
});
|
||||
|
||||
it("allows a complicated valid expression", () => {
|
||||
it('allows a complicated valid expression', () => {
|
||||
// given
|
||||
const predicate = (identifier: string) =>
|
||||
[...safeOperators, ...literals, "floor", "random"].includes(identifier);
|
||||
const predicate = (identifier: string) => [...safeOperators, ...literals, 'floor', 'random'].includes(identifier);
|
||||
const validator = new Validator(predicate);
|
||||
const input = "typeof (floor(random() * 5) / 2) === 'number' ? 42 : 'foo'";
|
||||
|
||||
|
@ -99,9 +98,9 @@ describe("Validator", () => {
|
|||
expect(validate).not.toThrow();
|
||||
});
|
||||
|
||||
it("disallows a complicated expression if it contains a disallowed identifier", () => {
|
||||
it('disallows a complicated expression if it contains a disallowed identifier', () => {
|
||||
// given
|
||||
const predicate = (identifier: string) => [...safeOperators, ...literals, "ceil"].includes(identifier);
|
||||
const predicate = (identifier: string) => [...safeOperators, ...literals, 'ceil'].includes(identifier);
|
||||
const validator = new Validator(predicate);
|
||||
const input = "ceil.constructor('alert(1); return 1;')()";
|
||||
|
||||
|
@ -112,15 +111,15 @@ describe("Validator", () => {
|
|||
expect(validate).toThrowError("'constructor' is not an allowed identifier.");
|
||||
});
|
||||
|
||||
it("disallows arrow functions", () => {
|
||||
it('disallows arrow functions', () => {
|
||||
// given
|
||||
const validator = new Validator();
|
||||
const input = "() => {}";
|
||||
const input = '() => {}';
|
||||
|
||||
// when
|
||||
const validate = () => validator.validate(input);
|
||||
|
||||
// then
|
||||
expect(validate).toThrowError("Invalid or unexpected token (3)");
|
||||
expect(validate).toThrowError('Invalid or unexpected token (3)');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import de from "../../lang/de.json";
|
||||
import en from "../../lang/en.json";
|
||||
import de from '../../lang/de.json';
|
||||
import en from '../../lang/en.json';
|
||||
|
||||
describe("English and german localization files", () => {
|
||||
it("should have the same keys.", () => {
|
||||
describe('English and german localization files', () => {
|
||||
it('should have the same keys.', () => {
|
||||
const deKeys = Object.keys(de);
|
||||
const enKeys = Object.keys(en);
|
||||
expect(deKeys).toEqual(enKeys);
|
||||
|
|
|
@ -2,23 +2,23 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import en from "../lang/en.json";
|
||||
import en from '../lang/en.json';
|
||||
|
||||
function setupPrimitives() {
|
||||
Object.defineProperties(Number, {
|
||||
isNumeric: {
|
||||
value: function (n: unknown) {
|
||||
if (n instanceof Array) return false;
|
||||
else if (([null, ""] as unknown[]).includes(n)) return false;
|
||||
else if (([null, ''] as unknown[]).includes(n)) return false;
|
||||
// @ts-expect-error Abusing JavaScript a bit here, but it's the implementation from foundry
|
||||
return +n === +n;
|
||||
},
|
||||
},
|
||||
fromString: {
|
||||
value: function (str: unknown) {
|
||||
if (typeof str !== "string" || !str.length) return NaN;
|
||||
if (typeof str !== 'string' || !str.length) return NaN;
|
||||
// Remove whitespace.
|
||||
str = str.replace(/\s+/g, "");
|
||||
str = str.replace(/\s+/g, '');
|
||||
return Number(str);
|
||||
},
|
||||
},
|
||||
|
|
|
@ -6,7 +6,7 @@ export class DS4ActiveEffectConfig extends ActiveEffectConfig {
|
|||
/** @override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
template: "systems/ds4/templates/sheets/active-effect/active-effect-config.hbs",
|
||||
template: 'systems/ds4/templates/sheets/active-effect/active-effect-config.hbs',
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ export class DS4ActiveEffectConfig extends ActiveEffectConfig {
|
|||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
const checkbox = html[0]?.querySelector('input[name="flags.ds4.itemEffectConfig.applyToItems"]');
|
||||
checkbox?.addEventListener("change", () => this.#toggleItemEffectConfig(checkbox.checked));
|
||||
checkbox?.addEventListener('change', () => this.#toggleItemEffectConfig(checkbox.checked));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,14 +25,14 @@ export class DS4ActiveEffectConfig extends ActiveEffectConfig {
|
|||
* @param {boolean} active The target state
|
||||
*/
|
||||
#toggleItemEffectConfig(active) {
|
||||
const elements = this.element[0]?.querySelectorAll(".ds4-item-effect-config");
|
||||
const elements = this.element[0]?.querySelectorAll('.ds4-item-effect-config');
|
||||
elements?.forEach((element) => {
|
||||
if (active) {
|
||||
element.classList.remove("ds4-hidden");
|
||||
element.classList.remove('ds4-hidden');
|
||||
} else {
|
||||
element.classList.add("ds4-hidden");
|
||||
element.classList.add('ds4-hidden');
|
||||
}
|
||||
});
|
||||
this.setPosition({ height: "auto" });
|
||||
this.setPosition({ height: 'auto' });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4 } from "../../config";
|
||||
import { DS4ActiveEffect } from "../../documents/active-effect";
|
||||
import { isCheck } from "../../documents/actor/actor-data-properties-base";
|
||||
import { getDS4Settings } from "../../settings";
|
||||
import { notifications } from "../../ui/notifications";
|
||||
import { enforce, getCanvas, getGame } from "../../utils/utils";
|
||||
import { disableOverriddenFields } from "../sheet-helpers";
|
||||
import { DS4 } from '../../config';
|
||||
import { DS4ActiveEffect } from '../../documents/active-effect';
|
||||
import { isCheck } from '../../documents/actor/actor-data-properties-base';
|
||||
import { getDS4Settings } from '../../settings';
|
||||
import { notifications } from '../../ui/notifications';
|
||||
import { enforce, getCanvas, getGame } from '../../utils/utils';
|
||||
import { disableOverriddenFields } from '../sheet-helpers';
|
||||
|
||||
/**
|
||||
* The base sheet class for all {@link DS4Actor}s.
|
||||
|
@ -20,14 +20,14 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
/** @override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ["sheet", "ds4-actor-sheet"],
|
||||
classes: ['sheet', 'ds4-actor-sheet'],
|
||||
height: 645,
|
||||
scrollY: [".ds4-sheet-body"],
|
||||
tabs: [{ navSelector: ".ds4-sheet-tab-nav", contentSelector: ".ds4-sheet-body", initial: "values" }],
|
||||
scrollY: ['.ds4-sheet-body'],
|
||||
tabs: [{ navSelector: '.ds4-sheet-tab-nav', contentSelector: '.ds4-sheet-body', initial: 'values' }],
|
||||
dragDrop: [
|
||||
{ dragSelector: ".item-list .item", dropSelector: null },
|
||||
{ dragSelector: ".effect-list .effect", dropSelector: null },
|
||||
{ dragSelector: ".ds4-check", dropSelector: null },
|
||||
{ dragSelector: '.item-list .item', dropSelector: null },
|
||||
{ dragSelector: '.effect-list .effect', dropSelector: null },
|
||||
{ dragSelector: '.ds4-check', dropSelector: null },
|
||||
],
|
||||
width: 650,
|
||||
});
|
||||
|
@ -35,7 +35,7 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
|
||||
/** @override */
|
||||
get template() {
|
||||
const basePath = "systems/ds4/templates/sheets/actor";
|
||||
const basePath = 'systems/ds4/templates/sheets/actor';
|
||||
if (!getGame().user?.isGM && this.actor.limited) return `${basePath}/limited-sheet.hbs`;
|
||||
return `${basePath}/${this.actor.type}-sheet.hbs`;
|
||||
}
|
||||
|
@ -74,11 +74,7 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
* @protected
|
||||
*/
|
||||
addTooltipsToData(context) {
|
||||
const valueGroups = [
|
||||
context.data.system.attributes,
|
||||
context.data.system.traits,
|
||||
context.data.system.combatValues,
|
||||
];
|
||||
const valueGroups = [context.data.system.attributes, context.data.system.traits, context.data.system.combatValues];
|
||||
|
||||
valueGroups.forEach((valueGroup) => {
|
||||
Object.values(valueGroup).forEach((attribute) => {
|
||||
|
@ -95,9 +91,9 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
* @protected
|
||||
*/
|
||||
getTooltipForValue(value) {
|
||||
return `${value.base} (${getGame().i18n.localize("DS4.TooltipBaseValue")}) + ${
|
||||
return `${value.base} (${getGame().i18n.localize('DS4.TooltipBaseValue')}) + ${
|
||||
value.mod
|
||||
} (${getGame().i18n.localize("DS4.TooltipModifier")}) ➞ ${getGame().i18n.localize("DS4.TooltipEffects")} ➞ ${
|
||||
} (${getGame().i18n.localize('DS4.TooltipModifier')}) ➞ ${getGame().i18n.localize('DS4.TooltipEffects')} ➞ ${
|
||||
value.total
|
||||
}`;
|
||||
}
|
||||
|
@ -111,16 +107,16 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
|
||||
if (!this.options.editable) return;
|
||||
|
||||
html.find(".control-item").on("click", this.onControlItem.bind(this));
|
||||
html.find(".change-item").on("change", this.onChangeItem.bind(this));
|
||||
html.find('.control-item').on('click', this.onControlItem.bind(this));
|
||||
html.find('.change-item').on('change', this.onChangeItem.bind(this));
|
||||
|
||||
html.find(".control-effect").on("click", this.onControlEffect.bind(this));
|
||||
html.find(".change-effect").on("change", this.onChangeEffect.bind(this));
|
||||
html.find('.control-effect').on('click', this.onControlEffect.bind(this));
|
||||
html.find('.change-effect').on('change', this.onChangeEffect.bind(this));
|
||||
|
||||
html.find(".rollable-item").on("click", this.onRollItem.bind(this));
|
||||
html.find(".rollable-check").on("click", this.onRollCheck.bind(this));
|
||||
html.find('.rollable-item').on('click', this.onRollItem.bind(this));
|
||||
html.find('.rollable-check').on('click', this.onRollCheck.bind(this));
|
||||
|
||||
html.find(".sort-items").on("click", this.onSortItems.bind(this));
|
||||
html.find('.sort-items').on('click', this.onSortItems.bind(this));
|
||||
|
||||
disableOverriddenFields(this.form, this.actor.overrides, (key) => `[name="${key}"]`);
|
||||
for (const item of this.actor.items) {
|
||||
|
@ -141,12 +137,12 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
onControlItem(event) {
|
||||
event.preventDefault();
|
||||
const a = event.currentTarget;
|
||||
switch (a.dataset["action"]) {
|
||||
case "create":
|
||||
switch (a.dataset['action']) {
|
||||
case 'create':
|
||||
return this.onCreateItem(event);
|
||||
case "edit":
|
||||
case 'edit':
|
||||
return this.onEditItem(event);
|
||||
case "delete":
|
||||
case 'delete':
|
||||
return this.onDeleteItem(event);
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +172,7 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
const item = await fromUuid(uuid);
|
||||
enforce(
|
||||
item && item.parent === this.actor,
|
||||
getGame().i18n.format("DS4.ErrorActorDoesNotHaveItem", { uuid, actor: this.actor.name }),
|
||||
getGame().i18n.format('DS4.ErrorActorDoesNotHaveItem', { uuid, actor: this.actor.name }),
|
||||
);
|
||||
item.sheet?.render(true);
|
||||
}
|
||||
|
@ -193,7 +189,7 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
const item = await fromUuid(uuid);
|
||||
enforce(
|
||||
item && item.parent === this.actor,
|
||||
getGame().i18n.format("DS4.ErrorActorDoesNotHaveItem", { uuid, actor: this.actor.name }),
|
||||
getGame().i18n.format('DS4.ErrorActorDoesNotHaveItem', { uuid, actor: this.actor.name }),
|
||||
);
|
||||
item.delete();
|
||||
$(li).slideUp(200, () => this.render(false));
|
||||
|
@ -207,7 +203,7 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
* @protected
|
||||
*/
|
||||
onChangeItem(event) {
|
||||
return this.onChangeEmbeddedDocument(event, "Item");
|
||||
return this.onChangeEmbeddedDocument(event, 'Item');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -220,12 +216,12 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
onControlEffect(event) {
|
||||
event.preventDefault();
|
||||
const a = event.currentTarget;
|
||||
switch (a.dataset["action"]) {
|
||||
case "create":
|
||||
switch (a.dataset['action']) {
|
||||
case 'create':
|
||||
return this.onCreateEffect();
|
||||
case "edit":
|
||||
case 'edit':
|
||||
return this.onEditEffect(event);
|
||||
case "delete":
|
||||
case 'delete':
|
||||
return this.onDeleteEffect(event);
|
||||
}
|
||||
}
|
||||
|
@ -252,7 +248,7 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
const effect = await fromUuid(uuid);
|
||||
enforce(
|
||||
effect && (effect.parent === this.actor || effect.parent.parent === this.actor),
|
||||
getGame().i18n.format("DS4.ErrorActorDoesNotHaveEffect", { uuid, actor: this.actor.name }),
|
||||
getGame().i18n.format('DS4.ErrorActorDoesNotHaveEffect', { uuid, actor: this.actor.name }),
|
||||
);
|
||||
effect.sheet?.render(true);
|
||||
}
|
||||
|
@ -269,7 +265,7 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
const effect = await fromUuid(uuid);
|
||||
enforce(
|
||||
effect && (effect.parent === this.actor || effect.parent.parent === this.actor),
|
||||
getGame().i18n.format("DS4.ErrorActorDoesNotHaveEffect", { uuid, actor: this.actor.name }),
|
||||
getGame().i18n.format('DS4.ErrorActorDoesNotHaveEffect', { uuid, actor: this.actor.name }),
|
||||
);
|
||||
effect.delete();
|
||||
$(li).slideUp(200, () => this.render(false));
|
||||
|
@ -283,7 +279,7 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
* @protected
|
||||
*/
|
||||
onChangeEffect(event) {
|
||||
return this.onChangeEmbeddedDocument(event, "ActiveEffect");
|
||||
return this.onChangeEmbeddedDocument(event, 'ActiveEffect');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -301,22 +297,22 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
|
||||
const documentElement = element.closest(embeddedDocumentListEntryProperties[documentName].selector);
|
||||
const uuid = documentElement.dataset[embeddedDocumentListEntryProperties[documentName].uuidDataAttribute];
|
||||
const property = element.dataset["property"];
|
||||
const property = element.dataset['property'];
|
||||
enforce(property !== undefined, TypeError("HTML element does not provide 'data-property' attribute"));
|
||||
|
||||
const newValue = this.parseValue(element);
|
||||
|
||||
const document = await fromUuid(uuid);
|
||||
|
||||
if (documentName === "Item") {
|
||||
if (documentName === 'Item') {
|
||||
enforce(
|
||||
document && document.parent === this.actor,
|
||||
getGame().i18n.format("DS4.ErrorActorDoesNotHaveItem", { uuid, actor: this.actor.name }),
|
||||
getGame().i18n.format('DS4.ErrorActorDoesNotHaveItem', { uuid, actor: this.actor.name }),
|
||||
);
|
||||
} else {
|
||||
enforce(
|
||||
document && (document.parent === this.actor || document.parent.parent === this.actor),
|
||||
getGame().i18n.format("DS4.ErrorActorDoesNotHaveEffect", { uuid, actor: this.actor.name }),
|
||||
getGame().i18n.format('DS4.ErrorActorDoesNotHaveEffect', { uuid, actor: this.actor.name }),
|
||||
);
|
||||
}
|
||||
document.update({ [property]: newValue });
|
||||
|
@ -335,23 +331,21 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
*/
|
||||
parseValue(element) {
|
||||
switch (element.type) {
|
||||
case "checkbox": {
|
||||
const inverted = Boolean(element.dataset["inverted"]);
|
||||
case 'checkbox': {
|
||||
const inverted = Boolean(element.dataset['inverted']);
|
||||
const value = element.checked;
|
||||
return inverted ? !value : value;
|
||||
}
|
||||
case "text": {
|
||||
case 'text': {
|
||||
const value = element.value;
|
||||
return value;
|
||||
}
|
||||
case "number": {
|
||||
case 'number': {
|
||||
const value = Number(element.value.trim());
|
||||
return value;
|
||||
}
|
||||
default: {
|
||||
throw new TypeError(
|
||||
"Binding of item property to this type of HTML element not supported; given: " + element,
|
||||
);
|
||||
throw new TypeError('Binding of item property to this type of HTML element not supported; given: ' + element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -368,7 +362,7 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
const item = await fromUuid(uuid);
|
||||
enforce(
|
||||
item && item.parent === this.actor,
|
||||
getGame().i18n.format("DS4.ErrorActorDoesNotHaveItem", { uuid, actor: this.actor.name }),
|
||||
getGame().i18n.format('DS4.ErrorActorDoesNotHaveItem', { uuid, actor: this.actor.name }),
|
||||
);
|
||||
item.roll().catch((e) => notifications.error(e, { log: true }));
|
||||
}
|
||||
|
@ -381,7 +375,7 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
onRollCheck(event) {
|
||||
event.preventDefault();
|
||||
event.currentTarget.blur();
|
||||
const check = event.currentTarget.dataset["check"];
|
||||
const check = event.currentTarget.dataset['check'];
|
||||
this.actor.rollCheck(check).catch((e) => notifications.error(e, { log: true }));
|
||||
}
|
||||
|
||||
|
@ -396,17 +390,17 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
const check = target.dataset.check;
|
||||
if (!check) return super._onDragStart(event);
|
||||
|
||||
enforce(isCheck(check), getGame().i18n.format("DS4.ErrorCannotDragMissingCheck", { check }));
|
||||
enforce(isCheck(check), getGame().i18n.format('DS4.ErrorCannotDragMissingCheck', { check }));
|
||||
|
||||
const dragData = {
|
||||
actorId: this.actor.id,
|
||||
sceneId: this.actor.isToken ? getCanvas().scene?.id : null,
|
||||
tokenId: this.actor.isToken ? this.actor.token?.id : null,
|
||||
type: "Check",
|
||||
type: 'Check',
|
||||
data: check,
|
||||
};
|
||||
|
||||
event.dataTransfer?.setData("text/plain", JSON.stringify(dragData));
|
||||
event.dataTransfer?.setData('text/plain', JSON.stringify(dragData));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -417,11 +411,11 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
onSortItems(event) {
|
||||
event.preventDefault();
|
||||
const target = event.currentTarget;
|
||||
const type = target.parentElement?.dataset["type"];
|
||||
const type = target.parentElement?.dataset['type'];
|
||||
enforce(type !== undefined, `Could not find property 'type' in the dataset of the parent of ${target}`);
|
||||
const dataPath = target.dataset["dataPath"];
|
||||
const dataPath = target.dataset['dataPath'];
|
||||
enforce(dataPath !== undefined, `Could not find property 'dataPath' in the dataset of ${target}`);
|
||||
const dataPath2 = target.dataset["dataPath2"];
|
||||
const dataPath2 = target.dataset['dataPath2'];
|
||||
/** @type {import("../../documents/item/item").DS4Item[]}*/
|
||||
const items = this.actor.items.filter((item) => item.type === type);
|
||||
items.sort((a, b) => a.sort - b.sort);
|
||||
|
@ -434,14 +428,14 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
const propertyA = getProperty(a, dataPath);
|
||||
const propertyB = getProperty(b, dataPath);
|
||||
const comparison =
|
||||
typeof propertyA === "string" || typeof propertyB === "string"
|
||||
typeof propertyA === 'string' || typeof propertyB === 'string'
|
||||
? compareAsStrings(propertyA, propertyB, invert)
|
||||
: compareAsNumbers(propertyA, propertyB, invert);
|
||||
|
||||
if (comparison === 0 && dataPath2 !== undefined) {
|
||||
const propertyA = getProperty(a, dataPath);
|
||||
const propertyB = getProperty(b, dataPath);
|
||||
return typeof propertyA === "string" || typeof propertyB === "string"
|
||||
return typeof propertyA === 'string' || typeof propertyB === 'string'
|
||||
? compareAsStrings(propertyA, propertyB, invert)
|
||||
: compareAsNumbers(propertyA, propertyB, invert);
|
||||
}
|
||||
|
@ -461,7 +455,7 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
sort: (i + 1) * CONST.SORT_INTEGER_DENSITY,
|
||||
}));
|
||||
|
||||
this.actor.updateEmbeddedDocuments("Item", updates);
|
||||
this.actor.updateEmbeddedDocuments('Item', updates);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -473,7 +467,7 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
const item = await Item.implementation.fromDropData(data);
|
||||
if (item && !this.actor.canOwnItemType(item.type)) {
|
||||
notifications.warn(
|
||||
getGame().i18n.format("DS4.WarningActorCannotOwnItem", {
|
||||
getGame().i18n.format('DS4.WarningActorCannotOwnItem', {
|
||||
actorName: this.actor.name,
|
||||
actorType: this.actor.type,
|
||||
itemName: item.name,
|
||||
|
@ -491,12 +485,12 @@ export class DS4ActorSheet extends ActorSheet {
|
|||
*/
|
||||
const embeddedDocumentListEntryProperties = Object.freeze({
|
||||
ActiveEffect: {
|
||||
selector: ".effect",
|
||||
uuidDataAttribute: "effectUuid",
|
||||
selector: '.effect',
|
||||
uuidDataAttribute: 'effectUuid',
|
||||
},
|
||||
Item: {
|
||||
selector: ".item",
|
||||
uuidDataAttribute: "itemUuid",
|
||||
selector: '.item',
|
||||
uuidDataAttribute: 'itemUuid',
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4ActorSheet } from "./base-sheet";
|
||||
import { DS4ActorSheet } from './base-sheet';
|
||||
|
||||
/**
|
||||
* The Sheet class for DS4 Character Actors
|
||||
|
@ -10,7 +10,7 @@ import { DS4ActorSheet } from "./base-sheet";
|
|||
export class DS4CharacterActorSheet extends DS4ActorSheet {
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ["sheet", "ds4-actor-sheet", "ds4-character-sheet"],
|
||||
classes: ['sheet', 'ds4-actor-sheet', 'ds4-character-sheet'],
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4ActorSheet } from "./base-sheet";
|
||||
import { DS4ActorSheet } from './base-sheet';
|
||||
|
||||
/**
|
||||
* The Sheet class for DS4 Creature Actors
|
||||
|
@ -10,17 +10,16 @@ import { DS4ActorSheet } from "./base-sheet";
|
|||
export class DS4CreatureActorSheet extends DS4ActorSheet {
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ["sheet", "ds4-actor-sheet", "ds4-creature-sheet"],
|
||||
classes: ['sheet', 'ds4-actor-sheet', 'ds4-creature-sheet'],
|
||||
});
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async getData(options = {}) {
|
||||
const context = await super.getData(options);
|
||||
context.data.system.baseInfo.description = await TextEditor.enrichHTML(
|
||||
context.data.system.baseInfo.description,
|
||||
{ async: true },
|
||||
);
|
||||
context.data.system.baseInfo.description = await TextEditor.enrichHTML(context.data.system.baseInfo.description, {
|
||||
async: true,
|
||||
});
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4 } from "../config";
|
||||
import { DS4ActiveEffect } from "../documents/active-effect";
|
||||
import { enforce, getGame } from "../utils/utils";
|
||||
import { disableOverriddenFields } from "./sheet-helpers";
|
||||
import { DS4 } from '../config';
|
||||
import { DS4ActiveEffect } from '../documents/active-effect';
|
||||
import { enforce, getGame } from '../utils/utils';
|
||||
import { disableOverriddenFields } from './sheet-helpers';
|
||||
|
||||
/**
|
||||
* The Sheet class for DS4 Items
|
||||
|
@ -16,17 +16,17 @@ export class DS4ItemSheet extends ItemSheet {
|
|||
/** @override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ["sheet", "ds4-item-sheet"],
|
||||
classes: ['sheet', 'ds4-item-sheet'],
|
||||
height: 400,
|
||||
scrollY: [".ds4-sheet-body"],
|
||||
tabs: [{ navSelector: ".ds4-sheet-tab-nav", contentSelector: ".ds4-sheet-body", initial: "description" }],
|
||||
scrollY: ['.ds4-sheet-body'],
|
||||
tabs: [{ navSelector: '.ds4-sheet-tab-nav', contentSelector: '.ds4-sheet-body', initial: 'description' }],
|
||||
width: 540,
|
||||
});
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
const basePath = "systems/ds4/templates/sheets/item";
|
||||
const basePath = 'systems/ds4/templates/sheets/item';
|
||||
return `${basePath}/${this.item.type}-sheet.hbs`;
|
||||
}
|
||||
|
||||
|
@ -60,9 +60,9 @@ export class DS4ItemSheet extends ItemSheet {
|
|||
setPosition(options = {}) {
|
||||
const position = super.setPosition(options);
|
||||
if (position) {
|
||||
const sheetBody = this.element.find(".sheet-body");
|
||||
const sheetBody = this.element.find('.sheet-body');
|
||||
const bodyHeight = position.height - 192;
|
||||
sheetBody.css("height", bodyHeight);
|
||||
sheetBody.css('height', bodyHeight);
|
||||
}
|
||||
|
||||
return position;
|
||||
|
@ -77,7 +77,7 @@ export class DS4ItemSheet extends ItemSheet {
|
|||
|
||||
if (!this.options.editable) return;
|
||||
|
||||
html.find(".control-effect").on("click", this.onControlEffect.bind(this));
|
||||
html.find('.control-effect').on('click', this.onControlEffect.bind(this));
|
||||
|
||||
disableOverriddenFields(this.form, this.item.overrides, (key) => `[name="${key}"]`);
|
||||
}
|
||||
|
@ -92,12 +92,12 @@ export class DS4ItemSheet extends ItemSheet {
|
|||
onControlEffect(event) {
|
||||
event.preventDefault();
|
||||
const a = event.currentTarget;
|
||||
switch (a.dataset["action"]) {
|
||||
case "create":
|
||||
switch (a.dataset['action']) {
|
||||
case 'create':
|
||||
return this.onCreateEffect();
|
||||
case "edit":
|
||||
case 'edit':
|
||||
return this.onEditEffect(event);
|
||||
case "delete":
|
||||
case 'delete':
|
||||
return this.onDeleteEffect(event);
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ export class DS4ItemSheet extends ItemSheet {
|
|||
.parents(embeddedDocumentListEntryProperties.ActiveEffect.selector)
|
||||
.data(embeddedDocumentListEntryProperties.ActiveEffect.idDataAttribute);
|
||||
const effect = this.item.effects.get(id);
|
||||
enforce(effect, getGame().i18n.format("DS4.ErrorItemDoesNotHaveEffect", { id, item: this.item.name }));
|
||||
enforce(effect, getGame().i18n.format('DS4.ErrorItemDoesNotHaveEffect', { id, item: this.item.name }));
|
||||
effect.sheet?.render(true);
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ export class DS4ItemSheet extends ItemSheet {
|
|||
onDeleteEffect(event) {
|
||||
const li = $(event.currentTarget).parents(embeddedDocumentListEntryProperties.ActiveEffect.selector);
|
||||
const id = li.data(embeddedDocumentListEntryProperties.ActiveEffect.idDataAttribute);
|
||||
this.item.deleteEmbeddedDocuments("ActiveEffect", [id]);
|
||||
this.item.deleteEmbeddedDocuments('ActiveEffect', [id]);
|
||||
li.slideUp(200, () => this.render(false));
|
||||
}
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ export class DS4ItemSheet extends ItemSheet {
|
|||
*/
|
||||
const embeddedDocumentListEntryProperties = Object.freeze({
|
||||
ActiveEffect: {
|
||||
selector: ".effect",
|
||||
idDataAttribute: "effectId",
|
||||
selector: '.effect',
|
||||
idDataAttribute: 'effectId',
|
||||
},
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { getGame } from "../utils/utils";
|
||||
import { getGame } from '../utils/utils';
|
||||
|
||||
/**
|
||||
* Disable elements in the given form that match the selector returned for overridden properties.
|
||||
|
@ -11,17 +11,17 @@ import { getGame } from "../utils/utils";
|
|||
* @param {(key: string) => string} selector A function that generates a selector, based on a property key
|
||||
*/
|
||||
export function disableOverriddenFields(form, overrides, selector) {
|
||||
const inputs = ["INPUT", "SELECT", "TEXTAREA", "BUTTON"];
|
||||
const titleAddition = `(${getGame().i18n.localize("DS4.TooltipNotEditableDueToEffects")})`;
|
||||
const inputs = ['INPUT', 'SELECT', 'TEXTAREA', 'BUTTON'];
|
||||
const titleAddition = `(${getGame().i18n.localize('DS4.TooltipNotEditableDueToEffects')})`;
|
||||
|
||||
for (const key of Object.keys(foundry.utils.flattenObject(overrides))) {
|
||||
const elements = form?.querySelectorAll(selector(key));
|
||||
elements?.forEach((element) => {
|
||||
if (inputs.includes(element.tagName) && !element.hasAttribute("disabled")) {
|
||||
element.setAttribute("disabled", "");
|
||||
const title = element.getAttribute("title");
|
||||
if (inputs.includes(element.tagName) && !element.hasAttribute('disabled')) {
|
||||
element.setAttribute('disabled', '');
|
||||
const title = element.getAttribute('title');
|
||||
const newTitle = title === null ? titleAddition : `${title} ${titleAddition}`;
|
||||
element.setAttribute("title", newTitle);
|
||||
element.setAttribute('title', newTitle);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
462
src/config.ts
462
src/config.ts
|
@ -10,348 +10,348 @@ const i18nKeys = {
|
|||
* Define the set of acttack types that can be performed with weapon items
|
||||
*/
|
||||
attackTypes: {
|
||||
melee: "DS4.AttackTypeMelee",
|
||||
ranged: "DS4.AttackTypeRanged",
|
||||
meleeRanged: "DS4.AttackTypeMeleeRanged",
|
||||
melee: 'DS4.AttackTypeMelee',
|
||||
ranged: 'DS4.AttackTypeRanged',
|
||||
meleeRanged: 'DS4.AttackTypeMeleeRanged',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the set of item availabilties
|
||||
*/
|
||||
itemAvailabilities: {
|
||||
unset: "DS4.ItemAvailabilityUnset",
|
||||
hamlet: "DS4.ItemAvailabilityHamlet",
|
||||
village: "DS4.ItemAvailabilityVilage",
|
||||
city: "DS4.ItemAvailabilityCity",
|
||||
elves: "DS4.ItemAvailabilityElves",
|
||||
dwarves: "DS4.ItemAvailabilityDwarves",
|
||||
nowhere: "DS4.ItemAvailabilityNowhere",
|
||||
unset: 'DS4.ItemAvailabilityUnset',
|
||||
hamlet: 'DS4.ItemAvailabilityHamlet',
|
||||
village: 'DS4.ItemAvailabilityVilage',
|
||||
city: 'DS4.ItemAvailabilityCity',
|
||||
elves: 'DS4.ItemAvailabilityElves',
|
||||
dwarves: 'DS4.ItemAvailabilityDwarves',
|
||||
nowhere: 'DS4.ItemAvailabilityNowhere',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the set of item types
|
||||
*/
|
||||
itemTypes: {
|
||||
weapon: "DS4.ItemTypeWeapon",
|
||||
armor: "DS4.ItemTypeArmor",
|
||||
shield: "DS4.ItemTypeShield",
|
||||
spell: "DS4.ItemTypeSpell",
|
||||
equipment: "DS4.ItemTypeEquipment",
|
||||
loot: "DS4.ItemTypeLoot",
|
||||
talent: "DS4.ItemTypeTalent",
|
||||
racialAbility: "DS4.ItemTypeRacialAbility",
|
||||
language: "DS4.ItemTypeLanguage",
|
||||
alphabet: "DS4.ItemTypeAlphabet",
|
||||
specialCreatureAbility: "DS4.ItemTypeSpecialCreatureAbility",
|
||||
weapon: 'DS4.ItemTypeWeapon',
|
||||
armor: 'DS4.ItemTypeArmor',
|
||||
shield: 'DS4.ItemTypeShield',
|
||||
spell: 'DS4.ItemTypeSpell',
|
||||
equipment: 'DS4.ItemTypeEquipment',
|
||||
loot: 'DS4.ItemTypeLoot',
|
||||
talent: 'DS4.ItemTypeTalent',
|
||||
racialAbility: 'DS4.ItemTypeRacialAbility',
|
||||
language: 'DS4.ItemTypeLanguage',
|
||||
alphabet: 'DS4.ItemTypeAlphabet',
|
||||
specialCreatureAbility: 'DS4.ItemTypeSpecialCreatureAbility',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the set of armor types, a character may only wear one item of each at any given time
|
||||
*/
|
||||
armorTypes: {
|
||||
body: "DS4.ArmorTypeBody",
|
||||
helmet: "DS4.ArmorTypeHelmet",
|
||||
vambrace: "DS4.ArmorTypeVambrace",
|
||||
greaves: "DS4.ArmorTypeGreaves",
|
||||
vambraceGreaves: "DS4.ArmorTypeVambraceGreaves",
|
||||
body: 'DS4.ArmorTypeBody',
|
||||
helmet: 'DS4.ArmorTypeHelmet',
|
||||
vambrace: 'DS4.ArmorTypeVambrace',
|
||||
greaves: 'DS4.ArmorTypeGreaves',
|
||||
vambraceGreaves: 'DS4.ArmorTypeVambraceGreaves',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define abbreviations for the armor types
|
||||
*/
|
||||
armorTypesAbbr: {
|
||||
body: "DS4.ArmorTypeBodyAbbr",
|
||||
helmet: "DS4.ArmorTypeHelmetAbbr",
|
||||
vambrace: "DS4.ArmorTypeVambraceAbbr",
|
||||
greaves: "DS4.ArmorTypeGreavesAbbr",
|
||||
vambraceGreaves: "DS4.ArmorTypeVambraceGreavesAbbr",
|
||||
body: 'DS4.ArmorTypeBodyAbbr',
|
||||
helmet: 'DS4.ArmorTypeHelmetAbbr',
|
||||
vambrace: 'DS4.ArmorTypeVambraceAbbr',
|
||||
greaves: 'DS4.ArmorTypeGreavesAbbr',
|
||||
vambraceGreaves: 'DS4.ArmorTypeVambraceGreavesAbbr',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the set of armor materials, used to determine if a character may wear the armor without additional penalties
|
||||
*/
|
||||
armorMaterialTypes: {
|
||||
cloth: "DS4.ArmorMaterialTypeCloth",
|
||||
leather: "DS4.ArmorMaterialTypeLeather",
|
||||
chain: "DS4.ArmorMaterialTypeChain",
|
||||
plate: "DS4.ArmorMaterialTypePlate",
|
||||
natural: "DS4.ArmorMaterialTypeNatural",
|
||||
cloth: 'DS4.ArmorMaterialTypeCloth',
|
||||
leather: 'DS4.ArmorMaterialTypeLeather',
|
||||
chain: 'DS4.ArmorMaterialTypeChain',
|
||||
plate: 'DS4.ArmorMaterialTypePlate',
|
||||
natural: 'DS4.ArmorMaterialTypeNatural',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the abbreviations of armor materials
|
||||
*/
|
||||
armorMaterialTypesAbbr: {
|
||||
cloth: "DS4.ArmorMaterialTypeClothAbbr",
|
||||
leather: "DS4.ArmorMaterialTypeLeatherAbbr",
|
||||
chain: "DS4.ArmorMaterialTypeChainAbbr",
|
||||
plate: "DS4.ArmorMaterialTypePlateAbbr",
|
||||
natural: "DS4.ArmorMaterialTypeNaturalAbbr",
|
||||
cloth: 'DS4.ArmorMaterialTypeClothAbbr',
|
||||
leather: 'DS4.ArmorMaterialTypeLeatherAbbr',
|
||||
chain: 'DS4.ArmorMaterialTypeChainAbbr',
|
||||
plate: 'DS4.ArmorMaterialTypePlateAbbr',
|
||||
natural: 'DS4.ArmorMaterialTypeNaturalAbbr',
|
||||
},
|
||||
|
||||
spellTypes: {
|
||||
spellcasting: "DS4.SpellTypeSpellcasting",
|
||||
targetedSpellcasting: "DS4.SpellTypeTargetedSpellcasting",
|
||||
spellcasting: 'DS4.SpellTypeSpellcasting',
|
||||
targetedSpellcasting: 'DS4.SpellTypeTargetedSpellcasting',
|
||||
},
|
||||
|
||||
spellGroups: {
|
||||
lightning: "DS4.SpellGroupLightning",
|
||||
earth: "DS4.SpellGroupEarth",
|
||||
water: "DS4.SpellGroupWater",
|
||||
ice: "DS4.SpellGroupIce",
|
||||
fire: "DS4.SpellGroupFire",
|
||||
healing: "DS4.SpellGroupHealing",
|
||||
light: "DS4.SpellGroupLight",
|
||||
air: "DS4.SpellGroupAir",
|
||||
transport: "DS4.SpellGroupTransport",
|
||||
damage: "DS4.SpellGroupDamage",
|
||||
shadow: "DS4.SpellGroupShadow",
|
||||
protection: "DS4.SpellGroupProtection",
|
||||
mindAffecting: "DS4.SpellGroupMindAffecting",
|
||||
demonology: "DS4.SpellGroupDemonology",
|
||||
necromancy: "DS4.SpellGroupNecromancy",
|
||||
transmutation: "DS4.SpellGroupTransmutation",
|
||||
area: "DS4.SpellGroupArea",
|
||||
lightning: 'DS4.SpellGroupLightning',
|
||||
earth: 'DS4.SpellGroupEarth',
|
||||
water: 'DS4.SpellGroupWater',
|
||||
ice: 'DS4.SpellGroupIce',
|
||||
fire: 'DS4.SpellGroupFire',
|
||||
healing: 'DS4.SpellGroupHealing',
|
||||
light: 'DS4.SpellGroupLight',
|
||||
air: 'DS4.SpellGroupAir',
|
||||
transport: 'DS4.SpellGroupTransport',
|
||||
damage: 'DS4.SpellGroupDamage',
|
||||
shadow: 'DS4.SpellGroupShadow',
|
||||
protection: 'DS4.SpellGroupProtection',
|
||||
mindAffecting: 'DS4.SpellGroupMindAffecting',
|
||||
demonology: 'DS4.SpellGroupDemonology',
|
||||
necromancy: 'DS4.SpellGroupNecromancy',
|
||||
transmutation: 'DS4.SpellGroupTransmutation',
|
||||
area: 'DS4.SpellGroupArea',
|
||||
},
|
||||
|
||||
cooldownDurations: {
|
||||
"0r": "DS4.CooldownDuration0R",
|
||||
"1r": "DS4.CooldownDuration1R",
|
||||
"2r": "DS4.CooldownDuration2R",
|
||||
"5r": "DS4.CooldownDuration5R",
|
||||
"10r": "DS4.CooldownDuration10R",
|
||||
"100r": "DS4.CooldownDuration100R",
|
||||
"1d": "DS4.CooldownDuration1D",
|
||||
d20d: "DS4.CooldownDurationD20D",
|
||||
'0r': 'DS4.CooldownDuration0R',
|
||||
'1r': 'DS4.CooldownDuration1R',
|
||||
'2r': 'DS4.CooldownDuration2R',
|
||||
'5r': 'DS4.CooldownDuration5R',
|
||||
'10r': 'DS4.CooldownDuration10R',
|
||||
'100r': 'DS4.CooldownDuration100R',
|
||||
'1d': 'DS4.CooldownDuration1D',
|
||||
d20d: 'DS4.CooldownDurationD20D',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the set of actor types
|
||||
*/
|
||||
actorTypes: {
|
||||
character: "DS4.ActorTypeCharacter",
|
||||
creature: "DS4.ActorTypeCreature",
|
||||
character: 'DS4.ActorTypeCharacter',
|
||||
creature: 'DS4.ActorTypeCreature',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the set of attributes an actor has
|
||||
*/
|
||||
attributes: {
|
||||
body: "DS4.AttributeBody",
|
||||
mobility: "DS4.AttributeMobility",
|
||||
mind: "DS4.AttributeMind",
|
||||
body: 'DS4.AttributeBody',
|
||||
mobility: 'DS4.AttributeMobility',
|
||||
mind: 'DS4.AttributeMind',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the set of traits an actor has
|
||||
*/
|
||||
traits: {
|
||||
strength: "DS4.TraitStrength",
|
||||
agility: "DS4.TraitAgility",
|
||||
intellect: "DS4.TraitIntellect",
|
||||
constitution: "DS4.TraitConstitution",
|
||||
dexterity: "DS4.TraitDexterity",
|
||||
aura: "DS4.TraitAura",
|
||||
strength: 'DS4.TraitStrength',
|
||||
agility: 'DS4.TraitAgility',
|
||||
intellect: 'DS4.TraitIntellect',
|
||||
constitution: 'DS4.TraitConstitution',
|
||||
dexterity: 'DS4.TraitDexterity',
|
||||
aura: 'DS4.TraitAura',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the set of combat values an actor has
|
||||
*/
|
||||
combatValues: {
|
||||
hitPoints: "DS4.CombatValuesHitPoints",
|
||||
defense: "DS4.CombatValuesDefense",
|
||||
initiative: "DS4.CombatValuesInitiative",
|
||||
movement: "DS4.CombatValuesMovement",
|
||||
meleeAttack: "DS4.CombatValuesMeleeAttack",
|
||||
rangedAttack: "DS4.CombatValuesRangedAttack",
|
||||
spellcasting: "DS4.CombatValuesSpellcasting",
|
||||
targetedSpellcasting: "DS4.CombatValuesTargetedSpellcasting",
|
||||
hitPoints: 'DS4.CombatValuesHitPoints',
|
||||
defense: 'DS4.CombatValuesDefense',
|
||||
initiative: 'DS4.CombatValuesInitiative',
|
||||
movement: 'DS4.CombatValuesMovement',
|
||||
meleeAttack: 'DS4.CombatValuesMeleeAttack',
|
||||
rangedAttack: 'DS4.CombatValuesRangedAttack',
|
||||
spellcasting: 'DS4.CombatValuesSpellcasting',
|
||||
targetedSpellcasting: 'DS4.CombatValuesTargetedSpellcasting',
|
||||
},
|
||||
|
||||
/**
|
||||
* The what do display in the actor sheets for the combat value text (in some languages, abbreviations are necessary)
|
||||
*/
|
||||
combatValuesSheet: {
|
||||
hitPoints: "DS4.CombatValuesHitPointsSheet",
|
||||
defense: "DS4.CombatValuesDefenseSheet",
|
||||
initiative: "DS4.CombatValuesInitiativeSheet",
|
||||
movement: "DS4.CombatValuesMovementSheet",
|
||||
meleeAttack: "DS4.CombatValuesMeleeAttackSheet",
|
||||
rangedAttack: "DS4.CombatValuesRangedAttackSheet",
|
||||
spellcasting: "DS4.CombatValuesSpellcastingSheet",
|
||||
targetedSpellcasting: "DS4.CombatValuesTargetedSpellcastingSheet",
|
||||
hitPoints: 'DS4.CombatValuesHitPointsSheet',
|
||||
defense: 'DS4.CombatValuesDefenseSheet',
|
||||
initiative: 'DS4.CombatValuesInitiativeSheet',
|
||||
movement: 'DS4.CombatValuesMovementSheet',
|
||||
meleeAttack: 'DS4.CombatValuesMeleeAttackSheet',
|
||||
rangedAttack: 'DS4.CombatValuesRangedAttackSheet',
|
||||
spellcasting: 'DS4.CombatValuesSpellcastingSheet',
|
||||
targetedSpellcasting: 'DS4.CombatValuesTargetedSpellcastingSheet',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the base info of a character
|
||||
*/
|
||||
characterBaseInfo: {
|
||||
race: "DS4.CharacterBaseInfoRace",
|
||||
class: "DS4.CharacterBaseInfoClass",
|
||||
heroClass: "DS4.CharacterBaseInfoHeroClass",
|
||||
culture: "DS4.CharacterBaseInfoCulture",
|
||||
race: 'DS4.CharacterBaseInfoRace',
|
||||
class: 'DS4.CharacterBaseInfoClass',
|
||||
heroClass: 'DS4.CharacterBaseInfoHeroClass',
|
||||
culture: 'DS4.CharacterBaseInfoCulture',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the progression info of a character
|
||||
*/
|
||||
characterProgression: {
|
||||
level: "DS4.CharacterProgressionLevel",
|
||||
experiencePoints: "DS4.CharacterProgressionExperiencePoints",
|
||||
talentPoints: "DS4.CharacterProgressionTalentPoints",
|
||||
progressPoints: "DS4.CharacterProgressionProgressPoints",
|
||||
level: 'DS4.CharacterProgressionLevel',
|
||||
experiencePoints: 'DS4.CharacterProgressionExperiencePoints',
|
||||
talentPoints: 'DS4.CharacterProgressionTalentPoints',
|
||||
progressPoints: 'DS4.CharacterProgressionProgressPoints',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the language info of a character
|
||||
*/
|
||||
characterLanguage: {
|
||||
languages: "DS4.CharacterLanguageLanguages",
|
||||
alphabets: "DS4.CharacterLanguageAlphabets",
|
||||
languages: 'DS4.CharacterLanguageLanguages',
|
||||
alphabets: 'DS4.CharacterLanguageAlphabets',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the profile info of a character
|
||||
*/
|
||||
characterProfile: {
|
||||
biography: "DS4.CharacterProfileBiography",
|
||||
gender: "DS4.CharacterProfileGender",
|
||||
birthday: "DS4.CharacterProfileBirthday",
|
||||
birthplace: "DS4.CharacterProfileBirthplace",
|
||||
age: "DS4.CharacterProfileAge",
|
||||
height: "DS4.CharacterProfileHeight",
|
||||
hairColor: "DS4.CharacterProfileHairColor",
|
||||
weight: "DS4.CharacterProfileWeight",
|
||||
eyeColor: "DS4.CharacterProfileEyeColor",
|
||||
specialCharacteristics: "DS4.CharacterProfileSpecialCharacteristics",
|
||||
biography: 'DS4.CharacterProfileBiography',
|
||||
gender: 'DS4.CharacterProfileGender',
|
||||
birthday: 'DS4.CharacterProfileBirthday',
|
||||
birthplace: 'DS4.CharacterProfileBirthplace',
|
||||
age: 'DS4.CharacterProfileAge',
|
||||
height: 'DS4.CharacterProfileHeight',
|
||||
hairColor: 'DS4.CharacterProfileHairColor',
|
||||
weight: 'DS4.CharacterProfileWeight',
|
||||
eyeColor: 'DS4.CharacterProfileEyeColor',
|
||||
specialCharacteristics: 'DS4.CharacterProfileSpecialCharacteristics',
|
||||
},
|
||||
/**
|
||||
* Define currency elements of a character
|
||||
*/
|
||||
characterCurrency: {
|
||||
gold: "DS4.CharacterCurrencyGold",
|
||||
silver: "DS4.CharacterCurrencySilver",
|
||||
copper: "DS4.CharacterCurrencyCopper",
|
||||
gold: 'DS4.CharacterCurrencyGold',
|
||||
silver: 'DS4.CharacterCurrencySilver',
|
||||
copper: 'DS4.CharacterCurrencyCopper',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the different creature types a creature can be
|
||||
*/
|
||||
creatureTypes: {
|
||||
animal: "DS4.CreatureTypeAnimal",
|
||||
construct: "DS4.CreatureTypeConstruct",
|
||||
humanoid: "DS4.CreatureTypeHumanoid",
|
||||
magicalEntity: "DS4.CreatureTypeMagicalEntity",
|
||||
plantBeing: "DS4.CreatureTypePlantBeing",
|
||||
undead: "DS4.CreatureTypeUndead",
|
||||
animal: 'DS4.CreatureTypeAnimal',
|
||||
construct: 'DS4.CreatureTypeConstruct',
|
||||
humanoid: 'DS4.CreatureTypeHumanoid',
|
||||
magicalEntity: 'DS4.CreatureTypeMagicalEntity',
|
||||
plantBeing: 'DS4.CreatureTypePlantBeing',
|
||||
undead: 'DS4.CreatureTypeUndead',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the different size categories creatures fall into
|
||||
*/
|
||||
creatureSizeCategories: {
|
||||
tiny: "DS4.CreatureSizeCategoryTiny",
|
||||
small: "DS4.CreatureSizeCategorySmall",
|
||||
normal: "DS4.CreatureSizeCategoryNormal",
|
||||
large: "DS4.CreatureSizeCategoryLarge",
|
||||
huge: "DS4.CreatureSizeCategoryHuge",
|
||||
colossal: "DS4.CreatureSizeCategoryColossal",
|
||||
tiny: 'DS4.CreatureSizeCategoryTiny',
|
||||
small: 'DS4.CreatureSizeCategorySmall',
|
||||
normal: 'DS4.CreatureSizeCategoryNormal',
|
||||
large: 'DS4.CreatureSizeCategoryLarge',
|
||||
huge: 'DS4.CreatureSizeCategoryHuge',
|
||||
colossal: 'DS4.CreatureSizeCategoryColossal',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the base info of a creature
|
||||
*/
|
||||
creatureBaseInfo: {
|
||||
loot: "DS4.CreatureBaseInfoLoot",
|
||||
foeFactor: "DS4.CreatureBaseInfoFoeFactor",
|
||||
creatureType: "DS4.CreatureBaseInfoCreatureType",
|
||||
sizeCategory: "DS4.CreatureBaseInfoSizeCategory",
|
||||
experiencePoints: "DS4.CreatureBaseInfoExperiencePoints",
|
||||
description: "DS4.CreatureBaseInfoDescription",
|
||||
loot: 'DS4.CreatureBaseInfoLoot',
|
||||
foeFactor: 'DS4.CreatureBaseInfoFoeFactor',
|
||||
creatureType: 'DS4.CreatureBaseInfoCreatureType',
|
||||
sizeCategory: 'DS4.CreatureBaseInfoSizeCategory',
|
||||
experiencePoints: 'DS4.CreatureBaseInfoExperiencePoints',
|
||||
description: 'DS4.CreatureBaseInfoDescription',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define translations for available distance units
|
||||
*/
|
||||
distanceUnits: {
|
||||
meter: "DS4.UnitMeters",
|
||||
kilometer: "DS4.UnitKilometers",
|
||||
custom: "DS4.UnitCustom",
|
||||
meter: 'DS4.UnitMeters',
|
||||
kilometer: 'DS4.UnitKilometers',
|
||||
custom: 'DS4.UnitCustom',
|
||||
},
|
||||
/**
|
||||
* Define abbreviations for available distance units
|
||||
*/
|
||||
distanceUnitsAbbr: {
|
||||
meter: "DS4.UnitMetersAbbr",
|
||||
kilometer: "DS4.UnitKilometersAbbr",
|
||||
custom: "DS4.UnitCustomAbbr",
|
||||
meter: 'DS4.UnitMetersAbbr',
|
||||
kilometer: 'DS4.UnitKilometersAbbr',
|
||||
custom: 'DS4.UnitCustomAbbr',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define translations for available duration units
|
||||
*/
|
||||
temporalUnits: {
|
||||
rounds: "DS4.UnitRounds",
|
||||
minutes: "DS4.UnitMinutes",
|
||||
hours: "DS4.UnitHours",
|
||||
days: "DS4.UnitDays",
|
||||
custom: "DS4.UnitCustom",
|
||||
rounds: 'DS4.UnitRounds',
|
||||
minutes: 'DS4.UnitMinutes',
|
||||
hours: 'DS4.UnitHours',
|
||||
days: 'DS4.UnitDays',
|
||||
custom: 'DS4.UnitCustom',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define abbreviations for available duration units
|
||||
*/
|
||||
temporalUnitsAbbr: {
|
||||
rounds: "DS4.UnitRoundsAbbr",
|
||||
minutes: "DS4.UnitMinutesAbbr",
|
||||
hours: "DS4.UnitHoursAbbr",
|
||||
days: "DS4.UnitDaysAbbr",
|
||||
custom: "DS4.UnitCustomAbbr",
|
||||
rounds: 'DS4.UnitRoundsAbbr',
|
||||
minutes: 'DS4.UnitMinutesAbbr',
|
||||
hours: 'DS4.UnitHoursAbbr',
|
||||
days: 'DS4.UnitDaysAbbr',
|
||||
custom: 'DS4.UnitCustomAbbr',
|
||||
},
|
||||
|
||||
checks: {
|
||||
appraise: "DS4.ChecksAppraise",
|
||||
changeSpell: "DS4.ChecksChangeSpell",
|
||||
climb: "DS4.ChecksClimb",
|
||||
communicate: "DS4.ChecksCommunicate",
|
||||
decipherScript: "DS4.ChecksDecipherScript",
|
||||
defend: "DS4.ChecksDefend",
|
||||
defyPoison: "DS4.ChecksDefyPoison",
|
||||
disableTraps: "DS4.ChecksDisableTraps",
|
||||
featOfStrength: "DS4.ChecksFeatOfStrength",
|
||||
flirt: "DS4.ChecksFlirt",
|
||||
haggle: "DS4.ChecksHaggle",
|
||||
hide: "DS4.ChecksHide",
|
||||
identifyMagic: "DS4.ChecksIdentifyMagic",
|
||||
jump: "DS4.ChecksJump",
|
||||
knowledge: "DS4.ChecksKnowledge",
|
||||
openLock: "DS4.ChecksOpenLock",
|
||||
perception: "DS4.ChecksPerception",
|
||||
pickPocket: "DS4.ChecksPickPocket",
|
||||
readTracks: "DS4.ChecksReadTracks",
|
||||
resistDisease: "DS4.ChecksResistDisease",
|
||||
ride: "DS4.ChecksRide",
|
||||
search: "DS4.ChecksSearch",
|
||||
senseMagic: "DS4.ChecksSenseMagic",
|
||||
sneak: "DS4.ChecksSneak",
|
||||
startFire: "DS4.ChecksStartFire",
|
||||
swim: "DS4.ChecksSwim",
|
||||
wakeUp: "DS4.ChecksWakeUp",
|
||||
workMechanism: "DS4.ChecksWorkMechanism",
|
||||
appraise: 'DS4.ChecksAppraise',
|
||||
changeSpell: 'DS4.ChecksChangeSpell',
|
||||
climb: 'DS4.ChecksClimb',
|
||||
communicate: 'DS4.ChecksCommunicate',
|
||||
decipherScript: 'DS4.ChecksDecipherScript',
|
||||
defend: 'DS4.ChecksDefend',
|
||||
defyPoison: 'DS4.ChecksDefyPoison',
|
||||
disableTraps: 'DS4.ChecksDisableTraps',
|
||||
featOfStrength: 'DS4.ChecksFeatOfStrength',
|
||||
flirt: 'DS4.ChecksFlirt',
|
||||
haggle: 'DS4.ChecksHaggle',
|
||||
hide: 'DS4.ChecksHide',
|
||||
identifyMagic: 'DS4.ChecksIdentifyMagic',
|
||||
jump: 'DS4.ChecksJump',
|
||||
knowledge: 'DS4.ChecksKnowledge',
|
||||
openLock: 'DS4.ChecksOpenLock',
|
||||
perception: 'DS4.ChecksPerception',
|
||||
pickPocket: 'DS4.ChecksPickPocket',
|
||||
readTracks: 'DS4.ChecksReadTracks',
|
||||
resistDisease: 'DS4.ChecksResistDisease',
|
||||
ride: 'DS4.ChecksRide',
|
||||
search: 'DS4.ChecksSearch',
|
||||
senseMagic: 'DS4.ChecksSenseMagic',
|
||||
sneak: 'DS4.ChecksSneak',
|
||||
startFire: 'DS4.ChecksStartFire',
|
||||
swim: 'DS4.ChecksSwim',
|
||||
wakeUp: 'DS4.ChecksWakeUp',
|
||||
workMechanism: 'DS4.ChecksWorkMechanism',
|
||||
},
|
||||
|
||||
/**
|
||||
* Translations for the standard check modifiers
|
||||
*/
|
||||
checkModifiers: {
|
||||
routine: "DS4.CheckModifierRoutine",
|
||||
veryEasy: "DS4.CheckModifierVeryEasy",
|
||||
easy: "DS4.CheckModifierEasy",
|
||||
normal: "DS4.CheckModifierMormal",
|
||||
difficult: "DS4.CheckModifierDifficult",
|
||||
veryDifficult: "DS4.CheckModifierVeryDifficult",
|
||||
extremelyDifficult: "DS4.CheckModifierExtremelyDifficult",
|
||||
custom: "DS4.CheckModifierCustom",
|
||||
routine: 'DS4.CheckModifierRoutine',
|
||||
veryEasy: 'DS4.CheckModifierVeryEasy',
|
||||
easy: 'DS4.CheckModifierEasy',
|
||||
normal: 'DS4.CheckModifierMormal',
|
||||
difficult: 'DS4.CheckModifierDifficult',
|
||||
veryDifficult: 'DS4.CheckModifierVeryDifficult',
|
||||
extremelyDifficult: 'DS4.CheckModifierExtremelyDifficult',
|
||||
custom: 'DS4.CheckModifierCustom',
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -385,51 +385,51 @@ export const DS4 = {
|
|||
* Define the file paths to icon images
|
||||
*/
|
||||
attackTypes: {
|
||||
melee: "systems/ds4/assets/icons/official/combat-values/melee-attack.png",
|
||||
meleeRanged: "systems/ds4/assets/icons/official/combat-values/melee-ranged-attack.png",
|
||||
ranged: "systems/ds4/assets/icons/official/combat-values/ranged-attack.png",
|
||||
melee: 'systems/ds4/assets/icons/official/combat-values/melee-attack.png',
|
||||
meleeRanged: 'systems/ds4/assets/icons/official/combat-values/melee-ranged-attack.png',
|
||||
ranged: 'systems/ds4/assets/icons/official/combat-values/ranged-attack.png',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the file paths to icon images
|
||||
*/
|
||||
spellTypes: {
|
||||
spellcasting: "systems/ds4/assets/icons/official/combat-values/spellcasting.png",
|
||||
targetedSpellcasting: "systems/ds4/assets/icons/official/combat-values/targeted-spellcasting.png",
|
||||
spellcasting: 'systems/ds4/assets/icons/official/combat-values/spellcasting.png',
|
||||
targetedSpellcasting: 'systems/ds4/assets/icons/official/combat-values/targeted-spellcasting.png',
|
||||
},
|
||||
|
||||
/**
|
||||
* Define the file paths to check images
|
||||
*/
|
||||
checks: {
|
||||
appraise: "systems/ds4/assets/icons/game-icons/delapouite/two-coins.svg",
|
||||
changeSpell: "systems/ds4/assets/icons/game-icons/delapouite/card-exchange.svg",
|
||||
climb: "systems/ds4/assets/icons/game-icons/caro-asercion/mountain-climbing.svg",
|
||||
communicate: "systems/ds4/assets/icons/game-icons/delapouite/discussion.svg",
|
||||
decipherScript: "systems/ds4/assets/icons/game-icons/lorc/rune-stone.svg",
|
||||
defend: "systems/ds4/assets/icons/game-icons/sbed/shield.svg",
|
||||
defyPoison: "systems/ds4/assets/icons/game-icons/lorc/poison-bottle.svg",
|
||||
disableTraps: "systems/ds4/assets/icons/game-icons/lorc/wolf-trap.svg",
|
||||
featOfStrength: "systems/ds4/assets/icons/game-icons/delapouite/biceps.svg",
|
||||
flirt: "systems/ds4/assets/icons/game-icons/lorc/charm.svg",
|
||||
haggle: "systems/ds4/assets/icons/game-icons/lorc/cash.svg",
|
||||
hide: "systems/ds4/assets/icons/game-icons/lorc/hidden.svg",
|
||||
identifyMagic: "systems/ds4/assets/icons/game-icons/lorc/uncertainty.svg",
|
||||
jump: "systems/ds4/assets/icons/game-icons/delapouite/jump-across.svg",
|
||||
knowledge: "systems/ds4/assets/icons/game-icons/delapouite/bookshelf.svg",
|
||||
openLock: "systems/ds4/assets/icons/game-icons/delapouite/padlock-open.svg",
|
||||
perception: "systems/ds4/assets/icons/game-icons/lorc/awareness.svg",
|
||||
pickPocket: "systems/ds4/assets/icons/game-icons/darkzaitev/robber-hand.svg",
|
||||
readTracks: "systems/ds4/assets/icons/game-icons/delapouite/deer-track.svg",
|
||||
resistDisease: "systems/ds4/assets/icons/game-icons/lorc/virus.svg",
|
||||
ride: "systems/ds4/assets/icons/game-icons/delapouite/cavalry.svg",
|
||||
search: "systems/ds4/assets/icons/game-icons/lorc/magnifying-glass.svg",
|
||||
senseMagic: "systems/ds4/assets/icons/game-icons/delapouite/sparkles.svg",
|
||||
sneak: "systems/ds4/assets/icons/game-icons/delapouite/mute.svg",
|
||||
startFire: "systems/ds4/assets/icons/game-icons/lorc/campfire.svg",
|
||||
swim: "systems/ds4/assets/icons/game-icons/delapouite/pool-dive.svg",
|
||||
wakeUp: "systems/ds4/assets/icons/game-icons/delapouite/alarm-clock.svg",
|
||||
workMechanism: "systems/ds4/assets/icons/game-icons/lorc/lever.svg",
|
||||
appraise: 'systems/ds4/assets/icons/game-icons/delapouite/two-coins.svg',
|
||||
changeSpell: 'systems/ds4/assets/icons/game-icons/delapouite/card-exchange.svg',
|
||||
climb: 'systems/ds4/assets/icons/game-icons/caro-asercion/mountain-climbing.svg',
|
||||
communicate: 'systems/ds4/assets/icons/game-icons/delapouite/discussion.svg',
|
||||
decipherScript: 'systems/ds4/assets/icons/game-icons/lorc/rune-stone.svg',
|
||||
defend: 'systems/ds4/assets/icons/game-icons/sbed/shield.svg',
|
||||
defyPoison: 'systems/ds4/assets/icons/game-icons/lorc/poison-bottle.svg',
|
||||
disableTraps: 'systems/ds4/assets/icons/game-icons/lorc/wolf-trap.svg',
|
||||
featOfStrength: 'systems/ds4/assets/icons/game-icons/delapouite/biceps.svg',
|
||||
flirt: 'systems/ds4/assets/icons/game-icons/lorc/charm.svg',
|
||||
haggle: 'systems/ds4/assets/icons/game-icons/lorc/cash.svg',
|
||||
hide: 'systems/ds4/assets/icons/game-icons/lorc/hidden.svg',
|
||||
identifyMagic: 'systems/ds4/assets/icons/game-icons/lorc/uncertainty.svg',
|
||||
jump: 'systems/ds4/assets/icons/game-icons/delapouite/jump-across.svg',
|
||||
knowledge: 'systems/ds4/assets/icons/game-icons/delapouite/bookshelf.svg',
|
||||
openLock: 'systems/ds4/assets/icons/game-icons/delapouite/padlock-open.svg',
|
||||
perception: 'systems/ds4/assets/icons/game-icons/lorc/awareness.svg',
|
||||
pickPocket: 'systems/ds4/assets/icons/game-icons/darkzaitev/robber-hand.svg',
|
||||
readTracks: 'systems/ds4/assets/icons/game-icons/delapouite/deer-track.svg',
|
||||
resistDisease: 'systems/ds4/assets/icons/game-icons/lorc/virus.svg',
|
||||
ride: 'systems/ds4/assets/icons/game-icons/delapouite/cavalry.svg',
|
||||
search: 'systems/ds4/assets/icons/game-icons/lorc/magnifying-glass.svg',
|
||||
senseMagic: 'systems/ds4/assets/icons/game-icons/delapouite/sparkles.svg',
|
||||
sneak: 'systems/ds4/assets/icons/game-icons/delapouite/mute.svg',
|
||||
startFire: 'systems/ds4/assets/icons/game-icons/lorc/campfire.svg',
|
||||
swim: 'systems/ds4/assets/icons/game-icons/delapouite/pool-dive.svg',
|
||||
wakeUp: 'systems/ds4/assets/icons/game-icons/delapouite/alarm-clock.svg',
|
||||
workMechanism: 'systems/ds4/assets/icons/game-icons/lorc/lever.svg',
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -437,16 +437,16 @@ export const DS4 = {
|
|||
* Profile info types for handlebars of a character
|
||||
*/
|
||||
characterProfileDTypes: {
|
||||
biography: "String",
|
||||
gender: "String",
|
||||
birthday: "String",
|
||||
birthplace: "String",
|
||||
age: "Number",
|
||||
height: "Number",
|
||||
hairColor: "String",
|
||||
weight: "Number",
|
||||
eyeColor: "String",
|
||||
specialCharacteristics: "String",
|
||||
biography: 'String',
|
||||
gender: 'String',
|
||||
birthday: 'String',
|
||||
birthplace: 'String',
|
||||
age: 'Number',
|
||||
height: 'Number',
|
||||
hairColor: 'String',
|
||||
weight: 'Number',
|
||||
eyeColor: 'String',
|
||||
specialCharacteristics: 'String',
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { getGame } from "../utils/utils";
|
||||
import { getGame } from '../utils/utils';
|
||||
|
||||
export function evaluateCheck(
|
||||
dice: number[],
|
||||
|
@ -41,7 +41,7 @@ function assignSubChecksToDice(
|
|||
const requiredNumberOfDice = getRequiredNumberOfDice(checkTargetNumber);
|
||||
|
||||
if (dice.length !== requiredNumberOfDice || requiredNumberOfDice < 1) {
|
||||
throw new Error(getGame().i18n.localize("DS4.ErrorInvalidNumberOfDice"));
|
||||
throw new Error(getGame().i18n.localize('DS4.ErrorInvalidNumberOfDice'));
|
||||
}
|
||||
|
||||
const checkTargetNumberForLastSubCheck = checkTargetNumber - 20 * (requiredNumberOfDice - 1);
|
||||
|
@ -68,8 +68,7 @@ function findIndexOfSmallestNonCoup(dice: number[], maximumCoupResult: number):
|
|||
.map((die, index): [number, number] => [die, index])
|
||||
.filter((indexedDie) => indexedDie[0] > maximumCoupResult)
|
||||
.reduce(
|
||||
(smallestIndexedDie, indexedDie) =>
|
||||
indexedDie[0] < smallestIndexedDie[0] ? indexedDie : smallestIndexedDie,
|
||||
(smallestIndexedDie, indexedDie) => (indexedDie[0] < smallestIndexedDie[0] ? indexedDie : smallestIndexedDie),
|
||||
[Infinity, -1],
|
||||
)[1];
|
||||
}
|
||||
|
@ -90,7 +89,7 @@ function shouldUseCoupForLastSubCheck(
|
|||
!Number.isInteger(indexOfSmallestNonCoup) ||
|
||||
smallestNonCoup === undefined
|
||||
) {
|
||||
throw new Error("Received an invalid value for the parameter indexOfSmallestNonCoup or indexOfFirstCoup,");
|
||||
throw new Error('Received an invalid value for the parameter indexOfSmallestNonCoup or indexOfFirstCoup,');
|
||||
}
|
||||
return (
|
||||
indexOfFirstCoup !== -1 &&
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DialogWithListeners } from "../apps/dialog-with-listeners";
|
||||
import { DS4 } from "../config";
|
||||
import { getGame } from "../utils/utils";
|
||||
import { DialogWithListeners } from '../apps/dialog-with-listeners';
|
||||
import { DS4 } from '../config';
|
||||
import { getGame } from '../utils/utils';
|
||||
|
||||
/** @typedef {"publicroll" | "gmroll" | "gmroll" | "selfroll"} RollModes */
|
||||
|
||||
|
@ -51,7 +51,7 @@ class CheckFactory {
|
|||
maximumCoupResult: 1,
|
||||
minimumFumbleResult: 20,
|
||||
useSlayingDice: false,
|
||||
rollMode: "publicroll",
|
||||
rollMode: 'publicroll',
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -59,9 +59,7 @@ class CheckFactory {
|
|||
* Execute this check factory.
|
||||
* @returns {Promise<ChatMessage | undefined>} A promise that resolves to the created chat message for the roll */
|
||||
async execute() {
|
||||
const innerFormula = ["ds", this.createCheckTargetNumberModifier(), this.createCoupFumbleModifier()].filterJoin(
|
||||
"",
|
||||
);
|
||||
const innerFormula = ['ds', this.createCheckTargetNumberModifier(), this.createCoupFumbleModifier()].filterJoin('');
|
||||
const formula = this.#options.useSlayingDice ? `{${innerFormula}}x` : innerFormula;
|
||||
const roll = Roll.create(formula);
|
||||
const speaker = this.#options.speaker ?? ChatMessage.getSpeaker();
|
||||
|
@ -82,7 +80,7 @@ class CheckFactory {
|
|||
*/
|
||||
createCheckTargetNumberModifier() {
|
||||
const totalCheckTargetNumber = this.#checkTargetNumber + this.#checkModifier;
|
||||
return totalCheckTargetNumber >= 0 ? `v${this.#checkTargetNumber + this.#checkModifier}` : "v0";
|
||||
return totalCheckTargetNumber >= 0 ? `v${this.#checkTargetNumber + this.#checkModifier}` : 'v0';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,7 +94,7 @@ class CheckFactory {
|
|||
this.#options.maximumCoupResult !== this.constructor.defaultOptions.maximumCoupResult;
|
||||
|
||||
if (isMinimumFumbleResultRequired || isMaximumCoupResultRequired) {
|
||||
return `c${this.#options.maximumCoupResult ?? ""}:${this.#options.minimumFumbleResult ?? ""}`;
|
||||
return `c${this.#options.maximumCoupResult ?? ''}:${this.#options.minimumFumbleResult ?? ''}`;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
@ -119,7 +117,7 @@ export async function createCheckRoll(checkTargetNumber, options = {}) {
|
|||
const newOptions = {
|
||||
maximumCoupResult: interactiveRollData.maximumCoupResult ?? options.maximumCoupResult,
|
||||
minimumFumbleResult: interactiveRollData.minimumFumbleResult ?? options.minimumFumbleResult,
|
||||
useSlayingDice: getGame().settings.get("ds4", "useSlayingDiceForAutomatedChecks"),
|
||||
useSlayingDice: getGame().settings.get('ds4', 'useSlayingDiceForAutomatedChecks'),
|
||||
rollMode: interactiveRollData.rollMode ?? options.rollMode,
|
||||
flavor: options.flavor,
|
||||
flavorData: options.flavorData,
|
||||
|
@ -148,15 +146,15 @@ export async function createCheckRoll(checkTargetNumber, options = {}) {
|
|||
* @returns {Promise<Partial<IntermediateInteractiveRollData>>} A promise that resolves to the data given by the user.
|
||||
*/
|
||||
async function askForInteractiveRollData(checkTargetNumber, options = {}, { template, title } = {}) {
|
||||
const usedTemplate = template ?? "systems/ds4/templates/dialogs/roll-options.hbs";
|
||||
const usedTitle = title ?? getGame().i18n.localize("DS4.DialogRollOptionsDefaultTitle");
|
||||
const usedTemplate = template ?? 'systems/ds4/templates/dialogs/roll-options.hbs';
|
||||
const usedTitle = title ?? getGame().i18n.localize('DS4.DialogRollOptionsDefaultTitle');
|
||||
const id = foundry.utils.randomID();
|
||||
const templateData = {
|
||||
title: usedTitle,
|
||||
checkTargetNumber: checkTargetNumber,
|
||||
maximumCoupResult: options.maximumCoupResult ?? this.constructor.defaultOptions.maximumCoupResult,
|
||||
minimumFumbleResult: options.minimumFumbleResult ?? this.constructor.defaultOptions.minimumFumbleResult,
|
||||
rollMode: options.rollMode ?? getGame().settings.get("core", "rollMode"),
|
||||
rollMode: options.rollMode ?? getGame().settings.get('core', 'rollMode'),
|
||||
rollModes: CONFIG.Dice.rollModes,
|
||||
checkModifiers: Object.entries(DS4.i18n.checkModifiers).map(([key, translation]) => {
|
||||
if (key in DS4.checkModifiers) {
|
||||
|
@ -178,21 +176,21 @@ async function askForInteractiveRollData(checkTargetNumber, options = {}, { temp
|
|||
buttons: {
|
||||
ok: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: getGame().i18n.localize("DS4.GenericOkButton"),
|
||||
label: getGame().i18n.localize('DS4.GenericOkButton'),
|
||||
callback: (html) => {
|
||||
if (!("jquery" in html)) {
|
||||
if (!('jquery' in html)) {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorUnexpectedHtmlType", {
|
||||
exType: "JQuery",
|
||||
realType: "HTMLElement",
|
||||
getGame().i18n.format('DS4.ErrorUnexpectedHtmlType', {
|
||||
exType: 'JQuery',
|
||||
realType: 'HTMLElement',
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
const innerForm = html[0]?.querySelector("form");
|
||||
const innerForm = html[0]?.querySelector('form');
|
||||
if (!innerForm) {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorCouldNotFindHtmlElement", {
|
||||
htmlElement: "form",
|
||||
getGame().i18n.format('DS4.ErrorCouldNotFindHtmlElement', {
|
||||
htmlElement: 'form',
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -202,26 +200,21 @@ async function askForInteractiveRollData(checkTargetNumber, options = {}, { temp
|
|||
},
|
||||
cancel: {
|
||||
icon: '<i class="fas fa-times"></i>',
|
||||
label: getGame().i18n.localize("DS4.GenericCancelButton"),
|
||||
label: getGame().i18n.localize('DS4.GenericCancelButton'),
|
||||
},
|
||||
},
|
||||
default: "ok",
|
||||
default: 'ok',
|
||||
},
|
||||
{
|
||||
activateAdditionalListeners: (html, app) => {
|
||||
const checkModifierCustomFormGroup = html
|
||||
.find(`#check-modifier-custom-${id}`)
|
||||
.parent(".form-group");
|
||||
html.find(`#check-modifier-${id}`).on("change", (event) => {
|
||||
if (
|
||||
event.currentTarget.value === "custom" &&
|
||||
checkModifierCustomFormGroup.hasClass("ds4-hidden")
|
||||
) {
|
||||
checkModifierCustomFormGroup.removeClass("ds4-hidden");
|
||||
app.setPosition({ height: "auto" });
|
||||
} else if (!checkModifierCustomFormGroup.hasClass("ds4-hidden")) {
|
||||
checkModifierCustomFormGroup.addClass("ds4-hidden");
|
||||
app.setPosition({ height: "auto" });
|
||||
const checkModifierCustomFormGroup = html.find(`#check-modifier-custom-${id}`).parent('.form-group');
|
||||
html.find(`#check-modifier-${id}`).on('change', (event) => {
|
||||
if (event.currentTarget.value === 'custom' && checkModifierCustomFormGroup.hasClass('ds4-hidden')) {
|
||||
checkModifierCustomFormGroup.removeClass('ds4-hidden');
|
||||
app.setPosition({ height: 'auto' });
|
||||
} else if (!checkModifierCustomFormGroup.hasClass('ds4-hidden')) {
|
||||
checkModifierCustomFormGroup.addClass('ds4-hidden');
|
||||
app.setPosition({ height: 'auto' });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -239,17 +232,17 @@ async function askForInteractiveRollData(checkTargetNumber, options = {}, { temp
|
|||
* @returns {Partial<IntermediateInteractiveRollData>}
|
||||
*/
|
||||
function parseDialogFormData(formData) {
|
||||
const chosenCheckTargetNumber = parseInt(formData["check-target-number"]?.value);
|
||||
const chosenCheckModifier = formData["check-modifier"]?.value;
|
||||
const chosenCheckTargetNumber = parseInt(formData['check-target-number']?.value);
|
||||
const chosenCheckModifier = formData['check-modifier']?.value;
|
||||
|
||||
const chosenCheckModifierValue =
|
||||
chosenCheckModifier === "custom"
|
||||
? parseInt(formData["check-modifier-custom"]?.value)
|
||||
chosenCheckModifier === 'custom'
|
||||
? parseInt(formData['check-modifier-custom']?.value)
|
||||
: parseInt(chosenCheckModifier);
|
||||
|
||||
const chosenMaximumCoupResult = parseInt(formData["maximum-coup-result"]?.value);
|
||||
const chosenMinimumFumbleResult = parseInt(formData["minimum-fumble-result"]?.value);
|
||||
const chosenRollMode = formData["roll-mode"]?.value;
|
||||
const chosenMaximumCoupResult = parseInt(formData['maximum-coup-result']?.value);
|
||||
const chosenMinimumFumbleResult = parseInt(formData['minimum-fumble-result']?.value);
|
||||
const chosenRollMode = formData['roll-mode']?.value;
|
||||
|
||||
return {
|
||||
checkTargetNumber: Number.isSafeInteger(chosenCheckTargetNumber) ? chosenCheckTargetNumber : undefined,
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { getGame } from "../utils/utils";
|
||||
import { evaluateCheck, getRequiredNumberOfDice } from "./check-evaluation";
|
||||
import { getGame } from '../utils/utils';
|
||||
import { evaluateCheck, getRequiredNumberOfDice } from './check-evaluation';
|
||||
|
||||
/**
|
||||
* Implements DS4 Checks as an emulated "dice throw".
|
||||
|
@ -25,8 +25,8 @@ export class DS4Check extends DiceTerm {
|
|||
});
|
||||
|
||||
// Parse and store check target number
|
||||
const checkTargetNumberModifier = this.modifiers.filter((m) => m[0] === "v")[0];
|
||||
const ctnRgx = new RegExp("v([0-9]+)?");
|
||||
const checkTargetNumberModifier = this.modifiers.filter((m) => m[0] === 'v')[0];
|
||||
const ctnRgx = new RegExp('v([0-9]+)?');
|
||||
const ctnMatch = checkTargetNumberModifier?.match(ctnRgx);
|
||||
if (ctnMatch) {
|
||||
const [parseCheckTargetNumber] = ctnMatch.slice(1);
|
||||
|
@ -38,8 +38,8 @@ export class DS4Check extends DiceTerm {
|
|||
this.number = getRequiredNumberOfDice(this.checkTargetNumber);
|
||||
|
||||
// Parse and store maximumCoupResult and minimumFumbleResult
|
||||
const coupFumbleModifier = this.modifiers.filter((m) => m[0] === "c")[0];
|
||||
const cfmRgx = new RegExp("c([0-9]+)?(:([0-9]+))?");
|
||||
const coupFumbleModifier = this.modifiers.filter((m) => m[0] === 'c')[0];
|
||||
const cfmRgx = new RegExp('c([0-9]+)?(:([0-9]+))?');
|
||||
const cfmMatch = coupFumbleModifier?.match(cfmRgx);
|
||||
if (cfmMatch) {
|
||||
const parseMaximumCoupResult = cfmMatch[1];
|
||||
|
@ -51,11 +51,11 @@ export class DS4Check extends DiceTerm {
|
|||
? parseInt(parseMinimumFumbleResult)
|
||||
: DS4Check.DEFAULT_MINIMUM_FUMBLE_RESULT;
|
||||
if (this.minimumFumbleResult <= this.maximumCoupResult)
|
||||
throw new SyntaxError(getGame().i18n.localize("DS4.ErrorDiceCoupFumbleOverlap"));
|
||||
throw new SyntaxError(getGame().i18n.localize('DS4.ErrorDiceCoupFumbleOverlap'));
|
||||
}
|
||||
|
||||
// Parse and store no fumble
|
||||
const noFumbleModifier = this.modifiers.filter((m) => m[0] === "n")[0];
|
||||
const noFumbleModifier = this.modifiers.filter((m) => m[0] === 'n')[0];
|
||||
if (noFumbleModifier) {
|
||||
this.canFumble = false;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ export class DS4Check extends DiceTerm {
|
|||
|
||||
/** @override */
|
||||
get expression() {
|
||||
return `ds${this.modifiers.join("")}`;
|
||||
return `ds${this.modifiers.join('')}`;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
|
@ -121,13 +121,13 @@ export class DS4Check extends DiceTerm {
|
|||
* @override
|
||||
*/
|
||||
getResultCSS(result) {
|
||||
return super.getResultCSS(result).filter((cssClass) => cssClass !== "min" && cssClass !== "max");
|
||||
return super.getResultCSS(result).filter((cssClass) => cssClass !== 'min' && cssClass !== 'max');
|
||||
}
|
||||
|
||||
static DEFAULT_CHECK_TARGET_NUMBER = 10;
|
||||
static DEFAULT_MAXIMUM_COUP_RESULT = 1;
|
||||
static DEFAULT_MINIMUM_FUMBLE_RESULT = 20;
|
||||
static DENOMINATION = "s";
|
||||
static DENOMINATION = 's';
|
||||
static MODIFIERS = {
|
||||
c: () => undefined, // Modifier is consumed in constructor for maximumCoupResult / minimumFumbleResult
|
||||
v: () => undefined, // Modifier is consumed in constructor for checkTargetNumber
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { getGame } from "../utils/utils";
|
||||
import { DS4Check } from "./check";
|
||||
import { getGame } from '../utils/utils';
|
||||
import { DS4Check } from './check';
|
||||
|
||||
export class DS4Roll extends Roll {
|
||||
/** @override */
|
||||
static CHAT_TEMPLATE = "systems/ds4/templates/dice/roll.hbs";
|
||||
static CHAT_TEMPLATE = 'systems/ds4/templates/dice/roll.hbs';
|
||||
|
||||
/**
|
||||
* @override
|
||||
|
@ -21,11 +21,11 @@ export class DS4Roll extends Roll {
|
|||
const isCoup = firstDiceTerm instanceof DS4Check && firstDiceTerm.coup;
|
||||
const isFumble = firstDiceTerm instanceof DS4Check && firstDiceTerm.fumble;
|
||||
const chatData = {
|
||||
formula: isPrivate ? "???" : this._formula,
|
||||
formula: isPrivate ? '???' : this._formula,
|
||||
flavor: isPrivate ? null : flavor,
|
||||
user: getGame().user?.id,
|
||||
tooltip: isPrivate ? "" : await this.getTooltip(),
|
||||
total: isPrivate ? "?" : Math.round((this.total ?? 0) * 100) / 100,
|
||||
tooltip: isPrivate ? '' : await this.getTooltip(),
|
||||
total: isPrivate ? '?' : Math.round((this.total ?? 0) * 100) / 100,
|
||||
isCoup: isPrivate ? null : isCoup,
|
||||
isFumble: isPrivate ? null : isFumble,
|
||||
};
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { getGame } from "../utils/utils";
|
||||
import { DS4Check } from "./check";
|
||||
import { getGame } from '../utils/utils';
|
||||
import { DS4Check } from './check';
|
||||
|
||||
export function registerSlayingDiceModifier() {
|
||||
PoolTerm.MODIFIERS.x = slay;
|
||||
|
@ -31,6 +31,6 @@ function slay(modifier) {
|
|||
this.results.push({ result: additionalRoll.total ?? 0, active: true });
|
||||
this.terms.push(formula);
|
||||
}
|
||||
if (checked > 1000) throw new Error(getGame().i18n.localize("DS4.ErrorSlayingDiceRecursionLimitExceeded"));
|
||||
if (checked > 1000) throw new Error(getGame().i18n.localize('DS4.ErrorSlayingDiceRecursionLimitExceeded'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { mathEvaluator } from "../expression-evaluation/evaluator";
|
||||
import { getGame } from "../utils/utils";
|
||||
import { mathEvaluator } from '../expression-evaluation/evaluator';
|
||||
import { getGame } from '../utils/utils';
|
||||
|
||||
/**
|
||||
* @typedef {object} ItemEffectConfig
|
||||
|
@ -26,7 +26,7 @@ export class DS4ActiveEffect extends ActiveEffect {
|
|||
/**
|
||||
* A fallback icon that can be used if no icon is defined for the effect.
|
||||
*/
|
||||
static FALLBACK_ICON = "icons/svg/aura.svg";
|
||||
static FALLBACK_ICON = 'icons/svg/aura.svg';
|
||||
|
||||
/**
|
||||
* A cached reference to the source document to avoid recurring database lookups
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4 } from "../../config";
|
||||
import { DS4 } from '../../config';
|
||||
|
||||
import type { ModifiableDataBaseTotal, ResourceDataBaseTotalMax } from "../common/common-data";
|
||||
import type { ModifiableDataBaseTotal, ResourceDataBaseTotalMax } from '../common/common-data';
|
||||
|
||||
export interface DS4ActorDataPropertiesDataBase {
|
||||
attributes: DS4ActorDataPropertiesDataAttributes;
|
||||
|
@ -25,7 +25,7 @@ type DS4ActorDataPropertiesDataAttributes = {
|
|||
type DS4ActorDataPropertiesDataTraits = { [Key in keyof typeof DS4.i18n.traits]: ModifiableDataBaseTotal<number> };
|
||||
|
||||
type DS4ActorDataPropertiesDataCombatValues = {
|
||||
[Key in keyof typeof DS4.i18n.combatValues]: Key extends "hitPoints"
|
||||
[Key in keyof typeof DS4.i18n.combatValues]: Key extends 'hitPoints'
|
||||
? ResourceDataBaseTotalMax<number>
|
||||
: ModifiableDataBaseTotal<number>;
|
||||
};
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4CharacterDataProperties } from "./character/character-data-properties";
|
||||
import type { DS4CreatureDataProperties } from "./creature/creature-data-properties";
|
||||
import type { DS4CharacterDataProperties } from './character/character-data-properties';
|
||||
import type { DS4CreatureDataProperties } from './creature/creature-data-properties';
|
||||
|
||||
declare global {
|
||||
interface DataConfig {
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4 } from "../../config";
|
||||
import { DS4 } from '../../config';
|
||||
|
||||
import type { ModifiableData, ModifiableDataBase, ResourceData } from "../common/common-data";
|
||||
import type { ModifiableData, ModifiableDataBase, ResourceData } from '../common/common-data';
|
||||
|
||||
export interface DS4ActorDataSourceDataBase {
|
||||
attributes: DS4ActorDataSourceDataAttributes;
|
||||
|
@ -32,9 +32,7 @@ export function isTrait(value: unknown): value is Trait {
|
|||
}
|
||||
|
||||
type DS4ActorDataSourceDataCombatValues = {
|
||||
[Key in keyof typeof DS4.i18n.combatValues]: Key extends "hitPoints"
|
||||
? ResourceData<number>
|
||||
: ModifiableData<number>;
|
||||
[Key in keyof typeof DS4.i18n.combatValues]: Key extends 'hitPoints' ? ResourceData<number> : ModifiableData<number>;
|
||||
};
|
||||
|
||||
type CombatValue = keyof DS4ActorDataSourceDataCombatValues;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4CharacterDataSource } from "./character/character-data-source";
|
||||
import type { DS4CreatureDataSource } from "./creature/creature-data-source";
|
||||
import type { DS4CharacterDataSource } from './character/character-data-source';
|
||||
import type { DS4CreatureDataSource } from './creature/creature-data-source';
|
||||
|
||||
declare global {
|
||||
interface SourceConfig {
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4 } from "../../config";
|
||||
import { createCheckRoll } from "../../dice/check-factory";
|
||||
import { mathEvaluator } from "../../expression-evaluation/evaluator";
|
||||
import { logger } from "../../utils/logger";
|
||||
import { getGame } from "../../utils/utils";
|
||||
import { DS4ActiveEffect } from "../active-effect";
|
||||
import { isAttribute, isTrait } from "./actor-data-source-base";
|
||||
import { DS4 } from '../../config';
|
||||
import { createCheckRoll } from '../../dice/check-factory';
|
||||
import { mathEvaluator } from '../../expression-evaluation/evaluator';
|
||||
import { logger } from '../../utils/logger';
|
||||
import { getGame } from '../../utils/utils';
|
||||
import { DS4ActiveEffect } from '../active-effect';
|
||||
import { isAttribute, isTrait } from './actor-data-source-base';
|
||||
|
||||
/**
|
||||
* The Actor class for DS4
|
||||
|
@ -39,9 +39,7 @@ export class DS4Actor extends Actor {
|
|||
maximumCoupResult: 1,
|
||||
};
|
||||
|
||||
Object.values(this.system.attributes).forEach(
|
||||
(attribute) => (attribute.total = attribute.base + attribute.mod),
|
||||
);
|
||||
Object.values(this.system.attributes).forEach((attribute) => (attribute.total = attribute.base + attribute.mod));
|
||||
|
||||
Object.values(this.system.traits).forEach((trait) => (trait.total = trait.base + trait.mod));
|
||||
}
|
||||
|
@ -85,11 +83,11 @@ export class DS4Actor extends Actor {
|
|||
const shouldEffectBeAppliedToItem = (effect, item) => {
|
||||
const { applyToItems, itemName, condition } = effect.flags.ds4?.itemEffectConfig ?? {};
|
||||
|
||||
if (!applyToItems || (itemName !== undefined && itemName !== "" && itemName !== item.name)) {
|
||||
if (!applyToItems || (itemName !== undefined && itemName !== '' && itemName !== item.name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (condition !== undefined && condition !== "") {
|
||||
if (condition !== undefined && condition !== '') {
|
||||
try {
|
||||
const replacedCondition = DS4Actor.replaceFormulaData(condition, { item, actor: this, effect });
|
||||
return replacedCondition !== undefined ? Boolean(mathEvaluator.evaluate(replacedCondition)) : false;
|
||||
|
@ -158,7 +156,7 @@ export class DS4Actor extends Actor {
|
|||
this.applyActiveEffectsToItem(item);
|
||||
}
|
||||
for (const item of this.items) {
|
||||
if (item.type === "talent") continue;
|
||||
if (item.type === 'talent') continue;
|
||||
this.applyActiveEffectsToItem(item);
|
||||
}
|
||||
}
|
||||
|
@ -184,8 +182,7 @@ export class DS4Actor extends Actor {
|
|||
this,
|
||||
this.actorEffects,
|
||||
(change) =>
|
||||
!this.derivedDataProperties.includes(change.key) &&
|
||||
!this.finalDerivedDataProperties.includes(change.key),
|
||||
!this.derivedDataProperties.includes(change.key) && !this.finalDerivedDataProperties.includes(change.key),
|
||||
).forEach(this.newStatuses.add.bind(this.newStatuses));
|
||||
}
|
||||
|
||||
|
@ -218,7 +215,7 @@ export class DS4Actor extends Actor {
|
|||
(combatValue) => `system.combatValues.${combatValue}.total`,
|
||||
);
|
||||
const checkProperties = Object.keys(DS4.i18n.checks)
|
||||
.filter((check) => check !== "defend")
|
||||
.filter((check) => check !== 'defend')
|
||||
.map((check) => `system.checks.${check}`);
|
||||
return combatValueProperties.concat(checkProperties);
|
||||
}
|
||||
|
@ -254,7 +251,7 @@ export class DS4Actor extends Actor {
|
|||
Object.values(this.system.attributes).forEach((attribute) => (attribute.total = Math.ceil(attribute.total)));
|
||||
Object.values(this.system.traits).forEach((trait) => (trait.total = Math.ceil(trait.total)));
|
||||
Object.entries(this.system.combatValues)
|
||||
.filter(([key]) => key !== "movement")
|
||||
.filter(([key]) => key !== 'movement')
|
||||
.forEach(([, combatValue]) => (combatValue.total = Math.ceil(combatValue.total)));
|
||||
Object.keys(this.system.checks).forEach((key) => {
|
||||
this.system.checks[key] = Math.ceil(this.system.checks[key]);
|
||||
|
@ -270,7 +267,7 @@ export class DS4Actor extends Actor {
|
|||
* @type {string[]}
|
||||
*/
|
||||
get finalDerivedDataProperties() {
|
||||
return ["system.combatValues.hitPoints.max", "system.checks.defend"];
|
||||
return ['system.combatValues.hitPoints.max', 'system.checks.defend'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -278,7 +275,7 @@ export class DS4Actor extends Actor {
|
|||
* @type {import("../item/item-data-source").ItemType[]}
|
||||
*/
|
||||
get ownableItemTypes() {
|
||||
return ["weapon", "armor", "shield", "equipment", "loot", "spell"];
|
||||
return ['weapon', 'armor', 'shield', 'equipment', 'loot', 'spell'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -330,7 +327,7 @@ export class DS4Actor extends Actor {
|
|||
*/
|
||||
get armorValueSpellMalusOfEquippedItems() {
|
||||
return this.equippedItemsWithArmor
|
||||
.filter((item) => !(item.type === "armor" && ["cloth", "natural"].includes(item.system.armorMaterialType)))
|
||||
.filter((item) => !(item.type === 'armor' && ['cloth', 'natural'].includes(item.system.armorMaterialType)))
|
||||
.reduce((sum, item) => sum + item.system.armorValue, 0);
|
||||
}
|
||||
|
||||
|
@ -340,7 +337,7 @@ export class DS4Actor extends Actor {
|
|||
* @protected
|
||||
*/
|
||||
get equippedItemsWithArmor() {
|
||||
return this.items.filter((item) => (item.type === "armor" || item.type === "shield") && item.system.equipped);
|
||||
return this.items.filter((item) => (item.type === 'armor' || item.type === 'shield') && item.system.equipped);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -360,8 +357,7 @@ export class DS4Actor extends Actor {
|
|||
disableTraps: system.attributes.mind.total + system.traits.dexterity.total,
|
||||
featOfStrength: system.attributes.body.total + system.traits.strength.total,
|
||||
flirt: system.attributes.mind.total + system.traits.aura.total,
|
||||
haggle:
|
||||
system.attributes.mind.total + Math.max(system.traits.intellect.total, system.traits.intellect.total),
|
||||
haggle: system.attributes.mind.total + Math.max(system.traits.intellect.total, system.traits.intellect.total),
|
||||
hide: system.attributes.mobility.total + system.traits.agility.total,
|
||||
identifyMagic: system.attributes.mind.total + system.traits.intellect.total,
|
||||
jump: system.attributes.mobility.total + system.traits.agility.total,
|
||||
|
@ -408,7 +404,7 @@ export class DS4Actor extends Actor {
|
|||
}
|
||||
|
||||
// Call a hook to handle token resource bar updates
|
||||
const allowed = Hooks.call("modifyTokenAttribute", { attribute, value, isDelta, isBar }, updates);
|
||||
const allowed = Hooks.call('modifyTokenAttribute', { attribute, value, isDelta, isBar }, updates);
|
||||
return allowed !== false ? this.update(updates) : this;
|
||||
}
|
||||
|
||||
|
@ -421,10 +417,10 @@ export class DS4Actor extends Actor {
|
|||
async rollCheck(check, options = {}) {
|
||||
const speaker = ChatMessage.getSpeaker({ actor: this, ...options.speaker });
|
||||
await createCheckRoll(this.system.checks[check], {
|
||||
rollMode: getGame().settings.get("core", "rollMode"),
|
||||
rollMode: getGame().settings.get('core', 'rollMode'),
|
||||
maximumCoupResult: this.system.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: this.system.rolling.minimumFumbleResult,
|
||||
flavor: "DS4.ActorCheckFlavor",
|
||||
flavor: 'DS4.ActorCheckFlavor',
|
||||
flavorData: { actor: speaker.alias ?? this.name, check: DS4.i18nKeys.checks[check] },
|
||||
speaker,
|
||||
});
|
||||
|
@ -445,10 +441,10 @@ export class DS4Actor extends Actor {
|
|||
const checkTargetNumber = this.system.attributes[attribute].total + this.system.traits[trait].total;
|
||||
const speaker = ChatMessage.getSpeaker({ actor: this, ...options.speaker });
|
||||
await createCheckRoll(checkTargetNumber, {
|
||||
rollMode: getGame().settings.get("core", "rollMode"),
|
||||
rollMode: getGame().settings.get('core', 'rollMode'),
|
||||
maximumCoupResult: this.system.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: this.system.rolling.minimumFumbleResult,
|
||||
flavor: "DS4.ActorGenericCheckFlavor",
|
||||
flavor: 'DS4.ActorGenericCheckFlavor',
|
||||
flavorData: {
|
||||
actor: speaker.alias ?? this.name,
|
||||
attribute: DS4.i18n.attributes[attribute],
|
||||
|
@ -464,14 +460,14 @@ export class DS4Actor extends Actor {
|
|||
* @protected
|
||||
*/
|
||||
async selectAttributeAndTrait() {
|
||||
const attributeIdentifier = "attribute-trait-selection-attribute";
|
||||
const traitIdentifier = "attribute-trait-selection-trait";
|
||||
const attributeIdentifier = 'attribute-trait-selection-attribute';
|
||||
const traitIdentifier = 'attribute-trait-selection-trait';
|
||||
return Dialog.prompt({
|
||||
title: getGame().i18n.localize("DS4.DialogAttributeTraitSelection"),
|
||||
content: await renderTemplate("systems/ds4/templates/dialogs/simple-select-form.hbs", {
|
||||
title: getGame().i18n.localize('DS4.DialogAttributeTraitSelection'),
|
||||
content: await renderTemplate('systems/ds4/templates/dialogs/simple-select-form.hbs', {
|
||||
selects: [
|
||||
{
|
||||
label: getGame().i18n.localize("DS4.Attribute"),
|
||||
label: getGame().i18n.localize('DS4.Attribute'),
|
||||
identifier: attributeIdentifier,
|
||||
options: Object.fromEntries(
|
||||
Object.entries(DS4.i18n.attributes).map(([attribute, translation]) => [
|
||||
|
@ -481,7 +477,7 @@ export class DS4Actor extends Actor {
|
|||
),
|
||||
},
|
||||
{
|
||||
label: getGame().i18n.localize("DS4.Trait"),
|
||||
label: getGame().i18n.localize('DS4.Trait'),
|
||||
identifier: traitIdentifier,
|
||||
options: Object.fromEntries(
|
||||
Object.entries(DS4.i18n.traits).map(([trait, translation]) => [
|
||||
|
@ -492,27 +488,27 @@ export class DS4Actor extends Actor {
|
|||
},
|
||||
],
|
||||
}),
|
||||
label: getGame().i18n.localize("DS4.GenericOkButton"),
|
||||
label: getGame().i18n.localize('DS4.GenericOkButton'),
|
||||
callback: (html) => {
|
||||
const selectedAttribute = html.find(`#${attributeIdentifier}`).val();
|
||||
if (!isAttribute(selectedAttribute)) {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorUnexpectedAttribute", {
|
||||
getGame().i18n.format('DS4.ErrorUnexpectedAttribute', {
|
||||
actualAttribute: selectedAttribute,
|
||||
expectedTypes: Object.keys(DS4.i18n.attributes)
|
||||
.map((attribute) => `'${attribute}'`)
|
||||
.join(", "),
|
||||
.join(', '),
|
||||
}),
|
||||
);
|
||||
}
|
||||
const selectedTrait = html.find(`#${traitIdentifier}`).val();
|
||||
if (!isTrait(selectedTrait)) {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorUnexpectedTrait", {
|
||||
getGame().i18n.format('DS4.ErrorUnexpectedTrait', {
|
||||
actualTrait: selectedTrait,
|
||||
expectedTypes: Object.keys(DS4.i18n.traits)
|
||||
.map((attribute) => `'${attribute}'`)
|
||||
.join(", "),
|
||||
.join(', '),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,17 +2,17 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ActorDataPropertiesDataBase } from "../actor-data-properties-base";
|
||||
import type { DS4ActorDataPropertiesDataBase } from '../actor-data-properties-base';
|
||||
import type {
|
||||
DS4CharacterDataSourceDataBaseInfo,
|
||||
DS4CharacterDataSourceDataCurrency,
|
||||
DS4CharacterDataSourceDataProfile,
|
||||
DS4CharacterDataSourceDataProgression,
|
||||
DS4CharacterDataSourceDataSlayerPoints,
|
||||
} from "./character-data-source";
|
||||
} from './character-data-source';
|
||||
|
||||
export interface DS4CharacterDataProperties {
|
||||
type: "character";
|
||||
type: 'character';
|
||||
data: DS4CharacterDataPropertiesData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { UsableResource } from "../../common/common-data";
|
||||
import type { DS4ActorDataSourceDataBase } from "../actor-data-source-base";
|
||||
import type { UsableResource } from '../../common/common-data';
|
||||
import type { DS4ActorDataSourceDataBase } from '../actor-data-source-base';
|
||||
|
||||
export interface DS4CharacterDataSource {
|
||||
type: "character";
|
||||
type: 'character';
|
||||
data: DS4CharacterDataSourceData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Actor } from "../actor";
|
||||
import { DS4Actor } from '../actor';
|
||||
|
||||
export class DS4Character extends DS4Actor {
|
||||
/** @override */
|
||||
|
@ -13,11 +13,11 @@ export class DS4Character extends DS4Actor {
|
|||
|
||||
/** @override */
|
||||
get finalDerivedDataProperties() {
|
||||
return [...super.finalDerivedDataProperties, "system.slayerPoints.max"];
|
||||
return [...super.finalDerivedDataProperties, 'system.slayerPoints.max'];
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get ownableItemTypes() {
|
||||
return [...super.ownableItemTypes, "talent", "racialAbility", "language", "alphabet"];
|
||||
return [...super.ownableItemTypes, 'talent', 'racialAbility', 'language', 'alphabet'];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ActorDataPropertiesDataBase } from "../actor-data-properties-base";
|
||||
import type { DS4CreatureDataSourceDataBaseInfo } from "./creature-data-source";
|
||||
import type { DS4ActorDataPropertiesDataBase } from '../actor-data-properties-base';
|
||||
import type { DS4CreatureDataSourceDataBaseInfo } from './creature-data-source';
|
||||
|
||||
export interface DS4CreatureDataProperties {
|
||||
type: "creature";
|
||||
type: 'creature';
|
||||
data: DS4CreatureDataPropertiesData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4 } from "../../../config";
|
||||
import type { DS4ActorDataSourceDataBase } from "../actor-data-source-base";
|
||||
import type { DS4 } from '../../../config';
|
||||
import type { DS4ActorDataSourceDataBase } from '../actor-data-source-base';
|
||||
|
||||
export interface DS4CreatureDataSource {
|
||||
type: "creature";
|
||||
type: 'creature';
|
||||
data: DS4CreatureDataSourceData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Actor } from "../actor";
|
||||
import { DS4Actor } from '../actor';
|
||||
|
||||
import type { ItemType } from "../../item/item-data-source";
|
||||
import type { ItemType } from '../../item/item-data-source';
|
||||
|
||||
export class DS4Creature extends DS4Actor {
|
||||
override get ownableItemTypes(): Array<ItemType> {
|
||||
return [...super.ownableItemTypes, "specialCreatureAbility"];
|
||||
return [...super.ownableItemTypes, 'specialCreatureAbility'];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { getGame } from "../../utils/utils";
|
||||
import { DS4Actor } from "./actor";
|
||||
import { DS4Character } from "./character/character";
|
||||
import { DS4Creature } from "./creature/creature";
|
||||
import { getGame } from '../../utils/utils';
|
||||
import { DS4Actor } from './actor';
|
||||
import { DS4Character } from './character/character';
|
||||
import { DS4Creature } from './creature/creature';
|
||||
|
||||
const handler = {
|
||||
/**
|
||||
|
@ -14,12 +14,12 @@ const handler = {
|
|||
*/
|
||||
construct(_, args) {
|
||||
switch (args[0]?.type) {
|
||||
case "character":
|
||||
case 'character':
|
||||
return new DS4Character(...args);
|
||||
case "creature":
|
||||
case 'creature':
|
||||
return new DS4Creature(...args);
|
||||
default:
|
||||
throw new Error(getGame().i18n.format("DS4.ErrorInvalidActorType", { type: args[0]?.type }));
|
||||
throw new Error(getGame().i18n.format('DS4.ErrorInvalidActorType', { type: args[0]?.type }));
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { getGame } from "../utils/utils";
|
||||
import { getGame } from '../utils/utils';
|
||||
|
||||
/**
|
||||
* @typedef {object} DS4ChatMessageFlags
|
||||
|
@ -22,7 +22,7 @@ export class DS4ChatMessage extends ChatMessage {
|
|||
const flavorData = Object.fromEntries(
|
||||
Object.entries(this.flags.ds4?.flavorData ?? {}).map(([key, value]) => [
|
||||
key,
|
||||
typeof value === "string" ? game.i18n.localize(value) : value,
|
||||
typeof value === 'string' ? game.i18n.localize(value) : value,
|
||||
]),
|
||||
);
|
||||
this.flavor = game.i18n.format(this.flavor, flavorData);
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4AlphabetDataSourceData } from "./alphabet-data-source";
|
||||
import type { DS4ItemDataPropertiesDataRollable } from '../item-data-properties-base';
|
||||
import type { DS4AlphabetDataSourceData } from './alphabet-data-source';
|
||||
|
||||
export interface DS4AlphabetDataProperties {
|
||||
type: "alphabet";
|
||||
type: 'alphabet';
|
||||
data: DS4AlphabetDataPropertiesData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataSourceDataBase } from "../item-data-source-base";
|
||||
import type { DS4ItemDataSourceDataBase } from '../item-data-source-base';
|
||||
|
||||
export interface DS4AlphabetDataSource {
|
||||
type: "alphabet";
|
||||
type: 'alphabet';
|
||||
data: DS4AlphabetDataSourceData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
import { DS4Item } from '../item';
|
||||
|
||||
export class DS4Alphabet extends DS4Item {}
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4ArmorDataSourceData } from "./armor-data-source";
|
||||
import type { DS4ItemDataPropertiesDataRollable } from '../item-data-properties-base';
|
||||
import type { DS4ArmorDataSourceData } from './armor-data-source';
|
||||
|
||||
export interface DS4ArmorDataProperties {
|
||||
type: "armor";
|
||||
type: 'armor';
|
||||
data: DS4ArmorDataPropertiesData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4 } from "../../../config";
|
||||
import type { DS4 } from '../../../config';
|
||||
import type {
|
||||
DS4ItemDataSourceDataBase,
|
||||
DS4ItemDataSourceDataEquipable,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
DS4ItemDataSourceDataProtective,
|
||||
} from "../item-data-source-base";
|
||||
} from '../item-data-source-base';
|
||||
|
||||
export interface DS4ArmorDataSource {
|
||||
type: "armor";
|
||||
type: 'armor';
|
||||
data: DS4ArmorDataSourceData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
import { DS4Item } from '../item';
|
||||
|
||||
export class DS4Armor extends DS4Item {}
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4EquipmentDataSourceData } from "./equipment-data-source";
|
||||
import type { DS4ItemDataPropertiesDataRollable } from '../item-data-properties-base';
|
||||
import type { DS4EquipmentDataSourceData } from './equipment-data-source';
|
||||
|
||||
export interface DS4EquipmentDataProperties {
|
||||
type: "equipment";
|
||||
type: 'equipment';
|
||||
data: DS4EquipmentDataPropertiesData;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@ import type {
|
|||
DS4ItemDataSourceDataBase,
|
||||
DS4ItemDataSourceDataEquipable,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
} from "../item-data-source-base";
|
||||
} from '../item-data-source-base';
|
||||
|
||||
export interface DS4EquipmentDataSource {
|
||||
type: "equipment";
|
||||
type: 'equipment';
|
||||
data: DS4EquipmentDataSourceData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
import { DS4Item } from '../item';
|
||||
|
||||
export class DS4Equipment extends DS4Item {}
|
||||
|
|
|
@ -2,17 +2,17 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4AlphabetDataProperties } from "./alphabet/alphabet-data-properties";
|
||||
import type { DS4ArmorDataProperties } from "./armor/armor-data-properties";
|
||||
import type { DS4EquipmentDataProperties } from "./equipment/equipment-data-properties";
|
||||
import type { DS4LanguageDataProperties } from "./language/language-data-properties";
|
||||
import type { DS4LootDataProperties } from "./loot/loot-data-properties";
|
||||
import type { DS4RacialAbilityDataProperties } from "./racial-ability/racial-ability-data-properties";
|
||||
import type { DS4ShieldDataProperties } from "./shield/shield-data-properties";
|
||||
import type { DS4SpecialCreatureAbilityDataProperties } from "./special-creature-ability/special-creature-ability-data-properties";
|
||||
import type { DS4SpellDataProperties } from "./spell/spell-data-properties";
|
||||
import type { DS4TalentDataProperties } from "./talent/talent-data-properties";
|
||||
import type { DS4WeaponDataProperties } from "./weapon/weapon-data-properties";
|
||||
import type { DS4AlphabetDataProperties } from './alphabet/alphabet-data-properties';
|
||||
import type { DS4ArmorDataProperties } from './armor/armor-data-properties';
|
||||
import type { DS4EquipmentDataProperties } from './equipment/equipment-data-properties';
|
||||
import type { DS4LanguageDataProperties } from './language/language-data-properties';
|
||||
import type { DS4LootDataProperties } from './loot/loot-data-properties';
|
||||
import type { DS4RacialAbilityDataProperties } from './racial-ability/racial-ability-data-properties';
|
||||
import type { DS4ShieldDataProperties } from './shield/shield-data-properties';
|
||||
import type { DS4SpecialCreatureAbilityDataProperties } from './special-creature-ability/special-creature-ability-data-properties';
|
||||
import type { DS4SpellDataProperties } from './spell/spell-data-properties';
|
||||
import type { DS4TalentDataProperties } from './talent/talent-data-properties';
|
||||
import type { DS4WeaponDataProperties } from './weapon/weapon-data-properties';
|
||||
|
||||
declare global {
|
||||
interface DataConfig {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4 } from "../../config";
|
||||
import type { DS4 } from '../../config';
|
||||
|
||||
export interface DS4ItemDataSourceDataBase {
|
||||
description: string;
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4 } from "../../config";
|
||||
import type { DS4AlphabetDataSource } from "./alphabet/alphabet-data-source";
|
||||
import type { DS4ArmorDataSource } from "./armor/armor-data-source";
|
||||
import type { DS4EquipmentDataSource } from "./equipment/equipment-data-source";
|
||||
import type { DS4LanguageDataSource } from "./language/language-data-source";
|
||||
import type { DS4LootDataSource } from "./loot/loot-data-source";
|
||||
import type { DS4RacialAbilityDataSource } from "./racial-ability/racial-ability-data-source";
|
||||
import type { DS4ShieldDataSource } from "./shield/shield-data-source";
|
||||
import type { DS4SpecialCreatureAbilityDataSource } from "./special-creature-ability/special-creature-ability-data-source";
|
||||
import type { DS4SpellDataSource } from "./spell/spell-data-source";
|
||||
import type { DS4TalentDataSource } from "./talent/talent-data-source";
|
||||
import type { DS4WeaponDataSource } from "./weapon/weapon-data-source";
|
||||
import type { DS4 } from '../../config';
|
||||
import type { DS4AlphabetDataSource } from './alphabet/alphabet-data-source';
|
||||
import type { DS4ArmorDataSource } from './armor/armor-data-source';
|
||||
import type { DS4EquipmentDataSource } from './equipment/equipment-data-source';
|
||||
import type { DS4LanguageDataSource } from './language/language-data-source';
|
||||
import type { DS4LootDataSource } from './loot/loot-data-source';
|
||||
import type { DS4RacialAbilityDataSource } from './racial-ability/racial-ability-data-source';
|
||||
import type { DS4ShieldDataSource } from './shield/shield-data-source';
|
||||
import type { DS4SpecialCreatureAbilityDataSource } from './special-creature-ability/special-creature-ability-data-source';
|
||||
import type { DS4SpellDataSource } from './spell/spell-data-source';
|
||||
import type { DS4TalentDataSource } from './talent/talent-data-source';
|
||||
import type { DS4WeaponDataSource } from './weapon/weapon-data-source';
|
||||
|
||||
declare global {
|
||||
interface SourceConfig {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { getGame } from "../../utils/utils";
|
||||
import { getGame } from '../../utils/utils';
|
||||
|
||||
/**
|
||||
* The Item class for DS4
|
||||
|
@ -25,7 +25,7 @@ export class DS4Item extends Item {
|
|||
* @returns {boolean} Whether the item is a non-equpped equibale or not
|
||||
*/
|
||||
isNonEquippedEuipable() {
|
||||
return "equipped" in this.system && !this.system.equipped;
|
||||
return 'equipped' in this.system && !this.system.equipped;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,7 +41,7 @@ export class DS4Item extends Item {
|
|||
* @returns {import("../item/item-data-source").ItemType[]} The rollable item types
|
||||
*/
|
||||
static get rollableItemTypes() {
|
||||
return ["weapon", "spell"];
|
||||
return ['weapon', 'spell'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,6 +52,6 @@ export class DS4Item extends Item {
|
|||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
async roll(options = {}) {
|
||||
throw new Error(getGame().i18n.format("DS4.ErrorRollingForItemTypeNotPossible", { type: this.type }));
|
||||
throw new Error(getGame().i18n.format('DS4.ErrorRollingForItemTypeNotPossible', { type: this.type }));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4LanguageDataSourceData } from "./language-data-source";
|
||||
import type { DS4ItemDataPropertiesDataRollable } from '../item-data-properties-base';
|
||||
import type { DS4LanguageDataSourceData } from './language-data-source';
|
||||
|
||||
export interface DS4LanguageDataProperties {
|
||||
type: "language";
|
||||
type: 'language';
|
||||
data: DS4LanguageDataPropertiesData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataSourceDataBase } from "../item-data-source-base";
|
||||
import type { DS4ItemDataSourceDataBase } from '../item-data-source-base';
|
||||
|
||||
export interface DS4LanguageDataSource {
|
||||
type: "language";
|
||||
type: 'language';
|
||||
data: DS4LanguageDataSourceData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
import { DS4Item } from '../item';
|
||||
|
||||
export class DS4Language extends DS4Item {}
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4LootDataSourceData } from "./loot-data-source";
|
||||
import type { DS4ItemDataPropertiesDataRollable } from '../item-data-properties-base';
|
||||
import type { DS4LootDataSourceData } from './loot-data-source';
|
||||
|
||||
export interface DS4LootDataProperties {
|
||||
type: "loot";
|
||||
type: 'loot';
|
||||
data: DS4LootDataPropertiesData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataSourceDataBase, DS4ItemDataSourceDataPhysical } from "../item-data-source-base";
|
||||
import type { DS4ItemDataSourceDataBase, DS4ItemDataSourceDataPhysical } from '../item-data-source-base';
|
||||
|
||||
export interface DS4LootDataSource {
|
||||
type: "loot";
|
||||
type: 'loot';
|
||||
data: DS4LootDataSourceData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
import { DS4Item } from '../item';
|
||||
|
||||
export class DS4Loot extends DS4Item {}
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { getGame } from "../../utils/utils";
|
||||
import { DS4Alphabet } from "./alphabet/alphabet";
|
||||
import { DS4Armor } from "./armor/armor";
|
||||
import { DS4Equipment } from "./equipment/equipment";
|
||||
import { DS4Item } from "./item";
|
||||
import { DS4Language } from "./language/language";
|
||||
import { DS4Loot } from "./loot/loot";
|
||||
import { DS4RacialAbility } from "./racial-ability/racial-ability";
|
||||
import { DS4Shield } from "./shield/shield";
|
||||
import { DS4SpecialCreatureAbility } from "./special-creature-ability/special-creature-ability";
|
||||
import { DS4Spell } from "./spell/spell";
|
||||
import { DS4Talent } from "./talent/talent";
|
||||
import { DS4Weapon } from "./weapon/weapon";
|
||||
import { getGame } from '../../utils/utils';
|
||||
import { DS4Alphabet } from './alphabet/alphabet';
|
||||
import { DS4Armor } from './armor/armor';
|
||||
import { DS4Equipment } from './equipment/equipment';
|
||||
import { DS4Item } from './item';
|
||||
import { DS4Language } from './language/language';
|
||||
import { DS4Loot } from './loot/loot';
|
||||
import { DS4RacialAbility } from './racial-ability/racial-ability';
|
||||
import { DS4Shield } from './shield/shield';
|
||||
import { DS4SpecialCreatureAbility } from './special-creature-ability/special-creature-ability';
|
||||
import { DS4Spell } from './spell/spell';
|
||||
import { DS4Talent } from './talent/talent';
|
||||
import { DS4Weapon } from './weapon/weapon';
|
||||
|
||||
const handler = {
|
||||
/**
|
||||
|
@ -23,30 +23,30 @@ const handler = {
|
|||
*/
|
||||
construct(_, args) {
|
||||
switch (args[0]?.type) {
|
||||
case "alphabet":
|
||||
case 'alphabet':
|
||||
return new DS4Alphabet(...args);
|
||||
case "armor":
|
||||
case 'armor':
|
||||
return new DS4Armor(...args);
|
||||
case "equipment":
|
||||
case 'equipment':
|
||||
return new DS4Equipment(...args);
|
||||
case "language":
|
||||
case 'language':
|
||||
return new DS4Language(...args);
|
||||
case "loot":
|
||||
case 'loot':
|
||||
return new DS4Loot(...args);
|
||||
case "racialAbility":
|
||||
case 'racialAbility':
|
||||
return new DS4RacialAbility(...args);
|
||||
case "shield":
|
||||
case 'shield':
|
||||
return new DS4Shield(...args);
|
||||
case "specialCreatureAbility":
|
||||
case 'specialCreatureAbility':
|
||||
return new DS4SpecialCreatureAbility(...args);
|
||||
case "spell":
|
||||
case 'spell':
|
||||
return new DS4Spell(...args);
|
||||
case "talent":
|
||||
case 'talent':
|
||||
return new DS4Talent(...args);
|
||||
case "weapon":
|
||||
case 'weapon':
|
||||
return new DS4Weapon(...args);
|
||||
default:
|
||||
throw new Error(getGame().i18n.format("DS4.ErrorInvalidItemType", { type: args[0]?.type }));
|
||||
throw new Error(getGame().i18n.format('DS4.ErrorInvalidItemType', { type: args[0]?.type }));
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4RacialAbilityDataSourceData } from "./racial-ability-data-source";
|
||||
import type { DS4ItemDataPropertiesDataRollable } from '../item-data-properties-base';
|
||||
import type { DS4RacialAbilityDataSourceData } from './racial-ability-data-source';
|
||||
|
||||
export interface DS4RacialAbilityDataProperties {
|
||||
type: "racialAbility";
|
||||
type: 'racialAbility';
|
||||
data: DS4RacialAbilityDataPropertiesData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataSourceDataBase } from "../item-data-source-base";
|
||||
import type { DS4ItemDataSourceDataBase } from '../item-data-source-base';
|
||||
|
||||
export interface DS4RacialAbilityDataSource {
|
||||
type: "racialAbility";
|
||||
type: 'racialAbility';
|
||||
data: DS4RacialAbilityDataSourceData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
import { DS4Item } from '../item';
|
||||
|
||||
export class DS4RacialAbility extends DS4Item {}
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4ShieldDataSourceData } from "./shield-data-source";
|
||||
import type { DS4ItemDataPropertiesDataRollable } from '../item-data-properties-base';
|
||||
import type { DS4ShieldDataSourceData } from './shield-data-source';
|
||||
|
||||
export interface DS4ShieldDataProperties {
|
||||
type: "shield";
|
||||
type: 'shield';
|
||||
data: DS4ShieldDataPropertiesData;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@ import type {
|
|||
DS4ItemDataSourceDataEquipable,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
DS4ItemDataSourceDataProtective,
|
||||
} from "../item-data-source-base";
|
||||
} from '../item-data-source-base';
|
||||
|
||||
export interface DS4ShieldDataSource {
|
||||
type: "shield";
|
||||
type: 'shield';
|
||||
data: DS4ShieldDataSourceData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
import { DS4Item } from '../item';
|
||||
|
||||
export class DS4Shield extends DS4Item {}
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4SpecialCreatureAbilityDataSourceData } from "./special-creature-ability-data-source";
|
||||
import type { DS4ItemDataPropertiesDataRollable } from '../item-data-properties-base';
|
||||
import type { DS4SpecialCreatureAbilityDataSourceData } from './special-creature-ability-data-source';
|
||||
|
||||
export interface DS4SpecialCreatureAbilityDataProperties {
|
||||
type: "specialCreatureAbility";
|
||||
type: 'specialCreatureAbility';
|
||||
data: DS4SpecialCreatureAbilityDataPropertiesData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataSourceDataBase } from "../item-data-source-base";
|
||||
import type { DS4ItemDataSourceDataBase } from '../item-data-source-base';
|
||||
|
||||
export interface DS4SpecialCreatureAbilityDataSource {
|
||||
type: "specialCreatureAbility";
|
||||
type: 'specialCreatureAbility';
|
||||
data: DS4SpecialCreatureAbilityDataSourceData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
import { DS4Item } from '../item';
|
||||
|
||||
export class DS4SpecialCreatureAbility extends DS4Item {}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { CooldownDuration, DS4SpellDataSourceData } from "./spell-data-source";
|
||||
import type { CooldownDuration, DS4SpellDataSourceData } from './spell-data-source';
|
||||
|
||||
export function calculateSpellPrice(data: DS4SpellDataSourceData): number | null {
|
||||
const spellPriceFactor = calculateSpellPriceFactor(data.cooldownDuration);
|
||||
|
@ -17,16 +17,16 @@ export function calculateSpellPrice(data: DS4SpellDataSourceData): number | null
|
|||
|
||||
function calculateSpellPriceFactor(cooldownDuration: CooldownDuration): number {
|
||||
switch (cooldownDuration) {
|
||||
case "0r":
|
||||
case "1r":
|
||||
case "2r":
|
||||
case "5r":
|
||||
case "10r":
|
||||
case "100r":
|
||||
case '0r':
|
||||
case '1r':
|
||||
case '2r':
|
||||
case '5r':
|
||||
case '10r':
|
||||
case '100r':
|
||||
return 1;
|
||||
case "1d":
|
||||
case '1d':
|
||||
return 2;
|
||||
case "d20d":
|
||||
case 'd20d':
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4SpellDataSourceData } from "./spell-data-source";
|
||||
import type { DS4ItemDataPropertiesDataRollable } from '../item-data-properties-base';
|
||||
import type { DS4SpellDataSourceData } from './spell-data-source';
|
||||
|
||||
export interface DS4SpellDataProperties {
|
||||
type: "spell";
|
||||
type: 'spell';
|
||||
data: DS4SpellDataPropertiesData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4 } from "../../../config";
|
||||
import type { DS4ItemDataSourceDataBase, DS4ItemDataSourceDataEquipable } from "../item-data-source-base";
|
||||
import type { DS4 } from '../../../config';
|
||||
import type { DS4ItemDataSourceDataBase, DS4ItemDataSourceDataEquipable } from '../item-data-source-base';
|
||||
|
||||
export interface DS4SpellDataSource {
|
||||
type: "spell";
|
||||
type: 'spell';
|
||||
data: DS4SpellDataSourceData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { createCheckRoll } from "../../../dice/check-factory";
|
||||
import { notifications } from "../../../ui/notifications";
|
||||
import { getGame } from "../../../utils/utils";
|
||||
import { DS4Item } from "../item";
|
||||
import { calculateSpellPrice } from "./calculate-spell-price";
|
||||
import { createCheckRoll } from '../../../dice/check-factory';
|
||||
import { notifications } from '../../../ui/notifications';
|
||||
import { getGame } from '../../../utils/utils';
|
||||
import { DS4Item } from '../item';
|
||||
import { calculateSpellPrice } from './calculate-spell-price';
|
||||
|
||||
export class DS4Spell extends DS4Item {
|
||||
/** @override */
|
||||
|
@ -24,7 +24,7 @@ export class DS4Spell extends DS4Item {
|
|||
|
||||
if (!this.system.equipped) {
|
||||
return notifications.warn(
|
||||
game.i18n.format("DS4.WarningItemMustBeEquippedToBeRolled", {
|
||||
game.i18n.format('DS4.WarningItemMustBeEquippedToBeRolled', {
|
||||
name: this.name,
|
||||
id: this.id,
|
||||
type: this.type,
|
||||
|
@ -33,14 +33,14 @@ export class DS4Spell extends DS4Item {
|
|||
}
|
||||
|
||||
if (!this.actor) {
|
||||
throw new Error(game.i18n.format("DS4.ErrorCannotRollUnownedItem", { name: this.name, id: this.id }));
|
||||
throw new Error(game.i18n.format('DS4.ErrorCannotRollUnownedItem', { name: this.name, id: this.id }));
|
||||
}
|
||||
|
||||
const ownerSystemData = this.actor.system;
|
||||
const hasComplexModifier = this.system.spellModifier.complex !== "";
|
||||
const hasComplexModifier = this.system.spellModifier.complex !== '';
|
||||
if (hasComplexModifier === undefined) {
|
||||
notifications.info(
|
||||
game.i18n.format("DS4.InfoManuallyEnterSpellModifier", {
|
||||
game.i18n.format('DS4.InfoManuallyEnterSpellModifier', {
|
||||
name: this.name,
|
||||
spellModifier: this.system.spellModifier.complex,
|
||||
}),
|
||||
|
@ -49,24 +49,23 @@ export class DS4Spell extends DS4Item {
|
|||
const spellType = this.system.spellType;
|
||||
const opponentDefense = this.system.opponentDefense;
|
||||
const checkTargetNumber =
|
||||
ownerSystemData.combatValues[spellType].total +
|
||||
(hasComplexModifier ? 0 : this.system.spellModifier.numerical);
|
||||
ownerSystemData.combatValues[spellType].total + (hasComplexModifier ? 0 : this.system.spellModifier.numerical);
|
||||
const speaker = ChatMessage.getSpeaker({ actor: this.actor, ...options.speaker });
|
||||
const flavor =
|
||||
opponentDefense !== undefined && opponentDefense !== 0
|
||||
? "DS4.ItemSpellCheckFlavorWithOpponentDefense"
|
||||
: "DS4.ItemSpellCheckFlavor";
|
||||
? 'DS4.ItemSpellCheckFlavorWithOpponentDefense'
|
||||
: 'DS4.ItemSpellCheckFlavor';
|
||||
/** @type {import("../../../dice/check-factory").DS4CheckFactoryOptions["flavorData"]} */
|
||||
const flavorData = {
|
||||
actor: speaker.alias ?? this.actor.name,
|
||||
spell: this.name,
|
||||
};
|
||||
if (opponentDefense !== undefined && opponentDefense !== 0) {
|
||||
flavorData.opponentDefense = (opponentDefense < 0 ? "" : "+") + opponentDefense;
|
||||
flavorData.opponentDefense = (opponentDefense < 0 ? '' : '+') + opponentDefense;
|
||||
}
|
||||
|
||||
await createCheckRoll(checkTargetNumber, {
|
||||
rollMode: game.settings.get("core", "rollMode"),
|
||||
rollMode: game.settings.get('core', 'rollMode'),
|
||||
maximumCoupResult: ownerSystemData.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: ownerSystemData.rolling.minimumFumbleResult,
|
||||
flavor: flavor,
|
||||
|
@ -80,6 +79,6 @@ export class DS4Spell extends DS4Item {
|
|||
* @memberof hookEvents
|
||||
* @param {DS4Item} item Item being rolled.
|
||||
*/
|
||||
Hooks.callAll("ds4.rollItem", this);
|
||||
Hooks.callAll('ds4.rollItem', this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { ModifiableDataBaseTotalMax } from "../../common/common-data";
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4TalentDataSourceData } from "./talent-data-source";
|
||||
import type { ModifiableDataBaseTotalMax } from '../../common/common-data';
|
||||
import type { DS4ItemDataPropertiesDataRollable } from '../item-data-properties-base';
|
||||
import type { DS4TalentDataSourceData } from './talent-data-source';
|
||||
|
||||
export interface DS4TalentDataProperties {
|
||||
type: "talent";
|
||||
type: 'talent';
|
||||
data: DS4TalentDataPropertiesData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { ModifiableDataBaseMax } from "../../common/common-data";
|
||||
import type { DS4ItemDataSourceDataBase } from "../item-data-source-base";
|
||||
import type { ModifiableDataBaseMax } from '../../common/common-data';
|
||||
import type { DS4ItemDataSourceDataBase } from '../item-data-source-base';
|
||||
|
||||
export interface DS4TalentDataSource {
|
||||
type: "talent";
|
||||
type: 'talent';
|
||||
data: DS4TalentDataSourceData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Item } from "../item";
|
||||
import { DS4Item } from '../item';
|
||||
|
||||
export class DS4Talent extends DS4Item {
|
||||
/** @override */
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4ItemDataPropertiesDataRollable } from "../item-data-properties-base";
|
||||
import type { DS4WeaponDataSourceData } from "./weapon-data-source";
|
||||
import type { DS4ItemDataPropertiesDataRollable } from '../item-data-properties-base';
|
||||
import type { DS4WeaponDataSourceData } from './weapon-data-source';
|
||||
|
||||
interface DS4WeaponDataPropertiesData extends DS4WeaponDataSourceData, DS4ItemDataPropertiesDataRollable {
|
||||
opponentDefenseForAttackType: {
|
||||
|
@ -13,6 +13,6 @@ interface DS4WeaponDataPropertiesData extends DS4WeaponDataSourceData, DS4ItemDa
|
|||
}
|
||||
|
||||
export interface DS4WeaponDataProperties {
|
||||
type: "weapon";
|
||||
type: 'weapon';
|
||||
data: DS4WeaponDataPropertiesData;
|
||||
}
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import type { DS4 } from "../../../config";
|
||||
import type { DS4 } from '../../../config';
|
||||
import type {
|
||||
DS4ItemDataSourceDataBase,
|
||||
DS4ItemDataSourceDataEquipable,
|
||||
DS4ItemDataSourceDataPhysical,
|
||||
} from "../item-data-source-base";
|
||||
} from '../item-data-source-base';
|
||||
|
||||
export interface DS4WeaponDataSource {
|
||||
type: "weapon";
|
||||
type: 'weapon';
|
||||
data: DS4WeaponDataSourceData;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4 } from "../../../config";
|
||||
import { createCheckRoll } from "../../../dice/check-factory";
|
||||
import { notifications } from "../../../ui/notifications";
|
||||
import { getGame } from "../../../utils/utils";
|
||||
import { DS4Item } from "../item";
|
||||
import { DS4 } from '../../../config';
|
||||
import { createCheckRoll } from '../../../dice/check-factory';
|
||||
import { notifications } from '../../../ui/notifications';
|
||||
import { getGame } from '../../../utils/utils';
|
||||
import { DS4Item } from '../item';
|
||||
|
||||
export class DS4Weapon extends DS4Item {
|
||||
/** @override */
|
||||
|
@ -14,10 +14,10 @@ export class DS4Weapon extends DS4Item {
|
|||
const system = this.system;
|
||||
system.rollable = system.equipped;
|
||||
system.opponentDefenseForAttackType = {};
|
||||
if (system.attackType === "melee" || system.attackType === "meleeRanged") {
|
||||
if (system.attackType === 'melee' || system.attackType === 'meleeRanged') {
|
||||
system.opponentDefenseForAttackType.melee = system.opponentDefense;
|
||||
}
|
||||
if (system.attackType === "ranged" || system.attackType === "meleeRanged") {
|
||||
if (system.attackType === 'ranged' || system.attackType === 'meleeRanged') {
|
||||
system.opponentDefenseForAttackType.ranged = system.opponentDefense;
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ export class DS4Weapon extends DS4Item {
|
|||
const game = getGame();
|
||||
if (!this.system.equipped) {
|
||||
return notifications.warn(
|
||||
game.i18n.format("DS4.WarningItemMustBeEquippedToBeRolled", {
|
||||
game.i18n.format('DS4.WarningItemMustBeEquippedToBeRolled', {
|
||||
name: this.name,
|
||||
id: this.id,
|
||||
type: this.type,
|
||||
|
@ -36,7 +36,7 @@ export class DS4Weapon extends DS4Item {
|
|||
}
|
||||
|
||||
if (!this.actor) {
|
||||
throw new Error(game.i18n.format("DS4.ErrorCannotRollUnownedItem", { name: this.name, id: this.id }));
|
||||
throw new Error(game.i18n.format('DS4.ErrorCannotRollUnownedItem', { name: this.name, id: this.id }));
|
||||
}
|
||||
|
||||
const ownerSystemData = this.actor.system;
|
||||
|
@ -48,19 +48,19 @@ export class DS4Weapon extends DS4Item {
|
|||
const speaker = ChatMessage.getSpeaker({ actor: this.actor, ...options.speaker });
|
||||
const flavor =
|
||||
opponentDefense !== undefined && opponentDefense !== 0
|
||||
? "DS4.ItemWeaponCheckFlavorWithOpponentDefense"
|
||||
: "DS4.ItemWeaponCheckFlavor";
|
||||
? 'DS4.ItemWeaponCheckFlavorWithOpponentDefense'
|
||||
: 'DS4.ItemWeaponCheckFlavor';
|
||||
/** @type {import("../../../dice/check-factory").DS4CheckFactoryOptions["flavorData"]} */
|
||||
const flavorData = {
|
||||
actor: speaker.alias ?? this.actor.name,
|
||||
weapon: this.name,
|
||||
};
|
||||
if (opponentDefense !== undefined && opponentDefense !== 0) {
|
||||
flavorData.opponentDefense = (opponentDefense < 0 ? "" : "+") + opponentDefense;
|
||||
flavorData.opponentDefense = (opponentDefense < 0 ? '' : '+') + opponentDefense;
|
||||
}
|
||||
|
||||
await createCheckRoll(checkTargetNumber, {
|
||||
rollMode: getGame().settings.get("core", "rollMode"),
|
||||
rollMode: getGame().settings.get('core', 'rollMode'),
|
||||
maximumCoupResult: ownerSystemData.rolling.maximumCoupResult,
|
||||
minimumFumbleResult: ownerSystemData.rolling.minimumFumbleResult,
|
||||
speaker,
|
||||
|
@ -68,7 +68,7 @@ export class DS4Weapon extends DS4Item {
|
|||
flavorData,
|
||||
});
|
||||
|
||||
Hooks.callAll("ds4.rollItem", this);
|
||||
Hooks.callAll('ds4.rollItem', this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,29 +77,29 @@ export class DS4Weapon extends DS4Item {
|
|||
* @protected
|
||||
*/
|
||||
async getPerformedAttackType() {
|
||||
if (this.system.attackType !== "meleeRanged") {
|
||||
if (this.system.attackType !== 'meleeRanged') {
|
||||
return this.system.attackType;
|
||||
}
|
||||
|
||||
const { melee, ranged } = { ...DS4.i18n.attackTypes };
|
||||
const identifier = `attack-type-selection-${foundry.utils.randomID()}`;
|
||||
return Dialog.prompt({
|
||||
title: getGame().i18n.localize("DS4.DialogAttackTypeSelection"),
|
||||
content: await renderTemplate("systems/ds4/templates/dialogs/simple-select-form.hbs", {
|
||||
title: getGame().i18n.localize('DS4.DialogAttackTypeSelection'),
|
||||
content: await renderTemplate('systems/ds4/templates/dialogs/simple-select-form.hbs', {
|
||||
selects: [
|
||||
{
|
||||
label: getGame().i18n.localize("DS4.AttackType"),
|
||||
label: getGame().i18n.localize('DS4.AttackType'),
|
||||
identifier,
|
||||
options: { melee, ranged },
|
||||
},
|
||||
],
|
||||
}),
|
||||
label: getGame().i18n.localize("DS4.GenericOkButton"),
|
||||
label: getGame().i18n.localize('DS4.GenericOkButton'),
|
||||
callback: (html) => {
|
||||
const selectedAttackType = html.find(`#${identifier}`).val();
|
||||
if (selectedAttackType !== "melee" && selectedAttackType !== "ranged") {
|
||||
if (selectedAttackType !== 'melee' && selectedAttackType !== 'ranged') {
|
||||
throw new Error(
|
||||
getGame().i18n.format("DS4.ErrorUnexpectedAttackType", {
|
||||
getGame().i18n.format('DS4.ErrorUnexpectedAttackType', {
|
||||
actualType: selectedAttackType,
|
||||
expectedTypes: "'melee', 'ranged'",
|
||||
}),
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { getGame } from "../utils/utils";
|
||||
import { DS4ActorProxy } from "./actor/proxy";
|
||||
import { getGame } from '../utils/utils';
|
||||
import { DS4ActorProxy } from './actor/proxy';
|
||||
|
||||
/** @type {object | undefined} */
|
||||
let fallbackData = undefined;
|
||||
|
@ -12,7 +12,7 @@ function getFallbackData() {
|
|||
if (!fallbackData) {
|
||||
fallbackData = {};
|
||||
for (const type of getGame().system.template.Actor?.types ?? []) {
|
||||
foundry.utils.mergeObject(fallbackData, new DS4ActorProxy({ type, name: "temporary" }).system);
|
||||
foundry.utils.mergeObject(fallbackData, new DS4ActorProxy({ type, name: 'temporary' }).system);
|
||||
}
|
||||
}
|
||||
return fallbackData;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import "../scss/ds4.scss";
|
||||
import '../scss/ds4.scss';
|
||||
|
||||
import { registerForHooks } from "./hooks/hooks";
|
||||
import { registerForHooks } from './hooks/hooks';
|
||||
|
||||
registerForHooks();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { Validator } from "./validator";
|
||||
import { Validator } from './validator';
|
||||
|
||||
export class Evaluator<Context extends object> {
|
||||
context?: Context;
|
||||
|
@ -28,7 +28,7 @@ export class Evaluator<Context extends object> {
|
|||
this.validator.validate(expression);
|
||||
|
||||
const body = `with (sandbox) { return ${expression}; }`;
|
||||
const evaluate = new Function("sandbox", body);
|
||||
const evaluate = new Function('sandbox', body);
|
||||
return evaluate(this.context ?? {});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,47 +15,47 @@ interface TokenWithoutSymbol {
|
|||
pos: number;
|
||||
}
|
||||
|
||||
type TypeWithSymbol = "iden" | "number" | "string";
|
||||
type TypeWithSymbol = 'iden' | 'number' | 'string';
|
||||
|
||||
type TypeWithoutSymbol =
|
||||
| "+"
|
||||
| "-"
|
||||
| "*"
|
||||
| "**"
|
||||
| "/"
|
||||
| "%"
|
||||
| "==="
|
||||
| "!=="
|
||||
| "=="
|
||||
| "!="
|
||||
| "<"
|
||||
| "<="
|
||||
| ">"
|
||||
| ">="
|
||||
| "&&"
|
||||
| "||"
|
||||
| "&"
|
||||
| "|"
|
||||
| "~"
|
||||
| "^"
|
||||
| "<<"
|
||||
| ">>"
|
||||
| ">>>"
|
||||
| "."
|
||||
| "?."
|
||||
| "??"
|
||||
| "!"
|
||||
| "?"
|
||||
| ":"
|
||||
| "("
|
||||
| ")"
|
||||
| "["
|
||||
| "]"
|
||||
| ","
|
||||
| "{"
|
||||
| "}"
|
||||
| "invalid"
|
||||
| "eof";
|
||||
| '+'
|
||||
| '-'
|
||||
| '*'
|
||||
| '**'
|
||||
| '/'
|
||||
| '%'
|
||||
| '==='
|
||||
| '!=='
|
||||
| '=='
|
||||
| '!='
|
||||
| '<'
|
||||
| '<='
|
||||
| '>'
|
||||
| '>='
|
||||
| '&&'
|
||||
| '||'
|
||||
| '&'
|
||||
| '|'
|
||||
| '~'
|
||||
| '^'
|
||||
| '<<'
|
||||
| '>>'
|
||||
| '>>>'
|
||||
| '.'
|
||||
| '?.'
|
||||
| '??'
|
||||
| '!'
|
||||
| '?'
|
||||
| ':'
|
||||
| '('
|
||||
| ')'
|
||||
| '['
|
||||
| ']'
|
||||
| ','
|
||||
| '{'
|
||||
| '}'
|
||||
| 'invalid'
|
||||
| 'eof';
|
||||
|
||||
export const literals = ["true", "false", "null", "undefined"];
|
||||
export const safeOperators = ["in", "instanceof", "typeof", "void"];
|
||||
export const literals = ['true', 'false', 'null', 'undefined'];
|
||||
export const safeOperators = ['in', 'instanceof', 'typeof', 'void'];
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue