Full SAN management
This commit is contained in:
@ -170,6 +170,7 @@ i.fvtt-cthulhu-eternal {
|
|||||||
background-position: 0%;
|
background-position: 0%;
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
}
|
}
|
||||||
|
.chat-san-request ul,
|
||||||
.chat-lethal-damage ul {
|
.chat-lethal-damage ul {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@ -177,14 +178,36 @@ i.fvtt-cthulhu-eternal {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
.chat-san-request ul .result-lethal,
|
||||||
.chat-lethal-damage ul .result-lethal {
|
.chat-lethal-damage ul .result-lethal {
|
||||||
color: var(--color-critical-failure);
|
color: var(--color-critical-failure);
|
||||||
font-family: var(--font-title);
|
font-family: var(--font-title);
|
||||||
}
|
}
|
||||||
|
.chat-san-request ul .san-loose-buttons,
|
||||||
|
.chat-lethal-damage ul .san-loose-buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
.chat-san-request ul .san-loose-buttons button,
|
||||||
|
.chat-lethal-damage ul .san-loose-buttons button {
|
||||||
|
margin: 0 2px;
|
||||||
|
font-family: var(--font-primary);
|
||||||
|
font-size: calc(var(--font-size-standard) * 1.1);
|
||||||
|
border: none;
|
||||||
|
padding: 2px 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
min-width: 3rem;
|
||||||
|
max-width: 3rem;
|
||||||
|
}
|
||||||
|
.chat-san-request ul .result-non-lethal,
|
||||||
.chat-lethal-damage ul .result-non-lethal {
|
.chat-lethal-damage ul .result-non-lethal {
|
||||||
color: var(--color-failure);
|
color: var(--color-failure);
|
||||||
font-family: var(--font-title);
|
font-family: var(--font-title);
|
||||||
}
|
}
|
||||||
|
.chat-san-request ul li,
|
||||||
.chat-lethal-damage ul li {
|
.chat-lethal-damage ul li {
|
||||||
margin: 0 10px;
|
margin: 0 10px;
|
||||||
font-family: var(--font-primary);
|
font-family: var(--font-primary);
|
||||||
@ -454,6 +477,14 @@ i.fvtt-cthulhu-eternal {
|
|||||||
min-width: 6rem;
|
min-width: 6rem;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .san-helplessness,
|
||||||
|
.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .san-violence {
|
||||||
|
display: flex;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .label-san-type {
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .label-bp {
|
.fvtt-cthulhu-eternal .protagonist-main .protagonist-pc .protagonist-right .san .label-bp {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
max-width: 3rem;
|
max-width: 3rem;
|
||||||
|
@ -156,14 +156,15 @@ 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(".san-loose").click((event) => {
|
||||||
|
CthulhuEternalUtils.applySANLoss(message, event)
|
||||||
|
})
|
||||||
|
$(html).find(".san-type").click((event) => {
|
||||||
|
CthulhuEternalUtils.applySANType(message, event)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Dice-so-nice Ready
|
|
||||||
Hooks.once("diceSoNiceReady", (dice3d) => {
|
|
||||||
//configureDiceSoNice(dice3d)
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a macro when dropping an entity on the hotbar
|
* Create a macro when dropping an entity on the hotbar
|
||||||
* Item - open roll dialog
|
* Item - open roll dialog
|
||||||
|
21
lang/en.json
21
lang/en.json
@ -516,6 +516,22 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Label": {
|
"Label": {
|
||||||
|
"sanLoss5": "You suffered a SAN loss of 5+ ({value}) : you suffer a temporary insanity (Flee, Submit, Struggle or understanding the Unnatural).",
|
||||||
|
"sanViolenceReset": "The violence SAN loss count has been reset.",
|
||||||
|
"sanHelplessnessReset": "The helplessness SAN loss count has been reset.",
|
||||||
|
"sanLoss": "You suffer a SAN loss",
|
||||||
|
"selectSANType": "Select the type of SAN loss with the buttons below.",
|
||||||
|
"Violence" : "Violence",
|
||||||
|
"Helplessness": "Helplessness",
|
||||||
|
"Unnatural": "Unnatural",
|
||||||
|
"sanLossViolence": "You suffered a SAN loss due to violence : violence progress path has evolved.",
|
||||||
|
"sanLossHelplessness": "You suffered a SAN loss due to helplessness : helplessness progress path has evolved.",
|
||||||
|
"adaptedToViolence": "You are now : Adapted to Violence.",
|
||||||
|
"adaptedToViolenceShort": "Adapted to Violence",
|
||||||
|
"adaptedToHelplessness": "You are now : Adapted to Helplessness.",
|
||||||
|
"adaptedToHelplessnessShort": "Adapted to Helplessness",
|
||||||
|
"SANTest": "You just rolled a SAN test : please select the SAN loss with the buttons below.",
|
||||||
|
"breakingPointReached": "Your SAN has reached your Breaking Point : you suffer a disorder (to be discussed with the GM). Reset the BP to its new value.",
|
||||||
"rollNudge": "Roll Nudge",
|
"rollNudge": "Roll Nudge",
|
||||||
"rollDamage": "Roll Damage",
|
"rollDamage": "Roll Damage",
|
||||||
"rollHealing": "Roll Healing",
|
"rollHealing": "Roll Healing",
|
||||||
@ -693,7 +709,10 @@
|
|||||||
"skillAlreadyExists": "Skill already exists",
|
"skillAlreadyExists": "Skill already exists",
|
||||||
"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. ",
|
||||||
|
"noRollDataFound": "No roll data found",
|
||||||
|
"noActorFound": "No actor found for this item.",
|
||||||
|
"noSanLossFound": "No SAN loss value found."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
lang/fr.json
23
lang/fr.json
@ -516,6 +516,24 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Label": {
|
"Label": {
|
||||||
|
"sanLoss5": "Perte de SAN de 5+ ({value}) : vous souffrez d'une folie temporaire (Fuite, Soumission, Lutte ou compréhension de l'Inconcevable).",
|
||||||
|
"sanViolenceReset": "Le décompte des pertes de SAN de violence a été réinitialisé.",
|
||||||
|
"sanHelplessnessReset": "Le décompte des pertes de SAN d'impuissance a été réinitialisé.",
|
||||||
|
"sanLoss": "Perte de SAN",
|
||||||
|
"noSanLoss": "Aucune perte de SAN",
|
||||||
|
"sanLossInfo": "Sélectionnez la perte de SAN à l'aide des boutons ci-dessous.",
|
||||||
|
"selectSANType": "Sélectionnez le type de perte de SAN à l'aide des boutons ci-dessous.",
|
||||||
|
"sanLossViolence": "Vous avez subi une perte de SAN due à la violence : le chemin de progression de la violence a évolué.",
|
||||||
|
"sanLossHelplessness": "Vous avez subi une perte de SAN due à l'impuissance : le chemin de progression de l'impuissance a évolué.",
|
||||||
|
"adaptedToViolence": "Vous êtes maintenant : Habitué à la violence",
|
||||||
|
"adaptedToViolenceShort": "Habitué à la violence",
|
||||||
|
"adaptedToHelplessness": "Vous êtes maintenant : Habitué à l'impuissance",
|
||||||
|
"adaptedToHelplessnessShort": "Habitué à l'impuissance",
|
||||||
|
"SANTest": "Vous venez de faire un jet de SAN : selectionnez la perte de SAN à l'aide des boutons ci-dessous.",
|
||||||
|
"breakingPointReached": "Vous avez atteint votre Point de Rupture (PR) : vous souffrez d'un trouble mental. Vous devez re-initialiser votre PR à l'aide du bouton disponible dans la section SAN de la fiche de PJ.",
|
||||||
|
"Violence" : "Violence",
|
||||||
|
"Helplessness": "Impuissance",
|
||||||
|
"Unnatural": "Inconcevable",
|
||||||
"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",
|
||||||
@ -693,7 +711,10 @@
|
|||||||
"skillAlreadyExists": "La compétence existe déja",
|
"skillAlreadyExists": "La compétence existe déja",
|
||||||
"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.",
|
||||||
|
"noRollDataFound": "Aucune donnée de jet trouvée.",
|
||||||
|
"noActorFound": "Aucun protagoniste trouvé.",
|
||||||
|
"noSanLossFound": "Aucune valeur de perte de SAN trouvée."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,7 @@ export default class CthulhuEternalProtagonistSheet extends CthulhuEternalActorS
|
|||||||
|
|
||||||
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
|
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
|
||||||
context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes, { async: true })
|
context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes, { async: true })
|
||||||
|
context.isGM = game.user.isGM
|
||||||
|
|
||||||
context.tooltipsCharacteristic = {
|
context.tooltipsCharacteristic = {
|
||||||
str: game.i18n.localize("CTHULHUETERNAL.Characteristic.Str"),
|
str: game.i18n.localize("CTHULHUETERNAL.Characteristic.Str"),
|
||||||
|
@ -568,7 +568,7 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
{ rollMode: rollMode },
|
{ rollMode: rollMode },
|
||||||
)
|
)
|
||||||
|
|
||||||
console.log("Roll to message", this.options, this.options.rollData, this.options.rollItem)
|
// 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
|
||||||
if (rollData.resultType.includes("failure") && rollItem.type === "skill") {
|
if (rollData.resultType.includes("failure") && rollItem.type === "skill") {
|
||||||
@ -594,6 +594,20 @@ export default class CthulhuEternalRoll extends Roll {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the roll is a SAN roll, we propose to select the SAN loss
|
||||||
|
if (rollData.rollType === "san") {
|
||||||
|
let msgData = {
|
||||||
|
rollItem: rollItem,
|
||||||
|
rollData: rollData
|
||||||
|
}
|
||||||
|
let msg = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/chat-san-request.hbs", msgData)
|
||||||
|
let chatMsg = await ChatMessage.create({
|
||||||
|
user: game.user.id,
|
||||||
|
content: msg,
|
||||||
|
speaker: ChatMessage.getSpeaker({ actor: rollData.actor })
|
||||||
|
}, { rollMode: rollData.rollMode, create: true })
|
||||||
|
await chatMsg.setFlag("fvtt-cthulhu-eternal", "rollData", rollData)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,8 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
|
|||||||
const characteristicField = (label) => {
|
const characteristicField = (label) => {
|
||||||
const schema = {
|
const schema = {
|
||||||
value: new fields.NumberField({ ...requiredInteger, initial: 3, min: 0 }),
|
value: new fields.NumberField({ ...requiredInteger, initial: 3, min: 0 }),
|
||||||
feature: new fields.StringField({ required: true, nullable: false, initial: "" })
|
feature: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||||||
|
max: new fields.NumberField({ ...requiredInteger, initial: 3, min: 0 })
|
||||||
}
|
}
|
||||||
return new fields.SchemaField(schema, { label })
|
return new fields.SchemaField(schema, { label })
|
||||||
}
|
}
|
||||||
@ -47,6 +48,7 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
|
|||||||
violence: new fields.ArrayField(new fields.BooleanField(), { required: true, initial: [false, false, false], min: 3, max: 3 }),
|
violence: new fields.ArrayField(new fields.BooleanField(), { required: true, initial: [false, false, false], min: 3, max: 3 }),
|
||||||
helplessness: new fields.ArrayField(new fields.BooleanField(), { required: true, initial: [false, false, false], min: 3, max: 3 }),
|
helplessness: new fields.ArrayField(new fields.BooleanField(), { required: true, initial: [false, false, false], min: 3, max: 3 }),
|
||||||
breakingPoint: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
breakingPoint: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
||||||
|
breakingPointReached: new fields.BooleanField({ required: true, initial: false }),
|
||||||
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 }),
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -132,6 +134,15 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
|
|||||||
updates[`system.damageBonus`] = dmgBonus
|
updates[`system.damageBonus`] = dmgBonus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BP (Breaking Point) management
|
||||||
|
if (!this.san.breakingPointReached && this.san.value <= this.san.breakingPoint) {
|
||||||
|
updates[`system.san.breakingPointReached`] = true
|
||||||
|
ChatMessage.create({
|
||||||
|
content: `<p>${game.i18n.format("CTHULHUETERNAL.Label.breakingPointReached", { bp: this.san.breakingPoint, san: this.san.value })}</p>`,
|
||||||
|
speaker: ChatMessage.getSpeaker({ actor: this.parent })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Unconsciousness management
|
// Unconsciousness management
|
||||||
if (!this.hp.unconscious && this.hp.value <= 2) {
|
if (!this.hp.unconscious && this.hp.value <= 2) {
|
||||||
updates[`system.hp.unconscious`] = true
|
updates[`system.hp.unconscious`] = true
|
||||||
@ -183,6 +194,108 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async applySANConsequences(rollData) {
|
||||||
|
// If sanType is "non", do nothing
|
||||||
|
if (rollData.sanType === "none") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let msgData = {
|
||||||
|
sanType: rollData.sanType,
|
||||||
|
sanLoss: rollData.sanLoss,
|
||||||
|
actorId: this.parent.id,
|
||||||
|
actorName: this.parent.name,
|
||||||
|
adaptedToHelplessness: this.biodata.adaptedToHelplessness,
|
||||||
|
adaptedToViolence: this.biodata.adaptedToViolence,
|
||||||
|
... rollData
|
||||||
|
}
|
||||||
|
let updates = {}
|
||||||
|
let template = ""
|
||||||
|
// Manage temporary insanity
|
||||||
|
if (rollData.sanLoss >= 5) {
|
||||||
|
rollData.resetMsg = false
|
||||||
|
if (rollData.sanType === "violence" && !this.biodata.adaptedToViolence) {
|
||||||
|
updates[`system.san.violence`] = [false, false, false]
|
||||||
|
rollData.resetMsg = "CTHULHUETERNAL.Label.sanViolenceReset"
|
||||||
|
}
|
||||||
|
if (rollData.sanType === "helplessness" && !this.biodata.adaptedToHelplessness) {
|
||||||
|
updates[`system.san.helplessness`] = [false, false, false]
|
||||||
|
rollData.resetMsg = "CTHULHUETERNAL.Label.sanHelplessnessReset"
|
||||||
|
}
|
||||||
|
template = "systems/fvtt-cthulhu-eternal/templates/chat-san-temp-insanity.hbs"
|
||||||
|
|
||||||
|
} else if (rollData.sanLoss === 0) { // Manage if sanLoss is 0
|
||||||
|
rollData.resetMsg = false
|
||||||
|
if (rollData.sanType === "violence" && !this.biodata.adaptedToViolence) {
|
||||||
|
updates[`system.san.violence`] = [false, false, false]
|
||||||
|
rollData.resetMsg = "CTHULHUETERNAL.Label.sanViolenceReset"
|
||||||
|
}
|
||||||
|
if (rollData.sanType === "helplessness" && !this.biodata.adaptedToHelplessness) {
|
||||||
|
updates[`system.san.helplessness`] = [false, false, false]
|
||||||
|
rollData.resetMsg = "CTHULHUETERNAL.Label.sanHelplessnessReset"
|
||||||
|
}
|
||||||
|
template = "systems/fvtt-cthulhu-eternal/templates/chat-san-loss-0.hbs"
|
||||||
|
|
||||||
|
} else if (rollData.sanType === "violence" ) {
|
||||||
|
// Set the first false element of the violence array to true
|
||||||
|
let violence = this.san.violence.slice()
|
||||||
|
let index = violence.findIndex(v => !v)
|
||||||
|
if (index !== -1) {
|
||||||
|
violence[index] = true
|
||||||
|
updates[`system.san.violence`] = violence
|
||||||
|
}
|
||||||
|
template = "systems/fvtt-cthulhu-eternal/templates/chat-san-loss-1-4.hbs"
|
||||||
|
// Check if all violence elements are true, if so, set adaptedToViolence to true
|
||||||
|
if (violence.every(v => v)) {
|
||||||
|
updates[`system.biodata.adaptedToViolence`] = true
|
||||||
|
updates[`system.san.violence`] = [false, false, false]
|
||||||
|
msgData.adaptedToViolence = true
|
||||||
|
}
|
||||||
|
} else if (rollData.sanType === "helplessness" ) {
|
||||||
|
// If sanType is "helplessness" and adapted to helplessness, set the first false element of the helplessness array to true
|
||||||
|
let helplessness = this.san.helplessness.slice()
|
||||||
|
let index = helplessness.findIndex(h => !h)
|
||||||
|
if (index !== -1) {
|
||||||
|
helplessness[index] = true
|
||||||
|
updates[`system.san.helplessness`] = helplessness
|
||||||
|
}
|
||||||
|
template = "systems/fvtt-cthulhu-eternal/templates/chat-san-loss-1-4.hbs"
|
||||||
|
// Check if all helplessness elements are true, if so, set adaptedToHelplessness to true
|
||||||
|
if (helplessness.every(h => h)) {
|
||||||
|
updates[`system.biodata.adaptedToHelplessness`] = true
|
||||||
|
updates[`system.san.helplessness`] = [false, false, false]
|
||||||
|
msgData.adaptedToHelplessness = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = await foundry.applications.handlebars.renderTemplate(template, msgData)
|
||||||
|
let msg = await ChatMessage.create({
|
||||||
|
content: content,
|
||||||
|
speaker: ChatMessage.getSpeaker({ actor: this.parent })
|
||||||
|
})
|
||||||
|
msg.setFlag("fvtt-cthulhu-eternal", "rollData", msgData)
|
||||||
|
if (Object.keys(updates).length > 0) {
|
||||||
|
this.parent.update(updates)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async modifySAN(rollData) {
|
||||||
|
let updates = {}
|
||||||
|
let san = Math.max(Math.min(this.san.value + rollData.sanLoss, this.san.max), 0)
|
||||||
|
if (this.san.value !== san) {
|
||||||
|
updates[`system.san.value`] = san
|
||||||
|
const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/chat-san-type-request.hbs", rollData)
|
||||||
|
let msg = await ChatMessage.create({
|
||||||
|
content: content,
|
||||||
|
speaker: ChatMessage.getSpeaker({ actor: this.parent })
|
||||||
|
})
|
||||||
|
msg.setFlag("fvtt-cthulhu-eternal", "rollData", rollData)
|
||||||
|
}
|
||||||
|
if (Object.keys(updates).length > 0) {
|
||||||
|
this.parent.update(updates)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
isStunned() {
|
isStunned() {
|
||||||
return this.hp.stunned
|
return this.hp.stunned
|
||||||
}
|
}
|
||||||
@ -215,6 +328,7 @@ export default class CthulhuEternalProtagonist extends foundry.abstract.TypeData
|
|||||||
let bp = Math.max(this.san.value - this.characteristics.pow.value, 0)
|
let bp = Math.max(this.san.value - this.characteristics.pow.value, 0)
|
||||||
if (this.san.breakingPoint !== bp) {
|
if (this.san.breakingPoint !== bp) {
|
||||||
updates[`system.san.breakingPoint`] = bp
|
updates[`system.san.breakingPoint`] = bp
|
||||||
|
updates[`system.san.breakingPointReached`] = false // Reset breaking point reached
|
||||||
}
|
}
|
||||||
if (Object.keys(updates).length > 0) {
|
if (Object.keys(updates).length > 0) {
|
||||||
this.parent.update(updates)
|
this.parent.update(updates)
|
||||||
|
@ -180,6 +180,55 @@ export default class CthulhuEternalUtils {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async applySANType(rollMessage, event) {
|
||||||
|
let rollData = rollMessage.getFlag("fvtt-cthulhu-eternal", "rollData")
|
||||||
|
if (!rollData) {
|
||||||
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noRollDataFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let actor = game.actors.get(rollData.actorId)
|
||||||
|
if (!actor) {
|
||||||
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noActorFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let sanType = event.currentTarget.dataset.sanType;
|
||||||
|
if (!sanType) {
|
||||||
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noSanTypeFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// If the sanType is "none", we don't apply any SAN processing
|
||||||
|
if (sanType === "none") {
|
||||||
|
ui.notifications.info(game.i18n.localize("CTHULHUETERNAL.Notifications.noSanLossApplied"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rollData.sanType = sanType
|
||||||
|
await actor.system.applySANConsequences(rollData)
|
||||||
|
// Delete the roll message
|
||||||
|
await rollMessage.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
static async applySANLoss(rollMessage, event) {
|
||||||
|
let rollData = rollMessage.getFlag("fvtt-cthulhu-eternal", "rollData")
|
||||||
|
if (!rollData) {
|
||||||
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noRollDataFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let actor = game.actors.get(rollData.actorId)
|
||||||
|
if (!actor) {
|
||||||
|
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noActorFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Get the san loss from the event : data-san-value
|
||||||
|
let sanLoss = event.currentTarget.dataset.sanValue
|
||||||
|
let r = new Roll(sanLoss.toString())
|
||||||
|
await r.evaluate()
|
||||||
|
rollData.sanLoss = -r.total
|
||||||
|
|
||||||
|
await actor.system.modifySAN(rollData)
|
||||||
|
// Delete the roll message
|
||||||
|
await rollMessage.delete()
|
||||||
|
}
|
||||||
|
|
||||||
static async healingRoll(rollMessage) {
|
static async healingRoll(rollMessage) {
|
||||||
let rollData = rollMessage.rolls[0]?.options?.rollData
|
let rollData = rollMessage.rolls[0]?.options?.rollData
|
||||||
let healingFormula = rollData.rollItem.system.healingFormula
|
let healingFormula = rollData.rollItem.system.healingFormula
|
||||||
|
@ -1 +1 @@
|
|||||||
MANIFEST-000131
|
MANIFEST-000143
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
2025/06/14-23:45:33.918294 7f78d8df86c0 Recovering log #129
|
2025/06/15-20:50:32.407889 7f78d9dfa6c0 Recovering log #141
|
||||||
2025/06/14-23:45:34.040033 7f78d8df86c0 Delete type=3 #127
|
2025/06/15-20:50:32.419111 7f78d9dfa6c0 Delete type=3 #139
|
||||||
2025/06/14-23:45:34.040084 7f78d8df86c0 Delete type=0 #129
|
2025/06/15-20:50:32.419180 7f78d9dfa6c0 Delete type=0 #141
|
||||||
|
2025/06/15-23:02:15.291797 7f78d37fe6c0 Level-0 table #146: started
|
||||||
|
2025/06/15-23:02:15.291843 7f78d37fe6c0 Level-0 table #146: 0 bytes OK
|
||||||
|
2025/06/15-23:02:15.346613 7f78d37fe6c0 Delete type=0 #144
|
||||||
|
2025/06/15-23:02:15.442962 7f78d37fe6c0 Manual compaction at level-0 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
2025/06/14-13:49:17.890351 7f78d8df86c0 Recovering log #125
|
2025/06/15-20:45:20.732548 7f78d95f96c0 Recovering log #137
|
||||||
2025/06/14-13:49:17.899990 7f78d8df86c0 Delete type=3 #123
|
2025/06/15-20:45:20.795953 7f78d95f96c0 Delete type=3 #135
|
||||||
2025/06/14-13:49:17.900040 7f78d8df86c0 Delete type=0 #125
|
2025/06/15-20:45:20.796016 7f78d95f96c0 Delete type=0 #137
|
||||||
2025/06/14-16:21:28.823932 7f78d37fe6c0 Level-0 table #130: started
|
2025/06/15-20:50:27.656562 7f78d37fe6c0 Level-0 table #142: started
|
||||||
2025/06/14-16:21:28.823960 7f78d37fe6c0 Level-0 table #130: 0 bytes OK
|
2025/06/15-20:50:27.656587 7f78d37fe6c0 Level-0 table #142: 0 bytes OK
|
||||||
2025/06/14-16:21:28.831212 7f78d37fe6c0 Delete type=0 #128
|
2025/06/15-20:50:27.663159 7f78d37fe6c0 Delete type=0 #140
|
||||||
2025/06/14-16:21:28.848927 7f78d37fe6c0 Manual compaction at level-0 from '!items!4oyPRBWPBWAChrJP' @ 72057594037927935 : 1 .. '!items!zVFfp3o0G0Zg3Ia4' @ 0 : 0; will stop at (end)
|
2025/06/15-20:50:27.663295 7f78d37fe6c0 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-000300
|
MANIFEST-000312
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
2025/06/14-23:45:33.811724 7f78d9dfa6c0 Recovering log #298
|
2025/06/15-20:50:32.394511 7f78d95f96c0 Recovering log #310
|
||||||
2025/06/14-23:45:33.914052 7f78d9dfa6c0 Delete type=3 #296
|
2025/06/15-20:50:32.404291 7f78d95f96c0 Delete type=3 #308
|
||||||
2025/06/14-23:45:33.914134 7f78d9dfa6c0 Delete type=0 #298
|
2025/06/15-20:50:32.404388 7f78d95f96c0 Delete type=0 #310
|
||||||
|
2025/06/15-23:02:15.346748 7f78d37fe6c0 Level-0 table #315: started
|
||||||
|
2025/06/15-23:02:15.346777 7f78d37fe6c0 Level-0 table #315: 0 bytes OK
|
||||||
|
2025/06/15-23:02:15.368088 7f78d37fe6c0 Delete type=0 #313
|
||||||
|
2025/06/15-23:02:15.442974 7f78d37fe6c0 Manual compaction at level-0 from '!folders!5PrT9QmN1cFPzDFP' @ 72057594037927935 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at (end)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
2025/06/14-13:49:17.875545 7f78d95f96c0 Recovering log #294
|
2025/06/15-20:45:20.673899 7f78d9dfa6c0 Recovering log #306
|
||||||
2025/06/14-13:49:17.886122 7f78d95f96c0 Delete type=3 #292
|
2025/06/15-20:45:20.728664 7f78d9dfa6c0 Delete type=3 #304
|
||||||
2025/06/14-13:49:17.886173 7f78d95f96c0 Delete type=0 #294
|
2025/06/15-20:45:20.728753 7f78d9dfa6c0 Delete type=0 #306
|
||||||
2025/06/14-16:21:28.817422 7f78d37fe6c0 Level-0 table #299: started
|
2025/06/15-20:50:27.650512 7f78d37fe6c0 Level-0 table #311: started
|
||||||
2025/06/14-16:21:28.817477 7f78d37fe6c0 Level-0 table #299: 0 bytes OK
|
2025/06/15-20:50:27.650541 7f78d37fe6c0 Level-0 table #311: 0 bytes OK
|
||||||
2025/06/14-16:21:28.823801 7f78d37fe6c0 Delete type=0 #297
|
2025/06/15-20:50:27.656452 7f78d37fe6c0 Delete type=0 #309
|
||||||
2025/06/14-16:21:28.848912 7f78d37fe6c0 Manual compaction at level-0 from '!folders!5PrT9QmN1cFPzDFP' @ 72057594037927935 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at (end)
|
2025/06/15-20:50:27.663286 7f78d37fe6c0 Manual compaction at level-0 from '!folders!5PrT9QmN1cFPzDFP' @ 72057594037927935 : 1 .. '!items!zvoUByzWSWZ87fxA' @ 0 : 0; will stop at (end)
|
||||||
|
Binary file not shown.
@ -86,6 +86,7 @@ i.fvtt-cthulhu-eternal {
|
|||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chat-san-request,
|
||||||
.chat-lethal-damage {
|
.chat-lethal-damage {
|
||||||
ul {
|
ul {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
@ -97,6 +98,23 @@ i.fvtt-cthulhu-eternal {
|
|||||||
color: var(--color-critical-failure);
|
color: var(--color-critical-failure);
|
||||||
font-family: var(--font-title);
|
font-family: var(--font-title);
|
||||||
}
|
}
|
||||||
|
.san-loose-buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin: 10px 0;
|
||||||
|
button {
|
||||||
|
margin: 0 2px;
|
||||||
|
font-family: var(--font-primary);
|
||||||
|
font-size: calc(var(--font-size-standard) * 1.1);
|
||||||
|
border: none;
|
||||||
|
padding: 2px 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
min-width: 3.0rem;
|
||||||
|
max-width: 3.0rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
.result-non-lethal {
|
.result-non-lethal {
|
||||||
color: var(--color-failure);
|
color: var(--color-failure);
|
||||||
font-family: var(--font-title);
|
font-family: var(--font-title);
|
||||||
|
@ -123,6 +123,14 @@
|
|||||||
min-width: 6rem;
|
min-width: 6rem;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
.san-helplessness,
|
||||||
|
.san-violence {
|
||||||
|
display: flex;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
.label-san-type {
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
.label-bp {
|
.label-bp {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
max-width: 3rem;
|
max-width: 3rem;
|
||||||
|
11
templates/chat-san-loss-0.hbs
Normal file
11
templates/chat-san-loss-0.hbs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<div class="{{cssClass}}">
|
||||||
|
<div class="chat-san-request">
|
||||||
|
<ul>
|
||||||
|
<li><strong>{{localize "CTHULHUETERNAL.Label.noSanLoss"}}</strong></li>
|
||||||
|
{{#if resetMsg}}
|
||||||
|
<li><strong>{{localize resetMsg}}</strong></li>
|
||||||
|
{{/if}}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
24
templates/chat-san-loss-1-4.hbs
Normal file
24
templates/chat-san-loss-1-4.hbs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<div class="{{cssClass}}">
|
||||||
|
<div class="chat-san-request">
|
||||||
|
<ul>
|
||||||
|
<li><strong>{{localize "CTHULHUETERNAL.Label.sanLoss"}}</strong></li>
|
||||||
|
{{#if (eq sanType "violence")}}
|
||||||
|
{{#if adaptedToViolence}}
|
||||||
|
<li class="orange-warning">{{localize "CTHULHUETERNAL.Label.adaptedToViolence"}}</li>
|
||||||
|
{{else}}
|
||||||
|
<li>{{localize "CTHULHUETERNAL.Label.sanLossViolence"}}</li>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (eq sanType "helplessness")}}
|
||||||
|
{{#if adaptedToHelplessness}}
|
||||||
|
<li class="orange-warning">{{localize "CTHULHUETERNAL.Label.adaptedToHelplessness"}}</li>
|
||||||
|
{{else}}
|
||||||
|
<li>{{localize "CTHULHUETERNAL.Label.sanLossHelplessness"}}</li>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
25
templates/chat-san-request.hbs
Normal file
25
templates/chat-san-request.hbs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<div class="{{cssClass}}">
|
||||||
|
<div class="chat-san-request">
|
||||||
|
<ul>
|
||||||
|
<li><strong>{{localize "CTHULHUETERNAL.Label.SANTest"}}</strong></li>
|
||||||
|
|
||||||
|
<li class="san-loose-buttons">
|
||||||
|
<button class="san-loose" data-san-value="0">0</button>
|
||||||
|
<button class="san-loose" data-san-value="1">1</button>
|
||||||
|
<button class="san-loose" data-san-value="2">2</button>
|
||||||
|
<button class="san-loose" data-san-value="3">3</button>
|
||||||
|
<button class="san-loose" data-san-value="4">4</button>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="san-loose-buttons">
|
||||||
|
<button class="san-loose" data-san-value="1d4">1d4</button>
|
||||||
|
<button class="san-loose" data-san-value="1d6">1d6</button>
|
||||||
|
<button class="san-loose" data-san-value="1d8">1d8</button>
|
||||||
|
<button class="san-loose" data-san-value="1d10">1d10</button>
|
||||||
|
<button class="san-loose" data-san-value="1d12">1d12</button>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
12
templates/chat-san-temp-insanity.hbs
Normal file
12
templates/chat-san-temp-insanity.hbs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<div class="{{cssClass}}">
|
||||||
|
<div class="chat-san-request">
|
||||||
|
<ul>
|
||||||
|
<li><strong>{{localize "CTHULHUETERNAL.Label.sanLoss5"}}</strong></li>
|
||||||
|
{{#if resetMsg}}
|
||||||
|
<li class="orange-warning">{{localize resetMsg}}</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
19
templates/chat-san-type-request.hbs
Normal file
19
templates/chat-san-type-request.hbs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<div class="{{cssClass}}">
|
||||||
|
<div class="chat-san-request">
|
||||||
|
<ul>
|
||||||
|
<li><strong>{{localize "CTHULHUETERNAL.Label.sanLoss"}} : {{sanLoss}}</strong></li>
|
||||||
|
<li><strong>{{localize "CTHULHUETERNAL.Label.selectSANType"}}</strong></li>
|
||||||
|
|
||||||
|
<li class="san-type-buttons">
|
||||||
|
<button class="san-type" data-san-value="{{sanLoss}}" data-san-type="violence">{{localize "CTHULHUETERNAL.Label.Violence"}}</button>
|
||||||
|
<button class="san-type" data-san-value="{{sanLoss}}" data-san-type="helplessness">{{localize "CTHULHUETERNAL.Label.Helplessness"}}</button>
|
||||||
|
</li>
|
||||||
|
<li class="san-type-buttons">
|
||||||
|
<button class="san-type" data-san-value="{{sanLoss}}" data-san-type="unnatural">{{localize "CTHULHUETERNAL.Label.Unnatural"}}</button>
|
||||||
|
<button class="san-type" data-san-value="{{sanLoss}}" data-san-type="none">{{localize "CTHULHUETERNAL.Label.None"}}</button>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -21,8 +21,13 @@
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{{localize "CTHULHUETERNAL.Label.biodata"}}</legend>
|
<legend>{{localize "CTHULHUETERNAL.Label.biodata"}}</legend>
|
||||||
<div class="adapted">
|
<div class="adapted">
|
||||||
|
{{#if isGM}}
|
||||||
{{formField systemFields.biodata.fields.adaptedToViolence value=system.biodata.adaptedToViolence name="system.biodata.adaptedToViolence" localize=true}}
|
{{formField systemFields.biodata.fields.adaptedToViolence value=system.biodata.adaptedToViolence name="system.biodata.adaptedToViolence" localize=true}}
|
||||||
{{formField systemFields.biodata.fields.adaptedToHelplessness value=system.biodata.adaptedToHelplessness name="system.biodata.adaptedToHelplessness" localize=true}}
|
{{formField systemFields.biodata.fields.adaptedToHelplessness value=system.biodata.adaptedToHelplessness name="system.biodata.adaptedToHelplessness" localize=true}}
|
||||||
|
{{else}}
|
||||||
|
{{formField systemFields.biodata.fields.adaptedToViolence value=system.biodata.adaptedToViolence name="system.biodata.adaptedToViolence" localize=true disabled=true}}
|
||||||
|
{{formField systemFields.biodata.fields.adaptedToHelplessness value=system.biodata.adaptedToHelplessness name="system.biodata.adaptedToHelplessness" localize=true disabled=true}}
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<div class="biodata">
|
<div class="biodata">
|
||||||
{{formField systemFields.biodata.fields.harshness value=system.biodata.harshness name="system.biodata.harshness" localize=true}}
|
{{formField systemFields.biodata.fields.harshness value=system.biodata.harshness name="system.biodata.harshness" localize=true}}
|
||||||
|
@ -76,17 +76,29 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flexrow">
|
<div class="flexrow">
|
||||||
|
|
||||||
<span class="label-field">{{localize "CTHULHUETERNAL.Label.violence"}}</span>
|
<div class="san-violence">
|
||||||
{{#each system.san.violence as |violence idx|}}
|
{{#if system.biodata.adaptedToViolence}}
|
||||||
<input class="san-checkbox" type="checkbox" data-action="updateCheckboxArray" data-index="{{@index}}"
|
<span class="">{{localize "CTHULHUETERNAL.Label.adaptedToViolenceShort"}}</span>
|
||||||
data-name="violence" {{#if violence}} checked {{/if}}>
|
{{else}}
|
||||||
{{/each}}
|
<span class="label-field label-san-type">{{localize "CTHULHUETERNAL.Label.violence"}}</span>
|
||||||
|
{{#each system.san.violence as |violence idx|}}
|
||||||
|
<input class="san-checkbox" type="checkbox" data-action="updateCheckboxArray" data-index="{{@index}}"
|
||||||
|
data-name="violence" {{#if violence}} checked {{/if}}>
|
||||||
|
{{/each}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
<span class="label-field">{{localize "CTHULHUETERNAL.Label.helplessness"}}</span>
|
<div class="san-helplessness">
|
||||||
{{#each system.san.helplessness as |helplessness idx|}}
|
{{#if system.biodata.adaptedToHelplessness}}
|
||||||
<input class="san-checkbox" type="checkbox" data-action="updateCheckboxArray" data-index="{{@index}}"
|
<span class="">{{localize "CTHULHUETERNAL.Label.adaptedToHelplessnessShort"}}</span>
|
||||||
data-name="helplessness" {{#if helplessness}} checked {{/if}}>
|
{{else}}
|
||||||
{{/each}}
|
<span class="label-field label-san-type">{{localize "CTHULHUETERNAL.Label.helplessness"}}</span>
|
||||||
|
{{#each system.san.helplessness as |helplessness idx|}}
|
||||||
|
<input class="san-checkbox" type="checkbox" data-action="updateCheckboxArray" data-index="{{@index}}"
|
||||||
|
data-name="helplessness" {{#if helplessness}} checked {{/if}}>
|
||||||
|
{{/each}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user