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

@@ -52,6 +52,7 @@ import { PART_TACHE } from "./roll/roll-part-tache.mjs";
import { PART_COMP } from "./roll/roll-part-comp.mjs";
import { PART_OEUVRE } from "./roll/roll-part-oeuvre.mjs";
import { PART_CUISINE } from "./roll/roll-part-cuisine.mjs";
import { RdDPossessionV2 } from "./rdd-possession-v2.mjs";
export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre']
@@ -2567,7 +2568,12 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
conjurerPossession(possession) {
RdDPossession.onConjurerPossession(this, possession)
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
RdDPossessionV2.rollConjurerPossession(this, possession)
}
else {
RdDPossession.onConjurerPossession(this, possession)
}
}
/* -------------------------------------------- */

View File

@@ -176,13 +176,14 @@ export class RdDBaseActorReve extends RdDBaseActor {
async santeIncDec(name, inc, isCritique = false) { }
async finDeRound(options = { terminer: false }) {
await this.$finDeRoundSuppressionEffetsTermines(options);
await this.finDeRoundBlessures();
await this.$finDeRoundSupprimerObsoletes();
await this.$finDeRoundEmpoignade();
await this.finDeRoundSuppressionEffetsTermines(options)
await this.finDeRoundBlessures()
await this.finDeRoundSupprimerObsoletes()
await this.finDeRoundEmpoignade()
await this.finDeRoundPossession()
}
async $finDeRoundSuppressionEffetsTermines(options) {
async finDeRoundSuppressionEffetsTermines(options) {
for (let effect of this.getEffects()) {
if (effect.duration.type !== 'none' && (effect.duration.remaining <= 0 || options.terminer)) {
await effect.delete();
@@ -194,20 +195,24 @@ export class RdDBaseActorReve extends RdDBaseActor {
async finDeRoundBlessures() {
}
async $finDeRoundSupprimerObsoletes() {
async finDeRoundSupprimerObsoletes() {
const obsoletes = []
.concat(this.itemTypes[ITEM_TYPES.empoignade].filter(it => it.system.pointsemp <= 0))
.concat(this.itemTypes[ITEM_TYPES.possession].filter(it => it.system.compteur < -2 || it.system.compteur > 2))
.map(it => it.id);
.map(it => it.id)
await this.deleteEmbeddedDocuments('Item', obsoletes);
}
async $finDeRoundEmpoignade() {
async finDeRoundEmpoignade() {
await Promise.all(this.itemTypes[ITEM_TYPES.empoignade]
.filter(it => it.system.pointsemp >= 2 && it.system.empoigneurid == this.id)
.map(async it => await RdDEmpoignade.onImmobilisation(this, it)))
}
async finDeRoundPossession(){
await Promise.all(this.itemTypes[ITEM_TYPES.possession]
.map(async it => await RdDPossessionV2.onPossession(this, it)))
}
async setSonne(sonne = true) { }
/* -------------------------------------------- */

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 }])
}
}
}
}

View File

@@ -62,7 +62,7 @@ export class RollPartPossession extends RollPartSelect {
})
button?.addEventListener("click", async e => {
e.preventDefault()
await RdDPossessionV2.createPossessionIfMissing(rollData.active.actor, rollData.opponent.actor)
await RdDPossessionV2.createPossessionIfMissing(rollData.active, rollData.opponent)
rollDialog.render()
})
}

View File

@@ -7,7 +7,7 @@ export class RollTypePossession extends RollType {
get name() { return "Posséder" }
prepare(rollData) {
rollData.type.possession = RdDPossessionV2.getTypePossessionAction(rollData, rollData.type.possession?.action)
rollData.type.possession = RdDPossessionV2.getTypePossessionAction(rollData.active, rollData.opponent, rollData.type.possession?.action)
}
title(rollData) {