diff --git a/.vscode/settings.json b/.vscode/settings.json index c46b4a1..75011bf 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,5 +9,14 @@ "[handlebars]": { "editor.defaultFormatter": "monosans.djlint" + }, + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[css]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" } } diff --git a/css/deltagreen.css b/css/deltagreen.css index 58791d7..c4f44a8 100644 --- a/css/deltagreen.css +++ b/css/deltagreen.css @@ -737,6 +737,37 @@ div .exhausted-section { margin-bottom: 5px; } +.tab.about { + .dg-about-links { + gap: 0.5rem; + margin-bottom: 1rem; + + a { + display: inline-flex; + align-items: center; + gap: 0.5rem; + width: fit-content; + max-width: 100%; + + i { + flex: 0 0 auto; + } + + span { + flex: 1 1 auto; + line-height: 1.4; + text-align: left; + } + } + } + + .dg-about-legal { + p { + margin: 0.5rem 0; + } + } +} + textarea.wounds { resize: none; height: 100px; diff --git a/module/data/actor/agent.js b/module/data/actor/agent.js index 1797bf1..a3b1fc8 100644 --- a/module/data/actor/agent.js +++ b/module/data/actor/agent.js @@ -1,7 +1,7 @@ import HumanSkillsActorData from "./base/human-skills.js"; import CharacterData from "./base/character.js"; -const { SchemaField, NumberField, StringField, BooleanField } = +const { SchemaField, NumberField, StringField, BooleanField, HTMLField } = foundry.data.fields; export default class AgentData extends CharacterData { @@ -29,8 +29,10 @@ export default class AgentData extends CharacterData { }), }), physical: new SchemaField({ - description: new StringField({ + description: new HTMLField({ initial: "", + blank: true, + textSearch: true, }), wounds: new StringField({ initial: "" }), firstAidAttempted: new BooleanField({ initial: false }), diff --git a/module/data/actor/npc.js b/module/data/actor/npc.js index 623d360..412cfc1 100644 --- a/module/data/actor/npc.js +++ b/module/data/actor/npc.js @@ -1,7 +1,7 @@ import HumanSkillsActorData from "./base/human-skills.js"; import CharacterData from "./base/character.js"; -const { SchemaField, NumberField, StringField, BooleanField } = +const { SchemaField, NumberField, StringField, BooleanField, HTMLField } = foundry.data.fields; export default class NPCData extends CharacterData { @@ -19,7 +19,7 @@ export default class NPCData extends CharacterData { biography: new SchemaField({ profession: new StringField({ initial: "" }), }), - notes: new StringField({ initial: "" }), + notes: new HTMLField({ initial: "", blank: true, textSearch: true }), shortDescription: new StringField({ initial: "" }), showUntrainedSkills: new BooleanField({ initial: true }), }; diff --git a/module/data/actor/unnatural.js b/module/data/actor/unnatural.js index 6a32949..7e293b6 100644 --- a/module/data/actor/unnatural.js +++ b/module/data/actor/unnatural.js @@ -1,7 +1,7 @@ import UnnaturalSkillsActorData from "./base/unnatural-skills.js"; import CharacterData from "./base/character.js"; -const { SchemaField, NumberField, StringField, BooleanField } = +const { SchemaField, NumberField, StringField, BooleanField, HTMLField } = foundry.data.fields; export default class UnnaturalData extends CharacterData { @@ -17,7 +17,12 @@ export default class UnnaturalData extends CharacterData { successLoss: new StringField({ initial: "1" }), }), schemaVersion: new NumberField({ initial: 1.0 }), - notes: new StringField({ initial: "" }), + notes: new HTMLField({ + initial: "", + blank: true, + textSearch: true, + allowColor: true, + }), shortDescription: new StringField({ initial: "" }), showUntrainedSkills: new BooleanField({ initial: true }), }; diff --git a/module/data/actor/vehicle.js b/module/data/actor/vehicle.js index e21ff07..e6e75e3 100644 --- a/module/data/actor/vehicle.js +++ b/module/data/actor/vehicle.js @@ -1,6 +1,6 @@ import SheetSettingsActorData from "./base/sheet-settings.js"; -const { SchemaField, NumberField, StringField, ArrayField } = +const { SchemaField, NumberField, StringField, ArrayField, HTMLField } = foundry.data.fields; export default class VehicleData extends foundry.abstract.TypeDataModel { @@ -8,7 +8,11 @@ export default class VehicleData extends foundry.abstract.TypeDataModel { return { ...SheetSettingsActorData.defineSchema(), name: new StringField({ initial: "" }), - description: new StringField({ initial: "" }), + description: new HTMLField({ + initial: "", + blank: true, + textSearch: true, + }), shortDescription: new StringField({ initial: "" }), health: new SchemaField({ value: new NumberField({ initial: 10 }), diff --git a/module/data/item/armor.js b/module/data/item/armor.js new file mode 100644 index 0000000..58e47ef --- /dev/null +++ b/module/data/item/armor.js @@ -0,0 +1,14 @@ +import defineBaseItemSystemFields from "./base-fields.js"; + +const { NumberField, StringField, BooleanField } = foundry.data.fields; + +export default class ArmorItemData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...defineBaseItemSystemFields(), + protection: new NumberField({ initial: 3, integer: true }), + equipped: new BooleanField({ initial: true }), + expense: new StringField({ initial: "Standard" }), + }; + } +} diff --git a/module/data/item/base-fields.js b/module/data/item/base-fields.js new file mode 100644 index 0000000..896b518 --- /dev/null +++ b/module/data/item/base-fields.js @@ -0,0 +1,11 @@ +const { HTMLField } = foundry.data.fields; + +/** + * Shared system fields for all Delta Green item types (from legacy template base). + * Item display name lives on the document (`Item#name`), not in system. + */ +export default function defineBaseItemSystemFields() { + return { + description: new HTMLField({ initial: "", blank: true, textSearch: true }), + }; +} diff --git a/module/data/item/bond.js b/module/data/item/bond.js new file mode 100644 index 0000000..81ff8df --- /dev/null +++ b/module/data/item/bond.js @@ -0,0 +1,14 @@ +import defineBaseItemSystemFields from "./base-fields.js"; + +const { NumberField, StringField, BooleanField } = foundry.data.fields; + +export default class BondItemData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...defineBaseItemSystemFields(), + score: new NumberField({ initial: 10, integer: true }), + relationship: new StringField({ initial: "" }), + hasBeenDamagedSinceLastHomeScene: new BooleanField({ initial: false }), + }; + } +} diff --git a/module/data/item/gear.js b/module/data/item/gear.js new file mode 100644 index 0000000..8d54208 --- /dev/null +++ b/module/data/item/gear.js @@ -0,0 +1,13 @@ +import defineBaseItemSystemFields from "./base-fields.js"; + +const { StringField, BooleanField } = foundry.data.fields; + +export default class GearItemData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...defineBaseItemSystemFields(), + equipped: new BooleanField({ initial: true }), + expense: new StringField({ initial: "Standard" }), + }; + } +} diff --git a/module/data/item/motivation.js b/module/data/item/motivation.js new file mode 100644 index 0000000..5d0831f --- /dev/null +++ b/module/data/item/motivation.js @@ -0,0 +1,14 @@ +import defineBaseItemSystemFields from "./base-fields.js"; + +const { StringField, BooleanField } = foundry.data.fields; + +export default class MotivationItemData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...defineBaseItemSystemFields(), + disorder: new StringField({ initial: "" }), + crossedOut: new BooleanField({ initial: false }), + disorderCured: new BooleanField({ initial: false }), + }; + } +} diff --git a/module/data/item/ritual.js b/module/data/item/ritual.js new file mode 100644 index 0000000..7386cf8 --- /dev/null +++ b/module/data/item/ritual.js @@ -0,0 +1,33 @@ +import defineBaseItemSystemFields from "./base-fields.js"; + +const { NumberField, StringField, BooleanField, SchemaField, HTMLField } = + foundry.data.fields; + +export default class RitualItemData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...defineBaseItemSystemFields(), + studyTime: new StringField({ initial: "" }), + sanity: new SchemaField({ + notes: new StringField({ initial: "" }), + failedLoss: new StringField({ initial: "1D10" }), + successLoss: new StringField({ initial: "0" }), + }), + learnedSanity: new SchemaField({ + notes: new StringField({ initial: "" }), + failedLoss: new StringField({ initial: "1D10" }), + successLoss: new StringField({ initial: "0" }), + }), + unnaturalSkillIncrease: new NumberField({ initial: 1, integer: true }), + activationCosts: new StringField({ initial: "" }), + activationTime: new StringField({ initial: "" }), + complexity: new StringField({ initial: "Simple" }), + handlerNotes: new HTMLField({ + initial: "", + blank: true, + textSearch: true, + }), + revealed: new BooleanField({ initial: false }), + }; + } +} diff --git a/module/data/item/tome.js b/module/data/item/tome.js new file mode 100644 index 0000000..2673153 --- /dev/null +++ b/module/data/item/tome.js @@ -0,0 +1,27 @@ +import defineBaseItemSystemFields from "./base-fields.js"; + +const { NumberField, StringField, BooleanField, SchemaField, HTMLField } = + foundry.data.fields; + +export default class TomeItemData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...defineBaseItemSystemFields(), + language: new StringField({ initial: "" }), + studyTime: new StringField({ initial: "" }), + unnaturalSkillIncrease: new NumberField({ initial: 5, integer: true }), + occultSkillIncrease: new NumberField({ initial: 3, integer: true }), + sanity: new SchemaField({ + notes: new StringField({ initial: "" }), + failedLoss: new StringField({ initial: "1D6" }), + successLoss: new StringField({ initial: "1D4" }), + }), + handlerNotes: new HTMLField({ + initial: "", + blank: true, + textSearch: true, + }), + revealed: new BooleanField({ initial: false }), + }; + } +} diff --git a/module/data/item/weapon.js b/module/data/item/weapon.js new file mode 100644 index 0000000..11777a2 --- /dev/null +++ b/module/data/item/weapon.js @@ -0,0 +1,23 @@ +import defineBaseItemSystemFields from "./base-fields.js"; + +const { NumberField, StringField, BooleanField } = foundry.data.fields; + +export default class WeaponItemData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...defineBaseItemSystemFields(), + skill: new StringField({ initial: "" }), + skillModifier: new NumberField({ initial: 0, integer: true }), + customSkillTarget: new NumberField({ initial: 50, integer: true }), + range: new StringField({ initial: "10M" }), + damage: new StringField({ initial: "1D8" }), + armorPiercing: new NumberField({ initial: 0, integer: true }), + lethality: new NumberField({ initial: 0, integer: true }), + isLethal: new BooleanField({ initial: false }), + killRadius: new StringField({ initial: "N/A" }), + ammo: new StringField({ initial: "" }), + expense: new StringField({ initial: "Standard" }), + equipped: new BooleanField({ initial: true }), + }; + } +} diff --git a/module/deltagreen.js b/module/deltagreen.js index 63f12f7..5f7aad5 100644 --- a/module/deltagreen.js +++ b/module/deltagreen.js @@ -25,18 +25,35 @@ import AgentData from "./data/actor/agent.js"; import UnnaturalData from "./data/actor/unnatural.js"; import NPCData from "./data/actor/npc.js"; import VehicleData from "./data/actor/vehicle.js"; +import WeaponItemData from "./data/item/weapon.js"; +import ArmorItemData from "./data/item/armor.js"; +import MotivationItemData from "./data/item/motivation.js"; +import BondItemData from "./data/item/bond.js"; +import GearItemData from "./data/item/gear.js"; +import TomeItemData from "./data/item/tome.js"; +import RitualItemData from "./data/item/ritual.js"; const { Actors, Items } = foundry.documents.collections; Hooks.once("init", async () => { Object.assign(CONFIG.Actor.dataModels, { - // The keys are the types defined in our template.json + // The keys are the types defined in system.json documentTypes.Actor agent: AgentData, unnatural: UnnaturalData, npc: NPCData, vehicle: VehicleData, }); + Object.assign(CONFIG.Item.dataModels, { + weapon: WeaponItemData, + armor: ArmorItemData, + motivation: MotivationItemData, + bond: BondItemData, + gear: GearItemData, + tome: TomeItemData, + ritual: RitualItemData, + }); + game.deltagreen = { DeltaGreenActor, DeltaGreenItem, diff --git a/module/roll/roll.js b/module/roll/roll.js index 80f7fbc..db002e4 100644 --- a/module/roll/roll.js +++ b/module/roll/roll.js @@ -594,10 +594,11 @@ export class DGLethalityRoll extends DGPercentileRoll { } let html = ""; - html += `
{{localize 'DG.About.Copyright'}}
-{{{localize 'DG.About.License'}}}
-{{localize 'DG.About.Copyright'}}
+{{{localize 'DG.About.License'}}}