Attempt to add HUD core
This commit is contained in:
@@ -3087,21 +3087,6 @@ i.fvtt-cthulhu-eternal {
|
|||||||
font-family: var(--font-primary);
|
font-family: var(--font-primary);
|
||||||
font-size: calc(var(--font-size-standard) * 1);
|
font-size: calc(var(--font-size-standard) * 1);
|
||||||
}
|
}
|
||||||
.dice-roll .intro-chat .intro-right ul .nudge-roll {
|
|
||||||
font-size: calc(var(--font-size-standard) * 1);
|
|
||||||
margin-left: 2rem;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.dice-roll .intro-chat .intro-right ul .healing-roll {
|
|
||||||
font-size: calc(var(--font-size-standard) * 1);
|
|
||||||
margin-left: 2rem;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.dice-roll .intro-chat .intro-right ul .roll-damage {
|
|
||||||
font-size: calc(var(--font-size-standard) * 1);
|
|
||||||
margin-left: 2rem;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.dice-roll .intro-chat .intro-right ul .result-success {
|
.dice-roll .intro-chat .intro-right ul .result-success {
|
||||||
color: var(--color-success);
|
color: var(--color-success);
|
||||||
font-family: var(--font-title);
|
font-family: var(--font-title);
|
||||||
@@ -3136,3 +3121,197 @@ i.fvtt-cthulhu-eternal {
|
|||||||
font-size: calc(var(--font-size-standard) * 1.2);
|
font-size: calc(var(--font-size-standard) * 1.2);
|
||||||
text-shadow: 0 0 10px var(--color-shadow-primary);
|
text-shadow: 0 0 10px var(--color-shadow-primary);
|
||||||
}
|
}
|
||||||
|
.dice-roll .chat-actions {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.375rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
border-top: 1px solid var(--color-border-light-primary);
|
||||||
|
background: rgba(0, 0, 0, 0.05);
|
||||||
|
border-radius: 0 0 5px 5px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.dice-roll .chat-actions .chat-action-button {
|
||||||
|
display: inline-flex !important;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
padding: 0 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
background: var(--color-dark-6);
|
||||||
|
color: var(--color-light-1);
|
||||||
|
border: 1px solid var(--color-border-light-primary);
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
text-decoration: none;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.dice-roll .chat-actions .chat-action-button:hover {
|
||||||
|
background: var(--color-dark-5);
|
||||||
|
border-color: var(--color-border-dark);
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
.dice-roll .chat-actions .chat-action-button i {
|
||||||
|
font-size: 1rem !important;
|
||||||
|
line-height: 1;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.dice-roll .chat-actions .nudge-roll,
|
||||||
|
.dice-roll .chat-actions .damage-roll,
|
||||||
|
.dice-roll .chat-actions .healing-roll,
|
||||||
|
.dice-roll .chat-actions .opposed-roll {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.opposed-roll-result {
|
||||||
|
padding: 1rem;
|
||||||
|
background: rgba(0, 0, 0, 0.05);
|
||||||
|
border-radius: 5px;
|
||||||
|
font-family: var(--font-primary);
|
||||||
|
}
|
||||||
|
.opposed-roll-result .opposed-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
border-bottom: 2px solid var(--color-border-light-primary);
|
||||||
|
}
|
||||||
|
.opposed-roll-result .opposed-header h3 {
|
||||||
|
margin: 0;
|
||||||
|
font-family: var(--font-title);
|
||||||
|
font-size: calc(var(--font-size-standard) * 1.2);
|
||||||
|
color: var(--color-dark-1);
|
||||||
|
}
|
||||||
|
.opposed-roll-result .opposed-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
.opposed-roll-result .opposed-winner,
|
||||||
|
.opposed-roll-result .opposed-loser {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.75rem;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
.opposed-roll-result .opposed-winner {
|
||||||
|
background: rgba(34, 139, 34, 0.1);
|
||||||
|
border: 2px solid var(--color-success);
|
||||||
|
}
|
||||||
|
.opposed-roll-result .opposed-loser {
|
||||||
|
background: rgba(220, 20, 60, 0.1);
|
||||||
|
border: 2px solid var(--color-failure);
|
||||||
|
}
|
||||||
|
.opposed-roll-result .character-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
.opposed-roll-result .character-info img {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 2px solid var(--color-border-light-primary);
|
||||||
|
}
|
||||||
|
.opposed-roll-result .character-info .character-name {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
.opposed-roll-result .character-info .character-name strong {
|
||||||
|
font-size: calc(var(--font-size-standard) * 0.85);
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--color-dark-2);
|
||||||
|
}
|
||||||
|
.opposed-roll-result .character-info .character-name .winner-name {
|
||||||
|
font-size: calc(var(--font-size-standard) * 1.1);
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--color-success);
|
||||||
|
}
|
||||||
|
.opposed-roll-result .character-info .character-name .loser-name {
|
||||||
|
font-size: calc(var(--font-size-standard) * 1.1);
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--color-failure);
|
||||||
|
}
|
||||||
|
.opposed-roll-result .roll-result {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
.opposed-roll-result .roll-result .roll-value {
|
||||||
|
font-size: calc(var(--font-size-standard) * 1.5);
|
||||||
|
font-weight: bold;
|
||||||
|
font-family: var(--font-title);
|
||||||
|
}
|
||||||
|
.opposed-roll-result .roll-result .critical-badge {
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: calc(var(--font-size-standard) * 0.8);
|
||||||
|
font-weight: bold;
|
||||||
|
text-transform: uppercase;
|
||||||
|
background: var(--color-critical-success);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.opposed-roll-result .winner-result .roll-value {
|
||||||
|
color: var(--color-success);
|
||||||
|
}
|
||||||
|
.opposed-roll-result .loser-result .roll-value {
|
||||||
|
color: var(--color-failure);
|
||||||
|
}
|
||||||
|
.opposed-roll-result .versus-separator {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
font-size: calc(var(--font-size-standard) * 1.1);
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--color-dark-2);
|
||||||
|
}
|
||||||
|
.opposed-roll-result .versus-separator i {
|
||||||
|
font-size: calc(var(--font-size-standard) * 1.3);
|
||||||
|
}
|
||||||
|
.opposed-roll-result .chat-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.375rem;
|
||||||
|
padding: 0.75rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
border-top: 1px solid var(--color-border-light-primary);
|
||||||
|
background: rgba(0, 0, 0, 0.05);
|
||||||
|
border-radius: 0 0 5px 5px;
|
||||||
|
}
|
||||||
|
.opposed-roll-result .chat-actions .chat-action-button {
|
||||||
|
display: inline-flex !important;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
padding: 0 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
background: var(--color-dark-6);
|
||||||
|
color: var(--color-light-1);
|
||||||
|
border: 1px solid var(--color-border-light-primary);
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
text-decoration: none;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.opposed-roll-result .chat-actions .chat-action-button:hover {
|
||||||
|
background: var(--color-dark-5);
|
||||||
|
border-color: var(--color-border-dark);
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
.opposed-roll-result .chat-actions .chat-action-button i {
|
||||||
|
font-size: 1rem !important;
|
||||||
|
line-height: 1;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ import * as applications from "./module/applications/_module.mjs"
|
|||||||
import { handleSocketEvent } from "./module/socket.mjs"
|
import { handleSocketEvent } from "./module/socket.mjs"
|
||||||
import CthulhuEternalUtils from "./module/utils.mjs"
|
import CthulhuEternalUtils from "./module/utils.mjs"
|
||||||
|
|
||||||
|
import { SystemManager } from './module/applications/hud/system-manager.js'
|
||||||
|
import { MODULE, REQUIRED_CORE_MODULE_VERSION } from './module/applications/hud/constants.js'
|
||||||
|
|
||||||
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 () {
|
Hooks.once("init", function () {
|
||||||
@@ -142,9 +145,22 @@ Hooks.once("ready", function () {
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
Hooks.on('tokenActionHudCoreApiReady', async () => {
|
||||||
|
/**
|
||||||
|
* Return the SystemManager and requiredCoreModuleVersion to Token Action HUD Core
|
||||||
|
*/
|
||||||
|
let module = {} // game.modules.get(MODULE.ID)
|
||||||
|
module.api = {
|
||||||
|
requiredCoreModuleVersion: REQUIRED_CORE_MODULE_VERSION,
|
||||||
|
SystemManager
|
||||||
|
}
|
||||||
|
Hooks.call('tokenActionHudSystemReady', module)
|
||||||
|
})
|
||||||
|
|
||||||
Hooks.on("renderChatMessageHTML", (message, html, data) => {
|
Hooks.on("renderChatMessageHTML", (message, html, data) => {
|
||||||
// Affichage des boutons de jet de dés uniquement pour les joueurs
|
// Affichage des boutons de jet de dés uniquement pour les joueurs
|
||||||
if (message.author.id === game.user.id) {
|
if (message.author.id === game.user.id || game.user.isGM) {
|
||||||
$(html).find(".nudge-roll").each((i, btn) => {
|
$(html).find(".nudge-roll").each((i, btn) => {
|
||||||
btn.style.display = "inline"
|
btn.style.display = "inline"
|
||||||
})
|
})
|
||||||
@@ -154,6 +170,11 @@ Hooks.on("renderChatMessageHTML", (message, html, data) => {
|
|||||||
$(html).find(".healing-roll").each((i, btn) => {
|
$(html).find(".healing-roll").each((i, btn) => {
|
||||||
btn.style.display = "inline"
|
btn.style.display = "inline"
|
||||||
})
|
})
|
||||||
|
if (game.user.isGM) {
|
||||||
|
$(html).find(".opposed-roll").each((i, btn) => {
|
||||||
|
btn.style.display = "inline"
|
||||||
|
})
|
||||||
|
}
|
||||||
$(html).find(".nudge-roll").click((event) => {
|
$(html).find(".nudge-roll").click((event) => {
|
||||||
CthulhuEternalUtils.nudgeRoll(message)
|
CthulhuEternalUtils.nudgeRoll(message)
|
||||||
})
|
})
|
||||||
@@ -170,6 +191,9 @@ Hooks.on("renderChatMessageHTML", (message, html, data) => {
|
|||||||
$(html).find(".san-type").click((event) => {
|
$(html).find(".san-type").click((event) => {
|
||||||
CthulhuEternalUtils.applySANType(message, event)
|
CthulhuEternalUtils.applySANType(message, event)
|
||||||
})
|
})
|
||||||
|
$(html).find(".opposed-roll").click((event) => {
|
||||||
|
CthulhuEternalUtils.opposedRollManagement(message, event)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if (game.user.isGM) {
|
if (game.user.isGM) {
|
||||||
$(html).find(".li-apply-wounds").each((i, btn) => {
|
$(html).find(".li-apply-wounds").each((i, btn) => {
|
||||||
|
|||||||
10
lang/en.json
10
lang/en.json
@@ -736,7 +736,11 @@
|
|||||||
"rangedRange": "Range",
|
"rangedRange": "Range",
|
||||||
"aimingLastRound": "Aiming Last Round (+20)",
|
"aimingLastRound": "Aiming Last Round (+20)",
|
||||||
"aimingWithSight": "Aiming with Sight (+20)",
|
"aimingWithSight": "Aiming with Sight (+20)",
|
||||||
"applyWounds": "Apply To"
|
"applyWounds": "Apply To",
|
||||||
|
"opposedRollWinner": "Opposed Roll Winner",
|
||||||
|
"opposedRollResult": "Opposed Roll Result",
|
||||||
|
"defeats": "defeats",
|
||||||
|
"critical": "Critical"
|
||||||
},
|
},
|
||||||
"ChatMessage": {
|
"ChatMessage": {
|
||||||
"exhausted": "Your protagonist is exhausted. He loses [[/r 1d6]] Willpower Points."
|
"exhausted": "Your protagonist is exhausted. He loses [[/r 1d6]] Willpower Points."
|
||||||
@@ -775,7 +779,9 @@
|
|||||||
"NoAmmo": "No more ammo for this weapon. ",
|
"NoAmmo": "No more ammo for this weapon. ",
|
||||||
"noRollDataFound": "No roll data found",
|
"noRollDataFound": "No roll data found",
|
||||||
"noActorFound": "No actor found for this item.",
|
"noActorFound": "No actor found for this item.",
|
||||||
"noSanLossFound": "No SAN loss value found."
|
"noSanLossFound": "No SAN loss value found.",
|
||||||
|
"opposedRollFirstStored": "First opposed roll stored. Perform and store the second roll to resolve the opposed roll.",
|
||||||
|
"opposedRollSecondStored": "Second opposed roll stored. The opposed roll is now being resolved."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
lang/fr.json
24
lang/fr.json
@@ -618,7 +618,7 @@
|
|||||||
"Unarmed": "Désarmé",
|
"Unarmed": "Désarmé",
|
||||||
"Cured": "Soigné",
|
"Cured": "Soigné",
|
||||||
"Uncured": "Non soigné",
|
"Uncured": "Non soigné",
|
||||||
"nudgedRoll": "Modifier le jeu",
|
"nudgedRoll": "Jet modifié : ",
|
||||||
"selectNewValue": "Sélectionner une nouvelle valeur",
|
"selectNewValue": "Sélectionner une nouvelle valeur",
|
||||||
"wpCost": "Cout en PVO",
|
"wpCost": "Cout en PVO",
|
||||||
"Hand": "A portée de main",
|
"Hand": "A portée de main",
|
||||||
@@ -740,7 +740,10 @@
|
|||||||
"stunnedWarning": "Votre protagoniste est étourdi. Il ne peut pas agir tant qu'il n'a pas réussi un test de CON x 5.",
|
"stunnedWarning": "Votre protagoniste est étourdi. Il ne peut pas agir tant qu'il n'a pas réussi un test de CON x 5.",
|
||||||
"deadWarning": "Votre protagoniste est mourrant. Il mourra s'il n'est pas soigné dans les {con} minutes",
|
"deadWarning": "Votre protagoniste est mourrant. Il mourra s'il n'est pas soigné dans les {con} minutes",
|
||||||
"unconsciousWarning": "Votre protagoniste est inconscient. Il ne peut pas agir tant qu'il n'a pas atteint 3 PV.",
|
"unconsciousWarning": "Votre protagoniste est inconscient. Il ne peut pas agir tant qu'il n'a pas atteint 3 PV.",
|
||||||
"Luck": "Chance",
|
"luck": "Chance",
|
||||||
|
"Other": "Autre",
|
||||||
|
"Skills": "Compétences",
|
||||||
|
"WP": "PVO",
|
||||||
"titleLuck": "Jet de Chance",
|
"titleLuck": "Jet de Chance",
|
||||||
"healingRoll": "Jet de soin, PV soignés",
|
"healingRoll": "Jet de soin, PV soignés",
|
||||||
"healingRollFailure": "Jet de soin échoué critique, PV perdus",
|
"healingRollFailure": "Jet de soin échoué critique, PV perdus",
|
||||||
@@ -757,7 +760,18 @@
|
|||||||
"rangedRange": "Portée",
|
"rangedRange": "Portée",
|
||||||
"aimingLastRound": "Visée lors du dernier round (+20)",
|
"aimingLastRound": "Visée lors du dernier round (+20)",
|
||||||
"aimingWithSight": "Visée avec lunette (+20)",
|
"aimingWithSight": "Visée avec lunette (+20)",
|
||||||
"applyWounds": "Appliquer à"
|
"applyWounds": "Appliquer à",
|
||||||
|
"opposedRollWinner": "Gagnant du jet opposé",
|
||||||
|
"opposedRollResult": "Résultat du jet opposé",
|
||||||
|
"defeats": "Défait",
|
||||||
|
"critical": "Critique",
|
||||||
|
"other": "Autre",
|
||||||
|
"str": "FOR",
|
||||||
|
"dex": "DEX",
|
||||||
|
"int": "INT",
|
||||||
|
"pow": "POU",
|
||||||
|
"con": "CON",
|
||||||
|
"cha": "CHA"
|
||||||
},
|
},
|
||||||
"ChatMessage": {
|
"ChatMessage": {
|
||||||
"exhausted": "Votre protagoniste est épuisé. Il perd [[/r 1d6]] Points de Volonté."
|
"exhausted": "Votre protagoniste est épuisé. Il perd [[/r 1d6]] Points de Volonté."
|
||||||
@@ -796,7 +810,9 @@
|
|||||||
"NoAmmo": "Aucune munition disponible pour cette arme.",
|
"NoAmmo": "Aucune munition disponible pour cette arme.",
|
||||||
"noRollDataFound": "Aucune donnée de jet trouvée.",
|
"noRollDataFound": "Aucune donnée de jet trouvée.",
|
||||||
"noActorFound": "Aucun protagoniste trouvé.",
|
"noActorFound": "Aucun protagoniste trouvé.",
|
||||||
"noSanLossFound": "Aucune valeur de perte de SAN trouvée."
|
"noSanLossFound": "Aucune valeur de perte de SAN trouvée.",
|
||||||
|
"opposedRollFirstStored": "Premier jet opposé enregistré. Effectuez et enregistrez le deuxième jet pour résoudre le jet opposé.",
|
||||||
|
"opposedRollSecondStored": "Deuxième jet opposé enregistré. Le jet opposé est maintenant en cours de résolution."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// System Module Imports
|
// System Module Imports
|
||||||
import { Utils } from './utils.js'
|
import { Utils } from './utils.js'
|
||||||
import { SYSTEM } from "../../config/system.mjs"
|
import { SYSTEM } from "../../config/system.mjs"
|
||||||
|
|
||||||
export let ActionHandler = null
|
export let ActionHandler = null
|
||||||
|
|
||||||
Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
||||||
@@ -38,7 +39,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
#buildCharacterActions() {
|
#buildCharacterActions() {
|
||||||
this.buildAttributes()
|
this.buildCharacteristics()
|
||||||
this.buildOther()
|
this.buildOther()
|
||||||
this.buildLuck()
|
this.buildLuck()
|
||||||
this.buildSkills()
|
this.buildSkills()
|
||||||
@@ -49,17 +50,17 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
return game.settings.get('token-action-hud-core', 'tooltips') === 'none'
|
return game.settings.get('token-action-hud-core', 'tooltips') === 'none'
|
||||||
}
|
}
|
||||||
|
|
||||||
async buildAttributes() {
|
async buildCharacteristics() {
|
||||||
const actions = []
|
const actions = []
|
||||||
for (const key in this.actor.system.characteristics) {
|
for (const key in this.actor.system.characteristics) {
|
||||||
const encodedValue = [coreModule.api.Utils.i18n('attributes'), key].join(this.delimiter)
|
const encodedValue = [coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.characteristics'), key].join(this.delimiter)
|
||||||
const tooltip = {
|
const tooltip = {
|
||||||
content: String(this.actor.system.characteristics[key].value * 5),
|
content: String(this.actor.system.characteristics[key].value * 5),
|
||||||
class: 'tah-system-tooltip',
|
class: 'tah-system-tooltip',
|
||||||
direction: 'LEFT'
|
direction: 'LEFT'
|
||||||
}
|
}
|
||||||
actions.push({
|
actions.push({
|
||||||
name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.' + key),
|
name: coreModule.api.Utils.i18n(`CTHULHUETERNAL.Label.${key}`),
|
||||||
id: key,
|
id: key,
|
||||||
info1: this.#showValue() ? { text: tooltip.content } : null,
|
info1: this.#showValue() ? { text: tooltip.content } : null,
|
||||||
tooltip,
|
tooltip,
|
||||||
@@ -67,7 +68,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
await this.addActions(actions, {
|
await this.addActions(actions, {
|
||||||
id: 'attributes',
|
id: 'characteristics',
|
||||||
type: 'system'
|
type: 'system'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -80,17 +81,17 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
direction: 'LEFT'
|
direction: 'LEFT'
|
||||||
}
|
}
|
||||||
actions.push({
|
actions.push({
|
||||||
name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.Luck'),
|
name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.luck'),
|
||||||
id: 'luck',
|
id: 'luck',
|
||||||
info1: this.#showValue() ? { text: '50' } : null,
|
info1: this.#showValue() ? { text: '50' } : null,
|
||||||
tooltip,
|
tooltip,
|
||||||
encodedValue: ['attributes', 'luck'].join(this.delimiter)
|
encodedValue: ['characteristics', 'luck'].join(this.delimiter)
|
||||||
})
|
})
|
||||||
await this.addActions(actions, { id: 'luck', type: 'system' })
|
await this.addActions(actions, { id: 'luck', type: 'system' })
|
||||||
}
|
}
|
||||||
|
|
||||||
async buildOther() {
|
async buildOther() {
|
||||||
if (typeof this.actor.system.sanity.value !== 'undefined') {
|
if (typeof this.actor.system?.san?.value !== 'undefined') {
|
||||||
const actions = []
|
const actions = []
|
||||||
const groupData = {
|
const groupData = {
|
||||||
id: 'other_sanity',
|
id: 'other_sanity',
|
||||||
@@ -99,7 +100,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
}
|
}
|
||||||
this.addGroup(groupData, { id: 'other', type: 'system' }, true)
|
this.addGroup(groupData, { id: 'other', type: 'system' }, true)
|
||||||
const tooltip = {
|
const tooltip = {
|
||||||
content: String(this.actor.system.san.value + '/' + this.actor.system.san.max),
|
content: `${this.actor.system.san.value}/${this.actor.system.san.max}`,
|
||||||
class: 'tah-system-tooltip',
|
class: 'tah-system-tooltip',
|
||||||
direction: 'LEFT'
|
direction: 'LEFT'
|
||||||
}
|
}
|
||||||
@@ -108,17 +109,19 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
id: 'sanity',
|
id: 'sanity',
|
||||||
info1: this.#showValue() ? { text: tooltip.content } : null,
|
info1: this.#showValue() ? { text: tooltip.content } : null,
|
||||||
tooltip,
|
tooltip,
|
||||||
encodedValue: ['attributes', 'sanity'].join(this.delimiter)
|
encodedValue: ['characteristics', 'sanity'].join(this.delimiter)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '+',
|
name: '+',
|
||||||
id: 'sanity_add',
|
id: 'sanity_add',
|
||||||
encodedValue: ['attributes', 'sanity_add'].join(this.delimiter)
|
tooltip,
|
||||||
|
encodedValue: ['characteristics', 'sanity_add'].join(this.delimiter)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '-',
|
name: '-',
|
||||||
id: 'sanity_subtract',
|
id: 'sanity_subtract',
|
||||||
encodedValue: ['attributes', 'sanity_subtract'].join(this.delimiter)
|
tooltip,
|
||||||
|
encodedValue: ['characteristics', 'sanity_subtract'].join(this.delimiter)
|
||||||
})
|
})
|
||||||
await this.addActions(actions, { id: 'other_sanity', type: 'system' })
|
await this.addActions(actions, { id: 'other_sanity', type: 'system' })
|
||||||
}
|
}
|
||||||
@@ -131,7 +134,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
}
|
}
|
||||||
this.addGroup(groupData, { id: 'other', type: 'system' }, true)
|
this.addGroup(groupData, { id: 'other', type: 'system' }, true)
|
||||||
const tooltip = {
|
const tooltip = {
|
||||||
content: String(this.actor.system.hp.value + '/' + this.actor.system.hp.max),
|
content: `${this.actor.system.hp.value}/${this.actor.system.hp.max}`,
|
||||||
class: 'tah-system-tooltip',
|
class: 'tah-system-tooltip',
|
||||||
direction: 'LEFT'
|
direction: 'LEFT'
|
||||||
}
|
}
|
||||||
@@ -140,17 +143,19 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
id: 'health',
|
id: 'health',
|
||||||
info1: this.#showValue() ? { text: tooltip.content } : null,
|
info1: this.#showValue() ? { text: tooltip.content } : null,
|
||||||
tooltip,
|
tooltip,
|
||||||
encodedValue: ['attributes', 'health'].join(this.delimiter)
|
encodedValue: ['characteristics', 'health'].join(this.delimiter)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '+',
|
name: '+',
|
||||||
id: 'health_add',
|
id: 'health_add',
|
||||||
encodedValue: ['attributes', 'health_add'].join(this.delimiter)
|
tooltip,
|
||||||
|
encodedValue: ['characteristics', 'health_add'].join(this.delimiter)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '-',
|
name: '-',
|
||||||
id: 'health_subtract',
|
id: 'health_subtract',
|
||||||
encodedValue: ['attributes', 'health_subtract'].join(this.delimiter)
|
tooltip,
|
||||||
|
encodedValue: ['characteristics', 'health_subtract'].join(this.delimiter)
|
||||||
})
|
})
|
||||||
await this.addActions(actions, { id: 'other_health', type: 'system' })
|
await this.addActions(actions, { id: 'other_health', type: 'system' })
|
||||||
}
|
}
|
||||||
@@ -163,7 +168,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
}
|
}
|
||||||
this.addGroup(groupData, { id: 'other', type: 'system' }, true)
|
this.addGroup(groupData, { id: 'other', type: 'system' }, true)
|
||||||
const tooltip = {
|
const tooltip = {
|
||||||
content: String(this.actor.system.wp.value + '/' + this.actor.system.wp.max),
|
content: `${this.actor.system.wp.value}/${this.actor.system.wp.max}`,
|
||||||
class: 'tah-system-tooltip',
|
class: 'tah-system-tooltip',
|
||||||
direction: 'LEFT'
|
direction: 'LEFT'
|
||||||
}
|
}
|
||||||
@@ -172,17 +177,19 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
id: 'wp',
|
id: 'wp',
|
||||||
info1: this.#showValue() ? { text: tooltip.content } : null,
|
info1: this.#showValue() ? { text: tooltip.content } : null,
|
||||||
tooltip,
|
tooltip,
|
||||||
encodedValue: ['attributes', 'wp'].join(this.delimiter)
|
encodedValue: ['characteristics', 'wp'].join(this.delimiter)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '+',
|
name: '+',
|
||||||
id: 'wp_add',
|
id: 'wp_add',
|
||||||
encodedValue: ['attributes', 'wp_add'].join(this.delimiter)
|
tooltip,
|
||||||
|
encodedValue: ['characteristics', 'wp_add'].join(this.delimiter)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '-',
|
name: '-',
|
||||||
id: 'wp_subtract',
|
id: 'wp_subtract',
|
||||||
encodedValue: ['attributes', 'wp_subtract'].join(this.delimiter)
|
tooltip,
|
||||||
|
encodedValue: ['characteristics', 'wp_subtract'].join(this.delimiter)
|
||||||
})
|
})
|
||||||
await this.addActions(actions, { id: 'other_wp', type: 'system' })
|
await this.addActions(actions, { id: 'other_wp', type: 'system' })
|
||||||
}
|
}
|
||||||
@@ -190,19 +197,20 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
|
|
||||||
async buildSkills() {
|
async buildSkills() {
|
||||||
const actions = []
|
const actions = []
|
||||||
let actorSkills = this.actor.items.filter(item => item.type === 'skill')
|
for (const item of this.actor.items) {
|
||||||
for (const skill in actorSkills) {
|
if (item.type !== 'skill') continue;
|
||||||
if (skill.system.computeScore() > 0) {
|
if (item.type === 'skill' && item.system.skillTotal > 0) {
|
||||||
|
const skill = item
|
||||||
const tooltip = {
|
const tooltip = {
|
||||||
content: String(skill.skill.system.computeScore()),
|
content: String(item.system.skillTotal),
|
||||||
direction: 'LEFT'
|
direction: 'LEFT'
|
||||||
}
|
}
|
||||||
actions.push({
|
actions.push({
|
||||||
name: skill.name,
|
name: `${skill.name} (${skill.system.skillTotal})`,
|
||||||
id: skill.id,
|
id: skill.id,
|
||||||
info1: this.#showValue() ? { text: tooltip.content } : null,
|
info1: this.#showValue() ? { text: tooltip.content } : null,
|
||||||
tooltip,
|
tooltip,
|
||||||
encodedValue: ['skills', s].join(this.delimiter)
|
encodedValue: ['skills', skill.id].join(this.delimiter)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,30 +218,24 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async buildEquipment() {
|
async buildEquipment() {
|
||||||
let weapons = this.actor.items.filter(item => item.type === 'weapon')
|
// const rituals = []
|
||||||
let skills = this.actor.items.filter(item => item.type === 'skill')
|
for (const item of this.actor.items) {
|
||||||
for (const item of weapons) {
|
|
||||||
// Push the weapon name as a new group
|
// Push the weapon name as a new group
|
||||||
const groupData = {
|
const groupData = {
|
||||||
id: 'weapons_' + item._id,
|
id: 'weapons_' + item._id,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
type: 'system'
|
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)
|
this.addGroup(groupData, { id: 'weapons', type: 'system' }, true)
|
||||||
if (item.type === 'weapon') {
|
if (item.type === 'weapon') {
|
||||||
const weapons = []
|
const weapons = []
|
||||||
const tooltip = {
|
const tooltip = {
|
||||||
content: String(skill.system.computeScore()),
|
content: String(item.system.skillTotal),
|
||||||
direction: 'LEFT'
|
direction: 'LEFT'
|
||||||
}
|
}
|
||||||
weapons.push({
|
weapons.push({
|
||||||
name: skill.name,
|
name: item.name,
|
||||||
id: skill._id,
|
id: item._id,
|
||||||
info1: this.#showValue() ? { text: tooltip.content } : null,
|
info1: this.#showValue() ? { text: tooltip.content } : null,
|
||||||
encodedValue: ['weapons', item._id].join(this.delimiter),
|
encodedValue: ['weapons', item._id].join(this.delimiter),
|
||||||
tooltip
|
tooltip
|
||||||
@@ -251,7 +253,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
tooltip: damageTooltip
|
tooltip: damageTooltip
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (item.system.isLethal) {
|
if (item.system.lethality > 0) {
|
||||||
const lethalityTooltip = {
|
const lethalityTooltip = {
|
||||||
content: String(item.system.lethality),
|
content: String(item.system.lethality),
|
||||||
direction: 'LEFT'
|
direction: 'LEFT'
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
/**
|
/**
|
||||||
* Module-based constants
|
* Module-based constants
|
||||||
*/
|
*/
|
||||||
export const SYSTEM = {
|
export const MODULE = {
|
||||||
ID: 'fvtt-cthulhu-eternal'
|
ID: 'token-action-hud-cthulhu-eternal'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Core module
|
* Core module
|
||||||
*/
|
*/
|
||||||
export const CORE_MODULE = {
|
export const CORE_MODULE = {
|
||||||
ID: 'token-action-hud-core'
|
ID: 'token-action-hud-core'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,18 +21,19 @@ export const REQUIRED_CORE_MODULE_VERSION = '2.0'
|
|||||||
* Action types
|
* Action types
|
||||||
*/
|
*/
|
||||||
export const ACTION_TYPE = {
|
export const ACTION_TYPE = {
|
||||||
attributes: 'CTHULHUETERNAL.Label.Characteristics',
|
characteristics: 'CTHULHUETERNAL.Label.characteristics',
|
||||||
skills: 'CTHULHUETERNAL.Label.Skill',
|
skills: 'CTHULHUETERNAL.Label.skills',
|
||||||
equipment: 'CTHULHUETERNAL.Label.Gear'
|
equipment: 'CTHULHUETERNAL.Label.gear'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Groups
|
* Groups
|
||||||
*/
|
*/
|
||||||
export const GROUP = {
|
export const GROUP = {
|
||||||
attributes: { id: 'attributes', name: 'CTHULHUETERNAL.Label.Characteristics', type: 'system' },
|
characteristics: { id: 'characteristics', name: 'CTHULHUETERNAL.Label.characteristics', type: 'system' },
|
||||||
luck: { id: 'luck', name: 'CTHULHUETERNAL.Label.Luck', type: 'system'},
|
luck: { id: 'luck', name: 'CTHULHUETERNAL.Label.luck', type: 'system' },
|
||||||
skills: { id: 'skills', name: 'CTHULHUETERNAL.Label.Skills', type: 'system' },
|
other: { id: 'other', name: 'CTHULHUETERNAL.Label.other', type: 'system' },
|
||||||
weapons: { id: 'weapons', name: 'CTHULHUETERNAL.Label.Weapons', type: 'system' },
|
skills: { id: 'skills', name: 'CTHULHUETERNAL.Label.skills', type: 'system' },
|
||||||
rituals: { id: 'rituals', name: 'CTHULHUETERNAL.Label.Rituals', type: 'system' }
|
weapons: { id: 'weapons', name: 'CTHULHUETERNAL.Label.weapons', type: 'system' },
|
||||||
|
rituals: { id: 'rituals', name: 'CTHULHUETERNAL.Label.rituals', type: 'system' }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,44 +6,42 @@ import { GROUP } from './constants.js'
|
|||||||
export let DEFAULTS = null
|
export let DEFAULTS = null
|
||||||
|
|
||||||
Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
||||||
const groups = GROUP
|
const groups = GROUP
|
||||||
Object.values(groups).forEach(group => {
|
Object.values(groups).forEach(group => {
|
||||||
group.name = coreModule.api.Utils.i18n(group.name)
|
group.name = coreModule.api.Utils.i18n(group.name)
|
||||||
group.listName = `Group: ${coreModule.api.Utils.i18n(group.listName ?? group.name)}`
|
group.listName = `Group: ${coreModule.api.Utils.i18n(group.listName ?? group.name)}`
|
||||||
})
|
})
|
||||||
const groupsArray = Object.values(groups)
|
const groupsArray = Object.values(groups)
|
||||||
DEFAULTS = {
|
DEFAULTS = {
|
||||||
layout: [
|
layout: [
|
||||||
{
|
{
|
||||||
nestId: 'statistics',
|
nestId: 'statistics',
|
||||||
id: 'statistics',
|
id: 'statistics',
|
||||||
name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.Characteristics'),
|
name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.characteristics'),
|
||||||
groups: [
|
groups: [
|
||||||
{ ...groups.attributes, nestId: 'statistics_attributes' },
|
{ ...groups.characteristics, nestId: 'statistics_characteristics' },
|
||||||
{ ...groups.other, nestId: 'statistics_other' },
|
{ ...groups.other, nestId: 'statistics_other' },
|
||||||
{ ...groups.luck, nestId: 'statistics_luck' }
|
{ ...groups.luck, nestId: 'statistics_luck' }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
nestId: 'skills',
|
nestId: 'skills',
|
||||||
id: 'skills',
|
id: 'skills',
|
||||||
name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.Skills'),
|
name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.skills'),
|
||||||
groups: [
|
groups: [
|
||||||
{ ...groups.skills, nestId: 'skills_skills' },
|
{ ...groups.skills, nestId: 'skills_skills' }
|
||||||
{ ...groups.typedSkills, nestId: 'skills_typed' },
|
]
|
||||||
{ ...groups.specialTraining, nestId: 'skills_special' }
|
},
|
||||||
]
|
{
|
||||||
},
|
nestId: 'equipment',
|
||||||
{
|
id: 'equipment',
|
||||||
nestId: 'equipment',
|
name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.gear'),
|
||||||
id: 'equipment',
|
groups: [
|
||||||
name: coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.Gear'),
|
{ ...groups.weapons, nestId: 'equipment_weapons' },
|
||||||
groups: [
|
{ ...groups.rituals, nestId: 'equipment_rituals' }
|
||||||
{ ...groups.weapons, nestId: 'equipment_weapons' },
|
]
|
||||||
{ ...groups.rituals, nestId: 'equipment_rituals' }
|
}
|
||||||
]
|
],
|
||||||
}
|
groups: groupsArray
|
||||||
],
|
}
|
||||||
groups: groupsArray
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|||||||
14
module/applications/hud/init.js
Normal file
14
module/applications/hud/init.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { SystemManager } from './system-manager.js'
|
||||||
|
import { MODULE, REQUIRED_CORE_MODULE_VERSION } from './constants.js'
|
||||||
|
|
||||||
|
Hooks.on('tokenActionHudCoreApiReady', async () => {
|
||||||
|
/**
|
||||||
|
* Return the SystemManager and requiredCoreModuleVersion to Token Action HUD Core
|
||||||
|
*/
|
||||||
|
const module = game.modules.get(MODULE.ID)
|
||||||
|
module.api = {
|
||||||
|
requiredCoreModuleVersion: REQUIRED_CORE_MODULE_VERSION,
|
||||||
|
SystemManager
|
||||||
|
}
|
||||||
|
Hooks.call('tokenActionHudSystemReady', module)
|
||||||
|
})
|
||||||
@@ -1,304 +1,258 @@
|
|||||||
|
|
||||||
import { SYSTEM } from "../../config/system.mjs"
|
import { SYSTEM } from "../../config/system.mjs"
|
||||||
import CthulhuEternalRoll from '../../documents/roll.mjs'
|
|
||||||
|
|
||||||
export let RollHandler = null
|
export let RollHandler = null
|
||||||
|
|
||||||
Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
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 {
|
||||||
/**
|
/**
|
||||||
* Extends Token Action HUD Core's RollHandler class and handles action events triggered when an action is clicked
|
* 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
|
||||||
*/
|
*/
|
||||||
RollHandler = class RollHandler extends coreModule.api.RollHandler {
|
async handleActionClick(event, encodedValue) {
|
||||||
/**
|
const [actionTypeId, actionId] = encodedValue.split('|')
|
||||||
* 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']
|
const knownCharacters = ['protagonist', 'creature']
|
||||||
|
|
||||||
// If single actor is selected
|
// If single actor is selected
|
||||||
if (this.actor) {
|
if (this.actor) {
|
||||||
await this.#handleAction(event, this.actor, this.token, actionTypeId, actionId)
|
await this.#handleAction(event, this.actor, this.token, actionTypeId, actionId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const controlledTokens = canvas.tokens.controlled
|
const controlledTokens = canvas.tokens.controlled
|
||||||
.filter((token) => knownCharacters.includes(token.actor?.type))
|
.filter((token) => knownCharacters.includes(token.actor?.type))
|
||||||
|
|
||||||
// If multiple actors are selected
|
// If multiple actors are selected
|
||||||
for (const token of controlledTokens) {
|
for (const token of controlledTokens) {
|
||||||
const actor = token.actor
|
const actor = token.actor
|
||||||
await this.#handleAction(event, actor, token, actionTypeId, actionId)
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 '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.items.find(i => i.type === 'skill' && i.id === actionId)
|
||||||
|
if (!skill) return ui.notifications.warn('Bad skill name in HUD.')
|
||||||
|
|
||||||
|
/** TO FIX
|
||||||
|
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
|
||||||
|
}
|
||||||
|
/* TO FIX
|
||||||
|
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
|
||||||
|
}
|
||||||
|
/* TOFIX
|
||||||
|
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
|
||||||
|
}
|
||||||
|
/* TOFIX
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
9
module/applications/hud/settings.js
Normal file
9
module/applications/hud/settings.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { MODULE } from './constants.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register module settings
|
||||||
|
* Called by Token Action HUD Core to register Token Action HUD system module settings
|
||||||
|
* @param {function} coreUpdate Token Action HUD Core update function
|
||||||
|
*/
|
||||||
|
export function register (coreUpdate) {
|
||||||
|
}
|
||||||
@@ -1,91 +1,92 @@
|
|||||||
// System Module Imports
|
// System Module Imports
|
||||||
import { ActionHandler } from './action-handler.js'
|
import { ActionHandler } from './action-handler.js'
|
||||||
import { RollHandler as Core } from './roll-handler.js'
|
import { RollHandler as Core } from './roll-handler.js'
|
||||||
import { SYSTEM } from './constants.js'
|
import { MODULE } from './constants.js'
|
||||||
import { DEFAULTS } from './defaults.js'
|
import { DEFAULTS } from './defaults.js'
|
||||||
|
import * as systemSettings from './settings.js'
|
||||||
|
|
||||||
export let SystemManager = null
|
export let SystemManager = null
|
||||||
|
|
||||||
Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
||||||
|
/**
|
||||||
|
* Extends Token Action HUD Core's SystemManager class
|
||||||
|
*/
|
||||||
|
SystemManager = class SystemManager extends coreModule.api.SystemManager {
|
||||||
/**
|
/**
|
||||||
* Extends Token Action HUD Core's SystemManager class
|
* Returns an instance of the ActionHandler to Token Action HUD Core
|
||||||
|
* Called by Token Action HUD Core
|
||||||
|
* @override
|
||||||
|
* @returns {class} The ActionHandler instance
|
||||||
*/
|
*/
|
||||||
SystemManager = class SystemManager extends coreModule.api.SystemManager {
|
getActionHandler() {
|
||||||
/**
|
return new ActionHandler()
|
||||||
* 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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: MODULE.ID, // The module ID
|
||||||
|
name: 'Template Style' // The name to display in the Token Action HUD Core 'Style' module setting
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,22 +1,7 @@
|
|||||||
import { SYSTEM } from './constants.js'
|
import { MODULE } from './constants.js'
|
||||||
|
|
||||||
export let Utils = null
|
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) => {
|
Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
||||||
/**
|
/**
|
||||||
* Utility functions
|
* Utility functions
|
||||||
@@ -31,7 +16,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
static getSetting(key, defaultValue = null) {
|
static getSetting(key, defaultValue = null) {
|
||||||
let value = defaultValue ?? null
|
let value = defaultValue ?? null
|
||||||
try {
|
try {
|
||||||
value = game.settings.get(SYSTEM.ID, key)
|
value = game.settings.get(MODULE.ID, key)
|
||||||
} catch {
|
} catch {
|
||||||
coreModule.api.Logger.debug(`Setting '${key}' not found`)
|
coreModule.api.Logger.debug(`Setting '${key}' not found`)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ export default class CthulhuEternalItemSheet extends HandlebarsApplicationMixin(
|
|||||||
dragover: this._onDragOver.bind(this),
|
dragover: this._onDragOver.bind(this),
|
||||||
drop: this._onDrop.bind(this),
|
drop: this._onDrop.bind(this),
|
||||||
}
|
}
|
||||||
return new DragDrop(d)
|
return new foundry.applications.ux.DragDrop.implementation(d)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,14 +141,14 @@ export default class CthulhuEternalItemSheet extends HandlebarsApplicationMixin(
|
|||||||
* @param {DragEvent} event The originating DragEvent
|
* @param {DragEvent} event The originating DragEvent
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
_onDragOver(event) {}
|
_onDragOver(event) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback actions which occur when a dragged element is dropped on a target.
|
* Callback actions which occur when a dragged element is dropped on a target.
|
||||||
* @param {DragEvent} event The originating DragEvent
|
* @param {DragEvent} event The originating DragEvent
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
async _onDrop(event) {}
|
async _onDrop(event) { }
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
|
|||||||
@@ -43,167 +43,167 @@ export const INSANITY = {
|
|||||||
|
|
||||||
export const ERA_CSS = {
|
export const ERA_CSS = {
|
||||||
jazz: { primaryFont: "RozhaOne", secondaryFont: "RozhaOne", titleFont: "Broadway", baseFontSize: "0.95rem", titleFontSize: "1.2rem", imgFilter: "brightness(0) saturate(100%) invert(52%) sepia(9%) saturate(2368%) hue-rotate(360deg) brightness(86%) contrast(84%)" },
|
jazz: { primaryFont: "RozhaOne", secondaryFont: "RozhaOne", titleFont: "Broadway", baseFontSize: "0.95rem", titleFontSize: "1.2rem", imgFilter: "brightness(0) saturate(100%) invert(52%) sepia(9%) saturate(2368%) hue-rotate(360deg) brightness(86%) contrast(84%)" },
|
||||||
modern: { primaryFont: "Georama", secondaryFont: "Georama", titleFont: "Georama", baseFontSize: "1.0rem", titleFontSize: "1.2rem",imgFilter: "brightness(0) saturate(100%) invert(92%) sepia(11%) saturate(1214%) hue-rotate(51deg) brightness(93%) contrast(86%)" },
|
modern: { primaryFont: "Georama", secondaryFont: "Georama", titleFont: "Georama", baseFontSize: "1.0rem", titleFontSize: "1.2rem", imgFilter: "brightness(0) saturate(100%) invert(92%) sepia(11%) saturate(1214%) hue-rotate(51deg) brightness(93%) contrast(86%)" },
|
||||||
future: { primaryFont: "Georama", secondaryFont: "Georama", titleFont: "Seabreed", baseFontSize: "1.0rem", titleFontSize: "2.0rem",imgFilter: "invert(90%) sepia(6%) saturate(1818%) hue-rotate(152deg) brightness(91%) contrast(91%)" },
|
future: { primaryFont: "Georama", secondaryFont: "Georama", titleFont: "Seabreed", baseFontSize: "1.0rem", titleFontSize: "2.0rem", imgFilter: "invert(90%) sepia(6%) saturate(1818%) hue-rotate(152deg) brightness(91%) contrast(91%)" },
|
||||||
victorian: { primaryFont: "Volkhov", secondaryFont: "Volkhov", titleFont: "Excelsior", baseFontSize: "1.0rem", titleFontSize: "1.2rem",imgFilter: "brightness(0) saturate(100%) invert(100%) sepia(59%) saturate(1894%) hue-rotate(337deg) brightness(88%) contrast(98%)" },
|
victorian: { primaryFont: "Volkhov", secondaryFont: "Volkhov", titleFont: "Excelsior", baseFontSize: "1.0rem", titleFontSize: "1.2rem", imgFilter: "brightness(0) saturate(100%) invert(100%) sepia(59%) saturate(1894%) hue-rotate(337deg) brightness(88%) contrast(98%)" },
|
||||||
coldwar: { primaryFont: "Georama", secondaryFont: "Georama", titleFont: "TopSecret", baseFontSize: "0.9rem", titleFontSize: "1.2rem",imgFilter: "brightness(0) saturate(100%) invert(81%) sepia(14%) saturate(2508%) hue-rotate(202deg) brightness(99%) contrast(105%)"},
|
coldwar: { primaryFont: "Georama", secondaryFont: "Georama", titleFont: "TopSecret", baseFontSize: "0.9rem", 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%)" },
|
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: "Skranji", 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%)"},
|
medieval: { primaryFont: "Skranji", 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%)"},
|
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%)"},
|
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%)" },
|
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%)" },
|
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.35rem",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 = {
|
export const RESOURCE_RATING = {
|
||||||
jazz: {
|
jazz: {
|
||||||
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
|
0: { name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets" },
|
||||||
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 700, assets: "CTHULHUETERNAL.Resource.PoorJazz"},
|
4: { name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 700, assets: "CTHULHUETERNAL.Resource.PoorJazz" },
|
||||||
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 3000, assets: "CTHULHUETERNAL.Resource.AverageJazz"},
|
8: { name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 3000, assets: "CTHULHUETERNAL.Resource.AverageJazz" },
|
||||||
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 5000, assets: "CTHULHUETERNAL.Resource.AboveAverageJazz"},
|
12: { name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 5000, assets: "CTHULHUETERNAL.Resource.AboveAverageJazz" },
|
||||||
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 10000, assets: "CTHULHUETERNAL.Resource.WellOffJazz"},
|
16: { name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 10000, assets: "CTHULHUETERNAL.Resource.WellOffJazz" },
|
||||||
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 15000, assets: "CTHULHUETERNAL.Resource.RichJazz"},
|
18: { name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 15000, assets: "CTHULHUETERNAL.Resource.RichJazz" },
|
||||||
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 50000, assets: "CTHULHUETERNAL.Resource.VeryRichJazz"},
|
19: { name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 50000, assets: "CTHULHUETERNAL.Resource.VeryRichJazz" },
|
||||||
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 100000, assets: "CTHULHUETERNAL.Resource.SuperRichJazz"}
|
20: { name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 100000, assets: "CTHULHUETERNAL.Resource.SuperRichJazz" }
|
||||||
},
|
},
|
||||||
modern: {
|
modern: {
|
||||||
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
|
0: { name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets" },
|
||||||
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorModern"},
|
4: { name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorModern" },
|
||||||
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageModern"},
|
8: { name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageModern" },
|
||||||
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageModern"},
|
12: { name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageModern" },
|
||||||
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffModern"},
|
16: { name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffModern" },
|
||||||
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 20000, assets: "CTHULHUETERNAL.Resource.RichModern"},
|
18: { name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 20000, assets: "CTHULHUETERNAL.Resource.RichModern" },
|
||||||
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichModern"},
|
19: { name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichModern" },
|
||||||
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichModern"}
|
20: { name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichModern" }
|
||||||
},
|
},
|
||||||
future: {
|
future: {
|
||||||
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
|
0: { name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets" },
|
||||||
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorModern"},
|
4: { name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorModern" },
|
||||||
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageModern"},
|
8: { name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageModern" },
|
||||||
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageModern"},
|
12: { name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageModern" },
|
||||||
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffModern"},
|
16: { name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffModern" },
|
||||||
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 20000, assets: "CTHULHUETERNAL.Resource.RichModern"},
|
18: { name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 20000, assets: "CTHULHUETERNAL.Resource.RichModern" },
|
||||||
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichModern"},
|
19: { name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichModern" },
|
||||||
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichModern"}
|
20: { name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichModern" }
|
||||||
},
|
},
|
||||||
coldwar: {
|
coldwar: {
|
||||||
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
|
0: { name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets" },
|
||||||
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
|
4: { name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar" },
|
||||||
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
|
8: { name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar" },
|
||||||
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
|
12: { name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar" },
|
||||||
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
|
16: { name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar" },
|
||||||
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
|
18: { name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar" },
|
||||||
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
|
19: { name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar" },
|
||||||
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
|
20: { name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar" }
|
||||||
},
|
},
|
||||||
ww1: {
|
ww1: {
|
||||||
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
|
0: { name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets" },
|
||||||
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
|
4: { name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar" },
|
||||||
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
|
8: { name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar" },
|
||||||
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
|
12: { name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar" },
|
||||||
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
|
16: { name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar" },
|
||||||
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
|
18: { name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar" },
|
||||||
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
|
19: { name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar" },
|
||||||
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
|
20: { name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar" }
|
||||||
},
|
},
|
||||||
ww2: {
|
ww2: {
|
||||||
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
|
0: { name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets" },
|
||||||
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
|
4: { name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar" },
|
||||||
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
|
8: { name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar" },
|
||||||
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
|
12: { name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar" },
|
||||||
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
|
16: { name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar" },
|
||||||
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
|
18: { name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar" },
|
||||||
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
|
19: { name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar" },
|
||||||
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
|
20: { name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar" }
|
||||||
},
|
},
|
||||||
medieval: {
|
medieval: {
|
||||||
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
|
0: { name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets" },
|
||||||
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
|
4: { name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar" },
|
||||||
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
|
8: { name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar" },
|
||||||
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
|
12: { name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar" },
|
||||||
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
|
16: { name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar" },
|
||||||
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
|
18: { name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar" },
|
||||||
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
|
19: { name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar" },
|
||||||
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
|
20: { name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar" }
|
||||||
},
|
},
|
||||||
revolution: {
|
revolution: {
|
||||||
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
|
0: { name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets" },
|
||||||
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
|
4: { name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar" },
|
||||||
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
|
8: { name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar" },
|
||||||
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
|
12: { name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar" },
|
||||||
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
|
16: { name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar" },
|
||||||
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
|
18: { name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar" },
|
||||||
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
|
19: { name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar" },
|
||||||
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
|
20: { name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar" }
|
||||||
},
|
},
|
||||||
ageofsail: {
|
ageofsail: {
|
||||||
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
|
0: { name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets" },
|
||||||
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
|
4: { name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar" },
|
||||||
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
|
8: { name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar" },
|
||||||
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
|
12: { name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar" },
|
||||||
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
|
16: { name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar" },
|
||||||
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
|
18: { name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar" },
|
||||||
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
|
19: { name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar" },
|
||||||
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
|
20: { name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar" }
|
||||||
},
|
},
|
||||||
classical: {
|
classical: {
|
||||||
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
|
0: { name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets" },
|
||||||
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
|
4: { name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar" },
|
||||||
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
|
8: { name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar" },
|
||||||
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
|
12: { name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar" },
|
||||||
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
|
16: { name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar" },
|
||||||
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
|
18: { name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar" },
|
||||||
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
|
19: { name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar" },
|
||||||
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
|
20: { name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar" }
|
||||||
},
|
},
|
||||||
postapo: {
|
postapo: {
|
||||||
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
|
0: { name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets" },
|
||||||
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar"},
|
4: { name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 20000, assets: "CTHULHUETERNAL.Resource.PoorColdWar" },
|
||||||
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar"},
|
8: { name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 50000, assets: "CTHULHUETERNAL.Resource.AverageColdWar" },
|
||||||
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar"},
|
12: { name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 100000, assets: "CTHULHUETERNAL.Resource.AboveAverageColdWar" },
|
||||||
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar"},
|
16: { name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 150000, assets: "CTHULHUETERNAL.Resource.WellOffColdWar" },
|
||||||
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar"},
|
18: { name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 200000, assets: "CTHULHUETERNAL.Resource.RichColdWar" },
|
||||||
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar"},
|
19: { name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 500000, assets: "CTHULHUETERNAL.Resource.VeryRichColdWar" },
|
||||||
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar"}
|
20: { name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 1000000, assets: "CTHULHUETERNAL.Resource.SuperRichColdWar" }
|
||||||
},
|
},
|
||||||
victorian: {
|
victorian: {
|
||||||
0: {name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets"},
|
0: { name: "Penury", description: "CTHULHUETERNAL.Resource.Penury", income: 0, assets: "CTHULHUETERNAL.Resource.NoAssets" },
|
||||||
4: {name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 30, assets: "CTHULHUETERNAL.Resource.PoorVictorian"},
|
4: { name: "Poor", description: "CTHULHUETERNAL.Resource.Poor", income: 30, assets: "CTHULHUETERNAL.Resource.PoorVictorian" },
|
||||||
8: {name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 90, assets: "CTHULHUETERNAL.Resource.AverageVictorian"},
|
8: { name: "Average", description: "CTHULHUETERNAL.Resource.Average", income: 90, assets: "CTHULHUETERNAL.Resource.AverageVictorian" },
|
||||||
12: {name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 400, assets: "CTHULHUETERNAL.Resource.AboveAverageVictorian"},
|
12: { name: "Above Average", description: "CTHULHUETERNAL.Resource.AboveAverage", income: 400, assets: "CTHULHUETERNAL.Resource.AboveAverageVictorian" },
|
||||||
16: {name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 1500, assets: "CTHULHUETERNAL.Resource.WellOffVictorian"},
|
16: { name: "Well Off", description: "CTHULHUETERNAL.Resource.WellOff", income: 1500, assets: "CTHULHUETERNAL.Resource.WellOffVictorian" },
|
||||||
18: {name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 5000, assets: "CTHULHUETERNAL.Resource.RichVictorian"},
|
18: { name: "Rich", description: "CTHULHUETERNAL.Resource.Rich", income: 5000, assets: "CTHULHUETERNAL.Resource.RichVictorian" },
|
||||||
19: {name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 40000, assets: "CTHULHUETERNAL.Resource.VeryRichVictorian"},
|
19: { name: "Very Rich", description: "CTHULHUETERNAL.Resource.VeryRich", income: 40000, assets: "CTHULHUETERNAL.Resource.VeryRichVictorian" },
|
||||||
20: {name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 200000, assets: "CTHULHUETERNAL.Resource.SuperRichVictorian"}
|
20: { name: "Super Rich", description: "CTHULHUETERNAL.Resource.SuperRich", income: 200000, assets: "CTHULHUETERNAL.Resource.SuperRichVictorian" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RESOURCE_BREAKDOWN = [
|
export const RESOURCE_BREAKDOWN = [
|
||||||
{ value: 0, hand: 0, stowed: 0, storage: 0, checks: 0},
|
{ value: 0, hand: 0, stowed: 0, storage: 0, checks: 0 },
|
||||||
{ value: 1, hand: 1, stowed: 0, storage: 0, checks: 1},
|
{ value: 1, hand: 1, stowed: 0, storage: 0, checks: 1 },
|
||||||
{ value: 2, hand: 2, stowed: 0, storage: 0, checks: 1},
|
{ value: 2, hand: 2, stowed: 0, storage: 0, checks: 1 },
|
||||||
{ value: 3, hand: 3, stowed: 0, storage: 0, checks: 1},
|
{ value: 3, hand: 3, stowed: 0, storage: 0, checks: 1 },
|
||||||
{ value: 4, hand: 4, stowed: 0, storage: 0, checks: 1},
|
{ value: 4, hand: 4, stowed: 0, storage: 0, checks: 1 },
|
||||||
{ value: 5, hand: 5, stowed: 0, storage: 0, checks: 1},
|
{ value: 5, hand: 5, stowed: 0, storage: 0, checks: 1 },
|
||||||
{ value: 6, hand: 6, stowed: 0, storage: 0, checks: 1},
|
{ value: 6, hand: 6, stowed: 0, storage: 0, checks: 1 },
|
||||||
{ value: 7, hand: 6, stowed: 1, storage: 0, checks: 2},
|
{ value: 7, hand: 6, stowed: 1, storage: 0, checks: 2 },
|
||||||
{ value: 8, hand: 6, stowed: 2, storage: 0, checks: 2},
|
{ value: 8, hand: 6, stowed: 2, storage: 0, checks: 2 },
|
||||||
{ value: 9, hand: 6, stowed: 3, storage: 0, checks: 2},
|
{ value: 9, hand: 6, stowed: 3, storage: 0, checks: 2 },
|
||||||
{ value: 10, hand: 6, stowed: 4, storage: 0, checks: 2},
|
{ value: 10, hand: 6, stowed: 4, storage: 0, checks: 2 },
|
||||||
{ value: 11, hand: 6, stowed: 5, storage: 0, checks: 2},
|
{ value: 11, hand: 6, stowed: 5, storage: 0, checks: 2 },
|
||||||
{ value: 12, hand: 6, stowed: 6, storage: 0, checks: 2},
|
{ value: 12, hand: 6, stowed: 6, storage: 0, checks: 2 },
|
||||||
{ value: 13, hand: 6, stowed: 6, storage: 1, checks: 3},
|
{ value: 13, hand: 6, stowed: 6, storage: 1, checks: 3 },
|
||||||
{ value: 14, hand: 6, stowed: 6, storage: 2, checks: 3},
|
{ value: 14, hand: 6, stowed: 6, storage: 2, checks: 3 },
|
||||||
{ value: 15, hand: 6, stowed: 6, storage: 3, checks: 3},
|
{ value: 15, hand: 6, stowed: 6, storage: 3, checks: 3 },
|
||||||
{ value: 16, hand: 6, stowed: 6, storage: 4, checks: 3},
|
{ value: 16, hand: 6, stowed: 6, storage: 4, checks: 3 },
|
||||||
{ value: 17, hand: 6, stowed: 6, storage: 5, checks: 3},
|
{ value: 17, hand: 6, stowed: 6, storage: 5, checks: 3 },
|
||||||
{ value: 18, hand: 6, stowed: 6, storage: 6, checks: 3},
|
{ value: 18, hand: 6, stowed: 6, storage: 6, checks: 3 },
|
||||||
{ value: 19, hand: 6, stowed: 6, storage: 7, checks: 3},
|
{ value: 19, hand: 6, stowed: 6, storage: 7, checks: 3 },
|
||||||
{ value: 20, hand: 6, stowed: 6, storage: 8, checks: 3}
|
{ value: 20, hand: 6, stowed: 6, storage: 8, checks: 3 }
|
||||||
]
|
]
|
||||||
|
|
||||||
export const DAMAGE_BONUS = [ -2, -2, -2, -2, -2, -1, -1, -1, -1, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2]
|
export const DAMAGE_BONUS = [-2, -2, -2, -2, -2, -1, -1, -1, -1, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2]
|
||||||
|
|
||||||
export const VEHICLE_SPEED = {
|
export const VEHICLE_SPEED = {
|
||||||
"none": "CTHULHUETERNAL.Label.None",
|
"none": "CTHULHUETERNAL.Label.None",
|
||||||
@@ -330,10 +330,10 @@ export const MULTIPLIER_CHOICES = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const WEAPON_SELECTIVE_FIRE_CHOICES = {
|
export const WEAPON_SELECTIVE_FIRE_CHOICES = {
|
||||||
"shortburst": { id: "shortburst", label: "CTHULHUETERNAL.Weapon.SelectiveFire.shortburst", ammoUsed: 3, lethality: 10, killRadius: 0},
|
"shortburst": { id: "shortburst", label: "CTHULHUETERNAL.Weapon.SelectiveFire.shortburst", ammoUsed: 3, lethality: 10, killRadius: 0 },
|
||||||
"longburst": { id: "longburst", label: "CTHULHUETERNAL.Weapon.SelectiveFire.longburst", ammoUsed: 5, lethality: 10, killRadius: 1},
|
"longburst": { id: "longburst", label: "CTHULHUETERNAL.Weapon.SelectiveFire.longburst", ammoUsed: 5, lethality: 10, killRadius: 1 },
|
||||||
"shortspray": { id: "shortspray", label: "CTHULHUETERNAL.Weapon.SelectiveFire.shortspray", ammoUsed: 10, lethality: 10, killRadius: 2},
|
"shortspray": { id: "shortspray", label: "CTHULHUETERNAL.Weapon.SelectiveFire.shortspray", ammoUsed: 10, lethality: 10, killRadius: 2 },
|
||||||
"longspray": { id: "longspray", label: "CTHULHUETERNAL.Weapon.SelectiveFire.longspray", ammoUsed: 20, lethality: 10, killRadius: 3},
|
"longspray": { id: "longspray", label: "CTHULHUETERNAL.Weapon.SelectiveFire.longspray", ammoUsed: 20, lethality: 10, killRadius: 3 },
|
||||||
}
|
}
|
||||||
|
|
||||||
// Melee stuff
|
// Melee stuff
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ export default class CthulhuEternalActor extends Actor {
|
|||||||
if (this.system.hp.value !== hp) {
|
if (this.system.hp.value !== hp) {
|
||||||
this.update({ "system.hp.value": hp })
|
this.update({ "system.hp.value": hp })
|
||||||
}
|
}
|
||||||
|
console.log("Applying wounds", { woundData, totalArmor, effectiveWounds })
|
||||||
// Chat message for GM only
|
// Chat message for GM only
|
||||||
if (game.user.isGM) {
|
if (game.user.isGM) {
|
||||||
let armorText = totalArmor > 0 ? game.i18n.format("CTHULHUETERNAL.Chat.armorAbsorbed", { armor: totalArmor }) : game.i18n.localize("CTHULHUETERNAL.Chat.noArmor")
|
let armorText = totalArmor > 0 ? game.i18n.format("CTHULHUETERNAL.Chat.armorAbsorbed", { armor: totalArmor }) : game.i18n.localize("CTHULHUETERNAL.Chat.noArmor")
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
let combatants = []
|
let combatants = []
|
||||||
if (game?.combat?.combatants) {
|
if (game?.combat?.combatants) {
|
||||||
for (let c of game.combat.combatants) {
|
for (let c of game.combat.combatants) {
|
||||||
if (c.actor.id !== actor.id) {
|
if (c.actorid !== actor.id) {
|
||||||
combatants.push({ id: c.id, name: c.name })
|
combatants.push({ id: c.id, name: c.name })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,8 +210,8 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
modifier += SYSTEM.WEAPON_VISIBILITY[rollData.visibilityChoice]?.modifier || 0
|
modifier += SYSTEM.WEAPON_VISIBILITY[rollData.visibilityChoice]?.modifier || 0
|
||||||
modifier += SYSTEM.WEAPON_ATTACKER_STATE[rollData.attackerStateChoice]?.modifier || 0
|
modifier += SYSTEM.WEAPON_ATTACKER_STATE[rollData.attackerStateChoice]?.modifier || 0
|
||||||
modifier += SYSTEM.WEAPON_TARGET_SIZE[rollData.targetSizeChoice]?.modifier || 0
|
modifier += SYSTEM.WEAPON_TARGET_SIZE[rollData.targetSizeChoice]?.modifier || 0
|
||||||
modifier += (rollData.aimingLastRound) ? 20 : 0
|
modifier += (rollData.aimingLastRoundFlag) ? 20 : 0
|
||||||
modifier += (rollData.aimingWithSight) ? 20 : 0
|
modifier += (rollData.aimingWithSightFlag) ? 20 : 0
|
||||||
return modifier
|
return modifier
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,9 +298,9 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
console.log("WP Not found", era, options.rollItem.system.weaponType)
|
console.log("WP Not found", era, options.rollItem.system.weaponType)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!target) {
|
/*if (!target) {
|
||||||
ui.notifications.warn(game.i18n.localize("CTHULHUETERNAL.Notifications.AttackNoTarget"))
|
ui.notifications.warn(game.i18n.localize("CTHULHUETERNAL.Notifications.AttackNoTarget"))
|
||||||
}
|
}*/
|
||||||
// Check if the weapon has enouth ammo in case of a firearm
|
// Check if the weapon has enouth ammo in case of a firearm
|
||||||
if (options.rollItem.system.isFireArm() && options.rollItem.system.ammo.value <= 0) {
|
if (options.rollItem.system.isFireArm() && options.rollItem.system.ammo.value <= 0) {
|
||||||
ui.notifications.warn(game.i18n.localize("CTHULHUETERNAL.Notifications.NoAmmo"))
|
ui.notifications.warn(game.i18n.localize("CTHULHUETERNAL.Notifications.NoAmmo"))
|
||||||
@@ -308,20 +308,9 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
}
|
}
|
||||||
options.weapon = options.rollItem
|
options.weapon = options.rollItem
|
||||||
|
|
||||||
if (options.rollItem.system.hasDirectSkill) {
|
options.rollItem = CthulhuEternalUtils.getWeaponSkill(actor, options.rollItem, era)
|
||||||
let skillName = options.rollItem.name
|
options.initialScore = options.rollItem.system.skillTotal
|
||||||
options.rollItem = { type: "skill", name: skillName, system: { base: 0, bonus: options.weapon.system.directSkillValue } }
|
console.log("WEAPON", era, options.rollItem)
|
||||||
options.initialScore = options.weapon.system.directSkillValue
|
|
||||||
} else {
|
|
||||||
let skillName = game.i18n.localize(SYSTEM.WEAPON_SKILL_MAPPING[era][options.rollItem.system.weaponType])
|
|
||||||
options.rollItem = actor.items.find(i => i.type === "skill" && i.name.toLowerCase() === skillName.toLowerCase())
|
|
||||||
if (!options.rollItem) {
|
|
||||||
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.NoWeaponSkill"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
options.initialScore = options.rollItem.system.computeScore()
|
|
||||||
console.log("WEAPON", skillName, era, options.rollItem)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
@@ -374,8 +363,8 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
visibilityChoice: "clear",
|
visibilityChoice: "clear",
|
||||||
attackerStateChoice: "normal",
|
attackerStateChoice: "normal",
|
||||||
targetSizeChoice: "normal",
|
targetSizeChoice: "normal",
|
||||||
aimingLastRound: false,
|
aimingLastRoundFlag: false,
|
||||||
aimingWithSight: false,
|
aimingWithSightFlag: false,
|
||||||
modifier,
|
modifier,
|
||||||
formula,
|
formula,
|
||||||
targetName: target?.name,
|
targetName: target?.name,
|
||||||
@@ -424,6 +413,14 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
options.multiplier = Number(event.target.value)
|
options.multiplier = Number(event.target.value)
|
||||||
this.updateResourceDialog(options)
|
this.updateResourceDialog(options)
|
||||||
})
|
})
|
||||||
|
$(".aimingLastRound").change(event => {
|
||||||
|
options.aimingLastRoundFlag = event.target.checked
|
||||||
|
this.updateResourceDialog(options)
|
||||||
|
})
|
||||||
|
$(".aimingWithSight").change(event => {
|
||||||
|
options.aimingWithSightFlag = event.target.checked
|
||||||
|
this.updateResourceDialog(options)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -526,6 +523,8 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
rollData.isFailure = this.options.isFailure
|
rollData.isFailure = this.options.isFailure
|
||||||
rollData.isCritical = this.options.isCritical
|
rollData.isCritical = this.options.isCritical
|
||||||
rollData.resultType = resultType
|
rollData.resultType = resultType
|
||||||
|
rollData.rollResult = this.total
|
||||||
|
rollData.total = this.total
|
||||||
this.options.rollData = foundry.utils.duplicate(rollData)
|
this.options.rollData = foundry.utils.duplicate(rollData)
|
||||||
|
|
||||||
// Keep track of the last defense roll for the actor
|
// Keep track of the last defense roll for the actor
|
||||||
@@ -553,7 +552,7 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
|
|
||||||
compareRolls(attackRoll, defenseRoll) {
|
compareRolls(attackRoll, defenseRoll) {
|
||||||
if (!defenseRoll || defenseRoll.round !== game?.combat?.round) {
|
if (!defenseRoll || defenseRoll.round !== game?.combat?.round) {
|
||||||
ui.notifications.info(game.i18n.localize("CTHULHUETERNAL.Notifications.NoDefenseRoll"))
|
// ui.notifications.info(game.i18n.localize("CTHULHUETERNAL.Notifications.NoDefenseRoll"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (attackRoll.isFailure) {
|
if (attackRoll.isFailure) {
|
||||||
@@ -677,7 +676,7 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
* @returns {Promise} - A promise that resolves when the message is created.
|
* @returns {Promise} - A promise that resolves when the message is created.
|
||||||
*/
|
*/
|
||||||
async toMessage(messageData = {}, { rollMode, create = true } = {}) {
|
async toMessage(messageData = {}, { rollMode, create = true } = {}) {
|
||||||
super.toMessage(
|
let rollMsg = await super.toMessage(
|
||||||
{
|
{
|
||||||
isFailure: this.resultType === "failure",
|
isFailure: this.resultType === "failure",
|
||||||
actingCharName: this.actorName,
|
actingCharName: this.actorName,
|
||||||
@@ -688,10 +687,11 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
},
|
},
|
||||||
{ rollMode: rollMode },
|
{ rollMode: rollMode },
|
||||||
)
|
)
|
||||||
|
|
||||||
// Manage the skill evolution if the roll is a failure
|
|
||||||
let rollData = this.options.rollData || this.options
|
let rollData = this.options.rollData || this.options
|
||||||
let rollItem = this.options.rollItem
|
let rollItem = this.options.rollItem
|
||||||
|
await rollMsg.setFlag("fvtt-cthulhu-eternal", "rollData", rollData)
|
||||||
|
|
||||||
|
// Manage the skill evolution if the roll is a failure
|
||||||
if (rollData.resultType.includes("failure") && rollItem.type === "skill") {
|
if (rollData.resultType.includes("failure") && rollItem.type === "skill") {
|
||||||
// Is the skill able to progress
|
// Is the skill able to progress
|
||||||
if (rollItem.system.diceEvolved && !rollItem.system.rollFailed) {
|
if (rollItem.system.diceEvolved && !rollItem.system.rollFailed) {
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
|
|||||||
insanity: new fields.StringField({ required: true, nullable: false, initial: "none", choices: SYSTEM.INSANITY }),
|
insanity: new fields.StringField({ required: true, nullable: false, initial: "none", choices: SYSTEM.INSANITY }),
|
||||||
})
|
})
|
||||||
|
|
||||||
schema.damageBonus = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
schema.damageBonus = new fields.NumberField({ ...requiredInteger, initial: 0, min: -2 })
|
||||||
|
|
||||||
schema.resources = new fields.SchemaField({
|
schema.resources = new fields.SchemaField({
|
||||||
value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), // Unused but kept for compatibility
|
value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), // Unused but kept for compatibility
|
||||||
@@ -129,7 +129,7 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
|
|||||||
dmgBonus = -1
|
dmgBonus = -1
|
||||||
} else if (this.characteristics.str.value <= 16) {
|
} else if (this.characteristics.str.value <= 16) {
|
||||||
dmgBonus = 1
|
dmgBonus = 1
|
||||||
} else if (this.characteristics.str.value <= 20) {
|
} else if (this.characteristics.str.value <= 40) {
|
||||||
dmgBonus = 2
|
dmgBonus = 2
|
||||||
}
|
}
|
||||||
if (this.damageBonus !== dmgBonus) {
|
if (this.damageBonus !== dmgBonus) {
|
||||||
|
|||||||
192
module/utils.mjs
192
module/utils.mjs
@@ -16,6 +16,14 @@ export default class CthulhuEternalUtils {
|
|||||||
config: true,
|
config: true,
|
||||||
onChange: _ => window.location.reload()
|
onChange: _ => window.location.reload()
|
||||||
});
|
});
|
||||||
|
game.settings.register("fvtt-cthulhu-eternal", "roll-opposed-store", {
|
||||||
|
name: "Roll Opposed Store",
|
||||||
|
hint: "Whether to store opposed roll results for later use",
|
||||||
|
default: { roll1: null, roll2: null },
|
||||||
|
scope: "world",
|
||||||
|
type: Object,
|
||||||
|
config: false
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static async loadCompendiumData(compendium) {
|
static async loadCompendiumData(compendium) {
|
||||||
@@ -180,6 +188,53 @@ export default class CthulhuEternalUtils {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static removeChatMessageId(messageId) {
|
||||||
|
if (messageId) {
|
||||||
|
game.messages.get(messageId)?.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static findChatMessageId(current) {
|
||||||
|
return HawkmoonUtility.getChatMessageId(HawkmoonUtility.findChatMessage(current));
|
||||||
|
}
|
||||||
|
|
||||||
|
static getChatMessageId(node) {
|
||||||
|
return node?.attributes.getNamedItem('data-message-id')?.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static findChatMessage(current) {
|
||||||
|
return HawkmoonUtility.findNodeMatching(current, it => it.classList.contains('chat-message') && it.attributes.getNamedItem('data-message-id'))
|
||||||
|
}
|
||||||
|
|
||||||
|
static findNodeMatching(current, predicate) {
|
||||||
|
if (current) {
|
||||||
|
if (predicate(current)) {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
return HawkmoonUtility.findNodeMatching(current.parentElement, predicate);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static getWeaponSkill(actor, weapon, era) {
|
||||||
|
let skill
|
||||||
|
if (weapon.system.hasDirectSkill) {
|
||||||
|
let skillName = weapon.name
|
||||||
|
skill = { type: "skill", name: skillName, system: { base: 0, bonus: weapon.system.directSkillValue, skillTotal: weapon.system.directSkillValue } }
|
||||||
|
} else {
|
||||||
|
let skillName = game.i18n.localize(SYSTEM.WEAPON_SKILL_MAPPING[era][weapon.system.weaponType])
|
||||||
|
skill = actor.items.find(i => i.type === "skill" && i.name.toLowerCase() === skillName.toLowerCase())
|
||||||
|
if (!skill) {
|
||||||
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.NoWeaponSkill"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skill
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
static async applySANType(rollMessage, event) {
|
static async applySANType(rollMessage, event) {
|
||||||
let rollData = rollMessage.getFlag("fvtt-cthulhu-eternal", "rollData")
|
let rollData = rollMessage.getFlag("fvtt-cthulhu-eternal", "rollData")
|
||||||
if (!rollData) {
|
if (!rollData) {
|
||||||
@@ -248,6 +303,134 @@ export default class CthulhuEternalUtils {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async opposedRollManagement(rollMessage, event) {
|
||||||
|
let rollData = rollMessage.getFlag("fvtt-cthulhu-eternal", "rollData")
|
||||||
|
if (!rollData) {
|
||||||
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noRollDataFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the store
|
||||||
|
let store = game.settings.get("fvtt-cthulhu-eternal", "roll-opposed-store")
|
||||||
|
if (!store.roll1) {
|
||||||
|
store.roll1 = {
|
||||||
|
rollData: rollData,
|
||||||
|
messageId: rollMessage.id
|
||||||
|
}
|
||||||
|
await game.settings.set("fvtt-cthulhu-eternal", "roll-opposed-store", store)
|
||||||
|
ui.notifications.info(game.i18n.localize("CTHULHUETERNAL.Notifications.opposedRollFirstStored"))
|
||||||
|
}
|
||||||
|
else if (!store.roll2) {
|
||||||
|
store.roll2 = {
|
||||||
|
rollData: rollData,
|
||||||
|
messageId: rollMessage.id
|
||||||
|
}
|
||||||
|
await game.settings.set("fvtt-cthulhu-eternal", "roll-opposed-store", store)
|
||||||
|
ui.notifications.info(game.i18n.localize("CTHULHUETERNAL.Notifications.opposedRollSecondStored"))
|
||||||
|
// Now perform the opposed roll resolution
|
||||||
|
await this.resolveOpposedRolls(store.roll1, store.roll2)
|
||||||
|
// Clear the store
|
||||||
|
store.roll1 = null
|
||||||
|
store.roll2 = null
|
||||||
|
await game.settings.set("fvtt-cthulhu-eternal", "roll-opposed-store", store)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.opposedRollStoreFull"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async resolveOpposedRolls(roll1, roll2) {
|
||||||
|
// Get actors
|
||||||
|
let actor1 = game.actors.get(roll1.rollData.actorId)
|
||||||
|
let actor2 = game.actors.get(roll2.rollData.actorId)
|
||||||
|
if (!actor1 || !actor2) {
|
||||||
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noActorFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Determine winner
|
||||||
|
let winner = null
|
||||||
|
let loser = null
|
||||||
|
// If there critical success/failure, apply them first (remark : this d100 results)
|
||||||
|
roll1.rollData.rollCompare = roll1.rollData.rollResult
|
||||||
|
roll2.rollData.rollCompare = roll2.rollData.rollResult
|
||||||
|
if (roll1.rollData.resultType === "successCritical") {
|
||||||
|
roll1.rollData.rollCompare = -roll1.rollData.rollResult
|
||||||
|
}
|
||||||
|
if (roll2.rollData.resultType === "failureCritical") {
|
||||||
|
roll2.rollData.rollCompare = 100 + roll2.rollData.rollResult
|
||||||
|
}
|
||||||
|
if (roll2.rollData.resultType === "successCritical") {
|
||||||
|
roll2.rollData.rollCompare = -roll2.rollData.rollResult
|
||||||
|
}
|
||||||
|
if (roll1.rollData.resultType === "failureCritical") {
|
||||||
|
roll1.rollData.rollCompare = roll1.rollData.rollResult * 2
|
||||||
|
}
|
||||||
|
if (roll1.rollData.isSuccess && roll2.rollData.isFailure) {
|
||||||
|
winner = { actor: actor1, rollData: roll1.rollData, messageId: roll1.messageId }
|
||||||
|
loser = { actor: actor2, rollData: roll2.rollData, messageId: roll2.messageId }
|
||||||
|
}
|
||||||
|
else if (roll2.rollData.isSuccess && roll1.rollData.isFailure) {
|
||||||
|
winner = { actor: actor2, rollData: roll2.rollData, messageId: roll2.messageId }
|
||||||
|
loser = { actor: actor1, rollData: roll1.rollData, messageId: roll1.messageId }
|
||||||
|
}
|
||||||
|
else if (roll1.rollData.rollCompare < roll2.rollData.rollCompare) {
|
||||||
|
winner = { actor: actor1, rollData: roll1.rollData, messageId: roll1.messageId }
|
||||||
|
loser = { actor: actor2, rollData: roll2.rollData, messageId: roll2.messageId }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
winner = { actor: actor2, rollData: roll2.rollData, messageId: roll2.messageId }
|
||||||
|
loser = { actor: actor1, rollData: roll1.rollData, messageId: roll1.messageId }
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Opposed roll result", winner, loser)
|
||||||
|
|
||||||
|
// Check if winner was attacking with a weapon that can apply damage
|
||||||
|
let canApplyDamage = winner && winner.rollData?.weapon && winner.rollData.weapon.system
|
||||||
|
|
||||||
|
// Prepare data for the template
|
||||||
|
let msgData = {
|
||||||
|
winner: {
|
||||||
|
actor: {
|
||||||
|
name: winner.actor.name,
|
||||||
|
img: winner.actor.img
|
||||||
|
},
|
||||||
|
rollData: {
|
||||||
|
rollResult: winner.rollData.rollResult || winner.rollData.total,
|
||||||
|
isCritical: winner.rollData.isCritical,
|
||||||
|
weapon: winner.rollData.weapon
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loser: {
|
||||||
|
actor: {
|
||||||
|
name: loser.actor.name,
|
||||||
|
img: loser.actor.img
|
||||||
|
},
|
||||||
|
rollData: {
|
||||||
|
rollResult: loser.rollData.rollResult || loser.rollData.total,
|
||||||
|
isCritical: loser.rollData.isCritical
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canApplyDamage: canApplyDamage
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the template
|
||||||
|
let content = await foundry.applications.handlebars.renderTemplate(
|
||||||
|
"systems/fvtt-cthulhu-eternal/templates/chat-opposed-result.hbs",
|
||||||
|
msgData
|
||||||
|
)
|
||||||
|
|
||||||
|
// Display the result in chat
|
||||||
|
let chatMsg = await ChatMessage.create({
|
||||||
|
speaker: ChatMessage.getSpeaker({ actor: winner.actor.id }),
|
||||||
|
content: content
|
||||||
|
})
|
||||||
|
|
||||||
|
// Store the winner's roll data for damage roll if applicable
|
||||||
|
if (canApplyDamage) {
|
||||||
|
await chatMsg.setFlag("fvtt-cthulhu-eternal", "rollData", winner.rollData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static translateRangeUnit(range) {
|
static translateRangeUnit(range) {
|
||||||
if (typeof range === 'string') {
|
if (typeof range === 'string') {
|
||||||
return game.i18n.localize(`CTHULHUETERNAL.Label.${range}`)
|
return game.i18n.localize(`CTHULHUETERNAL.Label.${range}`)
|
||||||
@@ -285,6 +468,7 @@ export default class CthulhuEternalUtils {
|
|||||||
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Label.noActorFound"))
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Label.noActorFound"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Damage roll data", rollData)
|
console.log("Damage roll data", rollData)
|
||||||
rollData.weapon.resultType = rollData.resultType // Keep the result type from the roll message
|
rollData.weapon.resultType = rollData.resultType // Keep the result type from the roll message
|
||||||
rollData.weapon.selectiveFireChoice = rollData.selectiveFireChoice // Keep the selected fire choice from the roll message
|
rollData.weapon.selectiveFireChoice = rollData.selectiveFireChoice // Keep the selected fire choice from the roll message
|
||||||
@@ -357,6 +541,10 @@ export default class CthulhuEternalUtils {
|
|||||||
roll.toMessage()
|
roll.toMessage()
|
||||||
|
|
||||||
actor.system.modifyWP(-dialogContext.wpCost)
|
actor.system.modifyWP(-dialogContext.wpCost)
|
||||||
|
|
||||||
|
// Delete the initial roll message
|
||||||
|
await rollMessage.delete()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static setupCSSRootVariables() {
|
static setupCSSRootVariables() {
|
||||||
@@ -395,6 +583,10 @@ export default class CthulhuEternalUtils {
|
|||||||
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noActorFound"))
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noActorFound"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
console.log("Applying wounds", woundData)
|
||||||
|
// Remove the chat message
|
||||||
|
this.removeChatMessageId(message.id)
|
||||||
|
|
||||||
// Get the targetted actorId from the HTML select event
|
// Get the targetted actorId from the HTML select event
|
||||||
let targetCombatantId = event.target.value
|
let targetCombatantId = event.target.value
|
||||||
let combatant = game.combat.combatants.get(targetCombatantId)
|
let combatant = game.combat.combatants.get(targetCombatantId)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
MANIFEST-000261
|
MANIFEST-000265
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2025/10/08-22:08:44.664871 7f77151f96c0 Recovering log #259
|
2025/11/12-23:40:11.531092 7f47827fc6c0 Recovering log #263
|
||||||
2025/10/08-22:08:44.675676 7f77151f96c0 Delete type=3 #257
|
2025/11/12-23:40:11.541025 7f47827fc6c0 Delete type=0 #263
|
||||||
2025/10/08-22:08:44.675773 7f77151f96c0 Delete type=0 #259
|
2025/11/12-23:40:11.541091 7f47827fc6c0 Delete type=3 #261
|
||||||
2025/10/08-23:43:02.763720 7f770f3ff6c0 Level-0 table #264: started
|
2025/11/12-23:40:47.861546 7f4780bff6c0 Level-0 table #268: started
|
||||||
2025/10/08-23:43:02.763751 7f770f3ff6c0 Level-0 table #264: 0 bytes OK
|
2025/11/12-23:40:47.861580 7f4780bff6c0 Level-0 table #268: 0 bytes OK
|
||||||
2025/10/08-23:43:02.770330 7f770f3ff6c0 Delete type=0 #262
|
2025/11/12-23:40:47.867844 7f4780bff6c0 Delete type=0 #266
|
||||||
2025/10/08-23:43:02.770574 7f770f3ff6c0 Manual compaction at level-0 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end)
|
2025/11/12-23:40:47.874806 7f4780bff6c0 Manual compaction at level-0 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2025/10/01-17:34:00.770173 7fc4987f86c0 Recovering log #255
|
2025/10/08-22:08:44.664871 7f77151f96c0 Recovering log #259
|
||||||
2025/10/01-17:34:00.786532 7fc4987f86c0 Delete type=3 #253
|
2025/10/08-22:08:44.675676 7f77151f96c0 Delete type=3 #257
|
||||||
2025/10/01-17:34:00.786591 7fc4987f86c0 Delete type=0 #255
|
2025/10/08-22:08:44.675773 7f77151f96c0 Delete type=0 #259
|
||||||
2025/10/01-20:52:25.677932 7fc497ff76c0 Level-0 table #260: started
|
2025/10/08-23:43:02.763720 7f770f3ff6c0 Level-0 table #264: started
|
||||||
2025/10/01-20:52:25.677997 7fc497ff76c0 Level-0 table #260: 0 bytes OK
|
2025/10/08-23:43:02.763751 7f770f3ff6c0 Level-0 table #264: 0 bytes OK
|
||||||
2025/10/01-20:52:26.027584 7fc497ff76c0 Delete type=0 #258
|
2025/10/08-23:43:02.770330 7f770f3ff6c0 Delete type=0 #262
|
||||||
2025/10/01-20:52:26.508239 7fc497ff76c0 Manual compaction at level-0 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end)
|
2025/10/08-23:43:02.770574 7f770f3ff6c0 Manual compaction at level-0 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000430
|
MANIFEST-000434
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2025/10/08-22:08:44.633139 7f77159fa6c0 Recovering log #428
|
2025/11/12-23:40:11.502931 7f4781ffb6c0 Recovering log #432
|
||||||
2025/10/08-22:08:44.643368 7f77159fa6c0 Delete type=3 #426
|
2025/11/12-23:40:11.512928 7f4781ffb6c0 Delete type=0 #432
|
||||||
2025/10/08-22:08:44.643480 7f77159fa6c0 Delete type=0 #428
|
2025/11/12-23:40:11.512984 7f4781ffb6c0 Delete type=3 #430
|
||||||
2025/10/08-23:43:02.756716 7f770f3ff6c0 Level-0 table #433: started
|
2025/11/12-23:40:47.855365 7f4780bff6c0 Level-0 table #437: started
|
||||||
2025/10/08-23:43:02.756789 7f770f3ff6c0 Level-0 table #433: 0 bytes OK
|
2025/11/12-23:40:47.855411 7f4780bff6c0 Level-0 table #437: 0 bytes OK
|
||||||
2025/10/08-23:43:02.763557 7f770f3ff6c0 Delete type=0 #431
|
2025/11/12-23:40:47.861414 7f4780bff6c0 Delete type=0 #435
|
||||||
2025/10/08-23:43:02.770557 7f770f3ff6c0 Manual compaction at level-0 from '!folders!5PrT9QmN1cFPzDFP' @ 72057594037927935 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at (end)
|
2025/11/12-23:40:47.874794 7f4780bff6c0 Manual compaction at level-0 from '!folders!5PrT9QmN1cFPzDFP' @ 72057594037927935 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2025/10/01-17:34:00.727436 7fc499ffb6c0 Recovering log #424
|
2025/10/08-22:08:44.633139 7f77159fa6c0 Recovering log #428
|
||||||
2025/10/01-17:34:00.744993 7fc499ffb6c0 Delete type=3 #422
|
2025/10/08-22:08:44.643368 7f77159fa6c0 Delete type=3 #426
|
||||||
2025/10/01-17:34:00.745065 7fc499ffb6c0 Delete type=0 #424
|
2025/10/08-22:08:44.643480 7f77159fa6c0 Delete type=0 #428
|
||||||
2025/10/01-20:52:26.571766 7fc497ff76c0 Level-0 table #429: started
|
2025/10/08-23:43:02.756716 7f770f3ff6c0 Level-0 table #433: started
|
||||||
2025/10/01-20:52:26.571816 7fc497ff76c0 Level-0 table #429: 0 bytes OK
|
2025/10/08-23:43:02.756789 7f770f3ff6c0 Level-0 table #433: 0 bytes OK
|
||||||
2025/10/01-20:52:26.607301 7fc497ff76c0 Delete type=0 #427
|
2025/10/08-23:43:02.763557 7f770f3ff6c0 Delete type=0 #431
|
||||||
2025/10/01-20:52:26.607477 7fc497ff76c0 Manual compaction at level-0 from '!folders!5PrT9QmN1cFPzDFP' @ 72057594037927935 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at (end)
|
2025/10/08-23:43:02.770557 7f770f3ff6c0 Manual compaction at level-0 from '!folders!5PrT9QmN1cFPzDFP' @ 72057594037927935 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000076
|
MANIFEST-000080
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2025/10/08-22:08:44.648914 7f770ffff6c0 Recovering log #74
|
2025/11/12-23:40:11.517421 7f4782ffd6c0 Recovering log #78
|
||||||
2025/10/08-22:08:44.660220 7f770ffff6c0 Delete type=3 #72
|
2025/11/12-23:40:11.527038 7f4782ffd6c0 Delete type=0 #78
|
||||||
2025/10/08-22:08:44.660388 7f770ffff6c0 Delete type=0 #74
|
2025/11/12-23:40:11.527106 7f4782ffd6c0 Delete type=3 #76
|
||||||
2025/10/08-23:43:02.832863 7f770f3ff6c0 Level-0 table #79: started
|
2025/11/12-23:40:47.867960 7f4780bff6c0 Level-0 table #83: started
|
||||||
2025/10/08-23:43:02.832918 7f770f3ff6c0 Level-0 table #79: 0 bytes OK
|
2025/11/12-23:40:47.867984 7f4780bff6c0 Level-0 table #83: 0 bytes OK
|
||||||
2025/10/08-23:43:02.839997 7f770f3ff6c0 Delete type=0 #77
|
2025/11/12-23:40:47.874660 7f4780bff6c0 Delete type=0 #81
|
||||||
2025/10/08-23:43:02.852551 7f770f3ff6c0 Manual compaction at level-0 from '!folders!0DI3T2jve3nsmsfZ' @ 72057594037927935 : 1 .. '!items!zyxA9DhO36t5OBDv' @ 0 : 0; will stop at (end)
|
2025/11/12-23:40:47.874816 7f4780bff6c0 Manual compaction at level-0 from '!folders!0DI3T2jve3nsmsfZ' @ 72057594037927935 : 1 .. '!items!zyxA9DhO36t5OBDv' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2025/10/01-17:34:00.750882 7fc4997fa6c0 Recovering log #70
|
2025/10/08-22:08:44.648914 7f770ffff6c0 Recovering log #74
|
||||||
2025/10/01-17:34:00.765634 7fc4997fa6c0 Delete type=3 #68
|
2025/10/08-22:08:44.660220 7f770ffff6c0 Delete type=3 #72
|
||||||
2025/10/01-17:34:00.765703 7fc4997fa6c0 Delete type=0 #70
|
2025/10/08-22:08:44.660388 7f770ffff6c0 Delete type=0 #74
|
||||||
2025/10/01-20:52:26.472838 7fc497ff76c0 Level-0 table #75: started
|
2025/10/08-23:43:02.832863 7f770f3ff6c0 Level-0 table #79: started
|
||||||
2025/10/01-20:52:26.472892 7fc497ff76c0 Level-0 table #75: 0 bytes OK
|
2025/10/08-23:43:02.832918 7f770f3ff6c0 Level-0 table #79: 0 bytes OK
|
||||||
2025/10/01-20:52:26.508046 7fc497ff76c0 Delete type=0 #73
|
2025/10/08-23:43:02.839997 7f770f3ff6c0 Delete type=0 #77
|
||||||
2025/10/01-20:52:26.508280 7fc497ff76c0 Manual compaction at level-0 from '!folders!0DI3T2jve3nsmsfZ' @ 72057594037927935 : 1 .. '!items!zyxA9DhO36t5OBDv' @ 0 : 0; will stop at (end)
|
2025/10/08-23:43:02.852551 7f770f3ff6c0 Manual compaction at level-0 from '!folders!0DI3T2jve3nsmsfZ' @ 72057594037927935 : 1 .. '!items!zyxA9DhO36t5OBDv' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
238
styles/roll.less
238
styles/roll.less
@@ -97,21 +97,6 @@
|
|||||||
font-family: var(--font-primary);
|
font-family: var(--font-primary);
|
||||||
font-size: calc(var(--font-size-standard) * 1);
|
font-size: calc(var(--font-size-standard) * 1);
|
||||||
}
|
}
|
||||||
.nudge-roll {
|
|
||||||
font-size: calc(var(--font-size-standard) * 1);
|
|
||||||
margin-left: 2rem;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.healing-roll {
|
|
||||||
font-size: calc(var(--font-size-standard) * 1);
|
|
||||||
margin-left: 2rem;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.roll-damage {
|
|
||||||
font-size: calc(var(--font-size-standard) * 1);
|
|
||||||
margin-left: 2rem;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.result-success {
|
.result-success {
|
||||||
color: var(--color-success);
|
color: var(--color-success);
|
||||||
font-family: var(--font-title);
|
font-family: var(--font-title);
|
||||||
@@ -149,4 +134,227 @@
|
|||||||
font-size: calc(var(--font-size-standard) * 1.2);
|
font-size: calc(var(--font-size-standard) * 1.2);
|
||||||
text-shadow: 0 0 10px var(--color-shadow-primary);
|
text-shadow: 0 0 10px var(--color-shadow-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chat-actions {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.375rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
border-top: 1px solid var(--color-border-light-primary);
|
||||||
|
background: rgba(0, 0, 0, 0.05);
|
||||||
|
border-radius: 0 0 5px 5px;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.chat-action-button {
|
||||||
|
display: inline-flex !important;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
padding: 0 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
background: var(--color-dark-6);
|
||||||
|
color: var(--color-light-1);
|
||||||
|
border: 1px solid var(--color-border-light-primary);
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
text-decoration: none;
|
||||||
|
line-height: 1;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--color-dark-5);
|
||||||
|
border-color: var(--color-border-dark);
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 1rem !important;
|
||||||
|
line-height: 1;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nudge-roll,
|
||||||
|
.damage-roll,
|
||||||
|
.healing-roll,
|
||||||
|
.opposed-roll {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.opposed-roll-result {
|
||||||
|
padding: 1rem;
|
||||||
|
background: rgba(0, 0, 0, 0.05);
|
||||||
|
border-radius: 5px;
|
||||||
|
font-family: var(--font-primary);
|
||||||
|
|
||||||
|
.opposed-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
border-bottom: 2px solid var(--color-border-light-primary);
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin: 0;
|
||||||
|
font-family: var(--font-title);
|
||||||
|
font-size: calc(var(--font-size-standard) * 1.2);
|
||||||
|
color: var(--color-dark-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.opposed-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.opposed-winner,
|
||||||
|
.opposed-loser {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.75rem;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.opposed-winner {
|
||||||
|
background: rgba(34, 139, 34, 0.1);
|
||||||
|
border: 2px solid var(--color-success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.opposed-loser {
|
||||||
|
background: rgba(220, 20, 60, 0.1);
|
||||||
|
border: 2px solid var(--color-failure);
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 2px solid var(--color-border-light-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-name {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-size: calc(var(--font-size-standard) * 0.85);
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--color-dark-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.winner-name {
|
||||||
|
font-size: calc(var(--font-size-standard) * 1.1);
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--color-success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.loser-name {
|
||||||
|
font-size: calc(var(--font-size-standard) * 1.1);
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--color-failure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.roll-result {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
|
||||||
|
.roll-value {
|
||||||
|
font-size: calc(var(--font-size-standard) * 1.5);
|
||||||
|
font-weight: bold;
|
||||||
|
font-family: var(--font-title);
|
||||||
|
}
|
||||||
|
|
||||||
|
.critical-badge {
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: calc(var(--font-size-standard) * 0.8);
|
||||||
|
font-weight: bold;
|
||||||
|
text-transform: uppercase;
|
||||||
|
background: var(--color-critical-success);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.winner-result .roll-value {
|
||||||
|
color: var(--color-success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.loser-result .roll-value {
|
||||||
|
color: var(--color-failure);
|
||||||
|
}
|
||||||
|
|
||||||
|
.versus-separator {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
font-size: calc(var(--font-size-standard) * 1.1);
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--color-dark-2);
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: calc(var(--font-size-standard) * 1.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.375rem;
|
||||||
|
padding: 0.75rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
border-top: 1px solid var(--color-border-light-primary);
|
||||||
|
background: rgba(0, 0, 0, 0.05);
|
||||||
|
border-radius: 0 0 5px 5px;
|
||||||
|
|
||||||
|
.chat-action-button {
|
||||||
|
display: inline-flex !important;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
padding: 0 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
background: var(--color-dark-6);
|
||||||
|
color: var(--color-light-1);
|
||||||
|
border: 1px solid var(--color-border-light-primary);
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
text-decoration: none;
|
||||||
|
line-height: 1;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--color-dark-5);
|
||||||
|
border-color: var(--color-border-dark);
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 1rem !important;
|
||||||
|
line-height: 1;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="intro-right">
|
<div class="intro-right">
|
||||||
<ul>
|
<ul>
|
||||||
|
<li><strong>{{actingCharName}}</strong></li>
|
||||||
{{#if (eq rollType "char")}}
|
{{#if (eq rollType "char")}}
|
||||||
<li><strong>{{localize "CTHULHUETERNAL.Label.charRoll"}}</strong></li>
|
<li><strong>{{localize "CTHULHUETERNAL.Label.charRoll"}}</strong></li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
@@ -66,6 +67,7 @@
|
|||||||
<li>{{localize "CTHULHUETERNAL.Label.targetScore"}}
|
<li>{{localize "CTHULHUETERNAL.Label.targetScore"}}
|
||||||
:
|
:
|
||||||
{{targetScore}}%</li>
|
{{targetScore}}%</li>
|
||||||
|
|
||||||
{{#if isSuccess}}
|
{{#if isSuccess}}
|
||||||
{{#if isCritical}}
|
{{#if isCritical}}
|
||||||
<li class="result-critical-success">{{localize
|
<li class="result-critical-success">{{localize
|
||||||
@@ -75,70 +77,8 @@
|
|||||||
{{else}}
|
{{else}}
|
||||||
<li class="result-success">
|
<li class="result-success">
|
||||||
{{localize "CTHULHUETERNAL.Label.success"}}
|
{{localize "CTHULHUETERNAL.Label.success"}}
|
||||||
{{#if isNudge}}
|
|
||||||
<a
|
|
||||||
class="nudge-roll"
|
|
||||||
data-tooltip="{{localize ' CTHULHUETERNAL.Label.rollNudge'}}"
|
|
||||||
><i class="fa-solid fa-circle-sort-down"></i></a>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (eq rollType "weapon")}}
|
|
||||||
<li>
|
|
||||||
{{#if (eq weapon.system.weaponType "rangedfirearm")}}
|
|
||||||
{{#if weapon.system.hasDamageDistance}}
|
|
||||||
{{#each weapon.system.damageDistance as |damageDistance|}}
|
|
||||||
{{#if (gt damageDistance.distance 0)}}
|
|
||||||
<a
|
|
||||||
class="damage-roll"
|
|
||||||
data-item-id="{{weapon.id}}"
|
|
||||||
data-action="roll"
|
|
||||||
data-roll-type="damage"
|
|
||||||
data-roll-value="{{damageDistance.damage}}"
|
|
||||||
>
|
|
||||||
<i class="fa-solid fa-gun"></i>
|
|
||||||
<span
|
|
||||||
class="damage-distance"
|
|
||||||
>{{damageDistance.distance}}:{{damageDistance.damage}} </span>
|
|
||||||
</a>
|
|
||||||
{{/if}}
|
|
||||||
{{/each}}
|
|
||||||
{{else}}
|
|
||||||
<a
|
|
||||||
class="damage-roll"
|
|
||||||
data-roll-value="{{weapon.system.damage}}"
|
|
||||||
data-tooltip="{{localize
|
|
||||||
'
|
|
||||||
CTHULHUETERNAL.Label.rollDamage'
|
|
||||||
}}"
|
|
||||||
><i class="fa-solid fa-gun"></i></a>
|
|
||||||
{{/if}}
|
|
||||||
{{else}}
|
|
||||||
<a
|
|
||||||
class="damage-roll"
|
|
||||||
data-roll-value="{{weapon.system.damage}}"
|
|
||||||
data-tooltip="{{localize
|
|
||||||
'
|
|
||||||
CTHULHUETERNAL.Label.rollDamage'
|
|
||||||
}}"
|
|
||||||
><i class="fa-solid fa-sword"></i></a>
|
|
||||||
{{/if}}
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
{{#if (eq rollType "skill")}}
|
|
||||||
{{#if rollItem.system.isHealing}}
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
class="healing-roll"
|
|
||||||
data-tooltip="{{localize
|
|
||||||
' CTHULHUETERNAL.Label.rollHealing'
|
|
||||||
}}"
|
|
||||||
><i class="fa-solid fa-heart"></i></a>
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if isFailure}}
|
{{#if isFailure}}
|
||||||
@@ -152,19 +92,9 @@
|
|||||||
{{localize "CTHULHUETERNAL.Label.failure"}}
|
{{localize "CTHULHUETERNAL.Label.failure"}}
|
||||||
</li>
|
</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if isNudge}}
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
class="nudge-roll"
|
|
||||||
data-tooltip="{{localize 'CTHULHUETERNAL.Label.rollNudge'}}"
|
|
||||||
><i class="fa-solid fa-circle-sort-down"></i></a>
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if isAttackRoll}}
|
<!-- {{#if isAttackRoll}}
|
||||||
{{#if defenseRoll}}
|
{{#if defenseRoll}}
|
||||||
<li>{{localize "CTHULHUETERNAL.Label.defenseRoll"}}</li>
|
<li>{{localize "CTHULHUETERNAL.Label.defenseRoll"}}</li>
|
||||||
{{#if attackSuccess}}
|
{{#if attackSuccess}}
|
||||||
@@ -181,27 +111,18 @@
|
|||||||
<li class="orange-warning">{{localize
|
<li class="orange-warning">{{localize
|
||||||
"CTHULHUETERNAL.Label.noDefenseRoll"
|
"CTHULHUETERNAL.Label.noDefenseRoll"
|
||||||
}}</li>
|
}}</li>
|
||||||
<a
|
|
||||||
class="opposed-roll"
|
|
||||||
data-tooltip="{{localize 'CTHULHUETERNAL.Label.opposedRoll'}}"
|
|
||||||
>
|
|
||||||
<i class="fa-duotone fa-light fa-arrows-to-line"></i></a>
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<li class="orange-warning">{{localize
|
<li class="orange-warning">{{localize
|
||||||
"CTHULHUETERNAL.Label.noTarget"
|
"CTHULHUETERNAL.Label.noTarget"
|
||||||
}}</li>
|
}}</li>
|
||||||
<a
|
|
||||||
class="opposed-roll"
|
|
||||||
data-tooltip="{{localize 'CTHULHUETERNAL.Label.opposedRoll'}}"
|
|
||||||
>
|
|
||||||
<i class="fa-duotone fa-light fa-arrows-to-line"></i></a>
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}} -->
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if isDamage}}
|
{{#if isDamage}}
|
||||||
<div>
|
<div>
|
||||||
{{#if (and isGM hasTarget)}}
|
{{#if (and isGM hasTarget)}}
|
||||||
@@ -221,4 +142,86 @@
|
|||||||
{{{tooltip}}}
|
{{{tooltip}}}
|
||||||
</div>
|
</div>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
|
|
||||||
|
{{! Zone d'actions regroupées }}
|
||||||
|
<div class="chat-actions">
|
||||||
|
{{#if isSuccess}}
|
||||||
|
{{#if isNudge}}
|
||||||
|
<a
|
||||||
|
class="nudge-roll chat-action-button"
|
||||||
|
data-tooltip="{{localize 'CTHULHUETERNAL.Label.rollNudge'}}"
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-circle-sort-down"></i>
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (eq rollType "weapon")}}
|
||||||
|
{{#if (eq weapon.system.weaponType "rangedfirearm")}}
|
||||||
|
{{#if weapon.system.hasDamageDistance}}
|
||||||
|
{{#each weapon.system.damageDistance as |damageDistance|}}
|
||||||
|
{{#if (gt damageDistance.distance 0)}}
|
||||||
|
<a
|
||||||
|
class="damage-roll chat-action-button"
|
||||||
|
data-item-id="{{weapon.id}}"
|
||||||
|
data-action="roll"
|
||||||
|
data-roll-type="damage"
|
||||||
|
data-roll-value="{{damageDistance.damage}}"
|
||||||
|
data-tooltip="{{localize
|
||||||
|
'CTHULHUETERNAL.Label.rollDamage'
|
||||||
|
}} ({{damageDistance.distance}}m : {{damageDistance.damage}})"
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-gun"></i>
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
{{/each}}
|
||||||
|
{{else}}
|
||||||
|
<a
|
||||||
|
class="damage-roll chat-action-button"
|
||||||
|
data-roll-value="{{weapon.system.damage}}"
|
||||||
|
data-tooltip="{{localize 'CTHULHUETERNAL.Label.rollDamage'}}"
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-gun"></i>
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
{{else}}
|
||||||
|
<a
|
||||||
|
class="damage-roll chat-action-button"
|
||||||
|
data-roll-value="{{weapon.system.damage}}"
|
||||||
|
data-tooltip="{{localize 'CTHULHUETERNAL.Label.rollDamage'}}"
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-sword"></i>
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (eq rollType "skill")}}
|
||||||
|
{{#if rollItem.system.isHealing}}
|
||||||
|
<a
|
||||||
|
class="healing-roll chat-action-button"
|
||||||
|
data-tooltip="{{localize 'CTHULHUETERNAL.Label.rollHealing'}}"
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-heart"></i>
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if isFailure}}
|
||||||
|
{{#if isNudge}}
|
||||||
|
<a
|
||||||
|
class="nudge-roll chat-action-button"
|
||||||
|
data-tooltip="{{localize 'CTHULHUETERNAL.Label.rollNudge'}}"
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-circle-sort-down"></i>
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="opposed-roll chat-action-button"
|
||||||
|
data-tooltip="{{localize 'CTHULHUETERNAL.Label.opposedRoll'}}"
|
||||||
|
>
|
||||||
|
<i class="fa-duotone fa-light fa-arrows-to-line"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
64
templates/chat-opposed-result.hbs
Normal file
64
templates/chat-opposed-result.hbs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
w{{! Template for opposed roll result }}
|
||||||
|
<div class="cthulhu-eternal-roll opposed-roll-result">
|
||||||
|
<div class="opposed-header">
|
||||||
|
<h3>{{localize "CTHULHUETERNAL.Label.opposedRollResult"}}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="opposed-content">
|
||||||
|
<div class="opposed-winner">
|
||||||
|
<div class="character-info">
|
||||||
|
<img src="{{winner.actor.img}}" alt="{{winner.actor.name}}" />
|
||||||
|
<div class="character-name">
|
||||||
|
<strong>{{localize "CTHULHUETERNAL.Label.opposedRollWinner"}}</strong>
|
||||||
|
<span class="winner-name">{{winner.actor.name}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="roll-result winner-result">
|
||||||
|
<span class="roll-value">{{winner.rollData.rollResult}}</span>
|
||||||
|
{{#if winner.rollData.isCritical}}
|
||||||
|
<span class="critical-badge">{{localize
|
||||||
|
"CTHULHUETERNAL.Label.critical"
|
||||||
|
}}</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="versus-separator">
|
||||||
|
<i class="fas fa-swords"></i>
|
||||||
|
<span>{{localize "CTHULHUETERNAL.Label.defeats"}}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="opposed-loser">
|
||||||
|
<div class="character-info">
|
||||||
|
<img src="{{loser.actor.img}}" alt="{{loser.actor.name}}" />
|
||||||
|
<div class="character-name">
|
||||||
|
<span class="loser-name">{{loser.actor.name}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="roll-result loser-result">
|
||||||
|
<span class="roll-value">{{loser.rollData.rollResult}}</span>
|
||||||
|
{{#if loser.rollData.isCritical}}
|
||||||
|
<span class="critical-badge">{{localize
|
||||||
|
"CTHULHUETERNAL.Label.critical"
|
||||||
|
}}</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if canApplyDamage}}
|
||||||
|
<div class="chat-actions">
|
||||||
|
<a
|
||||||
|
class="damage-roll chat-action-button"
|
||||||
|
data-roll-value="{{winner.rollData.weapon.system.damage}}"
|
||||||
|
data-tooltip="{{localize 'CTHULHUETERNAL.Label.rollDamage'}}"
|
||||||
|
>
|
||||||
|
{{#if (eq winner.rollData.weapon.system.weaponType "rangedfirearm")}}
|
||||||
|
<i class="fa-solid fa-gun"></i>
|
||||||
|
{{else}}
|
||||||
|
<i class="fa-solid fa-sword"></i>
|
||||||
|
{{/if}}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
@@ -1,135 +1,214 @@
|
|||||||
<div class="fvtt-cthulhu-eternal-roll-dialog">
|
<div class="fvtt-cthulhu-eternal-roll-dialog">
|
||||||
<fieldSet>
|
<fieldSet>
|
||||||
{{#if (eq rollType "skill")}}
|
{{#if (eq rollType "skill")}}
|
||||||
<legend>{{localize "CTHULHUETERNAL.Label.skill"}}</legend>
|
<legend>{{localize "CTHULHUETERNAL.Label.skill"}}</legend>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (eq rollType "char")}}
|
{{#if (eq rollType "char")}}
|
||||||
<legend>{{localize "CTHULHUETERNAL.Label.characteristic"}}</legend>
|
<legend>{{localize "CTHULHUETERNAL.Label.characteristic"}}</legend>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if (eq rollType "resource")}}
|
{{#if (eq rollType "resource")}}
|
||||||
<legend>{{localize "CTHULHUETERNAL.Label.resourceRating"}}</legend>
|
<legend>{{localize "CTHULHUETERNAL.Label.resourceRating"}}</legend>
|
||||||
<div class="dialog-skill">{{rollItem.name}} : <span class="resource-score">{{initialScore}} ({{mul initialScore
|
<div class="dialog-skill">{{rollItem.name}}
|
||||||
5}}%)</span></div>
|
:
|
||||||
<div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Hand"}} : {{rollItem.hand}} <input type="checkbox"
|
<span class="resource-score">{{initialScore}}
|
||||||
data-action="selectHand" {{checked rollItem.enableHand}}></div>
|
({{mul initialScore 5}}%)</span></div>
|
||||||
<div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Stowed"}} : {{rollItem.stowed}} <input type="checkbox"
|
<div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Hand"}}
|
||||||
data-action="selectStowed" {{checked rollItem.enableStowed}}></div>
|
:
|
||||||
<div class="dialog-skill">
|
{{rollItem.hand}}
|
||||||
{{localize "CTHULHUETERNAL.Label.Storage"}} : {{rollItem.storage}}
|
<input
|
||||||
<input type="checkbox" data-action="selectStorage" {{checked rollItem.enableStorage}}>
|
type="checkbox"
|
||||||
</div>
|
data-action="selectHand"
|
||||||
|
{{checked rollItem.enableHand}}
|
||||||
|
/></div>
|
||||||
|
<div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Stowed"}}
|
||||||
|
:
|
||||||
|
{{rollItem.stowed}}
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
data-action="selectStowed"
|
||||||
|
{{checked rollItem.enableStowed}}
|
||||||
|
/></div>
|
||||||
|
<div class="dialog-skill">
|
||||||
|
{{localize "CTHULHUETERNAL.Label.Storage"}}
|
||||||
|
:
|
||||||
|
{{rollItem.storage}}
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
data-action="selectStorage"
|
||||||
|
{{checked rollItem.enableStorage}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="dialog-skill">{{rollItem.name}} : {{initialScore}}%</div>
|
<div class="dialog-skill">{{rollItem.name}} : {{initialScore}}%</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if weapon}}
|
{{#if weapon}}
|
||||||
<div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Weapon"}} : {{weapon.name}}</div>
|
<div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Weapon"}}
|
||||||
|
:
|
||||||
|
{{weapon.name}}</div>
|
||||||
|
|
||||||
{{#if targetName}}
|
{{#if targetName}}
|
||||||
<div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Target"}} : {{targetName}}</div>
|
<div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Target"}}
|
||||||
{{/if}}
|
:
|
||||||
|
{{targetName}}</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (eq weapon.system.weaponType "melee")}}
|
||||||
|
<div class="dialog-skill">
|
||||||
|
{{localize "CTHULHUETERNAL.Label.targetMove"}}
|
||||||
|
<select name="meleeTargetMoveChoice" class="roll-skill-modifier">
|
||||||
|
{{selectOptions
|
||||||
|
choiceMeleeTargetMove
|
||||||
|
localize=true
|
||||||
|
selected=meleeTargetMoveChoice
|
||||||
|
valueAttr="id"
|
||||||
|
labelAttr="label"
|
||||||
|
}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if isRangedWeapon}}
|
||||||
|
<div class="dialog-skill">
|
||||||
|
{{localize "CTHULHUETERNAL.Label.rangedRange"}}
|
||||||
|
<select name="rangedRangeChoice" class="roll-skill-modifier">
|
||||||
|
{{selectOptions
|
||||||
|
choiceRangedRange
|
||||||
|
localize=true
|
||||||
|
selected=rangedRangeChoice
|
||||||
|
valueAttr="id"
|
||||||
|
labelAttr="label"
|
||||||
|
}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="dialog-skill">
|
||||||
|
{{localize "CTHULHUETERNAL.Label.targetMove"}}
|
||||||
|
<select name="rangedTargetMoveChoice" class="roll-skill-modifier">
|
||||||
|
{{selectOptions
|
||||||
|
choiceRangedTargetMove
|
||||||
|
localize=true
|
||||||
|
selected=rangedTargetMoveChoice
|
||||||
|
valueAttr="id"
|
||||||
|
labelAttr="label"
|
||||||
|
}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{#if (eq weapon.system.weaponType "melee")}}
|
<div class="dialog-skill">
|
||||||
<div class="dialog-skill">
|
{{localize "CTHULHUETERNAL.Label.aimingLastRound"}}
|
||||||
{{localize "CTHULHUETERNAL.Label.targetMove"}}
|
<input
|
||||||
<select name="meleeTargetMoveChoice" class="roll-skill-modifier">
|
type="checkbox"
|
||||||
{{selectOptions choiceMeleeTargetMove localize=true selected=meleeTargetMoveChoice valueAttr="id"
|
class="aimingLastRound"
|
||||||
labelAttr="label"}}
|
name="aimingLastRound"
|
||||||
</select>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{#if weapon.system.hasSight}}
|
||||||
{{#if isRangedWeapon}}
|
<div class="dialog-skill">
|
||||||
<div class="dialog-skill">
|
{{localize "CTHULHUETERNAL.Label.aimingWithSight"}}
|
||||||
{{localize "CTHULHUETERNAL.Label.rangedRange"}}
|
<input
|
||||||
<select name="rangedRangeChoice" class="roll-skill-modifier">
|
type="checkbox"
|
||||||
{{selectOptions choiceRangedRange localize=true selected=rangedRangeChoice valueAttr="id" labelAttr="label"}}
|
class="aimingWithSight"
|
||||||
</select>
|
name="aimingWithSight"
|
||||||
</div>
|
/>
|
||||||
<div class="dialog-skill">
|
</div>
|
||||||
{{localize "CTHULHUETERNAL.Label.targetMove"}}
|
{{/if}}
|
||||||
<select name="rangedTargetMoveChoice" class="roll-skill-modifier">
|
|
||||||
{{selectOptions choiceRangedTargetMove localize=true selected=rangedTargetMoveChoice valueAttr="id"
|
|
||||||
labelAttr="label"}}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="dialog-skill">
|
{{/if}}
|
||||||
{{localize "CTHULHUETERNAL.Label.aimingLastRound"}}
|
|
||||||
<input type="checkbox" name="aimingLastRound">
|
|
||||||
</div>
|
|
||||||
{{#if weapon.system.hasSight}}
|
|
||||||
<div class="dialog-skill">
|
|
||||||
{{localize "CTHULHUETERNAL.Label.aimingWithSight"}}
|
|
||||||
<input type="checkbox" name="aimingWithSight">
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{/if}}
|
<div class="dialog-skill">
|
||||||
|
{{localize "CTHULHUETERNAL.Label.visibility"}}
|
||||||
|
<select name="visibilityChoice" class="roll-skill-modifier">
|
||||||
|
{{selectOptions
|
||||||
|
choiceVisibility
|
||||||
|
localize=true
|
||||||
|
selected=visibilityChoice
|
||||||
|
valueAttr="id"
|
||||||
|
labelAttr="label"
|
||||||
|
}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="dialog-skill">
|
||||||
|
{{localize "CTHULHUETERNAL.Label.attackerState"}}
|
||||||
|
<select name="attackerStateChoice" class="roll-skill-modifier">
|
||||||
|
{{selectOptions
|
||||||
|
choiceAttackerState
|
||||||
|
localize=true
|
||||||
|
selected=attackerStateChoice
|
||||||
|
valueAttr="id"
|
||||||
|
labelAttr="label"
|
||||||
|
}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="dialog-skill">
|
||||||
|
{{localize "CTHULHUETERNAL.Label.targetSize"}}
|
||||||
|
<select name="targetSizeChoice" class="roll-skill-modifier">
|
||||||
|
{{selectOptions
|
||||||
|
choiceTargetSize
|
||||||
|
localize=true
|
||||||
|
selected=targetSizeChoice
|
||||||
|
valueAttr="id"
|
||||||
|
labelAttr="label"
|
||||||
|
}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="dialog-skill">
|
{{#if weapon.system.hasSelectiveFire}}
|
||||||
{{localize "CTHULHUETERNAL.Label.visibility"}}
|
<div class="dialog-skill">Selective Fire :
|
||||||
<select name="visibilityChoice" class="roll-skill-modifier">
|
<select name="selectiveFireChoice" class="roll-skill-modifier">
|
||||||
{{selectOptions choiceVisibility localize=true selected=visibilityChoice valueAttr="id" labelAttr="label"}}
|
{{selectOptions
|
||||||
</select>
|
choiceSelectiveFire
|
||||||
</div>
|
localize=true
|
||||||
<div class="dialog-skill">
|
selected=selectiveFireChoice
|
||||||
{{localize "CTHULHUETERNAL.Label.attackerState"}}
|
valueAttr="id"
|
||||||
<select name="attackerStateChoice" class="roll-skill-modifier">
|
labelAttr="label"
|
||||||
{{selectOptions choiceAttackerState localize=true selected=attackerStateChoice valueAttr="id"
|
}}
|
||||||
labelAttr="label"}}
|
</select>
|
||||||
</select>
|
</div>
|
||||||
</div>
|
{{/if}}
|
||||||
<div class="dialog-skill">
|
|
||||||
{{localize "CTHULHUETERNAL.Label.targetSize"}}
|
|
||||||
<select name="targetSizeChoice" class="roll-skill-modifier">
|
|
||||||
{{selectOptions choiceTargetSize localize=true selected=targetSizeChoice valueAttr="id" labelAttr="label"}}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{#if weapon.system.hasSelectiveFire}}
|
|
||||||
<div class="dialog-skill">Selective Fire :
|
|
||||||
<select name="selectiveFireChoice" class="roll-skill-modifier">
|
|
||||||
{{selectOptions choiceSelectiveFire localize=true selected=selectiveFireChoice valueAttr="id"
|
|
||||||
labelAttr="label"}}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if isZeroWP}}
|
{{#if isZeroWP}}
|
||||||
<div class="dialog-skill red-warning">{{localize "CTHULHUETERNAL.Label.ZeroWP"}}</div>
|
<div class="dialog-skill red-warning">{{localize
|
||||||
|
"CTHULHUETERNAL.Label.ZeroWP"
|
||||||
|
}}</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if isLowWP}}
|
{{#if isLowWP}}
|
||||||
<div class="dialog-skill orange-warning">{{localize "CTHULHUETERNAL.Label.LowWP"}} : -20%</div>
|
<div class="dialog-skill orange-warning">{{localize
|
||||||
{{/if}}
|
"CTHULHUETERNAL.Label.LowWP"
|
||||||
|
}}
|
||||||
|
: -20%</div>
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if isExhausted}}
|
{{#if isExhausted}}
|
||||||
<div class="dialog-skill orange-warning">{{localize "CTHULHUETERNAL.Label.Exhausted"}} : -20%</div>
|
<div class="dialog-skill orange-warning">{{localize
|
||||||
|
"CTHULHUETERNAL.Label.Exhausted"
|
||||||
|
}}
|
||||||
|
: -20%</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
</fieldSet>
|
</fieldSet>
|
||||||
|
|
||||||
|
|
||||||
{{#if hasModifier}}
|
{{#if hasModifier}}
|
||||||
<fieldSet class="dialog-modifier">
|
<fieldSet class="dialog-modifier">
|
||||||
<legend>{{localize "CTHULHUETERNAL.Label.modifier"}}</legend>
|
<legend>{{localize "CTHULHUETERNAL.Label.modifier"}}</legend>
|
||||||
<select name="modifier" class="roll-skill-modifier">
|
<select name="modifier" class="roll-skill-modifier">
|
||||||
{{selectOptions choiceModifier selected=modifier}}
|
{{selectOptions choiceModifier selected=modifier}}
|
||||||
</select>
|
</select>
|
||||||
</fieldSet>
|
</fieldSet>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if hasMultiplier}}
|
{{#if hasMultiplier}}
|
||||||
<fieldSet class="dialog-modifier">
|
<fieldSet class="dialog-modifier">
|
||||||
<legend>{{localize "CTHULHUETERNAL.Label.multiplier"}}</legend>
|
<legend>{{localize "CTHULHUETERNAL.Label.multiplier"}}</legend>
|
||||||
<select name="multiplier" class="roll-skill-modifier roll-skill-multiplier">
|
<select
|
||||||
{{selectOptions choiceMultiplier selected=multiplier}}
|
name="multiplier"
|
||||||
</select>
|
class="roll-skill-modifier roll-skill-multiplier"
|
||||||
</fieldSet>
|
>
|
||||||
|
{{selectOptions choiceMultiplier selected=multiplier}}
|
||||||
|
</select>
|
||||||
|
</fieldSet>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<fieldSet>
|
<fieldSet>
|
||||||
|
|||||||
Reference in New Issue
Block a user