Gestion des difficultés de Possession
- gestion de la difficulté imposée sur la défense - gestion des particulières en attaque considérées en finesse - utilisation du rêve actuel pour les personnages
This commit is contained in:
parent
e46f35ef92
commit
2db6895c76
@ -45,7 +45,7 @@ const POSSESSION_SANS_DRACONIC = {
|
||||
name: 'Sans draconic',
|
||||
system: {
|
||||
niveau: 0,
|
||||
defaut_carac: "reve",
|
||||
defaut_carac: "reve-actuel",
|
||||
}
|
||||
};
|
||||
|
||||
@ -275,12 +275,12 @@ export class RdDActor extends RdDBaseActor {
|
||||
.sort(Misc.descending(it => it.system.niveau))
|
||||
.find(it=>true);
|
||||
if (possession) {
|
||||
return duplicate(possession);
|
||||
return possession.clone();
|
||||
}
|
||||
const draconics = [...this.getDraconicList().filter(it => it.system.niveau >= 0),
|
||||
const draconics = [...this.getDraconicList().filter(it => it.system.niveau >= 0).map(it =>it.clone()),
|
||||
POSSESSION_SANS_DRACONIC]
|
||||
.sort(Misc.descending(it => it.system.niveau));
|
||||
return duplicate(draconics[0]);
|
||||
return draconics[0];
|
||||
}
|
||||
|
||||
getPossession(possessionId) {
|
||||
@ -780,7 +780,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
async combattreReveDeDragon(force) {
|
||||
let rollData = {
|
||||
actor: this,
|
||||
competence: duplicate(this.getDraconicOuPossession()),
|
||||
competence: this.getDraconicOuPossession(),
|
||||
canClose: false,
|
||||
rencontre: await game.system.rdd.rencontresTMR.getReveDeDragon(force),
|
||||
tmr: true,
|
||||
@ -2301,14 +2301,14 @@ export class RdDActor extends RdDBaseActor {
|
||||
carac: this.system.carac,
|
||||
competence: this.getCompetence(idOrName)
|
||||
}
|
||||
if (rollData.competence.type == 'competencecreature') {
|
||||
if (rollData.competence.system.iscombat && options.tryTarget && Targets.hasTargets()) {
|
||||
if (rollData.competence.type == TYPES.competencecreature) {
|
||||
const arme = RdDItemCompetenceCreature.armeCreature(rollData.competence)
|
||||
if (arme && options.tryTarget && Targets.hasTargets()) {
|
||||
Targets.selectOneToken(target => {
|
||||
if (rollData.competence.system.ispossession) {
|
||||
if (arme.action == "possession") {
|
||||
RdDPossession.onAttaquePossession(target, this, rollData.competence)
|
||||
}
|
||||
else {
|
||||
const arme = RdDItemCompetenceCreature.armeCreature(rollData.competence)
|
||||
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme)
|
||||
}
|
||||
});
|
||||
@ -3135,9 +3135,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
conjurerPossession(possession) {
|
||||
// TODO: choix de la compétence de draconic ou de possession
|
||||
let draconic = this.getDraconicOuPossession();
|
||||
RdDPossession.onConjurerPossession(this, draconic, possession)
|
||||
RdDPossession.onConjurerPossession(this, possession)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -495,6 +495,25 @@ class _10_7_19_CategorieCompetenceCreature extends Migration {
|
||||
}
|
||||
}
|
||||
|
||||
class _10_7_19_PossessionsEntiteVictime extends Migration {
|
||||
get code() { return "possessions-entite-victime"; }
|
||||
get version() { return "10.7.19"; }
|
||||
|
||||
async migrate() {
|
||||
await this.applyItemsUpdates(items => items
|
||||
.filter(it => TYPES.possession == it.type)
|
||||
.map(it => this.migratePossession(it))
|
||||
);
|
||||
}
|
||||
|
||||
migratePossession(it) {
|
||||
return { _id: it.id,
|
||||
'system.entite.actorid': it.system.possesseurid,
|
||||
'system.victime.actorid': it.system.possedeid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class Migrations {
|
||||
static getMigrations() {
|
||||
return [
|
||||
@ -512,6 +531,7 @@ export class Migrations {
|
||||
new _10_5_0_UpdatePeriodicite(),
|
||||
new _10_7_0_MigrationBlessures(),
|
||||
new _10_7_19_CategorieCompetenceCreature(),
|
||||
new _10_7_19_PossessionsEntiteVictime(),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { RdDCarac } from "./rdd-carac.js";
|
||||
import { RdDPossession } from "./rdd-possession.js";
|
||||
|
||||
const conditionsTactiques = [
|
||||
{ type: '', descr: '', dmg: 0, attaque: 0, parade: 0, esquive: true },
|
||||
@ -27,6 +28,9 @@ export class RdDBonus {
|
||||
if (rollData.isEmpoignade && rollData.rolled?.isPart) {
|
||||
return true
|
||||
}
|
||||
if (RdDPossession.isDefensePossession(rollData)) {
|
||||
return RdDPossession.isPossessionFinesse(rollData)
|
||||
}
|
||||
return rollData.attackerRoll?.particuliere == 'finesse';
|
||||
}
|
||||
|
||||
@ -74,7 +78,7 @@ export class RdDBonus {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _dmgArme(rollData) {
|
||||
if ( rollData.arme) {
|
||||
if (rollData.arme) {
|
||||
let dmgBase = rollData.arme.system.dommagesReels ?? Number(rollData.arme.system.dommages ?? 0);
|
||||
//Le bonus dégats magiques ne peut pas faire dépasser le bonus de l'arme (cf p.278)
|
||||
return dmgBase + Math.min(dmgBase, rollData.arme.system.magique ? rollData.arme.system.ecaille_efficacite : 0);
|
||||
|
@ -1,9 +1,9 @@
|
||||
/* -------------------------------------------- */
|
||||
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 { Targets } from "./targets.js";
|
||||
import { TYPES } from "./item.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* On part du principe qu'une entité démarre tjs
|
||||
@ -20,9 +20,9 @@ export class RdDPossession {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static searchPossessionFromEntite(attacker, defender) {
|
||||
let poss = attacker.items.find(poss => poss.type == 'possession' && poss.system.possedeid == defender.id);
|
||||
let poss = attacker.items.find(poss => poss.type == TYPES.possession && poss.system.victime.actorid == defender.id);
|
||||
if (!poss) {
|
||||
poss = defender.items.find(poss => poss.type == 'possession' && poss.system.possedeid == defender.id);
|
||||
poss = defender.items.find(poss => poss.type == TYPES.possession && poss.system.victime.actorid == defender.id);
|
||||
}
|
||||
return poss && duplicate(poss) || undefined;
|
||||
}
|
||||
@ -31,13 +31,13 @@ export class RdDPossession {
|
||||
static async onAttaquePossession(target, attacker, competence, suitePossession = undefined) {
|
||||
const defender = target.actor;
|
||||
const fromEntite = RdDPossession.searchPossessionFromEntite(attacker, defender);
|
||||
const isNouvelle = !suitePossession && ! fromEntite;
|
||||
const isNouvelle = !suitePossession && !fromEntite;
|
||||
const possession = (suitePossession ?? fromEntite ?? (await RdDPossession.createPossession(attacker, defender)));
|
||||
|
||||
RdDPossession.$updateEtatPossession(possession)
|
||||
|
||||
let rollData = {
|
||||
mode: "possession",
|
||||
mode: "attaque",
|
||||
isECNIDefender: false,
|
||||
competence: competence.clone(),
|
||||
possession: possession,
|
||||
@ -45,25 +45,26 @@ export class RdDPossession {
|
||||
defender: defender,
|
||||
targetToken: Targets.extractTokenData(target)
|
||||
};
|
||||
if (attacker.isCreatureEntite()) {
|
||||
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
||||
}
|
||||
RdDPossession.selectCompetenceDraconicOuPossession(rollData, attacker)
|
||||
|
||||
await RdDPossession.$rollAttaquePossession(attacker, rollData, isNouvelle);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async onConjurerPossession(attacker, competence, possession) {
|
||||
static async onConjurerPossession(attacker, possession) {
|
||||
possession = duplicate(possession);
|
||||
RdDPossession.$updateEtatPossession(possession)
|
||||
|
||||
const defender = game.actors.get(possession.system.entite.actorid);
|
||||
let rollData = {
|
||||
mode: "possession",
|
||||
mode: "attaque",
|
||||
isECNIDefender: true,
|
||||
competence: competence,
|
||||
possession: possession,
|
||||
attacker: attacker,
|
||||
defender: game.actors.get(possession.system.possesseurid)
|
||||
defender: defender,
|
||||
};
|
||||
RdDPossession.selectCompetenceDraconicOuPossession(rollData, attacker)
|
||||
|
||||
await RdDPossession.$rollAttaquePossession(attacker, rollData);
|
||||
}
|
||||
|
||||
@ -71,7 +72,7 @@ export class RdDPossession {
|
||||
static async onDefensePossession(attackerId, defenderId, possessionId) {
|
||||
let attacker = game.actors.get(attackerId)
|
||||
let possession = attacker?.getPossession(possessionId)
|
||||
defenderId = defenderId ?? possession?.system.possesseurid ?? undefined
|
||||
defenderId = defenderId ?? possession?.system.entite.actorid ?? undefined
|
||||
let defender = game.actors.get(defenderId)
|
||||
possession = possession ?? defender?.getPossession(possessionId) ?? undefined;
|
||||
|
||||
@ -82,20 +83,30 @@ export class RdDPossession {
|
||||
possession = duplicate(possession)
|
||||
// Update for draconic roll
|
||||
let rollData = {
|
||||
mode: "conjuration",
|
||||
mode: "defense",
|
||||
isECNIDefender: defender.type == "entite",
|
||||
possession: possession,
|
||||
attacker: attacker,
|
||||
defender: defender,
|
||||
competence: defender.getDraconicOuPossession(),
|
||||
selectedCarac: defender.system.carac.reve,
|
||||
forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: defender.getReveActuel() } }
|
||||
}
|
||||
rollData.competence.system.defaut_carac = 'reve-actuel'
|
||||
RdDPossession.selectCompetenceDraconicOuPossession(rollData, defender)
|
||||
rollData.diffLibre = RdDPossession.getInfoAttaque(rollData).diffLibre
|
||||
|
||||
await RdDPossession.$rollDefensePossession(defender, rollData);
|
||||
}
|
||||
|
||||
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'
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async $rollAttaquePossession(attacker, rollData, isNouvelle = false) {
|
||||
const dialog = await RdDRoll.create(attacker, rollData,
|
||||
@ -104,21 +115,22 @@ export class RdDPossession {
|
||||
name: 'jet-possession',
|
||||
label: rollData.isECNIDefender ? 'Conjurer la possession' : 'Possession',
|
||||
callbacks: [
|
||||
{ condition: r => (r.rolled.isSuccess), action: async (r) => await RdDPossession.$onRollPossession(r, true, isNouvelle) },
|
||||
{ condition: r => (r.rolled.isEchec), action: async (r) => await RdDPossession.$onRollPossession(r, false, isNouvelle) },
|
||||
{ action: async (r) => await RdDPossession.$onRollPossession(r, isNouvelle) },
|
||||
]
|
||||
});
|
||||
dialog.render(true);
|
||||
dialog.render(true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async $onRollPossession(rollData, isSuccess, isNouvelle = false) {
|
||||
rollData.possession.isSuccess = isSuccess;
|
||||
RdDPossession.$updateEtatPossession(rollData.possession);
|
||||
static async $onRollPossession(rollData, isNouvelle = false) {
|
||||
rollData.possession.isSuccess = rollData.rolled.isSuccess;
|
||||
RdDPossession.$updateEtatPossession(rollData.possession, rollData);
|
||||
if (isNouvelle) {
|
||||
// Creer la possession sur le defenseur
|
||||
rollData.defender.createEmbeddedDocuments('Item', [rollData.possession.toObject()])
|
||||
await rollData.defender.createEmbeddedDocuments('Item', [rollData.possession.toObject()])
|
||||
}
|
||||
const possession = (rollData.isECNIDefender ? rollData.attacker : rollData.defender).getPossession(rollData.possession.system.possessionid)
|
||||
RdDPossession.storePossessionAttaque(possession, rollData)
|
||||
await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-resultat-possession.html');
|
||||
}
|
||||
|
||||
@ -139,23 +151,30 @@ export class RdDPossession {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async $onRollConjuration(rollData) {
|
||||
let actor = game.actors.get(rollData.possession.system.possedeid)
|
||||
let victime = game.actors.get(rollData.possession.system.victime.actorid)
|
||||
let compteur = rollData.possession.system.compteur
|
||||
if (!rollData.rolled.isSuccess) {
|
||||
if (rollData.isECNIDefender) {
|
||||
rollData.possession.system.compteur--
|
||||
compteur--
|
||||
} else {
|
||||
rollData.possession.system.compteur++
|
||||
compteur++
|
||||
}
|
||||
let update = { _id: rollData.possession._id, "system.compteur": rollData.possession.system.compteur }
|
||||
await actor.updateEmbeddedDocuments('Item', [update])
|
||||
}
|
||||
|
||||
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
|
||||
RdDPossession.$updateEtatPossession(rollData.possession)
|
||||
|
||||
await RdDResolutionTable.displayRollData(rollData,rollData.defender, 'chat-resultat-possession.html')
|
||||
await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-resultat-possession.html')
|
||||
if (rollData.possession.isPosseder || rollData.possession.isConjurer) {
|
||||
// conjuration
|
||||
actor.deleteEmbeddedDocuments("Item", [rollData.possession._id])
|
||||
victime.deleteEmbeddedDocuments("Item", [rollData.possession._id])
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,13 +199,43 @@ export class RdDPossession {
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async createPossession(attacker, defender) {
|
||||
return await Item.create({
|
||||
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, possessionid: randomID(16), possesseurid: attacker.id, possedeid: defender.id, date: 0, compteur: 0 }
|
||||
},
|
||||
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,
|
||||
possessionid: randomID(16),
|
||||
entite: { actorid: attacker.id },
|
||||
victime: { actorid: defender.id },
|
||||
compteur: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
temporary: true
|
||||
})
|
||||
|
@ -75,8 +75,8 @@ export class RdDTokenHud {
|
||||
(event) => {
|
||||
const actionIndex = event.currentTarget.attributes['data-action-index']?.value;
|
||||
const action = hudData.actions[actionIndex];
|
||||
if (action.action == 'possession') {
|
||||
const possession = combatant.actor.getPossession(action.system.possessionid);
|
||||
const possession = action.action == 'possession' ? combatant.actor.getPossession(action.system.possessionid) : undefined;
|
||||
if (possession) {
|
||||
combatant.actor.conjurerPossession(possession);
|
||||
}
|
||||
else {
|
||||
|
@ -5,6 +5,7 @@ import { RdDItemSort } from "./item-sort.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDBonus } from "./rdd-bonus.js";
|
||||
import { RdDCarac } from "./rdd-carac.js";
|
||||
import { RdDPossession } from "./rdd-possession.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||
|
||||
@ -30,7 +31,7 @@ export const referenceAjustements = {
|
||||
},
|
||||
diffLibre: {
|
||||
isUsed: (rollData, actor) => rollData.diffLibre != undefined,
|
||||
getLabel: (rollData, actor) => rollData.selectedSort?.name ?? rollData.attackerRoll ? 'Imposée' : 'Libre',
|
||||
getLabel: (rollData, actor) => rollData.selectedSort?.name ?? rollData.attackerRoll ?? RdDPossession.isDefensePossession(rollData) ? 'Imposée' : 'Libre',
|
||||
getValue: (rollData, actor) => rollData.selectedSort
|
||||
? RdDItemSort.getDifficulte(rollData.selectedSort, rollData.diffLibre)
|
||||
: rollData.diffLibre ?? rollData.competence?.system.default_diffLibre ?? 0
|
||||
|
@ -611,10 +611,17 @@
|
||||
"typepossession": "",
|
||||
"possede": false,
|
||||
"possessionid": "",
|
||||
"possesseurid": "",
|
||||
"possedeid": "",
|
||||
"compteur": 0,
|
||||
"date": 0
|
||||
"entite": {
|
||||
"actorid": "",
|
||||
"diffLibre": 0,
|
||||
"finesse": false
|
||||
},
|
||||
"victime": {
|
||||
"actorid": "",
|
||||
"diffLibre": 0,
|
||||
"finesse": false
|
||||
},
|
||||
"compteur": 0
|
||||
},
|
||||
"blessure": {
|
||||
"templates": ["temporel"],
|
||||
|
@ -1,6 +1,6 @@
|
||||
<img class="chat-icon" src="{{competence.img}}" />
|
||||
<h4>
|
||||
{{#if (eq mode "possession")}}
|
||||
{{#if (eq mode "attaque")}}
|
||||
{{attacker.name}} tente de {{#if isECNIDefender}}conjurer la possession de{{else}}posséder{{/if}} {{defender.name}}
|
||||
{{else}}
|
||||
{{defender.name}} tente de {{#if isECNIDefender}}résister à{{else}}conjurer la possession de{{/if}} {{attacker.name}}
|
||||
@ -12,7 +12,7 @@
|
||||
<div>
|
||||
<span class='chat-card-button-area'>
|
||||
<br>
|
||||
{{#if (eq mode "possession")}}
|
||||
{{#if (eq mode "attaque")}}
|
||||
{{#if possession.isSuccess}}
|
||||
<a class='defense-possession chat-card-button'
|
||||
data-attackerId='{{attacker.id}}'
|
||||
|
Loading…
Reference in New Issue
Block a user