From b3eb908f0593202ab62b8aa18dbb43dcee483d13 Mon Sep 17 00:00:00 2001 From: LeRatierBretonnien Date: Fri, 7 Feb 2025 18:06:08 +0100 Subject: [PATCH] Add rituals and tomes and creatures --- css/fvtt-cthulhu-eternal.css | 652 ++++++++++++++++++ cthulhu-eternal.mjs | 4 +- lang/en.json | 87 ++- module/applications/_module.mjs | 1 + module/applications/sheets/creature-sheet.mjs | 175 +++++ module/documents/roll.mjs | 22 +- module/models/_module.mjs | 1 + module/models/creature.mjs | 80 +++ module/models/weapon.mjs | 3 + .../skills/{000130.log => 000134.log} | 0 packs-system/skills/CURRENT | 2 +- packs-system/skills/LOG | 16 +- packs-system/skills/LOG.old | 16 +- packs-system/skills/MANIFEST-000128 | Bin 143 -> 0 bytes packs-system/skills/MANIFEST-000132 | Bin 0 -> 143 bytes styles/creature.less | 644 +++++++++++++++++ styles/fvtt-cthulhu-eternal.less | 1 + styles/mixins.less | 7 + system.json | 3 +- templates/creature-biography.hbs | 12 + templates/creature-main.hbs | 95 +++ templates/creature-skills.hbs | 57 ++ templates/weapon.hbs | 5 + 23 files changed, 1855 insertions(+), 28 deletions(-) create mode 100644 module/applications/sheets/creature-sheet.mjs create mode 100644 module/models/creature.mjs rename packs-system/skills/{000130.log => 000134.log} (100%) delete mode 100644 packs-system/skills/MANIFEST-000128 create mode 100644 packs-system/skills/MANIFEST-000132 create mode 100644 styles/creature.less create mode 100644 templates/creature-biography.hbs create mode 100644 templates/creature-main.hbs create mode 100644 templates/creature-skills.hbs diff --git a/css/fvtt-cthulhu-eternal.css b/css/fvtt-cthulhu-eternal.css index bc3add8..15d91fe 100644 --- a/css/fvtt-cthulhu-eternal.css +++ b/css/fvtt-cthulhu-eternal.css @@ -190,6 +190,10 @@ i.fvtt-cthulhu-eternal { font-family: var(--font-secondary); font-size: calc(var(--font-size-standard) * 1); } +.fvtt-cthulhu-eternal .creature-sheet-common label { + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1); +} .fvtt-cthulhu-eternal .item-sheet-common .form-fields { padding-top: 4px; } @@ -1105,6 +1109,654 @@ i.fvtt-cthulhu-eternal { .fvtt-cthulhu-eternal .tab.vehicle-equipment prose-mirror.active { min-height: 150px; } +.fvtt-cthulhu-eternal .creature-content { + font-family: var(--font-primary); + font-size: calc(var(--font-size-standard) * 1); + color: var(--color-dark-1); + background-image: var(--background-image-base); + background-repeat: no-repeat; + background-size: 100% 100%; + overflow: scroll; +} +.fvtt-cthulhu-eternal .creature-content input:disabled, +.fvtt-cthulhu-eternal .creature-content select:disabled { + background-color: rgba(0, 0, 0, 0.2); + border-color: transparent; + color: var(--color-dark-3); +} +.fvtt-cthulhu-eternal .creature-content input, +.fvtt-cthulhu-eternal .creature-content select { + background-color: rgba(0, 0, 0, 0.1); + border-color: var(--color-dark-6); + color: var(--color-dark-2); +} +.fvtt-cthulhu-eternal .creature-content input[name="name"] { + height: 40px; + margin-right: 10px; + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1); + font-weight: bold; + border: none; +} +.fvtt-cthulhu-eternal .creature-content fieldset { + margin-bottom: 4px; + border-radius: 4px; +} +.fvtt-cthulhu-eternal .creature-content .form-fields input, +.fvtt-cthulhu-eternal .creature-content .form-fields select { + text-align: center; + font-size: calc(var(--font-size-standard) * 1); +} +.fvtt-cthulhu-eternal .creature-content .form-fields select { + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1); +} +.fvtt-cthulhu-eternal .creature-content legend { + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1.2); + font-weight: bold; + letter-spacing: 1px; +} +.fvtt-cthulhu-eternal .creature-content label { + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1); +} +.fvtt-cthulhu-eternal .sheet-tabs { + background-color: var(--color-light-1); +} +.fvtt-cthulhu-eternal .creature-main { + background-color: var(--color-light-1); + display: flex; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc { + display: flex; + gap: 4px; + flex: 1; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left { + min-width: 180px; + display: flex; + flex-direction: column; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-left-image { + display: flex; + justify-content: center; + align-items: center; + padding-bottom: 8px; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-left-image .creature-img { + height: 140px; + width: auto; + border: none; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-hp { + gap: 2px; + align-items: center; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-hp input { + flex: none; + width: 2rem; + margin-left: 4px; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-hp .damage-bonus { + font-size: calc(var(--font-size-standard) * 0.8); +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-hp .hp-separator { + font-size: calc(var(--font-size-standard) * 1.2); + display: flex; + align-items: center; + justify-content: center; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-dv .form-fields, +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-dmax .form-fields { + flex: none; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-left .creature-dmax-edit input { + display: flex; + width: 60px; + font-size: calc(var(--font-size-standard) * 1.4); + align-items: center; + justify-content: center; + padding: 0 5px 0 5px; + text-align: center; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right { + display: flex; + flex-direction: column; + gap: 5px; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .creature-name { + display: flex; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .creature-name input { + font-family: var(--font-title); + font-size: var(--font-size-title); + width: 400px; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .san { + align-content: flex-start; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .san input { + min-width: 2.2rem; + max-width: 2.2rem; + margin-bottom: 4px; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .san select { + min-width: 6rem; + max-width: 6rem; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .san .rollable:hover, +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .san .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; + font-size: 0.9rem; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .san .button { + min-width: 4rem; + max-width: 4rem; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .san .san-checkbox { + min-width: 1rem; + max-width: 1rem; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .san .label-short-field { + font-size: 0.9rem; + max-width: 3rem; + min-width: 3rem; + flex-grow: 1; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .san .label-recovery { + margin-left: 4px; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .san .label-field { + font-size: 0.9rem; + max-width: 6rem; + min-width: 6rem; + flex-grow: 1; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .san .label-bp { + flex-grow: 1; + max-width: 3rem; + min-width: 3rem; + margin-left: 4px; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .san .label-insanity { + flex-grow: 1; + margin-left: 4px; + max-width: 8rem; + min-width: 8rem; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .san .spacing { + margin-left: 4px; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .san .d100 { + flex: 0; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .willpower input { + min-width: 2.4rem; + max-width: 2.4rem; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .willpower input[type="checkbox"] { + min-width: 1rem; + max-width: 1rem; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .willpower .label-field { + flex-grow: 1; + margin-left: 4px; + max-width: 5rem; + min-width: 5rem; + font-size: 0.9rem; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right .willpower .checkbox { + flex-grow: 0; + min-width: 1rem; + max-width: 1rem; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc .creature-right label { + min-width: 120px; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc-play { + min-width: 500px; +} +.fvtt-cthulhu-eternal .creature-main .creature-pc-edit { + min-width: 650px; +} +.fvtt-cthulhu-eternal .creature-main .creature-characteristics { + background-color: var(--color-light-1); + display: flex; + flex-direction: column; + gap: 5px; + flex: 1; +} +.fvtt-cthulhu-eternal .creature-main .creature-characteristics .creature-characteristic { + display: flex; + align-items: center; +} +.fvtt-cthulhu-eternal .creature-main .creature-characteristics .creature-characteristic .rollable:hover, +.fvtt-cthulhu-eternal .creature-main .creature-characteristics .creature-characteristic .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; +} +.fvtt-cthulhu-eternal .creature-main .creature-characteristics .creature-characteristic .rollable { + min-width: 3rem; + max-width: 3rem; +} +.fvtt-cthulhu-eternal .creature-main .creature-characteristics .creature-characteristic .char-text { + margin-left: 0.5rem; +} +.fvtt-cthulhu-eternal .creature-main .creature-characteristics .creature-characteristic .d100 { + flex: 0; + max-width: 0.6rem; +} +.fvtt-cthulhu-eternal .creature-main .creature-characteristics .creature-characteristic .form-group { + flex: 0; + padding-left: 5px; +} +.fvtt-cthulhu-eternal .creature-main .creature-characteristics .creature-characteristic .form-group .form-fields { + font-size: 1.1rem; + flex: none; + width: 40px; +} +.fvtt-cthulhu-eternal .creature-main .creature-characteristic-play { + min-width: 225px; +} +.fvtt-cthulhu-eternal .creature-main .creature-characteristic-edit { + min-width: 400px; +} +.fvtt-cthulhu-eternal .creature-biography { + background-color: var(--color-light-1); +} +.fvtt-cthulhu-eternal .creature-biography prose-mirror.inactive { + min-height: 40px; +} +.fvtt-cthulhu-eternal .creature-biography prose-mirror.active { + min-height: 150px; +} +.fvtt-cthulhu-eternal .creature-biography .field-label { + margin-left: 8px; +} +.fvtt-cthulhu-eternal .creature-biography .adapted { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 8px; +} +.fvtt-cthulhu-eternal .creature-biography .adapted label { + min-width: 20rem; +} +.fvtt-cthulhu-eternal .creature-biography .resources { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 8px; +} +.fvtt-cthulhu-eternal .creature-biography .resources label { + min-width: 8rem; +} +.fvtt-cthulhu-eternal .creature-biography .features, +.fvtt-cthulhu-eternal .creature-biography .biodata { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 8px; +} +.fvtt-cthulhu-eternal .creature-biography .features label, +.fvtt-cthulhu-eternal .creature-biography .biodata label { + min-width: 3rem; +} +.fvtt-cthulhu-eternal .creature-biography .features .feature, +.fvtt-cthulhu-eternal .creature-biography .biodata .feature { + display: flex; + align-items: center; + gap: 4px; + min-width: 18rem; + max-width: 18rem; +} +.fvtt-cthulhu-eternal .tab.creature-skills { + background-color: var(--color-light-1); + display: grid; + grid-template-columns: 1fr; +} +.fvtt-cthulhu-eternal .tab.creature-skills legend a { + font-size: calc(var(--font-size-standard) * 1.4); + padding-left: 5px; +} +.fvtt-cthulhu-eternal .tab.creature-skills .armors { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 4px; +} +.fvtt-cthulhu-eternal .tab.creature-skills .armors .armor { + display: flex; + align-items: center; + gap: 4px; + min-width: 13rem; + max-width: 13rem; +} +.fvtt-cthulhu-eternal .tab.creature-skills .armors .armor .rollable:hover, +.fvtt-cthulhu-eternal .tab.creature-skills .armors .armor .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; +} +.fvtt-cthulhu-eternal .tab.creature-skills .armors .armor .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; +} +.fvtt-cthulhu-eternal .tab.creature-skills .armors .armor .protection { + min-width: 5rem; + max-width: 5rem; +} +.fvtt-cthulhu-eternal .tab.creature-skills .armors .armor .name { + min-width: 8rem; + max-width: 8rem; +} +.fvtt-cthulhu-eternal .tab.creature-skills .armors .armor .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; +} +.fvtt-cthulhu-eternal .tab.creature-skills .weapons { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; +} +.fvtt-cthulhu-eternal .tab.creature-skills .weapons .weapon { + display: flex; + align-items: center; + gap: 4px; + min-width: 13rem; + max-width: 13rem; +} +.fvtt-cthulhu-eternal .tab.creature-skills .weapons .weapon .rollable:hover, +.fvtt-cthulhu-eternal .tab.creature-skills .weapons .weapon .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; +} +.fvtt-cthulhu-eternal .tab.creature-skills .weapons .weapon .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; +} +.fvtt-cthulhu-eternal .tab.creature-skills .weapons .weapon .damage { + min-width: 6rem; + max-width: 6rem; +} +.fvtt-cthulhu-eternal .tab.creature-skills .weapons .weapon .name { + min-width: 10rem; + max-width: 10rem; +} +.fvtt-cthulhu-eternal .tab.creature-skills .weapons .weapon .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; +} +.fvtt-cthulhu-eternal .tab.creature-skills .skills { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 4px; +} +.fvtt-cthulhu-eternal .tab.creature-skills .skills .skill { + display: flex; + align-items: center; + gap: 4px; + margin-left: 4px; + min-width: 12.3rem; + max-width: 12.3rem; +} +.fvtt-cthulhu-eternal .tab.creature-skills .skills .skill .rollable:hover, +.fvtt-cthulhu-eternal .tab.creature-skills .skills .skill .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; +} +.fvtt-cthulhu-eternal .tab.creature-skills .skills .skill .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; +} +.fvtt-cthulhu-eternal .tab.creature-skills .skills .skill .score { + min-width: 1.2rem; + max-width: 1.2rem; +} +.fvtt-cthulhu-eternal .tab.creature-skills .skills .skill .name { + min-width: 10rem; + max-width: 10rem; +} +.fvtt-cthulhu-eternal .tab.creature-skills .skills .skill .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; +} +.fvtt-cthulhu-eternal .tab.creature-status { + background-color: var(--color-light-1); + display: grid; + grid-template-columns: 1fr; +} +.fvtt-cthulhu-eternal .tab.creature-status legend a { + font-size: calc(var(--font-size-standard) * 1.4); + padding-left: 5px; +} +.fvtt-cthulhu-eternal .tab.creature-status .bonds { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; +} +.fvtt-cthulhu-eternal .tab.creature-status .bonds .bond { + display: flex; + align-items: center; + gap: 4px; + min-width: 18rem; + max-width: 18rem; +} +.fvtt-cthulhu-eternal .tab.creature-status .bonds .bond .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; +} +.fvtt-cthulhu-eternal .tab.creature-status .bonds .bond .name { + min-width: 12rem; + max-width: 12rem; +} +.fvtt-cthulhu-eternal .tab.creature-status .bonds .bond .type { + min-width: 6rem; + max-width: 6rem; +} +.fvtt-cthulhu-eternal .tab.creature-status .bonds .bond .level { + min-width: 2rem; + max-width: 2rem; +} +.fvtt-cthulhu-eternal .tab.creature-status .bonds .bond .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; +} +.fvtt-cthulhu-eternal .tab.creature-status .motivations { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; +} +.fvtt-cthulhu-eternal .tab.creature-status .motivations .motivation { + display: flex; + align-items: center; + gap: 4px; + min-width: 14rem; + max-width: 14rem; +} +.fvtt-cthulhu-eternal .tab.creature-status .motivations .motivation .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; +} +.fvtt-cthulhu-eternal .tab.creature-status .motivations .motivation .name { + min-width: 12rem; + max-width: 12rem; +} +.fvtt-cthulhu-eternal .tab.creature-status .motivations .motivation .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; +} +.fvtt-cthulhu-eternal .tab.creature-status .mentaldisorders { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; +} +.fvtt-cthulhu-eternal .tab.creature-status .mentaldisorders .mentaldisorder { + display: flex; + align-items: center; + gap: 4px; + min-width: 18rem; + max-width: 18rem; +} +.fvtt-cthulhu-eternal .tab.creature-status .mentaldisorders .mentaldisorder .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; +} +.fvtt-cthulhu-eternal .tab.creature-status .mentaldisorders .mentaldisorder .name { + min-width: 14rem; + max-width: 14rem; +} +.fvtt-cthulhu-eternal .tab.creature-status .mentaldisorders .mentaldisorder .cured { + min-width: 5rem; + max-width: 5rem; +} +.fvtt-cthulhu-eternal .tab.creature-status .mentaldisorders .mentaldisorder .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; +} +.fvtt-cthulhu-eternal .tab.creature-status .injuries { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; +} +.fvtt-cthulhu-eternal .tab.creature-status .injuries .injury { + display: flex; + align-items: center; + gap: 4px; + min-width: 16rem; + max-width: 16rem; +} +.fvtt-cthulhu-eternal .tab.creature-status .injuries .injury .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; +} +.fvtt-cthulhu-eternal .tab.creature-status .injuries .injury .name { + min-width: 14rem; + max-width: 14rem; +} +.fvtt-cthulhu-eternal .tab.creature-status .injuries .injury .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; +} +.fvtt-cthulhu-eternal .tab.creature-equipment { + background-color: var(--color-light-1); + display: grid; + grid-template-columns: 1fr; +} +.fvtt-cthulhu-eternal .tab.creature-equipment legend a { + font-size: calc(var(--font-size-standard) * 1.4); + padding-left: 5px; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .gears { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 4px; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .gears .gear { + display: flex; + align-items: center; + gap: 4px; + min-width: 13rem; + max-width: 13rem; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .gears .gear .rollable:hover, +.fvtt-cthulhu-eternal .tab.creature-equipment .gears .gear .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .gears .gear .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .gears .gear .name { + min-width: 10rem; + max-width: 10rem; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .gears .gear .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .rituals { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .rituals .ritual { + display: flex; + align-items: center; + gap: 4px; + min-width: 20rem; + max-width: 20rem; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .rituals .ritual .rollable:hover, +.fvtt-cthulhu-eternal .tab.creature-equipment .rituals .ritual .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .rituals .ritual .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .rituals .ritual .name { + min-width: 17rem; + max-width: 17rem; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .rituals .ritual .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .tomes { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .tomes .tome { + display: flex; + align-items: center; + gap: 4px; + min-width: 20rem; + max-width: 20rem; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .tomes .tome .rollable:hover, +.fvtt-cthulhu-eternal .tab.creature-equipment .tomes .tome .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .tomes .tome .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .tomes .tome .name { + min-width: 17rem; + max-width: 17rem; +} +.fvtt-cthulhu-eternal .tab.creature-equipment .tomes .tome .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; +} +.fvtt-cthulhu-eternal .tab.creature-equipment prose-mirror.inactive { + min-height: 40px; +} +.fvtt-cthulhu-eternal .tab.creature-equipment prose-mirror.active { + min-height: 150px; +} .fvtt-cthulhu-eternal .skill-content { font-family: var(--font-primary); font-size: calc(var(--font-size-standard) * 1); diff --git a/cthulhu-eternal.mjs b/cthulhu-eternal.mjs index 59d23ce..c0bec44 100644 --- a/cthulhu-eternal.mjs +++ b/cthulhu-eternal.mjs @@ -33,7 +33,8 @@ Hooks.once("init", function () { CONFIG.Actor.documentClass = documents.CthulhuEternalActor CONFIG.Actor.dataModels = { protagonist: models.CthulhuEternalProtagonist, - vehicle: models.CthulhuEternalVehicle + vehicle: models.CthulhuEternalVehicle, + creature: models.CthulhuEternalCreature } CONFIG.Item.documentClass = documents.CthulhuEternalItem @@ -56,6 +57,7 @@ Hooks.once("init", function () { Actors.unregisterSheet("core", ActorSheet) Actors.registerSheet("fvtt-cthulhu-eternal", applications.CthulhuEternalProtagonistSheet, { types: ["protagonist"], makeDefault: true }) Actors.registerSheet("fvtt-cthulhu-eternal", applications.CthulhuEternalVehicleSheet, { types: ["vehicle"], makeDefault: true }) + Actors.registerSheet("fvtt-cthulhu-eternal", applications.CthulhuEternalCreatureSheet, { types: ["creature"], makeDefault: true }) Items.unregisterSheet("core", ItemSheet) Items.registerSheet("fvtt-cthulhu-eternal", applications.CthulhuEternalSkillSheet, { types: ["skill"], makeDefault: true }) diff --git a/lang/en.json b/lang/en.json index 3f0c18a..ec6b4cd 100644 --- a/lang/en.json +++ b/lang/en.json @@ -2,7 +2,8 @@ "TYPES": { "Actor": { "protagonist": "Protagonist", - "vehicle": "Vehicle" + "vehicle": "Vehicle", + "creature": "Creature" }, "Item": { "skill": "Skill", @@ -114,6 +115,83 @@ } } }, + "Creature": { + "FIELDS": { + "damageBonus": { + "label": "Dmg.Bonus" + }, + "resources": { + "permanentRating": { + "label": "Permanent Rating" + }, + "hand": { + "label": "Hand" + }, + "stowed": { + "label": "Stowed" + }, + "storage": { + "label": "Storage" + } + }, + "biodata": { + "feature": { + "label": "Feature" + }, + "adaptedToViolence": { + "label": "Adapted to violence" + }, + "adaptedToHelplessness": { + "label": "Adapted to helplessness" + }, + "harshness": { + "label": "Harshness" + }, + "age": { + "label": "Age" + }, + "gender": { + "label": "Gender" + }, + "hair": { + "label": "Hair" + }, + "eyes": { + "label": "Eyes" + }, + "height": { + "label": "Height" + }, + "home": { + "label": "Home" + }, + "birthplace": { + "label": "Birthplace" + }, + "label": "Biodata" + }, + "characteristics:": { + "str": { + "label": "Strength" + }, + "dex": { + "label": "Dexterity" + }, + "int": { + "label": "Intelligence" + }, + "pow": { + "label": "Power" + }, + "con": { + "label": "Constitution" + }, + "char": { + "label": "Charisma" + } + } + } + }, "Insanity": { "None": "None", "Flee": "Flee", @@ -188,6 +266,12 @@ "riflecarabine": "Rifle/Carabine" }, "FIELDS": { + "hasDirectSkill": { + "label": "Has direct skill" + }, + "directSkillValue": { + "label": "Direct skill value" + }, "state": { "label": "State" }, @@ -398,6 +482,7 @@ } }, "Label": { + "creature": "Creature", "Rituals": "Rituals", "Tomes": "Tomes", "otherBenefits": "Other Benefits", diff --git a/module/applications/_module.mjs b/module/applications/_module.mjs index a3f4c15..ac67f7c 100644 --- a/module/applications/_module.mjs +++ b/module/applications/_module.mjs @@ -11,4 +11,5 @@ export { default as CthulhuEternalMotivationSheet } from "./sheets/motivation-sh export { default as CthulhuEternalArchetypeSheet } from "./sheets/archetype-sheet.mjs" export { default as CthulhuEternalRitualSheet } from "./sheets/ritual-sheet.mjs" export { default as CthulhuEternalVehicleSheet } from "./sheets/vehicle-sheet.mjs" +export { default as CthulhuEternalCreatureSheet } from "./sheets/creature-sheet.mjs" export { default as CthulhuEternalTomeSheet } from "./sheets/tome-sheet.mjs" diff --git a/module/applications/sheets/creature-sheet.mjs b/module/applications/sheets/creature-sheet.mjs new file mode 100644 index 0000000..96b9b22 --- /dev/null +++ b/module/applications/sheets/creature-sheet.mjs @@ -0,0 +1,175 @@ +import CthulhuEternalActorSheet from "./base-actor-sheet.mjs" + +export default class CthulhuEternalCreatureSheet extends CthulhuEternalActorSheet { + /** @override */ + static DEFAULT_OPTIONS = { + classes: ["creature"], + position: { + width: 860, + height: 620, + }, + window: { + contentClasses: ["creature-content"], + }, + actions: { + createArmor: CthulhuEternalCreatureSheet.#onCreateArmor, + createWeapon: CthulhuEternalCreatureSheet.#onCreateWeapon, + createSkill: CthulhuEternalCreatureSheet.#onCreateSkill, + + }, + } + + /** @override */ + static PARTS = { + main: { + template: "systems/fvtt-cthulhu-eternal/templates/creature-main.hbs", + }, + tabs: { + template: "templates/generic/tab-navigation.hbs", + }, + skills: { + template: "systems/fvtt-cthulhu-eternal/templates/creature-skills.hbs", + }, + biography: { + template: "systems/fvtt-cthulhu-eternal/templates/creature-biography.hbs", + }, + } + + /** @override */ + tabGroups = { + sheet: "skills", + } + + /** + * Prepare an array of form header tabs. + * @returns {Record>} + */ + #getTabs() { + const tabs = { + skills: { id: "skills", group: "sheet", icon: "fa-solid fa-shapes", label: "CTHULHUETERNAL.Label.skills" }, + biography: { id: "biography", group: "sheet", icon: "fa-solid fa-book", label: "CTHULHUETERNAL.Label.biography" }, + } + for (const v of Object.values(tabs)) { + v.active = this.tabGroups[v.group] === v.id + v.cssClass = v.active ? "active" : "" + } + return tabs + } + + /** @override */ + async _prepareContext() { + const context = await super._prepareContext() + context.tabs = this.#getTabs() + + context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true }) + context.enrichedNotes = await TextEditor.enrichHTML(this.document.system.notes, { async: true }) + + context.tooltipsCharacteristic = { + str: game.i18n.localize("CTHULHUETERNAL.Characteristic.Str"), + dex: game.i18n.localize("CTHULHUETERNAL.Characteristic.Dex"), + con: game.i18n.localize("CTHULHUETERNAL.Characteristic.Con"), + int: game.i18n.localize("CTHULHUETERNAL.Characteristic.Int"), + pow: game.i18n.localize("CTHULHUETERNAL.Characteristic.Pow"), + cha: game.i18n.localize("CTHULHUETERNAL.Characteristic.Cha") + } + + return context + } + + /** @override */ + async _preparePartContext(partId, context) { + const doc = this.document + switch (partId) { + case "main": + break + case "skills": + context.tab = context.tabs.skills + context.skills = doc.itemTypes.skill + context.skills.sort((a, b) => a.name.localeCompare(b.name)) + context.weapons = doc.itemTypes.weapon + context.weapons.sort((a, b) => a.name.localeCompare(b.name)) + context.armors = doc.itemTypes.armor + context.armors.sort((a, b) => a.name.localeCompare(b.name)) + break + case "biography": + context.tab = context.tabs.biography + context.enrichedDescription = await TextEditor.enrichHTML(doc.system.description, { async: true }) + context.enrichedNotes = await TextEditor.enrichHTML(doc.system.notes, { async: true }) + break + } + return context + } + + /** + * Creates a new attack item directly from the sheet and embeds it into the document. + * @param {Event} event The initiating click event. + * @param {HTMLElement} target The current target of the event listener. + */ + static #onCreateWeapon(event, target) { + this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("CTHULHUETERNAL.Label.newWeapon"), type: "weapon" }]) + } + + static #onCreateArmor(event, target) { + this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("CTHULHUETERNAL.Label.newArmor"), type: "armor" }]) + } + + static #onCreateSkill(event, target) { + this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("CTHULHUETERNAL.Label.newSkill"), type: "skill" }]) + } + + /** + * Handles the roll action triggered by user interaction. + * + * @param {PointerEvent} event The event object representing the user interaction. + * @param {HTMLElement} target The target element that triggered the roll. + * + * @returns {Promise} A promise that resolves when the roll action is complete. + * + * @throws {Error} Throws an error if the roll type is not recognized. + * + * @description This method checks the current mode (edit or not) and determines the type of roll + * (save, resource, or damage) based on the target element's data attributes. It retrieves the + * corresponding value from the document's system and performs the roll. + */ + async _onRoll(event, target) { + const rollType = $(event.currentTarget).data("roll-type") + let item + let li + // Debug : console.log(">>>>", event, target, rollType) + // Deprecated : if (this.isEditMode) return + switch (rollType) { + case "char": + let charId = $(event.currentTarget).data("char-id") + item = foundry.utils.duplicate(this.actor.system.characteristics[charId]) + item.name = game.i18n.localize(`CTHULHUETERNAL.Label.${charId}Long`) + item.targetScore = item.value * 5 + break + case "skill": + li = $(event.currentTarget).parents(".item"); + item = this.actor.items.get(li.data("item-id")); + break + case "weapon": + case "damage": + li = $(event.currentTarget).parents(".item"); + item = this.actor.items.get(li.data("item-id")); + item.damageBonus = this.actor.system.damageBonus + break + default: + throw new Error(`Unknown roll type ${rollType}`) + } + await this.document.system.roll(rollType, item) + } + + async _onDrop(event) { + if (!this.isEditable || !this.isEditMode) return + const data = TextEditor.getDragEventData(event) + + // Handle different data types + switch (data.type) { + case "Item": + const item = await fromUuid(data.uuid) + return super._onDropItem(item) + } + } + +} diff --git a/module/documents/roll.mjs b/module/documents/roll.mjs index d4a3c16..17009e9 100644 --- a/module/documents/roll.mjs +++ b/module/documents/roll.mjs @@ -178,16 +178,22 @@ export default class CthulhuEternalRoll extends Roll { console.log("WP Not found", era, options.rollItem.system.weaponType) return } - let skillName = game.i18n.localize(SYSTEM.WEAPON_SKILL_MAPPING[era][options.rollItem.system.weaponType]) - let actor = game.actors.get(options.actorId) options.weapon = options.rollItem - options.rollItem = actor.items.find(i => i.type === "skill" && i.name.toLowerCase() === skillName.toLowerCase()) - if (!options.rollItem) { - ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.NoWeaponSkill")) - return + if (options.rollItem.system.hasDirectSkill) { + let skillName = options.rollItem.name + options.rollItem = {type: "skill", name: skillName, system: {base: 0, bonus: options.weapon.system.directSkillValue} } + options.initialScore = options.weapon.system.directSkillValue + } else { + let skillName = game.i18n.localize(SYSTEM.WEAPON_SKILL_MAPPING[era][options.rollItem.system.weaponType]) + let actor = game.actors.get(options.actorId) + options.rollItem = actor.items.find(i => i.type === "skill" && i.name.toLowerCase() === skillName.toLowerCase()) + if (!options.rollItem) { + ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.NoWeaponSkill")) + return + } + options.initialScore = options.rollItem.system.computeScore() + console.log("WEAPON", skillName, era, options.rollItem) } - options.initialScore = options.rollItem.system.computeScore() - console.log("WEAPON", skillName, era, options.rollItem) break default: options.initialScore = 50 diff --git a/module/models/_module.mjs b/module/models/_module.mjs index b3f069f..c3a7743 100644 --- a/module/models/_module.mjs +++ b/module/models/_module.mjs @@ -11,5 +11,6 @@ export { default as CthulhuEternalMotivation } from "./motivation.mjs" export { default as CthulhuEternalArchetype } from "./archetype.mjs" export { default as CthulhuEternalRitual } from "./ritual.mjs" export { default as CthulhuEternalVehicle } from "./vehicle.mjs" +export { default as CthulhuEternalCreature } from "./creature.mjs" export { default as CthulhuEternalTome } from "./tome.mjs" diff --git a/module/models/creature.mjs b/module/models/creature.mjs new file mode 100644 index 0000000..836d77d --- /dev/null +++ b/module/models/creature.mjs @@ -0,0 +1,80 @@ +import { SYSTEM } from "../config/system.mjs" +import CthulhuEternalRoll from "../documents/roll.mjs" + +export default class CthulhuEternalCreature extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields + const requiredInteger = { required: true, nullable: false, integer: true } + const schema = {} + + // Carac + const characteristicField = (label) => { + const schema = { + value: new fields.NumberField({ ...requiredInteger, initial: 3, min: 0 }), + feature: new fields.StringField({ required: true, nullable: false, initial: "" }) + } + return new fields.SchemaField(schema, { label }) + } + + schema.characteristics = new fields.SchemaField( + Object.values(SYSTEM.CHARACTERISTICS).reduce((obj, characteristic) => { + obj[characteristic.id] = characteristicField(characteristic.label) + return obj + }, {}), + ) + + schema.wp = new fields.SchemaField({ + value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), + max: new fields.NumberField({ ...requiredInteger, initial: 3, min: 0 }), + exhausted: new fields.BooleanField({ required: true, initial: false }) + }) + + schema.hp = new fields.SchemaField({ + value: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 }), + max: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 }) + }) + schema.movement = new fields.StringField({ required: true, initial: "" }) + schema.sanLoss = new fields.StringField({ required: true, initial: "1/1D6" }) + + schema.armor = new fields.StringField({ required: true, initial: "" }) + schema.size = new fields.StringField({ required: true, initial: "medium", choices: SYSTEM.CREATURE_SIZE }) + schema.damageBonus = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) + + schema.description = new fields.HTMLField({ required: true, textSearch: true }) + schema.notes = new fields.HTMLField({ required: true, textSearch: true }) + + return schema + } + + /** @override */ + static LOCALIZATION_PREFIXES = ["CTHULHUETERNAL.Creature"] + + /** */ + /** + * Rolls a dice for a character. + * @param {("save"|"resource|damage")} rollType The type of the roll. + * @param {number} rollItem The target value for the roll. Which caracteristic or resource. If the roll is a damage roll, this is the id of the item. + * @returns {Promise} - A promise that resolves to null if the roll is cancelled. + */ + async roll(rollType, rollItem) { + let opponentTarget + const hasTarget = opponentTarget !== undefined + + let roll = await CthulhuEternalRoll.prompt({ + rollType, + rollItem, + isLowWP: false, + isZeroWP: false, + isExhausted: false, + actorId: this.parent.id, + actorName: this.parent.name, + actorImage: this.parent.img, + hasTarget, + target: opponentTarget + }) + if (!roll) return null + + await roll.toMessage({}, { rollMode: roll.options.rollMode }) + } + +} diff --git a/module/models/weapon.mjs b/module/models/weapon.mjs index 7d0c310..3378ad6 100644 --- a/module/models/weapon.mjs +++ b/module/models/weapon.mjs @@ -12,6 +12,9 @@ export default class LethalFantasySkill extends foundry.abstract.TypeDataModel { schema.settings = new fields.StringField({ required: true, initial: setting, choices: SYSTEM.AVAILABLE_SETTINGS }) schema.weaponType = new fields.StringField({ required: true, initial: "melee", choices: SYSTEM.WEAPON_TYPE }) + schema.hasDirectSkill = new fields.BooleanField({ required: true, initial: false }) + schema.directSkillValue = new fields.NumberField({ required: true, initial: 0, min: 0, max:99 }) + schema.damage = new fields.StringField({required: true, initial: "1d6"}) schema.baseRange = new fields.StringField({required: true, initial: ""}) schema.rangeUnit = new fields.StringField({ required: true, initial: "yard", choices: SYSTEM.WEAPON_RANGE_UNIT }) diff --git a/packs-system/skills/000130.log b/packs-system/skills/000134.log similarity index 100% rename from packs-system/skills/000130.log rename to packs-system/skills/000134.log diff --git a/packs-system/skills/CURRENT b/packs-system/skills/CURRENT index a8d9908..c39c670 100644 --- a/packs-system/skills/CURRENT +++ b/packs-system/skills/CURRENT @@ -1 +1 @@ -MANIFEST-000128 +MANIFEST-000132 diff --git a/packs-system/skills/LOG b/packs-system/skills/LOG index 6eda6a0..3783327 100644 --- a/packs-system/skills/LOG +++ b/packs-system/skills/LOG @@ -1,8 +1,8 @@ -2025/02/07-07:58:04.988627 7ffae7fff6c0 Recovering log #126 -2025/02/07-07:58:04.998629 7ffae7fff6c0 Delete type=3 #124 -2025/02/07-07:58:04.998698 7ffae7fff6c0 Delete type=0 #126 -2025/02/07-08:34:42.926911 7ffae6bff6c0 Level-0 table #131: started -2025/02/07-08:34:42.926943 7ffae6bff6c0 Level-0 table #131: 0 bytes OK -2025/02/07-08:34:42.933490 7ffae6bff6c0 Delete type=0 #129 -2025/02/07-08:34:42.933666 7ffae6bff6c0 Manual compaction at level-0 from '!folders!DD8331Hda4rhvEf9' @ 72057594037927935 : 1 .. '!items!zplzTG30QXHURusr' @ 0 : 0; will stop at (end) -2025/02/07-08:34:42.944681 7ffae6bff6c0 Manual compaction at level-1 from '!folders!DD8331Hda4rhvEf9' @ 72057594037927935 : 1 .. '!items!zplzTG30QXHURusr' @ 0 : 0; will stop at (end) +2025/02/07-17:41:28.897688 7fd3051fa6c0 Recovering log #130 +2025/02/07-17:41:28.908107 7fd3051fa6c0 Delete type=3 #128 +2025/02/07-17:41:28.908173 7fd3051fa6c0 Delete type=0 #130 +2025/02/07-18:05:31.341547 7fd2febff6c0 Level-0 table #135: started +2025/02/07-18:05:31.341579 7fd2febff6c0 Level-0 table #135: 0 bytes OK +2025/02/07-18:05:31.348653 7fd2febff6c0 Delete type=0 #133 +2025/02/07-18:05:31.348812 7fd2febff6c0 Manual compaction at level-0 from '!folders!DD8331Hda4rhvEf9' @ 72057594037927935 : 1 .. '!items!zplzTG30QXHURusr' @ 0 : 0; will stop at (end) +2025/02/07-18:05:31.359791 7fd2febff6c0 Manual compaction at level-1 from '!folders!DD8331Hda4rhvEf9' @ 72057594037927935 : 1 .. '!items!zplzTG30QXHURusr' @ 0 : 0; will stop at (end) diff --git a/packs-system/skills/LOG.old b/packs-system/skills/LOG.old index 4d2e435..6eda6a0 100644 --- a/packs-system/skills/LOG.old +++ b/packs-system/skills/LOG.old @@ -1,8 +1,8 @@ -2025/02/06-23:17:39.180197 7ffaecbf96c0 Recovering log #122 -2025/02/06-23:17:39.191385 7ffaecbf96c0 Delete type=3 #120 -2025/02/06-23:17:39.191461 7ffaecbf96c0 Delete type=0 #122 -2025/02/07-00:19:54.566098 7ffae6bff6c0 Level-0 table #127: started -2025/02/07-00:19:54.566176 7ffae6bff6c0 Level-0 table #127: 0 bytes OK -2025/02/07-00:19:54.572437 7ffae6bff6c0 Delete type=0 #125 -2025/02/07-00:19:54.583220 7ffae6bff6c0 Manual compaction at level-0 from '!folders!DD8331Hda4rhvEf9' @ 72057594037927935 : 1 .. '!items!zplzTG30QXHURusr' @ 0 : 0; will stop at (end) -2025/02/07-00:19:54.596307 7ffae6bff6c0 Manual compaction at level-1 from '!folders!DD8331Hda4rhvEf9' @ 72057594037927935 : 1 .. '!items!zplzTG30QXHURusr' @ 0 : 0; will stop at (end) +2025/02/07-07:58:04.988627 7ffae7fff6c0 Recovering log #126 +2025/02/07-07:58:04.998629 7ffae7fff6c0 Delete type=3 #124 +2025/02/07-07:58:04.998698 7ffae7fff6c0 Delete type=0 #126 +2025/02/07-08:34:42.926911 7ffae6bff6c0 Level-0 table #131: started +2025/02/07-08:34:42.926943 7ffae6bff6c0 Level-0 table #131: 0 bytes OK +2025/02/07-08:34:42.933490 7ffae6bff6c0 Delete type=0 #129 +2025/02/07-08:34:42.933666 7ffae6bff6c0 Manual compaction at level-0 from '!folders!DD8331Hda4rhvEf9' @ 72057594037927935 : 1 .. '!items!zplzTG30QXHURusr' @ 0 : 0; will stop at (end) +2025/02/07-08:34:42.944681 7ffae6bff6c0 Manual compaction at level-1 from '!folders!DD8331Hda4rhvEf9' @ 72057594037927935 : 1 .. '!items!zplzTG30QXHURusr' @ 0 : 0; will stop at (end) diff --git a/packs-system/skills/MANIFEST-000128 b/packs-system/skills/MANIFEST-000128 deleted file mode 100644 index 5c9f77ed03862fe49bb16a18a56575d0537893c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 143 zcmdmC8h9Xufss)vC$%g!CnZVGsj?)sJhM2}IX|}`u_&=5zlfcQ_1HlkMa8uIoRrj} zVnr7h3u9wLkCa4{qKq=vG)u;A1~8CU%q&UGEmo{5$f*i(H#P{2@CXemEiPj0g2*4e ht6zDwe;|=2kVp$i1OSZ>DF6Tf diff --git a/packs-system/skills/MANIFEST-000132 b/packs-system/skills/MANIFEST-000132 new file mode 100644 index 0000000000000000000000000000000000000000..4e28685a0e3bf2c393fecc418a8972be598721f6 GIT binary patch literal 143 zcmdmC8h9Xufss)vC$%g!CnZVGsj?)sJhM2}IX|}`u_&=5zlfcQ_1HlkMa8uIoRrj} zVnr7h3u9wLkCa4{qKq=vG)u;A1~8CU%q&UGEmo{5$f*i(H#P{2@CXemEiPj0g2+!v h^jg5pz{u3f$jQLm#>n!HDKosM9wgER66pYm004SdC+h$J literal 0 HcmV?d00001 diff --git a/styles/creature.less b/styles/creature.less new file mode 100644 index 0000000..beddf7c --- /dev/null +++ b/styles/creature.less @@ -0,0 +1,644 @@ +.creature-content { + .sheet-common(); + .creature-sheet-common(); + overflow: scroll; +} + +.sheet-tabs { + background-color: var(--color-light-1); +} + +.creature-main { + background-color: var(--color-light-1); + display: flex; + + .creature-pc { + display: flex; + gap: 4px; + flex: 1; + + .creature-left { + min-width: 180px; + display: flex; + flex-direction: column; + + .creature-left-image { + display: flex; + justify-content: center; + align-items: center; + padding-bottom: 8px; + .creature-img { + height: 140px; + width: auto; + border: none; + } + } + + .creature-hp { + gap: 2px; + align-items: center; + input { + flex: none; + width: 2rem; + margin-left: 4px; + } + .damage-bonus { + font-size: calc(var(--font-size-standard) * 0.8); + } + .hp-separator { + font-size: calc(var(--font-size-standard) * 1.2); + display: flex; + align-items: center; + justify-content: center; + } + } + + .creature-dv, + .creature-dmax { + .form-fields { + flex: none; + } + } + .creature-dmax-edit { + input { + display: flex; + width: 60px; + font-size: calc(var(--font-size-standard) * 1.4); + align-items: center; + justify-content: center; + padding: 0 5px 0 5px; + text-align: center; + } + } + } + + .creature-right { + display: flex; + flex-direction: column; + gap: 5px; + + .creature-name { + display: flex; + input { + font-family: var(--font-title); + font-size: var(--font-size-title); + width: 400px; + } + } + .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; + } + .button { + min-width: 4rem; + max-width: 4rem; + } + .san-checkbox { + min-width: 1rem; + max-width: 1rem; + } + .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 { + min-width: 2.4rem; + max-width: 2.4rem; + } + input[type="checkbox"] { + min-width: 1rem; + max-width: 1rem; + } + .label-field { + flex-grow: 1; + margin-left: 4px; + max-width: 5rem; + min-width: 5rem; + font-size: 0.9rem; + } + .checkbox { + flex-grow: 0; + min-width: 1rem; + max-width: 1rem; + } + } + label { + min-width: 120px; + } + } + } + + .creature-pc-play { + min-width: 500px; + } + + .creature-pc-edit { + min-width: 650px; + } + + .creature-characteristics { + background-color: var(--color-light-1); + display: flex; + flex-direction: column; + gap: 5px; + flex: 1; + + .creature-characteristic { + display: flex; + align-items: center; + .rollable:hover, + .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; + } + .rollable { + min-width: 3rem; + max-width: 3rem; + } + .char-text { + margin-left: 0.5rem; + } + .d100 { + flex: 0; + max-width: 0.6rem; + } + .form-group { + flex: 0; + padding-left: 5px; + .form-fields { + font-size: 1.1rem; + flex: none; + width: 40px; + } + } + } + } + + .creature-characteristic-play { + min-width: 225px; + } + + .creature-characteristic-edit { + min-width: 400px; + } +} + +.creature-biography { + background-color: var(--color-light-1); + prose-mirror.inactive { + min-height: 40px; + } + prose-mirror.active { + min-height: 150px; + } + .field-label { + margin-left: 8px; + } + + .adapted { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 8px; + label { + min-width: 20rem; + } + } + + .resources { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 8px; + label { + min-width: 8rem; + } + } + + .features, + .biodata { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 8px; + label { + min-width: 3rem; + } + .feature { + display: flex; + align-items: center; + gap: 4px; + min-width: 18rem; + max-width: 18rem; + } + } +} + +.tab.creature-skills { + background-color: var(--color-light-1); + display: grid; + grid-template-columns: 1fr; + legend { + a { + font-size: calc(var(--font-size-standard) * 1.4); + padding-left: 5px; + } + } + + .armors { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 4px; + .armor { + display: flex; + align-items: center; + gap: 4px; + min-width: 13rem; + max-width: 13rem; + .rollable:hover, + .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; + } + .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; + } + .protection { + min-width: 5rem; + max-width: 5rem; + } + .name { + min-width: 8rem; + max-width: 8rem; + } + .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; + } + } + } + + .weapons { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; + .weapon { + display: flex; + align-items: center; + gap: 4px; + min-width: 13rem; + max-width: 13rem; + .rollable:hover, + .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; + } + .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; + } + .damage { + min-width: 6rem; + max-width: 6rem; + } + .name { + min-width: 10rem; + max-width: 10rem; + } + .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; + } + } + } + + .skills { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 4px; + .skill { + display: flex; + align-items: center; + gap: 4px; + margin-left: 4px; + min-width: 12.3rem; + max-width: 12.3rem; + .rollable:hover, + .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; + } + .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; + } + .score { + min-width: 1.2rem; + max-width: 1.2rem; + } + .name { + min-width: 10rem; + max-width: 10rem; + } + .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; + } + } + } +} + +.tab.creature-status { + background-color: var(--color-light-1); + display: grid; + grid-template-columns: 1fr; + legend { + a { + font-size: calc(var(--font-size-standard) * 1.4); + padding-left: 5px; + } + } + + .bonds { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; + .bond { + display: flex; + align-items: center; + gap: 4px; + min-width: 18rem; + max-width: 18rem; + .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; + } + .name { + min-width: 12rem; + max-width: 12rem; + } + .type { + min-width: 6rem; + max-width: 6rem; + } + .level { + min-width: 2rem; + max-width: 2rem; + } + .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; + } + } + } + + .motivations { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; + .motivation { + display: flex; + align-items: center; + gap: 4px; + min-width: 14rem; + max-width: 14rem; + .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; + } + .name { + min-width: 12rem; + max-width: 12rem; + } + .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; + } + } + } + + .mentaldisorders { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; + .mentaldisorder { + display: flex; + align-items: center; + gap: 4px; + min-width: 18rem; + max-width: 18rem; + .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; + } + .name { + min-width: 14rem; + max-width: 14rem; + } + .cured { + min-width: 5rem; + max-width: 5rem; + } + .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; + } + } + } + + .injuries { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; + .injury { + display: flex; + align-items: center; + gap: 4px; + min-width: 16rem; + max-width: 16rem; + .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; + } + .name { + min-width: 14rem; + max-width: 14rem; + } + .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; + } + } + } +} + +.tab.creature-equipment { + background-color: var(--color-light-1); + display: grid; + grid-template-columns: 1fr; + legend { + a { + font-size: calc(var(--font-size-standard) * 1.4); + padding-left: 5px; + } + } + + .gears { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 4px; + .gear { + display: flex; + align-items: center; + gap: 4px; + min-width: 13rem; + max-width: 13rem; + .rollable:hover, + .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; + } + .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; + } + .name { + min-width: 10rem; + max-width: 10rem; + } + .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; + } + } + } + + .rituals { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; + .ritual { + display: flex; + align-items: center; + gap: 4px; + min-width: 20rem; + max-width: 20rem; + .rollable:hover, + .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; + } + .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; + } + .name { + min-width: 17rem; + max-width: 17rem; + } + .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; + } + } + } + + .tomes { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 4px; + .tome { + display: flex; + align-items: center; + gap: 4px; + min-width: 20rem; + max-width: 20rem; + .rollable:hover, + .rollable:focus { + text-shadow: 0 0 8px var(--color-shadow-primary); + cursor: pointer; + } + .controls { + font-size: 0.7rem; + min-width: 1.8rem; + max-width: 1.8rem; + } + .name { + min-width: 17rem; + max-width: 17rem; + } + .item-img { + width: 24px; + height: 24px; + margin: 4px 0 0 0; + } + } + } + + prose-mirror.inactive { + min-height: 40px; + } + prose-mirror.active { + min-height: 150px; + } +} diff --git a/styles/fvtt-cthulhu-eternal.less b/styles/fvtt-cthulhu-eternal.less index 8caaaec..c8aa0f4 100644 --- a/styles/fvtt-cthulhu-eternal.less +++ b/styles/fvtt-cthulhu-eternal.less @@ -5,6 +5,7 @@ @import "mixins.less"; @import "protagonist.less"; @import "vehicle.less"; + @import "creature.less"; @import "skill.less"; @import "injury.less"; @import "weapon.less"; diff --git a/styles/mixins.less b/styles/mixins.less index 614f80e..82fed54 100644 --- a/styles/mixins.less +++ b/styles/mixins.less @@ -68,6 +68,13 @@ } } +.creature-sheet-common { + label { + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1.0); + } +} + .item-sheet-common { .form-fields { padding-top: 4px; diff --git a/system.json b/system.json index 8925939..ea5f397 100644 --- a/system.json +++ b/system.json @@ -35,7 +35,8 @@ "documentTypes": { "Actor": { "protagonist": { "htmlFields": ["description", "notes"] }, - "vehicle": { "htmlFields": ["description", "notes"] } + "vehicle": { "htmlFields": ["description", "notes"] }, + "creature": { "htmlFields": ["description", "notes"] } }, "Item": { "skill": { "htmlFields": ["description"] }, diff --git a/templates/creature-biography.hbs b/templates/creature-biography.hbs new file mode 100644 index 0000000..9cb5840 --- /dev/null +++ b/templates/creature-biography.hbs @@ -0,0 +1,12 @@ +
+ +
+ {{localize "CTHULHUETERNAL.Label.description"}} + {{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}} +
+ +
+ {{localize "CTHULHUETERNAL.Label.notes"}} + {{formInput systemFields.notes enriched=enrichedNotes value=system.notes name="system.notes" toggled=true}} +
+
\ No newline at end of file diff --git a/templates/creature-main.hbs b/templates/creature-main.hbs new file mode 100644 index 0000000..721ea43 --- /dev/null +++ b/templates/creature-main.hbs @@ -0,0 +1,95 @@ +
+
+ {{localize "CTHULHUETERNAL.Label.creature"}} +
+
+
+ +
+ +
+
+
+ {{formInput fields.name value=source.name rootId=partId disabled=isPlayMode}} + + + +
+
+ {{localize "CTHULHUETERNAL.Label.HP"}} +
+ {{formField systemFields.hp.fields.value value=system.hp.value}} + / + {{formField systemFields.hp.fields.max value=system.hp.max }} +
+
+ {{formField systemFields.damageBonus value=system.damageBonus classes="damage-bonus"}} +
+
+ +
+ {{localize "CTHULHUETERNAL.Label.willpower"}} +
+ + {{formInput systemFields.wp.fields.value value=system.wp.value}} + + {{formInput systemFields.wp.fields.max value=system.wp.max rootId=partId }} + + {{formInput systemFields.wp.fields.exhausted value=system.wp.exhausted classes="checkbox"}} +
+
+ +
+ + +
+
+ +
+ {{localize "CTHULHUETERNAL.Label.characteristics"}} +
+ + + {{formField systemFields.characteristics.fields.str.fields.value value=system.characteristics.str.value + rootId=partId disabled=isPlayMode }} + +
+
+ + + {{formField systemFields.characteristics.fields.dex.fields.value value=system.characteristics.dex.value + rootId=partId disabled=isPlayMode }} + +
+
+ + + {{formField systemFields.characteristics.fields.con.fields.value value=system.characteristics.con.value + rootId=partId disabled=isPlayMode }} + +
+
+ + + {{formField systemFields.characteristics.fields.int.fields.value value=system.characteristics.int.value + rootId=partId disabled=isPlayMode }} + +
+
+ + + {{formField systemFields.characteristics.fields.pow.fields.value value=system.characteristics.pow.value + rootId=partId disabled=isPlayMode }} + +
+ +
+ +
\ No newline at end of file diff --git a/templates/creature-skills.hbs b/templates/creature-skills.hbs new file mode 100644 index 0000000..c845acf --- /dev/null +++ b/templates/creature-skills.hbs @@ -0,0 +1,57 @@ +
+ +
+ {{localize "CTHULHUETERNAL.Label.weapons"}}{{#if isEditMode}} + {{/if}} + +
+ {{#each weapons as |item|}} + {{!log 'weapon' this}} + + {{/each}} +
+
+ +
+ {{localize "CTHULHUETERNAL.Label.skills"}} +
+ {{#each skills as |item|}} +
+ + +
{{item.name}} +
+
+ {{item.system.skillTotal}} +
+
+ + +
+
+ {{/each}} +
+
+ + +
\ No newline at end of file diff --git a/templates/weapon.hbs b/templates/weapon.hbs index 6348cb3..f8317d0 100644 --- a/templates/weapon.hbs +++ b/templates/weapon.hbs @@ -13,6 +13,11 @@ {{formField systemFields.state value=system.state localize=true}} + {{formField systemFields.hasDirectSkill value=system.hasDirectSkill }} + {{#if system.hasDirectSkill}} + {{formField systemFields.directSkillValue value=system.directSkillValue }} + {{/if}} + {{formField systemFields.damage value=system.damage}} {{formField systemFields.baseRange value=system.baseRange}} {{formField systemFields.rangeUnit value=system.rangeUnit localize=true}}