diff --git a/module/data/actor/agent.js b/module/data/actor/agent.js new file mode 100644 index 0000000..222914e --- /dev/null +++ b/module/data/actor/agent.js @@ -0,0 +1,56 @@ +import HumanSkillsActorData from "./base/human-skills.js"; +import CharacterData from "./base/character.js"; + +const { SchemaField, NumberField, StringField, BooleanField } = + foundry.data.fields; + +export default class AgentData extends CharacterData { + static defineSchema() { + const superData = super.defineSchema(); + + return { + ...superData, + ...HumanSkillsActorData.defineSchema(), + schemaVersion: new NumberField({ initial: 1.0 }), + sanity: new SchemaField({ + value: new NumberField({ initial: 100 }), + currentBreakingPoint: new NumberField({ initial: 101 }), + adaptations: new SchemaField({ + violence: new SchemaField({ + incident1: new BooleanField({ initial: false }), + incident2: new BooleanField({ initial: false }), + incident3: new BooleanField({ initial: false }), + }), + helplessness: new SchemaField({ + incident1: new BooleanField({ initial: false }), + incident2: new BooleanField({ initial: false }), + incident3: new BooleanField({ initial: false }), + }), + }), + }), + physical: new SchemaField({ + description: new StringField({ + initial: "(Physical description of agent)", + }), + wounds: new StringField({ initial: "" }), + firstAidAttempted: new BooleanField({ initial: false }), + exhausted: new BooleanField({ initial: false }), + exhaustedPenalty: new NumberField({ initial: -20 }), + }), + biography: new SchemaField({ + profession: new StringField({ initial: "" }), + employer: new StringField({ initial: "" }), + nationality: new StringField({ initial: "" }), + sex: new StringField({ initial: "" }), + age: new StringField({ initial: "" }), + education: new StringField({ initial: "" }), + }), + corruption: new SchemaField({ + value: new NumberField({ initial: 0 }), + haveSeenTheYellowSign: new BooleanField({ initial: false }), + gift: new StringField({ initial: "" }), + insight: new StringField({ initial: "" }), + }), + }; + } +} diff --git a/module/data/actor/base/base-actor.js b/module/data/actor/base/base-actor.js new file mode 100644 index 0000000..e47ffe0 --- /dev/null +++ b/module/data/actor/base/base-actor.js @@ -0,0 +1,20 @@ +import { resourceField, statisticsField } from "./general.js"; + +const { SchemaField } = foundry.data.fields; + +export default class BaseActorData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + health: resourceField(10, 10), + wp: resourceField(10, 10), + statistics: new SchemaField({ + str: statisticsField(10), + con: statisticsField(10), + dex: statisticsField(10), + int: statisticsField(10), + pow: statisticsField(10), + cha: statisticsField(10), + }), + }; + } +} diff --git a/module/data/actor/base/character.js b/module/data/actor/base/character.js new file mode 100644 index 0000000..fe3636d --- /dev/null +++ b/module/data/actor/base/character.js @@ -0,0 +1,11 @@ +import BaseActorData from "./base-actor.js"; +import SheetSettingsActorData from "./sheet-settings.js"; + +export default class CharacterData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...BaseActorData.defineSchema(), + ...SheetSettingsActorData.defineSchema(), + }; + } +} diff --git a/module/data/actor/base/general.js b/module/data/actor/base/general.js new file mode 100644 index 0000000..0d702bf --- /dev/null +++ b/module/data/actor/base/general.js @@ -0,0 +1,25 @@ +const { SchemaField, NumberField, StringField, BooleanField } = + foundry.data.fields; + +export function skillField(initialValue, label) { + return new SchemaField({ + proficiency: new NumberField({ initial: initialValue }), + label: new StringField({ initial: label }), + failure: new BooleanField({ initial: false }), + }); +} + +export function resourceField(initialValue, initialMax) { + return new SchemaField({ + min: new NumberField({ initial: 0 }), + value: new NumberField({ initial: initialValue }), + max: new NumberField({ initial: initialMax }), + }); +} + +export function statisticsField(initialValue) { + return new SchemaField({ + value: new NumberField({ initial: initialValue }), + distinguishing_feature: new StringField({ initial: "" }), + }); +} diff --git a/module/data/actor/base/human-skills.js b/module/data/actor/base/human-skills.js new file mode 100644 index 0000000..9e5bf7c --- /dev/null +++ b/module/data/actor/base/human-skills.js @@ -0,0 +1,62 @@ +import { skillField } from "./general.js"; + +const { SchemaField, NumberField, StringField, ArrayField, ObjectField } = + foundry.data.fields; +const { TypeDataModel } = foundry.abstract; + +export default class HumanSkillsActorData extends TypeDataModel { + static defineSchema() { + return { + skills: new SchemaField({ + accounting: skillField(10, "Accounting"), + alertness: skillField(20, "Alertness"), + anthropology: skillField(0, "Anthropology"), + archeology: skillField(0, "Archeology"), + artillery: skillField(0, "Artillery"), + athletics: skillField(30, "Athletics"), + bureaucracy: skillField(10, "Bureaucracy"), + computer_science: skillField(0, "Computer Science"), + criminology: skillField(10, "Criminology"), + demolitions: skillField(0, "Demolitions"), + disguise: skillField(10, "Disguise"), + dodge: skillField(30, "Dodge"), + drive: skillField(20, "Drive"), + firearms: skillField(20, "Firearms"), + first_aid: skillField(10, "First Aid"), + forensics: skillField(0, "Forensics"), + heavy_machiner: skillField(10, "Heavy Machinery"), + heavy_weapons: skillField(0, "Heavy Weapons"), + history: skillField(10, "History"), + humint: skillField(10, "HUMINT"), + law: skillField(0, "Law"), + medicine: skillField(0, "Medicine"), + melee_weapons: skillField(30, "Melee Weapons"), + navigate: skillField(10, "Navigate"), + occult: skillField(10, "Occult"), + persuade: skillField(20, "Persuade"), + pharmacy: skillField(0, "Pharmacy"), + psychotherapy: skillField(10, "Psychotherapy"), + ride: skillField(10, "Ride"), + search: skillField(20, "Search"), + sigint: skillField(0, "SIGINT"), + stealth: skillField(10, "Stealth"), + surgery: skillField(0, "Surgery"), + survival: skillField(10, "Survival"), + swim: skillField(20, "Swim"), + unarmed_combat: skillField(40, "Unarmed Combat"), + unnatural: new SchemaField({ + proficiency: new NumberField({ initial: 0 }), + label: new StringField({ initial: "Unnatural" }), + }), + }), + typedSkills: new ObjectField({}), + specialTraining: new ArrayField( + new SchemaField({ + attribute: new StringField(), + id: new StringField(), + name: new StringField(), + }), + ), + }; + } +} diff --git a/module/data/actor/base/sheet-settings.js b/module/data/actor/base/sheet-settings.js new file mode 100644 index 0000000..0ebfc87 --- /dev/null +++ b/module/data/actor/base/sheet-settings.js @@ -0,0 +1,21 @@ +const { SchemaField, NumberField, BooleanField } = foundry.data.fields; +const { TypeDataModel } = foundry.abstract; + +export default class SheetSettingsActorData extends TypeDataModel { + static defineSchema() { + return { + settings: new SchemaField({ + sorting: new SchemaField({ + weaponSortAlphabetical: new BooleanField({ initial: false }), + armorSortAlphabetical: new BooleanField({ initial: false }), + gearSortAlphabetical: new BooleanField({ initial: false }), + tomeSortAlphabetical: new BooleanField({ initial: false }), + ritualSortAlphabetical: new BooleanField({ initial: false }), + }), + rolling: new SchemaField({ + defaultPercentileModifier: new NumberField({ initial: 20 }), + }), + }), + }; + } +} diff --git a/module/data/actor/base/unnatural-skills.js b/module/data/actor/base/unnatural-skills.js new file mode 100644 index 0000000..5278f52 --- /dev/null +++ b/module/data/actor/base/unnatural-skills.js @@ -0,0 +1,62 @@ +import { skillField } from "./general.js"; + +const { SchemaField, NumberField, StringField, ArrayField, ObjectField } = + foundry.data.fields; +const { TypeDataModel } = foundry.abstract; + +export default class UnnaturalSkillsActorData extends TypeDataModel { + static defineSchema() { + return { + skills: new SchemaField({ + accounting: skillField(0, "Accounting"), + alertness: skillField(50, "Alertness"), + anthropology: skillField(0, "Anthropology"), + archeology: skillField(0, "Archeology"), + artillery: skillField(0, "Artillery"), + athletics: skillField(50, "Athletics"), + bureaucracy: skillField(0, "Bureaucracy"), + computer_science: skillField(0, "Computer Science"), + criminology: skillField(0, "Criminology"), + demolitions: skillField(0, "Demolitions"), + disguise: skillField(0, "Disguise"), + dodge: skillField(50, "Dodge"), + drive: skillField(0, "Drive"), + firearms: skillField(0, "Firearms"), + first_aid: skillField(0, "First Aid"), + forensics: skillField(0, "Forensics"), + heavy_machiner: skillField(0, "Heavy Machinery"), + heavy_weapons: skillField(0, "Heavy Weapons"), + history: skillField(0, "History"), + humint: skillField(0, "HUMINT"), + law: skillField(0, "Law"), + medicine: skillField(0, "Medicine"), + melee_weapons: skillField(50, "Melee Weapons"), + navigate: skillField(0, "Navigate"), + occult: skillField(0, "Occult"), + persuade: skillField(0, "Persuade"), + pharmacy: skillField(0, "Pharmacy"), + psychotherapy: skillField(0, "Psychotherapy"), + ride: skillField(0, "Ride"), + search: skillField(0, "Search"), + sigint: skillField(0, "SIGINT"), + stealth: skillField(50, "Stealth"), + surgery: skillField(0, "Surgery"), + survival: skillField(0, "Survival"), + swim: skillField(0, "Swim"), + unarmed_combat: skillField(50, "Unarmed Combat"), + unnatural: new SchemaField({ + proficiency: new NumberField({ initial: 0 }), + label: new StringField({ initial: "Unnatural" }), + }), + }), + typedSkills: new ObjectField({}), + specialTraining: new ArrayField( + new SchemaField({ + attribute: new StringField(), + id: new StringField(), + name: new StringField(), + }), + ), + }; + } +} diff --git a/module/data/actor/npc.js b/module/data/actor/npc.js new file mode 100644 index 0000000..ff67ffd --- /dev/null +++ b/module/data/actor/npc.js @@ -0,0 +1,24 @@ +import HumanSkillsActorData from "./base/human-skills.js"; +import CharacterData from "./base/character.js"; + +const { SchemaField, NumberField, StringField, BooleanField } = + foundry.data.fields; + +export default class NPCData extends CharacterData { + static defineSchema() { + const superData = super.defineSchema(); + + return { + ...superData, + ...HumanSkillsActorData.defineSchema(), + schemaVersion: new NumberField({ initial: 1.0 }), + sanity: new SchemaField({ + value: new NumberField({ initial: 100 }), + currentBreakingPoint: new NumberField({ initial: 101 }), + }), + notes: new StringField({ initial: "" }), + shortDescription: new StringField({ initial: "" }), + showUntrainedSkills: new BooleanField({ initial: true }), + }; + } +} diff --git a/module/data/actor/unnatural.js b/module/data/actor/unnatural.js new file mode 100644 index 0000000..6a32949 --- /dev/null +++ b/module/data/actor/unnatural.js @@ -0,0 +1,25 @@ +import UnnaturalSkillsActorData from "./base/unnatural-skills.js"; +import CharacterData from "./base/character.js"; + +const { SchemaField, NumberField, StringField, BooleanField } = + foundry.data.fields; + +export default class UnnaturalData extends CharacterData { + static defineSchema() { + const superData = super.defineSchema(); + + return { + ...superData, + ...UnnaturalSkillsActorData.defineSchema(), + sanity: new SchemaField({ + notes: new StringField({ initial: "" }), + failedLoss: new StringField({ initial: "1D4" }), + successLoss: new StringField({ initial: "1" }), + }), + schemaVersion: new NumberField({ initial: 1.0 }), + notes: new StringField({ initial: "" }), + shortDescription: new StringField({ initial: "" }), + showUntrainedSkills: new BooleanField({ initial: true }), + }; + } +} diff --git a/module/data/actor/vehicle.js b/module/data/actor/vehicle.js new file mode 100644 index 0000000..e21ff07 --- /dev/null +++ b/module/data/actor/vehicle.js @@ -0,0 +1,23 @@ +import SheetSettingsActorData from "./base/sheet-settings.js"; + +const { SchemaField, NumberField, StringField, ArrayField } = + foundry.data.fields; + +export default class VehicleData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...SheetSettingsActorData.defineSchema(), + name: new StringField({ initial: "" }), + description: new StringField({ initial: "" }), + shortDescription: new StringField({ initial: "" }), + health: new SchemaField({ + value: new NumberField({ initial: 10 }), + min: new NumberField({ initial: 0 }), + max: new NumberField({ initial: 10 }), + }), + speed: new StringField({ initial: "" }), + expense: new StringField({ initial: "Standard" }), + passengers: new ArrayField(new StringField()), + }; + } +} diff --git a/module/deltagreen.js b/module/deltagreen.js index bf7d084..f481204 100644 --- a/module/deltagreen.js +++ b/module/deltagreen.js @@ -20,10 +20,22 @@ import { handleInlineActions } from "./other/inline.js"; import DGNPCSheet from "./sheets/npc-sheet.js"; import DGUnnaturalSheet from "./sheets/unnatural-sheet.js"; import DGVehicleSheet from "./sheets/vehicle-sheet.js"; +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"; 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 + agent: AgentData, + unnatural: UnnaturalData, + npc: NPCData, + vehicle: VehicleData, + }); + game.deltagreen = { DeltaGreenActor, DeltaGreenItem, diff --git a/system.json b/system.json index 1383928..758daa5 100644 --- a/system.json +++ b/system.json @@ -187,5 +187,13 @@ "units": "m" }, "primaryTokenAttribute": "health", - "secondaryTokenAttribute": "wp" + "secondaryTokenAttribute": "wp", + "documentTypes": { + "Actor": { + "agent": {}, + "unnatural": {}, + "npc": {}, + "vehicle": {} + } + } } diff --git a/template.json b/template.json index 63efaaf..68dc905 100644 --- a/template.json +++ b/template.json @@ -1,519 +1,4 @@ { - "Actor": { - "types": ["agent", "unnatural", "npc", "vehicle"], - "templates": { - "base": { - "health": { - "value": 10, - "min": 0, - "max": 10 - }, - "wp": { - "value": 10, - "min": 0, - "max": 10 - }, - "statistics": { - "str": { - "value": 10, - "distinguishing_feature": "" - }, - "con": { - "value": 10, - "distinguishing_feature": "" - }, - "dex": { - "value": 10, - "distinguishing_feature": "" - }, - "int": { - "value": 10, - "distinguishing_feature": "" - }, - "pow": { - "value": 10, - "distinguishing_feature": "" - }, - "cha": { - "value": 10, - "distinguishing_feature": "" - } - } - }, - "sheet-settings": { - "settings": { - "sorting": { - "weaponSortAlphabetical": false, - "armorSortAlphabetical": false, - "gearSortAlphabetical": false, - "tomeSortAlphabetical": false, - "ritualSortAlphabetical": false - }, - "rolling": { - "defaultPercentileModifier": 20 - } - } - }, - "human_skills": { - "skills": { - "accounting": { - "label": "Accounting", - "proficiency": 10, - "failure": false - }, - "alertness": { - "label": "Alertness", - "proficiency": 20, - "failure": false - }, - "anthropology": { - "label": "Anthropology", - "proficiency": 0, - "failure": false - }, - "archeology": { - "label": "Archeology", - "proficiency": 0, - "failure": false - }, - "artillery": { - "label": "Artillery", - "proficiency": 0, - "failure": false - }, - "athletics": { - "label": "Athletics", - "proficiency": 30, - "failure": false - }, - "bureaucracy": { - "label": "Bureaucracy", - "proficiency": 10, - "failure": false - }, - "computer_science": { - "label": "Computer Science", - "proficiency": 0, - "failure": false - }, - "criminology": { - "label": "Criminology", - "proficiency": 10, - "failure": false - }, - "demolitions": { - "label": "Demolitions", - "proficiency": 0, - "failure": false - }, - "disguise": { - "label": "Disguise", - "proficiency": 10, - "failure": false - }, - "dodge": { - "label": "Dodge", - "proficiency": 30, - "failure": false - }, - "drive": { - "label": "Drive", - "proficiency": 20, - "failure": false - }, - "firearms": { - "label": "Firearms", - "proficiency": 20, - "failure": false - }, - "first_aid": { - "label": "First Aid", - "proficiency": 10, - "failure": false - }, - "forensics": { - "label": "Forensics", - "proficiency": 0, - "failure": false - }, - "heavy_machiner": { - "label": "Heavy Machinery", - "proficiency": 10, - "failure": false - }, - "heavy_weapons": { - "label": "Heavy Weapons", - "proficiency": 0, - "failure": false - }, - "history": { - "label": "History", - "proficiency": 10, - "failure": false - }, - "humint": { - "label": "HUMINT", - "proficiency": 10, - "failure": false - }, - "law": { - "label": "Law", - "proficiency": 0, - "failure": false - }, - "medicine": { - "label": "Medicine", - "proficiency": 0, - "failure": false - }, - "melee_weapons": { - "label": "Melee Weapons", - "proficiency": 30, - "failure": false - }, - "navigate": { - "label": "Navigate", - "proficiency": 10, - "failure": false - }, - "occult": { - "label": "Occult", - "proficiency": 10, - "failure": false - }, - "persuade": { - "label": "Persuade", - "proficiency": 20, - "failure": false - }, - "pharmacy": { - "label": "Pharmacy", - "proficiency": 0, - "failure": false - }, - "psychotherapy": { - "label": "Psychotherapy", - "proficiency": 10, - "failure": false - }, - "ride": { - "label": "Ride", - "proficiency": 10, - "failure": false - }, - "search": { - "label": "Search", - "proficiency": 20, - "failure": false - }, - "sigint": { - "label": "SIGINT", - "proficiency": 0, - "failure": false - }, - "stealth": { - "label": "Stealth", - "proficiency": 10, - "failure": false - }, - "surgery": { - "label": "Surgery", - "proficiency": 0, - "failure": false - }, - "survival": { - "label": "Survival", - "proficiency": 10, - "failure": false - }, - "swim": { - "label": "Swim", - "proficiency": 20, - "failure": false - }, - "unarmed_combat": { - "label": "Unarmed Combat", - "proficiency": 40, - "failure": false - }, - "unnatural": { - "label": "Unnatural", - "proficiency": 0 - } - }, - "typedSkills": {}, - "specialTraining": [] - }, - "unnatural_skills": { - "skills": { - "accounting": { - "label": "Accounting", - "proficiency": 0, - "failure": false - }, - "alertness": { - "label": "Alertness", - "proficiency": 50, - "failure": false - }, - "anthropology": { - "label": "Anthropology", - "proficiency": 0, - "failure": false - }, - "archeology": { - "label": "Archeology", - "proficiency": 0, - "failure": false - }, - "artillery": { - "label": "Artillery", - "proficiency": 0, - "failure": false - }, - "athletics": { - "label": "Athletics", - "proficiency": 50, - "failure": false - }, - "bureaucracy": { - "label": "Bureaucracy", - "proficiency": 0, - "failure": false - }, - "computer_science": { - "label": "Computer Science", - "proficiency": 0, - "failure": false - }, - "criminology": { - "label": "Criminology", - "proficiency": 0, - "failure": false - }, - "demolitions": { - "label": "Demolitions", - "proficiency": 0, - "failure": false - }, - "disguise": { - "label": "Disguise", - "proficiency": 0, - "failure": false - }, - "dodge": { - "label": "Dodge", - "proficiency": 50, - "failure": false - }, - "drive": { - "label": "Drive", - "proficiency": 0, - "failure": false - }, - "firearms": { - "label": "Firearms", - "proficiency": 0, - "failure": false - }, - "first_aid": { - "label": "First Aid", - "proficiency": 0, - "failure": false - }, - "forensics": { - "label": "Forensics", - "proficiency": 0, - "failure": false - }, - "heavy_machiner": { - "label": "Heavy Machinery", - "proficiency": 0, - "failure": false - }, - "heavy_weapons": { - "label": "Heavy Weapons", - "proficiency": 0, - "failure": false - }, - "history": { - "label": "History", - "proficiency": 0, - "failure": false - }, - "humint": { - "label": "HUMINT", - "proficiency": 0, - "failure": false - }, - "law": { - "label": "Law", - "proficiency": 0, - "failure": false - }, - "medicine": { - "label": "Medicine", - "proficiency": 0, - "failure": false - }, - "melee_weapons": { - "label": "Melee Weapons", - "proficiency": 50, - "failure": false - }, - "navigate": { - "label": "Navigate", - "proficiency": 0, - "failure": false - }, - "occult": { - "label": "Occult", - "proficiency": 0, - "failure": false - }, - "persuade": { - "label": "Persuade", - "proficiency": 0, - "failure": false - }, - "pharmacy": { - "label": "Pharmacy", - "proficiency": 0, - "failure": false - }, - "psychotherapy": { - "label": "Psychotherapy", - "proficiency": 0, - "failure": false - }, - "ride": { - "label": "Ride", - "proficiency": 0, - "failure": false - }, - "search": { - "label": "Search", - "proficiency": 0, - "failure": false - }, - "sigint": { - "label": "SIGINT", - "proficiency": 0, - "failure": false - }, - "stealth": { - "label": "Stealth", - "proficiency": 50, - "failure": false - }, - "surgery": { - "label": "Surgery", - "proficiency": 0, - "failure": false - }, - "survival": { - "label": "Survival", - "proficiency": 0, - "failure": false - }, - "swim": { - "label": "Swim", - "proficiency": 0, - "failure": false - }, - "unarmed_combat": { - "label": "Unarmed Combat", - "proficiency": 50, - "failure": false - }, - "unnatural": { - "label": "Unnatural", - "proficiency": 0 - } - }, - "typedSkills": {}, - "specialTraining": [] - } - }, - "unnatural": { - "templates": ["base", "unnatural_skills", "sheet-settings"], - "sanity": { - "notes": "", - "failedLoss": "1D4", - "successLoss": "1" - }, - "schemaVersion": 1.0, - "notes": "", - "shortDescription": "", - "showUntrainedSkills": true - }, - "npc": { - "templates": ["base", "human_skills", "sheet-settings"], - "schemaVersion": 1.0, - "sanity": { - "value": 100, - "currentBreakingPoint": 101 - }, - "notes": "", - "shortDescription": "", - "showUntrainedSkills": true - }, - "vehicle": { - "templates": ["sheet-settings"], - "name": "", - "description": "", - "shortDescription": "", - "health": { - "value": 10, - "min": 0, - "max": 10 - }, - "speed": "", - "expense": "Standard", - "passengers": [] - }, - "agent": { - "templates": ["base", "human_skills", "sheet-settings"], - "schemaVersion": 1.0, - "sanity": { - "value": 100, - "currentBreakingPoint": 101, - "adaptations": { - "violence": { - "incident1": false, - "incident2": false, - "incident3": false - }, - "helplessness": { - "incident1": false, - "incident2": false, - "incident3": false - } - } - }, - "physical": { - "description": "(Physical description of agent)", - "wounds": "", - "firstAidAttempted": false, - "exhausted": false, - "exhaustedPenalty": -20 - }, - "biography": { - "profession": "", - "employer": "", - "nationality": "", - "sex": "", - "age": "", - "education": "" - }, - "corruption": { - "value": 0, - "haveSeenTheYellowSign": false, - "gift": "", - "insight": "" - } - } - }, "Item": { "types": [ "weapon",