2023-04-21 18:18:20 +02:00
|
|
|
/* -------------------------------------------- */
|
|
|
|
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";
|
2023-04-21 22:28:51 +02:00
|
|
|
import { STATUSES } from "./settings/status-effects.js";
|
2023-04-21 18:18:20 +02:00
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
export class RdDEmpoignade {
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
static init() {
|
|
|
|
}
|
|
|
|
|
2023-04-21 22:27:47 +02:00
|
|
|
/* -------------------------------------------- */
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2023-04-21 18:18:20 +02:00
|
|
|
/* -------------------------------------------- */
|
|
|
|
static getEmpoignadeById(actor, id) {
|
2023-04-21 22:23:40 +02:00
|
|
|
let emp = actor.itemTypes['empoignade'].find(it => it.system.empoignadeid == id)
|
2023-04-21 18:18:20 +02:00
|
|
|
return emp && duplicate(emp) || undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
static getEmpoignade(attacker, defender) {
|
2023-04-21 22:23:40 +02:00
|
|
|
let emp = attacker.itemTypes['empoignade'].find(it => it.system.empoigneurid == attacker.id && it.system.empoigneid == defender.id)
|
2023-04-21 18:18:20 +02:00
|
|
|
if (!emp) {
|
2023-04-21 22:23:40 +02:00
|
|
|
emp = attacker.itemTypes['empoignade'].find(it => it.system.empoigneurid == defender.id && it.system.empoigneid == attacker.id)
|
2023-04-21 18:18:20 +02:00
|
|
|
}
|
|
|
|
if (emp) {
|
2023-04-21 22:23:40 +02:00
|
|
|
return duplicate(emp);
|
2023-04-21 18:18:20 +02:00
|
|
|
}
|
2023-04-21 22:23:40 +02:00
|
|
|
return undefined;
|
2023-04-21 18:18:20 +02:00
|
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
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])
|
|
|
|
|
2023-04-22 07:55:26 +02:00
|
|
|
//let attacker = game.actors.get(empoignade.system.empoigneurid)
|
|
|
|
//emp = RdDEmpoignade.getEmpoignadeById(attacker, empoignade.system.empoignadeid)
|
|
|
|
//await attacker.deleteEmbeddedDocuments('Item', [emp._id])
|
2023-04-21 18:18:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
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)
|
|
|
|
|
2023-04-21 23:09:40 +02:00
|
|
|
//console.log("Perte d'endurance :!!!", perteMode)
|
2023-04-21 18:18:20 +02:00
|
|
|
let endValue = defender.system.sante.endurance.value
|
|
|
|
if (perteMode == "end0") {
|
2023-04-21 22:28:51 +02:00
|
|
|
await defender.santeIncDec("endurance", -endValue);
|
2023-04-21 18:18:20 +02:00
|
|
|
}
|
|
|
|
if (perteMode == "end1") {
|
2023-04-21 22:28:51 +02:00
|
|
|
await defender.santeIncDec("endurance", -(endValue - 1));
|
2023-04-21 18:18:20 +02:00
|
|
|
}
|
|
|
|
if (perteMode == "endmoitie") {
|
2023-04-21 22:28:51 +02:00
|
|
|
await defender.santeIncDec("endurance", -Math.floor(endValue / 2));
|
2023-04-21 18:18:20 +02:00
|
|
|
}
|
|
|
|
if (perteMode == "endquart") {
|
2023-04-21 22:28:51 +02:00
|
|
|
await defender.santeIncDec("endurance", -(3 * Math.floor(endValue / 4)));
|
2023-04-21 18:18:20 +02:00
|
|
|
}
|
|
|
|
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) {
|
2023-04-21 22:23:40 +02:00
|
|
|
let empIds = actor.itemTypes["empoignade"].map(it => it.id)
|
|
|
|
await actor.deleteEmbeddedDocuments('Item', empIds)
|
2023-04-21 18:18:20 +02:00
|
|
|
}
|
|
|
|
}
|
2023-04-21 22:23:40 +02:00
|
|
|
|
2023-04-21 18:18:20 +02:00
|
|
|
/* -------------------------------------------- */
|
|
|
|
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({
|
2023-04-21 22:28:51 +02:00
|
|
|
name: "Empoignade en cours de " + attacker.name + ' sur ' + defender.name,
|
|
|
|
type: 'empoignade',
|
2023-04-21 18:18:20 +02:00
|
|
|
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
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|