Gestion de possession - fin de round

- affichage du message pour indiquer l'état d'une possession en fin de
round
- bouton de conjuration depuis la feuille de personnage
This commit is contained in:
2025-12-05 18:03:08 +01:00
parent 19cabe816e
commit 98e8c7a10c
8 changed files with 127 additions and 41 deletions

View File

@@ -5,6 +5,7 @@ import RollDialog from "./roll/roll-dialog.mjs";
import { Targets } from "./targets.js";
import { RdDUtility } from "./rdd-utility.js";
import { ROLL_TYPE_POSSESSION } from "./roll/roll-constants.mjs";
import { TokenActor } from "./technical/actor-token.mjs";
export const ACTIONS_POSSESSION = {
ATTAQUE: 'attaque',
@@ -21,7 +22,7 @@ export class RdDPossessionV2 {
}
static $isInverse(entite, victime) {
return !entite.isEntiteNonIncarnee() && victime.isEntiteNonIncarnee()
return !entite.actor.isEntiteNonIncarnee() && victime.actor.isEntiteNonIncarnee()
}
/* -------------------------------------------- */
@@ -29,7 +30,7 @@ export class RdDPossessionV2 {
if (RdDPossessionV2.$isInverse(entite, victime)) {
return RdDPossessionV2.findPossession(victime, entite)
}
return victime.itemTypes[ITEM_TYPES.possession].find(poss => poss.system.entiteid == entite.id)
return victime.actor.itemTypes[ITEM_TYPES.possession].find(it => it.system.entiteid == entite.id)
}
static async createPossessionIfMissing(entite, victime) {
@@ -38,30 +39,36 @@ export class RdDPossessionV2 {
}
const existing = RdDPossessionV2.findPossession(entite, victime)
if (!existing) {
await victime.createEmbeddedDocuments('Item', [{
await victime.actor.createEmbeddedDocuments('Item', [{
name: `Possession de ${entite.name}`,
type: ITEM_TYPES.possession,
img: RDD_CONFIG.icons.possession,
system: { entiteid: entite.id, victimeid: victime.id, compteur: 0 }
system: {
entiteid: entite.actor.id,
entitetokenid: entite.token.id,
victimeid: victime.actor.id,
victimetokenid: victime.token.id,
compteur: 0
}
}])
}
}
static getTypePossession(activeActor, opponentActor) {
const isEntite = activeActor.isEntiteNonIncarnee() && !opponentActor.isEntiteNonIncarnee();
const itemPossession = RdDPossessionV2.findPossession(activeActor, opponentActor);
const compteur = itemPossession?.system.compteur ?? 0;
static getTypePossession(active, opponent) {
const itemPossession = RdDPossessionV2.findPossession(active, opponent)
const isEntite = active.actor.isEntiteNonIncarnee() && !opponent.actor.isEntiteNonIncarnee()
const compteur = itemPossession?.system.compteur ?? 0
return {
isEntite: isEntite,
isPersonnage: activeActor.isPersonnage(),
isPersonnage: active.actor.isPersonnage(),
isCompteurPossession: Math.sign(compteur) >= 0,
compteur: Math.abs(compteur)
};
}
}
static getTypePossessionAction(roll, action) {
const possession = RdDPossessionV2.getTypePossession(roll.active.actor, roll.opponent.actor)
static getTypePossessionAction(active, opponent, action) {
const possession = RdDPossessionV2.getTypePossession(active, opponent)
possession.isAttaque = RdDPossessionV2.isAttaque(action)
possession.action = RdDPossessionV2.$getAction(possession.isAttaque, possession.isEntite)
return possession
@@ -93,8 +100,8 @@ export class RdDPossessionV2 {
}
static async rollAttaquePossession(actor) {
const selectedToken = RdDUtility.getSelectedToken(actor)
Targets.selectOneTargetToken(async target => {
const selectedToken = RdDUtility.getSelectedToken(actor)
RollDialog.create(
{
ids: {
@@ -109,7 +116,7 @@ export class RdDPossessionV2 {
{
onRollDone: RollDialog.onRollDoneClose,
callbacks: [
async (roll) => await RdDPossessionV2.createPossessionIfMissing(roll.active.actor, roll.opponent.actor),
async (roll) => await RdDPossessionV2.createPossessionIfMissing(roll.active, roll.opponent),
async (roll) => RdDPossessionV2.$setParticuliereFinesse(roll),
async (roll) => await RdDPossessionV2.chatMessageDefensePossession(roll)
]
@@ -117,6 +124,32 @@ export class RdDPossessionV2 {
})
}
static async rollConjurerPossession(actor, possession) {
if (possession.system.possede){
ui.notifications.warn(`${actor.name} est totalement possédé, impossible de conjurer l'entité`)
return
}
RollDialog.create(
{
ids: {
actorId: possession.system.victimeid,
actorTokenId: possession.system.victimetokenid,
opponentId: possession.system.entiteid,
opponentTokenId: possession.system.entitetokenid
},
passeArme: foundry.utils.randomID(16),
type: { allowed: [ROLL_TYPE_POSSESSION], current: ROLL_TYPE_POSSESSION, possession: { action: ACTIONS_POSSESSION.ATTAQUE } },
},
{
onRollDone: RollDialog.onRollDoneClose,
callbacks: [
async (roll) => await RdDPossessionV2.createPossessionIfMissing(roll.active, roll.opponent),
async (roll) => RdDPossessionV2.$setParticuliereFinesse(roll),
async (roll) => await RdDPossessionV2.chatMessageDefensePossession(roll)
]
})
}
static $setParticuliereFinesse(roll) {
if (roll.rolled.isPart) {
roll.particuliere = RDD_CONFIG.particuliere.finesse.key
@@ -140,18 +173,20 @@ export class RdDPossessionV2 {
ChatUtility.remover(chatMessage)
]
});
}
static async onRollDefense(defense) {
if (defense.rolled.isEchec) {
await RdDPossessionV2.addPointPossession(defense.opponent.actor, defense.active.actor)
}
RdDPossessionV2.resetPossession(defense)
}
static async onRollDefense(defense) {
if (defense.rolled.isEchec) {
await RdDPossessionV2.addPointPossession(defense.opponent.actor, defense.active.actor)
}
RdDPossessionV2.resetPossession(defense)
}
static async onMarquerPointPossession(roll) {
roll.type = {}
await RdDPossessionV2.addPointPossession(roll.opponent.actor, roll.active.actor)
await RdDPossessionV2.addPointPossession(roll.opponent, roll.active)
RdDPossessionV2.resetPossession(roll)
await ChatMessage.create({
@@ -166,7 +201,7 @@ export class RdDPossessionV2 {
static resetPossession(roll) {
roll.type.possession = foundry.utils.mergeObject(
roll.type.possession ?? {},
RdDPossessionV2.getTypePossession(roll.opponent.actor, roll.active.actor))
RdDPossessionV2.getTypePossession(roll.opponent, roll.active))
}
static async addPointPossession(entite, victime, points = 1) {
@@ -176,7 +211,7 @@ export class RdDPossessionV2 {
const existing = RdDPossessionV2.findPossession(entite, victime)
if (existing) {
const compteur = (existing.system.compteur ?? 0) + points
await victime.updateEmbeddedDocuments('Item', [{ _id: existing.id, 'system.compteur': compteur }])
await victime.actor.updateEmbeddedDocuments('Item', [{ _id: existing.id, 'system.compteur': compteur }])
}
}
@@ -184,7 +219,7 @@ export class RdDPossessionV2 {
const defense = RollBasicParts.prepareDefense(attackerRoll)
defense.type = {
possession: RdDPossessionV2.getTypePossessionAction(defense, ACTIONS_POSSESSION.DEFENSE)
possession: RdDPossessionV2.getTypePossessionAction(defense.active, defense.opponent, ACTIONS_POSSESSION.DEFENSE)
}
const chatDemandeDefense = await ChatMessage.create({
@@ -203,4 +238,24 @@ export class RdDPossessionV2 {
})
}
}
static async onPossession(actor, possession) {
if (Math.abs(possession.system.compteur) >= 2) {
await ChatMessage.create({
alias: actor.getAlias(),
whisper: ChatUtility.getOwners(actor),
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/possession/chat-fin-possession.hbs', {
possession,
active: TokenActor.fromActor(actor),
opponent: TokenActor.fromActor(game.actors.get(possession.system.entiteid))
})
})
if (possession.system.compteur <= -2) {
await actor.deleteEmbeddedDocuments('Item', [possession.id])
}
if (possession.system.compteur >= 2) {
await actor.updateEmbeddedDocuments('Item', [{ _id: possession.id, 'system.possede': true }])
}
}
}
}