Vincent Vandemeulebrouck
f541849306
Déplacement dans le module empoignade du message et de la vérification d'empoignade en cours. Le message est donc centralisé (possible de le modifier une fois pour toutes les utilisations)
315 lines
13 KiB
JavaScript
315 lines
13 KiB
JavaScript
/* -------------------------------------------- */
|
|
import { RdDCombat } from "./rdd-combat.js";
|
|
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, StatusEffects } 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) {
|
|
// TODO ? central storage ?
|
|
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", -defender.system.sante.endurance.value);
|
|
}
|
|
if (perteMode == "end1") {
|
|
await defender.santeIncDec("endurance", -(defender.system.sante.endurance.value - 1));
|
|
}
|
|
if (perteMode == "endmoitie") {
|
|
await defender.santeIncDec("endurance", -Math.floor(defender.system.sante.endurance.value / 2));
|
|
}
|
|
if (perteMode == "endquart") {
|
|
await defender.santeIncDec("endurance", -(3 * Math.floor(defender.system.sante.endurance.value / 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
|
|
})
|
|
}
|
|
} |