Compare commits
	
		
			11 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b21c5ac9bb | |||
| a43bebc63b | |||
| 2b418695c4 | |||
| 5dbb168891 | |||
| 009024296c | |||
| 968c7da5c5 | |||
| 67ff06f953 | |||
| 24c5c685d0 | |||
| d62b5472fe | |||
| a1ef74a3ad | |||
| ff89b62133 | 
| @@ -27,7 +27,7 @@ jobs: | ||||
|       env: | ||||
|         version: ${{steps.get_version.outputs.version-without-v}} | ||||
|         url: https://www.uberwald.me/gitea/${{gitea.repository}} | ||||
|         manifest: https://www.uberwald.me/gitea/public/${{gitea.repository}}/releases/download/latest/system.json | ||||
|         manifest: https://www.uberwald.me/gitea/public/fvtt-cthulhu-eternal/releases/download/latest/system.json | ||||
|         download: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/fvtt-cthulhu-eternal.zip | ||||
|      | ||||
|     # Create a zip file with all files required by the module to add to the release | ||||
| @@ -50,3 +50,14 @@ jobs: | ||||
|           ./fvtt-cthulhu-eternal.zip | ||||
|           system.json | ||||
|         api_key: '${{secrets.ALLOW_PUSH_RELEASE}}' | ||||
|      | ||||
|     - name: Publish to Foundry server   | ||||
|       uses: djlechuck/foundryvtt-publish-package-action@v1 | ||||
|       with: | ||||
|         token: ${{ secrets.FOUNDRYVTT_RELEASE_TOKEN }} | ||||
|         id: 'fvtt-cthulhu-eternal' | ||||
|         version: ${{github.event.release.tag_name}} | ||||
|         manifest: 'https://www.uberwald.me/gitea/public/fvtt-cthulhu-eternal/releases/download/latest/system.json' | ||||
|         notes: 'https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/fvtt-cthulhu-eternal.zip' | ||||
|         compatibility-minimum: '12' | ||||
|         compatibility-verified: '12' | ||||
							
								
								
									
										15
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,6 +1,15 @@ | ||||
|  | ||||
| <h2><em>Cthulhu Eternal RPG</em> for Foundry Virtual TableTop</h2> | ||||
| # Cthulhu Eternal RPG for FoundryVTT | ||||
|  | ||||
| <div align="center"> | ||||
| Cthulhu Eternal : https://cthulhueternal.com/  | ||||
|  | ||||
| </div> | ||||
| The system contains :  | ||||
|   | ||||
| - Protagonist, Creature and Vehicle sheet | ||||
| - Arcane, Archetype, Armor, Bond, Gear, Injury, Mental Disorder, Motivation, Ritual, Skill, Tome, Weapon items | ||||
| - Support for all available eras | ||||
| - Pre-filled compendium for each era | ||||
| - Specific look&fell for each era | ||||
| - And much more ! | ||||
|  | ||||
| Discord Contact : LeRatierBretonnien (at Official Foundry Discord of French Foundry Discord) | ||||
|   | ||||
							
								
								
									
										8
									
								
								changelog.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								changelog.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| # 12.0.12 | ||||
|  | ||||
| - Add missing skills for WW1, WW2, future and post-apocalyptic | ||||
| - Fix packaging  | ||||
|    | ||||
| # 12.0.11 | ||||
|  | ||||
| - Initial release | ||||
| @@ -2680,6 +2680,14 @@ i.fvtt-cthulhu-eternal { | ||||
|   margin-top: 8px; | ||||
|   background-color: var(--color-light-1); | ||||
| } | ||||
| .fvtt-cthulhu-eternal .ritual-content fieldset .editor-content { | ||||
|   max-height: 400px; | ||||
|   overflow-y: auto; | ||||
| } | ||||
| .fvtt-cthulhu-eternal .ritual-content fieldset .editor-container { | ||||
|   max-height: 400px; | ||||
|   overflow-y: auto; | ||||
| } | ||||
| .fvtt-cthulhu-eternal .ritual-content .header { | ||||
|   background-color: var(--color-light-1); | ||||
|   display: flex; | ||||
|   | ||||
| @@ -14,7 +14,7 @@ import * as applications from "./module/applications/_module.mjs" | ||||
| import { handleSocketEvent } from "./module/socket.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)}}} | ||||
| 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) } } } | ||||
|  | ||||
| Hooks.once("init", function () { | ||||
|   console.info("Cthulhu Eternal RPG | Initializing System") | ||||
| @@ -97,6 +97,7 @@ Hooks.once("init", function () { | ||||
|   console.info("CTHULHU ETERNAL | System Initialized") | ||||
| }) | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Perform one-time configuration of system configuration objects. | ||||
|  */ | ||||
| @@ -126,14 +127,14 @@ Hooks.on("renderChatMessage", (message, html, data) => { | ||||
|       btn.style.display = "inline" | ||||
|     }) | ||||
|     html.find(".nudge-roll").click((event) => { | ||||
|       CthulhuEternalUtils.nudgeRoll(message)   | ||||
|       CthulhuEternalUtils.nudgeRoll(message) | ||||
|     }) | ||||
|   } | ||||
| }) | ||||
|  | ||||
| // Dice-so-nice Ready | ||||
| Hooks.once("diceSoNiceReady", (dice3d) => { | ||||
|   configureDiceSoNice(dice3d) | ||||
|   //configureDiceSoNice(dice3d) | ||||
| }) | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -212,7 +212,7 @@ | ||||
|         }, | ||||
|         "settings": { | ||||
|           "label": "Settings era" | ||||
|         },   | ||||
|         }, | ||||
|         "diceEvolved": { | ||||
|           "label": "Can increase on failure" | ||||
|         }, | ||||
| @@ -395,7 +395,7 @@ | ||||
|       "FIELDS": { | ||||
|         "settings": { | ||||
|           "label": "Settings era" | ||||
|         },   | ||||
|         }, | ||||
|         "value": { | ||||
|           "label": "Value" | ||||
|         }, | ||||
| @@ -438,7 +438,7 @@ | ||||
|         }, | ||||
|         "otherBenefits": { | ||||
|           "label": "Other Benefits" | ||||
|         },   | ||||
|         }, | ||||
|         "creationDate": { | ||||
|           "label": "Creation Date" | ||||
|         }, | ||||
| @@ -457,6 +457,7 @@ | ||||
|       "Simple": "Simple", | ||||
|       "Complex": "Complex", | ||||
|       "Elaborate": "Elaborate", | ||||
|       "Difficult": "Difficult", | ||||
|       "FIELDS": { | ||||
|         "ritualType": { | ||||
|           "label": "Type" | ||||
| @@ -529,7 +530,7 @@ | ||||
|       "intShort": "INT", | ||||
|       "powShort": "POW", | ||||
|       "conShort": "CON", | ||||
|       "chaShort": "CHA",       | ||||
|       "chaShort": "CHA", | ||||
|       "strLong": "Strength", | ||||
|       "dexLong": "Dexterity", | ||||
|       "intLong": "Intelligence", | ||||
|   | ||||
							
								
								
									
										294
									
								
								module/applications/hud/action-handler.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										294
									
								
								module/applications/hud/action-handler.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,294 @@ | ||||
| // System Module Imports | ||||
| import { Utils } from './utils.js' | ||||
| import { SYSTEM } from "../../config/system.mjs" | ||||
| export let ActionHandler = null | ||||
|  | ||||
| Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { | ||||
|   /** | ||||
|    * Extends Token Action HUD Core's ActionHandler class and builds system-defined actions for the HUD | ||||
|    */ | ||||
|   ActionHandler = class ActionHandler extends coreModule.api.ActionHandler { | ||||
|     /** | ||||
|      * Build system actions | ||||
|      * Called by Token Action HUD Core | ||||
|      * @override | ||||
|      * @param {array} groupIds | ||||
|      */ | ||||
|     async buildSystemActions(groupIds) { | ||||
|       // Set actor and token variables | ||||
|       this.actors = (!this.actor) ? this._getActors() : [this.actor] | ||||
|       this.actorType = this.actor?.type | ||||
|  | ||||
|       // Set items variable | ||||
|       if (this.actor) { | ||||
|         let items = this.actor.items | ||||
|         items = coreModule.api.Utils.sortItemsByName(items) | ||||
|         this.items = items | ||||
|       } | ||||
|  | ||||
|       if (this.actorType !== 'vehicle') { | ||||
|         this.#buildCharacterActions() | ||||
|       } else if (!this.actor) { | ||||
|         this.#buildMultipleTokenActions() | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Build character actions | ||||
|      * @private | ||||
|      */ | ||||
|     #buildCharacterActions() { | ||||
|       this.buildAttributes() | ||||
|       this.buildOther() | ||||
|       this.buildLuck() | ||||
|       this.buildSkills() | ||||
|       this.buildEquipment() | ||||
|     } | ||||
|  | ||||
|     #showValue() { | ||||
|       return game.settings.get('token-action-hud-core', 'tooltips') === 'none' | ||||
|     } | ||||
|  | ||||
|     async buildAttributes() { | ||||
|       const actions = [] | ||||
|       for (const key in this.actor.system.characteristics) { | ||||
|         const encodedValue = [coreModule.api.Utils.i18n('attributes'), key].join(this.delimiter) | ||||
|         const tooltip = { | ||||
|           content: String(this.actor.system.characteristics[key].value * 5), | ||||
|           class: 'tah-system-tooltip', | ||||
|           direction: 'LEFT' | ||||
|         } | ||||
|         actions.push({ | ||||
|           name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.' + key), | ||||
|           id: key, | ||||
|           info1: this.#showValue() ? { text: tooltip.content } : null, | ||||
|           tooltip, | ||||
|           encodedValue | ||||
|         }) | ||||
|       } | ||||
|       await this.addActions(actions, { | ||||
|         id: 'attributes', | ||||
|         type: 'system' | ||||
|       }) | ||||
|     } | ||||
|  | ||||
|     async buildLuck() { | ||||
|       const actions = [] | ||||
|       const tooltip = { | ||||
|         content: '50', | ||||
|         class: 'tah-system-tooltip', | ||||
|         direction: 'LEFT' | ||||
|       } | ||||
|       actions.push({ | ||||
|         name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.Luck'), | ||||
|         id: 'luck', | ||||
|         info1: this.#showValue() ? { text: '50' } : null, | ||||
|         tooltip, | ||||
|         encodedValue: ['attributes', 'luck'].join(this.delimiter) | ||||
|       }) | ||||
|       await this.addActions(actions, { id: 'luck', type: 'system' }) | ||||
|     } | ||||
|  | ||||
|     async buildOther() { | ||||
|       if (typeof this.actor.system.sanity.value !== 'undefined') { | ||||
|         const actions = [] | ||||
|         const groupData = { | ||||
|           id: 'other_sanity', | ||||
|           name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.SAN'), | ||||
|           type: 'system' | ||||
|         } | ||||
|         this.addGroup(groupData, { id: 'other', type: 'system' }, true) | ||||
|         const tooltip = { | ||||
|           content: String(this.actor.system.san.value + '/' + this.actor.system.san.max), | ||||
|           class: 'tah-system-tooltip', | ||||
|           direction: 'LEFT' | ||||
|         } | ||||
|         actions.push({ | ||||
|           name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.SAN'), | ||||
|           id: 'sanity', | ||||
|           info1: this.#showValue() ? { text: tooltip.content } : null, | ||||
|           tooltip, | ||||
|           encodedValue: ['attributes', 'sanity'].join(this.delimiter) | ||||
|         }, | ||||
|           { | ||||
|             name: '+', | ||||
|             id: 'sanity_add', | ||||
|             encodedValue: ['attributes', 'sanity_add'].join(this.delimiter) | ||||
|           }, | ||||
|           { | ||||
|             name: '-', | ||||
|             id: 'sanity_subtract', | ||||
|             encodedValue: ['attributes', 'sanity_subtract'].join(this.delimiter) | ||||
|           }) | ||||
|         await this.addActions(actions, { id: 'other_sanity', type: 'system' }) | ||||
|       } | ||||
|       if (typeof this.actor.system.hp.value !== 'undefined') { | ||||
|         const actions = [] | ||||
|         const groupData = { | ||||
|           id: 'other_health', | ||||
|           name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.HP'), | ||||
|           type: 'system' | ||||
|         } | ||||
|         this.addGroup(groupData, { id: 'other', type: 'system' }, true) | ||||
|         const tooltip = { | ||||
|           content: String(this.actor.system.hp.value + '/' + this.actor.system.hp.max), | ||||
|           class: 'tah-system-tooltip', | ||||
|           direction: 'LEFT' | ||||
|         } | ||||
|         actions.push({ | ||||
|           name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.HP'), | ||||
|           id: 'health', | ||||
|           info1: this.#showValue() ? { text: tooltip.content } : null, | ||||
|           tooltip, | ||||
|           encodedValue: ['attributes', 'health'].join(this.delimiter) | ||||
|         }, | ||||
|           { | ||||
|             name: '+', | ||||
|             id: 'health_add', | ||||
|             encodedValue: ['attributes', 'health_add'].join(this.delimiter) | ||||
|           }, | ||||
|           { | ||||
|             name: '-', | ||||
|             id: 'health_subtract', | ||||
|             encodedValue: ['attributes', 'health_subtract'].join(this.delimiter) | ||||
|           }) | ||||
|         await this.addActions(actions, { id: 'other_health', type: 'system' }) | ||||
|       } | ||||
|       if (typeof this.actor.system.wp.value !== 'undefined') { | ||||
|         const actions = [] | ||||
|         const groupData = { | ||||
|           id: 'other_wp', | ||||
|           name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.WP'), | ||||
|           type: 'system' | ||||
|         } | ||||
|         this.addGroup(groupData, { id: 'other', type: 'system' }, true) | ||||
|         const tooltip = { | ||||
|           content: String(this.actor.system.wp.value + '/' + this.actor.system.wp.max), | ||||
|           class: 'tah-system-tooltip', | ||||
|           direction: 'LEFT' | ||||
|         } | ||||
|         actions.push({ | ||||
|           name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.WP'), | ||||
|           id: 'wp', | ||||
|           info1: this.#showValue() ? { text: tooltip.content } : null, | ||||
|           tooltip, | ||||
|           encodedValue: ['attributes', 'wp'].join(this.delimiter) | ||||
|         }, | ||||
|           { | ||||
|             name: '+', | ||||
|             id: 'wp_add', | ||||
|             encodedValue: ['attributes', 'wp_add'].join(this.delimiter) | ||||
|           }, | ||||
|           { | ||||
|             name: '-', | ||||
|             id: 'wp_subtract', | ||||
|             encodedValue: ['attributes', 'wp_subtract'].join(this.delimiter) | ||||
|           }) | ||||
|         await this.addActions(actions, { id: 'other_wp', type: 'system' }) | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     async buildSkills() { | ||||
|       const actions = [] | ||||
|       let actorSkills = this.actor.items.filter(item => item.type === 'skill') | ||||
|       for (const skill in actorSkills) { | ||||
|         if (skill.system.computeScore() > 0) { | ||||
|           const tooltip = { | ||||
|             content: String(skill.skill.system.computeScore()), | ||||
|             direction: 'LEFT' | ||||
|           } | ||||
|           actions.push({ | ||||
|             name: skill.name, | ||||
|             id: skill.id, | ||||
|             info1: this.#showValue() ? { text: tooltip.content } : null, | ||||
|             tooltip, | ||||
|             encodedValue: ['skills', s].join(this.delimiter) | ||||
|           }) | ||||
|         } | ||||
|       } | ||||
|       await this.addActions(actions, { id: 'skills', type: 'system' }) | ||||
|     } | ||||
|  | ||||
|     async buildEquipment() { | ||||
|       let weapons = this.actor.items.filter(item => item.type === 'weapon') | ||||
|       let skills = this.actor.items.filter(item => item.type === 'skill') | ||||
|       for (const item of weapons) { | ||||
|         // Push the weapon name as a new group | ||||
|         const groupData = { | ||||
|           id: 'weapons_' + item._id, | ||||
|           name: item.name, | ||||
|           type: 'system' | ||||
|         } | ||||
|         if (!SYSTEM.WEAPON_SKILL_MAPPING[era] || !SYSTEM.WEAPON_SKILL_MAPPING[era][options.rollItem.system.weaponType]) { | ||||
|           continue | ||||
|         } | ||||
|         let skillName = game.i18n.localize(SYSTEM.WEAPON_SKILL_MAPPING[era][options.rollItem.system.weaponType]) | ||||
|         let skill = skills.find(skill => skill.name.toLowerCase() === skillName.toLowerCase()) | ||||
|         this.addGroup(groupData, { id: 'weapons', type: 'system' }, true) | ||||
|         if (item.type === 'weapon') { | ||||
|           const weapons = [] | ||||
|           const tooltip = { | ||||
|             content: String(skill.system.computeScore()), | ||||
|             direction: 'LEFT' | ||||
|           } | ||||
|           weapons.push({ | ||||
|             name: skill.name, | ||||
|             id: skill._id, | ||||
|             info1: this.#showValue() ? { text: tooltip.content } : null, | ||||
|             encodedValue: ['weapons', item._id].join(this.delimiter), | ||||
|             tooltip | ||||
|           }) | ||||
|           const damageTooltip = { | ||||
|             content: String(item.system.damage), | ||||
|             direction: 'LEFT' | ||||
|           } | ||||
|           if (item.system.damage !== '') { | ||||
|             weapons.push({ | ||||
|               name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.Damage'), | ||||
|               id: item._id, | ||||
|               info1: this.#showValue() ? { text: damageTooltip.content } : null, | ||||
|               encodedValue: ['damage', item._id].join(this.delimiter), | ||||
|               tooltip: damageTooltip | ||||
|             }) | ||||
|           } | ||||
|           if (item.system.isLethal) { | ||||
|             const lethalityTooltip = { | ||||
|               content: String(item.system.lethality), | ||||
|               direction: 'LEFT' | ||||
|             } | ||||
|             weapons.push({ | ||||
|               name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.Lethality'), | ||||
|               id: item._id, | ||||
|               info1: this.#showValue() ? { text: lethalityTooltip.content } : null, | ||||
|               encodedValue: ['lethality', item._id].join(this.delimiter), | ||||
|               tooltip: lethalityTooltip | ||||
|             }) | ||||
|           } | ||||
|           await this.addActions(weapons, { | ||||
|             id: 'weapons_' + item._id, | ||||
|             type: 'system' | ||||
|           }) | ||||
|         }/* else if (item.type === 'ritual') { | ||||
|                     rituals.push({ | ||||
|                         name: item.name, | ||||
|                         id: item._id, | ||||
|                         encodedValue: ['rituals', item.name].join(this.delimiter) | ||||
|                     }) | ||||
|                 } */ | ||||
|  | ||||
|         /* await this.addActions(rituals, { | ||||
|             id: 'rituals', | ||||
|             type: 'system' | ||||
|         }) */ | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Build multiple token actions | ||||
|      * @private | ||||
|      * @returns {object} | ||||
|      */ | ||||
|     #buildMultipleTokenActions() { | ||||
|     } | ||||
|   } | ||||
| }) | ||||
							
								
								
									
										38
									
								
								module/applications/hud/constants.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								module/applications/hud/constants.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| /** | ||||
|  * Module-based constants | ||||
|  */ | ||||
| export const SYSTEM = { | ||||
|     ID: 'fvtt-cthulhu-eternal' | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Core module | ||||
|  */ | ||||
| export const CORE_MODULE = { | ||||
|     ID: 'token-action-hud-core' | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Core module version required by the system module | ||||
|  */ | ||||
| export const REQUIRED_CORE_MODULE_VERSION = '2.0' | ||||
|  | ||||
| /** | ||||
|  * Action types | ||||
|  */ | ||||
| export const ACTION_TYPE = { | ||||
|     attributes: 'CTHULHUETERNAL.Label.Characteristics', | ||||
|     skills: 'CTHULHUETERNAL.Label.Skill', | ||||
|     equipment: 'CTHULHUETERNAL.Label.Gear' | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Groups | ||||
|  */ | ||||
| export const GROUP = { | ||||
|     attributes: { id: 'attributes', name: 'CTHULHUETERNAL.Label.Characteristics', type: 'system' }, | ||||
|     luck: { id: 'luck', name: 'CTHULHUETERNAL.Label.Luck', type: 'system'}, | ||||
|     skills: { id: 'skills', name: 'CTHULHUETERNAL.Label.Skills', type: 'system' }, | ||||
|     weapons: { id: 'weapons', name: 'CTHULHUETERNAL.Label.Weapons', type: 'system' }, | ||||
|     rituals: { id: 'rituals', name: 'CTHULHUETERNAL.Label.Rituals', type: 'system' } | ||||
| } | ||||
							
								
								
									
										49
									
								
								module/applications/hud/defaults.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								module/applications/hud/defaults.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| import { GROUP } from './constants.js' | ||||
|  | ||||
| /** | ||||
|  * Default layout and groups | ||||
|  */ | ||||
| export let DEFAULTS = null | ||||
|  | ||||
| Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { | ||||
|     const groups = GROUP | ||||
|     Object.values(groups).forEach(group => { | ||||
|         group.name = coreModule.api.Utils.i18n(group.name) | ||||
|         group.listName = `Group: ${coreModule.api.Utils.i18n(group.listName ?? group.name)}` | ||||
|     }) | ||||
|     const groupsArray = Object.values(groups) | ||||
|     DEFAULTS = { | ||||
|         layout: [ | ||||
|             { | ||||
|                 nestId: 'statistics', | ||||
|                 id: 'statistics', | ||||
|                 name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.Characteristics'), | ||||
|                 groups: [ | ||||
|                     { ...groups.attributes, nestId: 'statistics_attributes' }, | ||||
|                     { ...groups.other, nestId: 'statistics_other' }, | ||||
|                     { ...groups.luck, nestId: 'statistics_luck' } | ||||
|                 ] | ||||
|             }, | ||||
|             { | ||||
|                 nestId: 'skills', | ||||
|                 id: 'skills', | ||||
|                 name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.Skills'), | ||||
|                 groups: [ | ||||
|                     { ...groups.skills, nestId: 'skills_skills' }, | ||||
|                     { ...groups.typedSkills, nestId: 'skills_typed' }, | ||||
|                     { ...groups.specialTraining, nestId: 'skills_special' } | ||||
|                 ] | ||||
|             }, | ||||
|             { | ||||
|                 nestId: 'equipment', | ||||
|                 id: 'equipment', | ||||
|                 name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.Gear'), | ||||
|                 groups: [ | ||||
|                     { ...groups.weapons, nestId: 'equipment_weapons' }, | ||||
|                     { ...groups.rituals, nestId: 'equipment_rituals' } | ||||
|                 ] | ||||
|             } | ||||
|         ], | ||||
|         groups: groupsArray | ||||
|     } | ||||
| }) | ||||
							
								
								
									
										304
									
								
								module/applications/hud/roll-handler.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										304
									
								
								module/applications/hud/roll-handler.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,304 @@ | ||||
| import { SYSTEM } from "../../config/system.mjs" | ||||
| import CthulhuEternalRoll  from '../../documents/roll.mjs' | ||||
|  | ||||
| export let RollHandler = null | ||||
|  | ||||
| Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { | ||||
|     /** | ||||
|      * Extends Token Action HUD Core's RollHandler class and handles action events triggered when an action is clicked | ||||
|      */ | ||||
|     RollHandler = class RollHandler extends coreModule.api.RollHandler { | ||||
|         /** | ||||
|          * Handle action click | ||||
|          * Called by Token Action HUD Core when an action is left or right-clicked | ||||
|          * @override | ||||
|          * @param {object} event        The event | ||||
|          * @param {string} encodedValue The encoded value | ||||
|          */ | ||||
|         async handleActionClick (event, encodedValue) { | ||||
|             const [actionTypeId, actionId] = encodedValue.split('|') | ||||
|  | ||||
|             const knownCharacters = ['character'] | ||||
|  | ||||
|             // If single actor is selected | ||||
|             if (this.actor) { | ||||
|                 await this.#handleAction(event, this.actor, this.token, actionTypeId, actionId) | ||||
|                 return | ||||
|             } | ||||
|  | ||||
|             const controlledTokens = canvas.tokens.controlled | ||||
|                 .filter((token) => knownCharacters.includes(token.actor?.type)) | ||||
|  | ||||
|             // If multiple actors are selected | ||||
|             for (const token of controlledTokens) { | ||||
|                 const actor = token.actor | ||||
|                 await this.#handleAction(event, actor, token, actionTypeId, actionId) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Handle action hover | ||||
|          * Called by Token Action HUD Core when an action is hovered on or off | ||||
|          * @override | ||||
|          * @param {object} event        The event | ||||
|          * @param {string} encodedValue The encoded value | ||||
|          */ | ||||
|         async handleActionHover (event, encodedValue) { | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Handle group click | ||||
|          * Called by Token Action HUD Core when a group is right-clicked while the HUD is locked | ||||
|          * @override | ||||
|          * @param {object} event The event | ||||
|          * @param {object} group The group | ||||
|          */ | ||||
|         async handleGroupClick (event, group) { | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Handle action | ||||
|          * @private | ||||
|          * @param {object} event        The event | ||||
|          * @param {object} actor        The actor | ||||
|          * @param {object} token        The token | ||||
|          * @param {string} actionTypeId The action type id | ||||
|          * @param {string} actionId     The actionId | ||||
|          */ | ||||
|         async #handleAction (event, actor, token, actionTypeId, actionId) { | ||||
|             switch (actionTypeId) { | ||||
|             case 'attributes': | ||||
|                 await this.#handleAttributesAction(event, actor, actionId) | ||||
|                 break | ||||
|             case 'skills': | ||||
|                 await this.#handleSkillsAction(event, actor, actionId) | ||||
|                 break | ||||
|             case 'weapons': | ||||
|                 await this.#handleWeaponsAction(event, actor, actionId) | ||||
|                 break | ||||
|             case 'damage': | ||||
|                 await this.#handleDamageAction(event, actor, actionId) | ||||
|                 break | ||||
|             case 'lethality': | ||||
|                 await this.#handleLethalityAction(event, actor, actionId) | ||||
|                 break | ||||
|             case 'specialTraining': | ||||
|                 await this.#handleSpecialTrainingAction(event, actor, actionId) | ||||
|                 break | ||||
|             case 'typedSkills': | ||||
|                 await this.#handleCustomTypedAction(event, actor, actionId) | ||||
|                 break | ||||
|                 /* case 'rituals': | ||||
|                 await this.#handleRitualsAction(event, actor, actionId) | ||||
|                 break */ | ||||
|             case 'utility': | ||||
|                 await this.#handleUtilityAction(token, actionId) | ||||
|                 break | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Handle Attribute action | ||||
|          * @private | ||||
|          * @param {object} event    The event | ||||
|          * @param {object} actor    The actor | ||||
|          * @param {string} actionId The action id | ||||
|          */ | ||||
|         async #handleAttributesAction (event, actor, actionId) { | ||||
|             let rollType | ||||
|             if (actionId === 'wp' || actionId === 'health') return | ||||
|             if (actionId.includes('_add') || actionId.includes('_subtract')) { | ||||
|                 const attr = actionId.split('_')[0] | ||||
|                 const action = actionId.split('_')[1] | ||||
|                 const update = {} | ||||
|                 update.system = {} | ||||
|                 update.system[attr] = {} | ||||
|                 update.system[attr].value = action === 'add' ? this.actor.system[attr].value + 1 : this.actor.system[attr].value - 1 | ||||
|                 if (update.system[attr].value > this.actor.system[attr].max || update.system[attr].value < this.actor.system[attr].min) return | ||||
|                 return await this.actor.update(update) | ||||
|             } | ||||
|             if (actionId === 'sanity') { | ||||
|                 rollType = actionId | ||||
|             } else if (actionId === 'luck') { | ||||
|                 rollType = actionId | ||||
|             } else { | ||||
|                 rollType = 'stat' | ||||
|             } | ||||
|             const options = { | ||||
|                 actor: this.actor, | ||||
|                 rollType, | ||||
|                 key: actionId | ||||
|             } | ||||
|  | ||||
|             const roll = new DGPercentileRoll('1D100', {}, options) | ||||
|             return await this.actor.sheet.processRoll(event, roll) | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Handle Skill action | ||||
|          * @private | ||||
|          * @param {object} event    The event | ||||
|          * @param {object} actor    The actor | ||||
|          * @param {string} actionId The action id | ||||
|          */ | ||||
|         async #handleSkillsAction (event, actor, actionId) { | ||||
|             const options = { | ||||
|                 actor: this.actor, | ||||
|                 rollType: 'skill', | ||||
|                 key: actionId | ||||
|             } | ||||
|  | ||||
|             const skill = this.actor.system.skills[actionId] | ||||
|             if (!skill) return ui.notifications.warn('Bad skill name in HUD.') | ||||
|  | ||||
|             const roll = new DGPercentileRoll('1D100', {}, options) | ||||
|             await this.actor.sheet.processRoll(event, roll) | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Handle Typed/Custom skills action | ||||
|          * @private | ||||
|          * @param {object} event    The event | ||||
|          * @param {object} actor    The actor | ||||
|          * @param {string} actionId The action id | ||||
|          */ | ||||
|         async #handleCustomTypedAction (event, actor, actionId) { | ||||
|             const options = { | ||||
|                 actor: this.actor, | ||||
|                 rollType: 'skill', | ||||
|                 key: actionId | ||||
|             } | ||||
|             const roll = new DGPercentileRoll('1D100', {}, options) | ||||
|             await this.actor.sheet.processRoll(event, roll) | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Handle SoecialTraining action | ||||
|          * @private | ||||
|          * @param {object} event    The event | ||||
|          * @param {object} actor    The actor | ||||
|          * @param {string} actionId The action id | ||||
|          */ | ||||
|         async #handleSpecialTrainingAction (event, actor, actionId) { | ||||
|             const attr = this.actor.system.specialTraining.find(a => a.name === actionId).attribute | ||||
|             let target = 0 | ||||
|             if (DG.statistics.includes(attr)) { | ||||
|                 target = this.actor.system.statistics[attr].x5 | ||||
|             } else if (DG.skills.includes(attr)) { | ||||
|                 target = this.actor.system.skills[attr].proficiency | ||||
|             } else { | ||||
|                 target = this.actor.system.typedSkills[attr].proficiency | ||||
|             } | ||||
|             const options = { | ||||
|                 actor: this.actor, | ||||
|                 rollType: 'special-training', | ||||
|                 key: attr, | ||||
|                 specialTrainingName: actionId, | ||||
|                 target | ||||
|             } | ||||
|             const roll = new DGPercentileRoll('1D100', {}, options) | ||||
|             await this.actor.sheet.processRoll(event, roll) | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Handle Weapon action | ||||
|          * @private | ||||
|          * @param {object} event    The event | ||||
|          * @param {object} actor    The actor | ||||
|          * @param {string} actionId The action id | ||||
|          */ | ||||
|         async #handleWeaponsAction (event, actor, actionId) { | ||||
|             const item = this.actor.items.get(actionId) | ||||
|             const options = { | ||||
|                 actor: this.actor, | ||||
|                 rollType: 'weapon', | ||||
|                 key: item.system.skill, | ||||
|                 item | ||||
|             } | ||||
|             const roll = new DGPercentileRoll('1D100', {}, options) | ||||
|             await this.actor.sheet.processRoll(event, roll) | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Handle Damage action | ||||
|          * @private | ||||
|          * @param {object} event    The event | ||||
|          * @param {object} actor    The actor | ||||
|          * @param {string} actionId The action id | ||||
|          */ | ||||
|         async #handleDamageAction (event, actor, actionId) { | ||||
|             const item = this.actor.items.get(actionId) | ||||
|             if (item.system.lethality > 0 && event.ctrlKey) { | ||||
|                 // Toggle on/off lethality | ||||
|                 const isLethal = !item.system.isLethal | ||||
|                 await item.update({ 'system.isLethal': isLethal }) | ||||
|             } else { | ||||
|                 const options = { | ||||
|                     actor: this.actor, | ||||
|                     rollType: 'damage', | ||||
|                     key: item.system.damage, | ||||
|                     item | ||||
|                 } | ||||
|                 const roll = new DGDamageRoll(item.system.damage, {}, options) | ||||
|                 await this.actor.sheet.processRoll(event, roll) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Handle Lethality action | ||||
|          * @private | ||||
|          * @param {object} event    The event | ||||
|          * @param {object} actor    The actor | ||||
|          * @param {string} actionId The action id | ||||
|          */ | ||||
|         async #handleLethalityAction (event, actor, actionId) { | ||||
|             const item = await this.actor.items.get(actionId) | ||||
|             if (item.system.damage !== '' && event.ctrlKey) { | ||||
|                 const isLethal = !item.system.isLethal | ||||
|                 await item.update({ 'system.isLethal': isLethal }) | ||||
|             } else { | ||||
|                 const options = { | ||||
|                     actor: this.actor, | ||||
|                     rollType: 'lethality', | ||||
|                     key: item.system.lethality, | ||||
|                     item | ||||
|                 } | ||||
|                 const roll = new DGLethalityRoll(item.system.damage, {}, options) | ||||
|                 await this.actor.sheet.processRoll(event, roll) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Handle Ritual action | ||||
|          * @private | ||||
|          * @param {object} event    The event | ||||
|          * @param {object} actor    The actor | ||||
|          * @param {string} actionId The action id | ||||
|          */ | ||||
|         async #handleRitualsAction (event, actor, actionId) { | ||||
|             const options = { | ||||
|                 actor: this.actor, | ||||
|                 rollType: 'ritual', | ||||
|                 key: actionId | ||||
|             } | ||||
|             const roll = new DGPercentileRoll('1D100', {}, options) | ||||
|             await this.actor.sheet.processRoll(event, roll) | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Handle utility action | ||||
|          * @private | ||||
|          * @param {object} token    The token | ||||
|          * @param {string} actionId The action id | ||||
|          */ | ||||
|         async #handleUtilityAction (token, actionId) { | ||||
|             switch (actionId) { | ||||
|             case 'endTurn': | ||||
|                 if (game.combat?.current?.tokenId === token.id) { | ||||
|                     await game.combat?.nextTurn() | ||||
|                 } | ||||
|                 break | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| }) | ||||
							
								
								
									
										91
									
								
								module/applications/hud/system-manager.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								module/applications/hud/system-manager.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | ||||
| // System Module Imports | ||||
| import { ActionHandler } from './action-handler.js' | ||||
| import { RollHandler as Core } from './roll-handler.js' | ||||
| import { SYSTEM } from './constants.js' | ||||
| import { DEFAULTS } from './defaults.js' | ||||
|  | ||||
| export let SystemManager = null | ||||
|  | ||||
| Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { | ||||
|     /** | ||||
|      * Extends Token Action HUD Core's SystemManager class | ||||
|      */ | ||||
|     SystemManager = class SystemManager extends coreModule.api.SystemManager { | ||||
|         /** | ||||
|          * Returns an instance of the ActionHandler to Token Action HUD Core | ||||
|          * Called by Token Action HUD Core | ||||
|          * @override | ||||
|          * @returns {class} The ActionHandler instance | ||||
|          */ | ||||
|         getActionHandler () { | ||||
|             return new ActionHandler() | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns a list of roll handlers to Token Action HUD Core | ||||
|          * Used to populate the Roll Handler module setting choices | ||||
|          * Called by Token Action HUD Core | ||||
|          * @override | ||||
|          * @returns {object} The available roll handlers | ||||
|          */ | ||||
|         getAvailableRollHandlers () { | ||||
|             const coreTitle = 'Core Template' | ||||
|             const choices = { core: coreTitle } | ||||
|             return choices | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns an instance of the RollHandler to Token Action HUD Core | ||||
|          * Called by Token Action HUD Core | ||||
|          * @override | ||||
|          * @param {string} rollHandlerId The roll handler ID | ||||
|          * @returns {class}              The RollHandler instance | ||||
|          */ | ||||
|         getRollHandler (rollHandlerId) { | ||||
|             let rollHandler | ||||
|             switch (rollHandlerId) { | ||||
|             case 'core': | ||||
|             default: | ||||
|                 rollHandler = new Core() | ||||
|                 break | ||||
|             } | ||||
|             return rollHandler | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the default layout and groups to Token Action HUD Core | ||||
|          * Called by Token Action HUD Core | ||||
|          * @returns {object} The default layout and groups | ||||
|          */ | ||||
|         async registerDefaults () { | ||||
|             return DEFAULTS | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Register Token Action HUD system module settings | ||||
|          * Called by Token Action HUD Core | ||||
|          * @override | ||||
|          * @param {function} coreUpdate The Token Action HUD Core update function | ||||
|          */ | ||||
|         registerSettings (coreUpdate) { | ||||
|             /*systemSettings.register(coreUpdate)*/ | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns styles to Token Action HUD Core | ||||
|          * Called by Token Action HUD Core | ||||
|          * @override | ||||
|          * @returns {object} The TAH system styles | ||||
|          */ | ||||
|         registerStyles () { | ||||
|             return { | ||||
|                 template: { | ||||
|                     class: 'tah-style-template-style', // The class to add to first DIV element | ||||
|                     file: 'tah-template-style', // The file without the css extension | ||||
|                     moduleId: SYSTEM.ID, // The module ID | ||||
|                     name: 'Template Style' // The name to display in the Token Action HUD Core 'Style' module setting | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| }) | ||||
							
								
								
									
										55
									
								
								module/applications/hud/utils.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								module/applications/hud/utils.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| import { SYSTEM } from './constants.js' | ||||
|  | ||||
| export let Utils = null | ||||
|  | ||||
| function registerHUD() { | ||||
|   Hooks.on('tokenActionHudCoreApiReady', async () => { | ||||
|     /** | ||||
|      * Return the SystemManager and requiredCoreModuleVersion to Token Action HUD Core | ||||
|      */ | ||||
|     const module = game.system | ||||
|     module.api = { | ||||
|       requiredCoreModuleVersion: "2.0", | ||||
|       SystemManager | ||||
|     } | ||||
|     Hooks.call('tokenActionHudSystemReady', module) | ||||
|   }) | ||||
|  | ||||
| } | ||||
|  | ||||
| Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { | ||||
|   /** | ||||
|    * Utility functions | ||||
|    */ | ||||
|   Utils = class Utils { | ||||
|     /** | ||||
|      * Get setting | ||||
|      * @param {string} key               The key | ||||
|      * @param {string=null} defaultValue The default value | ||||
|      * @returns {string}                 The setting value | ||||
|      */ | ||||
|     static getSetting(key, defaultValue = null) { | ||||
|       let value = defaultValue ?? null | ||||
|       try { | ||||
|         value = game.settings.get(SYSTEM.ID, key) | ||||
|       } catch { | ||||
|         coreModule.api.Logger.debug(`Setting '${key}' not found`) | ||||
|       } | ||||
|       return value | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set setting | ||||
|      * @param {string} key   The key | ||||
|      * @param {string} value The value | ||||
|      */ | ||||
|     static async setSetting(key, value) { | ||||
|       try { | ||||
|         value = await game.settings.set(MODULE.ID, key, value) | ||||
|         coreModule.api.Logger.debug(`Setting '${key}' set to '${value}'`) | ||||
|       } catch { | ||||
|         coreModule.api.Logger.debug(`Setting '${key}' not found`) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| }) | ||||
| @@ -1,6 +1,6 @@ | ||||
| import LethalFantasyItemSheet from "./base-item-sheet.mjs" | ||||
| import CthulhuEternalItemSheet from "./base-item-sheet.mjs" | ||||
|  | ||||
| export default class LethalFantasyWeaponSheet extends LethalFantasyItemSheet { | ||||
| export default class CthulhuEternalWeaponSheet extends CthulhuEternalItemSheet { | ||||
|   /** @override */ | ||||
|   static DEFAULT_OPTIONS = { | ||||
|     classes: ["weapon"], | ||||
|   | ||||
| @@ -6,16 +6,16 @@ import * as BOND from "./bond.mjs" | ||||
| export const SYSTEM_ID = "fvtt-cthulhu-eternal" | ||||
|  | ||||
| export const ASCII = ` | ||||
| ▄████▄  ▄▄▄█████▓ ██░ ██  █    ██  ██▓     ██░ ██  █    ██    ▓█████▄▄▄█████▓▓█████  ██▀███   ███▄    █  ▄▄▄       ██▓     | ||||
| ▒██▀ ▀█  ▓  ██▒ ▓▒▓██░ ██▒ ██  ▓██▒▓██▒    ▓██░ ██▒ ██  ▓██▒   ▓█   ▀▓  ██▒ ▓▒▓█   ▀ ▓██ ▒ ██▒ ██ ▀█   █ ▒████▄    ▓██▒     | ||||
| ▒▓█    ▄ ▒ ▓██░ ▒░▒██▀▀██░▓██  ▒██░▒██░    ▒██▀▀██░▓██  ▒██░   ▒███  ▒ ▓██░ ▒░▒███   ▓██ ░▄█ ▒▓██  ▀█ ██▒▒██  ▀█▄  ▒██░     | ||||
| ▒▓▓▄ ▄██▒░ ▓██▓ ░ ░▓█ ░██ ▓▓█  ░██░▒██░    ░▓█ ░██ ▓▓█  ░██░   ▒▓█  ▄░ ▓██▓ ░ ▒▓█  ▄ ▒██▀▀█▄  ▓██▒  ▐▌██▒░██▄▄▄▄██ ▒██░     | ||||
| ▄████▄  ▄▄▄█████▓ ██░ ██  █    ██  ██▓     ██░ ██  █    ██    ▓█████▄▄▄█████▓▓█████  ██▀███   ███▄    █  ▄▄▄       ██▓ | ||||
| ▒██▀ ▀█  ▓  ██▒ ▓▒▓██░ ██▒ ██  ▓██▒▓██▒    ▓██░ ██▒ ██  ▓██▒   ▓█   ▀▓  ██▒ ▓▒▓█   ▀ ▓██ ▒ ██▒ ██ ▀█   █ ▒████▄    ▓██▒ | ||||
| ▒▓█    ▄ ▒ ▓██░ ▒░▒██▀▀██░▓██  ▒██░▒██░    ▒██▀▀██░▓██  ▒██░   ▒███  ▒ ▓██░ ▒░▒███   ▓██ ░▄█ ▒▓██  ▀█ ██▒▒██  ▀█▄  ▒██░ | ||||
| ▒▓▓▄ ▄██▒░ ▓██▓ ░ ░▓█ ░██ ▓▓█  ░██░▒██░    ░▓█ ░██ ▓▓█  ░██░   ▒▓█  ▄░ ▓██▓ ░ ▒▓█  ▄ ▒██▀▀█▄  ▓██▒  ▐▌██▒░██▄▄▄▄██ ▒██░ | ||||
| ▒ ▓███▀ ░  ▒██▒ ░ ░▓█▒░██▓▒▒█████▓ ░██████▒░▓█▒░██▓▒▒█████▓    ░▒████▒ ▒██▒ ░ ░▒████▒░██▓ ▒██▒▒██░   ▓██░ ▓█   ▓██▒░██████▒ | ||||
| ░ ░▒ ▒  ░  ▒ ░░    ▒ ░░▒░▒░▒▓▒ ▒ ▒ ░ ▒░▓  ░ ▒ ░░▒░▒░▒▓▒ ▒ ▒    ░░ ▒░ ░ ▒ ░░   ░░ ▒░ ░░ ▒▓ ░▒▓░░ ▒░   ▒ ▒  ▒▒   ▓▒█░░ ▒░▓  ░ | ||||
|   ░  ▒       ░     ▒ ░▒░ ░░░▒░ ░ ░ ░ ░ ▒  ░ ▒ ░▒░ ░░░▒░ ░ ░     ░ ░  ░   ░     ░ ░  ░  ░▒ ░ ▒░░ ░░   ░ ▒░  ▒   ▒▒ ░░ ░ ▒  ░ | ||||
| ░          ░       ░  ░░ ░ ░░░ ░ ░   ░ ░    ░  ░░ ░ ░░░ ░ ░       ░    ░         ░     ░░   ░    ░   ░ ░   ░   ▒     ░ ░    | ||||
| ░          ░       ░  ░░ ░ ░░░ ░ ░   ░ ░    ░  ░░ ░ ░░░ ░ ░       ░    ░         ░     ░░   ░    ░   ░ ░   ░   ▒     ░ ░ | ||||
| ░ ░                ░  ░  ░   ░         ░  ░ ░  ░  ░   ░           ░  ░           ░  ░   ░              ░       ░  ░    ░  ░ | ||||
| ░                                                                                                                           | ||||
| ░ | ||||
| ` | ||||
|  | ||||
|  | ||||
| @@ -49,11 +49,11 @@ export const ERA_CSS = { | ||||
|   coldwar: { primaryFont: "Georama", secondaryFont: "Georama", titleFont: "TopSecret", baseFontSize: "1.0rem", titleFontSize: "1.2rem",imgFilter: "brightness(0) saturate(100%) invert(81%) sepia(14%) saturate(2508%) hue-rotate(202deg) brightness(99%) contrast(105%)"}, | ||||
|   revolution: { primaryFont: "IMFell", secondaryFont: "IMFell", titleFont: "Dominican", baseFontSize: "1.0rem",titleFontSize: "1.3rem",imgFilter: "brightness(0) saturate(100%) invert(81%) sepia(25%) saturate(386%) hue-rotate(7deg) brightness(101%) contrast(84%)" }, | ||||
|   medieval: { primaryFont: "UncialAntiqua", secondaryFont: "UncialAntiqua", titleFont: "Luminari", baseFontSize: "0.9rem",titleFontSize: "1.2rem",imgFilter: "brightness(0) saturate(100%) invert(93%) sepia(46%) saturate(354%) hue-rotate(321deg) brightness(93%) contrast(87%)"}, | ||||
|   ww2: { primaryFont: "SairaStencilOne", secondaryFont: "SairaStencilOne", titleFont: "Armalite", baseFontSize: "0.9rem",titleFontSize: "1.2rem",imgFilter: "filter: invert(44%) sepia(8%) saturate(2657%) hue-rotate(40deg) brightness(96%) contrast(75%)"},   | ||||
|   ww1: { primaryFont: "CarterOne", secondaryFont: "CarterOne", titleFont: "SigmarOne", baseFontSize: "0.9rem",titleFontSize: "1.1rem",imgFilter: "invert(28%) sepia(27%) saturate(475%) hue-rotate(76deg) brightness(95%) contrast(93%)"},   | ||||
|   ww2: { primaryFont: "SairaStencilOne", secondaryFont: "SairaStencilOne", titleFont: "Armalite", baseFontSize: "0.9rem",titleFontSize: "1.2rem",imgFilter: "filter: invert(44%) sepia(8%) saturate(2657%) hue-rotate(40deg) brightness(96%) contrast(75%)"}, | ||||
|   ww1: { primaryFont: "CarterOne", secondaryFont: "CarterOne", titleFont: "SigmarOne", baseFontSize: "0.9rem",titleFontSize: "1.1rem",imgFilter: "invert(28%) sepia(27%) saturate(475%) hue-rotate(76deg) brightness(95%) contrast(93%)"}, | ||||
|   ageofsail: { primaryFont: "SailRegular", secondaryFont: "SailRegular", titleFont: "P22Operina", baseFontSize: "1.1rem",titleFontSize: "1.2rem",imgFilter: "brightness(0) saturate(100%) invert(43%) sepia(74%) saturate(3154%) hue-rotate(336deg) brightness(95%) contrast(83%)" }, | ||||
|   classical: { primaryFont: "ChantelliAntiqua", secondaryFont: "ChantelliAntiqua", titleFont: "TrajanPro", baseFontSize: "0.9rem",titleFontSize: "1.1rem",imgFilter: "brightness(0) saturate(100%) invert(52%) sepia(32%) saturate(7492%) hue-rotate(265deg) brightness(89%) contrast(95%)" }, | ||||
|   postapo: { primaryFont: "Teko", secondaryFont: "Teko", titleFont: "Teko", baseFontSize: "1.25rem",titleFontSize: "1.5rem",imgFilter: "brightness(0) saturate(100%) invert(44%) sepia(55%) saturate(2341%) hue-rotate(329deg) brightness(122%) contrast(103%))" } | ||||
|   postapo: { primaryFont: "Teko", secondaryFont: "Teko", titleFont: "Teko", baseFontSize: "1.35rem",titleFontSize: "1.5rem",imgFilter: "brightness(0) saturate(100%) invert(44%) sepia(55%) saturate(2341%) hue-rotate(329deg) brightness(122%) contrast(103%))" } | ||||
| } | ||||
|  | ||||
| export const RESOURCE_RATING = { | ||||
| @@ -122,7 +122,7 @@ export const VEHICLE_SPEED = { | ||||
|   "fast": "CTHULHUETERNAL.Label.Fast" | ||||
| } | ||||
|  | ||||
| export const EQUIPMENT_STATES = {  | ||||
| export const EQUIPMENT_STATES = { | ||||
|   "pristine": "CTHULHUETERNAL.Label.Pristine", | ||||
|   "worn": "CTHULHUETERNAL.Label.Worn", | ||||
|   "junk": "CTHULHUETERNAL.Label.Junk" | ||||
| @@ -240,6 +240,7 @@ export const MULTIPLIER_CHOICES = { | ||||
|  | ||||
| export const RITUAL_TYPES = { | ||||
|   "simple": "CTHULHUETERNAL.Ritual.Simple", | ||||
|   "difficult": "CTHULHUETERNAL.Ritual.Difficult", | ||||
|   "complex": "CTHULHUETERNAL.Ritual.Complex", | ||||
|   "elaborate": "CTHULHUETERNAL.Ritual.Elaborate" | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
|  | ||||
| import { SYSTEM } from "../config/system.mjs" | ||||
|  | ||||
| export default class CthulhuEternalRoll extends Roll { | ||||
|   /** | ||||
|    * The HTML template path used to render dice checks of this type | ||||
| @@ -146,6 +147,24 @@ export default class CthulhuEternalRoll extends Roll { | ||||
|         options.isNudge = false | ||||
|         break | ||||
|       case "damage": | ||||
|         let isLethal = false | ||||
|         options.isNudge = false | ||||
|         if (options.rollItem.system.lethality > 0) { | ||||
|           let lethalityRoll = new Roll("1d100") | ||||
|           await lethalityRoll.evaluate() | ||||
|           isLethal = (lethalityRoll.total <= options.rollItem.system.lethality) | ||||
|           let flavor = `${options.rollItem.name} - <strong>Lethality Roll</strong> : ${lethalityRoll.total} <= ${options.rollItem.system.lethality} => ${isLethal}` | ||||
|           if ( isLethal) { | ||||
|             flavor += `<br>The target is lethally wounded => HP = 0` | ||||
|           } else { | ||||
|             let wounds = Math.floor(lethalityRoll.total/10) + (lethalityRoll.total % 10) | ||||
|             flavor += `<br>The target is not lethally wounded => HP loss = ${wounds}` | ||||
|           } | ||||
|           await lethalityRoll.toMessage({ | ||||
|             flavor:flavor | ||||
|           }); | ||||
|           return | ||||
|         } | ||||
|         let formula = options.rollItem.system.damage | ||||
|         if ( options.rollItem.system.weaponType === "melee" || options.rollItem.system.weaponType === "unarmed") { | ||||
|           formula += ` + ${options.rollItem.damageBonus}` | ||||
| @@ -155,16 +174,6 @@ export default class CthulhuEternalRoll extends Roll { | ||||
|         await damageRoll.toMessage({ | ||||
|           flavor: `${options.rollItem.name} - Damage Roll` | ||||
|         }); | ||||
|         let isLethal = false | ||||
|         options.isNudge = false | ||||
|         if (options.rollItem.system.lethality > 0) { | ||||
|           let lethalityRoll = new Roll("1d100") | ||||
|           await lethalityRoll.evaluate() | ||||
|           isLethal = (lethalityRoll.total <= options.rollItem.system.lethality) | ||||
|           await lethalityRoll.toMessage({ | ||||
|             flavor: `${options.rollItem.name} - Lethality Roll : ${lethalityRoll.total} <= ${options.rollItem.system.lethality} => ${isLethal}` | ||||
|           }); | ||||
|         } | ||||
|         return | ||||
|       case "weapon": | ||||
|         let era = game.settings.get("fvtt-cthulhu-eternal", "settings-era") | ||||
| @@ -185,7 +194,7 @@ export default class CthulhuEternalRoll extends Roll { | ||||
|           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)           | ||||
|           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")) | ||||
| @@ -320,19 +329,19 @@ export default class CthulhuEternalRoll extends Roll { | ||||
|     let unit = this.total - (dec * 10) | ||||
|     if (this.total <= rollData.targetScore) { | ||||
|       resultType = "success" | ||||
|       // Detect if decimal == unit in the dire total result  | ||||
|       // Detect if decimal == unit in the dire total result | ||||
|       if (dec === unit || this.total === 1) { | ||||
|         resultType = "successCritical" | ||||
|       } | ||||
|     } else { | ||||
|       // Detect if decimal == unit in the dire total result  | ||||
|       // Detect if decimal == unit in the dire total result | ||||
|       if (dec === unit || this.total === 100) { | ||||
|         resultType = "failureCritical" | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     this.options.resultType = resultType | ||||
|     if (this.options.isNudgedRoll) {  | ||||
|     if (this.options.isNudgedRoll) { | ||||
|       this.options.isSuccess = resultType === "success" || resultType === "successCritical" | ||||
|       this.options.isFailure = resultType === "failure" || resultType === "failureCritical" | ||||
|       this.options.isCritical = false | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { SYSTEM } from "../config/system.mjs" | ||||
|  | ||||
| export default class LethalFantasySkill extends foundry.abstract.TypeDataModel { | ||||
| export default class CthulhuEternalWeapon extends foundry.abstract.TypeDataModel { | ||||
|   static defineSchema() { | ||||
|     const fields = foundry.data.fields | ||||
|     const schema = {} | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
|  | ||||
| import CthulhuEternalRoll from "./documents/roll.mjs" | ||||
| import { SystemManager } from './applications/hud/system-manager.js' | ||||
| import { SYSTEM } from "./config/system.mjs" | ||||
|  | ||||
| export default class CthulhuEternalUtils { | ||||
|  | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								packs-system/rituals/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								packs-system/rituals/000005.ldb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										1
									
								
								packs-system/rituals/CURRENT
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packs-system/rituals/CURRENT
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| MANIFEST-000010 | ||||
							
								
								
									
										0
									
								
								packs-system/rituals/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								packs-system/rituals/LOCK
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										8
									
								
								packs-system/rituals/LOG
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								packs-system/rituals/LOG
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| 2025/04/25-00:23:55.566074 7fd0855fa6c0 Recovering log #8 | ||||
| 2025/04/25-00:23:55.627155 7fd0855fa6c0 Delete type=3 #6 | ||||
| 2025/04/25-00:23:55.627214 7fd0855fa6c0 Delete type=0 #8 | ||||
| 2025/04/25-00:24:39.296644 7fd07effd6c0 Level-0 table #13: started | ||||
| 2025/04/25-00:24:39.296707 7fd07effd6c0 Level-0 table #13: 0 bytes OK | ||||
| 2025/04/25-00:24:39.302890 7fd07effd6c0 Delete type=0 #11 | ||||
| 2025/04/25-00:24:39.309638 7fd07effd6c0 Manual compaction at level-0 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end) | ||||
| 2025/04/25-00:24:39.309671 7fd07effd6c0 Manual compaction at level-1 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end) | ||||
							
								
								
									
										8
									
								
								packs-system/rituals/LOG.old
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								packs-system/rituals/LOG.old
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| 2025/04/24-23:56:15.236151 7fd0855fa6c0 Recovering log #4 | ||||
| 2025/04/24-23:56:15.247158 7fd0855fa6c0 Delete type=0 #4 | ||||
| 2025/04/24-23:56:15.247228 7fd0855fa6c0 Delete type=3 #2 | ||||
| 2025/04/25-00:23:51.709456 7fd07effd6c0 Level-0 table #9: started | ||||
| 2025/04/25-00:23:51.709498 7fd07effd6c0 Level-0 table #9: 0 bytes OK | ||||
| 2025/04/25-00:23:51.747489 7fd07effd6c0 Delete type=0 #7 | ||||
| 2025/04/25-00:23:51.747677 7fd07effd6c0 Manual compaction at level-0 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end) | ||||
| 2025/04/25-00:23:51.809910 7fd07effd6c0 Manual compaction at level-1 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end) | ||||
							
								
								
									
										
											BIN
										
									
								
								packs-system/rituals/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								packs-system/rituals/MANIFEST-000010
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								packs-system/skills/000165.ldb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								packs-system/skills/000165.ldb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										0
									
								
								packs-system/skills/000176.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								packs-system/skills/000176.log
									
									
									
									
									
										Normal file
									
								
							| @@ -1 +1 @@ | ||||
| MANIFEST-000132 | ||||
| MANIFEST-000174 | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| 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) | ||||
| 2025/04/25-00:23:55.465639 7fd07f7fe6c0 Recovering log #172 | ||||
| 2025/04/25-00:23:55.561118 7fd07f7fe6c0 Delete type=3 #170 | ||||
| 2025/04/25-00:23:55.561198 7fd07f7fe6c0 Delete type=0 #172 | ||||
| 2025/04/25-00:24:39.302991 7fd07effd6c0 Level-0 table #177: started | ||||
| 2025/04/25-00:24:39.303023 7fd07effd6c0 Level-0 table #177: 0 bytes OK | ||||
| 2025/04/25-00:24:39.309509 7fd07effd6c0 Delete type=0 #175 | ||||
| 2025/04/25-00:24:39.309652 7fd07effd6c0 Manual compaction at level-0 from '!folders!5PrT9QmN1cFPzDFP' @ 72057594037927935 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at (end) | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| 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/04/24-23:56:15.221751 7fd07f7fe6c0 Recovering log #168 | ||||
| 2025/04/24-23:56:15.231420 7fd07f7fe6c0 Delete type=0 #168 | ||||
| 2025/04/24-23:56:15.231515 7fd07f7fe6c0 Delete type=3 #166 | ||||
| 2025/04/25-00:23:51.673765 7fd07effd6c0 Level-0 table #173: started | ||||
| 2025/04/25-00:23:51.673830 7fd07effd6c0 Level-0 table #173: 0 bytes OK | ||||
| 2025/04/25-00:23:51.709271 7fd07effd6c0 Delete type=0 #171 | ||||
| 2025/04/25-00:23:51.747663 7fd07effd6c0 Manual compaction at level-0 from '!folders!5PrT9QmN1cFPzDFP' @ 72057594037927935 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at (end) | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								packs-system/skills/MANIFEST-000174
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								packs-system/skills/MANIFEST-000174
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										0
									
								
								packs-system/skills/lost/000159.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								packs-system/skills/lost/000159.log
									
									
									
									
									
										Normal file
									
								
							| @@ -5,6 +5,14 @@ | ||||
|   fieldset { | ||||
|     margin-top: 8px; | ||||
|     background-color: var(--color-light-1); | ||||
|     .editor-content { | ||||
|       max-height: 400px; | ||||
|       overflow-y: auto; | ||||
|     } | ||||
|     .editor-container { | ||||
|       max-height: 400px; | ||||
|       overflow-y: auto; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .header { | ||||
|   | ||||
							
								
								
									
										10
									
								
								system.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								system.json
									
									
									
									
									
								
							| @@ -6,7 +6,7 @@ | ||||
|   "download": "#{DOWNLOAD}#", | ||||
|   "url": "https://www.uberwald.me/gitea/public/fvtt-cthulhu-eternal", | ||||
|   "license": "LICENSE", | ||||
|   "version": "12.0.5", | ||||
|   "version": "12.0.6", | ||||
|   "authors": [ | ||||
|     { | ||||
|       "name": "Uberwald", | ||||
| @@ -61,6 +61,14 @@ | ||||
|       "system": "fvtt-cthulhu-eternal", | ||||
|       "path": "packs-system/skills", | ||||
|       "type": "Item" | ||||
|     }, | ||||
|     { | ||||
|       "name": "rituals", | ||||
|       "banner": "", | ||||
|       "label": "Rituals", | ||||
|       "system": "fvtt-cthulhu-eternal", | ||||
|       "path": "packs-system/rituals", | ||||
|       "type": "Item" | ||||
|     } | ||||
|   ], | ||||
|   "grid": { | ||||
|   | ||||
| @@ -2,11 +2,11 @@ | ||||
|   <div class="header"> | ||||
|     <img class="item-img era-icon-color" src="{{item.img}}" data-edit="img" data-action="editImage" data-tooltip="{{item.name}}" /> | ||||
|     {{formInput fields.name value=source.name}} | ||||
|   </div>   | ||||
|   </div> | ||||
|  | ||||
|   <fieldset> | ||||
|     <legend>{{localize "CTHULHUETERNAL.Label.description"}}</legend> | ||||
|     {{formInput systemFields.description enriched=description value=system.description name="system.description" toggled=true}} | ||||
|     {{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}} | ||||
|   </fieldset> | ||||
|  | ||||
| </section> | ||||
| @@ -2,15 +2,15 @@ | ||||
|   <div class="header"> | ||||
|     <img class="item-img" src="{{item.img}}" data-edit="img" data-action="editImage" data-tooltip="{{item.name}}" /> | ||||
|     {{formInput fields.name value=source.name}} | ||||
|   </div>   | ||||
|   </div> | ||||
|  | ||||
|   <fieldset> | ||||
|     {{formField systemFields.settings value=system.settings localize=true}} | ||||
|   </fieldset>   | ||||
|   </fieldset> | ||||
|  | ||||
|   <fieldset> | ||||
|     <legend>{{localize "CTHULHUETERNAL.Label.description"}}</legend> | ||||
|     {{formInput systemFields.description enriched=description value=system.description name="system.description" toggled=true}} | ||||
|     {{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}} | ||||
|   </fieldset> | ||||
|  | ||||
| </section>h | ||||
|   | ||||
| @@ -15,7 +15,7 @@ | ||||
|     <legend>{{localize "CTHULHUETERNAL.Label.description"}}</legend> | ||||
|     {{formInput | ||||
|     systemFields.description | ||||
|     enriched=description | ||||
|     enriched=enrichedDescription | ||||
|     value=system.description | ||||
|     name="system.description" | ||||
|     toggled="false" | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
|  | ||||
|   <fieldset> | ||||
|     <legend>{{localize "CTHULHUETERNAL.Label.description"}}</legend> | ||||
|     {{formInput systemFields.description enriched=description value=system.description name="system.description" | ||||
|     {{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" | ||||
|     toggled=true}} | ||||
|   </fieldset> | ||||
|  | ||||
|   | ||||
| @@ -2,8 +2,8 @@ | ||||
|   <div class="header"> | ||||
|     <img class="item-img" src="{{item.img}}" data-edit="img" data-action="editImage" data-tooltip="{{item.name}}" /> | ||||
|     {{formInput fields.name value=source.name}} | ||||
|   </div>  | ||||
|    | ||||
|   </div> | ||||
|  | ||||
|   <fieldset> | ||||
|     {{formField systemFields.cured value=system.cured localize=true}} | ||||
|   </fieldset> | ||||
| @@ -12,7 +12,7 @@ | ||||
|     <legend>{{localize "CTHULHUETERNAL.Label.description"}}</legend> | ||||
|     {{formInput | ||||
|       systemFields.description | ||||
|       enriched=description | ||||
|       enriched=enrichedDescription | ||||
|       value=system.description | ||||
|       name="system.description" | ||||
|       toggled="false" | ||||
|   | ||||
| @@ -2,11 +2,11 @@ | ||||
|   <div class="header"> | ||||
|     <img class="item-img" src="{{item.img}}" data-edit="img" data-action="editImage" data-tooltip="{{item.name}}" /> | ||||
|     {{formInput fields.name value=source.name}} | ||||
|   </div>   | ||||
|   </div> | ||||
|  | ||||
|   <fieldset> | ||||
|     <legend>{{localize "CTHULHUETERNAL.Label.description"}}</legend> | ||||
|     {{formInput systemFields.description enriched=description value=system.description name="system.description" toggled=true}} | ||||
|     {{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}} | ||||
|   </fieldset> | ||||
|  | ||||
| </section> | ||||
| @@ -2,22 +2,23 @@ | ||||
|   <div class="header"> | ||||
|     <img class="item-img" src="{{item.img}}" data-edit="img" data-action="editImage" data-tooltip="{{item.name}}" /> | ||||
|     {{formInput fields.name value=source.name}} | ||||
|   </div>   | ||||
|   </div> | ||||
|  | ||||
|   <fieldset> | ||||
|      | ||||
|  | ||||
|     {{formField systemFields.ritualType value=system.ritualType localize=true}} | ||||
|     {{formField systemFields.studyTime value=system.studyTime}} | ||||
|     {{formField systemFields.studySAN value=system.studySAN}} | ||||
|     {{formField systemFields.activationTime value=system.activationTime}} | ||||
|     {{formField systemFields.activationSAN value=system.activationSAN}} | ||||
|     {{formField systemFields.activationWP value=system.activationWP}} | ||||
|      | ||||
|  | ||||
|   </fieldset> | ||||
|  | ||||
|   <fieldset> | ||||
|     <legend>{{localize "CTHULHUETERNAL.Label.description"}}</legend> | ||||
|     {{formInput systemFields.description enriched=description value=system.description name="system.description" toggled=true}} | ||||
|     {{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}} | ||||
|  | ||||
|   </fieldset> | ||||
|  | ||||
| </section> | ||||
| @@ -2,10 +2,10 @@ | ||||
|   <div class="header"> | ||||
|     <img class="item-img" src="{{item.img}}" data-edit="img" data-action="editImage" data-tooltip="{{item.name}}" /> | ||||
|     {{formInput fields.name value=source.name}} | ||||
|   </div>   | ||||
|   </div> | ||||
|  | ||||
|   <fieldset> | ||||
|          | ||||
|  | ||||
|     <div class="form-group"> | ||||
|       {{formField systemFields.language value=system.language }} | ||||
|     </div> | ||||
| @@ -36,7 +36,7 @@ | ||||
|  | ||||
|   <fieldset> | ||||
|     <legend>{{localize "CTHULHUETERNAL.Label.description"}}</legend> | ||||
|     {{formInput systemFields.description enriched=description value=system.description name="system.description" toggled=true}} | ||||
|     {{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}} | ||||
|   </fieldset> | ||||
|  | ||||
| </section> | ||||
| @@ -28,12 +28,12 @@ | ||||
|  | ||||
|     {{formField systemFields.resourceLevel value=system.resourceLevel}} | ||||
|   </fieldset> | ||||
|    | ||||
|  | ||||
|   <fieldset> | ||||
|     <legend>{{localize "CTHULHUETERNAL.Label.description"}}</legend> | ||||
|     {{formInput | ||||
|     systemFields.description | ||||
|     enriched=description | ||||
|     enriched=enrichedDescription | ||||
|     value=system.description | ||||
|     name="system.description" | ||||
|     toggled=true | ||||
|   | ||||
		Reference in New Issue
	
	Block a user