Compare commits

..

31 Commits

Author SHA1 Message Date
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: public/foundryvtt-reve-de-dragon#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: public/foundryvtt-reve-de-dragon#645
2023-05-25 20:37:01 +02:00
36 changed files with 494 additions and 590 deletions

4
.gitignore vendored
View File

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

View File

@@ -1,24 +1,9 @@
---
# v11.0
# v10.7 - L'os de Semolosse
## v10.7.19 - les fantômes de Semolosse
- 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 Semolosse
- correction des dates de blessures qui ne marchaient plus
## v10.7.17 - le doigt du destin de Semolosse
- correction de la validation d'encaissement par le MJ
## v10.7.16 - la morsure de Semolosse
- correction de l'affichage des objets suite à confusion
- correction de liens dans la liste des équipements
## v10.7.14 - l'expérience de Semolosse
- Affichage des personnages accordés sur les fiches des entités
- Refonte du journal d'expérience

View File

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

View File

@@ -38,14 +38,13 @@ import { RdDItemBlessure } from "./item/blessure.js";
import { AppAstrologie } from "./sommeil/app-astrologie.js";
import { RdDEmpoignade } from "./rdd-empoignade.js";
import { ExperienceLog, XP_TOPIC } from "./actor/experience-log.js";
import { TYPES } from "./item.js";
const POSSESSION_SANS_DRACONIC = {
img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp',
name: 'Sans draconic',
system: {
niveau: 0,
defaut_carac: "reve-actuel",
defaut_carac: "reve",
}
};
@@ -110,7 +109,7 @@ export class RdDActor extends RdDBaseActor {
canReceive(item) {
if (this.isCreature()) {
return item.type == TYPES.competencecreature || item.isInventaire();
return item.type == 'competencecreature' || item.isInventaire();
}
if (this.isEntite()) {
return item.type == 'competencecreature';
@@ -271,16 +270,15 @@ export class RdDActor extends RdDBaseActor {
}
getDraconicOuPossession() {
const possession = this.items.filter(it => it.type == TYPES.competencecreature && it.system.categorie == 'possession')
.sort(Misc.descending(it => it.system.niveau))
.find(it=>true);
if (possession) {
return possession.clone();
const possessions = this.items.filter(it => it.type == 'competencecreature' && it.system.ispossession)
.sort(Misc.descending(it => it.system.niveau));
if (possessions.length > 0) {
return duplicate(possessions[0]);
}
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]
.sort(Misc.descending(it => it.system.niveau));
return draconics[0];
return duplicate(draconics[0]);
}
getPossession(possessionId) {
@@ -780,7 +778,7 @@ export class RdDActor extends RdDBaseActor {
async combattreReveDeDragon(force) {
let rollData = {
actor: this,
competence: this.getDraconicOuPossession(),
competence: duplicate(this.getDraconicOuPossession()),
canClose: false,
rencontre: await game.system.rdd.rencontresTMR.getReveDeDragon(force),
tmr: true,
@@ -961,9 +959,9 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
async updateCompetence(idOrName, compValue) {
const competence = this.getCompetence(idOrName);
let competence = this.getCompetence(idOrName);
if (competence) {
const toNiveau = compValue ?? RdDItemCompetence.getNiveauBase(competence.system.categorie, competence.getCategories());
let toNiveau = compValue ?? RdDItemCompetence.getNiveauBase(competence.system.categorie);
this.notifyCompetencesTronc(competence, toNiveau);
const fromNiveau = competence.system.niveau;
await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, 'system.niveau': toNiveau }]);
@@ -2301,14 +2299,14 @@ export class RdDActor extends RdDBaseActor {
carac: this.system.carac,
competence: this.getCompetence(idOrName)
}
if (rollData.competence.type == TYPES.competencecreature) {
const arme = RdDItemCompetenceCreature.armeCreature(rollData.competence)
if (arme && options.tryTarget && Targets.hasTargets()) {
if (rollData.competence.type == 'competencecreature') {
if (rollData.competence.system.iscombat && options.tryTarget && Targets.hasTargets()) {
Targets.selectOneToken(target => {
if (arme.action == "possession") {
if (rollData.competence.system.ispossession) {
RdDPossession.onAttaquePossession(target, this, rollData.competence)
}
else {
const arme = RdDItemCompetenceCreature.armeNaturelle(rollData.competence)
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme)
}
});
@@ -3055,7 +3053,7 @@ export class RdDActor extends RdDBaseActor {
const competence = this.getCompetence(arme.system.competence)
if (competence.isCompetencePossession()) {
if (competence.system.ispossession) {
return RdDPossession.onAttaquePossession(target, this, competence);
}
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme);
@@ -3135,7 +3133,9 @@ export class RdDActor extends RdDBaseActor {
/* -------------------------------------------- */
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 { RdDSheetUtility } from "../rdd-sheet-utility.js";
import { Monnaie } from "../item-monnaie.js";
import { RdDItem, TYPES } from "../item.js";
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
import { RdDItem } from "../item.js";
/* -------------------------------------------- */
/**
@@ -54,8 +53,6 @@ export class RdDBaseActorSheet extends ActorSheet {
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires);
this._appliquerRechercheObjets(formData.conteneurs, formData.inventaires);
formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs);
formData.competences.filter(it => it.type == TYPES.competencecreature)
.forEach(it => it.isdommages = RdDItemCompetenceCreature.isDommages(it))
return formData;
}
@@ -128,27 +125,27 @@ export class RdDBaseActorSheet extends ActorSheet {
.map(t => Misc.arrayOrEmpty(itemTypes[t]))
.reduce((a, b) => a.concat(b), [])
.sort(Misc.ascending(it => it.name));
}
/* -------------------------------------------- */ /** @override */
activateListeners(html) {
super.activateListeners(html);
this.html = html;
this.html.find('.conteneur-name a').click(async event => {
RdDUtility.toggleAfficheContenu(this.getItemId(event));
this.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('.actor-montrer').click(async event => this.actor.postActorToChat());
this.html.find('.recherche')
.each((index, field) => {
this._rechercheSelectArea(field);
})
.keyup(async event => this._rechercherKeyup(event))
.change(async event => this._rechercherKeyup(event));
this.html.find('.recherche').prop("disabled", false);
}
/* -------------------------------------------- */ /** @override */
activateListeners(html) {
super.activateListeners(html);
this.html = html;
this.html.find('.conteneur-name a').click(async event => {
RdDUtility.toggleAfficheContenu(this.getItemId(event));
this.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('.actor-montrer').click(async event => this.actor.postActorToChat());
this.html.find('.recherche')
.each((index, field) => {
this._rechercheSelectArea(field);
})
.keyup(async event => this._rechercherKeyup(event))
.change(async event => this._rechercherKeyup(event));
this.html.find('.recherche').prop( "disabled", false );
// Everything below here is only needed if the sheet is editable
if (!this.options.editable) return;

View File

@@ -248,12 +248,13 @@ export class RdDBaseActor extends Actor {
const vendeur = achat.vendeurId ? game.actors.get(achat.vendeurId) : undefined;
const acheteur = achat.acheteurId ? game.actors.get(achat.acheteurId) : undefined;
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) {
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;
}
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} !`);
return
}
@@ -264,7 +265,7 @@ export class RdDBaseActor extends Actor {
await this.decrementerVente(vendeur, itemVendu, quantite, cout);
if (acheteur) {
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);
}
if (cout > 0) {
@@ -305,9 +306,9 @@ export class RdDBaseActor extends Actor {
return this.getFortune() >= cout;
}
verifierQuantite(item, quantiteDemande) {
const disponible = item?.getQuantite();
return disponible == undefined || disponible >= quantiteDemande;
verifierQuantite(vendeur, item, quantiteTotal) {
const disponible = vendeur?.getQuantiteDisponible(item);
return disponible == undefined || disponible >= quantiteTotal;
}
async consommerNourritureAchetee(achat, vente, createdItemId) {

View File

@@ -22,7 +22,7 @@ export class RdDCommerce extends RdDBaseActor {
}
getQuantiteDisponible(item) {
return (this.system.illimite || item?.isService()) ? undefined : item.getQuantite();
return this.system.illimite || item.isService() ? undefined : item.getQuantite();
}
verifierFortune(cout) {

View File

@@ -1,5 +1,4 @@
import { RdDItemCompetenceCreature } from "./item-competencecreature.js"
import { TYPES } from "./item.js";
import { RdDCombatManager } from "./rdd-combat.js";
const nomCategorieParade = {
@@ -20,7 +19,7 @@ const nomCategorieParade = {
export class RdDItemArme extends 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 : '') {
case 'arme': return arme;
case 'competencecreature':
return RdDItemCompetenceCreature.armeCreature(arme);
return RdDItemCompetenceCreature.armeNaturelle(arme);
}
return RdDItemArme.mainsNues();
}

View File

@@ -23,7 +23,7 @@ const limitesArchetypes = [
];
/* -------------------------------------------- */
const categoriesCompetences = {
const categorieCompetences = {
"generale": { base: -4, label: "Générales" },
"particuliere": { base: -8, label: "Particulières" },
"specialisee": { base: -11, label: "Spécialisées" },
@@ -49,16 +49,16 @@ const competence_xp_cumul = _buildCumulXP();
export class RdDItemCompetence extends Item {
/* -------------------------------------------- */
static getCategories() {
return categoriesCompetences;
static getCategorieCompetences() {
return categorieCompetences;
}
/* -------------------------------------------- */
static getNiveauBase(category) {
return categorieCompetences[category].base;
}
/* -------------------------------------------- */
static getLabelCategorie(category) {
return categoriesCompetences[category].label;
}
/* -------------------------------------------- */
static getNiveauBase(category, categories = categoriesCompetences) {
return categories[category]?.base ?? 0;
return categorieCompetences[category].label;
}
/* -------------------------------------------- */
@@ -192,7 +192,7 @@ export class RdDItemCompetence extends 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";
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 {
static getCategories() {
return categories;
}
/* -------------------------------------------- */
static setRollDataCreature(rollData) {
rollData.competence = rollData.competence
rollData.carac = { "carac_creature": { label: rollData.competence.name, value: rollData.competence.system.carac_value } }
rollData.competence.system.defaut_carac = "carac_creature"
rollData.selectedCarac = rollData.carac.carac_creature
rollData.arme = RdDItemCompetenceCreature.armeCreature(rollData.competence);
rollData.competence.system.categorie = "creature"
rollData.selectedCarac = rollData.carac.carac_creature
if (rollData.competence.system.iscombat) {
rollData.arme = RdDItemCompetenceCreature.armeNaturelle(rollData.competence);
}
}
/* -------------------------------------------- */
static armeCreature(item) {
const categorieAttaque = RdDItemCompetenceCreature.getCategorieAttaque(item)
if (categorieAttaque != undefined) {
// si c'est un Item compétence: cloner pour ne pas modifier la compétence
let arme = item.clone();
mergeObject(arme,
static armeNaturelle(competencecreature) {
if (RdDItemCompetenceCreature.isCompetenceAttaque(competencecreature)) {
// si c'est un Item compétence: cloner pour ne pas modifier lma compétence
let arme = (competencecreature instanceof Item) ? competencecreature.clone(): competencecreature;
mergeObject(arme.system,
{
action: item.isCompetencePossession() ? 'possession' : 'attaque',
system: {
competence: arme.name,
cac: categorieAttaque == "naturelle" ? "naturelle" : "",
niveau: item.system.niveau,
initiative: RdDCombatManager.calculInitiative(item.system.niveau, item.system.carac_value),
equipe: true,
resistance: 100,
dommagesReels: arme.system.dommages,
penetration: 0,
force: 0,
rapide: true,
}
competence: arme.name,
initiative: RdDCombatManager.calculInitiative(competencecreature.system.niveau, competencecreature.system.carac_value),
niveau: competencecreature.system.niveau,
equipe: true,
resistance: 100,
dommagesReels: arme.system.dommages,
penetration: 0,
force: 0,
rapide: true,
cac: competencecreature.system.isnaturelle ? "naturelle" : "",
action: 'attaque'
});
return arme;
}
console.error("RdDItemCompetenceCreature.toActionArme(", competencecreature, ") : impossible de transformer l'Item en arme");
return undefined;
}
/* -------------------------------------------- */
static getCategorieAttaque(item) {
if (item.type == TYPES.competencecreature) {
switch (item.system.categorie) {
case "melee":
case "tir":
case "lancer":
case "naturelle":
case "possession":
return item.system.categorie
}
}
return undefined
static isCompetenceAttaque(item) {
return item.type == 'competencecreature' && item.system.iscombat;
}
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) {
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 { Misc } from "./misc.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
@@ -100,13 +98,9 @@ export class RdDItemSheet extends ItemSheet {
isComestible: this.item.getUtilisationCuisine(),
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');
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') {
formData.caracList = duplicate(game.system.model.Actor.personnage.carac)
formData.caracList["reve-actuel"] = duplicate(game.system.model.Actor.personnage.reve.reve)
@@ -255,8 +249,7 @@ export class RdDItemSheet extends ItemSheet {
event.preventDefault();
if (this.item.isCompetence()) {
const categorie = event.currentTarget.value;
const level = RdDItemCompetence.getNiveauBase(categorie, this.item.getCategories());
let level = RdDItemCompetence.getNiveauBase(event.currentTarget.value);
this.item.system.base = level;
this.html.find('[name="system.base"]').val(level);
}

View File

@@ -6,55 +6,48 @@ import { RdDTimestamp } from "./time/rdd-timestamp.js";
import { RdDUtility } from "./rdd-utility.js";
import { SystemCompendiums } from "./settings/system-compendiums.js";
import { RdDRaretes } from "./item/raretes.js";
import { RdDItemCompetence } from "./item-competence.js";
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
export const TYPES = {
competence: 'competence',
competencecreature: 'competencecreature',
empoignade: 'empoignade',
possession: 'possession',
blessure: 'blessure',
maladie: 'maladie',
poison: 'poison',
arme: 'arme',
armure: 'armure',
conteneur: 'conteneur',
objet: 'objet',
monnaie: 'monnaie',
gemme: 'gemme',
munition: 'munition',
nourritureboisson: 'nourritureboisson',
sort: 'sort',
herbe: 'herbe',
plante: 'plante',
ingredient: 'ingredient',
faune: 'faune',
ingredient: 'ingredient',
livre: 'livre',
potion: 'potion',
service: 'service',
musique: 'musique',
danse: 'danse',
chant: 'chant',
jeu: 'jeu',
recettecuisine: 'recettecuisine',
oeuvre: 'oeuvre',
recettealchimique: 'recettealchimique',
tache: 'tache',
sort: 'sort',
sortreserve: 'sortreserve',
rencontre: 'rencontre',
queue: 'queue',
ombre: 'ombre',
souffle: 'souffle',
tete: 'tete',
casetmr: 'casetmr',
meditation: 'meditation',
recettealchimique: 'recettealchimique',
chant: 'chant',
danse: 'danse',
jeu: 'jeu',
recettecuisine: 'recettecuisine',
musique: 'musique',
maladie: 'maladie',
poison: 'poison',
oeuvre: 'oeuvre',
monnaie: 'monnaie',
munition: 'munition',
nourritureboisson: 'nourritureboisson',
service: 'service',
signedraconique: 'signedraconique',
tarot: 'tarot',
nombreastral: 'nombreastral',
gemme: 'gemme',
possession: 'possession',
sortreserve: 'sortreserve',
extraitpoetique: 'extraitpoetique',
tarot: 'tarot',
empoignade: 'empoignade',
objet: 'objet'
}
const typesInventaireMateriel = [
TYPES.arme,
TYPES.armure,
@@ -220,7 +213,6 @@ export class RdDItem extends Item {
isService() { return this.type == TYPES.service; }
isCompetence() { return typesObjetsCompetence.includes(this.type) }
isCompetencePossession() { return TYPES.competencecreature == this.type && this.system.categorie == "possession" }
isTemporel() { return typesObjetsTemporels.includes(this.type) }
isOeuvre() { return typesObjetsOeuvres.includes(this.type) }
isDraconique() { return RdDItem.getItemTypesDraconiques().includes(this.type) }
@@ -237,13 +229,6 @@ export class RdDItem extends Item {
isPresentDansMilieux(milieux) {
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) {
const environnements = this.isInventaire() ? this.system.environnement : undefined;
@@ -380,7 +365,7 @@ export class RdDItem extends Item {
}
getEncTotal() {
return (this.getQuantite() ?? 0) * this.getEnc();
return (this.isService() ? 0 : this.getQuantite()) * this.getEnc();
}
getEnc() {

View File

@@ -2,7 +2,7 @@ import { RdDBaseActor } from "./actor/base-actor.js";
import { LOG_HEAD, SYSTEM_RDD } from "./constants.js";
import { Grammar } from "./grammar.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 { RdDRaretes } from "./item/raretes.js";
@@ -13,7 +13,7 @@ class Migration {
async applyItemsUpdates(computeUpdates) {
await game.actors.forEach(async (actor) => {
const actorItemUpdates = computeUpdates(actor.items).filter(it => it != undefined);
const actorItemUpdates = computeUpdates(actor.items);
if (actorItemUpdates.length > 0) {
console.log(
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) {
console.log(this.code, "Applying updates on items", itemUpdates);
await Item.updateDocuments(itemUpdates);
@@ -65,6 +65,7 @@ class _1_5_34_migrationPngWebp {
}
}
class _10_0_16_MigrationSortsReserve extends Migration {
get code() { return "creation-item-sort-reserve"; }
get version() { return "10.0.16"; }
@@ -369,7 +370,6 @@ class _10_4_6_ServicesEnCommerces extends Migration {
return itemToCreate;
}
}
class _10_5_0_UpdatePeriodicite extends Migration {
get code() { return "migration-periodicite-poisons-maladies"; }
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 {
static getMigrations() {
return [
@@ -530,8 +474,6 @@ export class Migrations {
new _10_4_6_ServicesEnCommerces(),
new _10_5_0_UpdatePeriodicite(),
new _10_7_0_MigrationBlessures(),
new _10_7_19_CategorieCompetenceCreature(),
new _10_7_19_PossessionsEntiteVictime(),
];
}
@@ -548,7 +490,7 @@ export class Migrations {
migrate() {
const currentVersion = game.settings.get(SYSTEM_RDD, "systemMigrationVersion");
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));
if (migrations.length > 0) {
migrations.sort((a, b) => this.compareVersions(a, b));

View File

@@ -1,5 +1,4 @@
import { RdDCarac } from "./rdd-carac.js";
import { RdDPossession } from "./rdd-possession.js";
const conditionsTactiques = [
{ type: '', descr: '', dmg: 0, attaque: 0, parade: 0, esquive: true },
@@ -28,9 +27,6 @@ export class RdDBonus {
if (rollData.isEmpoignade && rollData.rolled?.isPart) {
return true
}
if (RdDPossession.isDefensePossession(rollData)) {
return RdDPossession.isPossessionFinesse(rollData)
}
return rollData.attackerRoll?.particuliere == 'finesse';
}
@@ -78,7 +74,7 @@ export class RdDBonus {
/* -------------------------------------------- */
static _dmgArme(rollData) {
if (rollData.arme) {
if ( rollData.arme) {
let dmgBase = rollData.arme.system.dommagesReels ?? Number(rollData.arme.system.dommages ?? 0);
//Le bonus dégats magiques ne peut pas faire dépasser le bonus de l'arme (cf p.278)
return dmgBase + Math.min(dmgBase, rollData.arme.system.magique ? rollData.arme.system.ecaille_efficacite : 0);

View File

@@ -87,7 +87,7 @@ export class RdDCombatManager extends Combat {
let rollFormula = formula ?? RdDCombatManager.formuleInitiative(2, 10, 0, 0);
if (!formula) {
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) {
rollFormula = RdDCombatManager.formuleInitiative(2, competence.system.carac_value, competence.system.niveau, 0);
}
@@ -230,15 +230,15 @@ export class RdDCombatManager extends Combat {
}
static listActionsCreature(competences) {
return competences.map(it => RdDItemCompetenceCreature.armeCreature(it))
.filter(it => it != undefined);
return competences.filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
.map(it => RdDItemCompetenceCreature.armeNaturelle(it));
}
static listActionsPossessions(actor) {
return RdDCombatManager._indexActions(actor.getPossessions().map(p => {
return {
name: p.name,
action: 'possession',
action: 'conjurer',
system: {
competence: p.name,
possessionid: p.system.possessionid,
@@ -255,7 +255,7 @@ export class RdDCombatManager extends Combat {
return actions;
}
if (actor.isCreatureEntite()) {
actions = RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']);
actions = actions.concat(RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']));
} else if (actor.isPersonnage()) {
// Recupération des items 'arme'
const armes = actor.itemTypes['arme'].filter(it => RdDItemArme.isArmeUtilisable(it))
@@ -263,7 +263,7 @@ export class RdDCombatManager extends Combat {
.concat(RdDItemArme.mainsNues());
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) {
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") {
initOffset = 0;
initInfo = "Demi Surprise"
} else if (action.action == 'possession') {
} else if (action.action == 'conjurer') {
initOffset = 10;
caracForInit = combatant.actor.getReveActuel();
initInfo = "Possession"
@@ -790,7 +790,7 @@ export class RdDCombat {
passeArme: randomID(16),
mortalite: arme?.system.mortalite,
coupsNonMortels: false,
competence: competence.clone(),
competence: competence,
surprise: this.attacker.getSurprise(true),
surpriseDefenseur: this.defender.getSurprise(true),
targetToken: Targets.extractTokenData(this.target),
@@ -1045,7 +1045,7 @@ export class RdDCombat {
passeArme: attackerRoll.passeArme,
diffLibre: attackerRoll.diffLibre,
attackerRoll: attackerRoll,
competence: this.defender.getCompetence(competenceParade).clone(),
competence: this.defender.getCompetence(competenceParade),
arme: armeParade,
surprise: this.defender.getSurprise(true),
needParadeSignificative: ReglesOptionelles.isUsing('categorieParade') && RdDItemArme.needParadeSignificative(attackerRoll.arme, armeParade),
@@ -1126,7 +1126,7 @@ export class RdDCombat {
passeArme: attackerRoll.passeArme,
diffLibre: attackerRoll.diffLibre,
attackerRoll: attackerRoll,
competence: competence.clone(),
competence: competence,
surprise: this.defender.getSurprise(true),
surpriseDefenseur: this.defender.getSurprise(true),
carac: this.defender.system.carac,

View File

@@ -70,7 +70,7 @@ export class RdDEmpoignade {
let rollData = {
mode: mode,
isEmpoignade: true,
competence: attacker.getCompetence("Corps à corps").clone(),
competence: attacker.getCompetence("Corps à corps"),
selectedCarac: attacker.system.carac.melee,
empoignade: empoignade,
attackerId: attacker.id,

View File

@@ -1,9 +1,9 @@
/* -------------------------------------------- */
import { RdDCombat } from "./rdd-combat.js";
import { RdDResolutionTable } from "./rdd-resolution-table.js";
import { RdDRoll } from "./rdd-roll.js";
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
import { Targets } from "./targets.js";
import { TYPES } from "./item.js";
/* -------------------------------------------- */
/* On part du principe qu'une entité démarre tjs
@@ -20,9 +20,9 @@ export class RdDPossession {
/* -------------------------------------------- */
static searchPossessionFromEntite(attacker, defender) {
let poss = attacker.items.find(poss => poss.type == TYPES.possession && poss.system.victime.actorid == defender.id);
let poss = attacker.items.find(poss => poss.type == 'possession' && poss.system.possedeid == defender.id);
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;
}
@@ -31,40 +31,39 @@ export class RdDPossession {
static async onAttaquePossession(target, attacker, competence, suitePossession = undefined) {
const defender = target.actor;
const fromEntite = RdDPossession.searchPossessionFromEntite(attacker, defender);
const isNouvelle = !suitePossession && !fromEntite;
const isNouvelle = !suitePossession && ! fromEntite;
const possession = (suitePossession ?? fromEntite ?? (await RdDPossession.createPossession(attacker, defender)));
RdDPossession.$updateEtatPossession(possession)
let rollData = {
mode: "attaque",
mode: "possession",
isECNIDefender: false,
competence: competence.clone(),
competence: competence,
possession: possession,
attacker: attacker,
defender: defender,
targetToken: Targets.extractTokenData(target)
};
RdDPossession.selectCompetenceDraconicOuPossession(rollData, attacker)
if (attacker.isCreatureEntite()) {
RdDItemCompetenceCreature.setRollDataCreature(rollData)
}
await RdDPossession.$rollAttaquePossession(attacker, rollData, isNouvelle);
}
/* -------------------------------------------- */
static async onConjurerPossession(attacker, possession) {
static async onConjurerPossession(attacker, competence, possession) {
possession = duplicate(possession);
RdDPossession.$updateEtatPossession(possession)
const defender = game.actors.get(possession.system.entite.actorid);
let rollData = {
mode: "attaque",
mode: "possession",
isECNIDefender: true,
competence: competence,
possession: possession,
attacker: attacker,
defender: defender,
defender: game.actors.get(possession.system.possesseurid)
};
RdDPossession.selectCompetenceDraconicOuPossession(rollData, attacker)
await RdDPossession.$rollAttaquePossession(attacker, rollData);
}
@@ -72,7 +71,7 @@ export class RdDPossession {
static async onDefensePossession(attackerId, defenderId, possessionId) {
let attacker = game.actors.get(attackerId)
let possession = attacker?.getPossession(possessionId)
defenderId = defenderId ?? possession?.system.entite.actorid ?? undefined
defenderId = defenderId ?? possession?.system.possesseurid ?? undefined
let defender = game.actors.get(defenderId)
possession = possession ?? defender?.getPossession(possessionId) ?? undefined;
@@ -83,29 +82,19 @@ export class RdDPossession {
possession = duplicate(possession)
// Update for draconic roll
let rollData = {
mode: "defense",
mode: "conjuration",
isECNIDefender: defender.type == "entite",
possession: possession,
attacker: attacker,
defender: defender,
competence: defender.getDraconicOuPossession(),
selectedCarac: defender.system.carac.reve,
forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: defender.getReveActuel() } }
}
RdDPossession.selectCompetenceDraconicOuPossession(rollData, defender)
rollData.diffLibre = RdDPossession.getInfoAttaque(rollData).diffLibre
rollData.competence.system.defaut_carac = 'reve-actuel'
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) {
@@ -115,22 +104,21 @@ export class RdDPossession {
name: 'jet-possession',
label: rollData.isECNIDefender ? 'Conjurer la possession' : 'Possession',
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) {
rollData.possession.isSuccess = rollData.rolled.isSuccess;
RdDPossession.$updateEtatPossession(rollData.possession, rollData);
static async $onRollPossession(rollData, isSuccess, isNouvelle = false) {
rollData.possession.isSuccess = isSuccess;
RdDPossession.$updateEtatPossession(rollData.possession);
if (isNouvelle) {
// 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');
}
@@ -139,42 +127,35 @@ export class RdDPossession {
const dialog = await RdDRoll.create(defender, rollData,
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-possession.html' },
{
name: 'possession',
name: 'conjurer',
label: 'Conjurer une Possession',
callbacks: [
{ action: async (r) => await RdDPossession.$onRollConjuration(r) }
]
}
);
]
}
);
dialog.render(true);
}
}
/* -------------------------------------------- */
static async $onRollConjuration(rollData) {
let victime = game.actors.get(rollData.possession.system.victime.actorid)
let compteur = rollData.possession.system.compteur
let actor = game.actors.get(rollData.possession.system.possedeid)
if (!rollData.rolled.isSuccess) {
if (rollData.isECNIDefender) {
compteur--
rollData.possession.system.compteur--
} 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)
await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-resultat-possession.html')
await RdDResolutionTable.displayRollData(rollData,rollData.defender, 'chat-resultat-possession.html')
if (rollData.possession.isPosseder || rollData.possession.isConjurer) {
// conjuration
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) {
return await Item.create({
name: "Possession en cours de " + attacker.name, type: 'possession',
img: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
system: {
description: "", typepossession: attacker.name,
possede: false,
possessionid: randomID(16),
entite: { actorid: attacker.id },
victime: { actorid: defender.id },
compteur: 0
}
},
name: "Possession en cours de " + attacker.name, type: 'possession',
img: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
system: { description: "", typepossession: attacker.name, possede: false, possessionid: randomID(16), possesseurid: attacker.id, possedeid: defender.id, date: 0, compteur: 0 }
},
{
temporary: true
})

View File

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

View File

@@ -75,8 +75,8 @@ export class RdDTokenHud {
(event) => {
const actionIndex = event.currentTarget.attributes['data-action-index']?.value;
const action = hudData.actions[actionIndex];
const possession = action.action == 'possession' ? combatant.actor.getPossession(action.system.possessionid) : undefined;
if (possession) {
if (action.action == 'conjurer') {
const possession = combatant.actor.getPossession(action.system.possessionid);
combatant.actor.conjurerPossession(possession);
}
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-base-competence.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-parade.html',
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-potion.html',

View File

@@ -5,7 +5,6 @@ import { RdDItemSort } from "./item-sort.js";
import { Misc } from "./misc.js";
import { RdDBonus } from "./rdd-bonus.js";
import { RdDCarac } from "./rdd-carac.js";
import { RdDPossession } from "./rdd-possession.js";
import { RdDUtility } from "./rdd-utility.js";
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
@@ -31,7 +30,7 @@ export const referenceAjustements = {
},
diffLibre: {
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
? RdDItemSort.getDifficulte(rollData.selectedSort, rollData.diffLibre)
: rollData.diffLibre ?? rollData.competence?.system.default_diffLibre ?? 0

View File

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

View File

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

View File

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

View File

@@ -20,18 +20,20 @@ export class PixiTMR {
this.callbacksOnAnimate = [];
}
load( onLoad = (loader, resources) => {} ) {
let loader = this.pixiApp.loader;
async load( onLoad = (loader, resources) => {} ) {
// WIP - Deprecated since v7 : let loader = new PIXI.Loader();
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) });
loader.load( (loader, resources) => {
onLoad(loader, resources);
for (let onAnimate of this.callbacksOnAnimate) {
onAnimate();
}
});
onLoad();
for (let onAnimate of this.callbacksOnAnimate) {
onAnimate();
}
}
static getImgFromCode(code) {
return PixiTMR.textures[code]
}
static register(name, img) {
@@ -44,7 +46,9 @@ export class PixiTMR {
}
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
carteTmr.x = 0;
carteTmr.y = 0;
@@ -52,7 +56,8 @@ export class PixiTMR {
carteTmr.height = 860;
// Rotate around the center
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.tmrObject = this;
if (!this.tmrObject.viewOnly) {
@@ -63,9 +68,10 @@ export class PixiTMR {
}
sprite(code, options = {}) {
const texture = PIXI.utils.TextureCache[code];
let img = PixiTMR.getImgFromCode(code)
const texture = PIXI.utils.TextureCache[img];
if (!texture) {
console.error("Texture manquante", code)
console.error("Texture manquante", code, PIXI.utils.TextureCache)
return;
}
let sprite = new PIXI.Sprite(texture);
@@ -97,7 +103,8 @@ export class PixiTMR {
sprite.tooltip = new PIXI.Text(text, tooltipStyle);
sprite.tooltip.zIndex = tmrTokenZIndex.tooltip;
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))
.on('pointerover', () => this.onShowTooltip(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",
"title": "Rêve de Dragon",
"version": "10.7.19",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.7.19.zip",
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json",
"version": "11.0.5",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-11.0.5.zip",
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v11/system.json",
"compatibility": {
"minimum": "10",
"verified": "10",
"maximum": "10"
"minimum": "11",
"verified": "11",
"maximum": "11"
},
"description": "Rêve de Dragon RPG for FoundryVTT",
"authors": [
@@ -69,7 +69,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/competences.db",
"type": "Item",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -78,7 +81,9 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/arts-et-divertissements.db",
"type": "Item",
"private": false,
"ownership": {
"PLAYER": "OBSERVER"
},
"flags": {}
},
{
@@ -87,7 +92,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/competences-creatures.db",
"type": "Item",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -96,7 +104,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/competences-entites.db",
"type": "Item",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -105,7 +116,9 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/sorts-oniros.db",
"type": "Item",
"private": false,
"ownership": {
"PLAYER": "OBSERVER"
},
"flags": {}
},
{
@@ -114,7 +127,9 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/sorts-hypnos.db",
"type": "Item",
"private": false,
"ownership": {
"PLAYER": "OBSERVER"
},
"flags": {}
},
{
@@ -123,7 +138,9 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/sorts-narcos.db",
"type": "Item",
"private": false,
"ownership": {
"PLAYER": "OBSERVER"
},
"flags": {}
},
{
@@ -132,7 +149,9 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/sorts-thanatos.db",
"type": "Item",
"private": false,
"ownership": {
"PLAYER": "OBSERVER"
},
"flags": {}
},
{
@@ -141,7 +160,9 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/equipement.db",
"type": "Item",
"private": false,
"ownership": {
"PLAYER": "OBSERVER"
},
"flags": {}
},
{
@@ -150,7 +171,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/maladies-et-poisons.db",
"type": "Item",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -159,7 +183,9 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/rappel-des-regles.db",
"type": "JournalEntry",
"private": false,
"ownership": {
"PLAYER": "OBSERVER"
},
"flags": {}
},
{
@@ -168,7 +194,9 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/macros.db",
"type": "Macro",
"private": false,
"ownership": {
"PLAYER": "OBSERVER"
},
"flags": {}
},
{
@@ -177,7 +205,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/queues-de-dragon.db",
"type": "Item",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -186,7 +217,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/ombres-de-thanatos.db",
"type": "Item",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -195,7 +229,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/souffles-de-dragon.db",
"type": "Item",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -204,7 +241,9 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/tarot-draconique.db",
"type": "Item",
"private": false,
"ownership": {
"PLAYER": "OBSERVER"
},
"flags": {}
},
{
@@ -213,7 +252,9 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/extrait-poetique.db",
"type": "Item",
"private": false,
"ownership": {
"PLAYER": "OBSERVER"
},
"flags": {}
},
{
@@ -222,7 +263,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/tetes-de-dragon-pour-haut-revants.db",
"type": "Item",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -231,7 +275,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/tetes-de-dragon-pour-tous-personnages.db",
"type": "Item",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -240,7 +287,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/rencontres.db",
"type": "Item",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -249,7 +299,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/tables-diverses.db",
"type": "RollTable",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -258,7 +311,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/animaux.db",
"type": "Actor",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -267,7 +323,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/voyageurs.db",
"type": "Actor",
"private": false,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -276,7 +335,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/vehicules.db",
"type": "Actor",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -285,7 +347,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/archetypes.db",
"type": "Actor",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -294,7 +359,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/humanoides.db",
"type": "Actor",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -303,7 +371,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/entites-de-cauchemar.db",
"type": "Actor",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -312,7 +383,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/invocations.db",
"type": "Actor",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -321,7 +395,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/faune-flore-mineraux.db",
"type": "Item",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -330,7 +407,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/meditations-et-ecrits.db",
"type": "Item",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -339,7 +419,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/recettes-alchimiques.db",
"type": "Item",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
},
{
@@ -348,7 +431,10 @@
"system": "foundryvtt-reve-de-dragon",
"path": "packs/scenes-rdd.db",
"type": "Scene",
"private": true,
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
},
"flags": {}
}
],

View File

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

View File

@@ -9,24 +9,18 @@
<input class="competence-carac creature-carac" type="text" compname="{{comp.name}}" name="{{comp._id}}.carac"
value="{{comp.system.carac_value}}" data-dtype="number"
{{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
<input class="competence-value creature-niveau" type="text" data-dtype="number"
compname="{{comp.name}}" name="{{comp._id}}.niveau"
value="{{numberFormat comp.system.niveau decimals=0 sign=true}}"
{{#unless @root.options.vueDetaillee}}disabled{{/unless}}
/>
<input class="competence-damage creature-dommages" type="text" data-dtype="number"
{{#if comp.isdommages}}
compname="{{comp.name}}" name="{{comp._id}}.dommages"
value="{{numberFormat comp.system.dommages decimals=0 sign=true}}"
{{#unless @root.options.vueDetaillee}}disabled{{/unless}}
{{else}}disabled{{/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}}
<input class="competence-value creature-niveau" type="text" compname="{{comp.name}}" name="{{comp._id}}.niveau"
value="{{numberFormat comp.system.niveau decimals=0 sign=true}}" data-dtype="number"
{{#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"
{{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
{{#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>
{{/each}}
</ol>

View File

@@ -1,6 +1,6 @@
<img class="chat-icon" src="{{competence.img}}" />
<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}}
{{else}}
{{defender.name}} tente de {{#if isECNIDefender}}résister à{{else}}conjurer la possession de{{/if}} {{attacker.name}}
@@ -12,7 +12,7 @@
<div>
<span class='chat-card-button-area'>
<br>
{{#if (eq mode "attaque")}}
{{#if (eq mode "possession")}}
{{#if possession.isSuccess}}
<a class='defense-possession chat-card-button'
data-attackerId='{{attacker.id}}'

View File

@@ -1,3 +1,3 @@
{{#each @root.categories as |categorie key|}}
{{#each @root.categorieCompetences as |categorie key|}}
<option value="{{@key}}">{{categorie.label}}</option>
{{/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>
<select name="system.categorie" class="categorie" data-dtype="String">
{{#select system.categorie}}
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-categories.html"}}
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-categorie-competence.html"}}
{{/select}}
</select>
</div>

View File

@@ -6,38 +6,50 @@
<label for="system.categorie">Catégorie</label>
<select name="system.categorie" class="categorie" data-dtype="String">
{{#select system.categorie}}
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-categories.html"}}
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-categorie-competence.html"}}
{{/select}}
</select>
</div>
<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"/>
</div>
<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"/>
</div>
<div class="form-group">
<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"/>
</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">
<label for="niveau">Dommages (+dom)</label>
<input class="attribute-value" type="text" name="system.dommages" value="{{system.dommages}}" data-dtype="Number"/>
</div>
{{/if}}
{{#if isparade}}
{{/if}}
<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 system.categorie_parade}}
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-categorie-parade.html"}}
{{/select}}
</select>
</div>
{{/if}}
{{/unless}}
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html"}}
</section>