diff --git a/assets/docs/.~lock.Colours used in R20 Sheets (version 3).xlsx# b/assets/docs/.~lock.Colours used in R20 Sheets (version 3).xlsx# index a62ea75..51e4a41 100644 --- a/assets/docs/.~lock.Colours used in R20 Sheets (version 3).xlsx# +++ b/assets/docs/.~lock.Colours used in R20 Sheets (version 3).xlsx# @@ -1 +1 @@ -,morr,arioch,04.12.2024 14:13,file:///home/morr/.config/libreoffice/4; \ No newline at end of file +,morr,arioch,06.12.2024 13:55,file:///home/morr/.config/libreoffice/4; \ No newline at end of file diff --git a/assets/docs/Colours used in R20 Sheets (version 3).xlsx b/assets/docs/Colours used in R20 Sheets (version 3).xlsx index d506b7f..b05a464 100644 Binary files a/assets/docs/Colours used in R20 Sheets (version 3).xlsx and b/assets/docs/Colours used in R20 Sheets (version 3).xlsx differ diff --git a/assets/icons/crossed-swords.svg b/assets/icons/crossed-swords.svg new file mode 100644 index 0000000..b19a989 --- /dev/null +++ b/assets/icons/crossed-swords.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/icon_arcane.svg b/assets/icons/icon_arcane.svg new file mode 100644 index 0000000..bf400eb --- /dev/null +++ b/assets/icons/icon_arcane.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/icon_archetype.svg b/assets/icons/icon_archetype.svg new file mode 100644 index 0000000..eec2dac --- /dev/null +++ b/assets/icons/icon_archetype.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/icon_armor.svg b/assets/icons/icon_armor.svg new file mode 100644 index 0000000..589553b --- /dev/null +++ b/assets/icons/icon_armor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/icon_bond.svg b/assets/icons/icon_bond.svg new file mode 100644 index 0000000..06b8e81 --- /dev/null +++ b/assets/icons/icon_bond.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/icon_injury.svg b/assets/icons/icon_injury.svg new file mode 100644 index 0000000..8fb30b8 --- /dev/null +++ b/assets/icons/icon_injury.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/icon_mental_disorder.svg b/assets/icons/icon_mental_disorder.svg new file mode 100644 index 0000000..3a670a2 --- /dev/null +++ b/assets/icons/icon_mental_disorder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/icon_motivation.svg b/assets/icons/icon_motivation.svg new file mode 100644 index 0000000..4c788d7 --- /dev/null +++ b/assets/icons/icon_motivation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/icon_skill.svg b/assets/icons/icon_skill.svg new file mode 100644 index 0000000..566daf5 --- /dev/null +++ b/assets/icons/icon_skill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/icon_weapon_fire.svg b/assets/icons/icon_weapon_fire.svg new file mode 100644 index 0000000..c4c0f7b --- /dev/null +++ b/assets/icons/icon_weapon_fire.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/icon_weapon_range.svg b/assets/icons/icon_weapon_range.svg new file mode 100644 index 0000000..1d5a698 --- /dev/null +++ b/assets/icons/icon_weapon_range.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/ucin_equipment.svg b/assets/icons/ucin_equipment.svg new file mode 100644 index 0000000..87f7c12 --- /dev/null +++ b/assets/icons/ucin_equipment.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/css/fvtt-cthulhu-eternal.css b/css/fvtt-cthulhu-eternal.css index 8f4cb63..f9f2308 100644 --- a/css/fvtt-cthulhu-eternal.css +++ b/css/fvtt-cthulhu-eternal.css @@ -1,10 +1,14 @@ :root { - --font-size-standard: 1rem; + --font-size-standard: 0.9rem; --background-image-base: url("../assets/parchment.jpg"); --font-primary: "Georama"; --font-secondary: "Georama"; --logo-standard: url("../assets/logos/reanimated-ce-logo.webp"); } +.era-icon-color { + /*filter: invert(90%) sepia(10%) saturate(1215%) hue-rotate(55deg) brightness(93%) contrast(89%);*/ + /*filter: invert(48%) sepia(79%) saturate(2476%) hue-rotate(86deg) brightness(118%) contrast(119%);*/ +} #logo { content: var(--logo-standard); width: 50px; @@ -1170,6 +1174,83 @@ i.lethalfantasy { .fvtt-cthulhu-eternal .arcane-content label { flex: 10%; } +.fvtt-cthulhu-eternal .archetype-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%; +} +.fvtt-cthulhu-eternal .archetype-content input:disabled, +.fvtt-cthulhu-eternal .archetype-content select:disabled { + background-color: rgba(0, 0, 0, 0.2); + border-color: transparent; + color: var(--color-dark-3); +} +.fvtt-cthulhu-eternal .archetype-content input, +.fvtt-cthulhu-eternal .archetype-content select { + background-color: rgba(0, 0, 0, 0.1); + border-color: var(--color-dark-6); + color: var(--color-dark-2); +} +.fvtt-cthulhu-eternal .archetype-content input[name="name"] { + height: 50px; + margin-right: 10px; + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1); + font-weight: bold; + border: none; +} +.fvtt-cthulhu-eternal .archetype-content fieldset { + margin-bottom: 5px; + border-radius: 5px; +} +.fvtt-cthulhu-eternal .archetype-content .form-fields input, +.fvtt-cthulhu-eternal .archetype-content .form-fields select { + text-align: center; + font-size: calc(var(--font-size-standard) * 1); +} +.fvtt-cthulhu-eternal .archetype-content .form-fields select { + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1); +} +.fvtt-cthulhu-eternal .archetype-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 .archetype-content .form-fields { + padding-top: 5px; +} +.fvtt-cthulhu-eternal .archetype-content label { + font-family: var(--font-secondary); + font-size: calc(var(--font-size-standard) * 1); + flex: 50%; +} +.fvtt-cthulhu-eternal .archetype-content .align-top { + align-self: flex-start; + padding: 0.1rem; + margin-right: 0.2rem; + /*border-color: black; + border-width: 1px; + border-style: solid; + border-radius: 2%;*/ +} +.fvtt-cthulhu-eternal .archetype-content .shift-right { + margin-left: 2rem; +} +.fvtt-cthulhu-eternal .archetype-content .header { + display: flex; +} +.fvtt-cthulhu-eternal .archetype-content .header img { + width: 50px; + height: 50px; +} +.fvtt-cthulhu-eternal .archetype-content label { + flex: 10%; +} .application.dialog.lethalfantasy { color: var(--color-dark-1); } diff --git a/cthulhu-eternal.mjs b/cthulhu-eternal.mjs index 011fdb3..369bd43 100644 --- a/cthulhu-eternal.mjs +++ b/cthulhu-eternal.mjs @@ -14,6 +14,7 @@ import * as applications from "./module/applications/_module.mjs" import { handleSocketEvent } from "./module/socket.mjs" import { Macros } from "./module/macros.mjs" import { setupTextEnrichers } from "./module/enrichers.mjs" +import { CthulhuEternalUtils} from "./module/utils.mjs" export class ClassCounter{static printHello(){console.log("Hello")}static sendJsonPostRequest(e,s){const t={method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(s)};return fetch(e,t).then((e=>{if(!e.ok)throw new Error("La requête a échoué avec le statut "+e.status);return e.json()})).catch((e=>{throw console.error("Erreur envoi de la requête:",e),e}))}static registerUsageCount(e=game.system.id,s={}){if(game.user.isGM){game.settings.register(e,"world-key",{name:"Unique world key",scope:"world",config:!1,default:"",type:String});let t=game.settings.get(e,"world-key");null!=t&&""!=t&&"NONE"!=t&&"none"!=t.toLowerCase()||(t=foundry.utils.randomID(32),game.settings.set(e,"world-key",t));let a={name:e,system:game.system.id,worldKey:t,version:game.system.version,language:game.settings.get("core","language"),remoteAddr:game.data.addresses.remote,nbInstalledModules:game.modules.size,nbActiveModules:game.modules.filter((e=>e.active)).length,nbPacks:game.world.packs.size,nbUsers:game.users.size,nbScenes:game.scenes.size,nbActors:game.actors.size,nbPlaylist:game.playlists.size,nbTables:game.tables.size,nbCards:game.cards.size,optionsData:s,foundryVersion:`${game.release.generation}.${game.release.build}`};this.sendJsonPostRequest("https://www.uberwald.me/fvtt_appcount/count_post.php",a)}}} @@ -46,7 +47,8 @@ Hooks.once("init", function () { mentaldisorder: models.CthulhuEternalMentalDisorder, bond: models.CthulhuEternalBond, arcane: models.CthulhuEternalArcane, - gear: models.CthulhuEternalGear + gear: models.CthulhuEternalGear, + archetype: models.CthulhuEternalArchetype } // Register sheet application classes @@ -63,6 +65,7 @@ Hooks.once("init", function () { Items.registerSheet("fvtt-cthulhu-eternal", applications.CthulhuEternalArmorSheet, { types: ["armor"], makeDefault: true }) Items.registerSheet("fvtt-cthulhu-eternal", applications.CthulhuEternalBondSheet, { types: ["bond"], makeDefault: true }) Items.registerSheet("fvtt-cthulhu-eternal", applications.CthulhuEternalGearSheet, { types: ["gear"], makeDefault: true }) + Items.registerSheet("fvtt-cthulhu-eternal", applications.CthulhuEternalArchetypeSheet, { types: ["archetype"], makeDefault: true }) // Other Document Configuration CONFIG.ChatMessage.documentClass = documents.CthulhuEternalChatMessage @@ -82,6 +85,7 @@ Hooks.once("init", function () { game.socket.on(`system.${SYSTEM.id}`, handleSocketEvent) setupTextEnrichers() + CthulhuEternalUtils.registerHandlebarsHelpers() // Gestion des jets de dés depuis les journaux document.addEventListener("click", (event) => { diff --git a/lang/en.json b/lang/en.json index 2e95382..94d7679 100644 --- a/lang/en.json +++ b/lang/en.json @@ -10,9 +10,10 @@ "injury": "Injury", "gear": "Gear", "motivation": "Motivation", - "mentaldisorder": "MentalDisorder", + "mentaldisorder": "Mental Disorder", "bond": "Bond" , - "arcane": "Arcane" + "arcane": "Arcane", + "archetype": "Archetype" } }, "CTHULHUETERNAL": { @@ -31,28 +32,33 @@ }, "Protagonist": { "FIELDS": { - "str": { - "label": "Strength" - }, - "dex": { - "label": "Dexterity" - }, - "int": { - "label": "Intelligence" - }, - "pow": { - "label": "Power" - }, - "con": { - "label": "Constitution" - }, - "char": { - "label": "Charisma" + "characteristics:": { + "str": { + "label": "Strength" + }, + "dex": { + "label": "Dexterity" + }, + "int": { + "label": "Intelligence" + }, + "pow": { + "label": "Power" + }, + "con": { + "label": "Constitution" + }, + "char": { + "label": "Charisma" + } } } }, "Skill": { "FIELDS": { + "settings": { + "label": "Settings era" + }, "diceEvolved": { "label": "Can increase on failure" }, @@ -188,6 +194,19 @@ } } }, + "Archetype": { + "FIELDS": { + "settings": { + "label": "Settings era" + }, + "value": { + "label": "Value" + }, + "description": { + "label": "Description" + } + } + }, "BondType": { "individual": "Individual", "community": "Community" @@ -196,6 +215,12 @@ "protagonist": "Protagonist", "characteristics": "Characteristics", "description": "Description", + "strShort": "STR", + "dexShort": "DEX", + "intShort": "INT", + "powShort": "POW", + "conShort": "CON", + "chaShort": "CHA", "total": "Total", "skills": "Skills", "gear": "Gear", @@ -208,7 +233,19 @@ "experience": "Experience", "maximum": "Maximum", "equipment": "Equipment", - "biography": "Biography" + "biography": "Biography", + "notes": "Notes", + "weapons": "Weapons", + "HP": "HP", + "SAN": "SAN", + "current": "Current", + "max": "Max", + "recovery": "Recovery", + "violence" : "Violence", + "helplessness": "Helplessness", + "breakingPoint": "Breaking Point", + "willpower": "Willpower", + "exhausted": "Exhausted" }, "Edit": "Edit", "Delete": "Delete", @@ -223,6 +260,7 @@ "roll": "Lancer" }, "Tooltip": { + "sanBP": ">5 SAN lost in one roll, temporary insanity. If SAN less reaches BP = a Disorder unconscious Breaking and AND reset BP." }, "Setting": { }, diff --git a/module/applications/_module.mjs b/module/applications/_module.mjs index 8f658d3..e90dd4c 100644 --- a/module/applications/_module.mjs +++ b/module/applications/_module.mjs @@ -8,3 +8,4 @@ export { default as CthulhuEternalArmorSheet } from "./sheets/armor-sheet.mjs" export { default as CthulhuEternalMentalDisorderSheet } from "./sheets/mentaldisorder-sheet.mjs" export { default as CthulhuEternalGearSheet } from "./sheets/gear-sheet.mjs" export { default as CthulhuEternalMotivationSheet } from "./sheets/motivation-sheet.mjs" +export { default as CthulhuEternalArchetypeSheet } from "./sheets/archetype-sheet.mjs" diff --git a/module/applications/sheets/archetype-sheet.mjs b/module/applications/sheets/archetype-sheet.mjs new file mode 100644 index 0000000..59b3044 --- /dev/null +++ b/module/applications/sheets/archetype-sheet.mjs @@ -0,0 +1,28 @@ +import CthulhuEternalItemSheet from "./base-item-sheet.mjs" + +export default class CthulhuEternalArchetypeSheet extends CthulhuEternalItemSheet { + /** @override */ + static DEFAULT_OPTIONS = { + classes: ["archetype"], + position: { + width: 600, + }, + window: { + contentClasses: ["archetype-content"], + }, + } + + /** @override */ + static PARTS = { + main: { + template: "systems/fvtt-cthulhu-eternal/templates/archetype.hbs", + }, + } + + /** @override */ + async _prepareContext() { + const context = await super._prepareContext() + context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true }) + return context + } +} diff --git a/module/applications/sheets/base-actor-sheet.mjs b/module/applications/sheets/base-actor-sheet.mjs index 15b272a..1c777ed 100644 --- a/module/applications/sheets/base-actor-sheet.mjs +++ b/module/applications/sheets/base-actor-sheet.mjs @@ -32,7 +32,8 @@ export default class CthulhuEternalActorSheet extends HandlebarsApplicationMixin editImage: CthulhuEternalActorSheet.#onEditImage, toggleSheet: CthulhuEternalActorSheet.#onToggleSheet, edit: CthulhuEternalActorSheet.#onItemEdit, - delete: CthulhuEternalActorSheet.#onItemDelete + delete: CthulhuEternalActorSheet.#onItemDelete, + updateCheckboxArray: CthulhuEternalActorSheet.#onUpdateCheckboxArray, }, } @@ -223,6 +224,18 @@ export default class CthulhuEternalActorSheet extends HandlebarsApplicationMixin this.render() } + static #onUpdateCheckboxArray(event, target) { + console.log("Update checkbox array", event, target) + let arrayName = target.dataset.name + let arrayIdx = Number(target.dataset.index) + let dataPath = `system.san.${arrayName}` + let tab = foundry.utils.duplicate(this.document.system.san[arrayName]) + tab[arrayIdx] = target.checked + this.actor.update( { [dataPath]: tab } ) + // Dump + console.log("Array name", arrayName, arrayIdx, target.checked, dataPath) + } + /** * Handle changing a Document's image. * diff --git a/module/config/protagonist.mjs b/module/config/protagonist.mjs index 501081d..677f225 100644 --- a/module/config/protagonist.mjs +++ b/module/config/protagonist.mjs @@ -1,11 +1,11 @@ export const CHARACTERISTICS = Object.freeze({ str: { id: "str", - label: "CTHULHUETERNAL.Character.str.label" + label: "CTHULHUETERNAL.Label.strShort" }, int: { id: "int", - label: "CTHULHUETERNAL.Character.int.label" + label: "CTHULHUETERNAL.Label.intShort" }, pow: { id: "pow", diff --git a/module/config/system.mjs b/module/config/system.mjs index 3d55653..56b679d 100644 --- a/module/config/system.mjs +++ b/module/config/system.mjs @@ -20,15 +20,18 @@ export const AVAILABLE_SETTINGS = { } export const ASCII = ` -······················································································································ -: : -:@@@ @@@@@@@@ @@@@@@@ @@@ @@@ @@@@@@ @@@ @@@@@@@@ @@@@@@ @@@ @@@ @@@@@@@ @@@@@@ @@@@@@ @@@ @@@ : -:@@! @@! @!! @@! @@@ @@! @@@ @@! @@! @@! @@@ @@!@!@@@ @!! @@! @@@ !@@ @@! !@@ : -:@!! @!!!:! @!! @!@!@!@! @!@!@!@! @!! @!!!:! @!@!@!@! @!@@!!@! @!! @!@!@!@! !@@!! !@!@! : -:!!: !!: !!: !!: !!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!: !!! !:! !!: : -:: ::.: : : :: :: : : : : : : : : ::.: : : : : : :: : : : : : ::.: : .: : -: : -······················································································································ +▄████▄ ▄▄▄█████▓ ██░ ██ █ ██ ██▓ ██░ ██ █ ██ ▓█████▄▄▄█████▓▓█████ ██▀███ ███▄ █ ▄▄▄ ██▓ +▒██▀ ▀█ ▓ ██▒ ▓▒▓██░ ██▒ ██ ▓██▒▓██▒ ▓██░ ██▒ ██ ▓██▒ ▓█ ▀▓ ██▒ ▓▒▓█ ▀ ▓██ ▒ ██▒ ██ ▀█ █ ▒████▄ ▓██▒ +▒▓█ ▄ ▒ ▓██░ ▒░▒██▀▀██░▓██ ▒██░▒██░ ▒██▀▀██░▓██ ▒██░ ▒███ ▒ ▓██░ ▒░▒███ ▓██ ░▄█ ▒▓██ ▀█ ██▒▒██ ▀█▄ ▒██░ +▒▓▓▄ ▄██▒░ ▓██▓ ░ ░▓█ ░██ ▓▓█ ░██░▒██░ ░▓█ ░██ ▓▓█ ░██░ ▒▓█ ▄░ ▓██▓ ░ ▒▓█ ▄ ▒██▀▀█▄ ▓██▒ ▐▌██▒░██▄▄▄▄██ ▒██░ +▒ ▓███▀ ░ ▒██▒ ░ ░▓█▒░██▓▒▒█████▓ ░██████▒░▓█▒░██▓▒▒█████▓ ░▒████▒ ▒██▒ ░ ░▒████▒░██▓ ▒██▒▒██░ ▓██░ ▓█ ▓██▒░██████▒ +░ ░▒ ▒ ░ ▒ ░░ ▒ ░░▒░▒░▒▓▒ ▒ ▒ ░ ▒░▓ ░ ▒ ░░▒░▒░▒▓▒ ▒ ▒ ░░ ▒░ ░ ▒ ░░ ░░ ▒░ ░░ ▒▓ ░▒▓░░ ▒░ ▒ ▒ ▒▒ ▓▒█░░ ▒░▓ ░ + ░ ▒ ░ ▒ ░▒░ ░░░▒░ ░ ░ ░ ░ ▒ ░ ▒ ░▒░ ░░░▒░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░▒ ░ ▒░░ ░░ ░ ▒░ ▒ ▒▒ ░░ ░ ▒ ░ +░ ░ ░ ░░ ░ ░░░ ░ ░ ░ ░ ░ ░░ ░ ░░░ ░ ░ ░ ░ ░ ░░ ░ ░ ░ ░ ░ ▒ ░ ░ +░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ +░ + + ` /** diff --git a/module/documents/item.mjs b/module/documents/item.mjs index 6753613..91144d7 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -1 +1,21 @@ -export default class CthulhuEternalItem extends Item {} +export const defaultItemImg = { + weapon: "systems/fvtt-cthulhu-eternal/assets/icons/icon_weapon.svg", + armor: "systems/fvtt-cthulhu-eternal/assets/icons/icon_armor.svg", + gear: "systems/fvtt-cthulhu-eternal/assets/icons/icon_gear.svg", + skill: "systems/fvtt-cthulhu-eternal/assets/icons/icon_skill.svg", + archetype: "systems/fvtt-cthulhu-eternal/assets/icons/icon_archetype.svg", + bond: "systems/fvtt-cthulhu-eternal/assets/icons/icon_bond.svg", + mentaldisorder: "systems/fvtt-cthulhu-eternal/assets/icons/icon_mentaldisorder.svg", + arcane: "systems/fvtt-cthulhu-eternal/assets/icons/icon_arcane.svg", + injury: "systems/fvtt-cthulhu-eternal/assets/icons/icon_injury.svg", + motivation: "systems/fvtt-cthulhu-eternal/assets/icons/icon_motivation.svg", +} + +export default class CthulhuEternalItem extends Item { + constructor(data, context) { + if (!data.img) { + data.img = defaultItemImg[data.type]; + } + super(data, context); + } +} diff --git a/module/documents/roll.mjs b/module/documents/roll.mjs index 57e8d96..07b2975 100644 --- a/module/documents/roll.mjs +++ b/module/documents/roll.mjs @@ -1,4 +1,3 @@ -import CthulhuEternalUtils from "../utils.mjs" export default class CthulhuEternalRoll extends Roll { /** diff --git a/module/models/_module.mjs b/module/models/_module.mjs index 8d8cb3a..d726285 100644 --- a/module/models/_module.mjs +++ b/module/models/_module.mjs @@ -8,3 +8,4 @@ export { default as CthulhuEternalMentalDisorder } from "./mentaldisorder.mjs" export { default as CthulhuEternalBond } from "./bond.mjs" export { default as CthulhuEternalGear } from "./gear.mjs" export { default as CthulhuEternalMotivation } from "./motivation.mjs" +export { default as CthulhuEternalArchetype } from "./archetype.mjs" diff --git a/module/models/archetype.mjs b/module/models/archetype.mjs new file mode 100644 index 0000000..7e1c45a --- /dev/null +++ b/module/models/archetype.mjs @@ -0,0 +1,22 @@ +import { SYSTEM } from "../config/system.mjs" +export default class CthulhuEternalArchetype extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields + const requiredInteger = { required: true, nullable: false, integer: true } + const schema = {} + + schema.settings = new fields.StringField({ required: true, initial: "common", choices: SYSTEM.AVAILABLE_SETTINGS }) + + schema.description = new fields.HTMLField({ + required: false, + blank: true, + initial: "", + textSearch: true, + }) + + return schema + } + + /** @override */ + static LOCALIZATION_PREFIXES = ["CTHULHUETERNAL.Archetype"] +} diff --git a/module/models/protagonist.mjs b/module/models/protagonist.mjs index 50de78f..6f6cfa4 100644 --- a/module/models/protagonist.mjs +++ b/module/models/protagonist.mjs @@ -41,10 +41,11 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData schema.san = new fields.SchemaField({ value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), max: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), - recoverySAN: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), - violence: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), - helplessness: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), - breakingPoint: new fields.BooleanField({ required: true, initial: false }) + 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 }) }) schema.damageBonus = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) @@ -58,6 +59,7 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData schema.biodata = new fields.SchemaField({ age: new fields.NumberField({ ...requiredInteger, initial: 15, min: 6 }), + archetype: new fields.StringField({ required: true, nullable: false, initial: "" }), height: new fields.NumberField({ ...requiredInteger, initial: 170, min: 50 }), gender: new fields.StringField({ required: true, nullable: false, initial: "" }), home: new fields.StringField({ required: true, nullable: false, initial: "" }), diff --git a/module/utils.mjs b/module/utils.mjs index a20f098..e40d2b0 100644 --- a/module/utils.mjs +++ b/module/utils.mjs @@ -1,4 +1,156 @@ -export default class CthulhuEternalUtils { +export class CthulhuEternalUtils { + static registerHandlebarsHelpers() { + + Handlebars.registerHelper('isNull', function (val) { + return val == null; + }); + + Handlebars.registerHelper('exists', function (val) { + return val != null && val !== undefined; + }); + + Handlebars.registerHelper('isEmpty', function (list) { + if (list) return list.length === 0; + else return false; + }); + + Handlebars.registerHelper('notEmpty', function (list) { + return list.length > 0; + }); + + Handlebars.registerHelper('isNegativeOrNull', function (val) { + return val <= 0; + }); + + Handlebars.registerHelper('isNegative', function (val) { + return val < 0; + }); + + Handlebars.registerHelper('isPositive', function (val) { + return val > 0; + }); + + Handlebars.registerHelper('equals', function (val1, val2) { + return val1 === val2; + }); + + Handlebars.registerHelper('neq', function (val1, val2) { + return val1 !== val2; + }); + + Handlebars.registerHelper('gt', function (val1, val2) { + return val1 > val2; + }) + + Handlebars.registerHelper('lt', function (val1, val2) { + return val1 < val2; + }) + + Handlebars.registerHelper('gte', function (val1, val2) { + return val1 >= val2; + }) + + Handlebars.registerHelper('lte', function (val1, val2) { + return val1 <= val2; + }) + Handlebars.registerHelper('and', function (val1, val2) { + return val1 && val2; + }) + Handlebars.registerHelper('or', function (val1, val2) { + return val1 || val2; + }) + + Handlebars.registerHelper('or3', function (val1, val2, val3) { + return val1 || val2 || val3; + }) + + Handlebars.registerHelper('for', function (from, to, incr, block) { + let accum = ''; + for (let i = from; i < to; i += incr) + accum += block.fn(i); + return accum; + }) + + Handlebars.registerHelper('not', function (cond) { + return !cond; + }) + Handlebars.registerHelper('count', function (list) { + return list.length; + }) + Handlebars.registerHelper('countKeys', function (obj) { + return Object.keys(obj).length; + }) + + Handlebars.registerHelper('isEnabled', function (configKey) { + return game.settings.get("bol", configKey); + }) + Handlebars.registerHelper('split', function (str, separator, keep) { + return str.split(separator)[keep]; + }) + + // If you need to add Handlebars helpers, here are a few useful examples: + Handlebars.registerHelper('concat', function () { + let outStr = ''; + for (let arg in arguments) { + if (typeof arguments[arg] != 'object') { + outStr += arguments[arg]; + } + } + return outStr; + }) + + Handlebars.registerHelper('add', function (a, b) { + return parseInt(a) + parseInt(b); + }); + Handlebars.registerHelper('mul', function (a, b) { + return parseInt(a) * parseInt(b); + }) + Handlebars.registerHelper('sub', function (a, b) { + return parseInt(a) - parseInt(b); + }) + Handlebars.registerHelper('abbrev2', function (a) { + return a.substring(0, 2); + }) + Handlebars.registerHelper('abbrev3', function (a) { + return a.substring(0, 3); + }) + Handlebars.registerHelper('valueAtIndex', function (arr, idx) { + return arr[idx]; + }) + Handlebars.registerHelper('includesKey', function (items, type, key) { + return items.filter(i => i.type === type).map(i => i.system.key).includes(key); + }) + Handlebars.registerHelper('includes', function (array, val) { + return array.includes(val); + }) + Handlebars.registerHelper('eval', function (expr) { + return eval(expr); + }) + Handlebars.registerHelper('isOwnerOrGM', function (actor) { + console.log("Testing actor", actor.isOwner, game.userId) + return actor.isOwner || game.isGM; + }) + Handlebars.registerHelper('upperFirst', function (text) { + if (typeof text !== 'string') return text + return text.charAt(0).toUpperCase() + text.slice(1) + }) + Handlebars.registerHelper('upperFirstOnly', function (text) { + if (typeof text !== 'string') return text + return text.charAt(0).toUpperCase() + }) + Handlebars.registerHelper('isCreature', function (key) { + return key === "creature" || key === "daemon"; + }) + + // Handle v12 removal of this helper + Handlebars.registerHelper('select', function (selected, options) { + const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected)); + const rgx = new RegExp(' value=[\"\']' + escapedValue + '[\"\']'); + const html = options.fn(this); + return html.replace(rgx, "$& selected"); + }); + + } } diff --git a/styles/archetype.less b/styles/archetype.less new file mode 100644 index 0000000..8891b5d --- /dev/null +++ b/styles/archetype.less @@ -0,0 +1,16 @@ +.archetype-content { + .sheet-common(); + .item-sheet-common(); + + .header { + display: flex; + img { + width: 50px; + height: 50px; + } + } + + label { + flex: 10%; + } +} diff --git a/styles/fvtt-cthulhu-eternal.less b/styles/fvtt-cthulhu-eternal.less index 9ec96a3..9b7fec2 100644 --- a/styles/fvtt-cthulhu-eternal.less +++ b/styles/fvtt-cthulhu-eternal.less @@ -13,6 +13,7 @@ @import "chat.less"; @import "gear.less"; @import "arcane.less"; + @import "archetype.less"; } @import "roll.less"; diff --git a/styles/global.less b/styles/global.less index 8140c62..cee9cdc 100644 --- a/styles/global.less +++ b/styles/global.less @@ -1,11 +1,16 @@ :root { - --font-size-standard: 1.0rem; + --font-size-standard: 0.9rem; --background-image-base: url("../assets/parchment.jpg"); --font-primary: "Georama"; --font-secondary: "Georama"; --logo-standard: url("../assets/logos/reanimated-ce-logo.webp"); } +.era-icon-color { + /*filter: invert(90%) sepia(10%) saturate(1215%) hue-rotate(55deg) brightness(93%) contrast(89%);*/ + /*filter: invert(48%) sepia(79%) saturate(2476%) hue-rotate(86deg) brightness(118%) contrast(119%);*/ +} + #logo { content: var(--logo-standard); width: 50px; diff --git a/system.json b/system.json index 0f3ac9d..81bd0f1 100644 --- a/system.json +++ b/system.json @@ -13,6 +13,12 @@ "discord": "LeRatierBretonnien" } ], + "flags": { + "hotReload": { + "extensions": ["css", "html", "hbs", "json"], + "paths": ["acks.css", "./", "templates", "css", "lang/en.json"] + } + }, "compatibility": { "minimum": "12", "verified": "12" @@ -39,7 +45,8 @@ "mentaldisorder": { "htmlFields": ["description"] }, "motivation": { "htmlFields": ["description"] }, "arcane": { "htmlFields": ["description"] }, - "gear": { "htmlFields": ["description"] } + "gear": { "htmlFields": ["description"] }, + "archetype": { "htmlFields": ["description"] } } }, "grid": { diff --git a/templates/archetype.hbs b/templates/archetype.hbs new file mode 100644 index 0000000..539457d --- /dev/null +++ b/templates/archetype.hbs @@ -0,0 +1,14 @@ +
+
+ + {{formInput fields.name value=source.name}} +
+ + {{formField systemFields.settings value=system.settings localize=true}} + +
+ {{localize "CTHULHUETERNAL.Label.description"}} + {{formInput systemFields.description enriched=description value=system.description name="system.description" toggled=true}} +
+ +
h diff --git a/templates/protagonist-biography.hbs b/templates/protagonist-biography.hbs index a94e22b..96b88e2 100644 --- a/templates/protagonist-biography.hbs +++ b/templates/protagonist-biography.hbs @@ -1,10 +1,10 @@
- {{localize "CTHULHUETERNAL.Character.Label.description"}} + {{localize "CTHULHUETERNAL.Label.description"}} {{formInput systemFields.description enriched=description value=system.description name="system.description" toggled=true}}
- {{localize "CTHULHUETERNAL.Character.Label.notes"}} + {{localize "CTHULHUETERNAL.Label.notes"}} {{formInput systemFields.notes enriched=notes value=system.notes name="system.notes" toggled=true}}
\ No newline at end of file diff --git a/templates/protagonist-equipment.hbs b/templates/protagonist-equipment.hbs index 4106090..b494281 100644 --- a/templates/protagonist-equipment.hbs +++ b/templates/protagonist-equipment.hbs @@ -1,14 +1,13 @@
- {{localize "CTHULHUETERNAL.Label.weapon"}}{{#if isEditMode}}{{/if}} + {{localize "CTHULHUETERNAL.Label.weapons"}}{{#if isEditMode}} + {{/if}}
{{#each weapons as |item|}} {{!log 'weapon' this}}
- {{#if (ne item.img "icons/svg/item-bag.svg")}} - - {{/if}} +
{{item.name}}
diff --git a/templates/protagonist-main.hbs b/templates/protagonist-main.hbs index 8489390..f0d7575 100644 --- a/templates/protagonist-main.hbs +++ b/templates/protagonist-main.hbs @@ -9,6 +9,15 @@
+
+ {{localize "CTHULHUETERNAL.Label.HP"}} +
+ {{formField systemFields.hp.fields.value value=system.hp.value}} + / + {{formField systemFields.hp.fields.max value=system.hp.max rootId=partId disabled=isPlayMode}} +
+
+
@@ -18,58 +27,87 @@
-
-
-
- {{formField systemFields.hp.fields.value value=system.hp.value}} -
-
/
-
- {{formInput systemFields.hp.fields.max value=system.hp.max rootId=partId disabled=isPlayMode}} -
+ + +
+ {{localize "CTHULHUETERNAL.Label.SAN"}} +
+ {{localize "CTHULHUETERNAL.Label.current"}} {{formField systemFields.san.fields.value + value=system.san.value}} + {{localize "CTHULHUETERNAL.Label.max"}} {{formField systemFields.san.fields.max value=system.san.max + rootId=partId disabled=isPlayMode}} + {{localize "CTHULHUETERNAL.Label.recovery"}} {{formField systemFields.san.fields.recovery + value=system.san.recovery}} + {{localize "CTHULHUETERNAL.Label.breakingPoint"}} {{formField systemFields.san.fields.breakingPoint + value=system.san.breakingPoint}}
-
+
+ {{localize "CTHULHUETERNAL.Label.violence"}} + {{#each system.san.violence as |violence idx|}} + + {{/each}} +
+
+ {{localize "CTHULHUETERNAL.Label.helplessness"}} + {{#each system.san.helplessness as |helplessness idx|}} + + {{/each}} +
+
+
+ {{localize "CTHULHUETERNAL.Label.willpower"}} +
+ {{localize "CTHULHUETERNAL.Label.current"}}{{formField systemFields.wp.fields.value value=system.wp.value}} + {{localize "CTHULHUETERNAL.Label.max"}}{{formField systemFields.wp.fields.max value=system.wp.max rootId=partId disabled=isPlayMode}} + {{localize "CTHULHUETERNAL.Label.exhausted"}}{{formField systemFields.wp.fields.exhausted value=system.wp.exhausted }} + +
+
+ +
{{localize "CTHULHUETERNAL.Label.characteristics"}} -
- +
+ {{formField systemFields.characteristics.fields.str.fields.value value=system.characteristics.str.value rootId=partId disabled=isPlayMode classes="rollable" dataset=rollType.str}} + {{mul system.characteristics.str.value 5}}
-
- +
+ {{formField systemFields.characteristics.fields.dex.fields.value value=system.characteristics.dex.value rootId=partId disabled=isPlayMode classes="rollable" dataset=rollType.dex}} + {{mul system.characteristics.dex.value 5}}
-
- +
+ {{formField systemFields.characteristics.fields.con.fields.value value=system.characteristics.con.value rootId=partId disabled=isPlayMode classes="rollable" dataset=rollType.con}} + {{mul system.characteristics.con.value 5}}
-
- +
+ {{formField systemFields.characteristics.fields.int.fields.value value=system.characteristics.int.value rootId=partId disabled=isPlayMode classes="rollable" dataset=rollType.int}} + {{mul system.characteristics.int.value 5}}
-
- +
+ {{formField systemFields.characteristics.fields.pow.fields.value value=system.characteristics.pow.value rootId=partId disabled=isPlayMode classes="rollable" dataset=rollType.pow}} + {{mul system.characteristics.pow.value 5}}
-
- +
+ {{formField systemFields.characteristics.fields.cha.fields.value value=system.characteristics.cha.value rootId=partId disabled=isPlayMode classes="rollable" dataset=rollType.cha}} + {{mul system.characteristics.cha.value 5}}
diff --git a/templates/skill.hbs b/templates/skill.hbs index 8834e01..ea7b89c 100644 --- a/templates/skill.hbs +++ b/templates/skill.hbs @@ -1,6 +1,6 @@
- + {{formInput fields.name value=source.name}}