/* -------------------------------------------- */ import { RdDResolutionTable } from "./rdd-resolution-table.js"; import { RdDRoll } from "./rdd-roll.js"; import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; import { ChatUtility } from "./chat-utility.js"; import { STATUSES } from "./settings/status-effects.js"; /* -------------------------------------------- */ /* -------------------------------------------- */ export class RdDEmpoignade { /* -------------------------------------------- */ static init() { } /* -------------------------------------------- */ static checkEmpoignadeEnCours(actor) { // TODO: autoriser la perception? la comédie/séduction? if (RdDEmpoignade.isEmpoignadeEnCours(actor)) { ui.notifications.warn("Une empoignade est en cours ! Normalement, vous ne pouvez rien faire d'autre que continuer l'empoignade ou la rompre.") return true; } return false; } /* -------------------------------------------- */ static isEmpoignadeEnCours(actor) { return actor.itemTypes['empoignade'].find(it => it.system.pointsemp > 0) } /* -------------------------------------------- */ static getEmpoignadeById(actor, id) { let emp = actor.itemTypes['empoignade'].find(it => it.system.empoignadeid == id) return emp && duplicate(emp) || undefined; } /* -------------------------------------------- */ static getEmpoignade(attacker, defender) { let emp = attacker.itemTypes['empoignade'].find(it => it.system.empoigneurid == attacker.id && it.system.empoigneid == defender.id) if (!emp) { emp = attacker.itemTypes['empoignade'].find(it => it.system.empoigneurid == defender.id && it.system.empoigneid == attacker.id) } if (emp) { return duplicate(emp); } return undefined; } /* -------------------------------------------- */ static getMalusTaille(emp, attacker, defender) { // Si pas empoigné, alors 0 if (emp.system.pointsemp == 0) { return 0 } // Malus de -1 si différence de taille de 2 ou plus (p 135) if (attacker.system.carac.taille.value < defender.system.carac.taille.value - 1) { return attacker.system.carac.taille.value - (defender.system.carac.taille.value - 1) } return 0 } /* -------------------------------------------- */ static async onAttaqueEmpoignadeValidee(attacker, defender) { let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) const isNouvelle = empoignade == undefined; empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender)) let mode = (empoignade && empoignade.system.empoigneurid == attacker.id) ? "empoigner" : "liberer" let rollData = { mode: mode, isEmpoignade: true, competence: attacker.getCompetence("Corps à corps"), selectedCarac: attacker.system.carac.melee, empoignade: empoignade, attackerId: attacker.id, attackerName: attacker.name, defenderName: defender.name, defenderId: defender.id, malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender) } if (attacker.isCreatureEntite()) { RdDItemCompetenceCreature.setRollDataCreature(rollData) } if (empoignade.system.pointsemp >= 2) { let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-actions.html'); ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData) } else { await RdDEmpoignade.$rollAttaqueEmpoignade(attacker, rollData, isNouvelle); } } /* -------------------------------------------- */ static async onAttaqueEmpoignade(attacker, defender) { let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) const isNouvelle = empoignade == undefined; empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender)) //console.log("W.", empoignade, defender.hasArmeeMeleeEquipee()) if ((isNouvelle || empoignade.system.pointsemp == 0) && defender.hasArmeeMeleeEquipee()) { ChatUtility.createChatWithRollMode(attacker.name, { content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-valider.html`, { attacker: attacker, defender: defender }) }) } else { await this.onAttaqueEmpoignadeValidee(attacker, defender) } } /* -------------------------------------------- */ static async onAttaqueEmpoignadeFromItem(empoignade) { let attacker = game.actors.get(empoignade.system.empoigneurid) let defender = game.actors.get(empoignade.system.empoigneid) await this.onAttaqueEmpoignadeValidee(attacker, defender) } /* -------------------------------------------- */ static async $rollAttaqueEmpoignade(attacker, rollData, isNouvelle = false) { const dialog = await RdDRoll.create(attacker, rollData, { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' }, { name: 'jet-empoignade', label: 'Empoigner', callbacks: [ { condition: r => (r.rolled.isSuccess), action: async (r) => await RdDEmpoignade.$onRollEmpoignade(r, true, isNouvelle) }, { condition: r => (r.rolled.isEchec), action: async (r) => await RdDEmpoignade.$onRollEmpoignade(r, false, isNouvelle) }, ] }); dialog.render(true); } /* -------------------------------------------- */ static async $onRollEmpoignade(rollData, isSuccess, isNouvelle = false) { let attacker = game.actors.get(rollData.attackerId) let defender = game.actors.get(rollData.defenderId) let empoignade = rollData.empoignade empoignade.isSuccess = isSuccess; if (isSuccess && isNouvelle) { // Creer l'empoignade sur attaquant/defenseur await attacker.createEmbeddedDocuments('Item', [empoignade.toObject()]) await defender.createEmbeddedDocuments('Item', [empoignade.toObject()]) } let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-resultat.html'); ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData) } /* -------------------------------------------- */ static async onDefenseEmpoignade(rollData, defenseMode, competenceName = "Corps à corps", carac = "melee") { let attacker = game.actors.get(rollData.attackerId) let defender = game.actors.get(rollData.defenderId) let empoignade = this.getEmpoignade(attacker, defender) if (!empoignade) { ui.notifications.warn("Une erreur s'est produite : Aucune empoignade trouvée !!") return } empoignade = duplicate(empoignade) rollData.mode = defenseMode rollData.empoignade = empoignade rollData.competence = defender.getCompetence(competenceName), rollData.selectedCarac = defender.system.carac[carac], rollData.malusTaille = RdDEmpoignade.getMalusTaille(empoignade, defender, attacker) await RdDEmpoignade.$rollDefenseEmpoignade(defender, rollData); } /* -------------------------------------------- */ static async $rollDefenseEmpoignade(defender, rollData) { const dialog = await RdDRoll.create(defender, rollData, { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-empoignade.html' }, { name: 'empoignade', label: 'Contrer', callbacks: [ { action: async (r) => await RdDEmpoignade.$onRollContrerLiberer(r) } ] } ); dialog.render(true); } /* -------------------------------------------- */ static async $onRollContrerLiberer(rollData) { let empoignade = rollData.empoignade if (rollData.mode == "contrer-empoigner" && !rollData.rolled.isSuccess) { empoignade.system.pointsemp++ RdDEmpoignade.$updateEtatEmpoignade(empoignade) } if (rollData.mode == "contrer-liberer" && !rollData.rolled.isSuccess) { empoignade.system.pointsemp-- RdDEmpoignade.$updateEtatEmpoignade(empoignade) } if (empoignade.system.pointsemp >= 2) { let attacker = game.actors.get(empoignade.system.empoigneurid) let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-actions.html'); ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData) } await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-empoignade-resultat.html') } /* -------------------------------------------- */ static async $updateEtatEmpoignade(empoignade) { console.log("UPDATE Empoignade", empoignade) let defender = game.actors.get(empoignade.system.empoigneid) let emp = RdDEmpoignade.getEmpoignadeById(defender, empoignade.system.empoignadeid) let update = { _id: emp._id, "system.pointsemp": empoignade.system.pointsemp, "system.ausol": empoignade.system.ausol } await defender.updateEmbeddedDocuments('Item', [update]) let attacker = game.actors.get(empoignade.system.empoigneurid) emp = RdDEmpoignade.getEmpoignadeById(attacker, empoignade.system.empoignadeid) update = { _id: emp._id, "system.pointsemp": empoignade.system.pointsemp, "system.ausol": empoignade.system.ausol } await attacker.updateEmbeddedDocuments('Item', [update]) } /* -------------------------------------------- */ static async $deleteEmpoignade(empoignade) { console.log("DELETE Empoignade", empoignade) let defender = game.actors.get(empoignade.system.empoigneid) let emp = RdDEmpoignade.getEmpoignadeById(defender, empoignade.system.empoignadeid) await defender.deleteEmbeddedDocuments('Item', [emp._id]) let attacker = game.actors.get(empoignade.system.empoigneurid) emp = RdDEmpoignade.getEmpoignadeById(attacker, empoignade.system.empoignadeid) await attacker.deleteEmbeddedDocuments('Item', [emp._id]) } /* -------------------------------------------- */ static async entrainerAuSol(rollData) { let attacker = game.actors.get(rollData.attackerId) let defender = game.actors.get(rollData.defenderId) let empoignade = this.getEmpoignade(attacker, defender) empoignade.system.ausol = true await this.$updateEtatEmpoignade(empoignade) await attacker.setEffect(STATUSES.StatusProne, true); await defender.setEffect(STATUSES.StatusProne, true); let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-entrainer-sol.html'); ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData) } /* -------------------------------------------- */ static async projeterAuSol(rollData) { let attacker = game.actors.get(rollData.attackerId) let defender = game.actors.get(rollData.defenderId) let empoignade = this.getEmpoignade(attacker, defender) await defender.setEffect(STATUSES.StatusProne, true); await this.$deleteEmpoignade(empoignade) let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-projeter-sol.html'); ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData) } /* -------------------------------------------- */ static async perteEndurance(rollData, perteMode) { let attacker = game.actors.get(rollData.attackerId) let defender = game.actors.get(rollData.defenderId) let empoignade = this.getEmpoignade(attacker, defender) //console.log("Perte d'endurance :!!!", perteMode) let endValue = defender.system.sante.endurance.value if (perteMode == "end0") { await defender.santeIncDec("endurance", -endValue); } if (perteMode == "end1") { await defender.santeIncDec("endurance", -(endValue - 1)); } if (perteMode == "endmoitie") { await defender.santeIncDec("endurance", -Math.floor(endValue / 2)); } if (perteMode == "endquart") { await defender.santeIncDec("endurance", -(3 * Math.floor(endValue / 4))); } let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-perte-endurance.html'); ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData) } /* -------------------------------------------- */ static async deleteAllEmpoignades() { for (let actor of game.actors) { let empIds = actor.itemTypes["empoignade"].map(it => it.id) await actor.deleteEmbeddedDocuments('Item', empIds) } } /* -------------------------------------------- */ static async deleteLinkedEmpoignade(actorId, empoignade) { let actorDeleteId = (actorId == empoignade.system.empoigneurid) ? empoignade.system.empoigneid : empoignade.system.empoigneurid let actor = game.actors.get(actorDeleteId) let emp = this.getEmpoignadeById(actor, empoignade.system.empoignadeid) if (emp) { await actor.deleteEmbeddedDocuments('Item', [emp._id]) } } /* -------------------------------------------- */ static async createEmpoignade(attacker, defender) { return await Item.create({ name: "Empoignade en cours de " + attacker.name + ' sur ' + defender.name, type: 'empoignade', img: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp", system: { description: "", empoignadeid: randomID(16), compteempoigne: 0, empoigneurid: attacker.id, empoigneid: defender.id, ptsemp: 0, empoigneurname: attacker.name, empoignename: defender.name } }, { temporary: true }) } }