Compare commits

..

35 Commits

Author SHA1 Message Date
81492f2857 Merge pull request 'v11.0.6 - Report v10.7.18' (#652) from VincentVk/foundryvtt-reve-de-dragon:v11 into v11
Reviewed-on: #652
2023-06-08 06:51:57 +02:00
959e751e48 Correction rendu changelog en ligne 2023-06-08 01:47:04 +02:00
b6a124b57d v11.0.6 2023-06-08 01:44:17 +02:00
db2ca945a8 Fix: la date des blessures ne marchait plus
la liste des types (pour aider à la saisie) est une idée mitigée

- ça évite les fautes d'orthographe dans les constantes de types
Mais:
- on peut oublier un type
- si le type n'est pas défini, il est undefined
  (donc risques de regressions)

Saisie de tous les types du template.
2023-06-08 01:35:06 +02:00
667d764db1 Cherry pick v10 gixes 2023-06-05 20:19:42 +02:00
4273f5f48f Fix: validation encaissement MJ 2023-06-05 20:18:05 +02:00
6c4a8eb70f Correction de liens
Quelques liens pointaient sur les icones du bazaar de forge-vtt
2023-06-05 20:17:40 +02:00
eb029e8d66 Fix affichage des "objets" dans les commerces
La confusion entre les Item "objets" et le champ formData.objets
rendait les Item "objets" indisponibles (par exemple, les vêtements)
2023-06-05 20:17:19 +02:00
9ee14b3b56 Add .db again? 2023-06-04 22:17:02 +02:00
3203fae111 Add .db again? 2023-06-04 20:53:15 +02:00
755301275b Add .db again? 2023-06-04 20:51:49 +02:00
f6d5dc9d7c Add .db again? 2023-06-04 20:49:55 +02:00
5e9b47af1f Add .db again? 2023-06-04 20:47:47 +02:00
18dfb36a78 v11 release 2023-05-29 13:47:08 +02:00
febccd508f v11 release 2023-05-29 13:40:38 +02:00
b147f8937b v11 release 2023-05-29 13:33:31 +02:00
55a93b317a v10/v11 compat 2023-05-29 08:50:13 +02:00
02a630152d v10/v11 compat 2023-05-29 08:50:08 +02:00
ad8ac0de77 v10/v11 compat 2023-05-29 08:42:16 +02:00
dceb6f026f v10/v11 compat 2023-05-29 08:41:59 +02:00
ad37ee1b8e v10/v11 compat 2023-05-29 08:38:22 +02:00
4d40e2fe59 Merge pull request 'cherry-pick changements v10' (#647) from VincentVk/foundryvtt-reve-de-dragon:v11 into v11
Reviewed-on: #647
2023-05-29 07:47:58 +02:00
9d7e57d9fb Changelog v11 2023-05-28 22:11:16 +02:00
717029e572 Tri des listes d'items 2023-05-28 22:11:16 +02:00
d6f8976298 Utilisation de la dateReel du calendrier 2023-05-28 22:11:16 +02:00
92e93cbbea Refonte du journal d'expérience
Reprise du journal d'expérience pour:
- afficher ancienne/nouvelle valeur
- la valeur du changement
- si c'est manuel / automatique
- identifier les dépenses de stress
- identifier les augmentations de compétences
- les changements des compteurs
2023-05-28 22:11:16 +02:00
994eaad9a9 Ajout des acteurs accordés aux entités 2023-05-28 22:11:16 +02:00
cfed7e2afa v10/v11 compat 2023-05-25 21:16:59 +02:00
436f9e6fa4 v10/v11 compat 2023-05-25 21:06:03 +02:00
18a50197cd v10/v11 compat 2023-05-25 21:05:43 +02:00
b6910612f8 v10/v11 compat 2023-05-25 21:04:27 +02:00
4ba1ec8a2e v10/v11 compat 2023-05-25 21:04:02 +02:00
75a0f7c322 v10/v11 compat 2023-05-25 20:40:59 +02:00
e2a9f55740 Initial commit for v11 support 2023-05-25 20:39:53 +02:00
1e0788cde8 Merge pull request 'v11' (#645) from VincentVk/foundryvtt-reve-de-dragon:v11 into v11
Reviewed-on: #645
2023-05-25 20:37:01 +02:00
47 changed files with 681 additions and 913 deletions

4
.gitignore vendored
View File

@@ -8,3 +8,7 @@ todo.md
/jsconfig.json /jsconfig.json
/package.json /package.json
/package-lock.json /package-lock.json
/packs/*/
/packs/*/CURRENT
/packs/*/LOG
/packs/*/LOCK

View File

@@ -1,63 +1,39 @@
# v10.7 - L'os de Sémolosse # v11.0
## v10.7.20 - la poigne de Sémolosse # v10.7 - L'os de Semolosse
- 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 ## v10.7.18 - le repos de Semolosse
- 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 - correction des dates de blessures qui ne marchaient plus
## v10.7.17 - le doigt du destin de Sémolosse ## v10.7.17 - le doigt du destin de Semolosse
- correction de la validation d'encaissement par le MJ - correction de la validation d'encaissement par le MJ
## v10.7.16 - la morsure de Sémolosse ## v10.7.16 - la morsure de Semolosse
- correction de l'affichage des objets suite à confusion - correction de l'affichage des objets suite à confusion
- correction de liens dans la liste des équipements - correction de liens dans la liste des équipements
## v10.7.14 - l'expérience de Sémolosse ## v10.7.14 - l'expérience de Semolosse
- Affichage des personnages accordés sur les fiches des entités - Affichage des personnages accordés sur les fiches des entités
- Refonte du journal d'expérience - Refonte du journal d'expérience
- disponible pour les personnages des joueurs - disponible pour les personnages des joueurs
- explication "comptable" des changements (dépense ou ajout, changements de niveaux, ...) - explication "comptable" des changements (dépense ou ajout, changements de niveaux, ...)
- tri alphabétique des différentes listes (sorts, recettes, oeuvres, ...) - tri alphabétique des différentes listes (sorts, recettes, oeuvres, ...)
## v10.7.13 - l'armure de Sémolosse ## v10.7.13 - l'armure de Semolosse
- 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 Sémolosse ## v10.7.11 - Le Pugilat de Semolosse
- Fix sur la projection au sol. - Fix sur la projection au sol.
## v10.7.10 - Le Pugilat de Sémolosse ## v10.7.10 - Le Pugilat de Semolosse
- 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 Sémolosse ## v10.7.9 - Le Pugilat de Semolosse
- 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é)
@@ -123,14 +99,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 Sémolosse ## v10.7.2 - les maux de dents de Semolosse
- 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 Sémolosse ## v10.7.1 - L'os de Semolosse
- 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 Sémolosse ## v10.7.0 - L'os de Semolosse
- 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

View File

@@ -1,54 +1,56 @@
{ {
"ACTOR": { "TYPES": {
"TypePersonnage": "Personnage", "Actor": {
"TypeCreature": "Créature", "Personnage": "Personnage",
"TypeEntite": "Entité de cauchemar", "Creature": "Créature",
"TypeCommerce": "Commerce", "Entite": "Entité de cauchemar",
"TypeVehicule": "Véhicule" "Commerce": "Commerce",
}, "Vehicule": "Véhicule"
"ITEM": { },
"TypeArme": "Arme", "Item": {
"TypeArmure": "Armure", "Arme": "Arme",
"TypeBlessure": "Blessure", "Armure": "Armure",
"TypeCasetmr": "TMR spéciale", "Blessure": "Blessure",
"TypeChant": "Chant", "Casetmr": "TMR spéciale",
"TypeCompetence": "Compétence", "Chant": "Chant",
"TypeCompetencecreature": "Compétence de créature", "Competence": "Compétence",
"TypeConteneur": "Conteneur", "Competencecreature": "Compétence de créature",
"TypeDanse": "Danse", "Conteneur": "Conteneur",
"TypeExtraitpoetique": "Extrait poetique", "Danse": "Danse",
"TypeFaune": "Faune", "Extraitpoetique": "Extrait poetique",
"TypeGemme": "Gemme", "Faune": "Faune",
"TypeHerbe": "Herbe", "Gemme": "Gemme",
"TypeIngredient": "Ingrédient", "Herbe": "Herbe",
"TypeJeu": "Jeu", "Ingredient": "Ingrédient",
"TypeLivre": "Livre", "Jeu": "Jeu",
"TypeMaladie": "Maladie", "Livre": "Livre",
"TypeMeditation": "Méditation", "Maladie": "Maladie",
"TypeMonnaie": "Monnaie", "Meditation": "Méditation",
"TypeMunition": "Munition", "Monnaie": "Monnaie",
"TypeMusique": "Musique", "Munition": "Munition",
"TypeNombreastral": "Nombre astral", "Musique": "Musique",
"TypeNourritureboisson": "Nourriture & boisson", "Nombreastral": "Nombre astral",
"TypeObjet": "Objet", "Nourritureboisson": "Nourriture & boisson",
"TypeOeuvre": "Oeuvre", "Objet": "Objet",
"TypeOmbre": "Ombre de Thanatos", "Oeuvre": "Oeuvre",
"TypePlante": "Plante", "Ombre": "Ombre de Thanatos",
"TypePoison": "Poison", "Plante": "Plante",
"TypePossession": "Possession", "Poison": "Poison",
"TypePotion": "Potion", "Possession": "Possession",
"TypeQueue": "Queue de Dragon", "Potion": "Potion",
"TypeRecettealchimique": "Recette alchimique", "Queue": "Queue de Dragon",
"TypeRecettecuisine": "Recette de cuisine", "Recettealchimique": "Recette alchimique",
"TypeRencontre": "Rencontre TMR", "Recettecuisine": "Recette de cuisine",
"TypeService": "Service", "Rencontre": "Rencontre TMR",
"TypeSignedraconique": "Signe draconique", "Service": "Service",
"TypeSort": "Sort", "Signedraconique": "Signe draconique",
"TypeSortreserve": "Sort en réserve", "Sort": "Sort",
"TypeSouffle": "Souffle de Dragon", "Sortreserve": "Sort en réserve",
"TypeTache": "Tâche", "Souffle": "Souffle de Dragon",
"TypeTarot": "Carte de tarot", "Tache": "Tâche",
"TypeTete": "te de Dragon" "Tarot": "Carte de tarot",
"Tete": "Tête de Dragon"
}
}, },
"EFFECT": { "EFFECT": {
"StatusStunned": "Sonné", "StatusStunned": "Sonné",

View File

@@ -38,14 +38,13 @@ 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 { 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-actuel", defaut_carac: "reve",
} }
}; };
@@ -110,7 +109,7 @@ export class RdDActor extends RdDBaseActor {
canReceive(item) { canReceive(item) {
if (this.isCreature()) { if (this.isCreature()) {
return item.type == TYPES.competencecreature || item.isInventaire(); return item.type == 'competencecreature' || item.isInventaire();
} }
if (this.isEntite()) { if (this.isEntite()) {
return item.type == 'competencecreature'; return item.type == 'competencecreature';
@@ -271,26 +270,25 @@ export class RdDActor extends RdDBaseActor {
} }
getDraconicOuPossession() { getDraconicOuPossession() {
const possession = this.items.filter(it => it.type == TYPES.competencecreature && it.system.categorie == 'possession') const possessions = this.items.filter(it => it.type == 'competencecreature' && it.system.ispossession)
.sort(Misc.descending(it => it.system.niveau)) .sort(Misc.descending(it => it.system.niveau));
.find(it => true); if (possessions.length > 0) {
if (possession) { return duplicate(possessions[0]);
return possession.clone();
} }
const draconics = [...this.getDraconicList().filter(it => it.system.niveau >= 0).map(it => it.clone()), const draconics = [...this.getDraconicList().filter(it => it.system.niveau >= 0),
POSSESSION_SANS_DRACONIC] POSSESSION_SANS_DRACONIC]
.sort(Misc.descending(it => it.system.niveau)); .sort(Misc.descending(it => it.system.niveau));
return draconics[0]; return duplicate(draconics[0]);
} }
getPossession(possessionId) { getPossession(possessionId) {
return this.items.find(it => it.type == TYPES.possession && it.system.possessionid == possessionId); return this.items.find(it => it.type == 'possession' && it.system.possessionid == possessionId);
} }
getPossessions() { getPossessions() {
return this.items.filter(it => it.type == TYPES.possession); return this.items.filter(it => it.type == 'possession');
} }
getEmpoignades() { getEmpoignades() {
return this.items.filter(it => it.type == TYPES.empoignade); return this.items.filter(it => it.type == 'empoignade');
} }
getDemiReve() { getDemiReve() {
return this.system.reve.tmrpos.coord; return this.system.reve.tmrpos.coord;
@@ -298,7 +296,7 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async verifierPotionsEnchantees() { async verifierPotionsEnchantees() {
let potionsEnchantees = this.filterItems(it => it.system.categorie.toLowerCase().includes('enchant'), 'potion'); let potionsEnchantees = this.filterItems(it => it.type == 'potion' && it.system.categorie.toLowerCase().includes('enchant'));
for (let potion of potionsEnchantees) { for (let potion of potionsEnchantees) {
if (!potion.system.prpermanent) { if (!potion.system.prpermanent) {
console.log(potion); console.log(potion);
@@ -780,7 +778,7 @@ export class RdDActor extends RdDBaseActor {
async combattreReveDeDragon(force) { async combattreReveDeDragon(force) {
let rollData = { let rollData = {
actor: this, actor: this,
competence: this.getDraconicOuPossession(), competence: duplicate(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,
@@ -961,9 +959,9 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async updateCompetence(idOrName, compValue) { async updateCompetence(idOrName, compValue) {
const competence = this.getCompetence(idOrName); let competence = this.getCompetence(idOrName);
if (competence) { if (competence) {
const toNiveau = compValue ?? RdDItemCompetence.getNiveauBase(competence.system.categorie, competence.getCategories()); let toNiveau = compValue ?? RdDItemCompetence.getNiveauBase(competence.system.categorie);
this.notifyCompetencesTronc(competence, toNiveau); this.notifyCompetencesTronc(competence, toNiveau);
const fromNiveau = competence.system.niveau; const fromNiveau = competence.system.niveau;
await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, 'system.niveau': toNiveau }]); await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, 'system.niveau': toNiveau }]);
@@ -1124,7 +1122,7 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async computeMalusArmure() { async computeMalusArmure() {
if (this.isPersonnage()) { if (this.isPersonnage()) {
const malusArmure = this.filterItems(it => it.system.equipe, 'armure') const malusArmure = this.filterItems(it => it.type == 'armure' && it.system.equipe)
.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
@@ -1297,7 +1295,8 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */ /* -------------------------------------------- */
buildTMRInnaccessible() { buildTMRInnaccessible() {
const tmrInnaccessibles = this.filterItems(it => Draconique.isCaseTMR(it) && EffetsDraconiques.isInnaccessible(it)); const tmrInnaccessibles = this.filterItems(it => Draconique.isCaseTMR(it) &&
EffetsDraconiques.isInnaccessible(it));
return tmrInnaccessibles.map(it => it.system.coord); return tmrInnaccessibles.map(it => it.system.coord);
} }
@@ -1361,46 +1360,21 @@ 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()) {
@@ -2325,14 +2299,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 == TYPES.competencecreature) { if (rollData.competence.type == 'competencecreature') {
const arme = RdDItemCompetenceCreature.armeCreature(rollData.competence) if (rollData.competence.system.iscombat && options.tryTarget && Targets.hasTargets()) {
if (arme && options.tryTarget && Targets.hasTargets()) {
Targets.selectOneToken(target => { Targets.selectOneToken(target => {
if (arme.action == "possession") { if (rollData.competence.system.ispossession) {
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)
} }
}); });
@@ -2362,7 +2336,8 @@ 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;
let tachesExistantes = findTache(nomTache); const filterTacheLecture = it => it.type == 'tache' && it.name == 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',
@@ -2378,17 +2353,13 @@ export class RdDActor extends RdDBaseActor {
} }
} }
await this.createEmbeddedDocuments('Item', [tache], options); await this.createEmbeddedDocuments('Item', [tache], options);
tachesExistantes = findTache(nomTache) tachesExistantes = this.filterItems(filterTacheLecture);
} }
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 pour lesquelles on ne peut plus faire de premiers soins? // TODO or not TODO: filtrer les blessures poour lesquels 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')
} }
@@ -3082,7 +3053,7 @@ export class RdDActor extends RdDBaseActor {
const competence = this.getCompetence(arme.system.competence) const competence = this.getCompetence(arme.system.competence)
if (competence.isCompetencePossession()) { if (competence.system.ispossession) {
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);
@@ -3162,7 +3133,9 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */ /* -------------------------------------------- */
conjurerPossession(possession) { conjurerPossession(possession) {
RdDPossession.onConjurerPossession(this, possession) // TODO: choix de la compétence de draconic ou de possession
let draconic = this.getDraconicOuPossession();
RdDPossession.onConjurerPossession(this, draconic, possession)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */

View File

@@ -3,8 +3,7 @@ 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, TYPES } from "../item.js"; import { RdDItem } from "../item.js";
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
/** /**
@@ -54,8 +53,6 @@ export class RdDBaseActorSheet extends ActorSheet {
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires); this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires);
this._appliquerRechercheObjets(formData.conteneurs, formData.inventaires); 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;
} }
@@ -128,27 +125,27 @@ export class RdDBaseActorSheet extends ActorSheet {
.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;

View File

@@ -119,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] : this.items)?.filter(filter); } filterItems(filter, type = undefined) { return type ? this.itemTypes[type]?.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) });
@@ -144,18 +144,6 @@ 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']);
@@ -260,12 +248,13 @@ 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); const itemVendu = vendeur?.getItem(achat.vente.item._id) ?? game.items.get(achat.vente.item._id) ?? achat.vente.item;
if (!itemVendu) { if (!itemVendu) {
ChatUtility.notifyUser(achat.userId, 'warn', vendeur ? `Le vendeur n'a pas plus de ${achat.vente.item.name} !`: `Impossible de retrouver: ${achat.vente.item.name} !`); ui.notifications.warn("Erreur sur achat: rien à acheter<br>Si possible, transmettez les logs de la console aux développeurs");
console.log('Erreur sur achat: rien à acheter', achat);
return; return;
} }
if (vendeur && !this.verifierQuantite(itemVendu, quantite)) { if (!this.verifierQuantite(vendeur, 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
} }
@@ -276,7 +265,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(itemVendu, quantite); const createdItemId = await acheteur.creerQuantiteItem(achat.vente.item, quantite);
await acheteur.consommerNourritureAchetee(achat, achat.vente, createdItemId); await acheteur.consommerNourritureAchetee(achat, achat.vente, createdItemId);
} }
if (cout > 0) { if (cout > 0) {
@@ -317,9 +306,9 @@ export class RdDBaseActor extends Actor {
return this.getFortune() >= cout; return this.getFortune() >= cout;
} }
verifierQuantite(item, quantiteDemande) { verifierQuantite(vendeur, item, quantiteTotal) {
const disponible = item?.getQuantite(); const disponible = vendeur?.getQuantiteDisponible(item);
return disponible == undefined || disponible >= quantiteDemande; return disponible == undefined || disponible >= quantiteTotal;
} }
async consommerNourritureAchetee(achat, vente, createdItemId) { async consommerNourritureAchetee(achat, vente, createdItemId) {

View File

@@ -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) {

View File

@@ -78,7 +78,11 @@ export class ChatUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static async createChatWithRollMode(name, chatOptions) { static async createChatWithRollMode(name, chatOptions) {
let rollMode = game.settings.get("core", "rollMode") return await ChatUtility.createChatMessage(name, game.settings.get("core", "rollMode"), chatOptions);
}
/* -------------------------------------------- */
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) {

View File

@@ -1,5 +1,4 @@
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 = {
@@ -20,7 +19,7 @@ const nomCategorieParade = {
export class RdDItemArme extends Item { export class RdDItemArme extends Item {
static isArme(item) { static isArme(item) {
return RdDItemCompetenceCreature.getCategorieAttaque(item) || item.type == 'arme'; return (item.type == 'competencecreature' && item.system.iscombat) || item.type == 'arme';
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -28,7 +27,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.armeCreature(arme); return RdDItemCompetenceCreature.armeNaturelle(arme);
} }
return RdDItemArme.mainsNues(); return RdDItemArme.mainsNues();
} }

View File

@@ -23,7 +23,7 @@ const limitesArchetypes = [
]; ];
/* -------------------------------------------- */ /* -------------------------------------------- */
const categoriesCompetences = { const categorieCompetences = {
"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 getCategories() { static getCategorieCompetences() {
return categoriesCompetences; return categorieCompetences;
}
/* -------------------------------------------- */
static getNiveauBase(category) {
return categorieCompetences[category].base;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static getLabelCategorie(category) { static getLabelCategorie(category) {
return categoriesCompetences[category].label; return categorieCompetences[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, item.getCategories()); return Number(item.system.niveau) == RdDItemCompetence.getNiveauBase(item.system.categorie);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */

View File

@@ -1,97 +1,51 @@
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() {
return categories;
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static setRollDataCreature(rollData) { static setRollDataCreature(rollData) {
rollData.competence = rollData.competence
rollData.carac = { "carac_creature": { label: rollData.competence.name, value: rollData.competence.system.carac_value } } rollData.carac = { "carac_creature": { label: rollData.competence.name, value: rollData.competence.system.carac_value } }
rollData.competence.system.defaut_carac = "carac_creature" rollData.competence.system.defaut_carac = "carac_creature"
rollData.selectedCarac = rollData.carac.carac_creature rollData.competence.system.categorie = "creature"
rollData.arme = RdDItemCompetenceCreature.armeCreature(rollData.competence); rollData.selectedCarac = rollData.carac.carac_creature
if (rollData.competence.system.iscombat) {
rollData.arme = RdDItemCompetenceCreature.armeNaturelle(rollData.competence);
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static armeCreature(item) { static armeNaturelle(competencecreature) {
const categorieAttaque = RdDItemCompetenceCreature.getCategorieAttaque(item) if (RdDItemCompetenceCreature.isCompetenceAttaque(competencecreature)) {
if (categorieAttaque != undefined) { // si c'est un Item compétence: cloner pour ne pas modifier lma compétence
// si c'est un Item compétence: cloner pour ne pas modifier la compétence let arme = (competencecreature instanceof Item) ? competencecreature.clone(): competencecreature;
let arme = item.clone(); mergeObject(arme.system,
mergeObject(arme,
{ {
action: item.isCompetencePossession() ? 'possession' : 'attaque', competence: arme.name,
system: { initiative: RdDCombatManager.calculInitiative(competencecreature.system.niveau, competencecreature.system.carac_value),
competence: arme.name, niveau: competencecreature.system.niveau,
cac: categorieAttaque == "naturelle" ? "naturelle" : "", equipe: true,
niveau: item.system.niveau, resistance: 100,
initiative: RdDCombatManager.calculInitiative(item.system.niveau, item.system.carac_value), dommagesReels: arme.system.dommages,
equipe: true, penetration: 0,
resistance: 100, force: 0,
dommagesReels: arme.system.dommages, rapide: true,
penetration: 0, cac: competencecreature.system.isnaturelle ? "naturelle" : "",
force: 0, action: 'attaque'
rapide: true,
}
}); });
return arme; return arme;
} }
console.error("RdDItemCompetenceCreature.toActionArme(", competencecreature, ") : impossible de transformer l'Item en arme");
return undefined; return undefined;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static getCategorieAttaque(item) { static isCompetenceAttaque(item) {
if (item.type == TYPES.competencecreature) { return item.type == 'competencecreature' && item.system.iscombat;
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 !== "";

View File

@@ -11,8 +11,6 @@ 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
@@ -100,13 +98,9 @@ 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.categories = this.item.getCategories() formData.categorieCompetences = RdDItemCompetence.getCategorieCompetences()
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)
@@ -255,8 +249,7 @@ export class RdDItemSheet extends ItemSheet {
event.preventDefault(); event.preventDefault();
if (this.item.isCompetence()) { if (this.item.isCompetence()) {
const categorie = event.currentTarget.value; let level = RdDItemCompetence.getNiveauBase(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);
} }

View File

@@ -6,8 +6,6 @@ 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',
@@ -220,7 +218,6 @@ 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) }
@@ -237,13 +234,6 @@ 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;
@@ -380,7 +370,7 @@ export class RdDItem extends Item {
} }
getEncTotal() { getEncTotal() {
return (this.getQuantite() ?? 0) * this.getEnc(); return (this.isService() ? 0 : this.getQuantite()) * this.getEnc();
} }
getEnc() { getEnc() {

View File

@@ -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, TYPES } from "./item.js"; import { RdDItem } 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).filter(it => it != undefined); const actorItemUpdates = computeUpdates(actor.items);
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).filter(it => it != undefined); const itemUpdates = computeUpdates(game.items);
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,6 +65,7 @@ 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"; }
@@ -369,7 +370,6 @@ 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,62 +458,6 @@ 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 [
@@ -530,8 +474,6 @@ 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(),
]; ];
} }
@@ -548,7 +490,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));

View File

@@ -1,5 +1,4 @@
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 },
@@ -28,9 +27,6 @@ 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';
} }
@@ -78,7 +74,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);

View File

@@ -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 => RdDItemCompetenceCreature.getCategorieAttaque(it)) const competence = combatant.actor.items.find(it => it.system.iscombat)
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.map(it => RdDItemCompetenceCreature.armeCreature(it)) return competences.filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
.filter(it => it != undefined); .map(it => RdDItemCompetenceCreature.armeNaturelle(it));
} }
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: 'possession', action: 'conjurer',
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 = RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']); actions = actions.concat(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 = RdDCombatManager.listActionsArmes(armes, competences, actor.system.carac); actions = actions.concat(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 == 'possession') { } else if (action.action == 'conjurer') {
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.clone(), competence: competence,
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).clone(), competence: this.defender.getCompetence(competenceParade),
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.clone(), competence: competence,
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,

View File

@@ -4,8 +4,6 @@ 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";
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -16,47 +14,6 @@ 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?
@@ -67,92 +24,74 @@ 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[TYPES.empoignade].find(it => it.system.pointsemp > 0) return actor.itemTypes['empoignade'].find(it => it.system.pointsemp > 0)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static getEmpoignadeById(actor, id) { static getEmpoignadeById(actor, id) {
let emp = actor.itemTypes[TYPES.empoignade].find(it => it.system.empoignadeid == id) let emp = actor.itemTypes['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[TYPES.empoignade].find(it => let emp = attacker.itemTypes['empoignade'].find(it => it.system.empoigneurid == attacker.id && it.system.empoigneid == defender.id)
(it.system.empoigneurid == attacker.id && it.system.empoigneid == defender.id) || if (!emp) {
(it.system.empoigneurid == defender.id && it.system.empoigneid == attacker.id) emp = attacker.itemTypes['empoignade'].find(it => 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
} }
// 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, ...) // Malus de -1 si différence de taille de 2 ou plus (p 135)
const diffTaille = attacker.system.carac.taille.value - defender.system.carac.taille.value; if (attacker.system.carac.taille.value < defender.system.carac.taille.value - 1) {
const diffTailleAbs = Math.abs(diffTaille) return attacker.system.carac.taille.value - (defender.system.carac.taille.value - 1)
const signDiff = diffTaille > 0 ? 1 : -1
if (diffTailleAbs > 2) {
return signDiff * (diffTailleAbs - 1)
} }
return 0 return 0
} }
static isActionAutorisee(mode, attacker, defender) { /* -------------------------------------------- */
const acting = RdDEmpoignade.isActionDefenseur(mode) ? defender : attacker; static async onAttaqueEmpoignadeValidee(attacker, defender) {
if (acting.getUserLevel(game.user) < CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) { let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
ui.notifications.warn(`Vous n'êtes pas autorisé à choisir l'action de ${acting.name}`) const isNouvelle = empoignade == undefined;
return false; empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender))
}
return true
}
static isActionDefenseur(mode) { let mode = (empoignade && empoignade.system.empoigneurid == attacker.id) ? "empoigner" : "liberer"
switch (mode) {
case "liberer": let rollData = {
case "contrer-empoigner": mode: mode,
return true; isEmpoignade: 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))
@@ -166,38 +105,6 @@ 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)
@@ -205,20 +112,6 @@ 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,
@@ -226,40 +119,35 @@ export class RdDEmpoignade {
{ {
name: 'jet-empoignade', name: 'jet-empoignade',
label: 'Empoigner', label: 'Empoigner',
callbacks: [{ action: async (r) => await RdDEmpoignade.$onRollEmpoignade(r, isNouvelle) },] callbacks: [
{ 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, isNouvelle = false) { static async $onRollEmpoignade(rollData, isSuccess, isNouvelle = false) {
let attacker = game.actors.get(rollData.attacker.id) let attacker = game.actors.get(rollData.attackerId)
let defender = game.actors.get(rollData.defender.id) let defender = game.actors.get(rollData.defenderId)
let empoignade = rollData.empoignade
empoignade.isSuccess = isSuccess;
if (rollData.rolled.isSuccess && isNouvelle) { if (isSuccess && isNouvelle) {
const objectEmpoignade = rollData.empoignade.toObject();
// Creer l'empoignade sur attaquant/defenseur // Creer l'empoignade sur attaquant/defenseur
attacker.creerObjetParMJ(objectEmpoignade); await attacker.createEmbeddedDocuments('Item', [empoignade.toObject()])
defender.creerObjetParMJ(objectEmpoignade); await defender.createEmbeddedDocuments('Item', [empoignade.toObject()])
}
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');
RdDEmpoignade.$storeRollEmpoignade(msg, rollData); ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async onDefenseEmpoignade(attackerRoll, mode, competenceName = "Corps à corps", carac = "melee") { static async onDefenseEmpoignade(rollData, defenseMode, competenceName = "Corps à corps", carac = "melee") {
let attacker = game.actors.get(attackerRoll.attacker.id) let attacker = game.actors.get(rollData.attackerId)
let defender = game.actors.get(attackerRoll.defender.id) let defender = game.actors.get(rollData.defenderId)
if (!RdDEmpoignade.isActionAutorisee(mode, attacker, defender)) {
return
}
let empoignade = this.getEmpoignade(attacker, defender) let empoignade = this.getEmpoignade(attacker, defender)
if (!empoignade) { if (!empoignade) {
@@ -268,23 +156,18 @@ export class RdDEmpoignade {
} }
empoignade = duplicate(empoignade) empoignade = duplicate(empoignade)
let defenderRoll = { rollData.mode = defenseMode
mode, attacker, defender, empoignade, attackerRoll, rollData.empoignade = empoignade
diffLibre: attackerRoll.diffLibre, rollData.competence = defender.getCompetence(competenceName),
attaqueParticuliere: attackerRoll.particuliere, rollData.selectedCarac = defender.system.carac[carac],
competence: defender.getCompetence(competenceName).clone(), rollData.malusTaille = RdDEmpoignade.getMalusTaille(empoignade, defender, attacker)
surprise: defender.getSurprise(true),
carac: defender.system.carac, await RdDEmpoignade.$rollDefenseEmpoignade(defender, rollData);
selectedCarac: defender.system.carac[carac],
malusTaille: RdDEmpoignade.getMalusTaille(empoignade, defender, attacker),
show: {}
};
await RdDEmpoignade.$rollDefenseEmpoignade(defender, defenderRoll);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async $rollDefenseEmpoignade(defender, defenderRoll) { static async $rollDefenseEmpoignade(defender, rollData) {
const dialog = await RdDRoll.create(defender, defenderRoll, const dialog = await RdDRoll.create(defender, rollData,
{ 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',
@@ -300,7 +183,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)
@@ -309,12 +192,13 @@ export class RdDEmpoignade {
empoignade.system.pointsemp-- empoignade.system.pointsemp--
RdDEmpoignade.$updateEtatEmpoignade(empoignade) RdDEmpoignade.$updateEtatEmpoignade(empoignade)
} }
await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-empoignade-resultat.html')
if (empoignade.system.pointsemp >= 2) { if (empoignade.system.pointsemp >= 2) {
let msg = await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-empoignade-entrainer.html'); let attacker = game.actors.get(empoignade.system.empoigneurid)
RdDEmpoignade.$storeRollEmpoignade(msg, rollData); 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')
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -339,15 +223,16 @@ 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.attacker.id) let attacker = game.actors.get(rollData.attackerId)
let defender = game.actors.get(rollData.defender.id) let defender = game.actors.get(rollData.defenderId)
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
@@ -357,32 +242,25 @@ 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');
RdDEmpoignade.$storeRollEmpoignade(msg, rollData); ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async projeterAuSol(rollData) { static async projeterAuSol(rollData) {
let attacker = game.actors.get(rollData.attacker.id) let attacker = game.actors.get(rollData.attackerId)
let defender = game.actors.get(rollData.defender.id) let defender = game.actors.get(rollData.defenderId)
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');
RdDEmpoignade.$storeRollEmpoignade(msg, rollData); ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async perteEndurance(rollData, perteMode) { static async perteEndurance(rollData, perteMode) {
let attacker = game.actors.get(rollData.attacker.id) let attacker = game.actors.get(rollData.attackerId)
let defender = game.actors.get(rollData.defender.id) let defender = game.actors.get(rollData.defenderId)
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)
@@ -400,7 +278,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');
RdDEmpoignade.$storeRollEmpoignade(msg, rollData); ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */

View File

@@ -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 == TYPES.possession && poss.system.victime.actorid == defender.id); let poss = attacker.items.find(poss => poss.type == 'possession' && poss.system.possedeid == defender.id);
if (!poss) { if (!poss) {
poss = defender.items.find(poss => poss.type == TYPES.possession && poss.system.victime.actorid == defender.id); poss = defender.items.find(poss => poss.type == 'possession' && poss.system.possedeid == defender.id);
} }
return poss && duplicate(poss) || undefined; return poss && duplicate(poss) || undefined;
} }
@@ -31,40 +31,39 @@ 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: "attaque", mode: "possession",
isECNIDefender: false, isECNIDefender: false,
competence: competence.clone(), competence: competence,
possession: possession, possession: possession,
attacker: attacker, attacker: attacker,
defender: defender, defender: defender,
targetToken: Targets.extractTokenData(target) targetToken: Targets.extractTokenData(target)
}; };
RdDPossession.selectCompetenceDraconicOuPossession(rollData, attacker) if (attacker.isCreatureEntite()) {
RdDItemCompetenceCreature.setRollDataCreature(rollData)
}
await RdDPossession.$rollAttaquePossession(attacker, rollData, isNouvelle); await RdDPossession.$rollAttaquePossession(attacker, rollData, isNouvelle);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async onConjurerPossession(attacker, possession) { static async onConjurerPossession(attacker, competence, 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: "attaque", mode: "possession",
isECNIDefender: true, isECNIDefender: true,
competence: competence,
possession: possession, possession: possession,
attacker: attacker, attacker: attacker,
defender: defender, defender: game.actors.get(possession.system.possesseurid)
}; };
RdDPossession.selectCompetenceDraconicOuPossession(rollData, attacker)
await RdDPossession.$rollAttaquePossession(attacker, rollData); await RdDPossession.$rollAttaquePossession(attacker, rollData);
} }
@@ -72,7 +71,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.entite.actorid ?? undefined defenderId = defenderId ?? possession?.system.possesseurid ?? 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;
@@ -83,29 +82,19 @@ export class RdDPossession {
possession = duplicate(possession) possession = duplicate(possession)
// Update for draconic roll // Update for draconic roll
let rollData = { let rollData = {
mode: "defense", mode: "conjuration",
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() } }
} }
RdDPossession.selectCompetenceDraconicOuPossession(rollData, defender) rollData.competence.system.defaut_carac = 'reve-actuel'
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) {
@@ -115,22 +104,21 @@ 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: [
{ action: async (r) => await RdDPossession.$onRollPossession(r, isNouvelle) }, { condition: r => (r.rolled.isSuccess), action: async (r) => await RdDPossession.$onRollPossession(r, true, isNouvelle) },
{ condition: r => (r.rolled.isEchec), action: async (r) => await RdDPossession.$onRollPossession(r, false, isNouvelle) },
] ]
}); });
dialog.render(true); dialog.render(true);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async $onRollPossession(rollData, isNouvelle = false) { static async $onRollPossession(rollData, isSuccess, isNouvelle = false) {
rollData.possession.isSuccess = rollData.rolled.isSuccess; rollData.possession.isSuccess = isSuccess;
RdDPossession.$updateEtatPossession(rollData.possession, rollData); RdDPossession.$updateEtatPossession(rollData.possession);
if (isNouvelle) { if (isNouvelle) {
// Creer la possession sur le defenseur // Creer la possession sur le defenseur
await rollData.defender.createEmbeddedDocuments('Item', [rollData.possession.toObject()]) 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');
} }
@@ -139,42 +127,35 @@ 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: 'possession', name: 'conjurer',
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 victime = game.actors.get(rollData.possession.system.victime.actorid) let actor = game.actors.get(rollData.possession.system.possedeid)
let compteur = rollData.possession.system.compteur
if (!rollData.rolled.isSuccess) { if (!rollData.rolled.isSuccess) {
if (rollData.isECNIDefender) { if (rollData.isECNIDefender) {
compteur-- rollData.possession.system.compteur--
} else { } else {
compteur++ rollData.possession.system.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
victime.deleteEmbeddedDocuments("Item", [rollData.possession._id]) actor.deleteEmbeddedDocuments("Item", [rollData.possession._id])
} }
} }
@@ -199,43 +180,13 @@ 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: { system: { description: "", typepossession: attacker.name, possede: false, possessionid: randomID(16), possesseurid: attacker.id, possedeid: defender.id, date: 0, compteur: 0 }
description: "", typepossession: attacker.name, },
possede: false,
possessionid: randomID(16),
entite: { actorid: attacker.id },
victime: { actorid: defender.id },
compteur: 0
}
},
{ {
temporary: true temporary: true
}) })

View File

@@ -91,17 +91,13 @@ 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(RdDResolutionTable.actorChatName(actor), { return await ChatUtility.createChatWithRollMode(actor?.userName ?? game.user.name, {
content: await RdDResolutionTable.buildRollDataHtml(rollData, template) content: await RdDResolutionTable.buildRollDataHtml(rollData, actor, template)
}); });
} }
static actorChatName(actor) {
return actor?.userName ?? game.user.name;
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static async buildRollDataHtml(rollData, template = 'chat-resultat-general.html') { static async buildRollDataHtml(rollData, actor, 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);
} }

View File

@@ -1052,6 +1052,7 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */ /* -------------------------------------------- */
static _computeEventOddq(origEvent) { static _computeEventOddq(origEvent) {
console.log("EVENT", origEvent)
let canvasRect = origEvent.target.getBoundingClientRect(); let canvasRect = origEvent.target.getBoundingClientRect();
let x = origEvent.clientX - canvasRect.left; let x = origEvent.clientX - canvasRect.left;
let y = origEvent.clientY - canvasRect.top; let y = origEvent.clientY - canvasRect.top;

View File

@@ -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];
const possession = action.action == 'possession' ? combatant.actor.getPossession(action.system.possessionid) : undefined; if (action.action == 'conjurer') {
if (possession) { const possession = combatant.actor.getPossession(action.system.possessionid);
combatant.actor.conjurerPossession(possession); combatant.actor.conjurerPossession(possession);
} }
else { else {

View File

@@ -182,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-categories.html', 'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-competence.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',
@@ -668,7 +668,6 @@ 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 => {
@@ -695,6 +694,44 @@ 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);

View File

@@ -5,7 +5,6 @@ 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";
@@ -31,7 +30,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 ?? RdDPossession.isDefensePossession(rollData) ? 'Imposée' : 'Libre', getLabel: (rollData, actor) => rollData.selectedSort?.name ?? rollData.attackerRoll ? '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

View File

@@ -105,10 +105,11 @@ export class RdDCalendrier extends Application {
} }
return buttons return buttons
} }
async maximize() {
/*async maximize() {
await super.maximize() await super.maximize()
this.render(true) this.render(true)
} }*/
async close() { } async close() { }
@@ -273,6 +274,7 @@ export class RdDCalendrier extends Application {
/* -------------------------------------------- */ /* -------------------------------------------- */
async rebuildNombresAstraux(showDice = HIDE_DICE) { async rebuildNombresAstraux(showDice = HIDE_DICE) {
if (Misc.isUniqueConnectedGM()) { if (Misc.isUniqueConnectedGM()) {
console.log("Astral rebuild")
let newList = []; let newList = [];
for (let i = 0; i < MAX_NOMBRE_ASTRAL; i++) { for (let i = 0; i < MAX_NOMBRE_ASTRAL; i++) {
let dayIndex = this.timestamp.indexDate + i; let dayIndex = this.timestamp.indexDate + i;

View File

@@ -1,8 +1,10 @@
import { Draconique } from "./draconique.js"; import { Draconique } from "./draconique.js";
import { PixiTMR } from "./pixi-tmr.js";
export class CarteTmr extends Draconique { export class CarteTmr extends Draconique {
constructor() { constructor() {
console.log("Sprite create 1!!!!")
super(); super();
} }

View File

@@ -91,6 +91,8 @@ export class Draconique {
coordTMR: coordTMR coordTMR: coordTMR
}; };
token[type ?? this.code()] = linkData; token[type ?? this.code()] = linkData;
console.log("SPRITE: ", token.sprite)
//PixiTMR.getImgFromCode()
pixiTMR.addTooltip(token.sprite, this.tooltip(linkData)); pixiTMR.addTooltip(token.sprite, this.tooltip(linkData));
return token; return token;
} }

View File

@@ -20,18 +20,20 @@ export class PixiTMR {
this.callbacksOnAnimate = []; this.callbacksOnAnimate = [];
} }
load( onLoad = (loader, resources) => {} ) { async load( onLoad = (loader, resources) => {} ) {
let loader = this.pixiApp.loader; // WIP - Deprecated since v7 : let loader = new PIXI.Loader();
for (const [name, img] of Object.entries(PixiTMR.textures)) { for (const [name, img] of Object.entries(PixiTMR.textures)) {
loader = loader.add(name, img); const texture = await PIXI.Assets.load(img);
let image = PIXI.Sprite.from(texture);
} }
loader.onError.add((error, reason) => { console.log("ERROR", error, reason) }); onLoad();
loader.load( (loader, resources) => { for (let onAnimate of this.callbacksOnAnimate) {
onLoad(loader, resources); onAnimate();
for (let onAnimate of this.callbacksOnAnimate) { }
onAnimate(); }
}
}); static getImgFromCode(code) {
return PixiTMR.textures[code]
} }
static register(name, img) { static register(name, img) {
@@ -44,7 +46,9 @@ export class PixiTMR {
} }
carteTmr(code) { carteTmr(code) {
const carteTmr = new PIXI.Sprite(PIXI.utils.TextureCache[code]); let img = PixiTMR.getImgFromCode(code)
const carteTmr = new PIXI.Sprite(PIXI.utils.TextureCache[img]);
console.log(code, carteTmr)
// Setup the position of the TMR // Setup the position of the TMR
carteTmr.x = 0; carteTmr.x = 0;
carteTmr.y = 0; carteTmr.y = 0;
@@ -52,7 +56,8 @@ export class PixiTMR {
carteTmr.height = 860; carteTmr.height = 860;
// Rotate around the center // Rotate around the center
carteTmr.anchor.set(0); carteTmr.anchor.set(0);
carteTmr.interactive = true; carteTmr.eventMode = 'dynamic'; // PIXI 7 : Not sure ..
// This one is deprecated ; carteTmr.interactive = true;
carteTmr.buttonMode = true; carteTmr.buttonMode = true;
carteTmr.tmrObject = this; carteTmr.tmrObject = this;
if (!this.tmrObject.viewOnly) { if (!this.tmrObject.viewOnly) {
@@ -63,9 +68,10 @@ export class PixiTMR {
} }
sprite(code, options = {}) { sprite(code, options = {}) {
const texture = PIXI.utils.TextureCache[code]; let img = PixiTMR.getImgFromCode(code)
const texture = PIXI.utils.TextureCache[img];
if (!texture) { if (!texture) {
console.error("Texture manquante", code) console.error("Texture manquante", code, PIXI.utils.TextureCache)
return; return;
} }
let sprite = new PIXI.Sprite(texture); let sprite = new PIXI.Sprite(texture);
@@ -97,7 +103,8 @@ export class PixiTMR {
sprite.tooltip = new PIXI.Text(text, tooltipStyle); sprite.tooltip = new PIXI.Text(text, tooltipStyle);
sprite.tooltip.zIndex = tmrTokenZIndex.tooltip; sprite.tooltip.zIndex = tmrTokenZIndex.tooltip;
sprite.isOver = false; sprite.isOver = false;
sprite.interactive = true; // Deprecated : sprite.interactive = true;
sprite.eventMode = 'dynamic'; // PIXI 7 To be checked
sprite.on('pointerdown', event => this.onClickBackground(event)) sprite.on('pointerdown', event => this.onClickBackground(event))
.on('pointerover', () => this.onShowTooltip(sprite)) .on('pointerover', () => this.onShowTooltip(sprite))
.on('pointerout', () => this.onHideTooltip(sprite)); .on('pointerout', () => this.onHideTooltip(sprite));

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

View File

@@ -1,13 +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.21", "version": "11.0.6",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.7.21.zip", "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-11.0.6.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/v11/system.json",
"compatibility": { "compatibility": {
"minimum": "10", "minimum": "11",
"verified": "10", "verified": "11",
"maximum": "10" "maximum": "11"
}, },
"description": "Rêve de Dragon RPG for FoundryVTT", "description": "Rêve de Dragon RPG for FoundryVTT",
"authors": [ "authors": [
@@ -69,7 +69,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/competences.db", "path": "packs/competences.db",
"type": "Item", "type": "Item",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -78,7 +81,9 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/arts-et-divertissements.db", "path": "packs/arts-et-divertissements.db",
"type": "Item", "type": "Item",
"private": false, "ownership": {
"PLAYER": "OBSERVER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -87,7 +92,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/competences-creatures.db", "path": "packs/competences-creatures.db",
"type": "Item", "type": "Item",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -96,7 +104,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/competences-entites.db", "path": "packs/competences-entites.db",
"type": "Item", "type": "Item",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -105,7 +116,9 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/sorts-oniros.db", "path": "packs/sorts-oniros.db",
"type": "Item", "type": "Item",
"private": false, "ownership": {
"PLAYER": "OBSERVER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -114,7 +127,9 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/sorts-hypnos.db", "path": "packs/sorts-hypnos.db",
"type": "Item", "type": "Item",
"private": false, "ownership": {
"PLAYER": "OBSERVER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -123,7 +138,9 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/sorts-narcos.db", "path": "packs/sorts-narcos.db",
"type": "Item", "type": "Item",
"private": false, "ownership": {
"PLAYER": "OBSERVER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -132,7 +149,9 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/sorts-thanatos.db", "path": "packs/sorts-thanatos.db",
"type": "Item", "type": "Item",
"private": false, "ownership": {
"PLAYER": "OBSERVER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -141,7 +160,9 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/equipement.db", "path": "packs/equipement.db",
"type": "Item", "type": "Item",
"private": false, "ownership": {
"PLAYER": "OBSERVER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -150,7 +171,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/maladies-et-poisons.db", "path": "packs/maladies-et-poisons.db",
"type": "Item", "type": "Item",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -159,7 +183,9 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/rappel-des-regles.db", "path": "packs/rappel-des-regles.db",
"type": "JournalEntry", "type": "JournalEntry",
"private": false, "ownership": {
"PLAYER": "OBSERVER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -168,7 +194,9 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/macros.db", "path": "packs/macros.db",
"type": "Macro", "type": "Macro",
"private": false, "ownership": {
"PLAYER": "OBSERVER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -177,7 +205,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/queues-de-dragon.db", "path": "packs/queues-de-dragon.db",
"type": "Item", "type": "Item",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -186,7 +217,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/ombres-de-thanatos.db", "path": "packs/ombres-de-thanatos.db",
"type": "Item", "type": "Item",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -195,7 +229,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/souffles-de-dragon.db", "path": "packs/souffles-de-dragon.db",
"type": "Item", "type": "Item",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -204,7 +241,9 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/tarot-draconique.db", "path": "packs/tarot-draconique.db",
"type": "Item", "type": "Item",
"private": false, "ownership": {
"PLAYER": "OBSERVER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -213,7 +252,9 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/extrait-poetique.db", "path": "packs/extrait-poetique.db",
"type": "Item", "type": "Item",
"private": false, "ownership": {
"PLAYER": "OBSERVER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -222,7 +263,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/tetes-de-dragon-pour-haut-revants.db", "path": "packs/tetes-de-dragon-pour-haut-revants.db",
"type": "Item", "type": "Item",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -231,7 +275,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/tetes-de-dragon-pour-tous-personnages.db", "path": "packs/tetes-de-dragon-pour-tous-personnages.db",
"type": "Item", "type": "Item",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -240,7 +287,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/rencontres.db", "path": "packs/rencontres.db",
"type": "Item", "type": "Item",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -249,7 +299,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/tables-diverses.db", "path": "packs/tables-diverses.db",
"type": "RollTable", "type": "RollTable",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -258,7 +311,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/animaux.db", "path": "packs/animaux.db",
"type": "Actor", "type": "Actor",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -267,7 +323,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/voyageurs.db", "path": "packs/voyageurs.db",
"type": "Actor", "type": "Actor",
"private": false, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -276,7 +335,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/vehicules.db", "path": "packs/vehicules.db",
"type": "Actor", "type": "Actor",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -285,7 +347,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/archetypes.db", "path": "packs/archetypes.db",
"type": "Actor", "type": "Actor",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -294,7 +359,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/humanoides.db", "path": "packs/humanoides.db",
"type": "Actor", "type": "Actor",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -303,7 +371,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/entites-de-cauchemar.db", "path": "packs/entites-de-cauchemar.db",
"type": "Actor", "type": "Actor",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -312,7 +383,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/invocations.db", "path": "packs/invocations.db",
"type": "Actor", "type": "Actor",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -321,7 +395,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/faune-flore-mineraux.db", "path": "packs/faune-flore-mineraux.db",
"type": "Item", "type": "Item",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -330,7 +407,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/meditations-et-ecrits.db", "path": "packs/meditations-et-ecrits.db",
"type": "Item", "type": "Item",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -339,7 +419,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/recettes-alchimiques.db", "path": "packs/recettes-alchimiques.db",
"type": "Item", "type": "Item",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
}, },
{ {
@@ -348,7 +431,10 @@
"system": "foundryvtt-reve-de-dragon", "system": "foundryvtt-reve-de-dragon",
"path": "packs/scenes-rdd.db", "path": "packs/scenes-rdd.db",
"type": "Scene", "type": "Scene",
"private": true, "ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {} "flags": {}
} }
], ],

View File

@@ -586,11 +586,11 @@
}, },
"competencecreature": { "competencecreature": {
"templates": ["description"], "templates": ["description"],
"carac_value": 0, "categorie_parade": "",
"niveau": 0, "niveau": 0,
"default_diffLibre": 0, "default_diffLibre": 0,
"categorie": "", "categorie": "",
"categorie_parade": "", "carac_value": 0,
"iscombat": false, "iscombat": false,
"isnaturelle": true, "isnaturelle": true,
"ispossession": false, "ispossession": false,
@@ -611,17 +611,10 @@
"typepossession": "", "typepossession": "",
"possede": false, "possede": false,
"possessionid": "", "possessionid": "",
"entite": { "possesseurid": "",
"actorid": "", "possedeid": "",
"diffLibre": 0, "compteur": 0,
"finesse": false "date": 0
},
"victime": {
"actorid": "",
"diffLibre": 0,
"finesse": false
},
"compteur": 0
}, },
"blessure": { "blessure": {
"templates": ["temporel"], "templates": ["temporel"],

View File

@@ -9,24 +9,18 @@
<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" data-dtype="number" <input class="competence-value creature-niveau" type="text" compname="{{comp.name}}" name="{{comp._id}}.niveau"
compname="{{comp.name}}" name="{{comp._id}}.niveau" value="{{numberFormat comp.system.niveau decimals=0 sign=true}}" data-dtype="number"
value="{{numberFormat comp.system.niveau decimals=0 sign=true}}" {{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
{{#unless @root.options.vueDetaillee}}disabled{{/unless}} <input class="competence-damage creature-dommages" type="text" compname="{{comp.name}}" name="{{comp._id}}.dommages"
/> value="{{numberFormat comp.system.dommages decimals=0 sign=true}}" data-dtype="number"
<input class="competence-damage creature-dommages" type="text" data-dtype="number" {{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
{{#if comp.isdommages}} {{#if @root.options.vueDetaillee}}
compname="{{comp.name}}" name="{{comp._id}}.dommages" <div class="item-controls">
value="{{numberFormat comp.system.dommages decimals=0 sign=true}}" <a class="item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
{{#unless @root.options.vueDetaillee}}disabled{{/unless}} <a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
{{else}}disabled{{/if}} </div>
/> {{/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>

View File

@@ -0,0 +1,39 @@
<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>

View File

@@ -1,8 +1,7 @@
<img class="chat-icon" src="{{competence.img}}" /> <img class="chat-icon" src="{{competence.img}}" />
<h4> <h4>
{{attacker.name}} a entraîné {{defender.name}} au sol {{attackerName}} a entraîné {{defenderName}} au sol. L'empoignade peut continuer.
</h4> </h4>
<hr> <hr>
<div> <div>
L'empoignade peut continuer.
</div> </div>

View File

@@ -1,16 +0,0 @@
<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>

View File

@@ -1,35 +0,0 @@
<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>

View File

@@ -1,8 +1,7 @@
<img class="chat-icon" src="{{competence.img}}" /> <img class="chat-icon" src="{{competence.img}}" />
<h4> <h4>
{{attacker.name}} a fait perdre de l'endurance à {{defender.name}} {{attackerName}} a fait perdre de l'endurance à {{defenderName}}, qui reste immobilisé. L'empoignade peut continuer.
</h4> </h4>
<hr> <hr>
<div> <div>
{{defender.name}} reste immobilisé. L'empoignade peut continuer.
</div> </div>

View File

@@ -1,8 +1,7 @@
<img class="chat-icon" src="{{competence.img}}" /> <img class="chat-icon" src="{{competence.img}}" />
<h4> <h4>
{{attacker.name}} a projeté {{defender.name}} au sol {{attackerName}} a projeté {{defenderName}} au sol. L'empoignade est terminée et a été supprimée.
</h4> </h4>
<hr> <hr>
<div> <div>
L'empoignade est terminée et a été supprimée.
</div> </div>

View File

@@ -1,17 +1,16 @@
<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")}}
{{attacker.name}} tente d'empoigner {{defender.name}} {{attackerName}} tente d'empoigner {{defenderName}}
{{/if}} {{/if}}
{{#if (eq mode "contrer-empoigner")}} {{#if (eq mode "contrer-empoigner")}}
{{defender.name}} tente de contrer l'empoignade de {{attacker.name}} {{defenderName}} tente de contrer l'empoignade de {{attackerName}}
{{/if}} {{/if}}
{{#if (eq mode "liberer")}} {{#if (eq mode "liberer")}}
{{attacker.name}} tente de se libérer de l'empoignade de {{defender.name}} {{attackerName}} tente de se libérer de l'empoignade de {{defenderName}}
{{/if}} {{/if}}
{{#if (eq mode "contrer-liberer")}} {{#if (eq mode "contrer-liberer")}}
{{defender.name}} tente de contrer la libération de {{attacker.name}} {{defenderName}} tente de contrer la libération de {{attackerName}}
{{/if}} {{/if}}
</h4> </h4>
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}} {{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
@@ -21,7 +20,7 @@
{{#if (gte empoignade.system.pointsemp 2)}} {{#if (gte empoignade.system.pointsemp 2)}}
<br><strong>{{defender.name}} est empoigné et immobilisé par {{attacker.name}} !</strong> <br><strong>{{defenderName}} est empoigné et immobilisé par {{attackerName}} !</strong>
{{else}} {{else}}
<span class='chat-card-button-area'> <span class='chat-card-button-area'>
@@ -30,12 +29,16 @@
{{#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)
@@ -49,6 +52,8 @@
{{#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)
@@ -73,7 +78,8 @@
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>

View File

@@ -1,9 +1,10 @@
<img class="chat-icon" src="{{competence.img}}" /> <img class="chat-icon" src="{{competence.img}}" />
<h4> <h4>
{{attacker.name}} tente d'empoigner {{defender.name}} {{attackerName}} tente d'empoigner {{defenderName}}
</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}}
@@ -15,5 +16,5 @@
data-defenderId='{{defender.id}}'> data-defenderId='{{defender.id}}'>
Poursuivre l'empoignade Poursuivre l'empoignade
</a> </a>
</span>
</div> </div>

View File

@@ -1,6 +1,6 @@
<img class="chat-icon" src="{{competence.img}}" /> <img class="chat-icon" src="{{competence.img}}" />
<h4> <h4>
{{#if (eq mode "attaque")}} {{#if (eq mode "possession")}}
{{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 "attaque")}} {{#if (eq mode "possession")}}
{{#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}}'

View File

@@ -1,6 +1,6 @@
<form class="skill-roll-dialog"> <form class="skill-roll-dialog">
<h2> <h2>
{{defender.name}} tente de contrer l'empoignade de {{attacker.name}} {{defenderName}} tente de contrer l'empoignade de {{attackerName}}
</h2> </h2>
<div class="grid grid-2col"> <div class="grid grid-2col">
<div class="flex-group-left"> <div class="flex-group-left">

View File

@@ -1,3 +1,3 @@
{{#each @root.categories as |categorie key|}} {{#each @root.categorieCompetences as |categorie key|}}
<option value="{{@key}}">{{categorie.label}}</option> <option value="{{@key}}">{{categorie.label}}</option>
{{/each}} {{/each}}

View File

@@ -1,3 +0,0 @@
{{#each @root.categoriesCompetencesCreature as |categorie key|}}
<option value="{{@key}}">{{categorie.label}}</option>
{{/each}}

View File

@@ -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-categories.html"}} {{>"systems/foundryvtt-reve-de-dragon/templates/enum-categorie-competence.html"}}
{{/select}} {{/select}}
</select> </select>
</div> </div>

View File

@@ -6,38 +6,50 @@
<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-categories.html"}} {{>"systems/foundryvtt-reve-de-dragon/templates/enum-categorie-competence.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>
{{#if isdommages}} <div class="form-group">
<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>
{{/if}} {{/unless}}
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html"}} {{>"systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html"}}
</section> </section>