Fight helper !

This commit is contained in:
2025-10-01 11:24:41 +02:00
parent bc9f397755
commit 4af277d8a2
26 changed files with 218 additions and 105 deletions

View File

@@ -23,8 +23,10 @@ export default class CthulhuEternalActor extends Actor {
data.items.push(skill.toObject())
}
}
data.items.push({ type:"weapon", img: "systems/fvtt-cthulhu-eternal/assets/icons/icon_fist.svg",
name: game.i18n.localize("CTHULHUETERNAL.Label.Unarmed"), system: { damage: "1d4-1", weaponType: "unarmed" } })
data.items.push({
type: "weapon", img: "systems/fvtt-cthulhu-eternal/assets/icons/icon_fist.svg",
name: game.i18n.localize("CTHULHUETERNAL.Label.Unarmed"), system: { damage: "1d4-1", weaponType: "unarmed" }
})
}
return super.create(data, options);
@@ -43,6 +45,39 @@ export default class CthulhuEternalActor extends Actor {
return super._onUpdate(changed, options, userId)
}
applyWounds(woundData) {
let updates = {}
// Get available armor
let armors = this.items.filter(i => i.type === "armor" && i.system.equipped)
let totalArmor = 0
for (let armor of armors) {
totalArmor += armor.system.protection
}
let effectiveWounds = Math.max(woundData.rollResult - totalArmor, 0)
if (woundData.isLethal) {
effectiveWounds = this.system.hp.value // Killed!
}
// Apply armor reduction
let hp = Math.max(this.system.hp.value - effectiveWounds, 0)
if (this.system.hp.value !== hp) {
updates[`system.hp.value`] = hp
}
if (Object.keys(updates).length > 0) {
this.update(updates)
}
// Chat message for GM only
if (game.user.isGM) {
let armorText = totalArmor > 0 ? game.i18n.format("CTHULHUETERNAL.Chat.armorAbsorbed", { armor: totalArmor }) : game.i18n.localize("CTHULHUETERNAL.Chat.noArmor")
ChatMessage.create({
user: game.user.id,
speaker: { alias: this.name },
rollMode: "gmroll",
content: game.i18n.format("CTHULHUETERNAL.Chat.woundsApplied", { name: this.name, effectiveWounds, armorText }),
})
}
}
async createEmbeddedDocuments(embeddedName, data, operation) {
let newData = []
if (embeddedName === "Item") {
@@ -71,18 +106,18 @@ export default class CthulhuEternalActor extends Actor {
}
async _preCreate(data, options, user) {
await super._preCreate(data, options, user)
await super._preCreate(data, options, user)
// Configure prototype token settings
const prototypeToken = {}
if (this.type === "protagonist") {
Object.assign(prototypeToken, {
sight: { enabled: true },
actorLink: true,
disposition: CONST.TOKEN_DISPOSITIONS.FRIENDLY,
})
this.updateSource({ prototypeToken })
// Configure prototype token settings
const prototypeToken = {}
if (this.type === "protagonist") {
Object.assign(prototypeToken, {
sight: { enabled: true },
actorLink: true,
disposition: CONST.TOKEN_DISPOSITIONS.FRIENDLY,
})
this.updateSource({ prototypeToken })
}
}
}
}

View File

@@ -146,6 +146,15 @@ export default class CthulhuEternalRoll extends Roll {
ammoUsed = Number(ammoUsed)
let combatants = []
if (game?.combat?.combatants) {
for (let c of game.combat.combatants) {
if (c.actor.id !== actor.id) {
combatants.push({ id: c.actor.id, name: c.name })
}
}
}
if (weapon.system.lethality > 0) {
let lethalityRoll = new Roll("1d100")
await lethalityRoll.evaluate()
@@ -159,20 +168,22 @@ export default class CthulhuEternalRoll extends Roll {
}
let wounds = Math.floor(lethalityRoll.total / 10) + (lethalityRoll.total % 10)
let msgData = {
actorId: actor.id,
weapon,
wounds,
lethalScore,
isLethal,
ammoUsed,
rollResult: lethalityRoll.total,
combatants: combatants
}
let flavor = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/chat-lethal-damage.hbs", msgData)
ChatMessage.create({
let msg = await ChatMessage.create({
user: game.user.id,
content: flavor,
speaker: ChatMessage.getSpeaker({ actor: actor }),
}, { rollMode: options.rollMode, create: true })
await msg.setFlag("fvtt-cthulhu-eternal", "woundData", msgData)
return
}
@@ -190,21 +201,24 @@ export default class CthulhuEternalRoll extends Roll {
"system.ammo.value": Math.max(0, weapon.system.ammo.value - ammoUsed)
}])
}
console.log("Weapon damage formula", formula, weapon, ammoUsed)
let damageRoll = new Roll(formula)
await damageRoll.evaluate()
let msgData = {
weapon,
formula,
ammoUsed,
rollResult: damageRoll.total,
}
let flavor = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/chat-regular-damage.hbs", msgData)
ChatMessage.create({
user: game.user.id,
content: flavor,
speaker: ChatMessage.getSpeaker({ actor: actor }),
}, { rollMode: options.rollMode, create: true })
actorId: actor.id,
weapon,
formula,
ammoUsed,
rollResult: damageRoll.total,
combatants: combatants
}
let flavor = await foundry.applications.handlebars.renderTemplate("systems/fvtt-cthulhu-eternal/templates/chat-regular-damage.hbs", msgData)
let msg = await ChatMessage.create({
user: game.user.id,
content: flavor,
speaker: ChatMessage.getSpeaker({ actor: actor }),
}, { rollMode: options.rollMode, create: true })
await msg.setFlag("fvtt-cthulhu-eternal", "woundData", msgData)
}

View File

@@ -229,7 +229,7 @@ export default class CthulhuEternalUtils {
let healingFormula = rollData.rollItem.system.healingFormula
let healingMsg = "CTHULHUETERNAL.Label.healingRoll"
if (rollData.resultType === "successCritical") {
healingFormula += " * 2"
healingFormula += " * 2"
}
if (rollData.resultType === "failureCritical") {
healingMsg = "CTHULHUETERNAL.Label.healingRollFailure"
@@ -268,11 +268,11 @@ export default class CthulhuEternalUtils {
}
static async registerBabeleTranslations(babele) {
babele.registerConverters( {
'translateRangeUnit': (originalValue) => {
babele.registerConverters({
'translateRangeUnit': (originalValue) => {
return CthulhuEternalUtils.translateRangeUnit(originalValue)
},
'translateRange' : (originalValue) => {
'translateRange': (originalValue) => {
return CthulhuEternalUtils.translateRange(originalValue)
}
})
@@ -280,7 +280,7 @@ export default class CthulhuEternalUtils {
static async damageRoll(rollMessage, formula = null) {
let rollData = rollMessage.rolls[0]?.options?.rollData
let actor = game.actors.get(rollData.actorId)
let actor = game.actors.get(rollData.actorId)
if (!actor) {
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Label.noActorFound"))
return
@@ -336,8 +336,8 @@ export default class CthulhuEternalUtils {
rejectClose: false, // Click on Close button will not launch an error
render: (event, dialog) => {
$(".nudged-score-select").change(event => {
dialogContext.nudgedValue = Number(event.target.value)+1
dialogContext.wpCost = Math.ceil(Math.abs(rollMessage.rolls[0].total - dialogContext.nudgedValue) / 5)
dialogContext.nudgedValue = Number(event.target.value) + 1
dialogContext.wpCost = Math.ceil(Math.abs(rollMessage.rolls[0].total - dialogContext.nudgedValue) / 5)
$("#nudged-wp-cost").val(dialogContext.wpCost)
})
}
@@ -375,4 +375,24 @@ export default class CthulhuEternalUtils {
document.documentElement.style.setProperty('--background-image-base', `linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.8)), url("../assets/ui/${era}_background_main.webp")`);
}
static applyWounds(message, event) {
let woundData = message.getFlag("fvtt-cthulhu-eternal", "woundData")
if (!woundData) {
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noRollDataFound"))
return
}
let actor = game.actors.get(woundData.actorId)
if (!actor) {
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noActorFound"))
return
}
// Get the targetted actorId from the HTML select event
let targetActorId = event.target.value
let targetActor = game.actors.get(targetActorId)
if (!targetActor) {
ui.notifications.error(game.i18n.localize("CTHULHUETERNAL.Notifications.noTargetActorFound") + targetActorId)
return
}
targetActor.applyWounds(woundData)
}
}