Compare commits
32 Commits
Author | SHA1 | Date | |
---|---|---|---|
253a1bd433 | |||
e58d88fab6 | |||
631ee0b801 | |||
ed9c574cd2 | |||
bb624e8e96 | |||
40f2ac8714 | |||
804fa3b784 | |||
d35e47824d | |||
37d3fa5bc5 | |||
8a12eb865c | |||
5baa94b3f0 | |||
37c2b6432d | |||
fc63835a71 | |||
d82a543860 | |||
2e76961ba7 | |||
a9f50bbc5e | |||
8ba3476d7b | |||
4e8f6e8872 | |||
727701bdcd | |||
dcc0f0acfd | |||
61eee66ebe | |||
c75d10f69b | |||
333bb051c1 | |||
1bf247db33 | |||
49fc2c9b0a | |||
9013376096 | |||
972459a08d | |||
1607629365 | |||
8f7efdad87 | |||
2dbe0dea4a | |||
5fc455fbad | |||
8a7e4d3a9e |
60
changelog.md
60
changelog.md
@ -1,21 +1,63 @@
|
|||||||
---
|
# v10.7 - L'os de Sémolosse
|
||||||
# v10.7 - L'os de Semolosse
|
|
||||||
|
|
||||||
## v10.7.13 - l'armure de Semolosse
|
## v10.7.20 - la poigne de Sémolosse
|
||||||
|
- correction de méthodes qui filtrent les items
|
||||||
|
- recherche de cases TMR
|
||||||
|
- recherche de tâches de lecture
|
||||||
|
- recherche d'armure (pour le malus armure)
|
||||||
|
- recherche de potions
|
||||||
|
|
||||||
|
## v10.7.20 - la poigne de Sémolosse
|
||||||
|
- correction de l'empoignade
|
||||||
|
- les items d'empoignade sont ajoutés par le MJ quand nécessaire
|
||||||
|
- seul le joueur propriétaire du personnage peut effectuer ses choix et actions d'empoignade
|
||||||
|
- les caractéristiques du défenseur sont utilisées pour la défense
|
||||||
|
- la difficulté d'attaque est imposée au défenseur
|
||||||
|
- les attaques particulières sont en finesse (p133)
|
||||||
|
- on peut entraîner au sol dès 2 points d'empoignade
|
||||||
|
- les actions liée à l'immobilisation sont proposées en fin de round
|
||||||
|
|
||||||
|
## v10.7.19 - les fantômes de Sémolosse
|
||||||
|
- les créatures ont maintenant le droit d'avoir des compétences de tir, lancer, mêlée, armes naturelles, parade.
|
||||||
|
- les créatures armées utilisent la bonne phase d'initiative
|
||||||
|
- correction des possessions
|
||||||
|
- la difficulté de la défense est imposée par l'attaque
|
||||||
|
- une attaque particulière de possession est en finesse
|
||||||
|
- le rêve actuel des personnages est bien utilisé
|
||||||
|
- correction des achats par le MJ sans acteur sélectionné
|
||||||
|
|
||||||
|
## v10.7.18 - le repos de Sémolosse
|
||||||
|
- correction des dates de blessures qui ne marchaient plus
|
||||||
|
|
||||||
|
## v10.7.17 - le doigt du destin de Sémolosse
|
||||||
|
- correction de la validation d'encaissement par le MJ
|
||||||
|
|
||||||
|
## v10.7.16 - la morsure de Sémolosse
|
||||||
|
- correction de l'affichage des objets suite à confusion
|
||||||
|
- correction de liens dans la liste des équipements
|
||||||
|
|
||||||
|
## v10.7.14 - l'expérience de Sémolosse
|
||||||
|
- Affichage des personnages accordés sur les fiches des entités
|
||||||
|
- Refonte du journal d'expérience
|
||||||
|
- disponible pour les personnages des joueurs
|
||||||
|
- explication "comptable" des changements (dépense ou ajout, changements de niveaux, ...)
|
||||||
|
- tri alphabétique des différentes listes (sorts, recettes, oeuvres, ...)
|
||||||
|
|
||||||
|
## v10.7.13 - l'armure de Sémolosse
|
||||||
- Fix: en cas d'armure variable, la détérioration diminue le dé d'armure
|
- Fix: en cas d'armure variable, la détérioration diminue le dé d'armure
|
||||||
|
|
||||||
## v10.7.12
|
## v10.7.12
|
||||||
- Fix: si le MJ gère les changements de jours, l'option "sieste" de la fenêtre de repos est prise par défaut si chateau dormant n'est pas passé
|
- Fix: si le MJ gère les changements de jours, l'option "sieste" de la fenêtre de repos est prise par défaut si chateau dormant n'est pas passé
|
||||||
|
|
||||||
## v10.7.11 - Le Pugilat de Semolosse
|
## v10.7.11 - Le Pugilat de Sémolosse
|
||||||
- Fix sur la projection au sol.
|
- Fix sur la projection au sol.
|
||||||
|
|
||||||
## v10.7.10 - Le Pugilat de Semolosse
|
## v10.7.10 - Le Pugilat de Sémolosse
|
||||||
- Gestion de l'empoignade
|
- Gestion de l'empoignade
|
||||||
- Corrections sur l'initiative
|
- Corrections sur l'initiative
|
||||||
- Correction sur l'equipement des vêtements et bijoux
|
- Correction sur l'equipement des vêtements et bijoux
|
||||||
|
|
||||||
## v10.7.9 - Le Pugilat de Semolosse
|
## v10.7.9 - Le Pugilat de Sémolosse
|
||||||
|
|
||||||
- Gestion assistée de l'empoignade
|
- Gestion assistée de l'empoignade
|
||||||
1. On selectionne sa cible (ie le token qui va être empoigné)
|
1. On selectionne sa cible (ie le token qui va être empoigné)
|
||||||
@ -81,14 +123,14 @@
|
|||||||
- Horloge
|
- Horloge
|
||||||
- A l'heure de Couronne pile, les aiguilles des heures et des minutes pointent sur couronne (comme une montre) au lieu d'avoir l'aiguille des heures 15° à gauche
|
- A l'heure de Couronne pile, les aiguilles des heures et des minutes pointent sur couronne (comme une montre) au lieu d'avoir l'aiguille des heures 15° à gauche
|
||||||
|
|
||||||
## v10.7.2 - les maux de dents de Semolosse
|
## v10.7.2 - les maux de dents de Sémolosse
|
||||||
- correction des récupérations de blessures
|
- correction des récupérations de blessures
|
||||||
- la fin de château dormant se passe normalement
|
- la fin de château dormant se passe normalement
|
||||||
|
|
||||||
## v10.7.1 - L'os de Semolosse
|
## v10.7.1 - L'os de Sémolosse
|
||||||
- Fix rapide sur les jets de carac qui n'étaient plus possibles
|
- Fix rapide sur les jets de carac qui n'étaient plus possibles
|
||||||
|
|
||||||
## v10.7.0 - L'os de Semolosse
|
## v10.7.0 - L'os de Sémolosse
|
||||||
- gestion des blessures en items
|
- gestion des blessures en items
|
||||||
- soins du token ciblé par menu contextuel (comme le combat)
|
- soins du token ciblé par menu contextuel (comme le combat)
|
||||||
- automatisation des soins et de l'affichage de l'avancement des soins
|
- automatisation des soins et de l'affichage de l'avancement des soins
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { RdDActorSheet } from "./actor-sheet.js";
|
import { RdDActorSheet } from "./actor-sheet.js";
|
||||||
|
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
||||||
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
|
|
||||||
export class RdDActorEntiteSheet extends RdDActorSheet {
|
export class RdDActorEntiteSheet extends RdDActorSheet {
|
||||||
|
|
||||||
@ -13,6 +15,12 @@ export class RdDActorEntiteSheet extends RdDActorSheet {
|
|||||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }]
|
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
async getData() {
|
||||||
|
let formData = await super.getData();
|
||||||
|
formData.resonances = this.actor.system.sante.resonnance.actors.map(actorId => game.actors.get(actorId))
|
||||||
|
.map(actor => { return { id: actor.id, name: actor.name, img: actor.img } })
|
||||||
|
return formData
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/** @override */
|
/** @override */
|
||||||
@ -35,6 +43,23 @@ export class RdDActorEntiteSheet extends RdDActorSheet {
|
|||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value));
|
this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
|
this.html.find('.resonance-delete').click(async event => {
|
||||||
|
const li = RdDSheetUtility.getEventElement(event);
|
||||||
|
const actorId = li.data("actor-id");
|
||||||
|
if (actorId) {
|
||||||
|
const actorResonance = game.actors.get(actorId);
|
||||||
|
RdDUtility.confirmerSuppressionSubacteur(this, actorResonance, li, () => {
|
||||||
|
console.log('Delete : ', actorId);
|
||||||
|
this.removeSubacteur(actorId);
|
||||||
|
RdDUtility.slideOnDelete(this, li);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeSubacteur(actorId) {
|
||||||
|
let newResonances = this.actor.system.sante.resonnance.actors.filter(id => id != actorId);
|
||||||
|
await this.actor.update({ 'system.sante.resonnance.actors': newResonances }, { renderSheet: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,11 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
const actorId = li.data("actor-id");
|
const actorId = li.data("actor-id");
|
||||||
if (actorId) {
|
if (actorId) {
|
||||||
const subActor = game.actors.get(actorId);
|
const subActor = game.actors.get(actorId);
|
||||||
RdDUtility.confirmerSuppressionSubacteur(this, subActor, li);
|
RdDUtility.confirmerSuppressionSubacteur(this, subActor, li, () => {
|
||||||
|
console.log('Delete : ', subActor.id);
|
||||||
|
this.actor.removeSubacteur(subActor.id);
|
||||||
|
RdDUtility.slideOnDelete(this, li);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.html.find('.experiencelog-delete').click(async event => {
|
this.html.find('.experiencelog-delete').click(async event => {
|
||||||
@ -142,6 +146,13 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
const key = Number(li.data("key") ?? -1);
|
const key = Number(li.data("key") ?? -1);
|
||||||
await this.actor.deleteExperienceLog(0, key + 1);
|
await this.actor.deleteExperienceLog(0, key + 1);
|
||||||
});
|
});
|
||||||
|
this.html.find("input.derivee-value[name='system.compteurs.stress.value']").change(async event => {
|
||||||
|
this.actor.updateCompteurValue("stress", parseInt(event.target.value));
|
||||||
|
});
|
||||||
|
this.html.find("input.derivee-value[name='system.compteurs.experience.value']").change(async event => {
|
||||||
|
this.actor.updateCompteurValue("experience", parseInt(event.target.value));
|
||||||
|
});
|
||||||
|
|
||||||
this.html.find('.encaisser-direct').click(async event => {
|
this.html.find('.encaisser-direct').click(async event => {
|
||||||
this.actor.encaisser();
|
this.actor.encaisser();
|
||||||
})
|
})
|
||||||
@ -445,9 +456,9 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async selectTypeOeuvreToCreate() {
|
async selectTypeOeuvreToCreate() {
|
||||||
let typeObjets = RdDItem.getTypesOeuvres();
|
let types = RdDItem.getTypesOeuvres();
|
||||||
let content = `<span class="competence-label">Selectionnez le type d'oeuvre</span><select class="item-type">`;
|
let content = `<span class="competence-label">Selectionnez le type d'oeuvre</span><select class="item-type">`;
|
||||||
for (let typeName of typeObjets) {
|
for (let typeName of types) {
|
||||||
content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>`
|
content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>`
|
||||||
}
|
}
|
||||||
content += '</select>';
|
content += '</select>';
|
||||||
|
360
module/actor.js
360
module/actor.js
@ -37,13 +37,15 @@ import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
|||||||
import { RdDItemBlessure } from "./item/blessure.js";
|
import { RdDItemBlessure } from "./item/blessure.js";
|
||||||
import { AppAstrologie } from "./sommeil/app-astrologie.js";
|
import { AppAstrologie } from "./sommeil/app-astrologie.js";
|
||||||
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
||||||
|
import { ExperienceLog, XP_TOPIC } from "./actor/experience-log.js";
|
||||||
|
import { TYPES } from "./item.js";
|
||||||
|
|
||||||
const POSSESSION_SANS_DRACONIC = {
|
const POSSESSION_SANS_DRACONIC = {
|
||||||
img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp',
|
img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp',
|
||||||
name: 'Sans draconic',
|
name: 'Sans draconic',
|
||||||
system: {
|
system: {
|
||||||
niveau: 0,
|
niveau: 0,
|
||||||
defaut_carac: "reve",
|
defaut_carac: "reve-actuel",
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -108,7 +110,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
canReceive(item) {
|
canReceive(item) {
|
||||||
if (this.isCreature()) {
|
if (this.isCreature()) {
|
||||||
return item.type == 'competencecreature' || item.isInventaire();
|
return item.type == TYPES.competencecreature || item.isInventaire();
|
||||||
}
|
}
|
||||||
if (this.isEntite()) {
|
if (this.isEntite()) {
|
||||||
return item.type == 'competencecreature';
|
return item.type == 'competencecreature';
|
||||||
@ -269,25 +271,26 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDraconicOuPossession() {
|
getDraconicOuPossession() {
|
||||||
const possessions = this.items.filter(it => it.type == 'competencecreature' && it.system.ispossession)
|
const possession = this.items.filter(it => it.type == TYPES.competencecreature && it.system.categorie == 'possession')
|
||||||
.sort(Misc.descending(it => it.system.niveau));
|
.sort(Misc.descending(it => it.system.niveau))
|
||||||
if (possessions.length > 0) {
|
.find(it => true);
|
||||||
return duplicate(possessions[0]);
|
if (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]
|
POSSESSION_SANS_DRACONIC]
|
||||||
.sort(Misc.descending(it => it.system.niveau));
|
.sort(Misc.descending(it => it.system.niveau));
|
||||||
return duplicate(draconics[0]);
|
return draconics[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
getPossession(possessionId) {
|
getPossession(possessionId) {
|
||||||
return this.items.find(it => it.type == 'possession' && it.system.possessionid == possessionId);
|
return this.items.find(it => it.type == TYPES.possession && it.system.possessionid == possessionId);
|
||||||
}
|
}
|
||||||
getPossessions() {
|
getPossessions() {
|
||||||
return this.items.filter(it => it.type == 'possession');
|
return this.items.filter(it => it.type == TYPES.possession);
|
||||||
}
|
}
|
||||||
getEmpoignades() {
|
getEmpoignades() {
|
||||||
return this.items.filter(it => it.type == 'empoignade');
|
return this.items.filter(it => it.type == TYPES.empoignade);
|
||||||
}
|
}
|
||||||
getDemiReve() {
|
getDemiReve() {
|
||||||
return this.system.reve.tmrpos.coord;
|
return this.system.reve.tmrpos.coord;
|
||||||
@ -295,7 +298,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async verifierPotionsEnchantees() {
|
async verifierPotionsEnchantees() {
|
||||||
let potionsEnchantees = this.filterItems(it => it.type == 'potion' && it.system.categorie.toLowerCase().includes('enchant'));
|
let potionsEnchantees = this.filterItems(it => it.system.categorie.toLowerCase().includes('enchant'), 'potion');
|
||||||
for (let potion of potionsEnchantees) {
|
for (let potion of potionsEnchantees) {
|
||||||
if (!potion.system.prpermanent) {
|
if (!potion.system.prpermanent) {
|
||||||
console.log(potion);
|
console.log(potion);
|
||||||
@ -777,7 +780,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
async combattreReveDeDragon(force) {
|
async combattreReveDeDragon(force) {
|
||||||
let rollData = {
|
let rollData = {
|
||||||
actor: this,
|
actor: this,
|
||||||
competence: duplicate(this.getDraconicOuPossession()),
|
competence: this.getDraconicOuPossession(),
|
||||||
canClose: false,
|
canClose: false,
|
||||||
rencontre: await game.system.rdd.rencontresTMR.getReveDeDragon(force),
|
rencontre: await game.system.rdd.rencontresTMR.getReveDeDragon(force),
|
||||||
tmr: true,
|
tmr: true,
|
||||||
@ -821,31 +824,40 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async updateCarac(caracName, caracValue) {
|
async updateCarac(caracName, to) {
|
||||||
if (caracName == "force") {
|
if (caracName == "force") {
|
||||||
if (Number(caracValue) > this.getTaille() + 4) {
|
if (Number(to) > this.getTaille() + 4) {
|
||||||
ui.notifications.warn("Votre FORCE doit être au maximum de TAILLE+4");
|
ui.notifications.warn("Votre FORCE doit être au maximum de TAILLE+4");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (caracName == "reve") {
|
if (caracName == "reve") {
|
||||||
if (caracValue > Misc.toInt(this.system.reve.seuil.value)) {
|
if (to > Misc.toInt(this.system.reve.seuil.value)) {
|
||||||
this.setPointsDeSeuil(caracValue);
|
this.setPointsDeSeuil(to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (caracName == "chance") {
|
if (caracName == "chance") {
|
||||||
if (caracValue > Misc.toInt(this.system.compteurs.chance.value)) {
|
if (to > Misc.toInt(this.system.compteurs.chance.value)) {
|
||||||
this.setPointsDeChance(caracValue);
|
this.setPointsDeChance(to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await this.update({ [`system.carac.${caracName}.value`]: caracValue });
|
let selectedCarac = RdDActor._findCaracByName(this.system.carac, caracName);
|
||||||
|
const from = selectedCarac.value
|
||||||
|
await this.update({ [`system.carac.${caracName}.value`]: to });
|
||||||
|
await ExperienceLog.add(this, XP_TOPIC.CARAC, from, to, caracName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async updateCaracXP(caracName, caracXP) {
|
async updateCaracXP(caracName, to) {
|
||||||
if (caracName == 'Taille') {
|
if (caracName == 'Taille') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let selectedCarac = RdDActor._findCaracByName(this.system.carac, caracName);
|
||||||
|
if (!selectedCarac.derivee) {
|
||||||
|
const from = Number(selectedCarac.xp);
|
||||||
|
await this.update({ [`system.carac.${caracName}.xp`]: to });
|
||||||
|
await ExperienceLog.add(this, XP_TOPIC.XPCARAC, from, to, caracName);
|
||||||
|
}
|
||||||
this.checkCaracXP(caracName);
|
this.checkCaracXP(caracName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -857,16 +869,19 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
let carac = RdDActor._findCaracByName(this.system.carac, caracName);
|
let carac = RdDActor._findCaracByName(this.system.carac, caracName);
|
||||||
if (carac) {
|
if (carac) {
|
||||||
carac = duplicate(carac);
|
carac = duplicate(carac);
|
||||||
let xp = Number(carac.xp);
|
const fromXp = Number(carac.xp);
|
||||||
let value = Number(carac.value);
|
const fromValue = Number(carac.value);
|
||||||
while (xp >= RdDCarac.getCaracNextXp(value) && xp > 0) {
|
let toXp = fromXp;
|
||||||
xp -= RdDCarac.getCaracNextXp(value);
|
let toValue = fromValue;
|
||||||
value++;
|
while (toXp >= RdDCarac.getCaracNextXp(toValue) && toXp > 0) {
|
||||||
|
toXp -= RdDCarac.getCaracNextXp(toValue);
|
||||||
|
toValue++;
|
||||||
}
|
}
|
||||||
carac.xp = xp;
|
carac.xp = toXp;
|
||||||
carac.value = value;
|
carac.value = toValue;
|
||||||
await this.update({ [`system.carac.${caracName}`]: carac });
|
await this.update({ [`system.carac.${caracName}`]: carac });
|
||||||
this.updateExperienceLog("Carac +", xp, caracName + " passée à " + value);
|
await ExperienceLog.add(this, XP_TOPIC.XPCARAC, fromXp, toXp, caracName);
|
||||||
|
await ExperienceLog.add(this, XP_TOPIC.CARAC, fromValue, toValue, caracName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -874,17 +889,20 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
async updateCompetenceXPAuto(idOrName) {
|
async updateCompetenceXPAuto(idOrName) {
|
||||||
let competence = this.getCompetence(idOrName);
|
let competence = this.getCompetence(idOrName);
|
||||||
if (competence) {
|
if (competence) {
|
||||||
let xp = Number(competence.system.xp);
|
const fromXp = Number(competence.system.xp);
|
||||||
let niveau = Number(competence.system.niveau);
|
const fromNiveau = Number(competence.system.niveau);
|
||||||
while (xp >= RdDItemCompetence.getCompetenceNextXp(niveau) && xp > 0) {
|
let toXp = fromXp;
|
||||||
xp -= RdDItemCompetence.getCompetenceNextXp(niveau);
|
let toNiveau = fromNiveau;
|
||||||
niveau++;
|
while (toXp >= RdDItemCompetence.getCompetenceNextXp(toNiveau) && toXp > 0) {
|
||||||
|
toXp -= RdDItemCompetence.getCompetenceNextXp(toNiveau);
|
||||||
|
toNiveau++;
|
||||||
}
|
}
|
||||||
await competence.update({
|
await competence.update({
|
||||||
"system.xp": xp,
|
"system.xp": toXp,
|
||||||
"system.niveau": niveau,
|
"system.niveau": toNiveau,
|
||||||
});
|
});
|
||||||
this.updateExperienceLog("Compétence +", xp, competence.name + " passée à " + niveau);
|
await ExperienceLog.add(this, XP_TOPIC.XP, fromXp, toXp, competence.name);
|
||||||
|
await ExperienceLog.add(this, XP_TOPIC.NIVEAU, fromNiveau, toNiveau, competence.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -893,29 +911,33 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
if (!competence) {
|
if (!competence) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const stress = this.system.compteurs.experience.value;
|
const fromXp = competence.system.xp;
|
||||||
const niveau = Number(competence.system.niveau);
|
const fromXpStress = this.system.compteurs.experience.value;
|
||||||
const xpSuivant = RdDItemCompetence.getCompetenceNextXp(niveau);
|
const fromNiveau = Number(competence.system.niveau);
|
||||||
const xpRequis = xpSuivant - competence.system.xp;
|
const xpSuivant = RdDItemCompetence.getCompetenceNextXp(fromNiveau);
|
||||||
if (stress <= 0 || niveau >= competence.system.niveau_archetype) {
|
const xpRequis = xpSuivant - fromXp;
|
||||||
|
if (fromXpStress <= 0 || fromNiveau >= competence.system.niveau_archetype) {
|
||||||
ui.notifications.info(`La compétence ne peut pas augmenter!
|
ui.notifications.info(`La compétence ne peut pas augmenter!
|
||||||
stress disponible: ${stress}
|
stress disponible: ${fromXpStress}
|
||||||
expérience requise: ${xpRequis}
|
expérience requise: ${xpRequis}
|
||||||
niveau : ${niveau}
|
niveau : ${fromNiveau}
|
||||||
archétype : ${competence.system.niveau_archetype}`);
|
archétype : ${competence.system.niveau_archetype}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const xpUtilise = Math.max(0, Math.min(stress, xpRequis));
|
const xpUtilise = Math.max(0, Math.min(fromXpStress, xpRequis));
|
||||||
const gainNiveau = (xpUtilise >= xpRequis || xpRequis <= 0) ? 1 : 0;
|
const gainNiveau = (xpUtilise >= xpRequis || xpRequis <= 0) ? 1 : 0;
|
||||||
const nouveauNiveau = niveau + gainNiveau;
|
const toNiveau = fromNiveau + gainNiveau;
|
||||||
const nouveauXp = gainNiveau > 0 ? Math.max(competence.system.xp - xpSuivant, 0) : (competence.system.xp + xpUtilise);
|
const newXp = gainNiveau > 0 ? Math.max(fromXp - xpSuivant, 0) : (fromXp + xpUtilise);
|
||||||
await competence.update({
|
await competence.update({
|
||||||
"system.xp": nouveauXp,
|
"system.xp": newXp,
|
||||||
"system.niveau": nouveauNiveau,
|
"system.niveau": toNiveau,
|
||||||
});
|
});
|
||||||
const stressTransformeRestant = Math.max(0, stress - xpUtilise);
|
const toXpStress = Math.max(0, fromXpStress - xpUtilise);
|
||||||
await this.update({ "system.compteurs.experience.value": stressTransformeRestant });
|
await this.update({ "system.compteurs.experience.value": toXpStress });
|
||||||
this.updateExperienceLog('Dépense stress', xpUtilise, `Stress en ${competence.name} ${gainNiveau ? "pour passer à " + nouveauNiveau : ""}`);
|
|
||||||
|
await ExperienceLog.add(this, XP_TOPIC.TRANSFORM, fromXpStress, toXpStress, `Dépense stress`);
|
||||||
|
await ExperienceLog.add(this, XP_TOPIC.XP, fromXp, newXp, competence.name);
|
||||||
|
await ExperienceLog.add(this, XP_TOPIC.NIVEAU, fromNiveau, toNiveau, competence.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -939,51 +961,59 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async updateCompetence(idOrName, compValue) {
|
async updateCompetence(idOrName, compValue) {
|
||||||
|
const competence = this.getCompetence(idOrName);
|
||||||
|
if (competence) {
|
||||||
|
const toNiveau = compValue ?? RdDItemCompetence.getNiveauBase(competence.system.categorie, competence.getCategories());
|
||||||
|
this.notifyCompetencesTronc(competence, toNiveau);
|
||||||
|
const fromNiveau = competence.system.niveau;
|
||||||
|
await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, 'system.niveau': toNiveau }]);
|
||||||
|
await ExperienceLog.add(this, XP_TOPIC.NIVEAU, fromNiveau, toNiveau, competence.name, true);
|
||||||
|
} else {
|
||||||
|
console.log("Competence not found", idOrName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyCompetencesTronc(competence, toNiveau) {
|
||||||
|
const listTronc = RdDItemCompetence.getListTronc(competence.name).filter(it => {
|
||||||
|
const autreComp = this.getCompetence(it);
|
||||||
|
const niveauTr = autreComp?.system.niveau ?? 0;
|
||||||
|
return niveauTr < 0 && niveauTr < toNiveau;
|
||||||
|
});
|
||||||
|
if (listTronc.length > 0) {
|
||||||
|
ui.notifications.info(
|
||||||
|
"Vous avez modifié une compétence 'tronc'. Vérifiez que les compétences suivantes évoluent ensemble jusqu'au niveau 0 : <br>"
|
||||||
|
+ Misc.join(listTronc, '<br>'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async updateCompetenceXP(idOrName, toXp) {
|
||||||
let competence = this.getCompetence(idOrName);
|
let competence = this.getCompetence(idOrName);
|
||||||
if (competence) {
|
if (competence) {
|
||||||
let nouveauNiveau = compValue ?? RdDItemCompetence.getNiveauBase(competence.system.categorie);
|
if (isNaN(toXp) || typeof (toXp) != 'number') toXp = 0;
|
||||||
const tronc = RdDItemCompetence.getListTronc(competence.name).filter(it => {
|
const fromXp = competence.system.xp;
|
||||||
const comp = this.getCompetence(it);
|
this.checkCompetenceXP(idOrName, toXp);
|
||||||
const niveauTr = competence ? competence.system.niveau : 0;
|
await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, 'system.xp': toXp }]);
|
||||||
return niveauTr < 0 && niveauTr < nouveauNiveau;
|
await ExperienceLog.add(this, XP_TOPIC.XP, fromXp, toXp, competence.name, true);
|
||||||
});
|
if (toXp > fromXp) {
|
||||||
if (tronc.length > 0) {
|
RdDUtility.checkThanatosXP(idOrName);
|
||||||
let message = "Vous avez modifié une compétence 'tronc'. Vérifiez que les compétences suivantes évoluent ensemble jusqu'au niveau 0 : ";
|
|
||||||
for (let troncName of tronc) {
|
|
||||||
message += "<br>" + troncName;
|
|
||||||
}
|
|
||||||
ui.notifications.info(message);
|
|
||||||
}
|
}
|
||||||
const update = { _id: competence.id, 'system.niveau': nouveauNiveau };
|
|
||||||
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
|
|
||||||
} else {
|
} else {
|
||||||
console.log("Competence not found", idOrName);
|
console.log("Competence not found", idOrName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async updateCompetenceXP(idOrName, newXp) {
|
async updateCompetenceXPSort(idOrName, toXpSort) {
|
||||||
let competence = this.getCompetence(idOrName);
|
let competence = this.getCompetence(idOrName);
|
||||||
if (competence) {
|
if (competence) {
|
||||||
if (isNaN(newXp) || typeof (newXp) != 'number') newXp = 0;
|
if (isNaN(toXpSort) || typeof (toXpSort) != 'number') toXpSort = 0;
|
||||||
this.checkCompetenceXP(idOrName, newXp);
|
const fromXpSort = competence.system.xp_sort;
|
||||||
const update = { _id: competence.id, 'system.xp': newXp };
|
await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, 'system.xp_sort': toXpSort }]);
|
||||||
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
|
await ExperienceLog.add(this, XP_TOPIC.XPSORT, fromXpSort, toXpSort, competence.name, true);
|
||||||
this.updateExperienceLog("XP", newXp, "XP modifié en " + competence.name);
|
if (toXpSort > fromXpSort) {
|
||||||
} else {
|
RdDUtility.checkThanatosXP(idOrName);
|
||||||
console.log("Competence not found", idOrName);
|
}
|
||||||
}
|
|
||||||
RdDUtility.checkThanatosXP(idOrName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async updateCompetenceXPSort(idOrName, compValue) {
|
|
||||||
let competence = this.getCompetence(idOrName);
|
|
||||||
if (competence) {
|
|
||||||
if (isNaN(compValue) || typeof (compValue) != 'number') compValue = 0;
|
|
||||||
const update = { _id: competence.id, 'system.xp_sort': compValue };
|
|
||||||
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
|
|
||||||
this.updateExperienceLog("XP Sort", compValue, "XP modifié en sort de " + competence.name);
|
|
||||||
} else {
|
} else {
|
||||||
console.log("Competence not found", idOrName);
|
console.log("Competence not found", idOrName);
|
||||||
}
|
}
|
||||||
@ -993,26 +1023,12 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
async updateCompetenceArchetype(idOrName, compValue) {
|
async updateCompetenceArchetype(idOrName, compValue) {
|
||||||
let competence = this.getCompetence(idOrName);
|
let competence = this.getCompetence(idOrName);
|
||||||
if (competence) {
|
if (competence) {
|
||||||
compValue = compValue ?? 0;
|
await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, 'system.niveau_archetype': Math.max(compValue ?? 0, 0) }]);
|
||||||
const update = { _id: competence.id, 'system.niveau_archetype': compValue };
|
|
||||||
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
|
|
||||||
} else {
|
} else {
|
||||||
console.log("Competence not found", idOrName);
|
console.log("Competence not found", idOrName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async updateExperienceLog(modeXP, valeurXP, raisonXP = 'Inconnue') {
|
|
||||||
let d = new Date();
|
|
||||||
let expLog = duplicate(this.system.experiencelog);
|
|
||||||
expLog.push({
|
|
||||||
mode: Misc.upperFirst(modeXP), valeur: valeurXP, raison: Misc.upperFirst(raisonXP),
|
|
||||||
daterdd: game.system.rdd.calendrier.dateCourante(),
|
|
||||||
datereel: `${d.getDate()}/${d.getMonth() + 1}/${d.getFullYear()}`
|
|
||||||
});
|
|
||||||
await this.update({ [`system.experiencelog`]: expLog });
|
|
||||||
}
|
|
||||||
|
|
||||||
async deleteExperienceLog(from, count) {
|
async deleteExperienceLog(from, count) {
|
||||||
if (from >= 0 && count > 0) {
|
if (from >= 0 && count > 0) {
|
||||||
let expLog = duplicate(this.system.experiencelog);
|
let expLog = duplicate(this.system.experiencelog);
|
||||||
@ -1021,24 +1037,27 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async updateCompteurValue(fieldName, fieldValue, raison = 'Inconnue') {
|
async updateCompteurValue(fieldName, to) {
|
||||||
await this.update({ [`system.compteurs.${fieldName}.value`]: fieldValue });
|
const from = this.system.compteurs[fieldName].value
|
||||||
await this.addStressExperienceLog(fieldName, fieldValue, 'forcé: ' + raison);
|
await this.update({ [`system.compteurs.${fieldName}.value`]: to });
|
||||||
|
await this.addStressExperienceLog(fieldName, from, to, fieldName, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async addCompteurValue(fieldName, fieldValue, raison = 'Inconnue') {
|
async addCompteurValue(fieldName, add, raison) {
|
||||||
let oldValue = this.system.compteurs[fieldName].value;
|
let from = this.system.compteurs[fieldName].value;
|
||||||
await this.update({ [`system.compteurs.${fieldName}.value`]: Number(oldValue) + Number(fieldValue) });
|
const to = Number(from) + Number(add);
|
||||||
await this.addStressExperienceLog(fieldName, fieldValue, raison);
|
await this.update({ [`system.compteurs.${fieldName}.value`]: to });
|
||||||
|
await this.addStressExperienceLog(fieldName, from, to, raison);
|
||||||
}
|
}
|
||||||
|
|
||||||
async addStressExperienceLog(fieldName, fieldValue, raison) {
|
async addStressExperienceLog(topic, from, to, raison, manuel) {
|
||||||
switch (fieldName) {
|
switch (topic) {
|
||||||
case 'stress': case 'experience':
|
case 'stress':
|
||||||
await this.updateExperienceLog(fieldName, fieldValue, raison);
|
return await ExperienceLog.add(this, XP_TOPIC.STRESS, from, to, raison, manuel)
|
||||||
|
case 'experience':
|
||||||
|
return await ExperienceLog.add(this, XP_TOPIC.TRANSFORM, from, to, raison, manuel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1105,7 +1124,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async computeMalusArmure() {
|
async computeMalusArmure() {
|
||||||
if (this.isPersonnage()) {
|
if (this.isPersonnage()) {
|
||||||
const malusArmure = this.filterItems(it => it.type == 'armure' && it.system.equipe)
|
const malusArmure = this.filterItems(it => it.system.equipe, 'armure')
|
||||||
.map(it => it.system.malus ?? 0)
|
.map(it => it.system.malus ?? 0)
|
||||||
.reduce(Misc.sum(), 0);
|
.reduce(Misc.sum(), 0);
|
||||||
// Mise à jour éventuelle du malus armure
|
// Mise à jour éventuelle du malus armure
|
||||||
@ -1278,8 +1297,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
buildTMRInnaccessible() {
|
buildTMRInnaccessible() {
|
||||||
const tmrInnaccessibles = this.filterItems(it => Draconique.isCaseTMR(it) &&
|
const tmrInnaccessibles = this.filterItems(it => Draconique.isCaseTMR(it) && EffetsDraconiques.isInnaccessible(it));
|
||||||
EffetsDraconiques.isInnaccessible(it));
|
|
||||||
return tmrInnaccessibles.map(it => it.system.coord);
|
return tmrInnaccessibles.map(it => it.system.coord);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1343,21 +1361,46 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async finDeRound(options = { terminer: false }) {
|
async finDeRound(options = { terminer: false }) {
|
||||||
|
await this.$finDeRoundSuppressionEffetsTermines(options);
|
||||||
|
await this.$finDeRoundBlessuresGraves();
|
||||||
|
await this.$finDeRoundSupprimerObsoletes();
|
||||||
|
await this.$finDeRoundEmpoignade();
|
||||||
|
}
|
||||||
|
|
||||||
|
async $finDeRoundSuppressionEffetsTermines(options) {
|
||||||
for (let effect of this.getEffects()) {
|
for (let effect of this.getEffects()) {
|
||||||
if (effect.duration.type !== 'none' && (effect.duration.remaining <= 0 || options.terminer)) {
|
if (effect.duration.type !== 'none' && (effect.duration.remaining <= 0 || options.terminer)) {
|
||||||
await effect.delete();
|
await effect.delete();
|
||||||
ChatMessage.create({ content: `${this.name} n'est plus ${Misc.lowerFirst(game.i18n.localize(effect.system.label))} !` });
|
ChatMessage.create({ content: `${this.name} n'est plus ${Misc.lowerFirst(game.i18n.localize(effect.system.label))} !` });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async $finDeRoundBlessuresGraves() {
|
||||||
if (this.isPersonnage() || this.isCreature()) {
|
if (this.isPersonnage() || this.isCreature()) {
|
||||||
const nbGraves = this.filterItems(it => it.isGrave(), 'blessure').length
|
const nbGraves = this.filterItems(it => it.isGrave(), 'blessure').length;
|
||||||
if (nbGraves > 0) {
|
if (nbGraves > 0) {
|
||||||
// Gestion blessure graves : -1 pt endurance par blessure grave
|
// Gestion blessure graves : -1 pt endurance par blessure grave
|
||||||
await this.santeIncDec("endurance", - nbGraves);
|
await this.santeIncDec("endurance", -nbGraves);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async $finDeRoundSupprimerObsoletes() {
|
||||||
|
const obsoletes = []
|
||||||
|
.concat(this.itemTypes[TYPES.empoignade].filter(it => it.system.pointsemp <= 0))
|
||||||
|
.concat(this.itemTypes[TYPES.possession].filter(it => it.system.compteur < -2 || it.system.compteur > 2))
|
||||||
|
.map(it => it.id);
|
||||||
|
await this.deleteEmbeddedDocuments('Item', obsoletes);
|
||||||
|
}
|
||||||
|
|
||||||
|
async $finDeRoundEmpoignade(){
|
||||||
|
const immobilisations = this.itemTypes[TYPES.empoignade].filter(it => it.system.pointsemp >= 2 && it.system.empoigneurid == this.id);
|
||||||
|
immobilisations.forEach(emp => RdDEmpoignade.onImmobilisation(this,
|
||||||
|
game.actors.get(emp.system.empoigneid),
|
||||||
|
emp
|
||||||
|
))
|
||||||
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async setSonne(sonne = true) {
|
async setSonne(sonne = true) {
|
||||||
if (this.isEntite()) {
|
if (this.isEntite()) {
|
||||||
@ -1843,14 +1886,14 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async transformerStress() {
|
async transformerStress() {
|
||||||
const stress = Number(this.system.compteurs.stress.value);
|
const fromStress = Number(this.system.compteurs.stress.value);
|
||||||
if (this.system.sommeil?.insomnie || stress <= 0) {
|
if (this.system.sommeil?.insomnie || fromStress <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const stressRoll = await this._stressRoll(this.getReveActuel());
|
const stressRoll = await this._stressRoll(this.getReveActuel());
|
||||||
|
|
||||||
const conversion = Math.floor(stress * stressRoll.factor / 100);
|
const conversion = Math.floor(fromStress * stressRoll.factor / 100);
|
||||||
let dissolution = Math.max(0, Number(this.system.compteurs.dissolution.value));
|
let dissolution = Math.max(0, Number(this.system.compteurs.dissolution.value));
|
||||||
let exaltation = Math.max(0, Number(this.system.compteurs.exaltation.value));
|
let exaltation = Math.max(0, Number(this.system.compteurs.exaltation.value));
|
||||||
const annule = Math.min(dissolution, exaltation);
|
const annule = Math.min(dissolution, exaltation);
|
||||||
@ -1862,8 +1905,8 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
alias: this.name,
|
alias: this.name,
|
||||||
selectedCarac: this.system.carac.reve,
|
selectedCarac: this.system.carac.reve,
|
||||||
rolled: stressRoll,
|
rolled: stressRoll,
|
||||||
stress: stress,
|
stress: fromStress,
|
||||||
perte: Math.min(conversion, stress),
|
perte: Math.min(conversion, fromStress),
|
||||||
convertis: conversion - perteDissolution,
|
convertis: conversion - perteDissolution,
|
||||||
xp: conversion - perteDissolution + exaltation,
|
xp: conversion - perteDissolution + exaltation,
|
||||||
dissolution: dissolution,
|
dissolution: dissolution,
|
||||||
@ -1875,15 +1918,18 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-transformer-stress.html`, stressRollData)
|
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-transformer-stress.html`, stressRollData)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const toStress = Math.max(fromStress - stressRollData.perte - 1, 0);
|
||||||
|
const fromXpSress = Number(this.system.compteurs.experience.value);
|
||||||
|
const toXpStress = fromXpSress + Number(stressRollData.xp);
|
||||||
const updates = {
|
const updates = {
|
||||||
"system.compteurs.stress.value": Math.max(stress - stressRollData.perte - 1, 0),
|
"system.compteurs.stress.value": toStress,
|
||||||
"system.compteurs.experience.value": Number(this.system.compteurs.experience.value) + Number(stressRollData.xp),
|
"system.compteurs.experience.value": toXpStress,
|
||||||
"system.compteurs.dissolution.value": dissolution - perteDissolution,
|
"system.compteurs.dissolution.value": dissolution - perteDissolution,
|
||||||
"system.compteurs.exaltation.value": 0
|
"system.compteurs.exaltation.value": 0
|
||||||
}
|
}
|
||||||
await this.update(updates);
|
await this.update(updates);
|
||||||
|
await ExperienceLog.add(this, XP_TOPIC.STRESS, fromStress, toStress, 'Transformation')
|
||||||
this.updateExperienceLog('XP', stressRollData.xp, "Transformation du stress");
|
await ExperienceLog.add(this, XP_TOPIC.TRANSFORM, fromXpSress, toXpStress, 'Transformation')
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -2279,14 +2325,14 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
carac: this.system.carac,
|
carac: this.system.carac,
|
||||||
competence: this.getCompetence(idOrName)
|
competence: this.getCompetence(idOrName)
|
||||||
}
|
}
|
||||||
if (rollData.competence.type == 'competencecreature') {
|
if (rollData.competence.type == TYPES.competencecreature) {
|
||||||
if (rollData.competence.system.iscombat && options.tryTarget && Targets.hasTargets()) {
|
const arme = RdDItemCompetenceCreature.armeCreature(rollData.competence)
|
||||||
|
if (arme && options.tryTarget && Targets.hasTargets()) {
|
||||||
Targets.selectOneToken(target => {
|
Targets.selectOneToken(target => {
|
||||||
if (rollData.competence.system.ispossession) {
|
if (arme.action == "possession") {
|
||||||
RdDPossession.onAttaquePossession(target, this, rollData.competence)
|
RdDPossession.onAttaquePossession(target, this, rollData.competence)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const arme = RdDItemCompetenceCreature.armeNaturelle(rollData.competence)
|
|
||||||
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme)
|
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -2316,8 +2362,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async creerTacheDepuisLivre(item, options = { renderSheet: true }) {
|
async creerTacheDepuisLivre(item, options = { renderSheet: true }) {
|
||||||
const nomTache = "Lire " + item.name;
|
const nomTache = "Lire " + item.name;
|
||||||
const filterTacheLecture = it => it.type == 'tache' && it.name == nomTache;
|
let tachesExistantes = findTache(nomTache);
|
||||||
let tachesExistantes = this.filterItems(filterTacheLecture);
|
|
||||||
if (tachesExistantes.length == 0) {
|
if (tachesExistantes.length == 0) {
|
||||||
const tache = {
|
const tache = {
|
||||||
name: nomTache, type: 'tache',
|
name: nomTache, type: 'tache',
|
||||||
@ -2333,13 +2378,17 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
await this.createEmbeddedDocuments('Item', [tache], options);
|
await this.createEmbeddedDocuments('Item', [tache], options);
|
||||||
tachesExistantes = this.filterItems(filterTacheLecture);
|
tachesExistantes = findTache(nomTache)
|
||||||
}
|
}
|
||||||
return tachesExistantes.length > 0 ? tachesExistantes[0] : undefined;
|
return tachesExistantes.length > 0 ? tachesExistantes[0] : undefined;
|
||||||
|
|
||||||
|
function findTache(name) {
|
||||||
|
return this.filterItems(it => it.name == name, 'tache');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blessuresASoigner() {
|
blessuresASoigner() {
|
||||||
// TODO or not TODO: filtrer les blessures poour lesquels on ne peut plus faire de premiers soins?
|
// TODO or not TODO: filtrer les blessures pour lesquelles on ne peut plus faire de premiers soins?
|
||||||
return this.filterItems(it => it.system.gravite > 0 && it.system.gravite <= 6 && !(it.system.premierssoins.done && it.system.soinscomplets.done), 'blessure')
|
return this.filterItems(it => it.system.gravite > 0 && it.system.gravite <= 6 && !(it.system.premierssoins.done && it.system.soinscomplets.done), 'blessure')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2709,8 +2758,10 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
rollData.xpSort = RdDItemSigneDraconique.getXpSortSigneDraconique(rollData.rolled.code, rollData.signe);
|
rollData.xpSort = RdDItemSigneDraconique.getXpSortSigneDraconique(rollData.rolled.code, rollData.signe);
|
||||||
if (rollData.xpSort > 0) {
|
if (rollData.xpSort > 0) {
|
||||||
await this.updateEmbeddedDocuments("Item", [{ _id: compData._id, 'system.xp_sort': Misc.toInt(compData.system.xp_sort) + rollData.xpSort }]);
|
const fromXp = Number(compData.system.xp_sort);
|
||||||
await this.updateExperienceLog("XP Sort", rollData.xpSort, "Signe draconique en " + rollData.competence.name);
|
const toXp = fromXp + rollData.xpSort;
|
||||||
|
await this.updateEmbeddedDocuments("Item", [{ _id: compData._id, 'system.xp_sort': toXp }]);
|
||||||
|
await ExperienceLog.add(this, XP_TOPIC.XPSORT, fromXp, toXp, `${rollData.competence.name} : signe draconique`);
|
||||||
}
|
}
|
||||||
await this.deleteEmbeddedDocuments("Item", [rollData.signe._id]);
|
await this.deleteEmbeddedDocuments("Item", [rollData.signe._id]);
|
||||||
await RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-lecture-signedraconique.html');
|
await RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-lecture-signedraconique.html');
|
||||||
@ -2824,11 +2875,12 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async _xpCompetence(xpData) {
|
async _xpCompetence(xpData) {
|
||||||
if (xpData.competence) {
|
if (xpData.competence) {
|
||||||
const newXp = Misc.toInt(xpData.competence.system.xp) + xpData.xpCompetence;
|
const from = Number(xpData.competence.system.xp);
|
||||||
let update = { _id: xpData.competence._id, 'system.xp': newXp };
|
const to = from + xpData.xpCompetence;
|
||||||
|
let update = { _id: xpData.competence._id, 'system.xp': to };
|
||||||
await this.updateEmbeddedDocuments('Item', [update]);
|
await this.updateEmbeddedDocuments('Item', [update]);
|
||||||
xpData.checkComp = await this.checkCompetenceXP(xpData.competence.name, undefined, false);
|
xpData.checkComp = await this.checkCompetenceXP(xpData.competence.name, undefined, false);
|
||||||
this.updateExperienceLog("XP", xpData.xpCompetence, "XP gagné en " + xpData.competence.name);
|
await ExperienceLog.add(this, XP_TOPIC.XP, from, to, xpData.competence.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2838,10 +2890,12 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
let carac = duplicate(this.system.carac);
|
let carac = duplicate(this.system.carac);
|
||||||
let selectedCarac = RdDActor._findCaracByName(carac, xpData.caracName);
|
let selectedCarac = RdDActor._findCaracByName(carac, xpData.caracName);
|
||||||
if (!selectedCarac.derivee) {
|
if (!selectedCarac.derivee) {
|
||||||
selectedCarac.xp = Misc.toInt(selectedCarac.xp) + xpData.xpCarac;
|
const from = Number(selectedCarac.xp);
|
||||||
|
const to = from + xpData.xpCarac;
|
||||||
|
selectedCarac.xp = to;
|
||||||
await this.update({ "system.carac": carac });
|
await this.update({ "system.carac": carac });
|
||||||
xpData.checkCarac = await this.checkCaracXP(selectedCarac.label, false);
|
xpData.checkCarac = await this.checkCaracXP(selectedCarac.label, false);
|
||||||
this.updateExperienceLog("XP", xpData.xpCarac, "XP gagné en " + xpData.caracName);
|
await ExperienceLog.add(this, XP_TOPIC.XPCARAC, from, to, xpData.caracName);
|
||||||
} else {
|
} else {
|
||||||
xpData.caracRepartitionManuelle = true;
|
xpData.caracRepartitionManuelle = true;
|
||||||
}
|
}
|
||||||
@ -3028,7 +3082,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
|
|
||||||
const competence = this.getCompetence(arme.system.competence)
|
const competence = this.getCompetence(arme.system.competence)
|
||||||
if (competence.system.ispossession) {
|
if (competence.isCompetencePossession()) {
|
||||||
return RdDPossession.onAttaquePossession(target, this, competence);
|
return RdDPossession.onAttaquePossession(target, this, competence);
|
||||||
}
|
}
|
||||||
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme);
|
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme);
|
||||||
@ -3108,9 +3162,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
conjurerPossession(possession) {
|
conjurerPossession(possession) {
|
||||||
// TODO: choix de la compétence de draconic ou de possession
|
RdDPossession.onConjurerPossession(this, possession)
|
||||||
let draconic = this.getDraconicOuPossession();
|
|
||||||
RdDPossession.onConjurerPossession(this, draconic, possession)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -3179,25 +3231,31 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
if (attacker && !await attacker.accorder(this, 'avant-encaissement')) {
|
if (attacker && !await attacker.accorder(this, 'avant-encaissement')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const attackerId = attacker?.id;
|
||||||
if (ReglesOptionelles.isUsing('validation-encaissement-gr') && !game.user.isGM) {
|
if (ReglesOptionelles.isUsing('validation-encaissement-gr') && !game.user.isGM) {
|
||||||
RdDBaseActor.remoteActorCall({
|
RdDBaseActor.remoteActorCall({
|
||||||
actorId: this.id,
|
actorId: this.id,
|
||||||
method: 'validerEncaissement',
|
method: 'appliquerEncaissement',
|
||||||
args: [rollData, show]
|
args: [rollData, show, attackerId]
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
await this.appliquerEncaissement(rollData, show, attackerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async appliquerEncaissement(rollData, show, attackerId) {
|
||||||
const armure = await this.computeArmure(rollData);
|
const armure = await this.computeArmure(rollData);
|
||||||
if (ReglesOptionelles.isUsing('validation-encaissement-gr')) {
|
if (ReglesOptionelles.isUsing('validation-encaissement-gr')) {
|
||||||
DialogValidationEncaissement.validerEncaissement(this, rollData, armure, show, (encaissement, show) => this._appliquerEncaissement(encaissement, show, attacker));
|
DialogValidationEncaissement.validerEncaissement(this, rollData, armure, show, attackerId, (encaissement, show, attackerId) => this._appliquerEncaissement(encaissement, show, attackerId));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let encaissement = await RdDUtility.jetEncaissement(rollData, armure, { showDice: SHOW_DICE });
|
let encaissement = await RdDUtility.jetEncaissement(rollData, armure, { showDice: SHOW_DICE });
|
||||||
await this._appliquerEncaissement(encaissement, show, attacker)
|
await this._appliquerEncaissement(encaissement, show, attackerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _appliquerEncaissement(encaissement, show, attacker) {
|
async _appliquerEncaissement(encaissement, show, attackedId) {
|
||||||
|
const attacker = attackedId ? game.actors.get(attackedId) : undefined
|
||||||
let santeOrig = duplicate(this.system.sante);
|
let santeOrig = duplicate(this.system.sante);
|
||||||
|
|
||||||
const blessure = await this.ajouterBlessure(encaissement, attacker); // Will update the result table
|
const blessure = await this.ajouterBlessure(encaissement, attacker); // Will update the result table
|
||||||
|
@ -3,7 +3,8 @@ import { Misc } from "../misc.js";
|
|||||||
import { DialogSplitItem } from "../dialog-split-item.js";
|
import { DialogSplitItem } from "../dialog-split-item.js";
|
||||||
import { RdDSheetUtility } from "../rdd-sheet-utility.js";
|
import { RdDSheetUtility } from "../rdd-sheet-utility.js";
|
||||||
import { Monnaie } from "../item-monnaie.js";
|
import { Monnaie } from "../item-monnaie.js";
|
||||||
import { RdDItem } from "../item.js";
|
import { RdDItem, TYPES } from "../item.js";
|
||||||
|
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/**
|
/**
|
||||||
@ -50,16 +51,18 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
encTotal: await this.actor.computeEncTotal(),
|
encTotal: await this.actor.computeEncTotal(),
|
||||||
}
|
}
|
||||||
|
|
||||||
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
|
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires);
|
||||||
this._appliquerRechercheObjets(formData.objets, formData.conteneurs);
|
this._appliquerRechercheObjets(formData.conteneurs, formData.inventaires);
|
||||||
formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs);
|
formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs);
|
||||||
|
formData.competences.filter(it => it.type == TYPES.competencecreature)
|
||||||
|
.forEach(it => it.isdommages = RdDItemCompetenceCreature.isDommages(it))
|
||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
|
|
||||||
_appliquerRechercheObjets(objets, conteneurs) {
|
_appliquerRechercheObjets(conteneurs, inventaires) {
|
||||||
if (this.options.recherche?.text) {
|
if (this.options.recherche?.text) {
|
||||||
const recherche = this.options.recherche;
|
const recherche = this.options.recherche;
|
||||||
const allVisible = objets.filter(it => it.isNomTypeLike(recherche.text)).map(it => it.id);
|
const allVisible = inventaires.filter(it => it.isNomTypeLike(recherche.text)).map(it => it.id);
|
||||||
let addVisible = conteneurs.filter(it => it.isNomTypeLike(recherche.text)).map(it => it.id)
|
let addVisible = conteneurs.filter(it => it.isNomTypeLike(recherche.text)).map(it => it.id)
|
||||||
do {
|
do {
|
||||||
allVisible.push(...addVisible)
|
allVisible.push(...addVisible)
|
||||||
@ -67,11 +70,11 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
addVisible = parentsIds.filter(id => !allVisible.includes(id))
|
addVisible = parentsIds.filter(id => !allVisible.includes(id))
|
||||||
}
|
}
|
||||||
while (addVisible.length > 0)
|
while (addVisible.length > 0)
|
||||||
objets.forEach(it => it.system.isHidden = !allVisible.includes(it.id))
|
inventaires.forEach(it => it.system.isHidden = !allVisible.includes(it.id))
|
||||||
conteneurs.forEach(it => it.system.isHidden = !allVisible.includes(it.id))
|
conteneurs.forEach(it => it.system.isHidden = !allVisible.includes(it.id))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
objets.forEach(it => it.system.isHidden = false)
|
inventaires.forEach(it => it.system.isHidden = false)
|
||||||
conteneurs.forEach(it => it.system.isHidden = false)
|
conteneurs.forEach(it => it.system.isHidden = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,33 +121,34 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
formData.herbes = Misc.arrayOrEmpty(itemTypes['herbe']);
|
formData.herbes = Misc.arrayOrEmpty(itemTypes['herbe']);
|
||||||
formData.nourritureboissons = Misc.arrayOrEmpty(itemTypes['nourritureboisson']);
|
formData.nourritureboissons = Misc.arrayOrEmpty(itemTypes['nourritureboisson']);
|
||||||
formData.gemmes = Misc.arrayOrEmpty(itemTypes['gemme']);
|
formData.gemmes = Misc.arrayOrEmpty(itemTypes['gemme']);
|
||||||
formData.monnaie = Misc.arrayOrEmpty(itemTypes['monnaie']).sort(Monnaie.triValeurEntiere());
|
formData.monnaies = Misc.arrayOrEmpty(itemTypes['monnaie']).sort(Monnaie.triValeurEntiere());
|
||||||
|
formData.objets = Misc.arrayOrEmpty(itemTypes['objet'])
|
||||||
|
|
||||||
formData.objets = RdDItem.getItemTypesInventaire('all')
|
formData.inventaires = RdDItem.getItemTypesInventaire('all')
|
||||||
.map(t => Misc.arrayOrEmpty(itemTypes[t]))
|
.map(t => Misc.arrayOrEmpty(itemTypes[t]))
|
||||||
.reduce((a, b) => a.concat(b), [])
|
.reduce((a, b) => a.concat(b), [])
|
||||||
.sort(Misc.ascending(it => it.name));
|
.sort(Misc.ascending(it => it.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */ /** @override */
|
/* -------------------------------------------- */ /** @override */
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
this.html = html;
|
this.html = html;
|
||||||
|
|
||||||
this.html.find('.conteneur-name a').click(async event => {
|
this.html.find('.conteneur-name a').click(async event => {
|
||||||
RdDUtility.toggleAfficheContenu(this.getItemId(event));
|
RdDUtility.toggleAfficheContenu(this.getItemId(event));
|
||||||
this.render(true);
|
this.render(true);
|
||||||
});
|
});
|
||||||
this.html.find('.item-edit').click(async event => this.getItem(event)?.sheet.render(true))
|
this.html.find('.item-edit').click(async event => this.getItem(event)?.sheet.render(true))
|
||||||
this.html.find('.item-montrer').click(async event => this.getItem(event)?.postItemToChat());
|
this.html.find('.item-montrer').click(async event => this.getItem(event)?.postItemToChat());
|
||||||
this.html.find('.actor-montrer').click(async event => this.actor.postActorToChat());
|
this.html.find('.actor-montrer').click(async event => this.actor.postActorToChat());
|
||||||
this.html.find('.recherche')
|
this.html.find('.recherche')
|
||||||
.each((index, field) => {
|
.each((index, field) => {
|
||||||
this._rechercheSelectArea(field);
|
this._rechercheSelectArea(field);
|
||||||
})
|
})
|
||||||
.keyup(async event => this._rechercherKeyup(event))
|
.keyup(async event => this._rechercherKeyup(event))
|
||||||
.change(async event => this._rechercherKeyup(event));
|
.change(async event => this._rechercherKeyup(event));
|
||||||
this.html.find('.recherche').prop( "disabled", false );
|
this.html.find('.recherche').prop("disabled", false);
|
||||||
// Everything below here is only needed if the sheet is editable
|
// Everything below here is only needed if the sheet is editable
|
||||||
if (!this.options.editable) return;
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
@ -230,9 +234,9 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async selectObjetTypeToCreate() {
|
async selectObjetTypeToCreate() {
|
||||||
let typeObjets = this.getTypesInventaire().sort(Misc.ascending(type => Misc.typeName('Item', type)));
|
let types = this.getTypesInventaire().sort(Misc.ascending(type => Misc.typeName('Item', type)));
|
||||||
let content = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`;
|
let content = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`;
|
||||||
for (let typeName of typeObjets) {
|
for (let typeName of types) {
|
||||||
content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>`
|
content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>`
|
||||||
}
|
}
|
||||||
content += '</select>';
|
content += '</select>';
|
||||||
|
@ -3,6 +3,7 @@ import { SYSTEM_SOCKET_ID } from "../constants.js";
|
|||||||
import { Monnaie } from "../item-monnaie.js";
|
import { Monnaie } from "../item-monnaie.js";
|
||||||
import { Misc } from "../misc.js";
|
import { Misc } from "../misc.js";
|
||||||
import { RdDAudio } from "../rdd-audio.js";
|
import { RdDAudio } from "../rdd-audio.js";
|
||||||
|
import { RdDConfirm } from "../rdd-confirm.js";
|
||||||
import { RdDUtility } from "../rdd-utility.js";
|
import { RdDUtility } from "../rdd-utility.js";
|
||||||
import { SystemCompendiums } from "../settings/system-compendiums.js";
|
import { SystemCompendiums } from "../settings/system-compendiums.js";
|
||||||
import { APP_ASTROLOGIE_REFRESH } from "../sommeil/app-astrologie.js";
|
import { APP_ASTROLOGIE_REFRESH } from "../sommeil/app-astrologie.js";
|
||||||
@ -118,7 +119,7 @@ export class RdDBaseActor extends Actor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
listItems(type = undefined) { return (type ? this.itemTypes[type] : this.items); }
|
listItems(type = undefined) { return (type ? this.itemTypes[type] : this.items); }
|
||||||
filterItems(filter, type = undefined) { return type ? this.itemTypes[type]?.filter(filter) ?? [] : []; }
|
filterItems(filter, type = undefined) { return (type ? this.itemTypes[type] : this.items)?.filter(filter); }
|
||||||
findItemLike(idOrName, type) {
|
findItemLike(idOrName, type) {
|
||||||
return this.getItem(idOrName, type)
|
return this.getItem(idOrName, type)
|
||||||
?? Misc.findFirstLike(idOrName, this.listItems(type), { description: Misc.typeName('Item', type) });
|
?? Misc.findFirstLike(idOrName, this.listItems(type), { description: Misc.typeName('Item', type) });
|
||||||
@ -143,6 +144,18 @@ export class RdDBaseActor extends Actor {
|
|||||||
.forEach(async it => await it.onFinPeriodeTemporel(oldTimestamp, newTimestamp))
|
.forEach(async it => await it.onFinPeriodeTemporel(oldTimestamp, newTimestamp))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async creerObjetParMJ(object){
|
||||||
|
if (!Misc.isUniqueConnectedGM()) {
|
||||||
|
RdDBaseActor.remoteActorCall({
|
||||||
|
actorId: this.id,
|
||||||
|
method: 'creerObjetParMJ',
|
||||||
|
args: [object]
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await this.createEmbeddedDocuments('Item', [object])
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getFortune() {
|
getFortune() {
|
||||||
return Monnaie.getFortune(this.itemTypes['monnaie']);
|
return Monnaie.getFortune(this.itemTypes['monnaie']);
|
||||||
@ -247,13 +260,12 @@ export class RdDBaseActor extends Actor {
|
|||||||
const vendeur = achat.vendeurId ? game.actors.get(achat.vendeurId) : undefined;
|
const vendeur = achat.vendeurId ? game.actors.get(achat.vendeurId) : undefined;
|
||||||
const acheteur = achat.acheteurId ? game.actors.get(achat.acheteurId) : undefined;
|
const acheteur = achat.acheteurId ? game.actors.get(achat.acheteurId) : undefined;
|
||||||
const quantite = (achat.choix.nombreLots ?? 1) * (achat.vente.tailleLot);
|
const quantite = (achat.choix.nombreLots ?? 1) * (achat.vente.tailleLot);
|
||||||
const itemVendu = vendeur?.getItem(achat.vente.item._id) ?? game.items.get(achat.vente.item._id) ?? achat.vente.item;
|
const itemVendu = vendeur?.getItem(achat.vente.item._id) ?? game.items.get(achat.vente.item._id);
|
||||||
if (!itemVendu) {
|
if (!itemVendu) {
|
||||||
ui.notifications.warn("Erreur sur achat: rien à acheter<br>Si possible, transmettez les logs de la console aux développeurs");
|
ChatUtility.notifyUser(achat.userId, 'warn', vendeur ? `Le vendeur n'a pas plus de ${achat.vente.item.name} !`: `Impossible de retrouver: ${achat.vente.item.name} !`);
|
||||||
console.log('Erreur sur achat: rien à acheter', achat);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this.verifierQuantite(vendeur, itemVendu, quantite)) {
|
if (vendeur && !this.verifierQuantite(itemVendu, quantite)) {
|
||||||
ChatUtility.notifyUser(achat.userId, 'warn', `Le vendeur n'a pas assez de ${itemVendu.name} !`);
|
ChatUtility.notifyUser(achat.userId, 'warn', `Le vendeur n'a pas assez de ${itemVendu.name} !`);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -264,7 +276,7 @@ export class RdDBaseActor extends Actor {
|
|||||||
await this.decrementerVente(vendeur, itemVendu, quantite, cout);
|
await this.decrementerVente(vendeur, itemVendu, quantite, cout);
|
||||||
if (acheteur) {
|
if (acheteur) {
|
||||||
await acheteur.depenserSols(cout);
|
await acheteur.depenserSols(cout);
|
||||||
const createdItemId = await acheteur.creerQuantiteItem(achat.vente.item, quantite);
|
const createdItemId = await acheteur.creerQuantiteItem(itemVendu, quantite);
|
||||||
await acheteur.consommerNourritureAchetee(achat, achat.vente, createdItemId);
|
await acheteur.consommerNourritureAchetee(achat, achat.vente, createdItemId);
|
||||||
}
|
}
|
||||||
if (cout > 0) {
|
if (cout > 0) {
|
||||||
@ -305,9 +317,9 @@ export class RdDBaseActor extends Actor {
|
|||||||
return this.getFortune() >= cout;
|
return this.getFortune() >= cout;
|
||||||
}
|
}
|
||||||
|
|
||||||
verifierQuantite(vendeur, item, quantiteTotal) {
|
verifierQuantite(item, quantiteDemande) {
|
||||||
const disponible = vendeur?.getQuantiteDisponible(item);
|
const disponible = item?.getQuantite();
|
||||||
return disponible == undefined || disponible >= quantiteTotal;
|
return disponible == undefined || disponible >= quantiteDemande;
|
||||||
}
|
}
|
||||||
|
|
||||||
async consommerNourritureAchetee(achat, vente, createdItemId) {
|
async consommerNourritureAchetee(achat, vente, createdItemId) {
|
||||||
|
@ -22,7 +22,7 @@ export class RdDCommerce extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getQuantiteDisponible(item) {
|
getQuantiteDisponible(item) {
|
||||||
return this.system.illimite || item.isService() ? undefined : item.getQuantite();
|
return (this.system.illimite || item?.isService()) ? undefined : item.getQuantite();
|
||||||
}
|
}
|
||||||
|
|
||||||
verifierFortune(cout) {
|
verifierFortune(cout) {
|
||||||
|
39
module/actor/experience-log.js
Normal file
39
module/actor/experience-log.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
export const XP_TOPIC = {
|
||||||
|
XP: { code: 'xp', label: 'xp' },
|
||||||
|
XPSORT: { code: 'xpsort', label: 'xp sort' },
|
||||||
|
NIVEAU: { code: 'niveau', label: 'Niveau' },
|
||||||
|
XPCARAC: { code: 'xpcarac', label: 'xp carac' },
|
||||||
|
CARAC: { code: 'carac', label: 'Carac' },
|
||||||
|
STRESS: { code: 'stress', label: 'Stress' },
|
||||||
|
TRANSFORM: { code: 'xps', label: 'Transformé' },
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ExperienceLog {
|
||||||
|
|
||||||
|
static async add(actor, topic, from, to, raison, manuel = false) {
|
||||||
|
if (!actor.hasPlayerOwner || !actor.isPersonnage()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (from == to) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const newXpLog = {
|
||||||
|
mode: topic?.code ?? topic,
|
||||||
|
raison: (manuel ? '(manuel) ' : '') + raison,
|
||||||
|
from: from,
|
||||||
|
to: to,
|
||||||
|
valeur: to - from,
|
||||||
|
daterdd: game.system.rdd.calendrier.dateCourante(),
|
||||||
|
datereel: game.system.rdd.calendrier.dateReel().replace('T', ' ')
|
||||||
|
};
|
||||||
|
console.log('ExperienceLog.add', newXpLog)
|
||||||
|
const newExperienceLog = (actor.system.experiencelog ?? []).concat([newXpLog]);
|
||||||
|
await actor.update({ [`system.experiencelog`]: newExperienceLog });
|
||||||
|
}
|
||||||
|
|
||||||
|
static labelTopic(topic) {
|
||||||
|
const xpt = Object.values(XP_TOPIC).find(it => it.code == topic);
|
||||||
|
return xpt?.label ?? xpt?.code ?? topic;
|
||||||
|
}
|
||||||
|
}
|
@ -78,11 +78,7 @@ export class ChatUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async createChatWithRollMode(name, chatOptions) {
|
static async createChatWithRollMode(name, chatOptions) {
|
||||||
return await ChatUtility.createChatMessage(name, game.settings.get("core", "rollMode"), chatOptions);
|
let rollMode = game.settings.get("core", "rollMode")
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async createChatMessage(name, rollMode, chatOptions) {
|
|
||||||
switch (rollMode) {
|
switch (rollMode) {
|
||||||
case "blindroll": // GM only
|
case "blindroll": // GM only
|
||||||
if (!game.user.isGM) {
|
if (!game.user.isGM) {
|
||||||
|
@ -25,23 +25,13 @@ export class DialogChronologie extends Dialog {
|
|||||||
journalId: game.settings.get(SYSTEM_RDD, LATEST_USED_JOURNAL_ID),
|
journalId: game.settings.get(SYSTEM_RDD, LATEST_USED_JOURNAL_ID),
|
||||||
journaux: game.journal.filter(it => it.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)),
|
journaux: game.journal.filter(it => it.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)),
|
||||||
timestamp: game.system.rdd.calendrier.timestamp,
|
timestamp: game.system.rdd.calendrier.timestamp,
|
||||||
dateReel: DialogChronologie.getCurrentDateTime()
|
dateReel: game.system.rdd.calendrier.dateReel()
|
||||||
};
|
};
|
||||||
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-chronologie.html", dialogData);
|
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-chronologie.html", dialogData);
|
||||||
const dialog = new DialogChronologie(html, dialogData);
|
const dialog = new DialogChronologie(html, dialogData);
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getCurrentDateTime() {
|
|
||||||
return new Date().toLocaleString("sv-SE", {
|
|
||||||
year: "numeric",
|
|
||||||
month: "2-digit",
|
|
||||||
day: "2-digit",
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "2-digit"
|
|
||||||
}).replace(" ", "T");
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(html, dialogData) {
|
constructor(html, dialogData) {
|
||||||
const options = {
|
const options = {
|
||||||
classes: ["DialogChronologie"],
|
classes: ["DialogChronologie"],
|
||||||
@ -124,7 +114,7 @@ export class DialogChronologie extends Dialog {
|
|||||||
heure: RdDTimestamp.definition(this.html.find("form.rdddialogchrono :input[name='chronologie.heure']").val()),
|
heure: RdDTimestamp.definition(this.html.find("form.rdddialogchrono :input[name='chronologie.heure']").val()),
|
||||||
minute: this.html.find("form.rdddialogchrono :input[name='chronologie.minute']").val(),
|
minute: this.html.find("form.rdddialogchrono :input[name='chronologie.minute']").val(),
|
||||||
},
|
},
|
||||||
dateReel: this.html.find("form.rdddialogchrono :input[name='dateReel']").val().replace('T', ' ')
|
dateReel: this.html.find("form.rdddialogchrono :input[name='dateReel']").val()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import { RdDUtility } from "./rdd-utility.js";
|
|||||||
*/
|
*/
|
||||||
export class DialogValidationEncaissement extends Dialog {
|
export class DialogValidationEncaissement extends Dialog {
|
||||||
|
|
||||||
static async validerEncaissement(actor, rollData, armure, show, onEncaisser) {
|
static async validerEncaissement(actor, rollData, armure, show, attackerId, onEncaisser) {
|
||||||
let encaissement = await RdDUtility.jetEncaissement(rollData, armure, { showDice: HIDE_DICE });
|
let encaissement = await RdDUtility.jetEncaissement(rollData, armure, { showDice: HIDE_DICE });
|
||||||
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html', {
|
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html', {
|
||||||
actor: actor,
|
actor: actor,
|
||||||
@ -15,12 +15,12 @@ export class DialogValidationEncaissement extends Dialog {
|
|||||||
encaissement: encaissement,
|
encaissement: encaissement,
|
||||||
show: show
|
show: show
|
||||||
});
|
});
|
||||||
const dialog = new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, show, onEncaisser);
|
const dialog = new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, show, attackerId, onEncaisser);
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
constructor(html, actor, rollData, armure, encaissement, show, onEncaisser) {
|
constructor(html, actor, rollData, armure, encaissement, show, attackerId, onEncaisser) {
|
||||||
// Common conf
|
// Common conf
|
||||||
let buttons = {
|
let buttons = {
|
||||||
"valider": { label: "Valider", callback: html => this.onValider() },
|
"valider": { label: "Valider", callback: html => this.onValider() },
|
||||||
@ -48,6 +48,7 @@ export class DialogValidationEncaissement extends Dialog {
|
|||||||
this.armure = armure;
|
this.armure = armure;
|
||||||
this.encaissement = encaissement;
|
this.encaissement = encaissement;
|
||||||
this.show = show;
|
this.show = show;
|
||||||
|
this.attackerId = attackerId;
|
||||||
this.onEncaisser = onEncaisser;
|
this.onEncaisser = onEncaisser;
|
||||||
this.forceDiceResult = {total: encaissement.roll.result };
|
this.forceDiceResult = {total: encaissement.roll.result };
|
||||||
}
|
}
|
||||||
@ -66,6 +67,6 @@ export class DialogValidationEncaissement extends Dialog {
|
|||||||
|
|
||||||
async onValider() {
|
async onValider() {
|
||||||
this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult});
|
this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult});
|
||||||
this.onEncaisser(this.encaissement, this.show)
|
this.onEncaisser(this.encaissement, this.show, this.attackerId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js"
|
import { RdDItemCompetenceCreature } from "./item-competencecreature.js"
|
||||||
|
import { TYPES } from "./item.js";
|
||||||
import { RdDCombatManager } from "./rdd-combat.js";
|
import { RdDCombatManager } from "./rdd-combat.js";
|
||||||
|
|
||||||
const nomCategorieParade = {
|
const nomCategorieParade = {
|
||||||
@ -19,7 +20,7 @@ const nomCategorieParade = {
|
|||||||
export class RdDItemArme extends Item {
|
export class RdDItemArme extends Item {
|
||||||
|
|
||||||
static isArme(item) {
|
static isArme(item) {
|
||||||
return (item.type == 'competencecreature' && item.system.iscombat) || item.type == 'arme';
|
return RdDItemCompetenceCreature.getCategorieAttaque(item) || item.type == 'arme';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -27,7 +28,7 @@ export class RdDItemArme extends Item {
|
|||||||
switch (arme ? arme.type : '') {
|
switch (arme ? arme.type : '') {
|
||||||
case 'arme': return arme;
|
case 'arme': return arme;
|
||||||
case 'competencecreature':
|
case 'competencecreature':
|
||||||
return RdDItemCompetenceCreature.armeNaturelle(arme);
|
return RdDItemCompetenceCreature.armeCreature(arme);
|
||||||
}
|
}
|
||||||
return RdDItemArme.mainsNues();
|
return RdDItemArme.mainsNues();
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ const limitesArchetypes = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
const categorieCompetences = {
|
const categoriesCompetences = {
|
||||||
"generale": { base: -4, label: "Générales" },
|
"generale": { base: -4, label: "Générales" },
|
||||||
"particuliere": { base: -8, label: "Particulières" },
|
"particuliere": { base: -8, label: "Particulières" },
|
||||||
"specialisee": { base: -11, label: "Spécialisées" },
|
"specialisee": { base: -11, label: "Spécialisées" },
|
||||||
@ -49,16 +49,16 @@ const competence_xp_cumul = _buildCumulXP();
|
|||||||
|
|
||||||
export class RdDItemCompetence extends Item {
|
export class RdDItemCompetence extends Item {
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getCategorieCompetences() {
|
static getCategories() {
|
||||||
return categorieCompetences;
|
return categoriesCompetences;
|
||||||
}
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static getNiveauBase(category) {
|
|
||||||
return categorieCompetences[category].base;
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getLabelCategorie(category) {
|
static getLabelCategorie(category) {
|
||||||
return categorieCompetences[category].label;
|
return categoriesCompetences[category].label;
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static getNiveauBase(category, categories = categoriesCompetences) {
|
||||||
|
return categories[category]?.base ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -192,7 +192,7 @@ export class RdDItemCompetence extends Item {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static isNiveauBase(item) {
|
static isNiveauBase(item) {
|
||||||
return Number(item.system.niveau) == RdDItemCompetence.getNiveauBase(item.system.categorie);
|
return Number(item.system.niveau) == RdDItemCompetence.getNiveauBase(item.system.categorie, item.getCategories());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
@ -1,51 +1,97 @@
|
|||||||
|
|
||||||
|
import { RdDItem, TYPES } from "./item.js";
|
||||||
import { RdDCombatManager } from "./rdd-combat.js";
|
import { RdDCombatManager } from "./rdd-combat.js";
|
||||||
|
|
||||||
|
const categories = {
|
||||||
|
"generale": { base: 0, label: "Générale" },
|
||||||
|
"naturelle": { base: 0, label: "Arme naturelle" },
|
||||||
|
"melee": { base: 0, label: "Mêlée" },
|
||||||
|
"parade": { base: 0, label: "Parade" },
|
||||||
|
"tir": { base: 0, label: "Tir" },
|
||||||
|
"lancer": { base: 0, label: "Lancer" },
|
||||||
|
"possession": { base: 0, label: "Possession" },
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RdDItemCompetenceCreature extends Item {
|
export class RdDItemCompetenceCreature extends Item {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
static getCategories() {
|
||||||
static setRollDataCreature(rollData) {
|
return categories;
|
||||||
rollData.competence = rollData.competence
|
|
||||||
rollData.carac = { "carac_creature": { label: rollData.competence.name, value: rollData.competence.system.carac_value } }
|
|
||||||
rollData.competence.system.defaut_carac = "carac_creature"
|
|
||||||
rollData.competence.system.categorie = "creature"
|
|
||||||
rollData.selectedCarac = rollData.carac.carac_creature
|
|
||||||
if (rollData.competence.system.iscombat) {
|
|
||||||
rollData.arme = RdDItemCompetenceCreature.armeNaturelle(rollData.competence);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static armeNaturelle(competencecreature) {
|
static setRollDataCreature(rollData) {
|
||||||
if (RdDItemCompetenceCreature.isCompetenceAttaque(competencecreature)) {
|
rollData.carac = { "carac_creature": { label: rollData.competence.name, value: rollData.competence.system.carac_value } }
|
||||||
// si c'est un Item compétence: cloner pour ne pas modifier lma compétence
|
rollData.competence.system.defaut_carac = "carac_creature"
|
||||||
let arme = (competencecreature instanceof Item) ? competencecreature.clone(): competencecreature;
|
rollData.selectedCarac = rollData.carac.carac_creature
|
||||||
mergeObject(arme.system,
|
rollData.arme = RdDItemCompetenceCreature.armeCreature(rollData.competence);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static armeCreature(item) {
|
||||||
|
const categorieAttaque = RdDItemCompetenceCreature.getCategorieAttaque(item)
|
||||||
|
if (categorieAttaque != undefined) {
|
||||||
|
// si c'est un Item compétence: cloner pour ne pas modifier la compétence
|
||||||
|
let arme = item.clone();
|
||||||
|
mergeObject(arme,
|
||||||
{
|
{
|
||||||
competence: arme.name,
|
action: item.isCompetencePossession() ? 'possession' : 'attaque',
|
||||||
initiative: RdDCombatManager.calculInitiative(competencecreature.system.niveau, competencecreature.system.carac_value),
|
system: {
|
||||||
niveau: competencecreature.system.niveau,
|
competence: arme.name,
|
||||||
equipe: true,
|
cac: categorieAttaque == "naturelle" ? "naturelle" : "",
|
||||||
resistance: 100,
|
niveau: item.system.niveau,
|
||||||
dommagesReels: arme.system.dommages,
|
initiative: RdDCombatManager.calculInitiative(item.system.niveau, item.system.carac_value),
|
||||||
penetration: 0,
|
equipe: true,
|
||||||
force: 0,
|
resistance: 100,
|
||||||
rapide: true,
|
dommagesReels: arme.system.dommages,
|
||||||
cac: competencecreature.system.isnaturelle ? "naturelle" : "",
|
penetration: 0,
|
||||||
action: 'attaque'
|
force: 0,
|
||||||
|
rapide: true,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return arme;
|
return arme;
|
||||||
}
|
}
|
||||||
console.error("RdDItemCompetenceCreature.toActionArme(", competencecreature, ") : impossible de transformer l'Item en arme");
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static isCompetenceAttaque(item) {
|
static getCategorieAttaque(item) {
|
||||||
return item.type == 'competencecreature' && item.system.iscombat;
|
if (item.type == TYPES.competencecreature) {
|
||||||
|
switch (item.system.categorie) {
|
||||||
|
case "melee":
|
||||||
|
case "tir":
|
||||||
|
case "lancer":
|
||||||
|
case "naturelle":
|
||||||
|
case "possession":
|
||||||
|
return item.system.categorie
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
}
|
}
|
||||||
|
static isDommages(item) {
|
||||||
|
if (item.type == TYPES.competencecreature) {
|
||||||
|
switch (item.system.categorie) {
|
||||||
|
case "melee":
|
||||||
|
case "tir":
|
||||||
|
case "lancer":
|
||||||
|
case "naturelle":
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
static isParade(item) {
|
||||||
|
if (item.type == TYPES.competencecreature) {
|
||||||
|
switch (item.system.categorie) {
|
||||||
|
case "melee":
|
||||||
|
case "naturelle":
|
||||||
|
case "parade":
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static isCompetenceParade(item) {
|
static isCompetenceParade(item) {
|
||||||
return item.type == 'competencecreature' && item.system.categorie_parade !== "";
|
return item.type == 'competencecreature' && item.system.categorie_parade !== "";
|
||||||
|
@ -11,6 +11,8 @@ import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
|||||||
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||||
|
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||||
|
import { TYPES } from "./item.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extend the basic ItemSheet for RdD specific items
|
* Extend the basic ItemSheet for RdD specific items
|
||||||
@ -98,9 +100,13 @@ export class RdDItemSheet extends ItemSheet {
|
|||||||
isComestible: this.item.getUtilisationCuisine(),
|
isComestible: this.item.getUtilisationCuisine(),
|
||||||
options: RdDSheetUtility.mergeDocumentRights(this.options, this.item, this.isEditable)
|
options: RdDSheetUtility.mergeDocumentRights(this.options, this.item, this.isEditable)
|
||||||
}
|
}
|
||||||
|
if (this.item.type == TYPES.competencecreature) {
|
||||||
|
formData.isparade = RdDItemCompetenceCreature.isParade(this.item)
|
||||||
|
formData.isdommages = RdDItemCompetenceCreature.isDommages(this.item)
|
||||||
|
}
|
||||||
|
|
||||||
const competences = await SystemCompendiums.getCompetences('personnage');
|
const competences = await SystemCompendiums.getCompetences('personnage');
|
||||||
formData.categorieCompetences = RdDItemCompetence.getCategorieCompetences()
|
formData.categories = this.item.getCategories()
|
||||||
if (this.item.type == 'tache' || this.item.type == 'livre' || this.item.type == 'meditation' || this.item.type == 'oeuvre') {
|
if (this.item.type == 'tache' || this.item.type == 'livre' || this.item.type == 'meditation' || this.item.type == 'oeuvre') {
|
||||||
formData.caracList = duplicate(game.system.model.Actor.personnage.carac)
|
formData.caracList = duplicate(game.system.model.Actor.personnage.carac)
|
||||||
formData.caracList["reve-actuel"] = duplicate(game.system.model.Actor.personnage.reve.reve)
|
formData.caracList["reve-actuel"] = duplicate(game.system.model.Actor.personnage.reve.reve)
|
||||||
@ -249,7 +255,8 @@ export class RdDItemSheet extends ItemSheet {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
if (this.item.isCompetence()) {
|
if (this.item.isCompetence()) {
|
||||||
let level = RdDItemCompetence.getNiveauBase(event.currentTarget.value);
|
const categorie = event.currentTarget.value;
|
||||||
|
const level = RdDItemCompetence.getNiveauBase(categorie, this.item.getCategories());
|
||||||
this.item.system.base = level;
|
this.item.system.base = level;
|
||||||
this.html.find('[name="system.base"]').val(level);
|
this.html.find('[name="system.base"]').val(level);
|
||||||
}
|
}
|
||||||
|
@ -6,44 +6,55 @@ import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
|||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||||
import { RdDRaretes } from "./item/raretes.js";
|
import { RdDRaretes } from "./item/raretes.js";
|
||||||
|
import { RdDItemCompetence } from "./item-competence.js";
|
||||||
|
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||||
|
|
||||||
export const TYPES = {
|
export const TYPES = {
|
||||||
competence: 'competence',
|
competence: 'competence',
|
||||||
competencecreature: 'competencecreature',
|
competencecreature: 'competencecreature',
|
||||||
|
empoignade: 'empoignade',
|
||||||
|
possession: 'possession',
|
||||||
|
blessure: 'blessure',
|
||||||
|
maladie: 'maladie',
|
||||||
|
poison: 'poison',
|
||||||
arme: 'arme',
|
arme: 'arme',
|
||||||
armure: 'armure',
|
armure: 'armure',
|
||||||
conteneur: 'conteneur',
|
conteneur: 'conteneur',
|
||||||
sort: 'sort',
|
objet: 'objet',
|
||||||
|
monnaie: 'monnaie',
|
||||||
|
gemme: 'gemme',
|
||||||
|
munition: 'munition',
|
||||||
|
nourritureboisson: 'nourritureboisson',
|
||||||
herbe: 'herbe',
|
herbe: 'herbe',
|
||||||
faune: 'faune',
|
plante: 'plante',
|
||||||
ingredient: 'ingredient',
|
ingredient: 'ingredient',
|
||||||
|
faune: 'faune',
|
||||||
livre: 'livre',
|
livre: 'livre',
|
||||||
potion: 'potion',
|
potion: 'potion',
|
||||||
|
service: 'service',
|
||||||
|
musique: 'musique',
|
||||||
|
danse: 'danse',
|
||||||
|
chant: 'chant',
|
||||||
|
jeu: 'jeu',
|
||||||
|
recettecuisine: 'recettecuisine',
|
||||||
|
oeuvre: 'oeuvre',
|
||||||
|
recettealchimique: 'recettealchimique',
|
||||||
|
tache: 'tache',
|
||||||
|
sort: 'sort',
|
||||||
|
sortreserve: 'sortreserve',
|
||||||
rencontre: 'rencontre',
|
rencontre: 'rencontre',
|
||||||
queue: 'queue',
|
queue: 'queue',
|
||||||
ombre: 'ombre',
|
ombre: 'ombre',
|
||||||
souffle: 'souffle',
|
souffle: 'souffle',
|
||||||
tete: 'tete',
|
tete: 'tete',
|
||||||
|
casetmr: 'casetmr',
|
||||||
meditation: 'meditation',
|
meditation: 'meditation',
|
||||||
recettealchimique: 'recettealchimique',
|
|
||||||
chant: 'chant',
|
|
||||||
danse: 'danse',
|
|
||||||
jeu: 'jeu',
|
|
||||||
recettecuisine: 'recettecuisine',
|
|
||||||
musique: 'musique',
|
|
||||||
maladie: 'maladie',
|
|
||||||
poison: 'poison',
|
|
||||||
oeuvre: 'oeuvre',
|
|
||||||
nourritureboisson: 'nourritureboisson',
|
|
||||||
service: 'service',
|
|
||||||
signedraconique: 'signedraconique',
|
signedraconique: 'signedraconique',
|
||||||
gemme: 'gemme',
|
|
||||||
possession: 'possession',
|
|
||||||
sortreserve: 'sortreserve',
|
|
||||||
extraitpoetique: 'extraitpoetique',
|
|
||||||
tarot: 'tarot',
|
tarot: 'tarot',
|
||||||
empoignade: 'empoignade'
|
nombreastral: 'nombreastral',
|
||||||
|
extraitpoetique: 'extraitpoetique',
|
||||||
}
|
}
|
||||||
|
|
||||||
const typesInventaireMateriel = [
|
const typesInventaireMateriel = [
|
||||||
TYPES.arme,
|
TYPES.arme,
|
||||||
TYPES.armure,
|
TYPES.armure,
|
||||||
@ -209,6 +220,7 @@ export class RdDItem extends Item {
|
|||||||
isService() { return this.type == TYPES.service; }
|
isService() { return this.type == TYPES.service; }
|
||||||
|
|
||||||
isCompetence() { return typesObjetsCompetence.includes(this.type) }
|
isCompetence() { return typesObjetsCompetence.includes(this.type) }
|
||||||
|
isCompetencePossession() { return TYPES.competencecreature == this.type && this.system.categorie == "possession" }
|
||||||
isTemporel() { return typesObjetsTemporels.includes(this.type) }
|
isTemporel() { return typesObjetsTemporels.includes(this.type) }
|
||||||
isOeuvre() { return typesObjetsOeuvres.includes(this.type) }
|
isOeuvre() { return typesObjetsOeuvres.includes(this.type) }
|
||||||
isDraconique() { return RdDItem.getItemTypesDraconiques().includes(this.type) }
|
isDraconique() { return RdDItem.getItemTypesDraconiques().includes(this.type) }
|
||||||
@ -225,6 +237,13 @@ export class RdDItem extends Item {
|
|||||||
isPresentDansMilieux(milieux) {
|
isPresentDansMilieux(milieux) {
|
||||||
return this.getEnvironnements(milieux).length > 0
|
return this.getEnvironnements(milieux).length > 0
|
||||||
}
|
}
|
||||||
|
getCategories() {
|
||||||
|
switch (this.type) {
|
||||||
|
case TYPES.competence: return RdDItemCompetence.getCategories()
|
||||||
|
case TYPES.competencecreature: return RdDItemCompetenceCreature.getCategories()
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
|
||||||
getEnvironnements(milieux = undefined) {
|
getEnvironnements(milieux = undefined) {
|
||||||
const environnements = this.isInventaire() ? this.system.environnement : undefined;
|
const environnements = this.isInventaire() ? this.system.environnement : undefined;
|
||||||
@ -361,7 +380,7 @@ export class RdDItem extends Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getEncTotal() {
|
getEncTotal() {
|
||||||
return (this.isService() ? 0 : this.getQuantite()) * this.getEnc();
|
return (this.getQuantite() ?? 0) * this.getEnc();
|
||||||
}
|
}
|
||||||
|
|
||||||
getEnc() {
|
getEnc() {
|
||||||
|
@ -29,7 +29,7 @@ export class RdDConteneurItemSheet extends RdDItemInventaireSheet {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
prepareConteneurData(formData) {
|
prepareConteneurData(formData) {
|
||||||
RdDBaseActorSheet.filterItemsPerTypeForSheet(formData, this.actor.itemTypes);
|
RdDBaseActorSheet.filterItemsPerTypeForSheet(formData, this.actor.itemTypes);
|
||||||
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
|
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires);
|
||||||
formData.subItems = formData.conteneurs.find(it => it._id == this.item.id)?.subItems;
|
formData.subItems = formData.conteneurs.find(it => it._id == this.item.id)?.subItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { RdDBaseActor } from "./actor/base-actor.js";
|
|||||||
import { LOG_HEAD, SYSTEM_RDD } from "./constants.js";
|
import { LOG_HEAD, SYSTEM_RDD } from "./constants.js";
|
||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { Monnaie } from "./item-monnaie.js";
|
import { Monnaie } from "./item-monnaie.js";
|
||||||
import { RdDItem } from "./item.js";
|
import { RdDItem, TYPES } from "./item.js";
|
||||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||||
import { RdDRaretes } from "./item/raretes.js";
|
import { RdDRaretes } from "./item/raretes.js";
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ class Migration {
|
|||||||
|
|
||||||
async applyItemsUpdates(computeUpdates) {
|
async applyItemsUpdates(computeUpdates) {
|
||||||
await game.actors.forEach(async (actor) => {
|
await game.actors.forEach(async (actor) => {
|
||||||
const actorItemUpdates = computeUpdates(actor.items);
|
const actorItemUpdates = computeUpdates(actor.items).filter(it => it != undefined);
|
||||||
if (actorItemUpdates.length > 0) {
|
if (actorItemUpdates.length > 0) {
|
||||||
console.log(
|
console.log(
|
||||||
this.code,
|
this.code,
|
||||||
@ -24,7 +24,7 @@ class Migration {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const itemUpdates = computeUpdates(game.items);
|
const itemUpdates = computeUpdates(game.items).filter(it => it != undefined);
|
||||||
if (itemUpdates.length > 0) {
|
if (itemUpdates.length > 0) {
|
||||||
console.log(this.code, "Applying updates on items", itemUpdates);
|
console.log(this.code, "Applying updates on items", itemUpdates);
|
||||||
await Item.updateDocuments(itemUpdates);
|
await Item.updateDocuments(itemUpdates);
|
||||||
@ -65,7 +65,6 @@ class _1_5_34_migrationPngWebp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class _10_0_16_MigrationSortsReserve extends Migration {
|
class _10_0_16_MigrationSortsReserve extends Migration {
|
||||||
get code() { return "creation-item-sort-reserve"; }
|
get code() { return "creation-item-sort-reserve"; }
|
||||||
get version() { return "10.0.16"; }
|
get version() { return "10.0.16"; }
|
||||||
@ -370,6 +369,7 @@ class _10_4_6_ServicesEnCommerces extends Migration {
|
|||||||
return itemToCreate;
|
return itemToCreate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _10_5_0_UpdatePeriodicite extends Migration {
|
class _10_5_0_UpdatePeriodicite extends Migration {
|
||||||
get code() { return "migration-periodicite-poisons-maladies"; }
|
get code() { return "migration-periodicite-poisons-maladies"; }
|
||||||
get version() { return "10.5.0"; }
|
get version() { return "10.5.0"; }
|
||||||
@ -458,6 +458,62 @@ class _10_7_0_MigrationBlessures extends Migration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _10_7_19_CategorieCompetenceCreature extends Migration {
|
||||||
|
get code() { return "categorie-competence-creature"; }
|
||||||
|
get version() { return "10.7.19"; }
|
||||||
|
|
||||||
|
async migrate() {
|
||||||
|
await this.applyItemsUpdates(items => items
|
||||||
|
.filter(it => TYPES.competencecreature == it.type)
|
||||||
|
.map(it => this.migrateCompetenceCreature(it))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
migrateCompetenceCreature(it) {
|
||||||
|
const categorie = this.getCategorie(it)
|
||||||
|
if (categorie == it.system.categorie) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
return { _id: it.id, 'system.categorie': categorie }
|
||||||
|
}
|
||||||
|
|
||||||
|
getCategorie(it) {
|
||||||
|
if (it.system.ispossession) {
|
||||||
|
return 'possession'
|
||||||
|
}
|
||||||
|
switch (it.system.categorie) {
|
||||||
|
case "melee":
|
||||||
|
if (it.system.isnaturelle) {
|
||||||
|
return 'naturelle'
|
||||||
|
}
|
||||||
|
return 'melee'
|
||||||
|
case "particuliere": case "specialisee": case "connaissance":
|
||||||
|
return "generale"
|
||||||
|
default:
|
||||||
|
return it.system.categorie
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
export class Migrations {
|
||||||
static getMigrations() {
|
static getMigrations() {
|
||||||
return [
|
return [
|
||||||
@ -474,6 +530,8 @@ export class Migrations {
|
|||||||
new _10_4_6_ServicesEnCommerces(),
|
new _10_4_6_ServicesEnCommerces(),
|
||||||
new _10_5_0_UpdatePeriodicite(),
|
new _10_5_0_UpdatePeriodicite(),
|
||||||
new _10_7_0_MigrationBlessures(),
|
new _10_7_0_MigrationBlessures(),
|
||||||
|
new _10_7_19_CategorieCompetenceCreature(),
|
||||||
|
new _10_7_19_PossessionsEntiteVictime(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,7 +548,7 @@ export class Migrations {
|
|||||||
migrate() {
|
migrate() {
|
||||||
const currentVersion = game.settings.get(SYSTEM_RDD, "systemMigrationVersion");
|
const currentVersion = game.settings.get(SYSTEM_RDD, "systemMigrationVersion");
|
||||||
if (isNewerVersion(game.system.version, currentVersion)) {
|
if (isNewerVersion(game.system.version, currentVersion)) {
|
||||||
//if (true) { /* comment previous and uncomment here to test before upgrade */
|
// if (true) { /* comment previous and uncomment here to test before upgrade */
|
||||||
const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion));
|
const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion));
|
||||||
if (migrations.length > 0) {
|
if (migrations.length > 0) {
|
||||||
migrations.sort((a, b) => this.compareVersions(a, b));
|
migrations.sort((a, b) => this.compareVersions(a, b));
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { RdDCarac } from "./rdd-carac.js";
|
import { RdDCarac } from "./rdd-carac.js";
|
||||||
|
import { RdDPossession } from "./rdd-possession.js";
|
||||||
|
|
||||||
const conditionsTactiques = [
|
const conditionsTactiques = [
|
||||||
{ type: '', descr: '', dmg: 0, attaque: 0, parade: 0, esquive: true },
|
{ type: '', descr: '', dmg: 0, attaque: 0, parade: 0, esquive: true },
|
||||||
@ -27,6 +28,9 @@ export class RdDBonus {
|
|||||||
if (rollData.isEmpoignade && rollData.rolled?.isPart) {
|
if (rollData.isEmpoignade && rollData.rolled?.isPart) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if (RdDPossession.isDefensePossession(rollData)) {
|
||||||
|
return RdDPossession.isPossessionFinesse(rollData)
|
||||||
|
}
|
||||||
return rollData.attackerRoll?.particuliere == 'finesse';
|
return rollData.attackerRoll?.particuliere == 'finesse';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +78,7 @@ export class RdDBonus {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static _dmgArme(rollData) {
|
static _dmgArme(rollData) {
|
||||||
if ( rollData.arme) {
|
if (rollData.arme) {
|
||||||
let dmgBase = rollData.arme.system.dommagesReels ?? Number(rollData.arme.system.dommages ?? 0);
|
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)
|
//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);
|
return dmgBase + Math.min(dmgBase, rollData.arme.system.magique ? rollData.arme.system.ecaille_efficacite : 0);
|
||||||
|
@ -58,15 +58,6 @@ export class RdDCarac {
|
|||||||
selectedCarac?.label.match(/(Apparence|Force|Agilité|Dextérité|Vue|Ouïe|Odorat-Goût|Empathie|Dérobée|Mêlée|Tir|Lancer)/);
|
selectedCarac?.label.match(/(Apparence|Force|Agilité|Dextérité|Vue|Ouïe|Odorat-Goût|Empathie|Dérobée|Mêlée|Tir|Lancer)/);
|
||||||
}
|
}
|
||||||
|
|
||||||
static isIgnoreEtatGeneral(rollData) {
|
|
||||||
const selectedCarac = rollData.selectedCarac;
|
|
||||||
return !selectedCarac ||
|
|
||||||
rollData.ethylisme ||
|
|
||||||
RdDCarac.isChance(selectedCarac) ||
|
|
||||||
(RdDCarac.isReve(selectedCarac) && !rollData.competence);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static computeTotal(carac, beaute = undefined) {
|
static computeTotal(carac, beaute = undefined) {
|
||||||
const total = Object.values(carac ?? {}).filter(c => !c.derivee)
|
const total = Object.values(carac ?? {}).filter(c => !c.derivee)
|
||||||
.map(it => parseInt(it.value))
|
.map(it => parseInt(it.value))
|
||||||
|
@ -87,7 +87,7 @@ export class RdDCombatManager extends Combat {
|
|||||||
let rollFormula = formula ?? RdDCombatManager.formuleInitiative(2, 10, 0, 0);
|
let rollFormula = formula ?? RdDCombatManager.formuleInitiative(2, 10, 0, 0);
|
||||||
if (!formula) {
|
if (!formula) {
|
||||||
if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') {
|
if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') {
|
||||||
const competence = combatant.actor.items.find(it => it.system.iscombat)
|
const competence = combatant.actor.items.find(it => RdDItemCompetenceCreature.getCategorieAttaque(it))
|
||||||
if (competence) {
|
if (competence) {
|
||||||
rollFormula = RdDCombatManager.formuleInitiative(2, competence.system.carac_value, competence.system.niveau, 0);
|
rollFormula = RdDCombatManager.formuleInitiative(2, competence.system.carac_value, competence.system.niveau, 0);
|
||||||
}
|
}
|
||||||
@ -230,15 +230,15 @@ export class RdDCombatManager extends Combat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static listActionsCreature(competences) {
|
static listActionsCreature(competences) {
|
||||||
return competences.filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
|
return competences.map(it => RdDItemCompetenceCreature.armeCreature(it))
|
||||||
.map(it => RdDItemCompetenceCreature.armeNaturelle(it));
|
.filter(it => it != undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
static listActionsPossessions(actor) {
|
static listActionsPossessions(actor) {
|
||||||
return RdDCombatManager._indexActions(actor.getPossessions().map(p => {
|
return RdDCombatManager._indexActions(actor.getPossessions().map(p => {
|
||||||
return {
|
return {
|
||||||
name: p.name,
|
name: p.name,
|
||||||
action: 'conjurer',
|
action: 'possession',
|
||||||
system: {
|
system: {
|
||||||
competence: p.name,
|
competence: p.name,
|
||||||
possessionid: p.system.possessionid,
|
possessionid: p.system.possessionid,
|
||||||
@ -255,7 +255,7 @@ export class RdDCombatManager extends Combat {
|
|||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
if (actor.isCreatureEntite()) {
|
if (actor.isCreatureEntite()) {
|
||||||
actions = actions.concat(RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']));
|
actions = RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']);
|
||||||
} else if (actor.isPersonnage()) {
|
} else if (actor.isPersonnage()) {
|
||||||
// Recupération des items 'arme'
|
// Recupération des items 'arme'
|
||||||
const armes = actor.itemTypes['arme'].filter(it => RdDItemArme.isArmeUtilisable(it))
|
const armes = actor.itemTypes['arme'].filter(it => RdDItemArme.isArmeUtilisable(it))
|
||||||
@ -263,7 +263,7 @@ export class RdDCombatManager extends Combat {
|
|||||||
.concat(RdDItemArme.mainsNues());
|
.concat(RdDItemArme.mainsNues());
|
||||||
|
|
||||||
const competences = actor.itemTypes['competence'];
|
const competences = actor.itemTypes['competence'];
|
||||||
actions = actions.concat(RdDCombatManager.listActionsArmes(armes, competences, actor.system.carac));
|
actions = RdDCombatManager.listActionsArmes(armes, competences, actor.system.carac);
|
||||||
|
|
||||||
if (actor.system.attributs.hautrevant.value) {
|
if (actor.system.attributs.hautrevant.value) {
|
||||||
actions.push({ name: "Draconic", action: 'haut-reve', system: { initOnly: true, competence: "Draconic" } });
|
actions.push({ name: "Draconic", action: 'haut-reve', system: { initOnly: true, competence: "Draconic" } });
|
||||||
@ -351,7 +351,7 @@ export class RdDCombatManager extends Combat {
|
|||||||
} else if (combatant.actor.getSurprise() == "demi") {
|
} else if (combatant.actor.getSurprise() == "demi") {
|
||||||
initOffset = 0;
|
initOffset = 0;
|
||||||
initInfo = "Demi Surprise"
|
initInfo = "Demi Surprise"
|
||||||
} else if (action.action == 'conjurer') {
|
} else if (action.action == 'possession') {
|
||||||
initOffset = 10;
|
initOffset = 10;
|
||||||
caracForInit = combatant.actor.getReveActuel();
|
caracForInit = combatant.actor.getReveActuel();
|
||||||
initInfo = "Possession"
|
initInfo = "Possession"
|
||||||
@ -790,7 +790,7 @@ export class RdDCombat {
|
|||||||
passeArme: randomID(16),
|
passeArme: randomID(16),
|
||||||
mortalite: arme?.system.mortalite,
|
mortalite: arme?.system.mortalite,
|
||||||
coupsNonMortels: false,
|
coupsNonMortels: false,
|
||||||
competence: competence,
|
competence: competence.clone(),
|
||||||
surprise: this.attacker.getSurprise(true),
|
surprise: this.attacker.getSurprise(true),
|
||||||
surpriseDefenseur: this.defender.getSurprise(true),
|
surpriseDefenseur: this.defender.getSurprise(true),
|
||||||
targetToken: Targets.extractTokenData(this.target),
|
targetToken: Targets.extractTokenData(this.target),
|
||||||
@ -1045,7 +1045,7 @@ export class RdDCombat {
|
|||||||
passeArme: attackerRoll.passeArme,
|
passeArme: attackerRoll.passeArme,
|
||||||
diffLibre: attackerRoll.diffLibre,
|
diffLibre: attackerRoll.diffLibre,
|
||||||
attackerRoll: attackerRoll,
|
attackerRoll: attackerRoll,
|
||||||
competence: this.defender.getCompetence(competenceParade),
|
competence: this.defender.getCompetence(competenceParade).clone(),
|
||||||
arme: armeParade,
|
arme: armeParade,
|
||||||
surprise: this.defender.getSurprise(true),
|
surprise: this.defender.getSurprise(true),
|
||||||
needParadeSignificative: ReglesOptionelles.isUsing('categorieParade') && RdDItemArme.needParadeSignificative(attackerRoll.arme, armeParade),
|
needParadeSignificative: ReglesOptionelles.isUsing('categorieParade') && RdDItemArme.needParadeSignificative(attackerRoll.arme, armeParade),
|
||||||
@ -1126,7 +1126,7 @@ export class RdDCombat {
|
|||||||
passeArme: attackerRoll.passeArme,
|
passeArme: attackerRoll.passeArme,
|
||||||
diffLibre: attackerRoll.diffLibre,
|
diffLibre: attackerRoll.diffLibre,
|
||||||
attackerRoll: attackerRoll,
|
attackerRoll: attackerRoll,
|
||||||
competence: competence,
|
competence: competence.clone(),
|
||||||
surprise: this.defender.getSurprise(true),
|
surprise: this.defender.getSurprise(true),
|
||||||
surpriseDefenseur: this.defender.getSurprise(true),
|
surpriseDefenseur: this.defender.getSurprise(true),
|
||||||
carac: this.defender.system.carac,
|
carac: this.defender.system.carac,
|
||||||
|
@ -4,6 +4,8 @@ import { RdDRoll } from "./rdd-roll.js";
|
|||||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||||
import { ChatUtility } from "./chat-utility.js";
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
import { STATUSES } from "./settings/status-effects.js";
|
import { STATUSES } from "./settings/status-effects.js";
|
||||||
|
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||||
|
import { TYPES } from "./item.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
@ -14,6 +16,47 @@ export class RdDEmpoignade {
|
|||||||
static init() {
|
static init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static registerChatCallbacks(html) {
|
||||||
|
html.on("click", '.defense-empoignade-cac', event => {
|
||||||
|
const chatMessage = ChatUtility.getChatMessage(event);
|
||||||
|
const rollData = RdDEmpoignade.$readRollEmpoignade(chatMessage);
|
||||||
|
let defenseMode = event.currentTarget.attributes['data-defense-mode'].value
|
||||||
|
RdDEmpoignade.onDefenseEmpoignade(rollData, defenseMode, "Corps à corps", "melee")
|
||||||
|
});
|
||||||
|
html.on("click", '.defense-empoignade-esquive', event => {
|
||||||
|
const chatMessage = ChatUtility.getChatMessage(event);
|
||||||
|
const rollData = RdDEmpoignade.$readRollEmpoignade(chatMessage);
|
||||||
|
let defenseMode = event.currentTarget.attributes['data-defense-mode'].value
|
||||||
|
RdDEmpoignade.onDefenseEmpoignade(rollData, defenseMode, "Esquive", "derobee")
|
||||||
|
});
|
||||||
|
html.on("click", '.empoignade-poursuivre', event => {
|
||||||
|
let attackerId = event.currentTarget.attributes['data-attackerId'].value
|
||||||
|
let defenderId = event.currentTarget.attributes['data-defenderId'].value
|
||||||
|
RdDEmpoignade.onAttaqueEmpoignadeValidee(game.actors.get(attackerId), game.actors.get(defenderId))
|
||||||
|
});
|
||||||
|
html.on("click", '.empoignade-entrainer-sol', event => {
|
||||||
|
const chatMessage = ChatUtility.getChatMessage(event);
|
||||||
|
const rollData = RdDEmpoignade.$readRollEmpoignade(chatMessage);
|
||||||
|
RdDEmpoignade.entrainerAuSol(rollData)
|
||||||
|
ChatUtility.removeChatMessageId(chatMessage.id)
|
||||||
|
});
|
||||||
|
html.on("click", '.empoignade-projeter-sol', event => {
|
||||||
|
const chatMessage = ChatUtility.getChatMessage(event);
|
||||||
|
const rollData = RdDEmpoignade.$readRollEmpoignade(chatMessage);
|
||||||
|
RdDEmpoignade.projeterAuSol(rollData)
|
||||||
|
ChatUtility.removeChatMessageId(chatMessage.id)
|
||||||
|
});
|
||||||
|
html.on("change", '.empoignade-perte-endurance', event => {
|
||||||
|
const chatMessage = ChatUtility.getChatMessage(event);
|
||||||
|
const rollData = RdDEmpoignade.$readRollEmpoignade(chatMessage);
|
||||||
|
if (event.currentTarget.value && event.currentTarget.value != "none") {
|
||||||
|
RdDEmpoignade.perteEndurance(rollData, event.currentTarget.value)
|
||||||
|
ChatUtility.removeChatMessageId(chatMessage.id)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static checkEmpoignadeEnCours(actor) {
|
static checkEmpoignadeEnCours(actor) {
|
||||||
// TODO: autoriser la perception? la comédie/séduction?
|
// TODO: autoriser la perception? la comédie/séduction?
|
||||||
@ -24,74 +67,92 @@ export class RdDEmpoignade {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static $storeRollEmpoignade(msg, rollData) {
|
||||||
|
RdDEmpoignade.$reduceActorToIds(rollData);
|
||||||
|
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData);
|
||||||
|
}
|
||||||
|
|
||||||
|
static $reduceActorToIds(rollData) {
|
||||||
|
rollData.attacker = { id: rollData.attacker.id };
|
||||||
|
rollData.defender = { id: rollData.defender.id };
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static $readRollEmpoignade(msg) {
|
||||||
|
const rollData = ChatUtility.getMessageData(msg, 'empoignade-roll-data');
|
||||||
|
RdDEmpoignade.$replaceIdsWithActors(rollData);
|
||||||
|
return rollData
|
||||||
|
}
|
||||||
|
|
||||||
|
static $replaceIdsWithActors(rollData) {
|
||||||
|
rollData.attacker = game.actors.get(rollData.attacker.id);
|
||||||
|
rollData.defender = game.actors.get(rollData.defender.id);
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static isEmpoignadeEnCours(actor) {
|
static isEmpoignadeEnCours(actor) {
|
||||||
return actor.itemTypes['empoignade'].find(it => it.system.pointsemp > 0)
|
return actor.itemTypes[TYPES.empoignade].find(it => it.system.pointsemp > 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getEmpoignadeById(actor, id) {
|
static getEmpoignadeById(actor, id) {
|
||||||
let emp = actor.itemTypes['empoignade'].find(it => it.system.empoignadeid == id)
|
let emp = actor.itemTypes[TYPES.empoignade].find(it => it.system.empoignadeid == id)
|
||||||
return emp && duplicate(emp) || undefined;
|
return emp && duplicate(emp) || undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getEmpoignade(attacker, defender) {
|
static getEmpoignade(attacker, defender) {
|
||||||
let emp = attacker.itemTypes['empoignade'].find(it => it.system.empoigneurid == attacker.id && it.system.empoigneid == defender.id)
|
let emp = attacker.itemTypes[TYPES.empoignade].find(it =>
|
||||||
if (!emp) {
|
(it.system.empoigneurid == attacker.id && it.system.empoigneid == defender.id) ||
|
||||||
emp = attacker.itemTypes['empoignade'].find(it => it.system.empoigneurid == defender.id && it.system.empoigneid == attacker.id)
|
(it.system.empoigneurid == defender.id && it.system.empoigneid == attacker.id)
|
||||||
}
|
)
|
||||||
if (emp) {
|
if (emp) {
|
||||||
return duplicate(emp);
|
return duplicate(emp);
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getMalusTaille(emp, attacker, defender) {
|
static getMalusTaille(emp, attacker, defender) {
|
||||||
// Si pas empoigné, alors 0
|
// Si pas empoigné, alors 0
|
||||||
if (emp.system.pointsemp == 0) {
|
if (emp.system.pointsemp == 0) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
// Malus de -1 si différence de taille de 2 ou plus (p 135)
|
// p135: Malus de -1 par point de taille de différence de taille au delà de 1 (donc -2 pour une différence de 3, ...)
|
||||||
if (attacker.system.carac.taille.value < defender.system.carac.taille.value - 1) {
|
const diffTaille = attacker.system.carac.taille.value - defender.system.carac.taille.value;
|
||||||
return attacker.system.carac.taille.value - (defender.system.carac.taille.value - 1)
|
const diffTailleAbs = Math.abs(diffTaille)
|
||||||
|
const signDiff = diffTaille > 0 ? 1 : -1
|
||||||
|
|
||||||
|
if (diffTailleAbs > 2) {
|
||||||
|
return signDiff * (diffTailleAbs - 1)
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
static isActionAutorisee(mode, attacker, defender) {
|
||||||
static async onAttaqueEmpoignadeValidee(attacker, defender) {
|
const acting = RdDEmpoignade.isActionDefenseur(mode) ? defender : attacker;
|
||||||
let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
|
if (acting.getUserLevel(game.user) < CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) {
|
||||||
const isNouvelle = empoignade == undefined;
|
ui.notifications.warn(`Vous n'êtes pas autorisé à choisir l'action de ${acting.name}`)
|
||||||
empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender))
|
return false;
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
let mode = (empoignade && empoignade.system.empoigneurid == attacker.id) ? "empoigner" : "liberer"
|
static isActionDefenseur(mode) {
|
||||||
|
switch (mode) {
|
||||||
let rollData = {
|
case "liberer":
|
||||||
mode: mode,
|
case "contrer-empoigner":
|
||||||
isEmpoignade: true,
|
return 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);
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async onAttaqueEmpoignade(attacker, defender) {
|
static async onAttaqueEmpoignade(attacker, defender) {
|
||||||
|
if (!RdDEmpoignade.isActionAutorisee("empoigner", attacker, defender)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
|
let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
|
||||||
const isNouvelle = empoignade == undefined;
|
const isNouvelle = empoignade == undefined;
|
||||||
empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender))
|
empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender))
|
||||||
@ -105,6 +166,38 @@ export class RdDEmpoignade {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
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"
|
||||||
|
|
||||||
|
if (!RdDEmpoignade.isActionAutorisee(mode, attacker, defender)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let rollData = {
|
||||||
|
mode, empoignade, attacker, defender,
|
||||||
|
isEmpoignade: true,
|
||||||
|
competence: attacker.getCompetence("Corps à corps").clone(),
|
||||||
|
selectedCarac: attacker.system.carac.melee,
|
||||||
|
malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender)
|
||||||
|
}
|
||||||
|
if (attacker.isCreatureEntite()) {
|
||||||
|
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
||||||
|
}
|
||||||
|
if (empoignade.system.pointsemp >= 2) {
|
||||||
|
if (!empoignade.system.ausol) {
|
||||||
|
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-entrainer.html');
|
||||||
|
RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await RdDEmpoignade.$rollAttaqueEmpoignade(attacker, rollData, isNouvelle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async onAttaqueEmpoignadeFromItem(empoignade) {
|
static async onAttaqueEmpoignadeFromItem(empoignade) {
|
||||||
let attacker = game.actors.get(empoignade.system.empoigneurid)
|
let attacker = game.actors.get(empoignade.system.empoigneurid)
|
||||||
@ -112,6 +205,20 @@ export class RdDEmpoignade {
|
|||||||
await this.onAttaqueEmpoignadeValidee(attacker, defender)
|
await this.onAttaqueEmpoignadeValidee(attacker, defender)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async onImmobilisation(attacker, defender, empoignade) {
|
||||||
|
const rollData = {
|
||||||
|
mode: "immobilise",
|
||||||
|
empoignade, attacker, defender,
|
||||||
|
isEmpoignade: true,
|
||||||
|
competence: attacker.getCompetence("Corps à corps").clone()
|
||||||
|
}
|
||||||
|
const msg = await ChatMessage.create({
|
||||||
|
whisper: ChatUtility.getWhisperRecipientsAndGMs(attacker.name),
|
||||||
|
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-immobilise.html`, rollData)
|
||||||
|
})
|
||||||
|
RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async $rollAttaqueEmpoignade(attacker, rollData, isNouvelle = false) {
|
static async $rollAttaqueEmpoignade(attacker, rollData, isNouvelle = false) {
|
||||||
const dialog = await RdDRoll.create(attacker, rollData,
|
const dialog = await RdDRoll.create(attacker, rollData,
|
||||||
@ -119,35 +226,40 @@ export class RdDEmpoignade {
|
|||||||
{
|
{
|
||||||
name: 'jet-empoignade',
|
name: 'jet-empoignade',
|
||||||
label: 'Empoigner',
|
label: 'Empoigner',
|
||||||
callbacks: [
|
callbacks: [{ action: async (r) => await RdDEmpoignade.$onRollEmpoignade(r, isNouvelle) },]
|
||||||
{ 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);
|
dialog.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async $onRollEmpoignade(rollData, isSuccess, isNouvelle = false) {
|
static async $onRollEmpoignade(rollData, isNouvelle = false) {
|
||||||
let attacker = game.actors.get(rollData.attackerId)
|
let attacker = game.actors.get(rollData.attacker.id)
|
||||||
let defender = game.actors.get(rollData.defenderId)
|
let defender = game.actors.get(rollData.defender.id)
|
||||||
|
|
||||||
let empoignade = rollData.empoignade
|
|
||||||
empoignade.isSuccess = isSuccess;
|
|
||||||
|
|
||||||
if (isSuccess && isNouvelle) {
|
if (rollData.rolled.isSuccess && isNouvelle) {
|
||||||
|
const objectEmpoignade = rollData.empoignade.toObject();
|
||||||
// Creer l'empoignade sur attaquant/defenseur
|
// Creer l'empoignade sur attaquant/defenseur
|
||||||
await attacker.createEmbeddedDocuments('Item', [empoignade.toObject()])
|
attacker.creerObjetParMJ(objectEmpoignade);
|
||||||
await defender.createEmbeddedDocuments('Item', [empoignade.toObject()])
|
defender.creerObjetParMJ(objectEmpoignade);
|
||||||
|
}
|
||||||
|
|
||||||
|
rollData.empoignade.isSuccess = rollData.rolled.isSuccess;
|
||||||
|
if (rollData.rolled.isPart) {
|
||||||
|
rollData.particuliere = "finesse";
|
||||||
}
|
}
|
||||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-resultat.html');
|
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-resultat.html');
|
||||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async onDefenseEmpoignade(rollData, defenseMode, competenceName = "Corps à corps", carac = "melee") {
|
static async onDefenseEmpoignade(attackerRoll, mode, competenceName = "Corps à corps", carac = "melee") {
|
||||||
let attacker = game.actors.get(rollData.attackerId)
|
let attacker = game.actors.get(attackerRoll.attacker.id)
|
||||||
let defender = game.actors.get(rollData.defenderId)
|
let defender = game.actors.get(attackerRoll.defender.id)
|
||||||
|
if (!RdDEmpoignade.isActionAutorisee(mode, attacker, defender)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let empoignade = this.getEmpoignade(attacker, defender)
|
let empoignade = this.getEmpoignade(attacker, defender)
|
||||||
|
|
||||||
if (!empoignade) {
|
if (!empoignade) {
|
||||||
@ -156,18 +268,23 @@ export class RdDEmpoignade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
empoignade = duplicate(empoignade)
|
empoignade = duplicate(empoignade)
|
||||||
rollData.mode = defenseMode
|
let defenderRoll = {
|
||||||
rollData.empoignade = empoignade
|
mode, attacker, defender, empoignade, attackerRoll,
|
||||||
rollData.competence = defender.getCompetence(competenceName),
|
diffLibre: attackerRoll.diffLibre,
|
||||||
rollData.selectedCarac = defender.system.carac[carac],
|
attaqueParticuliere: attackerRoll.particuliere,
|
||||||
rollData.malusTaille = RdDEmpoignade.getMalusTaille(empoignade, defender, attacker)
|
competence: defender.getCompetence(competenceName).clone(),
|
||||||
|
surprise: defender.getSurprise(true),
|
||||||
await RdDEmpoignade.$rollDefenseEmpoignade(defender, rollData);
|
carac: defender.system.carac,
|
||||||
|
selectedCarac: defender.system.carac[carac],
|
||||||
|
malusTaille: RdDEmpoignade.getMalusTaille(empoignade, defender, attacker),
|
||||||
|
show: {}
|
||||||
|
};
|
||||||
|
await RdDEmpoignade.$rollDefenseEmpoignade(defender, defenderRoll);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async $rollDefenseEmpoignade(defender, rollData) {
|
static async $rollDefenseEmpoignade(defender, defenderRoll) {
|
||||||
const dialog = await RdDRoll.create(defender, rollData,
|
const dialog = await RdDRoll.create(defender, defenderRoll,
|
||||||
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-empoignade.html' },
|
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-empoignade.html' },
|
||||||
{
|
{
|
||||||
name: 'empoignade',
|
name: 'empoignade',
|
||||||
@ -183,7 +300,7 @@ export class RdDEmpoignade {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async $onRollContrerLiberer(rollData) {
|
static async $onRollContrerLiberer(rollData) {
|
||||||
let empoignade = rollData.empoignade
|
let empoignade = rollData.empoignade
|
||||||
|
|
||||||
if (rollData.mode == "contrer-empoigner" && !rollData.rolled.isSuccess) {
|
if (rollData.mode == "contrer-empoigner" && !rollData.rolled.isSuccess) {
|
||||||
empoignade.system.pointsemp++
|
empoignade.system.pointsemp++
|
||||||
RdDEmpoignade.$updateEtatEmpoignade(empoignade)
|
RdDEmpoignade.$updateEtatEmpoignade(empoignade)
|
||||||
@ -192,13 +309,12 @@ export class RdDEmpoignade {
|
|||||||
empoignade.system.pointsemp--
|
empoignade.system.pointsemp--
|
||||||
RdDEmpoignade.$updateEtatEmpoignade(empoignade)
|
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')
|
await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-empoignade-resultat.html')
|
||||||
|
if (empoignade.system.pointsemp >= 2) {
|
||||||
|
let msg = await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-empoignade-entrainer.html');
|
||||||
|
RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -223,16 +339,15 @@ export class RdDEmpoignade {
|
|||||||
let defender = game.actors.get(empoignade.system.empoigneid)
|
let defender = game.actors.get(empoignade.system.empoigneid)
|
||||||
let emp = RdDEmpoignade.getEmpoignadeById(defender, empoignade.system.empoignadeid)
|
let emp = RdDEmpoignade.getEmpoignadeById(defender, empoignade.system.empoignadeid)
|
||||||
await defender.deleteEmbeddedDocuments('Item', [emp._id])
|
await defender.deleteEmbeddedDocuments('Item', [emp._id])
|
||||||
|
|
||||||
//let attacker = game.actors.get(empoignade.system.empoigneurid)
|
|
||||||
//emp = RdDEmpoignade.getEmpoignadeById(attacker, empoignade.system.empoignadeid)
|
|
||||||
//await attacker.deleteEmbeddedDocuments('Item', [emp._id])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async entrainerAuSol(rollData) {
|
static async entrainerAuSol(rollData) {
|
||||||
let attacker = game.actors.get(rollData.attackerId)
|
let attacker = game.actors.get(rollData.attacker.id)
|
||||||
let defender = game.actors.get(rollData.defenderId)
|
let defender = game.actors.get(rollData.defender.id)
|
||||||
|
if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
let empoignade = this.getEmpoignade(attacker, defender)
|
let empoignade = this.getEmpoignade(attacker, defender)
|
||||||
|
|
||||||
empoignade.system.ausol = true
|
empoignade.system.ausol = true
|
||||||
@ -242,25 +357,32 @@ export class RdDEmpoignade {
|
|||||||
await defender.setEffect(STATUSES.StatusProne, true);
|
await defender.setEffect(STATUSES.StatusProne, true);
|
||||||
|
|
||||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-entrainer-sol.html');
|
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-entrainer-sol.html');
|
||||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async projeterAuSol(rollData) {
|
static async projeterAuSol(rollData) {
|
||||||
let attacker = game.actors.get(rollData.attackerId)
|
let attacker = game.actors.get(rollData.attacker.id)
|
||||||
let defender = game.actors.get(rollData.defenderId)
|
let defender = game.actors.get(rollData.defender.id)
|
||||||
|
if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
let empoignade = this.getEmpoignade(attacker, defender)
|
let empoignade = this.getEmpoignade(attacker, defender)
|
||||||
|
|
||||||
await defender.setEffect(STATUSES.StatusProne, true);
|
await defender.setEffect(STATUSES.StatusProne, true);
|
||||||
await this.$deleteEmpoignade(empoignade)
|
await this.$deleteEmpoignade(empoignade)
|
||||||
|
|
||||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-projeter-sol.html');
|
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-projeter-sol.html');
|
||||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async perteEndurance(rollData, perteMode) {
|
static async perteEndurance(rollData, perteMode) {
|
||||||
let attacker = game.actors.get(rollData.attackerId)
|
let attacker = game.actors.get(rollData.attacker.id)
|
||||||
let defender = game.actors.get(rollData.defenderId)
|
let defender = game.actors.get(rollData.defender.id)
|
||||||
|
if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
let empoignade = this.getEmpoignade(attacker, defender)
|
let empoignade = this.getEmpoignade(attacker, defender)
|
||||||
|
|
||||||
//console.log("Perte d'endurance :!!!", perteMode)
|
//console.log("Perte d'endurance :!!!", perteMode)
|
||||||
@ -278,7 +400,7 @@ export class RdDEmpoignade {
|
|||||||
await defender.santeIncDec("endurance", -(3 * Math.floor(endValue / 4)));
|
await defender.santeIncDec("endurance", -(3 * Math.floor(endValue / 4)));
|
||||||
}
|
}
|
||||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-perte-endurance.html');
|
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-perte-endurance.html');
|
||||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
import { RdDCombat } from "./rdd-combat.js";
|
|
||||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||||
import { RdDRoll } from "./rdd-roll.js";
|
import { RdDRoll } from "./rdd-roll.js";
|
||||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||||
import { Targets } from "./targets.js";
|
import { Targets } from "./targets.js";
|
||||||
|
import { TYPES } from "./item.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/* On part du principe qu'une entité démarre tjs
|
/* On part du principe qu'une entité démarre tjs
|
||||||
@ -20,9 +20,9 @@ export class RdDPossession {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static searchPossessionFromEntite(attacker, defender) {
|
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) {
|
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;
|
return poss && duplicate(poss) || undefined;
|
||||||
}
|
}
|
||||||
@ -31,39 +31,40 @@ export class RdDPossession {
|
|||||||
static async onAttaquePossession(target, attacker, competence, suitePossession = undefined) {
|
static async onAttaquePossession(target, attacker, competence, suitePossession = undefined) {
|
||||||
const defender = target.actor;
|
const defender = target.actor;
|
||||||
const fromEntite = RdDPossession.searchPossessionFromEntite(attacker, defender);
|
const fromEntite = RdDPossession.searchPossessionFromEntite(attacker, defender);
|
||||||
const isNouvelle = !suitePossession && ! fromEntite;
|
const isNouvelle = !suitePossession && !fromEntite;
|
||||||
const possession = (suitePossession ?? fromEntite ?? (await RdDPossession.createPossession(attacker, defender)));
|
const possession = (suitePossession ?? fromEntite ?? (await RdDPossession.createPossession(attacker, defender)));
|
||||||
|
|
||||||
RdDPossession.$updateEtatPossession(possession)
|
RdDPossession.$updateEtatPossession(possession)
|
||||||
|
|
||||||
let rollData = {
|
let rollData = {
|
||||||
mode: "possession",
|
mode: "attaque",
|
||||||
isECNIDefender: false,
|
isECNIDefender: false,
|
||||||
competence: competence,
|
competence: competence.clone(),
|
||||||
possession: possession,
|
possession: possession,
|
||||||
attacker: attacker,
|
attacker: attacker,
|
||||||
defender: defender,
|
defender: defender,
|
||||||
targetToken: Targets.extractTokenData(target)
|
targetToken: Targets.extractTokenData(target)
|
||||||
};
|
};
|
||||||
if (attacker.isCreatureEntite()) {
|
RdDPossession.selectCompetenceDraconicOuPossession(rollData, attacker)
|
||||||
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
|
||||||
}
|
|
||||||
|
|
||||||
await RdDPossession.$rollAttaquePossession(attacker, rollData, isNouvelle);
|
await RdDPossession.$rollAttaquePossession(attacker, rollData, isNouvelle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async onConjurerPossession(attacker, competence, possession) {
|
static async onConjurerPossession(attacker, possession) {
|
||||||
possession = duplicate(possession);
|
possession = duplicate(possession);
|
||||||
RdDPossession.$updateEtatPossession(possession)
|
RdDPossession.$updateEtatPossession(possession)
|
||||||
|
|
||||||
|
const defender = game.actors.get(possession.system.entite.actorid);
|
||||||
let rollData = {
|
let rollData = {
|
||||||
mode: "possession",
|
mode: "attaque",
|
||||||
isECNIDefender: true,
|
isECNIDefender: true,
|
||||||
competence: competence,
|
|
||||||
possession: possession,
|
possession: possession,
|
||||||
attacker: attacker,
|
attacker: attacker,
|
||||||
defender: game.actors.get(possession.system.possesseurid)
|
defender: defender,
|
||||||
};
|
};
|
||||||
|
RdDPossession.selectCompetenceDraconicOuPossession(rollData, attacker)
|
||||||
|
|
||||||
await RdDPossession.$rollAttaquePossession(attacker, rollData);
|
await RdDPossession.$rollAttaquePossession(attacker, rollData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +72,7 @@ export class RdDPossession {
|
|||||||
static async onDefensePossession(attackerId, defenderId, possessionId) {
|
static async onDefensePossession(attackerId, defenderId, possessionId) {
|
||||||
let attacker = game.actors.get(attackerId)
|
let attacker = game.actors.get(attackerId)
|
||||||
let possession = attacker?.getPossession(possessionId)
|
let possession = attacker?.getPossession(possessionId)
|
||||||
defenderId = defenderId ?? possession?.system.possesseurid ?? undefined
|
defenderId = defenderId ?? possession?.system.entite.actorid ?? undefined
|
||||||
let defender = game.actors.get(defenderId)
|
let defender = game.actors.get(defenderId)
|
||||||
possession = possession ?? defender?.getPossession(possessionId) ?? undefined;
|
possession = possession ?? defender?.getPossession(possessionId) ?? undefined;
|
||||||
|
|
||||||
@ -82,19 +83,29 @@ export class RdDPossession {
|
|||||||
possession = duplicate(possession)
|
possession = duplicate(possession)
|
||||||
// Update for draconic roll
|
// Update for draconic roll
|
||||||
let rollData = {
|
let rollData = {
|
||||||
mode: "conjuration",
|
mode: "defense",
|
||||||
isECNIDefender: defender.type == "entite",
|
isECNIDefender: defender.type == "entite",
|
||||||
possession: possession,
|
possession: possession,
|
||||||
attacker: attacker,
|
attacker: attacker,
|
||||||
defender: defender,
|
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);
|
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) {
|
static async $rollAttaquePossession(attacker, rollData, isNouvelle = false) {
|
||||||
@ -104,21 +115,22 @@ export class RdDPossession {
|
|||||||
name: 'jet-possession',
|
name: 'jet-possession',
|
||||||
label: rollData.isECNIDefender ? 'Conjurer la possession' : 'Possession',
|
label: rollData.isECNIDefender ? 'Conjurer la possession' : 'Possession',
|
||||||
callbacks: [
|
callbacks: [
|
||||||
{ condition: r => (r.rolled.isSuccess), action: async (r) => await RdDPossession.$onRollPossession(r, true, isNouvelle) },
|
{ action: async (r) => await RdDPossession.$onRollPossession(r, isNouvelle) },
|
||||||
{ condition: r => (r.rolled.isEchec), action: async (r) => await RdDPossession.$onRollPossession(r, false, isNouvelle) },
|
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async $onRollPossession(rollData, isSuccess, isNouvelle = false) {
|
static async $onRollPossession(rollData, isNouvelle = false) {
|
||||||
rollData.possession.isSuccess = isSuccess;
|
rollData.possession.isSuccess = rollData.rolled.isSuccess;
|
||||||
RdDPossession.$updateEtatPossession(rollData.possession);
|
RdDPossession.$updateEtatPossession(rollData.possession, rollData);
|
||||||
if (isNouvelle) {
|
if (isNouvelle) {
|
||||||
// Creer la possession sur le defenseur
|
// 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');
|
await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-resultat-possession.html');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,35 +139,42 @@ export class RdDPossession {
|
|||||||
const dialog = await RdDRoll.create(defender, rollData,
|
const dialog = await RdDRoll.create(defender, rollData,
|
||||||
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-possession.html' },
|
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-possession.html' },
|
||||||
{
|
{
|
||||||
name: 'conjurer',
|
name: 'possession',
|
||||||
label: 'Conjurer une Possession',
|
label: 'Conjurer une Possession',
|
||||||
callbacks: [
|
callbacks: [
|
||||||
{ action: async (r) => await RdDPossession.$onRollConjuration(r) }
|
{ action: async (r) => await RdDPossession.$onRollConjuration(r) }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async $onRollConjuration(rollData) {
|
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.rolled.isSuccess) {
|
||||||
if (rollData.isECNIDefender) {
|
if (rollData.isECNIDefender) {
|
||||||
rollData.possession.system.compteur--
|
compteur--
|
||||||
} else {
|
} 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)
|
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) {
|
if (rollData.possession.isPosseder || rollData.possession.isConjurer) {
|
||||||
// conjuration
|
// 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) {
|
static async createPossession(attacker, defender) {
|
||||||
return await Item.create({
|
return await Item.create({
|
||||||
name: "Possession en cours de " + attacker.name, type: 'possession',
|
name: "Possession en cours de " + attacker.name, type: 'possession',
|
||||||
img: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
|
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 }
|
system: {
|
||||||
},
|
description: "", typepossession: attacker.name,
|
||||||
|
possede: false,
|
||||||
|
possessionid: randomID(16),
|
||||||
|
entite: { actorid: attacker.id },
|
||||||
|
victime: { actorid: defender.id },
|
||||||
|
compteur: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
temporary: true
|
temporary: true
|
||||||
})
|
})
|
||||||
|
@ -91,13 +91,17 @@ export class RdDResolutionTable {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.html') {
|
static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.html') {
|
||||||
return await ChatUtility.createChatWithRollMode(actor?.userName ?? game.user.name, {
|
return await ChatUtility.createChatWithRollMode(RdDResolutionTable.actorChatName(actor), {
|
||||||
content: await RdDResolutionTable.buildRollDataHtml(rollData, actor, template)
|
content: await RdDResolutionTable.buildRollDataHtml(rollData, template)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static actorChatName(actor) {
|
||||||
|
return actor?.userName ?? game.user.name;
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async buildRollDataHtml(rollData, actor, template = 'chat-resultat-general.html') {
|
static async buildRollDataHtml(rollData, template = 'chat-resultat-general.html') {
|
||||||
rollData.show = rollData.show || {};
|
rollData.show = rollData.show || {};
|
||||||
return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData);
|
return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData);
|
||||||
}
|
}
|
||||||
|
@ -314,8 +314,8 @@ export class RdDRoll extends Dialog {
|
|||||||
HtmlUtility.showControlWhen(this.html.find(".use-encTotal"), rollData.ajustements.encTotal.visible && RdDCarac.isAgiliteOuDerobee(rollData.selectedCarac));
|
HtmlUtility.showControlWhen(this.html.find(".use-encTotal"), rollData.ajustements.encTotal.visible && RdDCarac.isAgiliteOuDerobee(rollData.selectedCarac));
|
||||||
HtmlUtility.showControlWhen(this.html.find(".use-surenc"), rollData.ajustements.surenc.visible && RdDCarac.isActionPhysique(rollData.selectedCarac));
|
HtmlUtility.showControlWhen(this.html.find(".use-surenc"), rollData.ajustements.surenc.visible && RdDCarac.isActionPhysique(rollData.selectedCarac));
|
||||||
HtmlUtility.showControlWhen(this.html.find(".utilisation-moral"), rollData.use.appelAuMoral);
|
HtmlUtility.showControlWhen(this.html.find(".utilisation-moral"), rollData.use.appelAuMoral);
|
||||||
HtmlUtility.showControlWhen(this.html.find(".diffMoral"), rollData.ajustements.moralTotal.used);
|
|
||||||
HtmlUtility.showControlWhen(this.html.find(".divAppelAuMoral"), rollData.use.appelAuMoral);
|
HtmlUtility.showControlWhen(this.html.find(".divAppelAuMoral"), rollData.use.appelAuMoral);
|
||||||
|
HtmlUtility.showControlWhen(this.html.find(".diffMoral"), rollData.ajustements.moralTotal.used);
|
||||||
|
|
||||||
// Mise à jour valeurs
|
// Mise à jour valeurs
|
||||||
this.html.find(".dialog-roll-title").text(this._getTitle(rollData));
|
this.html.find(".dialog-roll-title").text(this._getTitle(rollData));
|
||||||
|
@ -75,8 +75,8 @@ export class RdDTokenHud {
|
|||||||
(event) => {
|
(event) => {
|
||||||
const actionIndex = event.currentTarget.attributes['data-action-index']?.value;
|
const actionIndex = event.currentTarget.attributes['data-action-index']?.value;
|
||||||
const action = hudData.actions[actionIndex];
|
const action = hudData.actions[actionIndex];
|
||||||
if (action.action == 'conjurer') {
|
const possession = action.action == 'possession' ? combatant.actor.getPossession(action.system.possessionid) : undefined;
|
||||||
const possession = combatant.actor.getPossession(action.system.possessionid);
|
if (possession) {
|
||||||
combatant.actor.conjurerPossession(possession);
|
combatant.actor.conjurerPossession(possession);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -16,6 +16,7 @@ import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
|||||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||||
import { RdDRaretes } from "./item/raretes.js";
|
import { RdDRaretes } from "./item/raretes.js";
|
||||||
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
||||||
|
import { ExperienceLog } from "./actor/experience-log.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
// This table starts at 0 -> niveau -10
|
// This table starts at 0 -> niveau -10
|
||||||
@ -136,6 +137,7 @@ export class RdDUtility {
|
|||||||
'systems/foundryvtt-reve-de-dragon/templates/actor/blessure.hbs',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/blessure.hbs',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor/maladies-poisons.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/maladies-poisons.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor/possessions.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/possessions.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/resonances.hbs',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor/taches.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/taches.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor/taches.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/taches.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor/oeuvres.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/oeuvres.html',
|
||||||
@ -180,7 +182,7 @@ export class RdDUtility {
|
|||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-caracteristiques.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-caracteristiques.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-base-competence.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-base-competence.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-aspect-tarot.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-aspect-tarot.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-competence.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categories.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-ingredient.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-ingredient.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-parade.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-parade.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-potion.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-potion.html',
|
||||||
@ -283,6 +285,9 @@ export class RdDUtility {
|
|||||||
Handlebars.registerHelper('uniteQuantite', (itemId, actorId) => RdDUtility.getItem(itemId, actorId)?.getUniteQuantite());
|
Handlebars.registerHelper('uniteQuantite', (itemId, actorId) => RdDUtility.getItem(itemId, actorId)?.getUniteQuantite());
|
||||||
Handlebars.registerHelper('isFieldInventaireModifiable', (type, field) => RdDItem.isFieldInventaireModifiable(type, field));
|
Handlebars.registerHelper('isFieldInventaireModifiable', (type, field) => RdDItem.isFieldInventaireModifiable(type, field));
|
||||||
Handlebars.registerHelper('rarete-getChamp', (rarete, field) => RdDRaretes.getChamp(rarete, field));
|
Handlebars.registerHelper('rarete-getChamp', (rarete, field) => RdDRaretes.getChamp(rarete, field));
|
||||||
|
|
||||||
|
Handlebars.registerHelper('experienceLog-topic', topic => ExperienceLog.labelTopic(topic));
|
||||||
|
|
||||||
return loadTemplates(templatePaths);
|
return loadTemplates(templatePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,13 +339,13 @@ export class RdDUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static buildArbreDeConteneurs(conteneurs, objets) {
|
static buildArbreDeConteneurs(conteneurs, inventaires) {
|
||||||
let objetVersConteneur = {};
|
let objetVersConteneur = {};
|
||||||
// Attribution des objets aux conteneurs
|
// Attribution des objets aux conteneurs
|
||||||
for (let conteneur of conteneurs) {
|
for (let conteneur of conteneurs) {
|
||||||
conteneur.subItems = [];
|
conteneur.subItems = [];
|
||||||
for (let id of conteneur.system.contenu ?? []) {
|
for (let id of conteneur.system.contenu ?? []) {
|
||||||
let objet = objets.find(objet => (id == objet._id));
|
let objet = inventaires.find(objet => (id == objet._id));
|
||||||
if (objet) {
|
if (objet) {
|
||||||
objet.estContenu = true; // Permet de filtrer ce qui est porté dans le template
|
objet.estContenu = true; // Permet de filtrer ce qui est porté dans le template
|
||||||
objetVersConteneur[id] = conteneur._id;
|
objetVersConteneur[id] = conteneur._id;
|
||||||
@ -349,20 +354,20 @@ export class RdDUtility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let conteneur of conteneurs) {
|
for (let conteneur of conteneurs) {
|
||||||
conteneur.system.encTotal = RdDUtility.calculEncContenu(conteneur, objets);
|
conteneur.system.encTotal = RdDUtility.calculEncContenu(conteneur, inventaires);
|
||||||
}
|
}
|
||||||
return objetVersConteneur;
|
return objetVersConteneur;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static calculEncContenu(conteneur, objets) {
|
static calculEncContenu(conteneur, inventaires) {
|
||||||
const contenus = (conteneur.system.contenu ?? []).filter(id => id != undefined)
|
const contenus = (conteneur.system.contenu ?? []).filter(id => id != undefined)
|
||||||
.map(id => objets.find(it => (id == it.id)))
|
.map(id => inventaires.find(it => (id == it.id)))
|
||||||
.filter(it => it);
|
.filter(it => it);
|
||||||
let enc = Number(conteneur.system.encombrement ?? 0) * Number(conteneur.system.quantite ?? 1);
|
let enc = Number(conteneur.system.encombrement ?? 0) * Number(conteneur.system.quantite ?? 1);
|
||||||
for (let contenu of contenus) {
|
for (let contenu of contenus) {
|
||||||
if (contenu.type == 'conteneur') {
|
if (contenu.type == 'conteneur') {
|
||||||
enc += RdDUtility.calculEncContenu(contenu, objets);
|
enc += RdDUtility.calculEncContenu(contenu, inventaires);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
enc += Number(contenu.system.encombrement ?? 0) * Number(contenu.system.quantite ?? 1)
|
enc += Number(contenu.system.encombrement ?? 0) * Number(contenu.system.quantite ?? 1)
|
||||||
@ -663,6 +668,7 @@ export class RdDUtility {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async chatListeners(html) {
|
static async chatListeners(html) {
|
||||||
RdDCombat.registerChatCallbacks(html);
|
RdDCombat.registerChatCallbacks(html);
|
||||||
|
RdDEmpoignade.registerChatCallbacks(html);
|
||||||
|
|
||||||
// Gestion spécifique message passeurs
|
// Gestion spécifique message passeurs
|
||||||
html.on("click", '.tmr-passeur-coord a', event => {
|
html.on("click", '.tmr-passeur-coord a', event => {
|
||||||
@ -689,44 +695,6 @@ export class RdDUtility {
|
|||||||
RdDPossession.onDefensePossession(attackerId, defenderId, possessionId)
|
RdDPossession.onDefensePossession(attackerId, defenderId, possessionId)
|
||||||
});
|
});
|
||||||
|
|
||||||
html.on("click", '.defense-empoignade-cac', event => {
|
|
||||||
const chatMessage = ChatUtility.getChatMessage(event);
|
|
||||||
const rollData = ChatUtility.getMessageData(chatMessage, 'empoignade-roll-data');
|
|
||||||
let defenseMode = event.currentTarget.attributes['data-defense-mode'].value
|
|
||||||
RdDEmpoignade.onDefenseEmpoignade(rollData, defenseMode, "Corps à corps", "melee")
|
|
||||||
});
|
|
||||||
html.on("click", '.defense-empoignade-esquive', event => {
|
|
||||||
const chatMessage = ChatUtility.getChatMessage(event);
|
|
||||||
const rollData = ChatUtility.getMessageData(chatMessage, 'empoignade-roll-data');
|
|
||||||
let defenseMode = event.currentTarget.attributes['data-defense-mode'].value
|
|
||||||
RdDEmpoignade.onDefenseEmpoignade(rollData, defenseMode, "Esquive", "derobee")
|
|
||||||
});
|
|
||||||
html.on("click", '.empoignade-poursuivre', event => {
|
|
||||||
let attackerId = event.currentTarget.attributes['data-attackerId'].value
|
|
||||||
let defenderId = event.currentTarget.attributes['data-defenderId'].value
|
|
||||||
RdDEmpoignade.onAttaqueEmpoignadeValidee(game.actors.get(attackerId), game.actors.get(defenderId))
|
|
||||||
});
|
|
||||||
html.on("click", '.empoignade-entrainer-sol', event => {
|
|
||||||
const chatMessage = ChatUtility.getChatMessage(event);
|
|
||||||
const rollData = ChatUtility.getMessageData(chatMessage, 'empoignade-roll-data');
|
|
||||||
RdDEmpoignade.entrainerAuSol(rollData)
|
|
||||||
ChatUtility.removeChatMessageId(chatMessage.id)
|
|
||||||
});
|
|
||||||
html.on("click", '.empoignade-projeter-sol', event => {
|
|
||||||
const chatMessage = ChatUtility.getChatMessage(event);
|
|
||||||
const rollData = ChatUtility.getMessageData(chatMessage, 'empoignade-roll-data');
|
|
||||||
RdDEmpoignade.projeterAuSol(rollData)
|
|
||||||
ChatUtility.removeChatMessageId(chatMessage.id)
|
|
||||||
});
|
|
||||||
html.on("change", '.empoignade-perte-endurance', event => {
|
|
||||||
const chatMessage = ChatUtility.getChatMessage(event);
|
|
||||||
const rollData = ChatUtility.getMessageData(chatMessage, 'empoignade-roll-data');
|
|
||||||
if (event.currentTarget.value && event.currentTarget.value != "none") {
|
|
||||||
RdDEmpoignade.perteEndurance(rollData, event.currentTarget.value)
|
|
||||||
ChatUtility.removeChatMessageId(chatMessage.id)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// gestion bouton tchat Acheter
|
// gestion bouton tchat Acheter
|
||||||
html.on("click", '.button-acheter', event => {
|
html.on("click", '.button-acheter', event => {
|
||||||
const venteData = DialogItemAchat.preparerAchat(event.currentTarget);
|
const venteData = DialogItemAchat.preparerAchat(event.currentTarget);
|
||||||
@ -859,17 +827,13 @@ export class RdDUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static confirmerSuppressionSubacteur(sheet, subActor, htmlToDelete) {
|
static confirmerSuppressionSubacteur(sheet, subActor, htmlToDelete, onSuppression = ()=>{}) {
|
||||||
RdDConfirm.confirmer({
|
RdDConfirm.confirmer({
|
||||||
settingConfirmer: "confirmation-supprimer-lien-acteur",
|
settingConfirmer: "confirmation-supprimer-lien-acteur",
|
||||||
content: `<p>Etes vous certain de vouloir supprimer le lien vers ${subActor.name} ?</p>`,
|
content: `<p>Etes vous certain de vouloir supprimer le lien vers ${subActor.name} ?</p>`,
|
||||||
title: 'Confirmer la suppression',
|
title: 'Confirmer la suppression',
|
||||||
buttonLabel: 'Supprimer le lien',
|
buttonLabel: 'Supprimer le lien',
|
||||||
onAction: () => {
|
onAction: onSuppression
|
||||||
console.log('Delete : ', subActor.id);
|
|
||||||
sheet.actor.removeSubacteur(subActor.id);
|
|
||||||
RdDUtility.slideOnDelete(sheet, htmlToDelete);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import { RdDItemSort } from "./item-sort.js";
|
|||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
import { RdDBonus } from "./rdd-bonus.js";
|
import { RdDBonus } from "./rdd-bonus.js";
|
||||||
import { RdDCarac } from "./rdd-carac.js";
|
import { RdDCarac } from "./rdd-carac.js";
|
||||||
|
import { RdDPossession } from "./rdd-possession.js";
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ export const referenceAjustements = {
|
|||||||
},
|
},
|
||||||
diffLibre: {
|
diffLibre: {
|
||||||
isUsed: (rollData, actor) => rollData.diffLibre != undefined,
|
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
|
getValue: (rollData, actor) => rollData.selectedSort
|
||||||
? RdDItemSort.getDifficulte(rollData.selectedSort, rollData.diffLibre)
|
? RdDItemSort.getDifficulte(rollData.selectedSort, rollData.diffLibre)
|
||||||
: rollData.diffLibre ?? rollData.competence?.system.default_diffLibre ?? 0
|
: rollData.diffLibre ?? rollData.competence?.system.default_diffLibre ?? 0
|
||||||
@ -51,7 +52,7 @@ export const referenceAjustements = {
|
|||||||
getValue: (rollData, actor) => RdDBonus.find(rollData.surpriseDefenseur).attaque,
|
getValue: (rollData, actor) => RdDBonus.find(rollData.surpriseDefenseur).attaque,
|
||||||
},
|
},
|
||||||
etat: {
|
etat: {
|
||||||
isUsed: (rollData, actor) => !RdDCarac.isIgnoreEtatGeneral(rollData),
|
isUsed: (rollData, actor) => !RollDataAjustements.isIgnoreEtatGeneral(rollData),
|
||||||
getLabel: (rollData, actor) => 'Etat général',
|
getLabel: (rollData, actor) => 'Etat général',
|
||||||
getValue: (rollData, actor) => actor.getEtatGeneral({ ethylisme: rollData.forceAlcool != undefined })
|
getValue: (rollData, actor) => actor.getEtatGeneral({ ethylisme: rollData.forceAlcool != undefined })
|
||||||
},
|
},
|
||||||
@ -177,4 +178,11 @@ export class RollDataAjustements {
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isIgnoreEtatGeneral(rollData) {
|
||||||
|
const selectedCarac = rollData.selectedCarac;
|
||||||
|
return !selectedCarac ||
|
||||||
|
rollData.ethylisme ||
|
||||||
|
RdDCarac.isChance(selectedCarac) ||
|
||||||
|
(RdDCarac.isReve(selectedCarac) && !rollData.competence);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,6 +182,16 @@ export class RdDCalendrier extends Application {
|
|||||||
return this.timestamp.formatDate();
|
return this.timestamp.formatDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dateReel() {
|
||||||
|
return new Date().toLocaleString("sv-SE", {
|
||||||
|
year: "numeric",
|
||||||
|
month: "2-digit",
|
||||||
|
day: "2-digit",
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
isAfterIndexDate(indexDate) {
|
isAfterIndexDate(indexDate) {
|
||||||
// TODO: standardize
|
// TODO: standardize
|
||||||
return indexDate < this.timestamp.indexDate;
|
return indexDate < this.timestamp.indexDate;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { ExperienceLog, XP_TOPIC } from "../actor/experience-log.js";
|
||||||
import { ChatUtility } from "../chat-utility.js";
|
import { ChatUtility } from "../chat-utility.js";
|
||||||
import { Poetique } from "../poetique.js";
|
import { Poetique } from "../poetique.js";
|
||||||
import { RdDDice } from "../rdd-dice.js";
|
import { RdDDice } from "../rdd-dice.js";
|
||||||
@ -53,9 +54,10 @@ export class EffetsRencontre {
|
|||||||
static xp_sort_force = async (dialog, context) => {
|
static xp_sort_force = async (dialog, context) => {
|
||||||
let competence = context.competence;
|
let competence = context.competence;
|
||||||
if (competence) {
|
if (competence) {
|
||||||
const xpSort = Misc.toInt(competence.system.xp_sort) + context.rencontre.system.force;
|
const fromXpSort = Number(competence.system.xp_sort);
|
||||||
await this.updateEmbeddedDocuments("Item", [{ _id: compData._id, 'system.xp_sort': xpSort }]);
|
const toXpSort = fromXpSort + context.rencontre.system.force;
|
||||||
await this.updateExperienceLog("XP Sort", xpSort, `Rencontre d'un ${context.rencontre.name} en TMR`);
|
await this.updateEmbeddedDocuments("Item", [{ _id: compData._id, 'system.xp_sort': toXpSort }]);
|
||||||
|
await ExperienceLog.add(this, XP_TOPIC.XPSORT, fromXpSort, toXpSort, `${competence.name} - ${context.rencontre.name} en TMR`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,12 +1,13 @@
|
|||||||
{
|
{
|
||||||
"id": "foundryvtt-reve-de-dragon",
|
"id": "foundryvtt-reve-de-dragon",
|
||||||
"title": "Rêve de Dragon",
|
"title": "Rêve de Dragon",
|
||||||
"version": "10.7.13",
|
"version": "10.7.21",
|
||||||
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.7.13.zip",
|
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.7.21.zip",
|
||||||
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json",
|
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json",
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"minimum": "10",
|
"minimum": "10",
|
||||||
"verified": "10"
|
"verified": "10",
|
||||||
|
"maximum": "10"
|
||||||
},
|
},
|
||||||
"description": "Rêve de Dragon RPG for FoundryVTT",
|
"description": "Rêve de Dragon RPG for FoundryVTT",
|
||||||
"authors": [
|
"authors": [
|
||||||
|
@ -586,11 +586,11 @@
|
|||||||
},
|
},
|
||||||
"competencecreature": {
|
"competencecreature": {
|
||||||
"templates": ["description"],
|
"templates": ["description"],
|
||||||
"categorie_parade": "",
|
"carac_value": 0,
|
||||||
"niveau": 0,
|
"niveau": 0,
|
||||||
"default_diffLibre": 0,
|
"default_diffLibre": 0,
|
||||||
"categorie": "",
|
"categorie": "",
|
||||||
"carac_value": 0,
|
"categorie_parade": "",
|
||||||
"iscombat": false,
|
"iscombat": false,
|
||||||
"isnaturelle": true,
|
"isnaturelle": true,
|
||||||
"ispossession": false,
|
"ispossession": false,
|
||||||
@ -611,10 +611,17 @@
|
|||||||
"typepossession": "",
|
"typepossession": "",
|
||||||
"possede": false,
|
"possede": false,
|
||||||
"possessionid": "",
|
"possessionid": "",
|
||||||
"possesseurid": "",
|
"entite": {
|
||||||
"possedeid": "",
|
"actorid": "",
|
||||||
"compteur": 0,
|
"diffLibre": 0,
|
||||||
"date": 0
|
"finesse": false
|
||||||
|
},
|
||||||
|
"victime": {
|
||||||
|
"actorid": "",
|
||||||
|
"diffLibre": 0,
|
||||||
|
"finesse": false
|
||||||
|
},
|
||||||
|
"compteur": 0
|
||||||
},
|
},
|
||||||
"blessure": {
|
"blessure": {
|
||||||
"templates": ["temporel"],
|
"templates": ["temporel"],
|
||||||
|
@ -41,6 +41,9 @@
|
|||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/comp-creature.html"}}
|
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/comp-creature.html"}}
|
||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/comp-possession.html"}}
|
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/comp-possession.html"}}
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/resonances.hbs"}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group large-editor">
|
<div class="form-group large-editor">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{{#if recettesAlchimiques.length}}
|
{{#if recettesAlchimiques.length}}
|
||||||
<h3>Recettes Alchimiques</h3>
|
<h3>Recettes Alchimiques</h3>
|
||||||
<ul class="item-list alterne-list">
|
<ul class="item-list alterne-list">
|
||||||
{{#each recettesAlchimiques as |recette id|}}
|
{{#each (trier recettesAlchimiques) as |recette id|}}
|
||||||
<li class="item flexrow list-item" data-item-id="{{recette._id}}"><span class="competence-title recette-label item-edit"><a>{{recette.name}}</a></span>
|
<li class="item flexrow list-item" data-item-id="{{recette._id}}"><span class="competence-title recette-label item-edit"><a>{{recette.name}}</a></span>
|
||||||
<div class="item-controls flex-shrink">
|
<div class="item-controls flex-shrink">
|
||||||
<a class="item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
|
<a class="item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
{{/unless}}
|
{{/unless}}
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
{{#each system.services as |service key|}}
|
{{#each (trier system.services) as |service key|}}
|
||||||
<li class="item flexrow list-item" data-key="{{key}}">
|
<li class="item flexrow list-item" data-key="{{key}}">
|
||||||
<input {{@root.disabled}} type="text" name="services[{{key}}].name" value="{{service.name}}" data-dtype="String" />
|
<input {{@root.disabled}} type="text" name="services[{{key}}].name" value="{{service.name}}" data-dtype="String" />
|
||||||
<input {{@root.disabled}} type="checkbox" name="services[{{key}}].system.moral" {{#if service.system.moral}}checked{{/if}} />
|
<input {{@root.disabled}} type="checkbox" name="services[{{key}}].system.moral" {{#if service.system.moral}}checked{{/if}} />
|
||||||
|
@ -25,14 +25,14 @@
|
|||||||
<span class="equipement-detail">Prix (sols)</span>
|
<span class="equipement-detail">Prix (sols)</span>
|
||||||
<span class="equipement-actions">Actions</span>
|
<span class="equipement-actions">Actions</span>
|
||||||
</li>
|
</li>
|
||||||
{{#each objets as |item id|}}
|
{{#each (trier inventaires) as |item id|}}
|
||||||
{{#unless item.estContenu}}
|
{{#unless item.estContenu}}
|
||||||
{{#if (ne item.type 'conteneur')}}
|
{{#if (ne item.type 'conteneur')}}
|
||||||
{{buildLigneInventaire item ../options}}
|
{{buildLigneInventaire item ../options}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{#each conteneurs as |conteneur id|}}
|
{{#each (trier conteneurs) as |conteneur id|}}
|
||||||
{{buildLigneInventaire conteneur ../options}}
|
{{buildLigneInventaire conteneur ../options}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -9,18 +9,24 @@
|
|||||||
<input class="competence-carac creature-carac" type="text" compname="{{comp.name}}" name="{{comp._id}}.carac"
|
<input class="competence-carac creature-carac" type="text" compname="{{comp.name}}" name="{{comp._id}}.carac"
|
||||||
value="{{comp.system.carac_value}}" data-dtype="number"
|
value="{{comp.system.carac_value}}" data-dtype="number"
|
||||||
{{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
|
{{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
|
||||||
<input class="competence-value creature-niveau" type="text" compname="{{comp.name}}" name="{{comp._id}}.niveau"
|
<input class="competence-value creature-niveau" type="text" data-dtype="number"
|
||||||
value="{{numberFormat comp.system.niveau decimals=0 sign=true}}" data-dtype="number"
|
compname="{{comp.name}}" name="{{comp._id}}.niveau"
|
||||||
{{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
|
value="{{numberFormat comp.system.niveau decimals=0 sign=true}}"
|
||||||
<input class="competence-damage creature-dommages" type="text" compname="{{comp.name}}" name="{{comp._id}}.dommages"
|
{{#unless @root.options.vueDetaillee}}disabled{{/unless}}
|
||||||
value="{{numberFormat comp.system.dommages decimals=0 sign=true}}" data-dtype="number"
|
/>
|
||||||
{{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
|
<input class="competence-damage creature-dommages" type="text" data-dtype="number"
|
||||||
{{#if @root.options.vueDetaillee}}
|
{{#if comp.isdommages}}
|
||||||
<div class="item-controls">
|
compname="{{comp.name}}" name="{{comp._id}}.dommages"
|
||||||
<a class="item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
|
value="{{numberFormat comp.system.dommages decimals=0 sign=true}}"
|
||||||
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
{{#unless @root.options.vueDetaillee}}disabled{{/unless}}
|
||||||
</div>
|
{{else}}disabled{{/if}}
|
||||||
{{/if}}
|
/>
|
||||||
|
{{#if @root.options.vueDetaillee}}
|
||||||
|
<div class="item-controls">
|
||||||
|
<a class="item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
|
||||||
|
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ol>
|
</ol>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{{#if meditations.length}}
|
{{#if meditations.length}}
|
||||||
<h3>Méditations</h3>
|
<h3>Méditations</h3>
|
||||||
<ul class="item-list">
|
<ul class="item-list">
|
||||||
{{#each meditations as |meditation key|}}
|
{{#each (trier meditations) as |meditation key|}}
|
||||||
<li class="item flexrow" data-item-id="{{meditation._id}}" data-attribute="{{key}}">
|
<li class="item flexrow" data-item-id="{{meditation._id}}" data-attribute="{{key}}">
|
||||||
<img class="sheet-competence-img" src="{{meditation.img}}" />
|
<img class="sheet-competence-img" src="{{meditation.img}}" />
|
||||||
<span class="meditation-label flex-grow"><a data-item-id="{{meditation._id}}">{{meditation.name}} - {{meditation.system.competence}}</a></span>
|
<span class="meditation-label flex-grow"><a data-item-id="{{meditation._id}}">{{meditation.name}} - {{meditation.system.competence}}</a></span>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{{#if sortsReserve.length}}
|
{{#if sortsReserve.length}}
|
||||||
<h3>Sorts en Réserve</h3>
|
<h3>Sorts en Réserve</h3>
|
||||||
<ul class="item-list alterne-list">
|
<ul class="item-list alterne-list">
|
||||||
{{#each sortsReserve as |sort key|}}
|
{{#each (trier sortsReserve) as |sort key|}}
|
||||||
<li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}">
|
<li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}">
|
||||||
<img class="sheet-competence-img" src="{{sort.img}}" />
|
<img class="sheet-competence-img" src="{{sort.img}}" />
|
||||||
<span class="item-edit"><a>{{#if sort.system.echectotal}}Echec total: {{/if}}{{sort.name}} r{{sort.system.ptreve}}</a></span>
|
<span class="item-edit"><a>{{#if sort.system.echectotal}}Echec total: {{/if}}{{sort.name}} r{{sort.system.ptreve}}</a></span>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{{#if sorts.length}}
|
{{#if sorts.length}}
|
||||||
<h3>Sorts</h3>
|
<h3>Sorts</h3>
|
||||||
<ul class="item-list alterne-list">
|
<ul class="item-list alterne-list">
|
||||||
{{#each sorts as |sort key|}}
|
{{#each (trier sorts) as |sort key|}}
|
||||||
<li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}">
|
<li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}">
|
||||||
<img class="sheet-competence-img" src="{{sort.img}}" />
|
<img class="sheet-competence-img" src="{{sort.img}}" />
|
||||||
<span class="item-edit flex-grow-2">
|
<span class="item-edit flex-grow-2">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{{#if @root.options.isObserver}}
|
{{#if @root.options.isObserver}}
|
||||||
<span class="item-name"><h4>Argent et Monnaies (fortune: {{calc.fortune.sols}} sols {{calc.fortune.deniers}} deniers)</h4></span>
|
<span class="item-name"><h4>Argent et Monnaies (fortune: {{calc.fortune.sols}} sols {{calc.fortune.deniers}} deniers)</h4></span>
|
||||||
<ul class="item-list alterne-list">
|
<ul class="item-list alterne-list">
|
||||||
{{#each monnaie as |piece id|}}
|
{{#each monnaies as |piece id|}}
|
||||||
<li class="item flexrow list-item" data-item-id="{{piece._id}}">
|
<li class="item flexrow list-item" data-item-id="{{piece._id}}">
|
||||||
<img class="sheet-competence-img" src="{{piece.img}}" title="{{piece.name}}"/>
|
<img class="sheet-competence-img" src="{{piece.img}}" title="{{piece.name}}"/>
|
||||||
<span class="equipement-nom">{{piece.name}}</span>
|
<span class="equipement-nom">{{piece.name}}</span>
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
<span class="equipement-detail">Enc.</span>
|
<span class="equipement-detail">Enc.</span>
|
||||||
<span class="equipement-actions">Actions</span>
|
<span class="equipement-actions">Actions</span>
|
||||||
</li>
|
</li>
|
||||||
{{#each objets as |item id|}}
|
{{#each inventaires as |item id|}}
|
||||||
{{#unless item.estContenu}}
|
{{#unless item.estContenu}}
|
||||||
{{#if (ne item.type 'conteneur')}}
|
{{#if (ne item.type 'conteneur')}}
|
||||||
{{buildLigneInventaire item @root.options}}
|
{{buildLigneInventaire item @root.options}}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
<h3>Oeuvres diverses</h3><a class="chat-card-button creer-une-oeuvre">Créer une oeuvre</a>
|
<h3>Oeuvres diverses</h3><a class="chat-card-button creer-une-oeuvre">Créer une oeuvre</a>
|
||||||
<ul class="item-list alterne-list">
|
<ul class="item-list alterne-list">
|
||||||
{{#each chants as |chant id|}}
|
{{#each (trier chants) as |chant id|}}
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html" oeuvre=chant typeOeuvre="Chant" classOeuvre="chant-label"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html" oeuvre=chant typeOeuvre="Chant" classOeuvre="chant-label"}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{#each musiques as |musique id|}}
|
{{#each (trier musiques) as |musique id|}}
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html" oeuvre=musique typeOeuvre="Musique" classOeuvre="musique-label"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html" oeuvre=musique typeOeuvre="Musique" classOeuvre="musique-label"}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{#each danses as |danse id|}}
|
{{#each (trier danses) as |danse id|}}
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html" oeuvre=danse typeOeuvre="Danse" classOeuvre="danse-label"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html" oeuvre=danse typeOeuvre="Danse" classOeuvre="danse-label"}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{#each oeuvres as |oeuvre id|}}
|
{{#each (trier oeuvres) as |oeuvre id|}}
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html" oeuvre=oeuvre typeOeuvre=oeuvre.system.competence classOeuvre="oeuvre-label"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html" oeuvre=oeuvre typeOeuvre=oeuvre.system.competence classOeuvre="oeuvre-label"}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{#each recettescuisine as |recette id|}}
|
{{#each (trier recettescuisine) as |recette id|}}
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html" oeuvre=recette typeOeuvre="Recette de cuisine" classOeuvre="recettecuisine-label"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html" oeuvre=recette typeOeuvre="Recette de cuisine" classOeuvre="recettecuisine-label"}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
|
12
templates/actor/resonances.hbs
Normal file
12
templates/actor/resonances.hbs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<span class="item-name"><h4>Personnages accordés</h4></span>
|
||||||
|
<ul class="item-list alterne-list">
|
||||||
|
{{#each resonances as |actor|}}
|
||||||
|
<li class="item flexrow list-item" data-actor-id="{{actor.id}}">
|
||||||
|
<img class="sheet-competence-img" src="{{actor.img}}" title="{{actor.name}}"/>
|
||||||
|
<span class="subacteur-label"><a>{{actor.name}}</a></span>
|
||||||
|
<div class="flex-shrink">
|
||||||
|
<a class="resonance-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
@ -3,7 +3,7 @@
|
|||||||
<li class="item flexrow">
|
<li class="item flexrow">
|
||||||
<label class="derivee-label" for="system.compteurs.experience.value">Stress transformé</label>
|
<label class="derivee-label" for="system.compteurs.experience.value">Stress transformé</label>
|
||||||
{{#if options.vueDetaillee}}
|
{{#if options.vueDetaillee}}
|
||||||
<input type="number" name="system.compteurs.experience.value" value="{{system.compteurs.experience.value}}" data-dtype="number" size="3"/>
|
<input class="derivee-value" type="number" name="system.compteurs.experience.value" value="{{system.compteurs.experience.value}}" data-dtype="number" size="3"/>
|
||||||
{{else}}
|
{{else}}
|
||||||
<label name="system.compteurs.experience.value">{{system.compteurs.experience.value}}</label>
|
<label name="system.compteurs.experience.value">{{system.compteurs.experience.value}}</label>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
<h3>Journal d'Experience</h3>
|
<h3>Journal d'Experience</h3>
|
||||||
<div class="form-group large-editor">
|
<div class="form-group large-editor">
|
||||||
<ul class="item-list alterne-list">
|
<ul class="item-list alterne-list">
|
||||||
{{#each system.experiencelog as |xp key|}}
|
{{#each system.experiencelog as |xplog key|}}
|
||||||
<li class="experiencelog flexrow list-item" data-key="{{key}}">
|
<li class="experiencelog flexrow list-item" data-key="{{key}}">
|
||||||
<label class="flex-grow">{{xp.valeur}} {{xp.raison}}</label>
|
<label class="flex-shrink">{{xplog.valeur}} {{experienceLog-topic xplog.mode}} </label>
|
||||||
<label class="flex-shrink">{{xp.mode}}</label>
|
{{#if (or xplog.from xplog.to)}}
|
||||||
<label class="flex-shrink">{{xp.daterdd}}</label>
|
<label class="flex-grow">{{xplog.raison}}: de {{xplog.from}} à {{xplog.to}}</label>
|
||||||
<label class="flex-shrink">{{xp.datereel}}</label>
|
{{else}}
|
||||||
|
<label class="flex-grow">{{xplog.raison}}</label>
|
||||||
|
{{/if}}
|
||||||
|
<label class="flex-shrink">{{xplog.daterdd}}</label>
|
||||||
|
<label class="flex-shrink">{{xplog.datereel}}</label>
|
||||||
{{#if @root.options.isGM}}
|
{{#if @root.options.isGM}}
|
||||||
<span>
|
<span class="flex-shrink">
|
||||||
<a class="experiencelog-delete" title="Supprimer">
|
<a class="experiencelog-delete" title="Supprimer">
|
||||||
<i class="fas fa-trash"></i>
|
<i class="fas fa-trash"></i>
|
||||||
</a>
|
</a>
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" />
|
|
||||||
<h4>
|
|
||||||
{{attackerName}} a empoigné {{defenderName}}
|
|
||||||
</h4>
|
|
||||||
<hr>
|
|
||||||
<div>
|
|
||||||
|
|
||||||
<span class='chat-card-button-area'>
|
|
||||||
Au round suivant l'acquisition des 2 points d'Emp, {{attackerName}} peut faire perdre autant de points d'Endurance qu'il souhaite à {{defenderName}}
|
|
||||||
<br>
|
|
||||||
<a class='empoignade-perte-endurance chat-card-button'>
|
|
||||||
<select class='empoignade-perte-endurance'>
|
|
||||||
<option value="none">Faire perdre de l'endurance (selectionnez)</option>
|
|
||||||
<option value="end0">Endurance à 0</option>
|
|
||||||
<option value="end1">Endurance à 1</option>
|
|
||||||
<option value="endmoitie">La moitié de l'endurance</option>
|
|
||||||
<option value="endquart">Le quart de l'endurance</option>
|
|
||||||
</select>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{{#if empoignade.system.ausol}}
|
|
||||||
|
|
||||||
{{else}}
|
|
||||||
<br>
|
|
||||||
Dès l'acquisition des 2 points d'Emp, {{attackerName}} peut entraîner {{defenderName}} au sol. Les deux protagonistes restent empoignés.
|
|
||||||
<br>
|
|
||||||
<a class='empoignade-entrainer-sol chat-card-button'>
|
|
||||||
Entraîner au sol
|
|
||||||
</a>
|
|
||||||
<br>
|
|
||||||
A la fin du round ou les 2 points d'Emp sont acquis, {{attackerName}} peut projeter {{defenderName}} au sol. Les deux protagonistes ne sont plus empoignés.
|
|
||||||
<br>
|
|
||||||
<a class='empoignade-projeter-sol chat-card-button'>
|
|
||||||
Projeter au sol
|
|
||||||
</a>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
@ -1,7 +1,8 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" />
|
<img class="chat-icon" src="{{competence.img}}" />
|
||||||
<h4>
|
<h4>
|
||||||
{{attackerName}} a entraîné {{defenderName}} au sol. L'empoignade peut continuer.
|
{{attacker.name}} a entraîné {{defender.name}} au sol
|
||||||
</h4>
|
</h4>
|
||||||
<hr>
|
<hr>
|
||||||
<div>
|
<div>
|
||||||
|
L'empoignade peut continuer.
|
||||||
</div>
|
</div>
|
||||||
|
16
templates/chat-empoignade-entrainer.html
Normal file
16
templates/chat-empoignade-entrainer.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<img class="chat-icon" src="{{competence.img}}" />
|
||||||
|
<h4>
|
||||||
|
{{attacker.name}} a empoigné {{defender.name}}
|
||||||
|
</h4>
|
||||||
|
<hr>
|
||||||
|
<div>
|
||||||
|
<span class='chat-card-button-area'>
|
||||||
|
{{attacker.name}} vient d'obtenir 2 points d'Emp, et peut
|
||||||
|
entraîner {{defender.name}} au sol. Les deux protagonistes
|
||||||
|
restent empoignés.
|
||||||
|
<br>
|
||||||
|
<a class='empoignade-entrainer-sol chat-card-button'>
|
||||||
|
Entraîner au sol
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
35
templates/chat-empoignade-immobilise.html
Normal file
35
templates/chat-empoignade-immobilise.html
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<img class="chat-icon" src="{{competence.img}}" />
|
||||||
|
<h4>
|
||||||
|
{{attacker.name}} a empoigné {{defender.name}}
|
||||||
|
</h4>
|
||||||
|
<hr>
|
||||||
|
<div>
|
||||||
|
<span class='chat-card-button-area'>
|
||||||
|
<p>
|
||||||
|
{{attacker.name}} a obtenu 2 points d'Emp à la fin du round précédent, et peut:
|
||||||
|
|
||||||
|
<ul><li>
|
||||||
|
faire perdre des points d'Endurance à {{defender.name}}
|
||||||
|
<br>
|
||||||
|
<a class='empoignade-perte-endurance chat-card-button'>
|
||||||
|
<select class='empoignade-perte-endurance'>
|
||||||
|
<option value="none">Faire perdre de l'endurance (selectionnez)</option>
|
||||||
|
<option value="end0">Endurance à 0</option>
|
||||||
|
<option value="end1">Endurance à 1</option>
|
||||||
|
<option value="endmoitie">La moitié de l'endurance</option>
|
||||||
|
<option value="endquart">Le quart de l'endurance</option>
|
||||||
|
</select>
|
||||||
|
</a>
|
||||||
|
{{#if empoignade.system.ausol}}
|
||||||
|
{{else}}
|
||||||
|
</li><li>
|
||||||
|
projeter {{defender.name}} au sol. Les deux protagonistes ne sont plus empoignés.
|
||||||
|
<br>
|
||||||
|
<a class='empoignade-projeter-sol chat-card-button'>
|
||||||
|
Projeter au sol
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
</li></ul>
|
||||||
|
</p>
|
||||||
|
</span>
|
||||||
|
</div>
|
@ -1,7 +1,8 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" />
|
<img class="chat-icon" src="{{competence.img}}" />
|
||||||
<h4>
|
<h4>
|
||||||
{{attackerName}} a fait perdre de l'endurance à {{defenderName}}, qui reste immobilisé. L'empoignade peut continuer.
|
{{attacker.name}} a fait perdre de l'endurance à {{defender.name}}
|
||||||
</h4>
|
</h4>
|
||||||
<hr>
|
<hr>
|
||||||
<div>
|
<div>
|
||||||
|
{{defender.name}} reste immobilisé. L'empoignade peut continuer.
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" />
|
<img class="chat-icon" src="{{competence.img}}" />
|
||||||
<h4>
|
<h4>
|
||||||
{{attackerName}} a projeté {{defenderName}} au sol. L'empoignade est terminée et a été supprimée.
|
{{attacker.name}} a projeté {{defender.name}} au sol
|
||||||
</h4>
|
</h4>
|
||||||
<hr>
|
<hr>
|
||||||
<div>
|
<div>
|
||||||
|
L'empoignade est terminée et a été supprimée.
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" />
|
<img class="chat-icon" src="{{competence.img}}" />
|
||||||
<h4>
|
<h4>
|
||||||
|
{{log 'rollData' this}}
|
||||||
{{#if (eq mode "empoigner")}}
|
{{#if (eq mode "empoigner")}}
|
||||||
{{attackerName}} tente d'empoigner {{defenderName}}
|
{{attacker.name}} tente d'empoigner {{defender.name}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (eq mode "contrer-empoigner")}}
|
{{#if (eq mode "contrer-empoigner")}}
|
||||||
{{defenderName}} tente de contrer l'empoignade de {{attackerName}}
|
{{defender.name}} tente de contrer l'empoignade de {{attacker.name}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (eq mode "liberer")}}
|
{{#if (eq mode "liberer")}}
|
||||||
{{attackerName}} tente de se libérer de l'empoignade de {{defenderName}}
|
{{attacker.name}} tente de se libérer de l'empoignade de {{defender.name}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (eq mode "contrer-liberer")}}
|
{{#if (eq mode "contrer-liberer")}}
|
||||||
{{defenderName}} tente de contrer la libération de {{attackerName}}
|
{{defender.name}} tente de contrer la libération de {{attacker.name}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</h4>
|
</h4>
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
||||||
@ -20,7 +21,7 @@
|
|||||||
|
|
||||||
{{#if (gte empoignade.system.pointsemp 2)}}
|
{{#if (gte empoignade.system.pointsemp 2)}}
|
||||||
|
|
||||||
<br><strong>{{defenderName}} est empoigné et immobilisé par {{attackerName}} !</strong>
|
<br><strong>{{defender.name}} est empoigné et immobilisé par {{attacker.name}} !</strong>
|
||||||
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<span class='chat-card-button-area'>
|
<span class='chat-card-button-area'>
|
||||||
@ -29,16 +30,12 @@
|
|||||||
{{#if (eq mode "empoigner")}}
|
{{#if (eq mode "empoigner")}}
|
||||||
{{#if empoignade.isSuccess}}
|
{{#if empoignade.isSuccess}}
|
||||||
<a class='defense-empoignade-cac chat-card-button'
|
<a class='defense-empoignade-cac chat-card-button'
|
||||||
data-attackerId='{{attacker.id}}'
|
|
||||||
data-defenderId='{{defender.id}}'
|
|
||||||
data-diff-libre='{{diffLibre}}'
|
data-diff-libre='{{diffLibre}}'
|
||||||
data-defense-mode="contrer-empoigner">
|
data-defense-mode="contrer-empoigner">
|
||||||
Contrer l'empoignade (Corps à Corps)
|
Contrer l'empoignade (Corps à Corps)
|
||||||
</a>
|
</a>
|
||||||
{{#if (eq empoignade.system.pointsemp 0)}}
|
{{#if (eq empoignade.system.pointsemp 0)}}
|
||||||
<a class='defense-empoignade-esquive chat-card-button'
|
<a class='defense-empoignade-esquive chat-card-button'
|
||||||
data-attackerId='{{attacker.id}}'
|
|
||||||
data-defenderId='{{defender.id}}'
|
|
||||||
data-diff-libre='{{diffLibre}}'
|
data-diff-libre='{{diffLibre}}'
|
||||||
data-defense-mode="contrer-empoigner">
|
data-defense-mode="contrer-empoigner">
|
||||||
Contrer l'empoignade (Esquive)
|
Contrer l'empoignade (Esquive)
|
||||||
@ -52,8 +49,6 @@
|
|||||||
{{#if (eq mode "liberer")}}
|
{{#if (eq mode "liberer")}}
|
||||||
{{#if empoignade.isSuccess}}
|
{{#if empoignade.isSuccess}}
|
||||||
<a class='defense-empoignade-cac chat-card-button'
|
<a class='defense-empoignade-cac chat-card-button'
|
||||||
data-attackerId='{{attacker.id}}'
|
|
||||||
data-defenderId='{{defender.id}}'
|
|
||||||
data-diff-libre='{{diffLibre}}'
|
data-diff-libre='{{diffLibre}}'
|
||||||
data-defense-mode="contrer-liberer">
|
data-defense-mode="contrer-liberer">
|
||||||
Contrer la libération (Corps à Corps)
|
Contrer la libération (Corps à Corps)
|
||||||
@ -78,8 +73,7 @@
|
|||||||
La tentative de contrer la libération est un échec!
|
La tentative de contrer la libération est un échec!
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
</span>
|
||||||
<br>Points d'Emp: {{empoignade.system.pointsemp}}
|
<br>Points d'Emp: {{empoignade.system.pointsemp}}
|
||||||
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" />
|
<img class="chat-icon" src="{{competence.img}}" />
|
||||||
<h4>
|
<h4>
|
||||||
{{attackerName}} tente d'empoigner {{defenderName}}
|
{{attacker.name}} tente d'empoigner {{defender.name}}
|
||||||
</h4>
|
</h4>
|
||||||
<hr>
|
<hr>
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<span class='chat-card-button-area'>
|
<span class='chat-card-button-area'>
|
||||||
<br>
|
<br>
|
||||||
<strong>{{attacker.name}} tente d'empoigner {{defender.name}}, qui est équipé d'une arme de mêlée. {{defender.name}}
|
<strong>{{attacker.name}} tente d'empoigner {{defender.name}}, qui est équipé d'une arme de mêlée. {{defender.name}}
|
||||||
@ -16,5 +15,5 @@
|
|||||||
data-defenderId='{{defender.id}}'>
|
data-defenderId='{{defender.id}}'>
|
||||||
Poursuivre l'empoignade
|
Poursuivre l'empoignade
|
||||||
</a>
|
</a>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
@ -1,6 +1,6 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" />
|
<img class="chat-icon" src="{{competence.img}}" />
|
||||||
<h4>
|
<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}}
|
{{attacker.name}} tente de {{#if isECNIDefender}}conjurer la possession de{{else}}posséder{{/if}} {{defender.name}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{defender.name}} tente de {{#if isECNIDefender}}résister à{{else}}conjurer la possession de{{/if}} {{attacker.name}}
|
{{defender.name}} tente de {{#if isECNIDefender}}résister à{{else}}conjurer la possession de{{/if}} {{attacker.name}}
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<span class='chat-card-button-area'>
|
<span class='chat-card-button-area'>
|
||||||
<br>
|
<br>
|
||||||
{{#if (eq mode "possession")}}
|
{{#if (eq mode "attaque")}}
|
||||||
{{#if possession.isSuccess}}
|
{{#if possession.isSuccess}}
|
||||||
<a class='defense-possession chat-card-button'
|
<a class='defense-possession chat-card-button'
|
||||||
data-attackerId='{{attacker.id}}'
|
data-attackerId='{{attacker.id}}'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<form class="skill-roll-dialog">
|
<form class="skill-roll-dialog">
|
||||||
<h2>
|
<h2>
|
||||||
{{defenderName}} tente de contrer l'empoignade de {{attackerName}}
|
{{defender.name}} tente de contrer l'empoignade de {{attacker.name}}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="grid grid-2col">
|
<div class="grid grid-2col">
|
||||||
<div class="flex-group-left">
|
<div class="flex-group-left">
|
||||||
|
3
templates/enum-categorie-competencecreature.html
Normal file
3
templates/enum-categorie-competencecreature.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{{#each @root.categoriesCompetencesCreature as |categorie key|}}
|
||||||
|
<option value="{{@key}}">{{categorie.label}}</option>
|
||||||
|
{{/each}}
|
@ -1,3 +1,3 @@
|
|||||||
{{#each @root.categorieCompetences as |categorie key|}}
|
{{#each @root.categories as |categorie key|}}
|
||||||
<option value="{{@key}}">{{categorie.label}}</option>
|
<option value="{{@key}}">{{categorie.label}}</option>
|
||||||
{{/each}}
|
{{/each}}
|
@ -18,7 +18,7 @@
|
|||||||
<label for="system.categorie">Catégorie </label>
|
<label for="system.categorie">Catégorie </label>
|
||||||
<select name="system.categorie" class="categorie" data-dtype="String">
|
<select name="system.categorie" class="categorie" data-dtype="String">
|
||||||
{{#select system.categorie}}
|
{{#select system.categorie}}
|
||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-categorie-competence.html"}}
|
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-categories.html"}}
|
||||||
{{/select}}
|
{{/select}}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,50 +6,38 @@
|
|||||||
<label for="system.categorie">Catégorie</label>
|
<label for="system.categorie">Catégorie</label>
|
||||||
<select name="system.categorie" class="categorie" data-dtype="String">
|
<select name="system.categorie" class="categorie" data-dtype="String">
|
||||||
{{#select system.categorie}}
|
{{#select system.categorie}}
|
||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-categorie-competence.html"}}
|
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-categories.html"}}
|
||||||
{{/select}}
|
{{/select}}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="niveau">Valeur de Caractéristique </label>
|
<label for="niveau">Valeur de Caractéristique</label>
|
||||||
<input class="attribute-value" type="text" name="system.carac_value" value="{{system.carac_value}}" data-dtype="Number"/>
|
<input class="attribute-value" type="text" name="system.carac_value" value="{{system.carac_value}}" data-dtype="Number"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="niveau">Niveau </label>
|
<label for="niveau">Niveau</label>
|
||||||
<input class="attribute-value" type="text" name="system.niveau" value="{{system.niveau}}" data-dtype="Number"/>
|
<input class="attribute-value" type="text" name="system.niveau" value="{{system.niveau}}" data-dtype="Number"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="default_diffLibre">Difficulté libre par défaut</label>
|
<label for="default_diffLibre">Difficulté libre par défaut</label>
|
||||||
<input class="attribute-value" type="text" name="system.default_diffLibre" value="{{system.default_diffLibre}}" data-dtype="Number"/>
|
<input class="attribute-value" type="text" name="system.default_diffLibre" value="{{system.default_diffLibre}}" data-dtype="Number"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
{{#if isdommages}}
|
||||||
<label for="system.ispossession">Attaque de possession</label>
|
|
||||||
<input class="attribute-value" type="checkbox" name="system.ispossession" {{#if system.ispossession}}checked{{/if}}/>
|
|
||||||
</div>
|
|
||||||
{{#unless system.ispossession}}
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="system.iscombat">Compétence d'attaque</label>
|
|
||||||
<input class="attribute-value" type="checkbox" name="system.iscombat" {{#if system.iscombat}}checked{{/if}}/>
|
|
||||||
</div>
|
|
||||||
{{#if system.iscombat}}
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="system.isnaturelle">Arme naturelle</label>
|
|
||||||
<input class="attribute-value" type="checkbox" name="system.isnaturelle" {{#if system.isnaturelle}}checked{{/if}}/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="niveau">Dommages (+dom)</label>
|
<label for="niveau">Dommages (+dom)</label>
|
||||||
<input class="attribute-value" type="text" name="system.dommages" value="{{system.dommages}}" data-dtype="Number"/>
|
<input class="attribute-value" type="text" name="system.dommages" value="{{system.dommages}}" data-dtype="Number"/>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
{{#if isparade}}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Catégorie parade </label>
|
<label>Catégorie parade</label>
|
||||||
<select name="system.categorie_parade" id="categorie_parade" data-dtype="String">
|
<select name="system.categorie_parade" id="categorie_parade" data-dtype="String">
|
||||||
{{#select system.categorie_parade}}
|
{{#select system.categorie_parade}}
|
||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-categorie-parade.html"}}
|
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-categorie-parade.html"}}
|
||||||
{{/select}}
|
{{/select}}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
{{/unless}}
|
{{/if}}
|
||||||
|
|
||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html"}}
|
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html"}}
|
||||||
</section>
|
</section>
|
||||||
|
Loading…
Reference in New Issue
Block a user