From ed54e2dbd8b54e2359ee8aab847981c9b7bfcf20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Fr=C3=B6lich?= Date: Tue, 9 Sep 2025 20:41:43 +0200 Subject: [PATCH 1/9] refactor(#266): move private sanity logic into prepareContext --- CHANGELOG.md | 6 ++++++ module/sheets/base-actor-sheet.js | 15 +++++++++++++++ templates/actor/partials/sanity-agent.html | 21 +++++---------------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c7aec2..33ec08c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Release/Patch Notes +## Version 1.7.0 - ????-??-?? + +### **Tech Debt** + +- [#267](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/pull/267) - Moved private sanity logic out of templates. + ## Version 1.6.1 - 2025-09-09 > Thanks to the following new contributor: [Tobifroe](https://github.com/tobifroe). diff --git a/module/sheets/base-actor-sheet.js b/module/sheets/base-actor-sheet.js index 7b1227c..76bd6bc 100644 --- a/module/sheets/base-actor-sheet.js +++ b/module/sheets/base-actor-sheet.js @@ -94,6 +94,21 @@ export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { this._prepareSkillTooltips(); } + // Handle private sanity setting, override for GMs. + const keepSanityPrivate = game.settings.get( + "deltagreen", + "keepSanityPrivate", + ); + if (keepSanityPrivate && !game.user.isGM) { + context.maxSan = "???"; + context.currentSan = "???"; + context.keepSanityPrivate = true; + } else { + context.maxSan = this.actor.system.sanity.max; + context.currentSan = this.actor.system.sanity.value; + context.keepSanityPrivate = false; + } + // Set sanity block per actor type. context.sanityInputs = await foundry.applications.handlebars.renderTemplate( `${DGActorSheet.TEMPLATE_PATH}/partials/sanity-${this.actor.type}.html`, diff --git a/templates/actor/partials/sanity-agent.html b/templates/actor/partials/sanity-agent.html index 3a84228..cf37ebb 100644 --- a/templates/actor/partials/sanity-agent.html +++ b/templates/actor/partials/sanity-agent.html @@ -1,27 +1,16 @@ -{{#if (keepSanityPrivate)}} - -/ -
-
???
-
-{{else}} /
-
{{numberFormat actor.system.sanity.max decimals=0 sign=false}}
+
{{ maxSan }}
-{{/if}} From e377bda6444623fee0c857dcc8f2618ceec9e52e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Fr=C3=B6lich?= Date: Wed, 10 Sep 2025 09:31:50 +0200 Subject: [PATCH 2/9] chore: improve private sanity logic readability --- CHANGELOG.md | 6 -- module/sheets/base-actor-sheet.js | 144 ++++++++++++------------------ 2 files changed, 57 insertions(+), 93 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 33ec08c..7c7aec2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,5 @@ # Release/Patch Notes -## Version 1.7.0 - ????-??-?? - -### **Tech Debt** - -- [#267](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/pull/267) - Moved private sanity logic out of templates. - ## Version 1.6.1 - 2025-09-09 > Thanks to the following new contributor: [Tobifroe](https://github.com/tobifroe). diff --git a/module/sheets/base-actor-sheet.js b/module/sheets/base-actor-sheet.js index 76bd6bc..9b4e0f8 100644 --- a/module/sheets/base-actor-sheet.js +++ b/module/sheets/base-actor-sheet.js @@ -99,15 +99,11 @@ export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { "deltagreen", "keepSanityPrivate", ); - if (keepSanityPrivate && !game.user.isGM) { - context.maxSan = "???"; - context.currentSan = "???"; - context.keepSanityPrivate = true; - } else { - context.maxSan = this.actor.system.sanity.max; - context.currentSan = this.actor.system.sanity.value; - context.keepSanityPrivate = false; - } + const hideSan = keepSanityPrivate && !game.user.isGM; + + context.maxSan = hideSan ? "???" : this.actor.system.sanity.max; + context.currentSan = hideSan ? "???" : this.actor.system.sanity.value; + context.keepSanityPrivate = keepSanityPrivate; // Set sanity block per actor type. context.sanityInputs = await foundry.applications.handlebars.renderTemplate( @@ -784,110 +780,94 @@ export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { const currentGroup = typedSkills[targetSkill].group; let htmlContent = `
`; - htmlContent += ` `; + htmlContent += ` `; htmlContent += ` `; htmlContent += `
`; htmlContent += `
`; - htmlContent += ` `; + htmlContent += ` `; htmlContent += ` `; htmlContent += `
`; @@ -925,40 +905,31 @@ export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { let htmlContent = ""; htmlContent += `
`; - htmlContent += ` `; + htmlContent += ` `; htmlContent += ` `; htmlContent += `
`; htmlContent += `
`; - htmlContent += ` `; + htmlContent += ` `; htmlContent += ` `; htmlContent += `
`; @@ -1096,9 +1067,8 @@ export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { ([key, skill]) => ({ value: key, group: optionGroups.typedSkills, - label: `${game.i18n.localize(`DG.TypeSkills.${skill.group}`)} (${ - skill.label - })`, + label: `${game.i18n.localize(`DG.TypeSkills.${skill.group}`)} (${skill.label + })`, targetNumber: skill.proficiency, }), ); From d4d615e98613559039268a0825f793336dbfbbbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Fr=C3=B6lich?= Date: Wed, 10 Sep 2025 09:34:08 +0200 Subject: [PATCH 3/9] fix: use builtin input disabled helper, lint --- module/sheets/base-actor-sheet.js | 130 ++++++++++++--------- templates/actor/partials/sanity-agent.html | 4 +- 2 files changed, 79 insertions(+), 55 deletions(-) diff --git a/module/sheets/base-actor-sheet.js b/module/sheets/base-actor-sheet.js index 9b4e0f8..c82f66b 100644 --- a/module/sheets/base-actor-sheet.js +++ b/module/sheets/base-actor-sheet.js @@ -780,94 +780,110 @@ export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { const currentGroup = typedSkills[targetSkill].group; let htmlContent = `
`; - htmlContent += ` `; + htmlContent += ` `; htmlContent += ` `; htmlContent += `
`; htmlContent += `
`; - htmlContent += ` `; + htmlContent += ` `; htmlContent += ` `; htmlContent += `
`; @@ -905,31 +921,40 @@ export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { let htmlContent = ""; htmlContent += `
`; - htmlContent += ` `; + htmlContent += ` `; htmlContent += ` `; htmlContent += `
`; htmlContent += `
`; - htmlContent += ` `; + htmlContent += ` `; htmlContent += ` `; htmlContent += `
`; @@ -1067,8 +1092,9 @@ export default class DGActorSheet extends DGSheetMixin(ActorSheetV2) { ([key, skill]) => ({ value: key, group: optionGroups.typedSkills, - label: `${game.i18n.localize(`DG.TypeSkills.${skill.group}`)} (${skill.label - })`, + label: `${game.i18n.localize(`DG.TypeSkills.${skill.group}`)} (${ + skill.label + })`, targetNumber: skill.proficiency, }), ); diff --git a/templates/actor/partials/sanity-agent.html b/templates/actor/partials/sanity-agent.html index cf37ebb..d3658d2 100644 --- a/templates/actor/partials/sanity-agent.html +++ b/templates/actor/partials/sanity-agent.html @@ -3,9 +3,7 @@ breaking-point-hit{{/if }}" type="text" name="system.sanity.value" - {{#if keepSanityPrivate }} - readonly - {{/if }} + {{disabled keepSanityPrivate}} value="{{ currentSan }}" data-dtype="Number" data-tooltip="{{localize 'DG.Tooltip.CurrentSanityPartOne' }}{{actor.system.sanity.currentBreakingPoint }}{{localize 'DG.Tooltip.CurrentSanityPartTwo' }}" /> From 8a38be3a3b47aeda3f55c50a84eff1943e5ba321 Mon Sep 17 00:00:00 2001 From: reyzor1991 Date: Fri, 17 Oct 2025 11:01:47 +0300 Subject: [PATCH 4/9] ref 249, Add Actor data (#277) add actor data model --- module/data/actor/agent.js | 56 +++ module/data/actor/base/base-actor.js | 20 + module/data/actor/base/character.js | 11 + module/data/actor/base/general.js | 25 + module/data/actor/base/human-skills.js | 62 +++ module/data/actor/base/sheet-settings.js | 21 + module/data/actor/base/unnatural-skills.js | 62 +++ module/data/actor/npc.js | 24 + module/data/actor/unnatural.js | 25 + module/data/actor/vehicle.js | 23 + module/deltagreen.js | 12 + system.json | 10 +- template.json | 515 --------------------- 13 files changed, 350 insertions(+), 516 deletions(-) create mode 100644 module/data/actor/agent.js create mode 100644 module/data/actor/base/base-actor.js create mode 100644 module/data/actor/base/character.js create mode 100644 module/data/actor/base/general.js create mode 100644 module/data/actor/base/human-skills.js create mode 100644 module/data/actor/base/sheet-settings.js create mode 100644 module/data/actor/base/unnatural-skills.js create mode 100644 module/data/actor/npc.js create mode 100644 module/data/actor/unnatural.js create mode 100644 module/data/actor/vehicle.js 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", From 69b3ee069f51598355a73d8a3841480d2e8ec3e8 Mon Sep 17 00:00:00 2001 From: Samuel Lopez Date: Fri, 17 Oct 2025 11:47:16 +0200 Subject: [PATCH 5/9] feat (#211): move macros to System macros folder --- CHANGELOG.md | 6 ++++++ system.json | 11 +++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c7aec2..2160bd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Release/Patch Notes +## Version 1.7.0 - 2025-xx-xx + +### **Features:** + +- [#211](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/211) - Move macros to System macros folder in compendium. + ## Version 1.6.1 - 2025-09-09 > Thanks to the following new contributor: [Tobifroe](https://github.com/tobifroe). diff --git a/system.json b/system.json index 758daa5..06f140d 100644 --- a/system.json +++ b/system.json @@ -101,8 +101,15 @@ "armor", "hand-to-hand-weapons", "agent-pregens", - "operation-code-name-generator-tables", - "operation-code-name-generator-macro" + "operation-code-name-generator-tables" + ], + "folders": [ + { + "name": "System macros", + "sorting": "a", + "color": "#67b1e0", + "packs": ["operation-code-name-generator-macro"] + } ] } ], From 958e81dfa0fd282a83f50bd716dae07e4e39b512 Mon Sep 17 00:00:00 2001 From: Hrunh <65298324+Hrunh@users.noreply.github.com> Date: Thu, 11 Dec 2025 01:08:19 +0100 Subject: [PATCH 6/9] French Language Update New EN field added and translated in FR file --- lang/fr.json | 140 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 123 insertions(+), 17 deletions(-) diff --git a/lang/fr.json b/lang/fr.json index 8e68ba9..50ed52f 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -4,7 +4,6 @@ "DG.RollLuck": "Jet de Chance", "DG.Luck": "Chance", - "DG.FallbackText.ProfessionAndOrRank": "PROFESSION (RANG LE CAS ÉCHÉANT)", "DG.FallbackText.newItem": "Nouveau/el/elle {type}", "DG.Skills.accounting": "Comptabilité", @@ -46,6 +45,44 @@ "DG.Skills.unnatural": "Inconcevable", "DG.Skills.flight": "Voler", + "DG.Skills.Tooltip.accounting": "Repérez les signaux d'alerte financiers tels que les actifs cachés, les sociétés écrans ou les détournements de fonds.", + "DG.Skills.Tooltip.alertness": "Remarquez les dangers cachés, les mouvements subtils ou les sons discrets avant qu'ils ne deviennent des menaces.", + "DG.Skills.Tooltip.anthropology": "Comprendre la moralité, les croyances religieuses, les coutumes et les moeurs, ainsi qu’à identifier (mais pas à traduire) les langues obscures", + "DG.Skills.Tooltip.archeology": "Analyser le mode de vie d’un peuple à partir de ses ruines, à déterminer l’âge d’une relique, à distinguer un véritable vestige d’un faux et à identifier (mais pas à traduire) les langues humaines.", + "DG.Skills.Tooltip.artillery": "Usage sûr et précis des mortiers, missiles, canons de tank et autres armes d’artillerie lourde.", + "DG.Skills.Tooltip.athletics": "Courez, grimpez, sautez et lancez avec une force et une agilité entraînées.", + "DG.Skills.Tooltip.bureaucracy": "Manipuler les règles et les individus qui dirigent une organisation.", + "DG.Skills.Tooltip.computer_science": "Connaissance approfondie des ordinateurs, des systèmes informatiques et des programmes qui les régissent.", + "DG.Skills.Tooltip.criminology": "Connaissance du comportement des criminels et conspirateurs.", + "DG.Skills.Tooltip.demolitions": "Manipulation sans danger des explosifs en situation de crise.", + "DG.Skills.Tooltip.disguise": "Consiste à altérer l’apparence, la voix, la posture, la gestuelle et les manières de votre Agent pour éviter qu’on le reconnaisse, le tout sans attirer l ’attention.", + "DG.Skills.Tooltip.dodge": "Échapper au danger et aux attaques grâce à l’instinct et aux réflexes.", + "DG.Skills.Tooltip.drive": "Piloter une automobile ou une moto sans danger en situation de crise.", + "DG.Skills.Tooltip.firearms": "Tirer avec précision, en toute sécurité, à l’aide de petites armes à feu lors d’un combat.", + "DG.Skills.Tooltip.first_aid": "Traitement initial et stabilisation des blessures.", + "DG.Skills.Tooltip.forensics": "Permet de réunir des informations et des preuves au moyen d’un équipement approprié.", + "DG.Skills.Tooltip.heavy_machiner": "Manoeuvrer en toute sécurité un tracteur, une grue, un bulldozer, un tank, un poids lourd ou une autre machine volumineuse en situation de crise.", + "DG.Skills.Tooltip.heavy_weapons": "Employer avec sécurité et précision des armes lourdes portatives telles que des mitrailleuses et des lance-roquettes.", + "DG.Skills.Tooltip.history": "Dévoiler des faits et des théories relatives au passé de l’humanité.", + "DG.Skills.Tooltip.humint": "Cette compétence procure des informations sur un sujet grâce à l’observation, la conversation ou l’examen du comportement et des relations.", + "DG.Skills.Tooltip.law": "Exploiter les lois et les tribunaux au profit de votre Agent.", + "DG.Skills.Tooltip.medicine": "Étude et traitement des blessures et maladies. Sert à diagnostiquer la cause d’une blessure, d’une maladie ou d’une intoxication.", + "DG.Skills.Tooltip.melee_weapons": "Usage létal des armes rapprochées au combat.", + "DG.Skills.Tooltip.navigate": "Permet de rapidement retrouver son chemin grâce à des plans, des cartes et des tableaux, des méthodes d’orientation, des instruments ou en naviguant à l’estime.", + "DG.Skills.Tooltip.occult": "L’étude de l’inconcevable sous l’angle des traditions humaines, ce qui comprend des domaines comme les théories conspirationnistes, l’occultisme traditionnel, les sciences parallèles et la cryptozoologie.", + "DG.Skills.Tooltip.persuade": "Altérer une décision ou un désir solide chez autrui.", + "DG.Skills.Tooltip.pharmacy": "Connaissance des médicaments, de leurs ingrédients et de leur mode de fabrication, de leurs effets, de la posologie et des contre-indications.", + "DG.Skills.Tooltip.psychotherapy": "Diagnostic et traitement des maladies mentales.", + "DG.Skills.Tooltip.ride": "Gérer, dresser et monter des chevaux, ânes, chameaux et autres animaux de ce genre.", + "DG.Skills.Tooltip.search": "Retrouver des objets cachés ou placés à l’abri des regards.", + "DG.Skills.Tooltip.sigint": "Renseignements issus des transmissions. Comprend le cryptage, la surveillance des communications et de l’électronique, les systèmes de sécurité électroniques, la surveillance des communications radio et numérique, ainsi que l’élaboration et le déchiffrement de codes.", + "DG.Skills.Tooltip.stealth": "Dissimuler votre présence ou vos activités.", + "DG.Skills.Tooltip.surgery": "Traitement d’une blessure ou d’une anomalie par des moyens invasifs.", + "DG.Skills.Tooltip.survival": "Sert à trouver des pistes et des traces, à planifier une expédition, à prévoir le temps qu’il fait, à reconnaître les caractères inhabituels de la faune ou de la flore, à exploiter l’environnement pour glaner des informations ainsi qu’à trouver de la nourriture, de l’eau et des abris.", + "DG.Skills.Tooltip.swim": "Pour la plupart des Agents, la natation est un loisir. Servez-vous de la compétence Natation lors des situations de crise.", + "DG.Skills.Tooltip.unarmed_combat": "Autodéfense. Servez-vous de Combat à mains nues pour blesser ou tuer un adversaire avec vos seuls poings (ainsi que vos pieds, vos coudes, vos dents et votre tête).", + "DG.Skills.Tooltip.unnatural": "Connaissance des secrets fondamentaux de l’univers, propres à provoquer la folie.", + "DG.Skills.AddTypedOrCustomSkill": "Ajouter une compétence personnalisée", "DG.Skills.AddSkill": "Ajout Compétence", "DG.Skills.Apply": "Appliquer", @@ -67,6 +104,14 @@ "DG.TypeSkills.Science": "Science", "DG.TypeSkills.Other": "Autre", + "DG.TypeSkills.Tooltip.Art": "Maîtrise de la création ou de l’exécution d’une oeuvre capable d’altérer les émotions et les opinions.", + "DG.TypeSkills.Tooltip.Craft": "Fabriquer et réparer des outils et structures sophistiqués.", + "DG.TypeSkills.Tooltip.ForeignLanguage": "Parler couramment une autre langue. Chaque langue étrangère représente une compétence distincte.", + "DG.TypeSkills.Tooltip.MilitaryScience": "Connaissance de la culture, des techniques et des réglementations militaires.", + "DG.TypeSkills.Tooltip.Pilot": "Piloter, diriger et naviguer avec des véhicules aquatiques, aériens ou aérospatiaux.", + "DG.TypeSkills.Tooltip.Science": "Étude approfondie des phénomènes qui nous entourent.", + "DG.TypeSkills.Tooltip.Other": "Autre", + "DG.SpecialTraining.Dialog.CreateSpecialTraining": "Ajouter un Entraînement Spécial", "DG.SpecialTraining.Dialog.DropDown.CustomSkills": "Compétences Personnalisées/Typées", "DG.SpecialTraining.Dialog.DropDown.Skills": "Compétences", @@ -86,23 +131,41 @@ "DG.Attributes.pow": "POU", "DG.Attributes.cha": "CHA", - "DG.Navigation.Skills": "Compétences", - "DG.Navigation.Physical": "Statistiques", - "DG.Navigation.Mental": "Psychologie", - "DG.Navigation.Gear": "Équipement", - "DG.Navigation.CV": "Biographie", - "DG.Navigation.Contacts": "Attaches", + "DG.Attributes.Tooltip.HP": "Points de vie, un personnage devient inconscient à 2PV et meurt à 0PV", + "DG.Attributes.Tooltip.WP": "Les Points de Volonté (VOL) sont le carburant psychologique. Les Agents ont besoin de Points de Volonté pour continuer à travailler malgré l'épuisement ou les situations mentalement éprouvantes. Voir la page 47 du Manuel de l'agent pour plus de détails", + "DG.Attributes.Tooltip.SAN": "Les points de santé mentale (SAN) indiquent un lien avec l'humanité et la réalité telles que la plupart des gens les perçoivent. Cliquer pour effectuer un jet de SAN.", + "DG.Attributes.Tooltip.str": "Voir Page 19 du Manuel de l'Agent - Force", + "DG.Attributes.Tooltip.con": "Voir Page 19 du Manuel de l'Agent - Constitution", + "DG.Attributes.Tooltip.dex": "Voir Page 19 du Manuel de l'Agent - Dexterité", + "DG.Attributes.Tooltip.int": "Voir Page 19 du Manuel de l'Agent - Intelligence", + "DG.Attributes.Tooltip.pow": "Voir Page 19 du Manuel de l'Agent - Pouvoir", + "DG.Attributes.Tooltip.cha": "Voir Page 19 du Manuel de l'Agent - Charisme", - "DG.About.OnlineHelp": "Documentation en ligne", - "DG.About.OnlineHelpTooltip": "Lancer un navigateur avec l'aide en ligne de GitHub", - "DG.About.OnlineBugTracker": "Questions, rapports de bug ou demandes de developpement", - "DG.About.OnlineBugTrackerTooltip": "Lancer un navigateur avec l'issue tracker de GitHub", + "DG.Navigation.Agent.skills": "Compétences", + "DG.Navigation.Agent.physical": "Statistiques", + "DG.Navigation.Agent.motivations": "Psychologie", + "DG.Navigation.Agent.gear": "Équipement", + "DG.Navigation.Agent.bio": "Biographie", + "DG.Navigation.Agent.bonds": "Attaches", + "DG.Navigation.NPC.skills": "Compétences & Formation", + "DG.Navigation.NPC.gear": "Attaques & Capacités", + "DG.Navigation.Vehicle.gear": "Équipement", + "DG.Navigation.Vehicle.notes": "Notes", + + "DG.About.Changelog": "CHANGELOG (ONLINE)", + "DG.About.Copyright": "Publié par Arc Dream Publishing en accord avec Delta Green Partnership. La propriété intellectuelle connue sous le nom de Delta Green est une marque déposée et protégée par les droits d'auteur appartenant à Delta Green Partnership, qui en a autorisé l'utilisation ici.", + "DG.About.License": "Le contenu de ce système est concédé sous licence conformément aux conditions générales incluses dans le fichier licence, à l'exception des éléments qui font partie de la propriété intellectuelle de Delta Green.", + "DG.About.OnlineHelp": "Documentation du système sur (ONLINE)", + "DG.About.OnlineHelpTooltip": "Lancer le navigateur avec l'aide GitHub en ligne.", + "DG.About.OnlineBugTracker": "Questions, rapports de bug ou demandes de fonctionnalités (ONLINE)", + "DG.About.OnlineBugTrackerTooltip": "Lancer le navigateur avec le suivi des problèmes GitHub.", "DG.Roll.Rolling": "Jet de dés", "DG.Roll.Target": "Cible: ", "DG.Roll.Success": "Succés", "DG.Roll.Failure": "Échec", - "DG.Roll.Critical": "Critique", + "DG.Roll.CriticalSuccess": "Succés critique!", + "DG.Roll.CriticalFailure": "Échec critique!", "DG.Roll.Lethality": "Létalité", "DG.Roll.Lethal": "Létal", "DG.Roll.For": "Pour", @@ -119,6 +182,7 @@ "DG.Generic.AddButtonLabel": "Ajouter", "DG.Mental.BreakingPoint": "Seuil de Rupture: ", + "DG.Mental.Tooltip.BreakingPoint": "le Seuil de Rupture est le point à partir duquel la perte de SAN déclenche des troubles psychiques à long terme. Dès que la SAN de l’Agent atteint le Seuil de Rupture, il reçoit un trouble. Réinitialisez le Seuil de Rupture : il est désormais égal à la nouvelle valeur de SAN moins POU", "DG.Mental.Reset": "Réinit.", "DG.Mental.SanityLossIncidentsLabel": "Perte de SAN n'ayant pas entrainé la folie", "DG.Mental.Violence": "Violence", @@ -128,6 +192,8 @@ "DG.Mental.Motivations": "Motivations", "DG.Mental.Disorders": "Troubles psychiques", + "DG.Gear.WeaponTypes.Firearms": "Armes à feu", + "DG.Gear.WeaponTypes.Melee": "Mêlée", "DG.Gear.Weapons": "ARMES", "DG.Gear.Armor": "ARMURE ET MATÉRIEL", "DG.Gear.OtherGear": "AUTRES ÉQUIPEMENTS", @@ -153,11 +219,8 @@ "DG.Bonds.Score": "Score", "DG.Bonds.NewBond": "Nouvelle Attache", - "DG.Attributes.Tooltip.HP": "Points de vie, un personnage devient inconscient à 2PV et meurt à 0PV", "DG.Tooltip.MaximumHP": "La Santé maximum est la moyenne de FOR+CON, arrondi au supérieur", - "DG.Attributes.Tooltip.WP": "Les Points de Volonté (VOL) sont le carburant psychologique. Les Agents ont besoin de Points de Volonté pour continuer à travailler malgré l'épuisement ou les situations mentalement éprouvantes. Voir la page 47 du Manuel de l'agent pour plus de détails", "DG.Tooltip.MaximumWP": "La Volonté maximum est égale au POUVOIR", - "DG.Attributes.Tooltip.SAN": "Cliquer pour effectuer un jet de Santé Mentale", "DG.Tooltip.CurrentSanityPartOne": "Santé Mentale actuelle, le seuil de rupture actuel est ", "DG.Tooltip.CurrentSanityPartTwo": ", cliquez sur SAN ci-dessus pour effectuer un jet de santé mentale", "DG.Tooltip.MaximumSanity": "La Santé Mentale maximum est égale à 99 moins la compétence Paranaturel", @@ -191,7 +254,7 @@ "DG.ItemWindow.Motivations.DisorderNameTooltip": "Un trouble psychique remplace une motivation après avoir atteint un seuil de rupture", "DG.ItemWindow.Motivations.IsDisorderTooltip": "Cochez cette case si vous ajoutez un trouble psychique, ou si une motivation existante a été perdue en raison de l'acquisition d'un trouble", "DG.ItemWindow.Motivations.DisorderHasBeenCured": "Le trouble psychique a été \"Soigné\"", - "DG.ItemWindow.Motivations.DisorderHasBeenCuredTooltip": "Un succès critique sur un jet de chance peut guérir un trouble psychique. Il peut cependant réapparaître la prochaine fois qu'un seuil de rupture est atteint", + "DG.ItemWindow.Motivations.DisorderHasBeenCuredTooltip": "Un succès critique sur un jet de chance peut guérir un trouble psychique. Il peut cependant réapparaître la prochaine fois qu'un seuil de rupture est atteint", "DG.ItemWindow.Gear.Attributes": "Caractéristiques", "DG.ItemWindow.Gear.Description": "Description", @@ -247,7 +310,9 @@ "DG.Sheet.BlockHeaders.BreakingPointAndAdaptations": "SEUIL DE RUPTURE ET ADAPTATIONS", "DG.Sheet.BlockHeaders.MotivationsAndDisorders": "MOTIVATIONS ET TROUBLES PSYCHIQUES", "DG.Sheet.BlockHeaders.PersonalInfoCV": "DÉTAILS PERSONNELS ET NOTES", - "DG.Sheet.BlockHeaders.BondsRelationshipsContacts": "ATTACHES", + "DG.Sheet.BlockHeaders.BondsRelationshipsContacts": "ATTACHES, RELATIONS ET CONTACTS", + + "DG.AgentSheet.ProfessionPlaceholder": "PROFESSION (RANG LE CAS ÉCHÉANT)", "DG.UnnaturalSheet.HideUntrainedSkillsLabel": "Cacher compétences inconnues", "DG.UnnaturalSheet.NotesLabel": "Notes", @@ -278,6 +343,12 @@ "DG.ItemWindow.Weapons.SkillModifier": "Modificateur de compétence", "DG.ItemWindow.Custom": "Personnalisé", + "DG.Sheet.class.item": "Feuille d'Équipement", + "DG.Sheet.class.agent": "Feuille d'Agent", + "DG.Sheet.class.npc": "Feuille de PNJ", + "DG.Sheet.class.unnatural": "Feuille d'Inconcevable", + "DG.Sheet.class.vehicle": "Feuille de Véhicule", + "TYPES.Actor.agent": "Agent", "TYPES.Actor.npc": "PNJ", "TYPES.Actor.unnatural": "Inconcevable", @@ -315,6 +386,41 @@ "DG.ItemWindow.Ritual.StudyTime": "Temps d'étude", "DG.ItemWindow.Ritual.LearnedSanityDamage": "Dégâts SAN Étude", + "DG.MissionPaused": "Mission en pause", + + "DG.Settings.charactersheet.name": "Style de Feuille de Personnage", + "DG.Settings.charactersheet.hint": "Choisissez le style des fiches de Personnage. Le Programme est un style gouvernemental plus moderne, tandis que Les Cowboys et les Hors-la-loi ont un style machine à écrire plus ancien et plus brut.", + "DG.Settings.charactersheet.cowboys": "Les Cowboys", + "DG.Settings.charactersheet.outlaws": "Les Hors-la-loi", + "DG.Settings.charactersheet.program": "Le Programme", + "DG.Settings.sortskills.name": "Trier les comp. par colonne?", + "DG.Settings.sortskills.hint": "Coché: tri par colonne. Non coché: tri par ligne.", + "DG.Settings.hideSkillTooltips.name": "Masquer les infobulles des compétences", + "DG.Settings.hideSkillTooltips.hint": "Ne pas afficher les infobulles des compétences dans les fiches d'agent.", + "DG.Settings.keepSanityPrivate.name": "Gardez la SAN privée", + "DG.Settings.keepSanityPrivate.hint": "Masquer la santé mentale des joueurs dans les fiches d'agent et les jets de dés associés.", + "DG.Settings.skillImprovementFormula.name": "Jet d'amélioration des compétences par défaut", + "DG.Settings.skillImprovementFormula.hint": " Par défaut, 1d4. Il y a eu plusieurs errata à ce sujet, choisissez celui qui correspond le mieux au rythme de votre partie.", + "DG.Settings.skillImprovementFormula.1": "+1%", + "DG.Settings.skillImprovementFormula.2": "+1D3%", + "DG.Settings.skillImprovementFormula.3": "+1D4%", + "DG.Settings.skillImprovementFormula.4": "+1D4-1%", + "DG.Settings.alwaysShowHypergeometrySectionForPlayers.name": "Afficher la section Hypergéométrie", + "DG.Settings.alwaysShowHypergeometrySectionForPlayers.hint": "Afficher toujours la section des objets hypergéométriques (c'est-à-dire les rituels et les grimoires) sur les fiches des agents, même si l'agent ne possède aucun objet de ce type.", + "DG.Settings.showImpossibleLandscapesContent.name": "Aficher le contenu Impossible Landscapes", + "DG.Settings.showImpossibleLandscapesContent.hint": "Afficher les champs spécifiques à Impossible Landscapes dans les fiches d'agent. Ces champs ne sont visibles que par le MJ, même si ce paramètre est coché.", + "DG.Settings.skillFailure.name": "Marquer automatiquement l'échec d'une compétence", + "DG.Settings.skillFailure.hint": "Activez ce paramètre pour toujours cocher la case « Échec » en cas d'échec d'une compétence. Le MJ peut annuler l'action à partir du message du jet dans le chat.", + "DG.Settings.Saved": "Les paramètres actuels ont été enregistrés.", + + "DG.SettingsMenu.automation.name": "Menu Automatisaton", + "DG.SettingsMenu.automation.label": "Menu Automatisaton", + "DG.SettingsMenu.automation.title": "Config. Automatisation", + + "DG.SettingsMenu.handler.name": "Config. Officier Traitant", + "DG.SettingsMenu.handler.label": "Config. Officier Traitant", + "DG.SettingsMenu.handler.title": "Config. Officier Traitant seulement", + "DG.Messages.Skillsmark.Marked": "Cette compétence est marquée.", "DG.Messages.Skillsmark.Tooltip": "Voir p. 29 du Manuel de l'agent." } From c97750cf8cc2773ec673b5e9a560e1a2f8f9c872 Mon Sep 17 00:00:00 2001 From: Hrunh <65298324+Hrunh@users.noreply.github.com> Date: Thu, 11 Dec 2025 01:25:35 +0100 Subject: [PATCH 7/9] French language update - Errata "Language" modification missing --- lang/fr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lang/fr.json b/lang/fr.json index 50ed52f..d6646db 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -369,10 +369,10 @@ "DG.Ritual.Name": "Nom", "DG.Tome.Name": "Titre", - "DG.Tome.Language": "Language", + "DG.Tome.Language": "Langage", "DG.Tome.StudyTime": "Temps d'Étude", "DG.ItemWindow.Tome.Description": "Description", - "DG.ItemWindow.Tome.LanguagePlaceholder": "Language", + "DG.ItemWindow.Tome.LanguagePlaceholder": "Langage", "DG.ItemWindow.Tome.StudyTime": "Temps d'Étude", "DG.ItemWindow.Tome.OccultIncrease": "Augmentation en Occultisme", "DG.ItemWindow.Tome.UnnaturalIncrease": "Augmentation en Inconcevable", From ee9d9a179b52aa2c53bbc8573f32dc8a58572361 Mon Sep 17 00:00:00 2001 From: jalensailin Date: Thu, 11 Dec 2025 23:06:29 -0500 Subject: [PATCH 8/9] Add hotfix-dev release to github action workflow --- .github/actions/build-packs/action.yml | 3 +- .github/actions/setup-node/action.yml | 3 +- .github/actions/zip-system/action.yml | 15 +---- .github/workflows/publish-dev-release.yml | 68 +++++++++++++++++------ CONTRIBUTING.md | 3 +- 5 files changed, 59 insertions(+), 33 deletions(-) diff --git a/.github/actions/build-packs/action.yml b/.github/actions/build-packs/action.yml index ec50a58..1c9ffd2 100644 --- a/.github/actions/build-packs/action.yml +++ b/.github/actions/build-packs/action.yml @@ -1,5 +1,6 @@ name: "Build Compendium Packs" description: "Builds the compendium pack binaries from source JSON files" + runs: using: "composite" steps: @@ -7,5 +8,5 @@ runs: uses: ./.github/actions/setup-node - name: Build Compendium Packs - run: ./build/build-packs.sh shell: bash + run: ./build/build-packs.sh diff --git a/.github/actions/setup-node/action.yml b/.github/actions/setup-node/action.yml index f36e1de..1b77216 100644 --- a/.github/actions/setup-node/action.yml +++ b/.github/actions/setup-node/action.yml @@ -1,5 +1,6 @@ name: "Setup Node Project" description: "Sets up a Node.js project" + runs: using: "composite" steps: @@ -10,5 +11,5 @@ runs: cache: npm - name: Install dependencies - run: npm ci shell: bash + run: npm ci diff --git a/.github/actions/zip-system/action.yml b/.github/actions/zip-system/action.yml index ab61cdd..05de808 100644 --- a/.github/actions/zip-system/action.yml +++ b/.github/actions/zip-system/action.yml @@ -1,27 +1,18 @@ name: "Zip Project" description: "Zips the project for distribution" -inputs: - path: - description: "Path to output directory for zip file" - required: false - default: "" runs: using: "composite" steps: - name: Zip shell: bash run: | - if [[ -z "${{ inputs.path }}" ]]; then - OUTPUT_PATH="deltagreen.zip" - else - OUTPUT_PATH="${{ inputs.path }}/deltagreen.zip" - fi - zip -r "${OUTPUT_PATH}" . \ + zip -r deltagreen.zip . \ -x "packs/source/*" \ -x "build/*" \ -x "dist/*" \ -x ".*" \ -x "package.json" \ -x "package-lock.json" \ - -x "node_modules/*" + -x "node_modules/*" \ + -x "site/*" diff --git a/.github/workflows/publish-dev-release.yml b/.github/workflows/publish-dev-release.yml index b867b12..fbd3dd0 100644 --- a/.github/workflows/publish-dev-release.yml +++ b/.github/workflows/publish-dev-release.yml @@ -1,19 +1,15 @@ -name: Dev Build (GitHub Pages) - on: push: branches: - master + - hotfix/** workflow_dispatch: -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages permissions: contents: read pages: write id-token: write -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. concurrency: group: "pages" cancel-in-progress: false @@ -23,37 +19,73 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout + # ------------------------------- + # 1. Checkout SOURCE code + # ------------------------------- + - name: Checkout source repo uses: actions/checkout@v4 + # ------------------------------- + # 2. Create useful variables/output. + # ------------------------------- + - name: Compute branch folder + id: vars + shell: bash + run: | + BRANCH="${GITHUB_REF#refs/heads/}" + + if [[ "$BRANCH" == "master" ]]; then + TARGET="dev" + NON_TARGET="hotfix" + else + TARGET="hotfix" + NON_TARGET="dev" + fi + + echo "target=$TARGET" >> $GITHUB_OUTPUT + echo "non_target=$NON_TARGET" >> $GITHUB_OUTPUT + + # ------------------------------- + # 3. Build and Zip the system + # ------------------------------- - name: Build Packs uses: ./.github/actions/build-packs - name: Substitute Download Link uses: TomaszKandula/variable-substitution@v1.0.1 with: - files: "system.json" + files: system.json env: - version: dev - download: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/dev/deltagreen.zip - - - name: Copy system.json - run: mkdir -p dist/dev && cp system.json dist/dev/dev-system.json + version: ${{ steps.vars.outputs.target }} + download: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${{ steps.vars.outputs.target }}/deltagreen.zip - name: Zip uses: ./.github/actions/zip-system - with: - path: "dist/dev" - # Deploy to GitHub Pages (see https://github.com/actions/starter-workflows/blob/main/pages/static.yml) + # ------------------------------- + # 4. Deploy to Github Pages + # ------------------------------- + - name: Create Site Structure + shell: bash + run: | + # Create site directories. + mkdir -p site/dev site/hotfix + + # Download files from non-target build. + URL="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${{ steps.vars.outputs.non_target }}" + wget -O site/${{ steps.vars.outputs.non_target }}/deltagreen.zip "$URL"/deltagreen.zip + wget -O site/${{ steps.vars.outputs.non_target }}/system.json "$URL"/system.json + + # Copy files from current build. + cp system.json deltagreen.zip site/${{ steps.vars.outputs.target }}/ + - name: Setup Pages uses: actions/configure-pages@v5 - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: - path: "dist" + path: site - - name: Deploy to GitHub Pages - id: deployment + - name: Deploy uses: actions/deploy-pages@v4 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 07298f9..acbf6db 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -222,7 +222,8 @@ It is difficult to create a one-size-fits-all procedure for testing, because eac - If you do not follow the above advice, be aware that opening your main world while you have an in-progress (non-release) version of the system installed **will almost certainly break things in a way that cannot be fixed**. To go back to the release version of the system, uninstall the test build, and reinstall from the in-Foundry system browser. - Update to the target build: - Development setup: `git checkout` the target branch (or `master` for merged work), then restart Foundry. - - No dev setup: Install or update the system from the dev manifest: + - No dev setup: Install or update the system from the dev manifest: + - **Note**: Testing a **hotfix** branch? Use the hotfix manifest instead: - Use a clean test world: - Create a fresh world - Note, this is a good practice, but is not always strictly necessary. If you run into anything weird, a completely fresh world is always a good rule-out test. From c8b51b154eaa6e2fa9d296604103f6ca0e2dfd2a Mon Sep 17 00:00:00 2001 From: jalensailin Date: Fri, 12 Dec 2025 02:53:09 -0500 Subject: [PATCH 9/9] Add commit sha to testing version in manifest --- .github/workflows/publish-dev-release.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish-dev-release.yml b/.github/workflows/publish-dev-release.yml index fbd3dd0..e00daf7 100644 --- a/.github/workflows/publish-dev-release.yml +++ b/.github/workflows/publish-dev-release.yml @@ -45,6 +45,9 @@ jobs: echo "target=$TARGET" >> $GITHUB_OUTPUT echo "non_target=$NON_TARGET" >> $GITHUB_OUTPUT + - name: Set version + run: echo "SHORT_SHA=${GITHUB_SHA::7}" >> $GITHUB_ENV + # ------------------------------- # 3. Build and Zip the system # ------------------------------- @@ -56,7 +59,7 @@ jobs: with: files: system.json env: - version: ${{ steps.vars.outputs.target }} + version: ${{ steps.vars.outputs.target }}+${{ env.SHORT_SHA }} download: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${{ steps.vars.outputs.target }}/deltagreen.zip - name: Zip