diff --git a/.gitignore b/.gitignore index 9bada71..6f508c9 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,3 @@ styles/*.css # Node Modules node_modules/ -# Foundry VTT -packs/* - diff --git a/css/fvtt-cthulhu-eternal.css b/css/fvtt-cthulhu-eternal.css index 4b67ca7..e2fff05 100644 --- a/css/fvtt-cthulhu-eternal.css +++ b/css/fvtt-cthulhu-eternal.css @@ -304,20 +304,61 @@ i.fvtt-cthulhu-eternal { font-size: calc(var(--font-size-standard) * 1.4); width: 400px; } +.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san { + align-content: flex-start; +} .fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san input { min-width: 2.2rem; + max-width: 2.2rem; + margin-bottom: 4px; +} +.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san select { + min-width: 6rem; + max-width: 6rem; +} +.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .rollable:hover, +.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; + font-size: 0.9rem; } .fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .san-checkbox { min-width: 1rem; max-width: 1rem; } -.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .label-field { - flex-grow: 0; +.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .label-short-field { + font-size: 0.9rem; + max-width: 3rem; + min-width: 3rem; + flex-grow: 1; +} +.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .label-recovery { margin-left: 4px; } +.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .label-field { + font-size: 0.9rem; + max-width: 6rem; + min-width: 6rem; + flex-grow: 1; +} +.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .label-bp { + flex-grow: 1; + max-width: 3rem; + min-width: 3rem; + margin-left: 4px; +} +.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .label-insanity { + flex-grow: 1; + margin-left: 4px; + max-width: 8rem; + min-width: 8rem; +} .fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .spacing { margin-left: 4px; } +.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .d100 { + flex: 0; +} .fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .willpower input { min-width: 2.4rem; max-width: 2.4rem; @@ -422,6 +463,14 @@ i.fvtt-cthulhu-eternal { .fvtt-cthulhu-eternal .protagonist-biography .field-label { margin-left: 8px; } +.fvtt-cthulhu-eternal .protagonist-biography .adapted { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 8px; +} +.fvtt-cthulhu-eternal .protagonist-biography .adapted label { + min-width: 20rem; +} .fvtt-cthulhu-eternal .protagonist-biography .features, .fvtt-cthulhu-eternal .protagonist-biography .biodata { display: grid; diff --git a/lang/en.json b/lang/en.json index 86496b2..586c2db 100644 --- a/lang/en.json +++ b/lang/en.json @@ -38,6 +38,12 @@ "feature": { "label": "Feature" }, + "adaptedToViolence": { + "label": "Adapted to violence" + }, + "adaptedToHelplessness": { + "label": "Adapted to helplessness" + }, "harshness": { "label": "Harshness" }, @@ -86,6 +92,12 @@ } } }, + "Insanity": { + "None": "None", + "Flee": "Flee", + "Submit": "Submit", + "Struggle": "Struggle" + }, "Skill": { "Unnatural": "Unnatural", "Melee": "Melee Weapons", @@ -262,9 +274,13 @@ "veryHarsh": "Very Harsh" }, "Label": { + "sanBPShort": "BP", + "tempInsanity": "Temp. Insanity", "distinguishingFeatures": "Distinguishing Features", - "titleSkill": "Skill", - "titleWeapon": "Weapon", + "titleSkill": "Skill Roll", + "titleWeapon": "Weapon Roll", + "titleCharacteristic": "Characteristic Roll", + "titleSAN": "SAN Roll", "biodata": "Biodata", "skill": "Skill", "modifier": "Modifier", @@ -316,6 +332,7 @@ "criticalSuccess": "Critical Success", "criticalFailure": "Critical Failure", "Characteristic": "Characteristic", + "characteristic": "Characteristic", "targetScore": "Target Score", "gears": "Gears", "armors": "Armors", diff --git a/module/applications/sheets/protagonist-sheet.mjs b/module/applications/sheets/protagonist-sheet.mjs index 530c3a2..42f1ad1 100644 --- a/module/applications/sheets/protagonist-sheet.mjs +++ b/module/applications/sheets/protagonist-sheet.mjs @@ -207,6 +207,11 @@ export default class CthulhuEternalProtagonistSheet extends CthulhuEternalActorS li = $(event.currentTarget).parents(".item"); item = this.actor.items.get(li.data("item-id")); break + case "san": + item = foundry.utils.duplicate(this.actor.system.san) + item.name = game.i18n.localize("CTHULHUETERNAL.Label.SAN") + item.targetScore = item.value + break; default: throw new Error(`Unknown roll type ${rollType}`) } diff --git a/module/config/system.mjs b/module/config/system.mjs index 2d61256..939c1d9 100644 --- a/module/config/system.mjs +++ b/module/config/system.mjs @@ -34,6 +34,13 @@ export const AVAILABLE_SETTINGS = { postapo: "CTHULHUETERNAL.Settings.PostApo" } +export const INSANITY = { + "none": "CTHULHUETERNAL.Insanity.None", + "flee": "CTHULHUETERNAL.Insanity.Flee", + "struggle": "CTHULHUETERNAL.Insanity.Struggle", + "submit": "CTHULHUETERNAL.Insanity.Submit" +} + export const ERA_CSS = { jazz: { primaryFont: "RozhaOne", secondaryFont: "RozhaOne", titleFont: "Broadway", imgFilter: "brightness(0) saturate(100%) invert(52%) sepia(9%) saturate(2368%) hue-rotate(360deg) brightness(86%) contrast(84%)" }, modern: { primaryFont: "Georama", secondaryFont: "Georama", titleFont: "Georama", imgFilter: "brightness(0) saturate(100%) invert(92%) sepia(11%) saturate(1214%) hue-rotate(51deg) brightness(93%) contrast(86%)" }, @@ -181,5 +188,6 @@ export const SYSTEM = { RESOURCE_RATING, MENTAL_ILLNESS_CURE_SKILL, ERA_CSS, + INSANITY, ASCII } diff --git a/module/documents/roll.mjs b/module/documents/roll.mjs index 3802592..c6e7409 100644 --- a/module/documents/roll.mjs +++ b/module/documents/roll.mjs @@ -95,11 +95,12 @@ export default class CthulhuEternalRoll extends Roll { */ static async prompt(options = {}) { let formula = "1d100" - switch (options.rollType) { + switch (options.rollType) { case "skill": console.log(options.rollItem) options.initialScore = options.rollItem.system.computeScore() break + case "san": case "char": options.initialScore = options.rollItem.targetScore break @@ -269,6 +270,10 @@ export default class CthulhuEternalRoll extends Roll { return `${game.i18n.localize("CTHULHUETERNAL.Label.titleSkill")}` case "weapon": return `${game.i18n.localize("CTHULHUETERNAL.Label.titleWeapon")}` + case "char": + return `${game.i18n.localize("CTHULHUETERNAL.Label.titleCharacteristic")}` + case "san": + return `${game.i18n.localize("CTHULHUETERNAL.Label.titleSAN")}` default: return game.i18n.localize("CTHULHUETERNAL.Label.titleStandard") } diff --git a/module/models/protagonist.mjs b/module/models/protagonist.mjs index a420825..6dba796 100644 --- a/module/models/protagonist.mjs +++ b/module/models/protagonist.mjs @@ -44,7 +44,8 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData recovery: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), violence: new fields.ArrayField(new fields.BooleanField(), { required: true, initial: [false, false, false], min:3, max:3}), helplessness: new fields.ArrayField(new fields.BooleanField(), { required: true, initial: [false, false, false], min:3, max:3 }), - breakingPoint: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) + breakingPoint: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), + insanity: new fields.StringField({ required: true, nullable: false, initial: "none", choices:SYSTEM.INSANITY }), }) schema.damageBonus = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) @@ -66,6 +67,8 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData eyes: new fields.StringField({ required: true, nullable: false, initial: "" }), hair: new fields.StringField({ required: true, nullable: false, initial: "" }), harshness: new fields.StringField({ required: true, nullable: false, initial: "normal", choices:SYSTEM.HARSHNESS }), + adaptedToViolence: new fields.BooleanField({ required: true, initial: false }), + adaptedToHelplessness: new fields.BooleanField({ required: true, initial: false }) }) return schema diff --git a/styles/protagonist.less b/styles/protagonist.less index c0ce19f..56f7dde 100644 --- a/styles/protagonist.less +++ b/styles/protagonist.less @@ -67,20 +67,59 @@ } } .san { + align-content: flex-start; input { min-width: 2.2rem; + max-width: 2.2rem; + margin-bottom: 4px; } + select { + min-width: 6rem; + max-width: 6rem; + } + .rollable:hover, + .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; + font-size: 0.9rem; + } .san-checkbox { min-width: 1rem; max-width: 1rem; } - .label-field { - flex-grow: 0; + .label-short-field { + font-size: 0.9rem; + max-width: 3rem; + min-width: 3rem; + flex-grow: 1; + } + .label-recovery { margin-left: 4px; } + .label-field { + font-size: 0.9rem; + max-width: 6rem; + min-width: 6rem; + flex-grow: 1; + } + .label-bp { + flex-grow: 1; + max-width: 3rem; + min-width: 3rem; + margin-left: 4px; + } + .label-insanity { + flex-grow: 1; + margin-left: 4px; + max-width: 8rem; + min-width: 8rem; + } .spacing { margin-left: 4px; } + .d100 { + flex: 0; + } } .willpower { input { @@ -205,6 +244,15 @@ margin-left: 8px; } + .adapted { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 8px; + label { + min-width: 20rem; + } + } + .features, .biodata { display: grid; diff --git a/templates/protagonist-biography.hbs b/templates/protagonist-biography.hbs index e8a551f..13901ed 100644 --- a/templates/protagonist-biography.hbs +++ b/templates/protagonist-biography.hbs @@ -2,6 +2,10 @@