2021-11-11 09:37:00 +01:00
|
|
|
/* -------------------------------------------- */
|
|
|
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
|
|
|
import { RdDRoll } from "./rdd-roll.js";
|
|
|
|
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
2022-11-23 22:37:16 +01:00
|
|
|
import { Targets } from "./targets.js";
|
2024-09-25 22:56:24 +02:00
|
|
|
import { ITEM_TYPES } from "./item.js";
|
2021-11-11 09:37:00 +01:00
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* On part du principe qu'une entité démarre tjs
|
|
|
|
une possession via le MJ (ie un joueur ne controle pas une entité)
|
|
|
|
Donc la compétence Possession ne peut être démarrée que par le MJ.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
export class RdDPossession {
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
2022-07-02 01:41:55 +02:00
|
|
|
static init() {
|
2021-11-11 09:37:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
2022-07-02 01:41:55 +02:00
|
|
|
static searchPossessionFromEntite(attacker, defender) {
|
2024-09-25 22:56:24 +02:00
|
|
|
let poss = attacker.items.find(poss => poss.type == ITEM_TYPES.possession && poss.system.victime.actorid == defender.id);
|
2021-11-21 12:04:42 +01:00
|
|
|
if (!poss) {
|
2024-09-25 22:56:24 +02:00
|
|
|
poss = defender.items.find(poss => poss.type == ITEM_TYPES.possession && poss.system.victime.actorid == defender.id);
|
2021-11-21 12:04:42 +01:00
|
|
|
}
|
2024-05-02 14:08:02 +02:00
|
|
|
return poss && foundry.utils.duplicate(poss) || undefined;
|
2021-11-11 09:37:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
2022-11-23 22:37:16 +01:00
|
|
|
static async onAttaquePossession(target, attacker, competence, suitePossession = undefined) {
|
2022-11-22 02:12:26 +01:00
|
|
|
const defender = target.actor;
|
2022-11-23 22:37:16 +01:00
|
|
|
const fromEntite = RdDPossession.searchPossessionFromEntite(attacker, defender);
|
2023-06-14 01:48:32 +02:00
|
|
|
const isNouvelle = !suitePossession && !fromEntite;
|
2022-11-23 22:37:16 +01:00
|
|
|
const possession = (suitePossession ?? fromEntite ?? (await RdDPossession.createPossession(attacker, defender)));
|
2023-06-14 01:48:32 +02:00
|
|
|
|
2022-11-23 22:37:16 +01:00
|
|
|
RdDPossession.$updateEtatPossession(possession)
|
|
|
|
|
2022-11-22 02:12:26 +01:00
|
|
|
let rollData = {
|
2023-06-14 01:48:32 +02:00
|
|
|
mode: "attaque",
|
2022-11-22 02:12:26 +01:00
|
|
|
isECNIDefender: false,
|
2023-08-03 00:33:56 +02:00
|
|
|
competence: competence,
|
2022-11-22 02:12:26 +01:00
|
|
|
possession: possession,
|
|
|
|
attacker: attacker,
|
2022-11-23 22:37:16 +01:00
|
|
|
defender: defender,
|
|
|
|
targetToken: Targets.extractTokenData(target)
|
2022-11-22 02:12:26 +01:00
|
|
|
};
|
2023-06-14 01:48:32 +02:00
|
|
|
RdDPossession.selectCompetenceDraconicOuPossession(rollData, attacker)
|
|
|
|
|
2022-11-23 22:37:16 +01:00
|
|
|
await RdDPossession.$rollAttaquePossession(attacker, rollData, isNouvelle);
|
2021-11-11 09:37:00 +01:00
|
|
|
}
|
2023-06-14 01:48:32 +02:00
|
|
|
|
2021-11-11 09:37:00 +01:00
|
|
|
/* -------------------------------------------- */
|
2023-06-14 01:48:32 +02:00
|
|
|
static async onConjurerPossession(attacker, possession) {
|
2024-05-02 14:08:02 +02:00
|
|
|
possession = foundry.utils.duplicate(possession);
|
2022-11-23 22:37:16 +01:00
|
|
|
RdDPossession.$updateEtatPossession(possession)
|
2023-06-14 01:48:32 +02:00
|
|
|
|
|
|
|
const defender = game.actors.get(possession.system.entite.actorid);
|
2022-11-22 02:12:26 +01:00
|
|
|
let rollData = {
|
2023-06-14 01:48:32 +02:00
|
|
|
mode: "attaque",
|
2022-11-22 02:12:26 +01:00
|
|
|
isECNIDefender: true,
|
|
|
|
possession: possession,
|
|
|
|
attacker: attacker,
|
2023-06-14 01:48:32 +02:00
|
|
|
defender: defender,
|
2022-11-22 02:12:26 +01:00
|
|
|
};
|
2023-06-14 01:48:32 +02:00
|
|
|
RdDPossession.selectCompetenceDraconicOuPossession(rollData, attacker)
|
|
|
|
|
2022-11-22 02:12:26 +01:00
|
|
|
await RdDPossession.$rollAttaquePossession(attacker, rollData);
|
2021-11-21 12:04:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
2022-07-02 01:41:55 +02:00
|
|
|
static async onDefensePossession(attackerId, defenderId, possessionId) {
|
2022-06-12 08:17:59 +02:00
|
|
|
let attacker = game.actors.get(attackerId)
|
2022-11-22 02:12:26 +01:00
|
|
|
let possession = attacker?.getPossession(possessionId)
|
2023-06-14 01:48:32 +02:00
|
|
|
defenderId = defenderId ?? possession?.system.entite.actorid ?? undefined
|
2022-06-12 08:17:59 +02:00
|
|
|
let defender = game.actors.get(defenderId)
|
2022-11-22 02:12:26 +01:00
|
|
|
possession = possession ?? defender?.getPossession(possessionId) ?? undefined;
|
|
|
|
|
2022-07-02 01:41:55 +02:00
|
|
|
if (!possession) {
|
|
|
|
ui.notifications.warn("Une erreur s'est produite : Aucune possession trouvée !!")
|
|
|
|
return
|
2022-06-12 08:17:59 +02:00
|
|
|
}
|
2024-05-02 14:08:02 +02:00
|
|
|
possession = foundry.utils.duplicate(possession)
|
2021-11-21 12:04:42 +01:00
|
|
|
// Update for draconic roll
|
|
|
|
let rollData = {
|
2023-06-14 01:48:32 +02:00
|
|
|
mode: "defense",
|
2022-07-02 01:41:55 +02:00
|
|
|
isECNIDefender: defender.type == "entite",
|
2022-11-23 22:37:16 +01:00
|
|
|
possession: possession,
|
2022-07-02 01:41:55 +02:00
|
|
|
attacker: attacker,
|
|
|
|
defender: defender,
|
2021-11-21 12:04:42 +01:00
|
|
|
}
|
2023-06-14 01:48:32 +02:00
|
|
|
RdDPossession.selectCompetenceDraconicOuPossession(rollData, defender)
|
|
|
|
rollData.diffLibre = RdDPossession.getInfoAttaque(rollData).diffLibre
|
|
|
|
|
2022-11-23 22:37:16 +01:00
|
|
|
await RdDPossession.$rollDefensePossession(defender, rollData);
|
2022-11-22 02:12:26 +01:00
|
|
|
}
|
2023-06-14 01:48:32 +02:00
|
|
|
|
|
|
|
static selectCompetenceDraconicOuPossession(rollData, rollingActor) {
|
|
|
|
rollData.competence = rollingActor.getDraconicOuPossession();
|
|
|
|
if (rollingActor.isCreatureEntite()) {
|
|
|
|
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rollData.selectedCarac = rollingActor.system.carac.reve
|
|
|
|
rollData.forceCarac = { 'reve-actuel': { label: "Rêve Actuel", value: rollingActor.getReveActuel() } }
|
|
|
|
rollData.competence.system.defaut_carac = 'reve-actuel'
|
|
|
|
}
|
|
|
|
}
|
2022-11-22 02:12:26 +01:00
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
2022-11-23 22:37:16 +01:00
|
|
|
static async $rollAttaquePossession(attacker, rollData, isNouvelle = false) {
|
2022-11-22 02:12:26 +01:00
|
|
|
const dialog = await RdDRoll.create(attacker, rollData,
|
2022-11-23 22:37:16 +01:00
|
|
|
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' },
|
2022-11-22 02:12:26 +01:00
|
|
|
{
|
|
|
|
name: 'jet-possession',
|
|
|
|
label: rollData.isECNIDefender ? 'Conjurer la possession' : 'Possession',
|
|
|
|
callbacks: [
|
2023-06-14 01:48:32 +02:00
|
|
|
{ action: async (r) => await RdDPossession.$onRollPossession(r, isNouvelle) },
|
2022-11-22 02:12:26 +01:00
|
|
|
]
|
|
|
|
});
|
2023-06-14 01:48:32 +02:00
|
|
|
dialog.render(true);
|
2022-11-22 02:12:26 +01:00
|
|
|
}
|
2022-06-12 08:17:59 +02:00
|
|
|
|
2022-11-22 02:12:26 +01:00
|
|
|
/* -------------------------------------------- */
|
2023-06-14 01:48:32 +02:00
|
|
|
static async $onRollPossession(rollData, isNouvelle = false) {
|
|
|
|
rollData.possession.isSuccess = rollData.rolled.isSuccess;
|
|
|
|
RdDPossession.$updateEtatPossession(rollData.possession, rollData);
|
2022-11-23 22:37:16 +01:00
|
|
|
if (isNouvelle) {
|
|
|
|
// Creer la possession sur le defenseur
|
2023-06-14 01:48:32 +02:00
|
|
|
await rollData.defender.createEmbeddedDocuments('Item', [rollData.possession.toObject()])
|
2022-11-23 22:37:16 +01:00
|
|
|
}
|
2023-06-14 01:48:32 +02:00
|
|
|
const possession = (rollData.isECNIDefender ? rollData.attacker : rollData.defender).getPossession(rollData.possession.system.possessionid)
|
|
|
|
RdDPossession.storePossessionAttaque(possession, rollData)
|
2024-08-31 00:46:20 +02:00
|
|
|
await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-resultat-possession.html');
|
2022-11-23 22:37:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
static async $rollDefensePossession(defender, rollData) {
|
2022-06-12 08:17:59 +02:00
|
|
|
const dialog = await RdDRoll.create(defender, rollData,
|
2022-11-23 22:37:16 +01:00
|
|
|
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-possession.html' },
|
2021-11-21 12:04:42 +01:00
|
|
|
{
|
2023-06-13 01:55:38 +02:00
|
|
|
name: 'possession',
|
2021-11-21 12:04:42 +01:00
|
|
|
label: 'Conjurer une Possession',
|
|
|
|
callbacks: [
|
2022-11-23 22:37:16 +01:00
|
|
|
{ action: async (r) => await RdDPossession.$onRollConjuration(r) }
|
2023-06-14 01:48:32 +02:00
|
|
|
]
|
|
|
|
}
|
|
|
|
);
|
2022-11-22 02:12:26 +01:00
|
|
|
dialog.render(true);
|
2023-06-14 01:48:32 +02:00
|
|
|
}
|
2021-11-11 09:37:00 +01:00
|
|
|
|
2022-11-22 02:12:26 +01:00
|
|
|
/* -------------------------------------------- */
|
|
|
|
static async $onRollConjuration(rollData) {
|
2023-06-14 01:48:32 +02:00
|
|
|
let victime = game.actors.get(rollData.possession.system.victime.actorid)
|
|
|
|
let compteur = rollData.possession.system.compteur
|
2022-11-22 02:12:26 +01:00
|
|
|
if (!rollData.rolled.isSuccess) {
|
|
|
|
if (rollData.isECNIDefender) {
|
2023-06-14 01:48:32 +02:00
|
|
|
compteur--
|
2022-11-22 02:12:26 +01:00
|
|
|
} else {
|
2023-06-14 01:48:32 +02:00
|
|
|
compteur++
|
2022-11-22 02:12:26 +01:00
|
|
|
}
|
2021-11-11 09:37:00 +01:00
|
|
|
}
|
2023-06-14 01:48:32 +02:00
|
|
|
const possession = victime.getPossession(rollData.possession.system.possessionid)
|
|
|
|
await possession.update({
|
|
|
|
system: {
|
|
|
|
compteur: compteur,
|
|
|
|
entite: { diffLibre: 0, finesse: false },
|
|
|
|
victime: { diffLibre: 0, finesse: false }
|
|
|
|
}
|
|
|
|
})
|
|
|
|
rollData.possession = possession
|
2022-11-23 22:37:16 +01:00
|
|
|
RdDPossession.$updateEtatPossession(rollData.possession)
|
2022-11-22 02:12:26 +01:00
|
|
|
|
2024-08-31 00:46:20 +02:00
|
|
|
await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-resultat-possession.html')
|
2022-11-22 02:12:26 +01:00
|
|
|
if (rollData.possession.isPosseder || rollData.possession.isConjurer) {
|
|
|
|
// conjuration
|
2023-06-14 01:48:32 +02:00
|
|
|
victime.deleteEmbeddedDocuments("Item", [rollData.possession._id])
|
2022-11-22 02:12:26 +01:00
|
|
|
}
|
2021-11-11 09:37:00 +01:00
|
|
|
}
|
|
|
|
|
2022-07-02 01:41:55 +02:00
|
|
|
/* -------------------------------------------- */
|
2022-11-22 02:12:26 +01:00
|
|
|
static $updateEtatPossession(possession) {
|
|
|
|
possession.ptsConjuration = 0
|
|
|
|
possession.ptsPossession = 0
|
|
|
|
console.log("Possession", possession)
|
|
|
|
if (possession.system.compteur > 0) {
|
|
|
|
possession.ptsPossession = possession.system.compteur
|
|
|
|
}
|
|
|
|
if (possession.system.compteur < 0) {
|
|
|
|
possession.ptsConjuration = Math.abs(possession.system.compteur)
|
|
|
|
}
|
|
|
|
possession.isPosseder = false
|
|
|
|
possession.isConjurer = false
|
|
|
|
if (possession.ptsPossession >= 2) {
|
|
|
|
possession.isPosseder = true
|
|
|
|
}
|
|
|
|
if (possession.ptsConjuration >= 2) {
|
|
|
|
possession.isConjurer = true
|
|
|
|
}
|
2022-06-25 18:59:20 +02:00
|
|
|
}
|
|
|
|
|
2023-06-14 01:48:32 +02:00
|
|
|
/* -------------------------------------------- */
|
|
|
|
static isPossessionFinesse(rollData) {
|
|
|
|
return RdDPossession.getInfoAttaque(rollData).finesse
|
|
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
static getInfoAttaque(rollData) {
|
|
|
|
return rollData.possession.system[rollData.isECNIDefender ? 'victime' : 'entite'];
|
|
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
static isDefensePossession(rollData) {
|
|
|
|
return rollData.possession && rollData.mode == "defense"
|
|
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
static storePossessionAttaque(possession, rollData = undefined) {
|
|
|
|
const attaquant = rollData?.isECNIDefender ? 'victime' : 'entite'
|
|
|
|
possession.update({
|
|
|
|
[`system.${attaquant}`]: {
|
|
|
|
diffLibre: rollData?.diffLibre ?? 0,
|
|
|
|
finesse: rollData?.rolled.isPart ?? false
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-11-11 09:37:00 +01:00
|
|
|
/* -------------------------------------------- */
|
2022-07-02 01:41:55 +02:00
|
|
|
static async createPossession(attacker, defender) {
|
2022-11-23 22:37:16 +01:00
|
|
|
return await Item.create({
|
2023-06-14 01:48:32 +02:00
|
|
|
name: "Possession en cours de " + attacker.name, type: 'possession',
|
|
|
|
img: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
|
|
|
|
system: {
|
|
|
|
description: "", typepossession: attacker.name,
|
|
|
|
possede: false,
|
2024-09-01 20:39:25 +02:00
|
|
|
possessionid: foundry.utils.randomID(16),
|
2023-06-14 01:48:32 +02:00
|
|
|
entite: { actorid: attacker.id },
|
|
|
|
victime: { actorid: defender.id },
|
|
|
|
compteur: 0
|
|
|
|
}
|
|
|
|
},
|
2022-11-23 22:37:16 +01:00
|
|
|
{
|
|
|
|
temporary: true
|
|
|
|
})
|
2021-11-11 09:37:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|