Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e26db56585 | |||
| bb6a6248f2 | |||
| 7dc2492c96 |
@@ -0,0 +1 @@
|
|||||||
|
packs/** filter=lfs diff=lfs merge=lfs -text
|
||||||
@@ -60,4 +60,4 @@ jobs:
|
|||||||
manifest: 'https://www.uberwald.me/gitea/public/fvtt-cthulhu-eternal/releases/download/latest/system.json'
|
manifest: 'https://www.uberwald.me/gitea/public/fvtt-cthulhu-eternal/releases/download/latest/system.json'
|
||||||
notes: 'https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/fvtt-cthulhu-eternal.zip'
|
notes: 'https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/fvtt-cthulhu-eternal.zip'
|
||||||
compatibility-minimum: '13'
|
compatibility-minimum: '13'
|
||||||
compatibility-verified: '13'
|
compatibility-verified: '14'
|
||||||
@@ -5,4 +5,6 @@ styles/*.css
|
|||||||
|
|
||||||
# Node Modules
|
# Node Modules
|
||||||
node_modules/
|
node_modules/
|
||||||
|
.github/
|
||||||
|
.history/
|
||||||
|
|
||||||
|
|||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"cSpell.words": [
|
||||||
|
"CTHULHUETERNAL"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -232,6 +232,32 @@ i.fvtt-cthulhu-eternal {
|
|||||||
font-family: var(--font-primary);
|
font-family: var(--font-primary);
|
||||||
font-size: calc(var(--font-size-standard) * 1.02);
|
font-size: calc(var(--font-size-standard) * 1.02);
|
||||||
}
|
}
|
||||||
|
.chat-san-request ul .combatants-grid,
|
||||||
|
.chat-lethal-damage ul .combatants-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
gap: 4px;
|
||||||
|
margin: 8px 0;
|
||||||
|
}
|
||||||
|
.chat-san-request ul .combatants-grid button.apply-wounds-btn,
|
||||||
|
.chat-lethal-damage ul .combatants-grid button.apply-wounds-btn {
|
||||||
|
font-family: var(--font-primary);
|
||||||
|
font-size: calc(var(--font-size-standard) * 0.7);
|
||||||
|
border: 1px solid #4b4a44;
|
||||||
|
padding: 4px 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
background-color: #f0f0e0;
|
||||||
|
color: #1c1c1c;
|
||||||
|
}
|
||||||
|
.chat-san-request ul .combatants-grid button.apply-wounds-btn:hover,
|
||||||
|
.chat-lethal-damage ul .combatants-grid button.apply-wounds-btn:hover {
|
||||||
|
background-color: #d5d5c5;
|
||||||
|
border-color: #2d2d2a;
|
||||||
|
}
|
||||||
.fvtt-cthulhu-eternal .protagonist-sheet-common label {
|
.fvtt-cthulhu-eternal .protagonist-sheet-common label {
|
||||||
font-family: var(--font-secondary);
|
font-family: var(--font-secondary);
|
||||||
font-size: calc(var(--font-size-standard) * 1);
|
font-size: calc(var(--font-size-standard) * 1);
|
||||||
@@ -651,6 +677,12 @@ i.fvtt-cthulhu-eternal {
|
|||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
}
|
}
|
||||||
|
.fvtt-cthulhu-eternal .empty-state {
|
||||||
|
color: var(--color-text-light-6);
|
||||||
|
font-style: italic;
|
||||||
|
padding: 0.5rem 0.25rem;
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
.fvtt-cthulhu-eternal .tab.protagonist-skills .main-div .skills .skill {
|
.fvtt-cthulhu-eternal .tab.protagonist-skills .main-div .skills .skill {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -892,6 +924,20 @@ i.fvtt-cthulhu-eternal {
|
|||||||
min-width: 1.8rem;
|
min-width: 1.8rem;
|
||||||
max-width: 1.8rem;
|
max-width: 1.8rem;
|
||||||
}
|
}
|
||||||
|
.fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .armors .armor .equipped-toggle {
|
||||||
|
font-size: 1rem;
|
||||||
|
min-width: 1.4rem;
|
||||||
|
max-width: 1.4rem;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #888;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .armors .armor .equipped-toggle.active {
|
||||||
|
color: #4caf50;
|
||||||
|
}
|
||||||
|
.fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .armors .armor .equipped-toggle:hover {
|
||||||
|
color: #2196f3;
|
||||||
|
}
|
||||||
.fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .armors .armor .protection {
|
.fvtt-cthulhu-eternal .tab.protagonist-equipment .main-div .armors .armor .protection {
|
||||||
min-width: 5rem;
|
min-width: 5rem;
|
||||||
max-width: 5rem;
|
max-width: 5rem;
|
||||||
|
|||||||
+27
-2
@@ -170,6 +170,9 @@ 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"
|
||||||
})
|
})
|
||||||
|
$(html).find(".worn-weapon-check").each((i, btn) => {
|
||||||
|
btn.style.display = "inline"
|
||||||
|
})
|
||||||
if (game.user.isGM) {
|
if (game.user.isGM) {
|
||||||
$(html).find(".opposed-roll").each((i, btn) => {
|
$(html).find(".opposed-roll").each((i, btn) => {
|
||||||
btn.style.display = "inline"
|
btn.style.display = "inline"
|
||||||
@@ -185,6 +188,9 @@ Hooks.on("renderChatMessageHTML", (message, html, data) => {
|
|||||||
$(html).find(".healing-roll").click((event) => {
|
$(html).find(".healing-roll").click((event) => {
|
||||||
CthulhuEternalUtils.healingRoll(message)
|
CthulhuEternalUtils.healingRoll(message)
|
||||||
})
|
})
|
||||||
|
$(html).find(".worn-weapon-check").click((event) => {
|
||||||
|
CthulhuEternalUtils.wornWeaponCheck(message)
|
||||||
|
})
|
||||||
$(html).find(".san-loose").click((event) => {
|
$(html).find(".san-loose").click((event) => {
|
||||||
CthulhuEternalUtils.applySANLoss(message, event)
|
CthulhuEternalUtils.applySANLoss(message, event)
|
||||||
})
|
})
|
||||||
@@ -197,11 +203,30 @@ Hooks.on("renderChatMessageHTML", (message, html, data) => {
|
|||||||
}
|
}
|
||||||
if (game.user.isGM) {
|
if (game.user.isGM) {
|
||||||
$(html).find(".li-apply-wounds").each((i, btn) => {
|
$(html).find(".li-apply-wounds").each((i, btn) => {
|
||||||
btn.style.display = "inline"
|
btn.style.display = "block"
|
||||||
})
|
})
|
||||||
$(html).find(".li-apply-wounds-select").click((event) => {
|
$(html).find(".apply-wounds-btn").click((event) => {
|
||||||
CthulhuEternalUtils.applyWounds(message, event)
|
CthulhuEternalUtils.applyWounds(message, event)
|
||||||
})
|
})
|
||||||
|
$(html).find(".apply-wounds-btn").hover(
|
||||||
|
function (event) {
|
||||||
|
// Mouse enter - select the token
|
||||||
|
let combatantId = $(this).data("combatant-id")
|
||||||
|
if (combatantId && game.combat) {
|
||||||
|
let combatant = game.combat.combatants.get(combatantId)
|
||||||
|
if (combatant?.token) {
|
||||||
|
let token = canvas.tokens.get(combatant.token.id)
|
||||||
|
if (token) {
|
||||||
|
token.control({ releaseOthers: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function (event) {
|
||||||
|
// Mouse leave - release selection
|
||||||
|
canvas.tokens.releaseAll()
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -571,6 +571,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Label": {
|
"Label": {
|
||||||
|
"JunkWeapon": "This weapon is in 'Junk' state, -20% applied. Critical failure on a roll of 96-100",
|
||||||
|
"WornWeapon": "This weapon is 'Worn', a Luck roll will be performed.",
|
||||||
"noTarget": "No target selected",
|
"noTarget": "No target selected",
|
||||||
"noDefenseRoll": "No defense roll available",
|
"noDefenseRoll": "No defense roll available",
|
||||||
"opposedRoll": "Opposed Roll",
|
"opposedRoll": "Opposed Roll",
|
||||||
@@ -606,6 +608,10 @@
|
|||||||
"rollNudge": "Roll Nudge",
|
"rollNudge": "Roll Nudge",
|
||||||
"rollDamage": "Roll Damage",
|
"rollDamage": "Roll Damage",
|
||||||
"rollHealing": "Roll Healing",
|
"rollHealing": "Roll Healing",
|
||||||
|
"wornWeaponCheck": "Check Weapon Condition",
|
||||||
|
"wornWeaponCheckTitle": "Worn Weapon Condition Check",
|
||||||
|
"wornWeaponCheckSuccess": "{weapon}: Luck roll succeeded ({roll}/50) - Weapon remains worn.",
|
||||||
|
"wornWeaponCheckFailure": "{weapon}: Luck roll failed ({roll}/50) - Weapon became junk!",
|
||||||
"result": "Result",
|
"result": "Result",
|
||||||
"damageMessage": "Damage to apply",
|
"damageMessage": "Damage to apply",
|
||||||
"lethalityRoll": "Lethality Roll",
|
"lethalityRoll": "Lethality Roll",
|
||||||
@@ -617,6 +623,7 @@
|
|||||||
"ZeroWP": "Zero WP : Automatic failure (ie 0%)",
|
"ZeroWP": "Zero WP : Automatic failure (ie 0%)",
|
||||||
"LowWP": "Low WP",
|
"LowWP": "Low WP",
|
||||||
"Exhausted": "Exhausted",
|
"Exhausted": "Exhausted",
|
||||||
|
"wornWeaponWarning": "Worn weapon: Don't forget to make the luck roll after the attack!",
|
||||||
"creature": "Creature",
|
"creature": "Creature",
|
||||||
"Rituals": "Rituals",
|
"Rituals": "Rituals",
|
||||||
"Tomes": "Tomes",
|
"Tomes": "Tomes",
|
||||||
@@ -727,6 +734,8 @@
|
|||||||
"newMentalDisorder": "New Mental Disorder",
|
"newMentalDisorder": "New Mental Disorder",
|
||||||
"newWeapon": "New Weapon",
|
"newWeapon": "New Weapon",
|
||||||
"newArmor": "New Armor",
|
"newArmor": "New Armor",
|
||||||
|
"equipped": "Equipped (click to unequip)",
|
||||||
|
"unequipped": "Not equipped (click to equip)",
|
||||||
"newInjury": "New Injury",
|
"newInjury": "New Injury",
|
||||||
"newGear": "New Gear",
|
"newGear": "New Gear",
|
||||||
"newArcane": "New Arcane",
|
"newArcane": "New Arcane",
|
||||||
@@ -744,6 +753,12 @@
|
|||||||
"unconscious": "Unconscious",
|
"unconscious": "Unconscious",
|
||||||
"dying": "Dying",
|
"dying": "Dying",
|
||||||
"unconsciousWarning": "The Protagonist is unconscious. He cannot act until he has at least 3 HP.",
|
"unconsciousWarning": "The Protagonist is unconscious. He cannot act until he has at least 3 HP.",
|
||||||
|
"stunnedWarning": "The Protagonist is stunned. He cannot act until he succeeds at a CON × 5 test.",
|
||||||
|
"deadWarning": "The Protagonist is dying. He will die if not treated within {con} minutes.",
|
||||||
|
"noSkills": "No skills. Add skills to this character.",
|
||||||
|
"noWeapons": "No weapons. Add weapons in edit mode.",
|
||||||
|
"noArmors": "No armor. Add armor in edit mode.",
|
||||||
|
"noGears": "No gear. Add gear in edit mode.",
|
||||||
"luck": "Luck",
|
"luck": "Luck",
|
||||||
"Other": "Other",
|
"Other": "Other",
|
||||||
"Skills": "Skills",
|
"Skills": "Skills",
|
||||||
@@ -814,6 +829,8 @@
|
|||||||
"WrongEra": "The era of the item does not match the ear of the system",
|
"WrongEra": "The era of the item does not match the ear of the system",
|
||||||
"NoSelectiveFireChoices": "Not enough ammo fo Selective Fire choices for this weapon.",
|
"NoSelectiveFireChoices": "Not enough ammo fo Selective Fire choices for this weapon.",
|
||||||
"NoAmmo": "No more ammo for this weapon. ",
|
"NoAmmo": "No more ammo for this weapon. ",
|
||||||
|
"WeaponBecameJunk": "Weapon {weapon} became junk!",
|
||||||
|
"noWeaponFound": "No weapon found.",
|
||||||
"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.",
|
||||||
|
|||||||
+15
-2
@@ -565,6 +565,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Label": {
|
"Label": {
|
||||||
|
"JunkWeapon": "Cette arme est 'Défectueuse'', -20% appliqué. Échec critique sur un jet de 96-100",
|
||||||
|
"WornWeapon": "Cette arme est 'Usée', un jet de Chance sera effectué.",
|
||||||
"noTarget": "Aucune cible sélectionnée",
|
"noTarget": "Aucune cible sélectionnée",
|
||||||
"noDefenseRoll": "Aucun jet de défense existant",
|
"noDefenseRoll": "Aucun jet de défense existant",
|
||||||
"opposedRoll": "Jet opposé",
|
"opposedRoll": "Jet opposé",
|
||||||
@@ -600,6 +602,10 @@
|
|||||||
"rollNudge": "Modifier le jet",
|
"rollNudge": "Modifier le jet",
|
||||||
"rollDamage": "Jet de dégâts",
|
"rollDamage": "Jet de dégâts",
|
||||||
"rollHealing": "Jet de soin",
|
"rollHealing": "Jet de soin",
|
||||||
|
"wornWeaponCheck": "Vérifier l'état de l'arme",
|
||||||
|
"wornWeaponCheckTitle": "Vérification d'état d'arme usée",
|
||||||
|
"wornWeaponCheckSuccess": "{weapon} : Jet de chance réussi ({roll}/50) - L'arme reste usée.",
|
||||||
|
"wornWeaponCheckFailure": "{weapon} : Jet de chance échoué ({roll}/50) - L'arme devient défectueuse !",
|
||||||
"result": "Resultat",
|
"result": "Resultat",
|
||||||
"damageMessage": "Dégâts à appliquer",
|
"damageMessage": "Dégâts à appliquer",
|
||||||
"lethalityRoll": "Jet de Létalité",
|
"lethalityRoll": "Jet de Létalité",
|
||||||
@@ -610,8 +616,7 @@
|
|||||||
"Weapon": "Arme",
|
"Weapon": "Arme",
|
||||||
"ZeroWP": "PVO à 0 : Echec automatique (ie 0%)",
|
"ZeroWP": "PVO à 0 : Echec automatique (ie 0%)",
|
||||||
"LowWP": "PVO faibles",
|
"LowWP": "PVO faibles",
|
||||||
"Exhausted": "Epuisé",
|
"Exhausted": "Epuisé", "wornWeaponWarning": "Arme usée : N'oubliez pas de faire le jet de chance après l'attaque !", "creature": "Créature",
|
||||||
"creature": "Créature",
|
|
||||||
"Rituals": "Rituels",
|
"Rituals": "Rituels",
|
||||||
"Tomes": "Ouvrages",
|
"Tomes": "Ouvrages",
|
||||||
"otherBenefits": "Autres avantages",
|
"otherBenefits": "Autres avantages",
|
||||||
@@ -721,6 +726,8 @@
|
|||||||
"newMentalDisorder": "Nouveau Trouble mental",
|
"newMentalDisorder": "Nouveau Trouble mental",
|
||||||
"newWeapon": "Nouvelle Arme",
|
"newWeapon": "Nouvelle Arme",
|
||||||
"newArmor": "Nouvelle Armure",
|
"newArmor": "Nouvelle Armure",
|
||||||
|
"equipped": "Équipée (cliquer pour déséquiper)",
|
||||||
|
"unequipped": "Non équipée (cliquer pour équiper)",
|
||||||
"newInjury": "Nouvelle Blessure",
|
"newInjury": "Nouvelle Blessure",
|
||||||
"newGear": "Nouvel Equipement",
|
"newGear": "Nouvel Equipement",
|
||||||
"newArcane": "Nouvel Arcane",
|
"newArcane": "Nouvel Arcane",
|
||||||
@@ -740,6 +747,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.",
|
||||||
|
"noSkills": "Aucune compétence. Ajoutez des compétences à ce personnage.",
|
||||||
|
"noWeapons": "Aucune arme. Ajoutez des armes en mode édition.",
|
||||||
|
"noArmors": "Aucune armure. Ajoutez une armure en mode édition.",
|
||||||
|
"noGears": "Aucun équipement. Ajoutez de l'équipement en mode édition.",
|
||||||
"luck": "Chance",
|
"luck": "Chance",
|
||||||
"Other": "Autre",
|
"Other": "Autre",
|
||||||
"Skills": "Compétences",
|
"Skills": "Compétences",
|
||||||
@@ -810,6 +821,8 @@
|
|||||||
"WrongEra": "L'époque de l'item ne correspond pas à celle du jeu en cours.",
|
"WrongEra": "L'époque de l'item ne correspond pas à celle du jeu en cours.",
|
||||||
"NoSelectiveFireChoices": "Aucune option de tir sélectif n'est disponible pour cette arme : pas assez de munitions.",
|
"NoSelectiveFireChoices": "Aucune option de tir sélectif n'est disponible pour cette arme : pas assez de munitions.",
|
||||||
"NoAmmo": "Aucune munition disponible pour cette arme.",
|
"NoAmmo": "Aucune munition disponible pour cette arme.",
|
||||||
|
"WeaponBecameJunk": "L'arme {weapon} est devenue défectueuse !",
|
||||||
|
"noWeaponFound": "Aucune arme trouvée.",
|
||||||
"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.",
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
// System Module Imports
|
// System Module Imports
|
||||||
import { Utils } from './utils.js'
|
|
||||||
import { SYSTEM } from "../../config/system.mjs"
|
|
||||||
import CthulhuEternalUtils from '../../utils.mjs'
|
import CthulhuEternalUtils from '../../utils.mjs'
|
||||||
|
|
||||||
export let ActionHandler = null
|
export let ActionHandler = null
|
||||||
@@ -17,8 +15,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
* @param {array} groupIds
|
* @param {array} groupIds
|
||||||
*/
|
*/
|
||||||
async buildSystemActions(groupIds) {
|
async buildSystemActions(groupIds) {
|
||||||
// Set actor and token variables
|
// this.actor and this.actors are provided by the base class (TAH Core v2+)
|
||||||
this.actors = (!this.actor) ? this._getActors() : [this.actor]
|
|
||||||
this.actorType = this.actor?.type
|
this.actorType = this.actor?.type
|
||||||
|
|
||||||
// Set items variable
|
// Set items variable
|
||||||
@@ -28,9 +25,11 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
this.items = items
|
this.items = items
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.actorType !== 'vehicle') {
|
if (this.actor) {
|
||||||
this.#buildCharacterActions()
|
if (this.actorType !== 'vehicle') {
|
||||||
} else if (!this.actor) {
|
this.#buildCharacterActions()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
this.#buildMultipleTokenActions()
|
this.#buildMultipleTokenActions()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -201,9 +200,9 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
// Build alpha sorted skill list
|
// Build alpha sorted skill list
|
||||||
let skills = this.actor.items.filter(i => i.type === 'skill')
|
let skills = this.actor.items.filter(i => i.type === 'skill')
|
||||||
skills = skills.sort((a, b) => a.name.localeCompare(b.name))
|
skills = skills.sort((a, b) => a.name.localeCompare(b.name))
|
||||||
console.log('Building skills actions for skills:', skills)
|
|
||||||
for (const skill of skills) {
|
for (const skill of skills) {
|
||||||
console.log('Processing skill item:', skill)
|
//console.log('Processing skill item:', skill)
|
||||||
if (skill.system.skillTotal > 0) {
|
if (skill.system.skillTotal > 0) {
|
||||||
const tooltip = {
|
const tooltip = {
|
||||||
content: String(skill.system.skillTotal),
|
content: String(skill.system.skillTotal),
|
||||||
@@ -224,8 +223,8 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
async buildEquipment() {
|
async buildEquipment() {
|
||||||
let era = game.settings.get("fvtt-cthulhu-eternal", "settings-era")
|
let era = game.settings.get("fvtt-cthulhu-eternal", "settings-era")
|
||||||
|
|
||||||
// const rituals = []
|
const weapons = this.actor.items.filter(i => i.type === 'weapon')
|
||||||
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}`,
|
||||||
@@ -233,16 +232,14 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
type: 'system'
|
type: 'system'
|
||||||
}
|
}
|
||||||
this.addGroup(groupData, { id: 'weapons', type: 'system' }, true)
|
this.addGroup(groupData, { id: 'weapons', type: 'system' }, true)
|
||||||
if (item.type === 'weapon') {
|
|
||||||
let skill = CthulhuEternalUtils.getWeaponSkill(this.actor, item, era)
|
let skill = CthulhuEternalUtils.getWeaponSkill(this.actor, item, era)
|
||||||
item.skillTotal = skill ? skill.system.skillTotal : 0
|
item.skillTotal = skill ? skill.system.skillTotal : 0
|
||||||
let weapons = []
|
let weaponActions = []
|
||||||
const tooltip = {
|
const tooltip = {
|
||||||
content: String(item.skillTotal),
|
content: String(item.skillTotal),
|
||||||
direction: 'LEFT'
|
direction: 'LEFT'
|
||||||
}
|
}
|
||||||
console.log('Weapon skill total for', item.name, 'is', item.skillTotal, item._id)
|
weaponActions.push({
|
||||||
weapons.push({
|
|
||||||
name: `${item.name} (${item.skillTotal})`,
|
name: `${item.name} (${item.skillTotal})`,
|
||||||
id: `weapon_${item._id}`,
|
id: `weapon_${item._id}`,
|
||||||
info1: this.#showValue() ? { text: tooltip.content } : null,
|
info1: this.#showValue() ? { text: tooltip.content } : null,
|
||||||
@@ -260,7 +257,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
direction: 'LEFT'
|
direction: 'LEFT'
|
||||||
}
|
}
|
||||||
if (item.system.damage !== '') {
|
if (item.system.damage !== '') {
|
||||||
weapons.push({
|
weaponActions.push({
|
||||||
name: `${coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.Damage')} (${damage})`,
|
name: `${coreModule.api.Utils.i18n('CTHULHUETERNAL.Label.Damage')} (${damage})`,
|
||||||
id: `damage_${item._id}`,
|
id: `damage_${item._id}`,
|
||||||
info1: this.#showValue() ? { text: damageTooltip.content } : null,
|
info1: this.#showValue() ? { text: damageTooltip.content } : null,
|
||||||
@@ -268,23 +265,10 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
tooltip: damageTooltip
|
tooltip: damageTooltip
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
console.log('Adding weapon actions for', item.name, weapons)
|
await this.addActions(weaponActions, {
|
||||||
await this.addActions(weapons, {
|
|
||||||
id: `weapons_${item._id}`,
|
id: `weapons_${item._id}`,
|
||||||
type: 'system'
|
type: 'system'
|
||||||
})
|
})
|
||||||
}/* else if (item.type === 'ritual') {
|
|
||||||
rituals.push({
|
|
||||||
name: item.name,
|
|
||||||
id: item._id,
|
|
||||||
encodedValue: ['rituals', item.name].join(this.delimiter)
|
|
||||||
})
|
|
||||||
} */
|
|
||||||
|
|
||||||
/* await this.addActions(rituals, {
|
|
||||||
id: 'rituals',
|
|
||||||
type: 'system'
|
|
||||||
}) */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const CORE_MODULE = {
|
|||||||
/**
|
/**
|
||||||
* Core module version required by the system module
|
* Core module version required by the system module
|
||||||
*/
|
*/
|
||||||
export const REQUIRED_CORE_MODULE_VERSION = '2.0'
|
export const REQUIRED_CORE_MODULE_VERSION = '2'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action types
|
* Action types
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
|
|
||||||
import { SYSTEM } from "../../config/system.mjs"
|
|
||||||
|
|
||||||
export let RollHandler = null
|
export let RollHandler = null
|
||||||
|
|
||||||
Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
||||||
@@ -66,7 +63,6 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
* @param {string} actionId The actionId
|
* @param {string} actionId The actionId
|
||||||
*/
|
*/
|
||||||
async #handleAction(event, actor, token, actionTypeId, actionId) {
|
async #handleAction(event, actor, token, actionTypeId, actionId) {
|
||||||
console.log('Handling action', actionId, 'of type', actionTypeId, 'for actor', actor.name)
|
|
||||||
switch (actionTypeId) {
|
switch (actionTypeId) {
|
||||||
case 'characteristics':
|
case 'characteristics':
|
||||||
await this.#handleCharacteristicsAction(event, actor, actionId)
|
await this.#handleCharacteristicsAction(event, actor, actionId)
|
||||||
@@ -100,19 +96,17 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
* @param {string} actionId The action id
|
* @param {string} actionId The action id
|
||||||
*/
|
*/
|
||||||
async #handleCharacteristicsAction(event, actor, actionId) {
|
async #handleCharacteristicsAction(event, actor, actionId) {
|
||||||
let rollType
|
|
||||||
if (actionId === 'wp' || actionId === 'hp') return
|
if (actionId === 'wp' || actionId === 'hp') return
|
||||||
|
|
||||||
if (actionId.includes('_add') || actionId.includes('_subtract')) {
|
if (actionId.includes('_add') || actionId.includes('_subtract')) {
|
||||||
const attr = actionId.split('_')[0]
|
const attr = actionId.split('_')[0]
|
||||||
const action = actionId.split('_')[1]
|
const action = actionId.split('_')[1]
|
||||||
console.log('Updating', attr, 'with action', action)
|
|
||||||
const update = {}
|
const update = {}
|
||||||
update.system = {}
|
update.system = {}
|
||||||
update.system[attr] = {}
|
update.system[attr] = {}
|
||||||
update.system[attr].value = action === 'add' ? this.actor.system[attr].value + 1 : this.actor.system[attr].value - 1
|
update.system[attr].value = action === 'add' ? actor.system[attr].value + 1 : 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
|
if (update.system[attr].value > actor.system[attr].max || update.system[attr].value < actor.system[attr].min) return
|
||||||
return await this.actor.update(update)
|
return await actor.update(update)
|
||||||
}
|
}
|
||||||
if (actionId === 'san') {
|
if (actionId === 'san') {
|
||||||
let item = foundry.utils.duplicate(actor.system.san)
|
let item = foundry.utils.duplicate(actor.system.san)
|
||||||
@@ -155,7 +149,8 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
* @param {string} actionId The action id
|
* @param {string} actionId The action id
|
||||||
*/
|
*/
|
||||||
async #handleWeaponsAction(event, actor, actionId) {
|
async #handleWeaponsAction(event, actor, actionId) {
|
||||||
let weapon = actor.items.find(i => i.type === 'weapon' && i.id === actionId)
|
const weapon = actor.items.find(i => i.type === 'weapon' && i.id === actionId)
|
||||||
|
if (!weapon) return ui.notifications.warn(`Weapon not found for action id '${actionId}'`)
|
||||||
weapon.damageFormula = weapon.system.damage
|
weapon.damageFormula = weapon.system.damage
|
||||||
weapon.damageBonus = actor.system.damageBonus
|
weapon.damageBonus = actor.system.damageBonus
|
||||||
await actor.system.roll('weapon', weapon)
|
await actor.system.roll('weapon', weapon)
|
||||||
@@ -169,7 +164,8 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
* @param {string} actionId The action id
|
* @param {string} actionId The action id
|
||||||
*/
|
*/
|
||||||
async #handleDamageAction(event, actor, actionId) {
|
async #handleDamageAction(event, actor, actionId) {
|
||||||
let weapon = actor.items.find(i => i.type === 'weapon' && i.id === actionId)
|
const weapon = actor.items.find(i => i.type === 'weapon' && i.id === actionId)
|
||||||
|
if (!weapon) return ui.notifications.warn(`Weapon not found for action id '${actionId}'`)
|
||||||
weapon.damageFormula = weapon.system.damage
|
weapon.damageFormula = weapon.system.damage
|
||||||
weapon.damageBonus = actor.system.damageBonus
|
weapon.damageBonus = actor.system.damageBonus
|
||||||
await actor.system.roll('damage', weapon)
|
await actor.system.roll('damage', weapon)
|
||||||
@@ -183,13 +179,13 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
* @param {string} actionId The action id
|
* @param {string} actionId The action id
|
||||||
*/
|
*/
|
||||||
async #handleLethalityAction(event, actor, actionId) {
|
async #handleLethalityAction(event, actor, actionId) {
|
||||||
const item = await this.actor.items.get(actionId)
|
const item = actor.items.get(actionId)
|
||||||
if (item.system.damage !== '' && event.ctrlKey) {
|
if (item.system.damage !== '' && event.ctrlKey) {
|
||||||
const isLethal = !item.system.isLethal
|
const isLethal = !item.system.isLethal
|
||||||
await item.update({ 'system.isLethal': isLethal })
|
await item.update({ 'system.isLethal': isLethal })
|
||||||
} else {
|
} else {
|
||||||
const options = {
|
const options = {
|
||||||
actor: this.actor,
|
actor,
|
||||||
rollType: 'lethality',
|
rollType: 'lethality',
|
||||||
key: item.system.lethality,
|
key: item.system.lethality,
|
||||||
item
|
item
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// 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 { MODULE } from './constants.js'
|
|
||||||
import { DEFAULTS } from './defaults.js'
|
import { DEFAULTS } from './defaults.js'
|
||||||
import * as systemSettings from './settings.js'
|
import * as systemSettings from './settings.js'
|
||||||
|
|
||||||
@@ -79,14 +78,8 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
|||||||
* @returns {object} The TAH system styles
|
* @returns {object} The TAH system styles
|
||||||
*/
|
*/
|
||||||
registerStyles() {
|
registerStyles() {
|
||||||
return {
|
// No system-specific styles; use the core styles only
|
||||||
template: {
|
return {}
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -140,7 +140,6 @@ export default class CthulhuEternalActorSheet extends HandlebarsApplicationMixin
|
|||||||
_onDragOver(event) {}
|
_onDragOver(event) {}
|
||||||
|
|
||||||
async _onDropItem(item) {
|
async _onDropItem(item) {
|
||||||
console.log("Dropped item", item)
|
|
||||||
let itemData = item.toObject()
|
let itemData = item.toObject()
|
||||||
await this.document.createEmbeddedDocuments("Item", [itemData], { renderSheet: false })
|
await this.document.createEmbeddedDocuments("Item", [itemData], { renderSheet: false })
|
||||||
}
|
}
|
||||||
@@ -160,15 +159,12 @@ export default class CthulhuEternalActorSheet extends HandlebarsApplicationMixin
|
|||||||
}
|
}
|
||||||
|
|
||||||
static #onUpdateCheckboxArray(event, target) {
|
static #onUpdateCheckboxArray(event, target) {
|
||||||
console.log("Update checkbox array", event, target)
|
|
||||||
let arrayName = target.dataset.name
|
let arrayName = target.dataset.name
|
||||||
let arrayIdx = Number(target.dataset.index)
|
let arrayIdx = Number(target.dataset.index)
|
||||||
let dataPath = `system.san.${arrayName}`
|
let dataPath = `system.san.${arrayName}`
|
||||||
let tab = foundry.utils.duplicate(this.document.system.san[arrayName])
|
let tab = foundry.utils.duplicate(this.document.system.san[arrayName])
|
||||||
tab[arrayIdx] = target.checked
|
tab[arrayIdx] = target.checked
|
||||||
this.actor.update( { [dataPath]: tab } )
|
this.actor.update( { [dataPath]: tab } )
|
||||||
// Dump
|
|
||||||
console.log("Array name", arrayName, arrayIdx, target.checked, dataPath)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export default class CthulhuEternalProtagonistSheet extends CthulhuEternalActorS
|
|||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setBP: CthulhuEternalProtagonistSheet.#onSetBP,
|
setBP: CthulhuEternalProtagonistSheet.#onSetBP,
|
||||||
|
toggleEquipped: CthulhuEternalProtagonistSheet.#onToggleEquipped,
|
||||||
createGear: CthulhuEternalProtagonistSheet.#onCreateGear,
|
createGear: CthulhuEternalProtagonistSheet.#onCreateGear,
|
||||||
createArmor: CthulhuEternalProtagonistSheet.#onCreateArmor,
|
createArmor: CthulhuEternalProtagonistSheet.#onCreateArmor,
|
||||||
createWeapon: CthulhuEternalProtagonistSheet.#onCreateWeapon,
|
createWeapon: CthulhuEternalProtagonistSheet.#onCreateWeapon,
|
||||||
@@ -155,6 +156,12 @@ export default class CthulhuEternalProtagonistSheet extends CthulhuEternalActorS
|
|||||||
this.document.system.setBP()
|
this.document.system.setBP()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static #onToggleEquipped(event, target) {
|
||||||
|
const itemId = target.dataset.itemId
|
||||||
|
const item = this.document.items.get(itemId)
|
||||||
|
if (item) item.update({ "system.equipped": !item.system.equipped })
|
||||||
|
}
|
||||||
|
|
||||||
static #onCreateGear(event, target) {
|
static #onCreateGear(event, target) {
|
||||||
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("CTHULHUETERNAL.Label.newGear"), type: "gear" }])
|
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("CTHULHUETERNAL.Label.newGear"), type: "gear" }])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ export default class CthulhuEternalSkillSheet extends CthulhuEternalItemSheet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async #onRollProgress(event, target) {
|
static async #onRollProgress(event, target) {
|
||||||
console.log("Rolling progress for skill", this, event, target)
|
|
||||||
if (this.actor) {
|
if (this.actor) {
|
||||||
const roll = await new Roll("1d4").evaluate()
|
const roll = await new Roll("1d4").evaluate()
|
||||||
if (roll) {
|
if (roll) {
|
||||||
|
|||||||
@@ -42,6 +42,12 @@ export default class CthulhuEternalActor extends Actor {
|
|||||||
type: CONST.CHAT_MESSAGE_STYLES.OTHER
|
type: CONST.CHAT_MESSAGE_STYLES.OTHER
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if (this.type === "protagonist" && changed?.system?.hp !== undefined) {
|
||||||
|
const hp = this.system.hp
|
||||||
|
this.toggleStatusEffect("dead", { active: !!hp.dead })
|
||||||
|
this.toggleStatusEffect("unconscious", { active: !!hp.unconscious && !hp.dead })
|
||||||
|
this.toggleStatusEffect("stun", { active: !!hp.stunned && !hp.dead && !hp.unconscious })
|
||||||
|
}
|
||||||
return super._onUpdate(changed, options, userId)
|
return super._onUpdate(changed, options, userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +75,6 @@ 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")
|
||||||
|
|||||||
@@ -290,12 +290,10 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
let era = game.settings.get("fvtt-cthulhu-eternal", "settings-era")
|
let era = game.settings.get("fvtt-cthulhu-eternal", "settings-era")
|
||||||
if (era !== options.rollItem.system.settings) {
|
if (era !== options.rollItem.system.settings) {
|
||||||
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.WrongEra"))
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.WrongEra"))
|
||||||
console.log("WP Wrong Era", era, options.rollItem.system.weaponType)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!SYSTEM.WEAPON_SKILL_MAPPING[era]?.[options.rollItem.system.weaponType]) {
|
if (!SYSTEM.WEAPON_SKILL_MAPPING[era]?.[options.rollItem.system.weaponType]) {
|
||||||
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.NoWeaponType"))
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.NoWeaponType"))
|
||||||
console.log("WP Not found", era, options.rollItem.system.weaponType)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
/*if (!target) {
|
/*if (!target) {
|
||||||
@@ -310,7 +308,13 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
|
|
||||||
options.rollItem = CthulhuEternalUtils.getWeaponSkill(actor, options.rollItem, era)
|
options.rollItem = CthulhuEternalUtils.getWeaponSkill(actor, options.rollItem, era)
|
||||||
options.initialScore = options.rollItem.system.skillTotal
|
options.initialScore = options.rollItem.system.skillTotal
|
||||||
console.log("WEAPON", era, options.rollItem)
|
if (options.weapon.system.state === "junk") {
|
||||||
|
options.isJunk = true
|
||||||
|
options.initialScore = Math.max(0, options.initialScore - 20) // -20% for junk weapons
|
||||||
|
}
|
||||||
|
if (options.weapon.system.state === "worn") {
|
||||||
|
options.isWorn = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
@@ -341,6 +345,8 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
targetScore: options.initialScore,
|
targetScore: options.initialScore,
|
||||||
isLowWP: options.isLowWP,
|
isLowWP: options.isLowWP,
|
||||||
isZeroWP: options.isZeroWP,
|
isZeroWP: options.isZeroWP,
|
||||||
|
isJunk: options.isJunk,
|
||||||
|
isWorn: options.isWorn,
|
||||||
isExhausted: options.isExhausted,
|
isExhausted: options.isExhausted,
|
||||||
enableHand: options.rollItem.enableHand,
|
enableHand: options.rollItem.enableHand,
|
||||||
enableStowed: options.rollItem.enableStowed,
|
enableStowed: options.rollItem.enableStowed,
|
||||||
@@ -434,8 +440,6 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
rollData.rollMode = rollContext.visibility
|
rollData.rollMode = rollContext.visibility
|
||||||
|
|
||||||
// Update target score
|
// Update target score
|
||||||
console.log("Rolldata", rollData)
|
|
||||||
|
|
||||||
if (options.rollType === "resource") {
|
if (options.rollType === "resource") {
|
||||||
rollData.targetScore = options.initialScore * Number(rollContext.multiplier)
|
rollData.targetScore = options.initialScore * Number(rollContext.multiplier)
|
||||||
} else {
|
} else {
|
||||||
@@ -464,14 +468,15 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
const roll = new this(formula, options.data, rollData)
|
const roll = new this(formula, options.data, rollData)
|
||||||
await roll.evaluate()
|
await roll.evaluate()
|
||||||
|
|
||||||
roll.displayRollResult(roll, options, rollData)
|
await roll.displayRollResult(roll, options, rollData)
|
||||||
|
|
||||||
if (Hooks.call("fvtt-cthulhu-eternal.Roll", options, rollData, roll) === false) return
|
if (Hooks.call("fvtt-cthulhu-eternal.Roll", options, rollData, roll) === false) return
|
||||||
|
|
||||||
|
|
||||||
return roll
|
return roll
|
||||||
}
|
}
|
||||||
|
|
||||||
displayRollResult(formula, options, rollData) {
|
async displayRollResult(formula, options, rollData) {
|
||||||
|
|
||||||
// Compute the result quality
|
// Compute the result quality
|
||||||
let resultType = "failure"
|
let resultType = "failure"
|
||||||
@@ -489,6 +494,11 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
resultType = "failureCritical"
|
resultType = "failureCritical"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (rollData.weapon?.system?.state === "junk" && this.total > 95) {
|
||||||
|
this.options.isDestroyed = true
|
||||||
|
rollData.isDestroyed = true
|
||||||
|
resultType = "failureCritical"
|
||||||
|
}
|
||||||
// As per the rules, a roll of 100 is always a failure, even if the target is above 100
|
// As per the rules, a roll of 100 is always a failure, even if the target is above 100
|
||||||
if (this.total === 100) {
|
if (this.total === 100) {
|
||||||
resultType = "failureCritical"
|
resultType = "failureCritical"
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export default class CthulhuEternalArmor extends foundry.abstract.TypeDataModel
|
|||||||
|
|
||||||
schema.protection = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
|
schema.protection = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
|
||||||
schema.resourceLevel = new fields.NumberField({ required: true, initial: 0, min: 0 })
|
schema.resourceLevel = new fields.NumberField({ required: true, initial: 0, min: 0 })
|
||||||
|
schema.equipped = new fields.BooleanField({ required: true, initial: false })
|
||||||
|
|
||||||
return schema
|
return schema
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,6 +127,8 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
|
|||||||
dmgBonus = -2
|
dmgBonus = -2
|
||||||
} else if (this.characteristics.str.value <= 8) {
|
} else if (this.characteristics.str.value <= 8) {
|
||||||
dmgBonus = -1
|
dmgBonus = -1
|
||||||
|
} else if (this.characteristics.str.value <= 12) {
|
||||||
|
dmgBonus = 0
|
||||||
} else if (this.characteristics.str.value <= 16) {
|
} else if (this.characteristics.str.value <= 16) {
|
||||||
dmgBonus = 1
|
dmgBonus = 1
|
||||||
} else if (this.characteristics.str.value <= 40) {
|
} else if (this.characteristics.str.value <= 40) {
|
||||||
@@ -275,7 +277,6 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
|
|||||||
template = "systems/fvtt-cthulhu-eternal/templates/chat-san-loss-none.hbs"
|
template = "systems/fvtt-cthulhu-eternal/templates/chat-san-loss-none.hbs"
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("CthulhuEternalProtagonist.applySANConsequences", rollData, updates, template)
|
|
||||||
let content = await foundry.applications.handlebars.renderTemplate(template, msgData)
|
let content = await foundry.applications.handlebars.renderTemplate(template, msgData)
|
||||||
let msg = await ChatMessage.create({
|
let msg = await ChatMessage.create({
|
||||||
content: content,
|
content: content,
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ export default class CthulhuEternalWeapon extends foundry.abstract.TypeDataModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
isRanged() {
|
isRanged() {
|
||||||
console.log("isRanged", this.weaponType, this)
|
|
||||||
return this.weaponType.match("ranged")
|
return this.weaponType.match("ranged")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+62
-11
@@ -118,9 +118,6 @@ export default class CthulhuEternalUtils {
|
|||||||
return Object.keys(obj).length;
|
return Object.keys(obj).length;
|
||||||
})
|
})
|
||||||
|
|
||||||
Handlebars.registerHelper('isEnabled', function (configKey) {
|
|
||||||
return game.settings.get("bol", configKey);
|
|
||||||
})
|
|
||||||
Handlebars.registerHelper('split', function (str, separator, keep) {
|
Handlebars.registerHelper('split', function (str, separator, keep) {
|
||||||
return str.split(separator)[keep];
|
return str.split(separator)[keep];
|
||||||
})
|
})
|
||||||
@@ -164,7 +161,6 @@ export default class CthulhuEternalUtils {
|
|||||||
return eval(expr);
|
return eval(expr);
|
||||||
})
|
})
|
||||||
Handlebars.registerHelper('isOwnerOrGM', function (actor) {
|
Handlebars.registerHelper('isOwnerOrGM', function (actor) {
|
||||||
console.log("Testing actor", actor.isOwner, game.userId)
|
|
||||||
return actor.isOwner || game.isGM;
|
return actor.isOwner || game.isGM;
|
||||||
})
|
})
|
||||||
Handlebars.registerHelper('upperFirst', function (text) {
|
Handlebars.registerHelper('upperFirst', function (text) {
|
||||||
@@ -382,8 +378,6 @@ export default class CthulhuEternalUtils {
|
|||||||
loser = { actor: actor1, rollData: roll1.rollData, messageId: roll1.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
|
// Check if winner was attacking with a weapon that can apply damage
|
||||||
let canApplyDamage = winner && winner.rollData?.weapon && winner.rollData.weapon.system
|
let canApplyDamage = winner && winner.rollData?.weapon && winner.rollData.weapon.system
|
||||||
|
|
||||||
@@ -476,13 +470,72 @@ export default class CthulhuEternalUtils {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
rollData.weapon.damageFormula = formula || rollData.weapon.system.damage
|
rollData.weapon.damageFormula = formula || rollData.weapon.system.damage
|
||||||
actor.system.roll("damage", rollData.weapon)
|
actor.system.roll("damage", rollData.weapon)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async wornWeaponCheck(rollMessage) {
|
||||||
|
let rollData = rollMessage.rolls[0]?.options?.rollData
|
||||||
|
if (!rollData) {
|
||||||
|
rollData = rollMessage.getFlag("fvtt-cthulhu-eternal", "rollData")
|
||||||
|
}
|
||||||
|
if (!rollData) {
|
||||||
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Label.noRollDataFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let actor = game.actors.get(rollData.actorId)
|
||||||
|
if (!actor) {
|
||||||
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Label.noActorFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let weapon = rollData.weapon
|
||||||
|
if (!weapon) {
|
||||||
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Label.noWeaponFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lance un jet de chance (50%)
|
||||||
|
let luckRoll = new Roll("1d100")
|
||||||
|
await luckRoll.evaluate()
|
||||||
|
|
||||||
|
let isSuccess = luckRoll.total <= 50
|
||||||
|
let resultMsg = ""
|
||||||
|
|
||||||
|
if (isSuccess) {
|
||||||
|
// Succès - l'arme reste worn
|
||||||
|
resultMsg = game.i18n.format("CTHULHUETERNAL.Label.wornWeaponCheckSuccess", {
|
||||||
|
weapon: weapon.name,
|
||||||
|
roll: luckRoll.total
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Échec - l'arme devient junk
|
||||||
|
resultMsg = game.i18n.format("CTHULHUETERNAL.Label.wornWeaponCheckFailure", {
|
||||||
|
weapon: weapon.name,
|
||||||
|
roll: luckRoll.total
|
||||||
|
})
|
||||||
|
|
||||||
|
// Mettre à jour l'état de l'arme
|
||||||
|
await actor.updateEmbeddedDocuments("Item", [{
|
||||||
|
_id: weapon._id,
|
||||||
|
"system.state": "junk"
|
||||||
|
}])
|
||||||
|
|
||||||
|
ui.notifications.warn(game.i18n.format("CTHULHUETERNAL.Notifications.WeaponBecameJunk", { weapon: weapon.name }))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Créer un message de chat avec le résultat
|
||||||
|
await ChatMessage.create({
|
||||||
|
user: game.user.id,
|
||||||
|
content: `<div class="cthulhu-eternal-roll">
|
||||||
|
<h4>${game.i18n.localize("CTHULHUETERNAL.Label.wornWeaponCheckTitle")}</h4>
|
||||||
|
<p>${resultMsg}</p>
|
||||||
|
</div>`,
|
||||||
|
speaker: ChatMessage.getSpeaker({ actor: actor }),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
static async nudgeRoll(rollMessage) {
|
static async nudgeRoll(rollMessage) {
|
||||||
|
|
||||||
let dialogContext = rollMessage.rolls[0]?.options
|
let dialogContext = rollMessage.rolls[0]?.options
|
||||||
@@ -495,7 +548,6 @@ export default class CthulhuEternalUtils {
|
|||||||
|
|
||||||
// Build options table for the select operator between minValue and maxValue
|
// Build options table for the select operator between minValue and maxValue
|
||||||
dialogContext.nudgeOptions = Array.from({ length: dialogContext.maxValue - dialogContext.minValue + 1 }, (_, i) => dialogContext.minValue + i)
|
dialogContext.nudgeOptions = Array.from({ length: dialogContext.maxValue - dialogContext.minValue + 1 }, (_, i) => dialogContext.minValue + i)
|
||||||
console.log(dialogContext)
|
|
||||||
|
|
||||||
const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/nudge-dialog.hbs", dialogContext)
|
const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/nudge-dialog.hbs", dialogContext)
|
||||||
|
|
||||||
@@ -590,12 +642,11 @@ 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
|
// Remove the chat message
|
||||||
this.removeChatMessageId(message.id)
|
this.removeChatMessageId(message.id)
|
||||||
|
|
||||||
// Get the targetted actorId from the HTML select event
|
// Get the targetted actorId from the button's data attribute
|
||||||
let targetCombatantId = event.target.value
|
let targetCombatantId = event.currentTarget.dataset.combatantId
|
||||||
let combatant = game.combat.combatants.get(targetCombatantId)
|
let combatant = game.combat.combatants.get(targetCombatantId)
|
||||||
let targetActor = combatant.token?.actor || game.actors.get(combatant.actorId)
|
let targetActor = combatant.token?.actor || game.actors.get(combatant.actorId)
|
||||||
if (!targetActor) {
|
if (!targetActor) {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
MANIFEST-000269
|
MANIFEST-000281
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2025/11/12-23:48:30.686758 7f4781ffb6c0 Recovering log #267
|
2026/04/01-22:53:01.206674 7fcc60fed6c0 Recovering log #279
|
||||||
2025/11/12-23:48:30.697449 7f4781ffb6c0 Delete type=3 #265
|
2026/04/01-22:53:01.217456 7fcc60fed6c0 Delete type=3 #277
|
||||||
2025/11/12-23:48:30.697507 7f4781ffb6c0 Delete type=0 #267
|
2026/04/01-22:53:01.217537 7fcc60fed6c0 Delete type=0 #279
|
||||||
2025/11/13-13:58:42.410831 7f4780bff6c0 Level-0 table #272: started
|
2026/04/01-22:56:08.533863 7fcc4affd6c0 Level-0 table #284: started
|
||||||
2025/11/13-13:58:42.410865 7f4780bff6c0 Level-0 table #272: 0 bytes OK
|
2026/04/01-22:56:08.533906 7fcc4affd6c0 Level-0 table #284: 0 bytes OK
|
||||||
2025/11/13-13:58:42.417362 7f4780bff6c0 Delete type=0 #270
|
2026/04/01-22:56:08.586584 7fcc4affd6c0 Delete type=0 #282
|
||||||
2025/11/13-13:58:42.434870 7f4780bff6c0 Manual compaction at level-0 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end)
|
2026/04/01-22:56:08.586750 7fcc4affd6c0 Manual compaction at level-0 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2025/11/12-23:40:11.531092 7f47827fc6c0 Recovering log #263
|
2025/12/23-21:58:00.777018 7f1118ff96c0 Recovering log #275
|
||||||
2025/11/12-23:40:11.541025 7f47827fc6c0 Delete type=0 #263
|
2025/12/23-21:58:00.909461 7f1118ff96c0 Delete type=3 #273
|
||||||
2025/11/12-23:40:11.541091 7f47827fc6c0 Delete type=3 #261
|
2025/12/23-21:58:00.909547 7f1118ff96c0 Delete type=0 #275
|
||||||
2025/11/12-23:40:47.861546 7f4780bff6c0 Level-0 table #268: started
|
2025/12/23-22:36:20.406495 7f0e7bfff6c0 Level-0 table #280: started
|
||||||
2025/11/12-23:40:47.861580 7f4780bff6c0 Level-0 table #268: 0 bytes OK
|
2025/12/23-22:36:20.406537 7f0e7bfff6c0 Level-0 table #280: 0 bytes OK
|
||||||
2025/11/12-23:40:47.867844 7f4780bff6c0 Delete type=0 #266
|
2025/12/23-22:36:20.412428 7f0e7bfff6c0 Delete type=0 #278
|
||||||
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)
|
2025/12/23-22:36:20.419890 7f0e7bfff6c0 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-000438
|
MANIFEST-000450
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2025/11/12-23:48:30.659183 7f47817fa6c0 Recovering log #436
|
2026/04/01-22:53:01.173017 7fcc60fed6c0 Recovering log #448
|
||||||
2025/11/12-23:48:30.670042 7f47817fa6c0 Delete type=3 #434
|
2026/04/01-22:53:01.184049 7fcc60fed6c0 Delete type=3 #446
|
||||||
2025/11/12-23:48:30.670124 7f47817fa6c0 Delete type=0 #436
|
2026/04/01-22:53:01.184114 7fcc60fed6c0 Delete type=0 #448
|
||||||
2025/11/13-13:58:42.417482 7f4780bff6c0 Level-0 table #441: started
|
2026/04/01-22:56:08.365689 7fcc4affd6c0 Level-0 table #453: started
|
||||||
2025/11/13-13:58:42.417509 7f4780bff6c0 Level-0 table #441: 0 bytes OK
|
2026/04/01-22:56:08.365761 7fcc4affd6c0 Level-0 table #453: 0 bytes OK
|
||||||
2025/11/13-13:58:42.423396 7f4780bff6c0 Delete type=0 #439
|
2026/04/01-22:56:08.421424 7fcc4affd6c0 Delete type=0 #451
|
||||||
2025/11/13-13:58:42.434882 7f4780bff6c0 Manual compaction at level-0 from '!folders!5PrT9QmN1cFPzDFP' @ 72057594037927935 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at (end)
|
2026/04/01-22:56:08.586720 7fcc4affd6c0 Manual compaction at level-0 from '!folders!5PrT9QmN1cFPzDFP' @ 72057594037927935 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2025/11/12-23:40:11.502931 7f4781ffb6c0 Recovering log #432
|
2025/12/23-21:58:00.532068 7f1119ffb6c0 Recovering log #444
|
||||||
2025/11/12-23:40:11.512928 7f4781ffb6c0 Delete type=0 #432
|
2025/12/23-21:58:00.647819 7f1119ffb6c0 Delete type=3 #442
|
||||||
2025/11/12-23:40:11.512984 7f4781ffb6c0 Delete type=3 #430
|
2025/12/23-21:58:00.647954 7f1119ffb6c0 Delete type=0 #444
|
||||||
2025/11/12-23:40:47.855365 7f4780bff6c0 Level-0 table #437: started
|
2025/12/23-22:36:20.355345 7f0e7bfff6c0 Level-0 table #449: started
|
||||||
2025/11/12-23:40:47.855411 7f4780bff6c0 Level-0 table #437: 0 bytes OK
|
2025/12/23-22:36:20.355397 7f0e7bfff6c0 Level-0 table #449: 0 bytes OK
|
||||||
2025/11/12-23:40:47.861414 7f4780bff6c0 Delete type=0 #435
|
2025/12/23-22:36:20.362045 7f0e7bfff6c0 Delete type=0 #447
|
||||||
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)
|
2025/12/23-22:36:20.385891 7f0e7bfff6c0 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-000084
|
MANIFEST-000096
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2025/11/12-23:48:30.674156 7f4781ffb6c0 Recovering log #82
|
2026/04/01-22:53:01.192292 7fcc4b7fe6c0 Recovering log #94
|
||||||
2025/11/12-23:48:30.683495 7f4781ffb6c0 Delete type=3 #80
|
2026/04/01-22:53:01.202349 7fcc4b7fe6c0 Delete type=3 #92
|
||||||
2025/11/12-23:48:30.683546 7f4781ffb6c0 Delete type=0 #82
|
2026/04/01-22:53:01.202397 7fcc4b7fe6c0 Delete type=0 #94
|
||||||
2025/11/13-13:58:42.404378 7f4780bff6c0 Level-0 table #87: started
|
2026/04/01-22:56:08.421577 7fcc4affd6c0 Level-0 table #99: started
|
||||||
2025/11/13-13:58:42.404437 7f4780bff6c0 Level-0 table #87: 0 bytes OK
|
2026/04/01-22:56:08.421606 7fcc4affd6c0 Level-0 table #99: 0 bytes OK
|
||||||
2025/11/13-13:58:42.410719 7f4780bff6c0 Delete type=0 #85
|
2026/04/01-22:56:08.475595 7fcc4affd6c0 Delete type=0 #97
|
||||||
2025/11/13-13:58:42.434856 7f4780bff6c0 Manual compaction at level-0 from '!folders!0DI3T2jve3nsmsfZ' @ 72057594037927935 : 1 .. '!items!zyxA9DhO36t5OBDv' @ 0 : 0; will stop at (end)
|
2026/04/01-22:56:08.586731 7fcc4affd6c0 Manual compaction at level-0 from '!folders!0DI3T2jve3nsmsfZ' @ 72057594037927935 : 1 .. '!items!zyxA9DhO36t5OBDv' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
2025/11/12-23:40:11.517421 7f4782ffd6c0 Recovering log #78
|
2025/12/23-21:58:00.654695 7f1119ffb6c0 Recovering log #90
|
||||||
2025/11/12-23:40:11.527038 7f4782ffd6c0 Delete type=0 #78
|
2025/12/23-21:58:00.773269 7f1119ffb6c0 Delete type=3 #88
|
||||||
2025/11/12-23:40:11.527106 7f4782ffd6c0 Delete type=3 #76
|
2025/12/23-21:58:00.773360 7f1119ffb6c0 Delete type=0 #90
|
||||||
2025/11/12-23:40:47.867960 7f4780bff6c0 Level-0 table #83: started
|
2025/12/23-22:36:20.362172 7f0e7bfff6c0 Level-0 table #95: started
|
||||||
2025/11/12-23:40:47.867984 7f4780bff6c0 Level-0 table #83: 0 bytes OK
|
2025/12/23-22:36:20.362202 7f0e7bfff6c0 Level-0 table #95: 0 bytes OK
|
||||||
2025/11/12-23:40:47.874660 7f4780bff6c0 Delete type=0 #81
|
2025/12/23-22:36:20.368698 7f0e7bfff6c0 Delete type=0 #93
|
||||||
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)
|
2025/12/23-22:36:20.385910 7f0e7bfff6c0 Manual compaction at level-0 from '!folders!0DI3T2jve3nsmsfZ' @ 72057594037927935 : 1 .. '!items!zyxA9DhO36t5OBDv' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
+27
-4
@@ -111,8 +111,8 @@ i.fvtt-cthulhu-eternal {
|
|||||||
padding: 2px 2px;
|
padding: 2px 2px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background-color 0.3s;
|
transition: background-color 0.3s;
|
||||||
min-width: 6.0rem;
|
min-width: 6rem;
|
||||||
max-width: 6.0rem;
|
max-width: 6rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.san-loose-buttons {
|
.san-loose-buttons {
|
||||||
@@ -128,8 +128,8 @@ i.fvtt-cthulhu-eternal {
|
|||||||
padding: 2px 2px;
|
padding: 2px 2px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background-color 0.3s;
|
transition: background-color 0.3s;
|
||||||
min-width: 3.0rem;
|
min-width: 3rem;
|
||||||
max-width: 3.0rem;
|
max-width: 3rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.result-non-lethal {
|
.result-non-lethal {
|
||||||
@@ -141,5 +141,28 @@ i.fvtt-cthulhu-eternal {
|
|||||||
font-family: var(--font-primary);
|
font-family: var(--font-primary);
|
||||||
font-size: calc(var(--font-size-standard) * 1.02);
|
font-size: calc(var(--font-size-standard) * 1.02);
|
||||||
}
|
}
|
||||||
|
.combatants-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
gap: 4px;
|
||||||
|
margin: 8px 0;
|
||||||
|
button.apply-wounds-btn {
|
||||||
|
font-family: var(--font-primary);
|
||||||
|
font-size: calc(var(--font-size-standard) * 0.7);
|
||||||
|
border: 1px solid #4b4a44;
|
||||||
|
padding: 4px 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
background-color: #f0f0e0;
|
||||||
|
color: #1c1c1c;
|
||||||
|
&:hover {
|
||||||
|
background-color: #d5d5c5;
|
||||||
|
border-color: #2d2d2a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@
|
|||||||
},
|
},
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"minimum": "13",
|
"minimum": "13",
|
||||||
"verified": "13"
|
"verified": "14"
|
||||||
},
|
},
|
||||||
"esmodules": [
|
"esmodules": [
|
||||||
"cthulhu-eternal.mjs"
|
"cthulhu-eternal.mjs"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
{{formField systemFields.settings value=system.settings localize=true}}
|
{{formField systemFields.settings value=system.settings localize=true}}
|
||||||
{{formField systemFields.protection value=system.protection}}
|
{{formField systemFields.protection value=system.protection}}
|
||||||
{{formField systemFields.resourceLevel value=system.resourceLevel}}
|
{{formField systemFields.resourceLevel value=system.resourceLevel}}
|
||||||
|
{{formField systemFields.equipped value=system.equipped}}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,13 @@
|
|||||||
: -20%</li>
|
: -20%</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if isWorn}}
|
||||||
|
<li class="orange-warning"><i
|
||||||
|
class="fa-solid fa-triangle-exclamation"
|
||||||
|
></i>
|
||||||
|
{{localize "CTHULHUETERNAL.Label.wornWeaponWarning"}}</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{#if (eq rollType "resource")}}
|
{{#if (eq rollType "resource")}}
|
||||||
<li>{{localize "CTHULHUETERNAL.Label.multiplier"}}
|
<li>{{localize "CTHULHUETERNAL.Label.multiplier"}}
|
||||||
:
|
:
|
||||||
@@ -206,6 +213,18 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (eq rollType "weapon")}}
|
||||||
|
{{#if isWorn}}
|
||||||
|
<a
|
||||||
|
class="worn-weapon-check chat-action-button"
|
||||||
|
data-weapon-id="{{weapon.id}}"
|
||||||
|
data-tooltip="{{localize 'CTHULHUETERNAL.Label.wornWeaponCheck'}}"
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-dice"></i>
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{#if isFailure}}
|
{{#if isFailure}}
|
||||||
{{#if isNudge}}
|
{{#if isNudge}}
|
||||||
<a
|
<a
|
||||||
|
|||||||
@@ -1,34 +1,58 @@
|
|||||||
<div class="{{cssClass}}">
|
<div class="{{cssClass}}">
|
||||||
<div class="chat-lethal-damage">
|
<div class="chat-lethal-damage">
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>{{weapon.name}} : {{localize "CTHULHUETERNAL.Label.damageRoll"}}</strong></li>
|
<li><strong>{{weapon.name}}
|
||||||
<li>{{localize "CTHULHUETERNAL.Label.result"}} :{{rollResult}} ({{formula}})</li>
|
:
|
||||||
|
{{localize "CTHULHUETERNAL.Label.damageRoll"}}</strong></li>
|
||||||
|
<li>{{localize "CTHULHUETERNAL.Label.result"}}
|
||||||
|
:{{rollResult}}
|
||||||
|
({{formula}})</li>
|
||||||
|
|
||||||
{{#if (gt weapon.system.killRadius 0)}}
|
{{#if (gt weapon.system.killRadius 0)}}
|
||||||
<li>{{localize "CTHULHUETERNAL.Label.killRadius"}} : {{weapon.system.killRadius}} {{weapon.system.rangeUnit}}</li>
|
<li>{{localize "CTHULHUETERNAL.Label.killRadius"}}
|
||||||
<li>{{localize "CTHULHUETERNAL.Label.killRadiusInfo"}}</li>
|
:
|
||||||
|
{{weapon.system.killRadius}}
|
||||||
|
{{weapon.system.rangeUnit}}</li>
|
||||||
|
<li>{{localize "CTHULHUETERNAL.Label.killRadiusInfo"}}</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if (gt weapon.system.armorPiercing 0)}}
|
{{#if (gt weapon.system.armorPiercing 0)}}
|
||||||
<li>{{localize "CTHULHUETERNAL.Label.armorPiercing"}} : {{weapon.system.armorPiercing}}</li>
|
<li>{{localize "CTHULHUETERNAL.Label.armorPiercing"}}
|
||||||
|
:
|
||||||
|
{{weapon.system.armorPiercing}}</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (gt weapon.system.penetration 0)}}
|
{{#if (gt weapon.system.penetration 0)}}
|
||||||
<li>{{localize "CTHULHUETERNAL.Label.penetration"}} : {{weapon.system.penetration}}</li>
|
<li>{{localize "CTHULHUETERNAL.Label.penetration"}}
|
||||||
|
:
|
||||||
|
{{weapon.system.penetration}}</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if ammoUsed}}
|
{{#if ammoUsed}}
|
||||||
<li>{{localize "CTHULHUETERNAL.Label.ammoUsed"}}: {{ammoUsed}} / {{weapon.system.ammo.value}}</li>
|
<li>{{localize "CTHULHUETERNAL.Label.ammoUsed"}}:
|
||||||
|
{{ammoUsed}}
|
||||||
|
/
|
||||||
|
{{weapon.system.ammo.value}}</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<li class="li-apply-wounds">
|
<li class="li-apply-wounds">
|
||||||
{{localize "CTHULHUETERNAL.Label.applyWounds"}}
|
<div>{{localize "CTHULHUETERNAL.Label.applyWounds"}}</div>
|
||||||
<select name="combatant" class="li-apply-wounds-select">
|
<div class="combatants-grid">
|
||||||
<option value="none"></option>
|
{{#each combatants}}
|
||||||
{{selectOptions combatants valueAttr="id" labelAttr="name"}}
|
<button
|
||||||
</select>
|
class="apply-wounds-btn"
|
||||||
|
data-combatant-id="{{this.id}}"
|
||||||
|
title="{{this.name}}"
|
||||||
|
>
|
||||||
|
{{this.name}}
|
||||||
|
</button>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="result-non-lethal">{{localize "CTHULHUETERNAL.Label.damageMessage"}}: <strong>{{rollResult}}</strong>
|
<li class="result-non-lethal">{{localize
|
||||||
|
"CTHULHUETERNAL.Label.damageMessage"
|
||||||
|
}}:
|
||||||
|
<strong>{{rollResult}}</strong>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{{localize "CTHULHUETERNAL.Label.description"}}</legend>
|
<legend>{{localize "CTHULHUETERNAL.Label.description"}}</legend>
|
||||||
{{formInput systemFields.description enriched=enrichedDescriptionw value=system.description name="system.description" toggled=true}}
|
{{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
{{#each weapons as |item|}}
|
{{#each weapons as |item|}}
|
||||||
{{!log 'weapon' this}}
|
{{!log 'weapon' this}}
|
||||||
<div class="weapon item" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true">
|
<div class="weapon item" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true">
|
||||||
|
<!-- content -->
|
||||||
<img class="item-img" src="{{item.img}}" data-tooltip="{{item.name}}" />
|
<img class="item-img" src="{{item.img}}" data-tooltip="{{item.name}}" />
|
||||||
<img src="systems/fvtt-cthulhu-eternal/assets/ui/d100.svg" class="d100" />
|
<img src="systems/fvtt-cthulhu-eternal/assets/ui/d100.svg" class="d100" />
|
||||||
<div class="name rollable" data-roll-type="weapon" data-tooltip="{{{item.system.description}}}">
|
<div class="name rollable" data-roll-type="weapon" data-tooltip="{{{item.system.description}}}">
|
||||||
@@ -81,6 +81,8 @@
|
|||||||
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
|
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="empty-state">{{localize "CTHULHUETERNAL.Label.noWeapons"}}</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -99,6 +101,13 @@
|
|||||||
{{item.name}}
|
{{item.name}}
|
||||||
</div>
|
</div>
|
||||||
<span class="protection">{{localize "CTHULHUETERNAL.Label.armor"}} : {{item.system.protection}}</span>
|
<span class="protection">{{localize "CTHULHUETERNAL.Label.armor"}} : {{item.system.protection}}</span>
|
||||||
|
<a class="equipped-toggle {{#if item.system.equipped}}active{{/if}}"
|
||||||
|
data-action="toggleEquipped"
|
||||||
|
data-item-id="{{item.id}}"
|
||||||
|
data-item-uuid="{{item.uuid}}"
|
||||||
|
data-tooltip="{{#if item.system.equipped}}{{localize 'CTHULHUETERNAL.Label.equipped'}}{{else}}{{localize 'CTHULHUETERNAL.Label.unequipped'}}{{/if}}">
|
||||||
|
<i class="fas {{#if item.system.equipped}}fa-shield-halved{{else}}fa-shield{{/if}}"></i>
|
||||||
|
</a>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<a data-tooltip="{{localize 'CTHULHUETERNAL.Edit'}}" data-action="edit" data-item-id="{{item.id}}"
|
<a data-tooltip="{{localize 'CTHULHUETERNAL.Edit'}}" data-action="edit" data-item-id="{{item.id}}"
|
||||||
data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
|
data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
|
||||||
@@ -106,6 +115,8 @@
|
|||||||
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
|
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="empty-state">{{localize "CTHULHUETERNAL.Label.noArmors"}}</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -130,6 +141,8 @@
|
|||||||
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
|
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="empty-state">{{localize "CTHULHUETERNAL.Label.noGears"}}</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
<a data-tooltip="{{localize 'CTHULHUETERNAL.Delete'}}" data-action="delete" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
|
<a data-tooltip="{{localize 'CTHULHUETERNAL.Delete'}}" data-action="delete" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="empty-state">{{localize "CTHULHUETERNAL.Label.noSkills"}}</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|||||||
@@ -44,6 +44,16 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if weapon}}
|
{{#if weapon}}
|
||||||
|
{{#if isJunk}}
|
||||||
|
<div class="dialog-skill red-warning">{{localize
|
||||||
|
"CTHULHUETERNAL.Label.JunkWeapon"
|
||||||
|
}}</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if isWorn}}
|
||||||
|
<div class="dialog-skill orange-warning">{{localize
|
||||||
|
"CTHULHUETERNAL.Label.WornWeapon"
|
||||||
|
}}</div>
|
||||||
|
{{/if}}
|
||||||
<div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Weapon"}}
|
<div class="dialog-skill">{{localize "CTHULHUETERNAL.Label.Weapon"}}
|
||||||
:
|
:
|
||||||
{{weapon.name}}</div>
|
{{weapon.name}}</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user