forked from public/foundryvtt-reve-de-dragon
Compare commits
110 Commits
foundryvtt
...
foundryvtt
| Author | SHA1 | Date | |
|---|---|---|---|
| 19bfee7ea5 | |||
| ab884713f6 | |||
| 940237852b | |||
| 78ee23da96 | |||
| 862a267683 | |||
| 2373acc295 | |||
| 249d171511 | |||
| 018b6a32dd | |||
| 44ec511aa6 | |||
| ff44de3b3c | |||
| 8101b905d8 | |||
| 27dd89024e | |||
| 69a653d1e5 | |||
| bea4124388 | |||
| e5bb2e9afc | |||
| 1d3ae9bb1a | |||
| d4be2957a3 | |||
| 6c9d03be92 | |||
| 5a50917730 | |||
| d285e866be | |||
| ece9ab6f64 | |||
| 038e922f0f | |||
| 728c5f2f8e | |||
| e6592f8333 | |||
| 42567e7ca0 | |||
| 9d1fe6d8fd | |||
| f5bd0f32f4 | |||
| fad29f9652 | |||
| 9d51631d5c | |||
| d1b73e7658 | |||
| 54158ee10d | |||
| e089bdf9c8 | |||
| 41ab593059 | |||
| 42ad4c5b26 | |||
| 85f8a716d4 | |||
| 47f305d865 | |||
| 407b4f82d9 | |||
| c950f568fd | |||
| 0ed90f6177 | |||
| b74fc27079 | |||
| a65d4511c5 | |||
| e61417c44e | |||
| 8ca725bd38 | |||
| 441a5965c7 | |||
| f08c8f93da | |||
| d28362bf14 | |||
| e506382d18 | |||
| c1cecc76b3 | |||
| f2a3e1db45 | |||
| b69359a47d | |||
| fe6c2e2ff2 | |||
| 9bd13a6021 | |||
| a29630f9a2 | |||
| c7fd9f7596 | |||
| 7b18fd25c3 | |||
| 5c256e2c49 | |||
| 1c475348d5 | |||
| de5d32f88f | |||
| 76a02d60ca | |||
| 724c556b9e | |||
| 7dfba94a11 | |||
| 928c7bbcfe | |||
| 222a06a978 | |||
| b4edaf8584 | |||
| 3c062afd56 | |||
| 6de4fff403 | |||
| 3543f081b2 | |||
| 56f14e12a2 | |||
| e226af5ac5 | |||
| d8be37a2ec | |||
| ba2d9de7b6 | |||
| 6b8fb3267a | |||
| 05d6f64a31 | |||
| c0570e58b4 | |||
| 8389d578bc | |||
| f05ef79b97 | |||
| d2a8bfae4f | |||
| d54834fa71 | |||
| c898bf5212 | |||
| a118dc7334 | |||
| 46401e5d63 | |||
| 7eb1d9f838 | |||
| 1d8f4ebb88 | |||
| 145a92f462 | |||
| 5148d02314 | |||
| 000c89b11a | |||
| 5d4a18aac5 | |||
| 34b5df637f | |||
| 22572ca98c | |||
| a6a1c1009e | |||
| 288cf9162c | |||
| 4b1381e535 | |||
| 78336a3f45 | |||
| 3001ae44de | |||
| a43ceb3188 | |||
| 9e95a44efd | |||
| 179ea0c85b | |||
| 3821b5bea1 | |||
| 2739c650d9 | |||
| b101d58bee | |||
| 0e3d721fc7 | |||
| e1e45a83be | |||
| 3b14e54829 | |||
| 615a3f1315 | |||
| ca72d088cc | |||
| ac89b948ca | |||
| f22c4d2ec8 | |||
| ffd80394d3 | |||
| 0959d1b18e | |||
| 24e58abfcc |
123
changelog.md
123
changelog.md
@@ -1,4 +1,127 @@
|
|||||||
# v11.0
|
# v11.0
|
||||||
|
## v11.1.1 - Les fumebols de Werther de Zloth
|
||||||
|
- Fix: on peut de nouveau afficher les vues détaillées
|
||||||
|
- Fix: on peut ouvrir les sacs et contenants portés par les véhicules et créatures
|
||||||
|
- Fix: cuisiner du gibier prend maintenant bien les proportaions en compte
|
||||||
|
|
||||||
|
## v11.1.0 - Les choix de Werther de Zloth
|
||||||
|
- Les options suivantes peuvent être désactivées:
|
||||||
|
- La transformation de stress à Château Dormant
|
||||||
|
- La récuperation de chance à Château Dormant
|
||||||
|
- La récupération d'éthylisme
|
||||||
|
- La récupération de rêve (y compris fleurs de rêve et Rêves de Dragon: la rencontre a lieu, mais ne donne pas de rêve)
|
||||||
|
- Le jet de moral de Château Dormant
|
||||||
|
- Séparation des véhicules dans leur propre acteur
|
||||||
|
- Séparation des entités dans leur propre acteur
|
||||||
|
- Séparation des créatures dans leur propre acteur
|
||||||
|
- La fenêtre de signes draconiques ne sélectionne plus tout les haut-rêvants par défaut
|
||||||
|
- Un nouveau personnage a automatiquement son token relié
|
||||||
|
- corrections de bugs
|
||||||
|
- si on n'utilise pas les règles de fatigues, un reflet de rêve pouvait garder le Haut-rêvant dans les TMRs pour toujours
|
||||||
|
- certaines macros ne marchaient pas pour les créatures/entités/véhicules/commerces
|
||||||
|
- en cas de charge, les particulières sont toujours en force (p125)
|
||||||
|
|
||||||
|
## v11.0.28 - les fractures de Khrachtchoum
|
||||||
|
- La gravité de la blessure est affichée dans le résumé de l'encaissement
|
||||||
|
- Lors du changement d'acteur pendant le round
|
||||||
|
- le message annonçant le joueur dont c'est le tour ne contient plus d'informations de santé
|
||||||
|
- un message avec les informations de santé est envoyé au Gardienn et au propriétaire du token.acteur
|
||||||
|
- le jet de vie est bien fait par le token si besoin
|
||||||
|
- seul les propriétaires peuvent faire les jets de vie
|
||||||
|
- Amélioration de la fenêtre de jets
|
||||||
|
- le type de dégâts pour les attaques est toujours affiché
|
||||||
|
- le moral est indiqué avant l'icone d'appel au moral
|
||||||
|
|
||||||
|
## v11.0.27 - Khrachtchoum le méticuleux
|
||||||
|
- le tooltip dans les TMR reste visible si on ne bouge pas la souris
|
||||||
|
- le surencombrement n'affecte QUE les actions physiques
|
||||||
|
- on peut de nouveau fabriquer une potion depuis la fenêtre d'édition de l'herbe
|
||||||
|
- si les TMR sont minimisées alors qu'une action est requise, elles sont bien réaffichées lorsque l'action est faite
|
||||||
|
|
||||||
|
## v11.0.26 - le crépuscule de Khrachtchoum
|
||||||
|
- gestion correcte des TMRs
|
||||||
|
- les TMRs ne sont jamais minimisées (par le système) quand le haut-rêvant est en demi-rêve
|
||||||
|
- lorsqu'une fenêtre liée aux demi-rêve est affichée, cliquer sur les TMRs n'a pas d'effet
|
||||||
|
- les lancers de sorts et lectures de signes sont affichées en premier plan
|
||||||
|
- Les effets qui ouvrent une fenêtre sont bien affichés en premier plan
|
||||||
|
- en cas de rencontre suivie de maîtrises/conquêtes, les fenêtres s'enchaînent
|
||||||
|
- Le drag&drop vers la barre de macro est corrigé
|
||||||
|
- pour les créatures, possibilités d'avoir les attaques ou autres compétences
|
||||||
|
- pour les personnages, les macros sont créées:
|
||||||
|
- pour les compétences
|
||||||
|
- pour le corps à corps, trois macros sont créées: compétence, pugilat, empoignade
|
||||||
|
- pour les armes
|
||||||
|
- deux macros sont créées pour les armes à 1/2 mains
|
||||||
|
- deux macros sont créées pour les armes de mélée et lancer
|
||||||
|
- 4 macros si votre arbalête se lance, tire, et se manie à 1 ou 2 mains...
|
||||||
|
- les jets de compétences d'attaque des créatures fonctionnent de nouveau
|
||||||
|
|
||||||
|
## v11.0.25 - la vision du rêve de Khrachtchoum
|
||||||
|
- Les TMRs restent affichées tant que le Haut-rêvant est en demi-rêve
|
||||||
|
|
||||||
|
## v11.0.24 - les couleurs de Khrachtchoum
|
||||||
|
- nouvelle carte des TMRs
|
||||||
|
|
||||||
|
## v11.0.23 - la lumière de Khrachtchoum
|
||||||
|
- ajustement automatique de la luminosité selon l'heure pour les scènes:
|
||||||
|
- avec une vision des tokens (sinon: ce n'est pas une scène de carte pour tokens)
|
||||||
|
- avec illumination globale (correspondant à une illumination extérieure)
|
||||||
|
- quand lampe "allumée" dans la fenêtre du calendrier
|
||||||
|
|
||||||
|
## v11.0.22 - les automatismes de Khrachtchoum le Problémeux
|
||||||
|
- Macro pour attaquer avec les compétences de créatures
|
||||||
|
|
||||||
|
## v11.0.20
|
||||||
|
- Macro pour attaquer avec les armes des personnages
|
||||||
|
|
||||||
|
## v11.0.17
|
||||||
|
- Fix: les actions de commerce ne s'appliquait pas bien aux personnages des tokens non liés
|
||||||
|
|
||||||
|
## v11.0.15 - L'apprentissage de Khrachtchoum
|
||||||
|
- Fix: l'expérience ne s'appliquait plus sur certaines réussites particulières (régression depuis la 11.0.7)
|
||||||
|
|
||||||
|
## v11.0.14 - Les pincettes de Khrachtchoum le Problémeux
|
||||||
|
- Correction du calcul de la place restante lors de l'ajout dans un conteneur
|
||||||
|
|
||||||
|
## v11.0.13 - La multiplication de l'eau de Khrachtchoum le Problémeux
|
||||||
|
- Correction de la vente depuis un commerce ayant des quantités illimitées
|
||||||
|
|
||||||
|
## v11.0.12 - Les poids de la mesure de Khrachtchoum le Problémeux
|
||||||
|
- Correction des malus de surencombrement
|
||||||
|
- Le malus armure est correctement affiché dans l'onglet des caractéristiques
|
||||||
|
- Correction d'orthographe et amélioration des messages des oeuvres d'art
|
||||||
|
|
||||||
|
## v11.0.11 - Les bleus de Khrachtchoum le Problémeux
|
||||||
|
- si le gardien configure le sommeil, les joueurs sont notifiés que chateau dormant vient de passer
|
||||||
|
- possibilité de créer des armes et des compétences de créatures non-mortelles.
|
||||||
|
|
||||||
|
## v11.0.10 - Les Songes de Khrachtchoum le Problémeux
|
||||||
|
- on peut de nouveau se déplacer dans les TMRs d'un clic sur la case à atteindre
|
||||||
|
- Lire un livre depuis l'inventaire permet de nouveau de faire un jet de la tâche
|
||||||
|
créée au lieu de créer toujours une nouvelle tâche
|
||||||
|
- La sélection des TMR pour la création de signes draconiques ne cause plus d'erreurs
|
||||||
|
- la récupération d'endurance en cas d'insomnie est limitée à la moitié
|
||||||
|
- le résultat du sommeil lors d'un rêve de dragon à la première heure s'affiche normalement
|
||||||
|
- lorsque le gardien gère la durée des nuits, en cas de rêve de dragon,
|
||||||
|
les heures dormies sont déduites des heures restant à dormir
|
||||||
|
|
||||||
|
## v11.0.9 - Les Souvenirs de Khrachtchoum le Problémeux
|
||||||
|
- mode de saisie de l'archétype en vue détaillée
|
||||||
|
- création une nouvelle incarnation depuis l'archétype
|
||||||
|
- réorganisation de la fenêtre de sélection des règles optionnelles
|
||||||
|
- correction de l'affichage du type dans les fenêtres d'objets
|
||||||
|
|
||||||
|
## v11.0.8 - la poigne de Sémolosse
|
||||||
|
- lien vers le changelog
|
||||||
|
- organisation des compendiums du système
|
||||||
|
- 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
|
||||||
|
|
||||||
# v11.0.7
|
# v11.0.7
|
||||||
|
|
||||||
|
|||||||
@@ -7,33 +7,30 @@ import { Misc } from "./misc.js";
|
|||||||
import { RdDCombatManager } from "./rdd-combat.js";
|
import { RdDCombatManager } from "./rdd-combat.js";
|
||||||
import { RdDCarac } from "./rdd-carac.js";
|
import { RdDCarac } from "./rdd-carac.js";
|
||||||
import { DialogSplitItem } from "./dialog-split-item.js";
|
import { DialogSplitItem } from "./dialog-split-item.js";
|
||||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
||||||
import { STATUSES } from "./settings/status-effects.js";
|
import { STATUSES } from "./settings/status-effects.js";
|
||||||
import { MAINS_DIRECTRICES } from "./actor.js";
|
import { MAINS_DIRECTRICES } from "./actor.js";
|
||||||
import { RdDBaseActorSheet } from "./actor/base-actor-sheet.js";
|
import { RdDBaseActorReveSheet } from "./actor/base-actor-reve-sheet.js";
|
||||||
import { RdDItem } from "./item.js";
|
import { RdDItem } from "./item.js";
|
||||||
import { RdDItemBlessure } from "./item/blessure.js";
|
import { RdDItemBlessure } from "./item/blessure.js";
|
||||||
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
||||||
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/**
|
/**
|
||||||
* Extend the basic ActorSheet with some very simple modifications
|
* Extend the basic ActorSheet with some very simple modifications
|
||||||
* @extends {ActorSheet}
|
* @extends {ActorSheet}
|
||||||
*/
|
*/
|
||||||
export class RdDActorSheet extends RdDBaseActorSheet {
|
export class RdDActorSheet extends RdDBaseActorReveSheet {
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
RdDUtility.initAfficheContenu();
|
return mergeObject(RdDBaseActorReveSheet.defaultOptions, {
|
||||||
return mergeObject(super.defaultOptions, {
|
|
||||||
classes: ["rdd", "sheet", "actor"],
|
|
||||||
template: "systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html",
|
template: "systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html",
|
||||||
width: 550,
|
width: 550,
|
||||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
|
|
||||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }],
|
|
||||||
showCompNiveauBase: false,
|
showCompNiveauBase: false,
|
||||||
vueDetaillee: false
|
vueArchetype: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +52,8 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
surprise: RdDBonus.find(this.actor.getSurprise(false)).descr,
|
surprise: RdDBonus.find(this.actor.getSurprise(false)).descr,
|
||||||
resumeBlessures: this.actor.computeResumeBlessure(this.actor.system.blessures),
|
resumeBlessures: this.actor.computeResumeBlessure(this.actor.system.blessures),
|
||||||
caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute),
|
caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute),
|
||||||
surEncombrementMessage: this.actor.getMessageSurEncombrement(),
|
surEncombrementMessage: this.actor.isSurenc() ? "Sur-Encombrement!" : "",
|
||||||
|
malusArmure: this.actor.getMalusArmure()
|
||||||
})
|
})
|
||||||
|
|
||||||
this.timerRecherche = undefined;
|
this.timerRecherche = undefined;
|
||||||
@@ -79,9 +77,12 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// toujours avoir une liste d'armes (pour mettre esquive et corps à corps)
|
// toujours avoir une liste d'armes (pour mettre esquive et corps à corps)
|
||||||
formData.combat = duplicate(formData.armes ?? []);
|
const actor = this.actor;
|
||||||
|
formData.combat = duplicate(formData.armes);
|
||||||
RdDItemArme.computeNiveauArmes(formData.combat, formData.competences);
|
RdDItemArme.computeNiveauArmes(formData.combat, formData.competences);
|
||||||
RdDItemArme.ajoutCorpsACorps(formData.combat, formData.competences, formData.system.carac);
|
formData.combat.push(RdDItemArme.mainsNues(actor));
|
||||||
|
formData.combat.push(RdDItemArme.empoignade(actor));
|
||||||
|
|
||||||
formData.esquives = this.actor.getCompetences("Esquive");
|
formData.esquives = this.actor.getCompetences("Esquive");
|
||||||
formData.combat = RdDCombatManager.listActionsArmes(formData.combat, formData.competences, formData.system.carac);
|
formData.combat = RdDCombatManager.listActionsArmes(formData.combat, formData.competences, formData.system.carac);
|
||||||
formData.empoignades = this.actor.getEmpoignades();
|
formData.empoignades = this.actor.getEmpoignades();
|
||||||
@@ -110,20 +111,28 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */ /** @override */
|
/* -------------------------------------------- */
|
||||||
|
/** @override */
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
|
|
||||||
HtmlUtility.showControlWhen(this.html.find(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue"));
|
HtmlUtility.showControlWhen(this.html.find(".appliquerFatigue"), ReglesOptionnelles.isUsing("appliquer-fatigue"));
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
||||||
this.html.find('.item-action').click(async event => {
|
this.html.find('.sheet-possession-attack').click(async event => {
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
const poss = RdDSheetUtility.getItem(event, this.actor)
|
||||||
item?.actionPrincipale(this.actor, async () => this.render())
|
this.actor.conjurerPossession(poss)
|
||||||
});
|
})
|
||||||
|
|
||||||
|
this.html.find('.subacteur-label a').click(async event => {
|
||||||
|
let actorId = RdDSheetUtility.getEventItemData(event, 'actor-id');
|
||||||
|
let actor = game.actors.get(actorId);
|
||||||
|
if (actor) {
|
||||||
|
actor.sheet.render(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
this.html.find('.subacteur-delete').click(async event => {
|
this.html.find('.subacteur-delete').click(async event => {
|
||||||
const li = RdDSheetUtility.getEventElement(event);
|
const li = RdDSheetUtility.getEventElement(event);
|
||||||
const actorId = li.data("actor-id");
|
const actorId = li.data("actor-id");
|
||||||
@@ -153,18 +162,6 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
this.actor.updateCompteurValue("experience", parseInt(event.target.value));
|
this.actor.updateCompteurValue("experience", parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
|
|
||||||
this.html.find('.encaisser-direct').click(async event => {
|
|
||||||
this.actor.encaisser();
|
|
||||||
})
|
|
||||||
this.html.find('.sheet-possession-attack').click(async event => {
|
|
||||||
const poss = RdDSheetUtility.getItem(event, this.actor)
|
|
||||||
this.actor.conjurerPossession(poss)
|
|
||||||
})
|
|
||||||
this.html.find('.remise-a-neuf').click(async event => {
|
|
||||||
if (game.user.isGM) {
|
|
||||||
this.actor.remiseANeuf();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.html.find('.creer-tache').click(async event => {
|
this.html.find('.creer-tache').click(async event => {
|
||||||
this.createEmptyTache();
|
this.createEmptyTache();
|
||||||
});
|
});
|
||||||
@@ -174,9 +171,7 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
this.html.find('.creer-blessure-legere').click(async event => RdDItemBlessure.createBlessure(this.actor, 2));
|
this.html.find('.creer-blessure-legere').click(async event => RdDItemBlessure.createBlessure(this.actor, 2));
|
||||||
this.html.find('.creer-blessure-grave').click(async event => RdDItemBlessure.createBlessure(this.actor, 4));
|
this.html.find('.creer-blessure-grave').click(async event => RdDItemBlessure.createBlessure(this.actor, 4));
|
||||||
this.html.find('.creer-blessure-critique').click(async event => RdDItemBlessure.createBlessure(this.actor, 6));
|
this.html.find('.creer-blessure-critique').click(async event => RdDItemBlessure.createBlessure(this.actor, 6));
|
||||||
this.html.find('.creer-une-oeuvre').click(async event => {
|
this.html.find('.creer-une-oeuvre').click(async event => this.selectTypeOeuvreToCreate());
|
||||||
this.selectTypeOeuvreToCreate();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.html.find('.blessure-premierssoins-done').change(async event => {
|
this.html.find('.blessure-premierssoins-done').change(async event => {
|
||||||
const blessure = this.getBlessure(event);
|
const blessure = this.getBlessure(event);
|
||||||
@@ -201,11 +196,6 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Roll Carac
|
// Roll Carac
|
||||||
this.html.find('.carac-label a').click(async event => {
|
|
||||||
let caracName = event.currentTarget.attributes.name.value;
|
|
||||||
this.actor.rollCarac(caracName.toLowerCase());
|
|
||||||
});
|
|
||||||
|
|
||||||
this.html.find('.chance-actuelle').click(async event => {
|
this.html.find('.chance-actuelle').click(async event => {
|
||||||
this.actor.rollCarac('chance-actuelle');
|
this.actor.rollCarac('chance-actuelle');
|
||||||
});
|
});
|
||||||
@@ -214,14 +204,10 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
this.actor.rollAppelChance();
|
this.actor.rollAppelChance();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Roll Skill
|
||||||
this.html.find('[name="jet-astrologie"]').click(async event => {
|
this.html.find('[name="jet-astrologie"]').click(async event => {
|
||||||
this.actor.astrologieNombresAstraux();
|
this.actor.astrologieNombresAstraux();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Roll Skill
|
|
||||||
this.html.find('a.competence-label').click(async event => {
|
|
||||||
this.actor.rollCompetence(RdDSheetUtility.getItemId(event));
|
|
||||||
});
|
|
||||||
this.html.find('.tache-label a').click(async event => {
|
this.html.find('.tache-label a').click(async event => {
|
||||||
this.actor.rollTache(RdDSheetUtility.getItemId(event));
|
this.actor.rollTache(RdDSheetUtility.getItemId(event));
|
||||||
});
|
});
|
||||||
@@ -246,13 +232,6 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
this.html.find('.recettecuisine-label a').click(async event => {
|
this.html.find('.recettecuisine-label a').click(async event => {
|
||||||
this.actor.rollRecetteCuisine(RdDSheetUtility.getItemId(event));
|
this.actor.rollRecetteCuisine(RdDSheetUtility.getItemId(event));
|
||||||
});
|
});
|
||||||
this.html.find('.subacteur-label a').click(async event => {
|
|
||||||
let actorId = RdDSheetUtility.getEventItemData(event, 'actor-id');
|
|
||||||
let actor = game.actors.get(actorId);
|
|
||||||
if (actor) {
|
|
||||||
actor.sheet.render(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Boutons spéciaux MJs
|
// Boutons spéciaux MJs
|
||||||
this.html.find('.forcer-tmr-aleatoire').click(async event => {
|
this.html.find('.forcer-tmr-aleatoire').click(async event => {
|
||||||
@@ -287,35 +266,12 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat.");
|
ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Display TMR, visualisation
|
// Display TMR
|
||||||
this.html.find('.visu-tmr').click(async event => {
|
this.html.find('.visu-tmr').click(async event => { this.actor.displayTMR("visu") })
|
||||||
this.actor.displayTMR("visu");
|
this.html.find('.monte-tmr').click(async event => { this.actor.displayTMR("normal") })
|
||||||
});
|
this.html.find('.monte-tmr-rapide').click(async event => { this.actor.displayTMR("rapide") })
|
||||||
|
|
||||||
// Display TMR, normal
|
this.html.find('.repos').click(async event => { await this.actor.repos() })
|
||||||
this.html.find('.monte-tmr').click(async event => {
|
|
||||||
this.actor.displayTMR("normal");
|
|
||||||
});
|
|
||||||
|
|
||||||
// Display TMR, fast
|
|
||||||
this.html.find('.monte-tmr-rapide').click(async event => {
|
|
||||||
this.actor.displayTMR("rapide");
|
|
||||||
});
|
|
||||||
|
|
||||||
this.html.find('.repos').click(async event => {
|
|
||||||
await this.actor.repos();
|
|
||||||
});
|
|
||||||
this.html.find('.delete-active-effect').click(async event => {
|
|
||||||
if (game.user.isGM) {
|
|
||||||
let effect = this.html.find(event.currentTarget).parents(".active-effect").data('effect');
|
|
||||||
this.actor.removeEffect(effect);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.html.find('.enlever-tous-effets').click(async event => {
|
|
||||||
if (game.user.isGM) {
|
|
||||||
await this.actor.removeEffects();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.html.find('.carac-xp-augmenter').click(async event => {
|
this.html.find('.carac-xp-augmenter').click(async event => {
|
||||||
let caracName = event.currentTarget.name.replace("augmenter.", "");
|
let caracName = event.currentTarget.name.replace("augmenter.", "");
|
||||||
this.actor.updateCaracXPAuto(caracName);
|
this.actor.updateCaracXPAuto(caracName);
|
||||||
@@ -329,47 +285,39 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
|
|
||||||
if (this.options.vueDetaillee) {
|
if (this.options.vueDetaillee) {
|
||||||
// On carac change
|
// On carac change
|
||||||
this.html.find('.carac-value').change(async event => {
|
|
||||||
let caracName = event.currentTarget.name.replace(".value", "").replace("system.carac.", "");
|
|
||||||
this.actor.updateCarac(caracName, parseInt(event.target.value));
|
|
||||||
});
|
|
||||||
this.html.find('input.carac-xp').change(async event => {
|
this.html.find('input.carac-xp').change(async event => {
|
||||||
let caracName = event.currentTarget.name.replace(".xp", "").replace("system.carac.", "");
|
let caracName = event.currentTarget.name.replace(".xp", "").replace("system.carac.", "");
|
||||||
this.actor.updateCaracXP(caracName, parseInt(event.target.value));
|
this.actor.updateCaracXP(caracName, parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
// On competence change
|
|
||||||
this.html.find('.competence-value').change(async event => {
|
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
|
||||||
//console.log("Competence changed :", compName);
|
|
||||||
this.actor.updateCompetence(compName, parseInt(event.target.value));
|
|
||||||
});
|
|
||||||
// On competence xp change
|
// On competence xp change
|
||||||
this.html.find('input.competence-xp').change(async event => {
|
this.html.find('input.competence-xp').change(async event => {
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
this.actor.updateCompetenceXP(compName, parseInt(event.target.value));
|
this.actor.updateCompetenceXP(compName, parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
// On competence xp change
|
|
||||||
this.html.find('input.competence-xp-sort').change(async event => {
|
this.html.find('input.competence-xp-sort').change(async event => {
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
this.actor.updateCompetenceXPSort(compName, parseInt(event.target.value));
|
this.actor.updateCompetenceXPSort(compName, parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.html.find('.toggle-archetype').click(async event => {
|
||||||
|
this.options.vueArchetype = !this.options.vueArchetype;
|
||||||
|
this.render(true);
|
||||||
|
});
|
||||||
// On competence archetype change
|
// On competence archetype change
|
||||||
this.html.find('.competence-archetype').change(async event => {
|
this.html.find('.competence-archetype').change(async event => {
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
this.actor.updateCompetenceArchetype(compName, parseInt(event.target.value));
|
this.actor.updateCompetenceArchetype(compName, parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
this.html.find('.nouvelle-incarnation').click(async event => {
|
||||||
|
this.actor.nouvelleIncarnation();
|
||||||
|
});
|
||||||
|
|
||||||
this.html.find('.show-hide-competences').click(async event => {
|
this.html.find('.show-hide-competences').click(async event => {
|
||||||
this.options.showCompNiveauBase = !this.options.showCompNiveauBase;
|
this.options.showCompNiveauBase = !this.options.showCompNiveauBase;
|
||||||
this.render(true);
|
this.render(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.html.find('.vue-detaillee').click(async event => {
|
|
||||||
this.options.vueDetaillee = !this.options.vueDetaillee;
|
|
||||||
this.render(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
// On pts de reve change
|
// On pts de reve change
|
||||||
this.html.find('.pointsreve-value').change(async event => {
|
this.html.find('.pointsreve-value').change(async event => {
|
||||||
let reveValue = event.currentTarget.value;
|
let reveValue = event.currentTarget.value;
|
||||||
@@ -382,11 +330,6 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
this.actor.setPointsDeSeuil(event.currentTarget.value);
|
this.actor.setPointsDeSeuil(event.currentTarget.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
// On stress change
|
|
||||||
this.html.find('.compteur-edit').change(async event => {
|
|
||||||
let fieldName = event.currentTarget.attributes.name.value;
|
|
||||||
this.actor.updateCompteurValue(fieldName, parseInt(event.target.value));
|
|
||||||
});
|
|
||||||
|
|
||||||
this.html.find('.stress-test').click(async event => {
|
this.html.find('.stress-test').click(async event => {
|
||||||
this.actor.transformerStress();
|
this.actor.transformerStress();
|
||||||
@@ -408,7 +351,7 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
this.actor.jetVie();
|
this.actor.jetVie();
|
||||||
});
|
});
|
||||||
this.html.find('.jet-endurance').click(async event => {
|
this.html.find('.jet-endurance').click(async event => {
|
||||||
this.actor.jetEndurance();
|
await this.jetEndurance();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.html.find('.vie-plus').click(async event => {
|
this.html.find('.vie-plus').click(async event => {
|
||||||
@@ -417,12 +360,6 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
this.html.find('.vie-moins').click(async event => {
|
this.html.find('.vie-moins').click(async event => {
|
||||||
this.actor.santeIncDec("vie", -1);
|
this.actor.santeIncDec("vie", -1);
|
||||||
});
|
});
|
||||||
this.html.find('.endurance-plus').click(async event => {
|
|
||||||
this.actor.santeIncDec("endurance", 1);
|
|
||||||
});
|
|
||||||
this.html.find('.endurance-moins').click(async event => {
|
|
||||||
this.actor.santeIncDec("endurance", -1);
|
|
||||||
});
|
|
||||||
this.html.find('.ptreve-actuel-plus').click(async event => {
|
this.html.find('.ptreve-actuel-plus').click(async event => {
|
||||||
this.actor.reveActuelIncDec(1);
|
this.actor.reveActuelIncDec(1);
|
||||||
});
|
});
|
||||||
@@ -437,6 +374,16 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async jetEndurance() {
|
||||||
|
const endurance = this.actor.getEnduranceActuelle()
|
||||||
|
const result = await this.actor.jetEndurance(endurance);
|
||||||
|
ChatMessage.create({
|
||||||
|
content: `Jet d'Endurance : ${result.jetEndurance} / ${endurance}
|
||||||
|
<br>${this.actor.name} a ${result.sonne ? 'échoué' : 'réussi'} son Jet d'Endurance ${result.sonne ? 'et devient Sonné' : ''}`,
|
||||||
|
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.actor.name)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
getBlessure(event) {
|
getBlessure(event) {
|
||||||
const itemId = this.html.find(event.currentTarget).parents(".item-blessure").data('item-id');
|
const itemId = this.html.find(event.currentTarget).parents(".item-blessure").data('item-id');
|
||||||
const blessure = this.actor.getItem(itemId, 'blessure');
|
const blessure = this.actor.getItem(itemId, 'blessure');
|
||||||
|
|||||||
1192
module/actor.js
1192
module/actor.js
File diff suppressed because it is too large
Load Diff
64
module/actor/base-actor-reve-sheet.js
Normal file
64
module/actor/base-actor-reve-sheet.js
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import { RdDSheetUtility } from "../rdd-sheet-utility.js";
|
||||||
|
import { RdDBaseActorSheet } from "./base-actor-sheet.js";
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Extend the basic ActorSheet with some very simple modifications
|
||||||
|
* @extends {ActorSheet}
|
||||||
|
*/
|
||||||
|
export class RdDBaseActorReveSheet extends RdDBaseActorSheet {
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static get defaultOptions() {
|
||||||
|
return mergeObject(RdDBaseActorSheet.defaultOptions, {
|
||||||
|
width: 550
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/** @override */
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
|
||||||
|
// Everything below here is only needed if the sheet is editable
|
||||||
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
|
this.html.find('.encaisser-direct').click(async event => {
|
||||||
|
this.actor.encaisser();
|
||||||
|
})
|
||||||
|
this.html.find('.remise-a-neuf').click(async event => {
|
||||||
|
if (game.user.isGM) {
|
||||||
|
this.actor.remiseANeuf();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.html.find('.carac-label a').click(async event => {
|
||||||
|
let caracName = event.currentTarget.attributes.name.value;
|
||||||
|
this.actor.rollCarac(caracName.toLowerCase());
|
||||||
|
});
|
||||||
|
|
||||||
|
this.html.find('a.competence-label').click(async event => {
|
||||||
|
this.actor.rollCompetence(RdDSheetUtility.getItemId(event));
|
||||||
|
});
|
||||||
|
|
||||||
|
this.html.find('.delete-active-effect').click(async event => {
|
||||||
|
if (game.user.isGM) {
|
||||||
|
let effect = this.html.find(event.currentTarget).parents(".active-effect").data('effect');
|
||||||
|
this.actor.removeEffect(effect);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.html.find('.enlever-tous-effets').click(async event => {
|
||||||
|
if (game.user.isGM) {
|
||||||
|
await this.actor.removeEffects();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.html.find('.endurance-plus').click(async event => {
|
||||||
|
this.actor.santeIncDec("endurance", 1);
|
||||||
|
});
|
||||||
|
this.html.find('.endurance-moins').click(async event => {
|
||||||
|
this.actor.santeIncDec("endurance", -1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
509
module/actor/base-actor-reve.js
Normal file
509
module/actor/base-actor-reve.js
Normal file
@@ -0,0 +1,509 @@
|
|||||||
|
import { ChatUtility } from "../chat-utility.js";
|
||||||
|
import { DialogValidationEncaissement } from "../dialog-validation-encaissement.js";
|
||||||
|
import { Grammar } from "../grammar.js";
|
||||||
|
import { RdDItemCompetence } from "../item-competence.js";
|
||||||
|
import { Misc } from "../misc.js";
|
||||||
|
import { RdDEmpoignade } from "../rdd-empoignade.js";
|
||||||
|
import { RdDResolutionTable } from "../rdd-resolution-table.js";
|
||||||
|
import { RdDEncaisser } from "../rdd-roll-encaisser.js";
|
||||||
|
import { RdDRoll } from "../rdd-roll.js";
|
||||||
|
import { RdDUtility } from "../rdd-utility.js";
|
||||||
|
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
|
||||||
|
import { RdDBaseActor } from "./base-actor.js";
|
||||||
|
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
|
||||||
|
import { StatusEffects } from "../settings/status-effects.js";
|
||||||
|
import { TYPES } from "../item.js";
|
||||||
|
import { Targets } from "../targets.js";
|
||||||
|
import { RdDPossession } from "../rdd-possession.js";
|
||||||
|
import { RdDCombat } from "../rdd-combat.js";
|
||||||
|
import { RdDConfirm } from "../rdd-confirm.js";
|
||||||
|
import { ENTITE_INCARNE, SYSTEM_RDD } from "../constants.js";
|
||||||
|
import { RdDItemArme } from "../item-arme.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",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe de base pour les acteurs disposant de rêve (donc, pas des objets)
|
||||||
|
* - Entités de rêve
|
||||||
|
* - Créatures de "sang": créatures et humanoides
|
||||||
|
*/
|
||||||
|
export class RdDBaseActorReve extends RdDBaseActor {
|
||||||
|
|
||||||
|
getCaracChanceActuelle() {
|
||||||
|
return {
|
||||||
|
label: 'Chance actuelle',
|
||||||
|
value: this.getChanceActuel(),
|
||||||
|
type: "number"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getCaracReveActuel() {
|
||||||
|
return {
|
||||||
|
label: 'Rêve actuel',
|
||||||
|
value: this.getReveActuel(),
|
||||||
|
type: "number"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getReveActuel() { return this.getReve() }
|
||||||
|
getChanceActuel() { return this.getChance() }
|
||||||
|
|
||||||
|
getReve() { return Number(this.system.carac.reve?.value ?? 0) }
|
||||||
|
getForce() { return this.getReve() }
|
||||||
|
getTaille() { return Number(this.system.carac.taille?.value ?? 0) }
|
||||||
|
getAgilite() { return this.getForce() }
|
||||||
|
getChance() { return this.getReve() }
|
||||||
|
getMoralTotal() { return 0 }
|
||||||
|
getBonusDegat() { return Number(this.system.attributs?.plusdom?.value ?? 0) }
|
||||||
|
getProtectionNaturelle() { return Number(this.system.attributs?.protection?.value ?? 0) }
|
||||||
|
getSConst() { return 0 }
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getEncombrementMax() { return 0 }
|
||||||
|
isSurenc() { return false }
|
||||||
|
computeMalusSurEncombrement() { return 0 }
|
||||||
|
|
||||||
|
ajustementAstrologique() { return 0 }
|
||||||
|
getMalusArmure() { return 0 }
|
||||||
|
|
||||||
|
getEnduranceActuelle() {
|
||||||
|
return Number(this.system.sante?.endurance?.value ?? 0);
|
||||||
|
}
|
||||||
|
async jetEndurance(resteEndurance = undefined) { return { jetEndurance: 0, sonne: false } }
|
||||||
|
isDead() { return false }
|
||||||
|
blessuresASoigner() { return [] }
|
||||||
|
getEtatGeneral(options = { ethylisme: false }) { return 0 }
|
||||||
|
|
||||||
|
async computeArmure(attackerRoll) { return this.getProtectionNaturelle() }
|
||||||
|
async remiseANeuf() { }
|
||||||
|
async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { }
|
||||||
|
|
||||||
|
async santeIncDec(name, inc, isCritique = false) { }
|
||||||
|
|
||||||
|
async finDeRound(options = { terminer: false }) {
|
||||||
|
await this.$finDeRoundSuppressionEffetsTermines(options);
|
||||||
|
await this.finDeRoundBlessures();
|
||||||
|
await this.$finDeRoundSupprimerObsoletes();
|
||||||
|
await this.$finDeRoundEmpoignade();
|
||||||
|
}
|
||||||
|
|
||||||
|
async $finDeRoundSuppressionEffetsTermines(options) {
|
||||||
|
for (let effect of this.getEffects()) {
|
||||||
|
if (effect.duration.type !== 'none' && (effect.duration.remaining <= 0 || options.terminer)) {
|
||||||
|
await effect.delete();
|
||||||
|
ChatMessage.create({ content: `${this.name} n'est plus ${Misc.lowerFirst(game.i18n.localize(effect.system.label))} !` });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async finDeRoundBlessures() {
|
||||||
|
}
|
||||||
|
|
||||||
|
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) { }
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getCompetence(idOrName, options = {}) {
|
||||||
|
if (idOrName instanceof Item) {
|
||||||
|
return idOrName.isCompetence() ? idOrName : undefined
|
||||||
|
}
|
||||||
|
return RdDItemCompetence.findCompetence(this.items, idOrName, options)
|
||||||
|
}
|
||||||
|
getCompetences(name) {
|
||||||
|
return RdDItemCompetence.findCompetences(this.items, name)
|
||||||
|
}
|
||||||
|
getCompetenceCorpsACorps(options = {}) {
|
||||||
|
return this.getCompetence("Corps à corps", options)
|
||||||
|
}
|
||||||
|
getCompetencesEsquive() {
|
||||||
|
return this.getCompetences("esquive")
|
||||||
|
}
|
||||||
|
|
||||||
|
getArmeParade(armeParadeId) {
|
||||||
|
const item = armeParadeId ? this.getEmbeddedDocument('Item', armeParadeId) : undefined;
|
||||||
|
return RdDItemArme.getArme(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDraconicOuPossession() {
|
||||||
|
return POSSESSION_SANS_DRACONIC
|
||||||
|
}
|
||||||
|
|
||||||
|
getPossession(possessionId) {
|
||||||
|
return this.itemTypes[TYPES.possession].find(it => it.system.possessionid == possessionId);
|
||||||
|
}
|
||||||
|
getPossessions() {
|
||||||
|
return this.itemTypes[TYPES.possession];
|
||||||
|
}
|
||||||
|
getEmpoignades() {
|
||||||
|
return this.itemTypes[TYPES.empoignade];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async updateCreatureCompetence(idOrName, fieldName, value) {
|
||||||
|
let competence = this.getCompetence(idOrName);
|
||||||
|
if (competence) {
|
||||||
|
function getFieldPath(fieldName) {
|
||||||
|
switch (fieldName) {
|
||||||
|
case "niveau": return 'system.niveau';
|
||||||
|
case "dommages": return 'system.dommages';
|
||||||
|
case "carac_value": return 'system.carac_value';
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
const path = getFieldPath(fieldName);
|
||||||
|
if (path) {
|
||||||
|
await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, [path]: value }]); // updates one EmbeddedEntity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
isEffectAllowed(statusId) { return true }
|
||||||
|
|
||||||
|
getEffects(filter = e => true) {
|
||||||
|
return this.getEmbeddedCollection("ActiveEffect").filter(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
getEffect(statusId) {
|
||||||
|
return this.getEmbeddedCollection("ActiveEffect").find(it => it.flags?.core?.statusId == statusId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async setEffect(statusId, status) {
|
||||||
|
if (this.isEffectAllowed(statusId)) {
|
||||||
|
const effect = this.getEffect(statusId);
|
||||||
|
if (!status && effect) {
|
||||||
|
await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id]);
|
||||||
|
}
|
||||||
|
if (status && !effect) {
|
||||||
|
await this.createEmbeddedDocuments("ActiveEffect", [StatusEffects.status(statusId)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeEffect(statusId) {
|
||||||
|
const effect = this.getEffect(statusId);
|
||||||
|
if (effect) {
|
||||||
|
await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeEffects(filter = e => true) {
|
||||||
|
if (game.user.isGM) {
|
||||||
|
const ids = this.getEffects(filter).map(it => it.id);
|
||||||
|
await this.deleteEmbeddedDocuments('ActiveEffect', ids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getSurprise(isCombat = undefined) {
|
||||||
|
let niveauSurprise = this.getEffects()
|
||||||
|
.map(effect => StatusEffects.valeurSurprise(effect, isCombat))
|
||||||
|
.reduce(Misc.sum(), 0);
|
||||||
|
if (niveauSurprise > 1) {
|
||||||
|
return 'totale';
|
||||||
|
}
|
||||||
|
if (niveauSurprise == 1) {
|
||||||
|
return 'demi';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async computeEtatGeneral() {
|
||||||
|
// Par défaut, on ne calcule pas d'état général, seuls les personnages/créatures sont affectés
|
||||||
|
this.system.compteurs.etat.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async openRollDialog({ name, label, template, rollData, callbackAction }) {
|
||||||
|
const dialog = await RdDRoll.create(this, rollData,
|
||||||
|
{ html: template, close: async html => await this._onCloseRollDialog(html) },
|
||||||
|
{
|
||||||
|
name: name,
|
||||||
|
label: label,
|
||||||
|
callbacks: [
|
||||||
|
this.createCallbackExperience(),
|
||||||
|
this.createCallbackAppelAuMoral(),
|
||||||
|
{ action: callbackAction }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
dialog.render(true);
|
||||||
|
return dialog
|
||||||
|
}
|
||||||
|
|
||||||
|
createEmptyCallback() {
|
||||||
|
return {
|
||||||
|
condition: r => false,
|
||||||
|
action: r => { }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
createCallbackExperience() { return this.createEmptyCallback(); }
|
||||||
|
createCallbackAppelAuMoral() { return this.createEmptyCallback(); }
|
||||||
|
async _onCloseRollDialog(html) { }
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async roll() {
|
||||||
|
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||||
|
|
||||||
|
const carac = this.getCarac()
|
||||||
|
const selectedCaracName = ['apparence', 'perception', 'force', 'reve'].find(it => carac[it] != undefined)
|
||||||
|
|
||||||
|
await this.openRollDialog({
|
||||||
|
name: `jet-${this.id}`,
|
||||||
|
label: `Jet de ${this.name}`,
|
||||||
|
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll.html',
|
||||||
|
rollData: {
|
||||||
|
carac: carac,
|
||||||
|
selectedCarac: carac[selectedCaracName],
|
||||||
|
selectedCaracName: selectedCaracName,
|
||||||
|
competences: this.itemTypes['competence']
|
||||||
|
},
|
||||||
|
callbackAction: r => this.$onRollCaracResult(r)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getCarac() {
|
||||||
|
// TODO: le niveau d'une entité de cauchemar devrait être exclu...
|
||||||
|
const carac = mergeObject(duplicate(this.system.carac),
|
||||||
|
{
|
||||||
|
'reve-actuel': this.getCaracReveActuel(),
|
||||||
|
'chance-actuelle': this.getCaracChanceActuelle()
|
||||||
|
});
|
||||||
|
return carac;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async rollCarac(caracName, jetResistance = undefined) {
|
||||||
|
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||||
|
let selectedCarac = this.getCaracByName(caracName)
|
||||||
|
await this.openRollDialog({
|
||||||
|
name: 'jet-' + caracName,
|
||||||
|
label: 'Jet ' + Grammar.apostrophe('de', selectedCarac.label),
|
||||||
|
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html',
|
||||||
|
rollData: {
|
||||||
|
selectedCarac: selectedCarac,
|
||||||
|
competences: this.itemTypes['competence'],
|
||||||
|
jetResistance: jetResistance ? caracName : undefined
|
||||||
|
},
|
||||||
|
callbackAction: r => this.$onRollCaracResult(r)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async $onRollCaracResult(rollData) {
|
||||||
|
// Final chat message
|
||||||
|
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-general.html');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async rollCompetence(idOrName, options = { tryTarget: true }) {
|
||||||
|
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||||
|
const competence = this.getCompetence(idOrName);
|
||||||
|
let rollData = { carac: this.system.carac, competence: competence }
|
||||||
|
if (competence.type == TYPES.competencecreature) {
|
||||||
|
const arme = RdDItemCompetenceCreature.armeCreature(competence)
|
||||||
|
if (arme && options.tryTarget && Targets.hasTargets()) {
|
||||||
|
Targets.selectOneToken(target => {
|
||||||
|
if (arme.action == "possession") {
|
||||||
|
RdDPossession.onAttaquePossession(target, this, competence)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Transformer la competence de créature
|
||||||
|
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.openRollDialog({
|
||||||
|
name: 'jet-competence',
|
||||||
|
label: 'Jet ' + Grammar.apostrophe('de', competence.name),
|
||||||
|
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
|
||||||
|
rollData: rollData,
|
||||||
|
callbackAction: r => this.$onRollCompetence(r, options)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async $onRollCompetence(rollData, options) {
|
||||||
|
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-competence.html')
|
||||||
|
if (options?.onRollAutomate) {
|
||||||
|
options.onRollAutomate(rollData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** --------------------------------------------
|
||||||
|
* @param {*} arme item d'arme/compétence de créature
|
||||||
|
* @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
rollArme(arme, categorieArme = "competence") {
|
||||||
|
let compToUse = this.$getCompetenceArme(arme, categorieArme)
|
||||||
|
if (!Targets.hasTargets()) {
|
||||||
|
RdDConfirm.confirmer({
|
||||||
|
settingConfirmer: "confirmer-combat-sans-cible",
|
||||||
|
content: `<p>Voulez vous faire un jet de ${compToUse} sans choisir de cible valide?
|
||||||
|
<br>Tous les jets de combats devront être gérés à la main
|
||||||
|
</p>`,
|
||||||
|
title: 'Ne pas utiliser les automatisation de combat',
|
||||||
|
buttonLabel: "Pas d'automatisation",
|
||||||
|
onAction: async () => {
|
||||||
|
this.rollCompetence(compToUse, { tryTarget: false })
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Targets.selectOneToken(target => {
|
||||||
|
if (Targets.isTargetEntite(target)) {
|
||||||
|
ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée avec votre ${arme.name}!!!!`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const competence = this.getCompetence(compToUse)
|
||||||
|
//console.log("RollArme", competence, arme)
|
||||||
|
if (competence.isCompetencePossession()) {
|
||||||
|
return RdDPossession.onAttaquePossession(target, this, competence);
|
||||||
|
}
|
||||||
|
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
$getCompetenceArme(arme, competenceName) {
|
||||||
|
switch (arme.type) {
|
||||||
|
case TYPES.competencecreature:
|
||||||
|
return arme.name
|
||||||
|
case TYPES.arme:
|
||||||
|
switch (competenceName) {
|
||||||
|
case 'competence': return arme.system.competence;
|
||||||
|
case 'unemain': return RdDItemArme.competence1Mains(arme);
|
||||||
|
case 'deuxmains': return RdDItemArme.competence2Mains(arme);
|
||||||
|
case 'tir': return arme.system.tir;
|
||||||
|
case 'lancer': return arme.system.lancer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
verifierForceMin(item) {
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async resetItemUse() { }
|
||||||
|
async incDecItemUse(itemId, inc = 1) { }
|
||||||
|
getItemUse(itemId) { return 0; }
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async encaisser() { await RdDEncaisser.encaisser(this) }
|
||||||
|
|
||||||
|
async encaisserDommages(rollData, attacker = undefined, show = undefined) {
|
||||||
|
if (attacker && !await attacker.accorder(this, 'avant-encaissement')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const attackerId = attacker?.id;
|
||||||
|
if (ReglesOptionnelles.isUsing('validation-encaissement-gr') && !game.user.isGM) {
|
||||||
|
RdDBaseActor.remoteActorCall({
|
||||||
|
tokenId: this.token?.id,
|
||||||
|
actorId: this.id,
|
||||||
|
method: 'appliquerEncaissement',
|
||||||
|
args: [rollData, show, attackerId]
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const armure = await this.computeArmure(rollData);
|
||||||
|
if (ReglesOptionnelles.isUsing('validation-encaissement-gr')) {
|
||||||
|
DialogValidationEncaissement.validerEncaissement(this, rollData, armure,
|
||||||
|
jet => this.$onEncaissement(jet, show, attacker));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const jet = await RdDUtility.jetEncaissement(rollData, armure, { showDice: SHOW_DICE });
|
||||||
|
await this.$onEncaissement(jet, show, attacker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async $onEncaissement(jet, show, attacker) {
|
||||||
|
await this.onAppliquerJetEncaissement(jet, attacker);
|
||||||
|
await this.$afficherEncaissement(jet, show);
|
||||||
|
}
|
||||||
|
|
||||||
|
async onAppliquerJetEncaissement(encaissement, attacker) { }
|
||||||
|
|
||||||
|
async $afficherEncaissement(encaissement, show) {
|
||||||
|
mergeObject(encaissement, {
|
||||||
|
alias: this.name,
|
||||||
|
hasPlayerOwner: this.hasPlayerOwner,
|
||||||
|
show: show ?? {}
|
||||||
|
});
|
||||||
|
|
||||||
|
await ChatUtility.createChatWithRollMode(this.name, {
|
||||||
|
roll: encaissement.roll,
|
||||||
|
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html', encaissement)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!encaissement.hasPlayerOwner && encaissement.endurance != 0) {
|
||||||
|
encaissement = duplicate(encaissement);
|
||||||
|
encaissement.isGM = true;
|
||||||
|
ChatMessage.create({
|
||||||
|
whisper: ChatMessage.getWhisperRecipients("GM"),
|
||||||
|
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html', encaissement)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async accorder(entite, when = 'avant-encaissement') {
|
||||||
|
if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar")
|
||||||
|
|| entite == undefined
|
||||||
|
|| !entite.isEntite([ENTITE_INCARNE])
|
||||||
|
|| entite.isEntiteAccordee(this)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const rolled = await RdDResolutionTable.roll(this.getReveActuel(), - Number(entite.system.carac.niveau.value));
|
||||||
|
const rollData = {
|
||||||
|
alias: this.name,
|
||||||
|
rolled: rolled,
|
||||||
|
entite: entite.name,
|
||||||
|
selectedCarac: this.system.carac.reve
|
||||||
|
};
|
||||||
|
|
||||||
|
if (rolled.isSuccess) {
|
||||||
|
await entite.setEntiteReveAccordee(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-accorder-cauchemar.html');
|
||||||
|
if (rolled.isPart) {
|
||||||
|
await this.appliquerAjoutExperience(rollData, true);
|
||||||
|
}
|
||||||
|
return rolled.isSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
isEntiteAccordee(attacker) { return true }
|
||||||
|
|
||||||
|
async setEntiteReveAccordee(attacker) {
|
||||||
|
ui.notifications.error("Impossible de s'accorder à " + this.name + ": ce n'est pas une entite de cauchemer/rêve");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
275
module/actor/base-actor-sang.js
Normal file
275
module/actor/base-actor-sang.js
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
import { MAX_ENDURANCE_FATIGUE, RdDUtility } from "../rdd-utility.js";
|
||||||
|
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
|
||||||
|
import { STATUSES } from "../settings/status-effects.js";
|
||||||
|
import { TYPES } from "../item.js";
|
||||||
|
import { RdDBaseActorReve } from "./base-actor-reve.js";
|
||||||
|
import { RdDDice } from "../rdd-dice.js";
|
||||||
|
import { RdDItemBlessure } from "../item/blessure.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe de base pour les acteurs qui peuvent subir des blessures
|
||||||
|
* - créatures
|
||||||
|
* - humanoides
|
||||||
|
*/
|
||||||
|
export class RdDBaseActorSang extends RdDBaseActorReve {
|
||||||
|
|
||||||
|
|
||||||
|
getForce() { return Number(this.system.carac.force?.value ?? 0) }
|
||||||
|
|
||||||
|
getBonusDegat() { return Number(this.system.attributs?.plusdom?.value ?? 0) }
|
||||||
|
getProtectionNaturelle() { return Number(this.system.attributs?.protection?.value ?? 0) }
|
||||||
|
getSConst() { return 0 }
|
||||||
|
|
||||||
|
getEnduranceMax() {
|
||||||
|
return Math.max(1, Math.min(this.system.sante.endurance.max, MAX_ENDURANCE_FATIGUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
getFatigueActuelle() {
|
||||||
|
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||||
|
return Math.max(0, Math.min(this.getFatigueMax(), this.system.sante.fatigue?.value));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
getFatigueRestante() {
|
||||||
|
return this.getFatigueMax() - this.getFatigueActuelle();
|
||||||
|
}
|
||||||
|
|
||||||
|
getFatigueMin() {
|
||||||
|
return this.system.sante.endurance.max - this.system.sante.endurance.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
getFatigueMax() { return this.getEnduranceMax() * 2 }
|
||||||
|
|
||||||
|
malusFatigue() {
|
||||||
|
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||||
|
return RdDUtility.calculMalusFatigue(this.getFatigueActuelle(), this.getEnduranceMax())
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getEncombrementMax() { return Number(this.system.attributs?.encombrement?.value ?? 0) }
|
||||||
|
isSurenc() { return this.computeMalusSurEncombrement() < 0 }
|
||||||
|
|
||||||
|
computeMalusSurEncombrement() {
|
||||||
|
return Math.min(0, Math.floor(this.getEncombrementMax() - this.encTotal));
|
||||||
|
}
|
||||||
|
|
||||||
|
isDead() {
|
||||||
|
return this.system.sante.vie.value < -this.getSConst()
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
computeResumeBlessure() {
|
||||||
|
const blessures = this.filterItems(it => it.system.gravite > 0, 'blessure')
|
||||||
|
|
||||||
|
const nbLegeres = blessures.filter(it => it.isLegere()).length;
|
||||||
|
const nbGraves = blessures.filter(it => it.isGrave()).length;
|
||||||
|
const nbCritiques = blessures.filter(it => it.isCritique()).length;
|
||||||
|
|
||||||
|
if (nbLegeres + nbGraves + nbCritiques == 0) {
|
||||||
|
return "Aucune blessure";
|
||||||
|
}
|
||||||
|
let resume = "Blessures:";
|
||||||
|
if (nbLegeres > 0) {
|
||||||
|
resume += " " + nbLegeres + " légère" + (nbLegeres > 1 ? "s" : "");
|
||||||
|
}
|
||||||
|
if (nbGraves > 0) {
|
||||||
|
if (nbLegeres > 0)
|
||||||
|
resume += ",";
|
||||||
|
resume += " " + nbGraves + " grave" + (nbGraves > 1 ? "s" : "");
|
||||||
|
}
|
||||||
|
if (nbCritiques > 0) {
|
||||||
|
if (nbGraves > 0 || nbLegeres > 0)
|
||||||
|
resume += ",";
|
||||||
|
resume += " une CRITIQUE !";
|
||||||
|
}
|
||||||
|
return resume;
|
||||||
|
}
|
||||||
|
|
||||||
|
blessuresASoigner() { return [] }
|
||||||
|
getEtatGeneral(options = { ethylisme: false }) { return 0 }
|
||||||
|
|
||||||
|
async computeArmure(attackerRoll) { return this.getProtectionNaturelle() }
|
||||||
|
async remiseANeuf() { }
|
||||||
|
async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { }
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
async onAppliquerJetEncaissement(encaissement, attacker) {
|
||||||
|
const santeOrig = duplicate(this.system.sante);
|
||||||
|
const blessure = await this.ajouterBlessure(encaissement, attacker); // Will update the result table
|
||||||
|
const perteVie = await this.santeIncDec("vie", -encaissement.vie);
|
||||||
|
const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, blessure?.isCritique());
|
||||||
|
|
||||||
|
mergeObject(encaissement, {
|
||||||
|
resteEndurance: perteEndurance.newValue,
|
||||||
|
sonne: perteEndurance.sonne,
|
||||||
|
jetEndurance: perteEndurance.jetEndurance,
|
||||||
|
endurance: perteEndurance.perte,
|
||||||
|
vie: santeOrig.vie.value - perteVie.newValue,
|
||||||
|
blessure: blessure
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async santeIncDec(name, inc, isCritique = false) {
|
||||||
|
if (name == 'fatigue' && !ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const sante = duplicate(this.system.sante)
|
||||||
|
let compteur = sante[name];
|
||||||
|
if (!compteur) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let result = {
|
||||||
|
sonne: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let minValue = name == "vie" ? -this.getSConst() - 1 : 0;
|
||||||
|
|
||||||
|
result.newValue = Math.max(minValue, Math.min(compteur.value + inc, compteur.max));
|
||||||
|
//console.log("New value ", inc, minValue, result.newValue);
|
||||||
|
let fatigue = 0;
|
||||||
|
if (name == "endurance") {
|
||||||
|
if (result.newValue == 0 && inc < 0 && !isCritique) { // perte endurance et endurance devient 0 (sauf critique) -> -1 vie
|
||||||
|
sante.vie.value--;
|
||||||
|
result.perteVie = true;
|
||||||
|
}
|
||||||
|
result.newValue = Math.max(0, result.newValue);
|
||||||
|
if (inc > 0) { // le max d'endurance s'applique seulement à la récupération
|
||||||
|
result.newValue = Math.min(result.newValue, this._computeEnduranceMax())
|
||||||
|
}
|
||||||
|
const perte = compteur.value - result.newValue;
|
||||||
|
result.perte = perte;
|
||||||
|
if (perte > 1) {
|
||||||
|
// Peut-être sonné si 2 points d'endurance perdus d'un coup
|
||||||
|
mergeObject(result, await this.jetEndurance(result.newValue));
|
||||||
|
} else if (inc > 0) {
|
||||||
|
await this.setSonne(false);
|
||||||
|
}
|
||||||
|
if (sante.fatigue && inc < 0) { // Each endurance lost -> fatigue lost
|
||||||
|
fatigue = perte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compteur.value = result.newValue;
|
||||||
|
// If endurance lost, then the same amount of fatigue cannot be recovered
|
||||||
|
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && sante.fatigue && fatigue > 0) {
|
||||||
|
sante.fatigue.value = Math.max(sante.fatigue.value + fatigue, this.getFatigueMin());
|
||||||
|
}
|
||||||
|
await this.update({ "system.sante": sante })
|
||||||
|
if (this.isDead()) {
|
||||||
|
await this.setEffect(STATUSES.StatusComma, true);
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async ajouterBlessure(encaissement, attacker = undefined) {
|
||||||
|
if (encaissement.gravite < 0) return;
|
||||||
|
if (encaissement.gravite > 0) {
|
||||||
|
while (this.countBlessures(it => it.system.gravite == encaissement.gravite) >= RdDItemBlessure.maxBlessures(encaissement.gravite) && encaissement.gravite <= 6) {
|
||||||
|
// Aggravation
|
||||||
|
encaissement.gravite += 2
|
||||||
|
if (encaissement.gravite > 2) {
|
||||||
|
encaissement.vie += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const endActuelle = this.getEnduranceActuelle();
|
||||||
|
const blessure = await RdDItemBlessure.createBlessure(this, encaissement.gravite, encaissement.dmg.loc.label, attacker);
|
||||||
|
if (blessure.isCritique()) {
|
||||||
|
encaissement.endurance = endActuelle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blessure.isMort()) {
|
||||||
|
this.setEffect(STATUSES.StatusComma, true);
|
||||||
|
encaissement.mort = true;
|
||||||
|
ChatMessage.create({
|
||||||
|
content: `<img class="chat-icon" src="icons/svg/skull.svg" alt="charge" />
|
||||||
|
<strong>${this.name} vient de succomber à une seconde blessure critique ! Que les Dragons gardent son Archétype en paix !</strong>`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return blessure;
|
||||||
|
}
|
||||||
|
|
||||||
|
async supprimerBlessures(filterToDelete) {
|
||||||
|
const toDelete = this.filterItems(filterToDelete, TYPES.blessure)
|
||||||
|
.map(it => it.id);
|
||||||
|
await this.deleteEmbeddedDocuments('Item', toDelete);
|
||||||
|
}
|
||||||
|
|
||||||
|
countBlessures(filter = it => !it.isContusion()) {
|
||||||
|
return this.filterItems(filter, 'blessure').length
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async jetVie() {
|
||||||
|
let roll = await RdDDice.roll("1d20");
|
||||||
|
let msgText = "Jet de Vie : " + roll.total + " / " + this.system.sante.vie.value + "<br>";
|
||||||
|
if (roll.total <= this.system.sante.vie.value) {
|
||||||
|
msgText += "Jet réussi, pas de perte de point de vie (prochain jet dans 1 round pour 1 critique, SC minutes pour une grave)";
|
||||||
|
if (roll.total == 1) {
|
||||||
|
msgText += "La durée entre 2 jets de vie est multipliée par 20 (20 rounds pour une critique, SCx20 minutes pour une grave)";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
msgText += "Jet échoué, vous perdez 1 point de vie";
|
||||||
|
await this.santeIncDec("vie", -1);
|
||||||
|
if (roll.total == 20) {
|
||||||
|
msgText += "Votre personnage est mort !!!!!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const message = {
|
||||||
|
content: msgText,
|
||||||
|
whisper: ChatMessage.getWhisperRecipients(this.name)
|
||||||
|
};
|
||||||
|
ChatMessage.create(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async jetEndurance(resteEndurance = undefined) {
|
||||||
|
const jetEndurance = (await RdDDice.roll("1d20")).total;
|
||||||
|
const sonne = jetEndurance == 20 || jetEndurance > (resteEndurance ?? this.system.sante.endurance.value)
|
||||||
|
if (sonne) {
|
||||||
|
await this.setSonne();
|
||||||
|
}
|
||||||
|
return { jetEndurance, sonne }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async finDeRoundBlessures() {
|
||||||
|
const nbGraves = this.filterItems(it => it.isGrave(), 'blessure').length;
|
||||||
|
if (nbGraves > 0) {
|
||||||
|
// Gestion blessure graves : -1 pt endurance par blessure grave
|
||||||
|
await this.santeIncDec("endurance", -nbGraves);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async setSonne(sonne = true) {
|
||||||
|
if (!game.combat && sonne) {
|
||||||
|
ui.notifications.info(`${this.name} est hors combat, il ne reste donc pas sonné`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await this.setEffect(STATUSES.StatusStunned, sonne);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSonne() {
|
||||||
|
return this.getEffect(STATUSES.StatusStunned);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async computeEtatGeneral() {
|
||||||
|
this.system.compteurs.etat.value = this.malusVie() + this.malusFatigue() + this.malusEthylisme();
|
||||||
|
}
|
||||||
|
|
||||||
|
malusVie() {
|
||||||
|
return Math.min(this.system.sante.vie.value - this.system.sante.vie.max, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
malusEthylisme() { return 0 }
|
||||||
|
malusFatigue() { return 0 }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -16,13 +16,10 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
/** @override */
|
/** @override */
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
RdDUtility.initAfficheContenu();
|
RdDUtility.initAfficheContenu();
|
||||||
return mergeObject(super.defaultOptions, {
|
return mergeObject(ActorSheet.defaultOptions, {
|
||||||
classes: ["rdd", "sheet", "actor"],
|
classes: ["rdd", "sheet", "actor"],
|
||||||
template: "systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html",
|
|
||||||
width: 550,
|
|
||||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
|
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
|
||||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }],
|
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }],
|
||||||
showCompNiveauBase: false,
|
|
||||||
vueDetaillee: false
|
vueDetaillee: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -31,7 +28,7 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
async getData() {
|
async getData() {
|
||||||
Monnaie.validerMonnaies(this.actor.itemTypes['monnaie']);
|
Monnaie.validerMonnaies(this.actor.itemTypes['monnaie']);
|
||||||
|
|
||||||
this.actor.recompute();
|
this.actor.computeEtatGeneral();
|
||||||
let formData = {
|
let formData = {
|
||||||
title: this.title,
|
title: this.title,
|
||||||
id: this.actor.id,
|
id: this.actor.id,
|
||||||
@@ -135,6 +132,13 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
this.html = html;
|
this.html = html;
|
||||||
|
|
||||||
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
|
this.html.find('.item-action').click(async event => {
|
||||||
|
const item = RdDSheetUtility.getItem(event, this.actor);
|
||||||
|
item?.actionPrincipale(this.actor, async () => this.render())
|
||||||
|
});
|
||||||
|
|
||||||
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);
|
||||||
@@ -167,6 +171,26 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
this.html.find('.nettoyer-conteneurs').click(async event => {
|
this.html.find('.nettoyer-conteneurs').click(async event => {
|
||||||
this.actor.nettoyerConteneurs();
|
this.actor.nettoyerConteneurs();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.html.find('.vue-detaillee').click(async event => {
|
||||||
|
this.options.vueDetaillee = !this.options.vueDetaillee;
|
||||||
|
this.render(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.options.vueDetaillee) {
|
||||||
|
// On carac change
|
||||||
|
this.html.find('.carac-value').change(async event => {
|
||||||
|
let caracName = event.currentTarget.name.replace(".value", "").replace("system.carac.", "");
|
||||||
|
this.actor.updateCarac(caracName, parseInt(event.target.value));
|
||||||
|
});
|
||||||
|
// On competence change
|
||||||
|
this.html.find('.competence-value').change(async event => {
|
||||||
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
|
//console.log("Competence changed :", compName);
|
||||||
|
this.actor.updateCompetence(compName, parseInt(event.target.value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_rechercherKeyup(event) {
|
_rechercherKeyup(event) {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { ChatUtility } from "../chat-utility.js";
|
import { ChatUtility } from "../chat-utility.js";
|
||||||
import { SYSTEM_SOCKET_ID } from "../constants.js";
|
import { SYSTEM_SOCKET_ID } from "../constants.js";
|
||||||
|
import { Grammar } from "../grammar.js";
|
||||||
import { Monnaie } from "../item-monnaie.js";
|
import { Monnaie } from "../item-monnaie.js";
|
||||||
|
import { TYPES } from "../item.js";
|
||||||
import { Misc } from "../misc.js";
|
import { Misc } from "../misc.js";
|
||||||
import { RdDAudio } from "../rdd-audio.js";
|
import { RdDAudio } from "../rdd-audio.js";
|
||||||
import { RdDConfirm } from "../rdd-confirm.js";
|
import { RdDConfirm } from "../rdd-confirm.js";
|
||||||
@@ -9,6 +11,33 @@ import { SystemCompendiums } from "../settings/system-compendiums.js";
|
|||||||
import { APP_ASTROLOGIE_REFRESH } from "../sommeil/app-astrologie.js";
|
import { APP_ASTROLOGIE_REFRESH } from "../sommeil/app-astrologie.js";
|
||||||
|
|
||||||
export class RdDBaseActor extends Actor {
|
export class RdDBaseActor extends Actor {
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static _findCaracByName(carac, name) {
|
||||||
|
name = Grammar.toLowerCaseNoAccent(name);
|
||||||
|
switch (name) {
|
||||||
|
case 'reve-actuel': case 'reve actuel':
|
||||||
|
return carac.reve;
|
||||||
|
case 'chance-actuelle': case 'chance actuelle':
|
||||||
|
return carac.chance;
|
||||||
|
}
|
||||||
|
|
||||||
|
const caracList = Object.entries(carac);
|
||||||
|
let entry = Misc.findFirstLike(name, caracList, { mapper: it => it[0], description: 'caractéristique' });
|
||||||
|
if (!entry || entry.length == 0) {
|
||||||
|
entry = Misc.findFirstLike(name, caracList, { mapper: it => it[1].label, description: 'caractéristique' });
|
||||||
|
}
|
||||||
|
return entry && entry.length > 0 ? carac[entry[0]] : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
getCaracByName(name) {
|
||||||
|
switch (Grammar.toLowerCaseNoAccent(name)) {
|
||||||
|
case 'reve-actuel': case 'reve actuel':
|
||||||
|
return this.getCaracReveActuel();
|
||||||
|
case 'chance-actuelle': case 'chance-actuelle':
|
||||||
|
return this.getCaracChanceActuelle();
|
||||||
|
}
|
||||||
|
return RdDBaseActor._findCaracByName(this.system.carac, name);
|
||||||
|
}
|
||||||
|
|
||||||
static getDefaultImg(itemType) {
|
static getDefaultImg(itemType) {
|
||||||
return game.system.rdd.actorClasses[itemType]?.defaultIcon ?? defaultItemImg[itemType];
|
return game.system.rdd.actorClasses[itemType]?.defaultIcon ?? defaultItemImg[itemType];
|
||||||
@@ -50,7 +79,13 @@ export class RdDBaseActor extends Actor {
|
|||||||
|
|
||||||
static onRemoteActorCall(callData, userId) {
|
static onRemoteActorCall(callData, userId) {
|
||||||
if (userId == game.user.id) {
|
if (userId == game.user.id) {
|
||||||
const actor = game.actors.get(callData?.actorId);
|
let actor = game.actors.get(callData?.actorId);
|
||||||
|
if (callData.tokenId) {
|
||||||
|
let token = canvas.tokens.placeables.find(t => t.id == callData.tokenId)
|
||||||
|
if (token) {
|
||||||
|
actor = token.actor
|
||||||
|
}
|
||||||
|
}
|
||||||
if (Misc.isOwnerPlayerOrUniqueConnectedGM(actor)) { // Seul le joueur choisi effectue l'appel: le joueur courant si propriétaire de l'actor, ou le MJ sinon
|
if (Misc.isOwnerPlayerOrUniqueConnectedGM(actor)) { // Seul le joueur choisi effectue l'appel: le joueur courant si propriétaire de l'actor, ou le MJ sinon
|
||||||
const args = callData.args;
|
const args = callData.args;
|
||||||
console.info(`RdDBaseActor.onRemoteActorCall: pour l'Actor ${callData.actorId}, appel de RdDBaseActor.${callData.method}(`, ...args, ')');
|
console.info(`RdDBaseActor.onRemoteActorCall: pour l'Actor ${callData.actorId}, appel de RdDBaseActor.${callData.method}(`, ...args, ')');
|
||||||
@@ -105,11 +140,39 @@ export class RdDBaseActor extends Actor {
|
|||||||
super(docData, context);
|
super(docData, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
isCreatureEntite() { return this.type == 'creature' || this.type == 'entite'; }
|
/* -------------------------------------------- */
|
||||||
isCreature() { return this.type == 'creature'; }
|
async _preCreate(data, options, user) {
|
||||||
isEntite() { return this.type == 'entite'; }
|
await super._preCreate(data, options, user);
|
||||||
isPersonnage() { return this.type == 'personnage'; }
|
|
||||||
isVehicule() { return this.type == 'vehicule'; }
|
// Configure prototype token settings
|
||||||
|
const prototypeToken = {};
|
||||||
|
if (this.type === "personnage") Object.assign(prototypeToken, {
|
||||||
|
sight: { enabled: true }, actorLink: true, disposition: CONST.TOKEN_DISPOSITIONS.FRIENDLY
|
||||||
|
});
|
||||||
|
this.updateSource({ prototypeToken });
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
prepareData() {
|
||||||
|
super.prepareData()
|
||||||
|
this.prepareActorData()
|
||||||
|
this.cleanupConteneurs()
|
||||||
|
this.computeEtatGeneral()
|
||||||
|
this.computeEncTotal()
|
||||||
|
}
|
||||||
|
|
||||||
|
async prepareActorData() { }
|
||||||
|
async computeEtatGeneral() { }
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
findPlayer() {
|
||||||
|
return game.users.players.find(player => player.active && player.character?.id == this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
isCreatureEntite() { return this.isCreature() || this.isEntite() }
|
||||||
|
isCreature() { return false }
|
||||||
|
isEntite(typeentite = []) { return false }
|
||||||
|
isVehicule() { return false }
|
||||||
|
isPersonnage() { return false }
|
||||||
getItem(id, type = undefined) {
|
getItem(id, type = undefined) {
|
||||||
const item = this.items.get(id);
|
const item = this.items.get(id);
|
||||||
if (type == undefined || (item?.type == type)) {
|
if (type == undefined || (item?.type == type)) {
|
||||||
@@ -119,16 +182,14 @@ export class RdDBaseActor extends Actor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
listItems(type = undefined) { return (type ? this.itemTypes[type] : this.items); }
|
listItems(type = undefined) { return (type ? this.itemTypes[type] : this.items); }
|
||||||
filterItems(filter, type = undefined) { return type ? this.itemTypes[type]?.filter(filter) ?? [] : []; }
|
filterItems(filter, type = undefined) { return (type ? this.itemTypes[type] : this.items)?.filter(filter) ?? []; }
|
||||||
findItemLike(idOrName, type) {
|
findItemLike(idOrName, type) {
|
||||||
return this.getItem(idOrName, type)
|
return this.getItem(idOrName, type)
|
||||||
?? Misc.findFirstLike(idOrName, this.listItems(type), { description: Misc.typeName('Item', type) });
|
?? Misc.findFirstLike(idOrName, this.listItems(type), { description: Misc.typeName('Item', type) });
|
||||||
}
|
}
|
||||||
|
|
||||||
getMonnaie(id) { return this.findItemLike(id, 'monnaie'); }
|
getMonnaie(id) { return this.findItemLike(id, 'monnaie'); }
|
||||||
|
getEncombrementMax() { return 0 }
|
||||||
recompute() { }
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async onPreUpdateItem(item, change, options, id) { }
|
async onPreUpdateItem(item, change, options, id) { }
|
||||||
@@ -144,6 +205,29 @@ 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({
|
||||||
|
tokenId: this.token?.id,
|
||||||
|
actorId: this.id,
|
||||||
|
method: 'creerObjetParMJ',
|
||||||
|
args: [object]
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await this.createEmbeddedDocuments('Item', [object])
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async cleanupConteneurs() {
|
||||||
|
let updates = this.itemTypes['conteneur']
|
||||||
|
.filter(c => c.system.contenu.filter(id => this.getItem(id) == undefined).length > 0)
|
||||||
|
.map(c => { return { _id: c._id, 'system.contenu': c.system.contenu.filter(id => this.getItem(id) != undefined) } });
|
||||||
|
if (updates.length > 0) {
|
||||||
|
await this.updateEmbeddedDocuments("Item", updates)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getFortune() {
|
getFortune() {
|
||||||
return Monnaie.getFortune(this.itemTypes['monnaie']);
|
return Monnaie.getFortune(this.itemTypes['monnaie']);
|
||||||
@@ -208,6 +292,7 @@ export class RdDBaseActor extends Actor {
|
|||||||
if (fromActorId && !game.user.isGM) {
|
if (fromActorId && !game.user.isGM) {
|
||||||
RdDBaseActor.remoteActorCall({
|
RdDBaseActor.remoteActorCall({
|
||||||
userId: Misc.connectedGMOrUser(),
|
userId: Misc.connectedGMOrUser(),
|
||||||
|
tokenId: this.token?.id,
|
||||||
actorId: this.id,
|
actorId: this.id,
|
||||||
method: 'ajouterSols', args: [sols, fromActorId]
|
method: 'ajouterSols', args: [sols, fromActorId]
|
||||||
});
|
});
|
||||||
@@ -250,10 +335,10 @@ export class RdDBaseActor extends Actor {
|
|||||||
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);
|
||||||
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} !`);
|
ChatUtility.notifyUser(achat.userId, 'warn', vendeur ? `Le vendeur n'a pas plus de ${achat.vente.item.name} !` : `Impossible de retrouver: ${achat.vente.item.name} !`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (vendeur && !this.verifierQuantite(itemVendu, quantite)) {
|
if (vendeur && !vendeur.verifierQuantite(itemVendu, quantite)) {
|
||||||
ChatUtility.notifyUser(achat.userId, 'warn', `Le vendeur n'a pas assez de ${itemVendu.name} !`);
|
ChatUtility.notifyUser(achat.userId, 'warn', `Le vendeur n'a pas assez de ${itemVendu.name} !`);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -306,7 +391,7 @@ export class RdDBaseActor extends Actor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
verifierQuantite(item, quantiteDemande) {
|
verifierQuantite(item, quantiteDemande) {
|
||||||
const disponible = item?.getQuantite();
|
const disponible = this.getQuantiteDisponible(item);
|
||||||
return disponible == undefined || disponible >= quantiteDemande;
|
return disponible == undefined || disponible >= quantiteDemande;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,14 +440,6 @@ export class RdDBaseActor extends Actor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
computeMalusSurEncombrement() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
getEncombrementMax() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
async computeEncTotal() {
|
async computeEncTotal() {
|
||||||
if (!this.pack) {
|
if (!this.pack) {
|
||||||
this.encTotal = this.items.map(it => it.getEncTotal()).reduce(Misc.sum(), 0);
|
this.encTotal = this.items.map(it => it.getEncTotal()).reduce(Misc.sum(), 0);
|
||||||
@@ -371,6 +448,10 @@ export class RdDBaseActor extends Actor {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getEncTotal() {
|
||||||
|
return Math.floor(this.encTotal ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
async createItem(type, name = undefined) {
|
async createItem(type, name = undefined) {
|
||||||
if (!name) {
|
if (!name) {
|
||||||
name = 'Nouveau ' + Misc.typeName('Item', type);
|
name = 'Nouveau ' + Misc.typeName('Item', type);
|
||||||
@@ -435,62 +516,33 @@ export class RdDBaseActor extends Actor {
|
|||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
conteneurPeutContenir(dest, item) {
|
conteneurPeutContenir(dest, moved) {
|
||||||
if (!dest) {
|
if (!dest) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!dest.isConteneur()) {
|
if (!dest.isConteneur()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const destData = dest
|
if (moved.isConteneurContenu(dest)) {
|
||||||
if (this._isConteneurContenu(item, dest)) {
|
ui.notifications.warn(`Impossible de déplacer un conteneur parent (${moved.name}) dans un de ses contenus ${dest.name} !`);
|
||||||
ui.notifications.warn(`Impossible de déplacer un conteneur parent (${item.name}) dans un de ses contenus ${destData.name} !`);
|
return false;
|
||||||
return false; // Loop detected !
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculer le total actuel des contenus
|
// Calculer le total actuel des contenus
|
||||||
let encContenu = this.getRecursiveEnc(dest) - Number(destData.system.encombrement);
|
const encContenu = dest.getEncContenu();
|
||||||
let newEnc = this.getRecursiveEnc(item); // Calculer le total actuel du nouvel objet
|
const newEnc = moved.getEncTotal(); // Calculer le total actuel du nouvel objet
|
||||||
|
const placeDisponible = Math.roundDecimals(dest.system.capacite - encContenu - newEnc, 4)
|
||||||
|
|
||||||
// Teste si le conteneur de destination a suffisament de capacité pour recevoir le nouvel objet
|
// Teste si le conteneur de destination a suffisament de capacité pour recevoir le nouvel objet
|
||||||
if (Number(destData.system.capacite) < encContenu + newEnc) {
|
if (placeDisponible < 0) {
|
||||||
ui.notifications.warn(
|
ui.notifications.warn(
|
||||||
`Le conteneur ${dest.name} a une capacité de ${destData.system.capacite}, et contient déjà ${encContenu}.
|
`Le conteneur ${dest.name} a une capacité de ${dest.system.capacite}, et contient déjà ${encContenu}.
|
||||||
Impossible d'y ranger: ${item.name} d'encombrement ${newEnc}!`);
|
Impossible d'y ranger: ${moved.name} d'encombrement ${newEnc}!`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
_isConteneurContenu(item, conteneur) {
|
|
||||||
if (item?.isConteneur()) { // Si c'est un conteneur, il faut vérifier qu'on ne le déplace pas vers un sous-conteneur lui appartenant
|
|
||||||
for (let id of item.system.contenu) {
|
|
||||||
let subObjet = this.getItem(id);
|
|
||||||
if (subObjet?.id == conteneur.id) {
|
|
||||||
return true; // Loop detected !
|
|
||||||
}
|
|
||||||
if (subObjet?.isConteneur()) {
|
|
||||||
return this._isConteneurContenu(subObjet, conteneur);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
getRecursiveEnc(objet) {
|
|
||||||
if (!objet) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
const tplData = objet.system;
|
|
||||||
if (objet.type != 'conteneur') {
|
|
||||||
return Number(tplData.encombrement) * Number(tplData.quantite);
|
|
||||||
}
|
|
||||||
const encContenus = tplData.contenu.map(idContenu => this.getRecursiveEnc(this.getItem(idContenu)));
|
|
||||||
return encContenus.reduce(Misc.sum(), 0)
|
|
||||||
+ Number(tplData.encombrement) /* TODO? Number(tplData.quantite) -- on pourrait avoir plusieurs conteneurs...*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/** Ajoute un item dans un conteneur, sur la base
|
/** Ajoute un item dans un conteneur, sur la base
|
||||||
* de leurs ID */
|
* de leurs ID */
|
||||||
@@ -628,5 +680,20 @@ export class RdDBaseActor extends Actor {
|
|||||||
.then(html => ChatMessage.create(RdDUtility.chatDataSetup(html, modeOverride)));
|
.then(html => ChatMessage.create(RdDUtility.chatDataSetup(html, modeOverride)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actionImpossible(action) {
|
||||||
|
ui.notifications.info(`${this.name} ne peut pas faire cette action: ${action}`)
|
||||||
|
|
||||||
|
}
|
||||||
|
async roll() { this.actionImpossible("jet de caractéristiques") }
|
||||||
|
async jetEthylisme() { this.actionImpossible("jet d'éthylisme") }
|
||||||
|
async rollAppelChance() { this.actionImpossible("appel à la chance") }
|
||||||
|
async jetDeMoral() { this.actionImpossible("jet de moral") }
|
||||||
|
|
||||||
|
async actionPrincipale(item, onActionItem = async () => { }) {
|
||||||
|
switch (item.type) {
|
||||||
|
case TYPES.conteneur: return await item.sheet.render(true);
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
import { DialogItemAchat } from "../dialog-item-achat.js";
|
import { DialogItemAchat } from "../dialog-item-achat.js";
|
||||||
import { RdDItem } from "../item.js";
|
import { RdDItem } from "../item.js";
|
||||||
import { RdDSheetUtility } from "../rdd-sheet-utility.js";
|
|
||||||
import { RdDUtility } from "../rdd-utility.js";
|
import { RdDUtility } from "../rdd-utility.js";
|
||||||
import { RdDBaseActorSheet } from "./base-actor-sheet.js";
|
import { RdDBaseActorSheet } from "./base-actor-sheet.js";
|
||||||
import { RdDCommerce } from "./commerce.js";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extend the basic ActorSheet with some very simple modifications
|
* Extend the basic ActorSheet with some very simple modifications
|
||||||
@@ -14,12 +12,9 @@ export class RdDCommerceSheet extends RdDBaseActorSheet {
|
|||||||
/** @override */
|
/** @override */
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
return mergeObject(super.defaultOptions, {
|
return mergeObject(super.defaultOptions, {
|
||||||
classes: ["rdd", "sheet", "actor"],
|
|
||||||
template: "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-actor-sheet.html",
|
template: "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-actor-sheet.html",
|
||||||
width: 600,
|
width: 600, height: 720,
|
||||||
height: 720,
|
tabs: []
|
||||||
tabs: [],
|
|
||||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }]
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
get title() {
|
get title() {
|
||||||
|
|||||||
@@ -7,18 +7,8 @@ export class RdDCommerce extends RdDBaseActor {
|
|||||||
return "systems/foundryvtt-reve-de-dragon/icons/services/commerce.webp";
|
return "systems/foundryvtt-reve-de-dragon/icons/services/commerce.webp";
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareData() {
|
|
||||||
super.prepareData();
|
|
||||||
}
|
|
||||||
prepareDerivedData() {
|
|
||||||
super.prepareDerivedData();
|
|
||||||
}
|
|
||||||
|
|
||||||
canReceive(item) {
|
canReceive(item) {
|
||||||
if (item.isInventaire('all')) {
|
return item.isInventaire('all');
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.canReceive(item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getQuantiteDisponible(item) {
|
getQuantiteDisponible(item) {
|
||||||
@@ -28,6 +18,7 @@ export class RdDCommerce extends RdDBaseActor {
|
|||||||
verifierFortune(cout) {
|
verifierFortune(cout) {
|
||||||
return this.system.illimite || super.verifierFortune(cout);
|
return this.system.illimite || super.verifierFortune(cout);
|
||||||
}
|
}
|
||||||
|
|
||||||
async depenserSols(cout) {
|
async depenserSols(cout) {
|
||||||
if (this.system.illimite) {
|
if (this.system.illimite) {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
import { RdDActorSheet } from "./actor-sheet.js";
|
import { RdDBaseActorReveSheet } from "./base-actor-reve-sheet.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extend the basic ActorSheet with some very simple modifications
|
* Extend the basic ActorSheet with some very simple modifications
|
||||||
* @extends {ActorSheet}
|
* @extends {ActorSheet}
|
||||||
*/
|
*/
|
||||||
export class RdDActorCreatureSheet extends RdDActorSheet {
|
export class RdDCreatureSheet extends RdDBaseActorReveSheet {
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
return mergeObject(super.defaultOptions, {
|
return mergeObject(RdDBaseActorReveSheet.defaultOptions, {
|
||||||
classes: ["rdd", "sheet", "actor"],
|
|
||||||
template: "systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.html",
|
template: "systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.html",
|
||||||
width: 640,
|
width: 640, height: 720
|
||||||
height: 720,
|
|
||||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
|
|
||||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }]
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
65
module/actor/creature.js
Normal file
65
module/actor/creature.js
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import { ENTITE_INCARNE } from "../constants.js";
|
||||||
|
import { STATUSES } from "../settings/status-effects.js";
|
||||||
|
import { RdDBaseActorSang } from "./base-actor-sang.js";
|
||||||
|
|
||||||
|
export class RdDCreature extends RdDBaseActorSang {
|
||||||
|
|
||||||
|
static get defaultIcon() {
|
||||||
|
return "systems/foundryvtt-reve-de-dragon/icons/creatures/bramart.svg";
|
||||||
|
}
|
||||||
|
|
||||||
|
isCreature() { return true }
|
||||||
|
|
||||||
|
canReceive(item) {
|
||||||
|
return item.type == TYPES.competencecreature || item.isInventaire();
|
||||||
|
}
|
||||||
|
|
||||||
|
async remiseANeuf() {
|
||||||
|
await this.removeEffects(e => true);
|
||||||
|
await this.supprimerBlessures(it => true);
|
||||||
|
const updates = {
|
||||||
|
'system.sante.endurance.value': this.system.sante.endurance.max,
|
||||||
|
'system.sante.vie.value': this.system.sante.vie.max,
|
||||||
|
'system.sante.fatigue.value': 0
|
||||||
|
};
|
||||||
|
await this.update(updates);
|
||||||
|
}
|
||||||
|
|
||||||
|
async finDeRoundBlessures() {
|
||||||
|
const nbGraves = this.filterItems(it => it.isGrave(), 'blessure').length;
|
||||||
|
if (nbGraves > 0) {
|
||||||
|
// Gestion blessure graves : -1 pt endurance par blessure grave
|
||||||
|
await this.santeIncDec("endurance", -nbGraves);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isEffectAllowed(statusId) {
|
||||||
|
return [STATUSES.StatusComma].includes(statusId);
|
||||||
|
}
|
||||||
|
|
||||||
|
isEntiteAccordee(attacker) {
|
||||||
|
if (this.isEntite([ENTITE_INCARNE])) {
|
||||||
|
let resonnance = this.system.sante.resonnance
|
||||||
|
return (resonnance.actors.find(it => it == attacker.id))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async setEntiteReveAccordee(attacker) {
|
||||||
|
if (this.isEntite([ENTITE_INCARNE])) {
|
||||||
|
let resonnance = duplicate(this.system.sante.resonnance);
|
||||||
|
if (resonnance.actors.find(it => it == attacker.id)) {
|
||||||
|
// déjà accordé
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resonnance.actors.push(attacker.id);
|
||||||
|
await this.update({ "system.sante.resonnance": resonnance });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.setEntiteReveAccordee(attacker)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,20 +1,17 @@
|
|||||||
import { RdDActorSheet } from "./actor-sheet.js";
|
import { RdDBaseActorReveSheet } from "./base-actor-reve-sheet.js";
|
||||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
import { RdDSheetUtility } from "../rdd-sheet-utility.js";
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "../rdd-utility.js";
|
||||||
|
|
||||||
export class RdDActorEntiteSheet extends RdDActorSheet {
|
export class RdDActorEntiteSheet extends RdDBaseActorReveSheet {
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
return mergeObject(super.defaultOptions, {
|
return mergeObject(RdDBaseActorReveSheet.defaultOptions, {
|
||||||
classes: ["rdd", "sheet", "actor"],
|
|
||||||
template: "systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.html",
|
template: "systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.html",
|
||||||
width: 640,
|
width: 640, height: 720,
|
||||||
height: 720,
|
|
||||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
|
|
||||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }]
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getData() {
|
async getData() {
|
||||||
let formData = await super.getData();
|
let formData = await super.getData();
|
||||||
formData.resonances = this.actor.system.sante.resonnance.actors.map(actorId => game.actors.get(actorId))
|
formData.resonances = this.actor.system.sante.resonnance.actors.map(actorId => game.actors.get(actorId))
|
||||||
110
module/actor/entite.js
Normal file
110
module/actor/entite.js
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
import { ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js";
|
||||||
|
import { TYPES } from "../item.js";
|
||||||
|
import { Misc } from "../misc.js";
|
||||||
|
import { RdDEncaisser } from "../rdd-roll-encaisser.js";
|
||||||
|
import { STATUSES } from "../settings/status-effects.js";
|
||||||
|
import { RdDBaseActorReve } from "./base-actor-reve.js";
|
||||||
|
|
||||||
|
export class RdDEntite extends RdDBaseActorReve {
|
||||||
|
|
||||||
|
static get defaultIcon() {
|
||||||
|
return "systems/foundryvtt-reve-de-dragon/icons/entites/darquoine.webp";
|
||||||
|
}
|
||||||
|
|
||||||
|
canReceive(item) {
|
||||||
|
return item.type == TYPES.competencecreature
|
||||||
|
}
|
||||||
|
|
||||||
|
isEntite(typeentite = []) {
|
||||||
|
return (typeentite.length == 0 || typeentite.includes(this.system.definition.typeentite));
|
||||||
|
}
|
||||||
|
isNonIncarnee() { return this.isEntite([ENTITE_NONINCARNE]) }
|
||||||
|
|
||||||
|
getReveActuel() {
|
||||||
|
return Misc.toInt(this.system.carac.reve?.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
getForce() { return this.getReve() }
|
||||||
|
getAgilite() { return this.getReve() }
|
||||||
|
getChance() { return this.getReve() }
|
||||||
|
|
||||||
|
getDraconicOuPossession() {
|
||||||
|
return this.itemTypes[TYPES.competencecreature]
|
||||||
|
.filter(it => it.system.categorie == 'possession')
|
||||||
|
.sort(Misc.descending(it => it.system.niveau))
|
||||||
|
.find(it => true);
|
||||||
|
}
|
||||||
|
|
||||||
|
async remiseANeuf() {
|
||||||
|
await this.removeEffects(e => true);
|
||||||
|
if (!this.isNonIncarnee()) {
|
||||||
|
await this.update({
|
||||||
|
'system.sante.endurance.value': this.system.sante.endurance.max
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isDead() {
|
||||||
|
return this.isNonIncarnee() ? false : this.system.sante.endurance.value <= 0
|
||||||
|
}
|
||||||
|
|
||||||
|
async santeIncDec(name, inc, isCritique = false) {
|
||||||
|
if (name == 'endurance' && !this.isNonIncarnee()) {
|
||||||
|
const oldValue = this.system.sante.endurance.value;
|
||||||
|
const endurance = Math.max(0,
|
||||||
|
Math.min(oldValue + inc,
|
||||||
|
this.system.sante.endurance.max));
|
||||||
|
await this.update({ "system.sante.endurance.value": endurance })
|
||||||
|
await this.setEffect(STATUSES.StatusComma, endurance <= 0);
|
||||||
|
return {
|
||||||
|
perte: oldValue - endurance,
|
||||||
|
newValue: endurance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
async encaisser() {
|
||||||
|
if (this.isNonIncarnee()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await RdDEncaisser.encaisser(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
isEffectAllowed(statusId) {
|
||||||
|
return [STATUSES.StatusComma].includes(statusId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async onAppliquerJetEncaissement(encaissement, attacker) {
|
||||||
|
const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance);
|
||||||
|
mergeObject(encaissement, {
|
||||||
|
resteEndurance: perteEndurance.newValue,
|
||||||
|
endurance: perteEndurance.perte
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
isEntiteAccordee(attacker) {
|
||||||
|
if (this.isEntite([ENTITE_INCARNE])) {
|
||||||
|
let resonnance = this.system.sante.resonnance
|
||||||
|
return (resonnance.actors.find(it => it == attacker.id))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async setEntiteReveAccordee(attacker) {
|
||||||
|
if (this.isEntite([ENTITE_INCARNE])) {
|
||||||
|
let resonnance = duplicate(this.system.sante.resonnance);
|
||||||
|
if (resonnance.actors.find(it => it == attacker.id)) {
|
||||||
|
// déjà accordé
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resonnance.actors.push(attacker.id);
|
||||||
|
await this.update({ "system.sante.resonnance": resonnance });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.setEntiteReveAccordee(attacker)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,23 +1,35 @@
|
|||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "../rdd-utility.js";
|
||||||
import { RdDActorSheet } from "./actor-sheet.js";
|
import { RdDBaseActorSheet } from "./base-actor-sheet.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RdDActorVehiculeSheet extends RdDActorSheet {
|
export class RdDActorVehiculeSheet extends RdDBaseActorSheet {
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
RdDUtility.initAfficheContenu();
|
RdDUtility.initAfficheContenu();
|
||||||
|
|
||||||
return mergeObject(super.defaultOptions, {
|
return mergeObject(RdDBaseActorSheet.defaultOptions, {
|
||||||
classes: ["rdd", "sheet", "actor"],
|
|
||||||
template: "systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.html",
|
template: "systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.html",
|
||||||
width: 640,
|
width: 640, height: 720,
|
||||||
height: 720,
|
|
||||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
|
|
||||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }]
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async getData() {
|
||||||
|
let formData = await super.getData();
|
||||||
|
mergeObject(formData,
|
||||||
|
{
|
||||||
|
editable: this.isEditable,
|
||||||
|
cssClass: this.isEditable ? "editable" : "locked",
|
||||||
|
effects: this.actor.effects.map(e => foundry.utils.deepClone(e)),
|
||||||
|
limited: this.actor.limited,
|
||||||
|
owner: this.actor.isOwner,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.timerRecherche = undefined;
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
if (!this.options.editable) return;
|
if (!this.options.editable) return;
|
||||||
28
module/actor/vehicule.js
Normal file
28
module/actor/vehicule.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import { RdDBaseActor } from "./base-actor.js";
|
||||||
|
|
||||||
|
export class RdDVehicule extends RdDBaseActor {
|
||||||
|
|
||||||
|
static get defaultIcon() {
|
||||||
|
return "systems/foundryvtt-reve-de-dragon/icons/vehicules/charette.webp";
|
||||||
|
}
|
||||||
|
isVehicule() { return true }
|
||||||
|
|
||||||
|
canReceive(item) {
|
||||||
|
return item.isInventaire();
|
||||||
|
}
|
||||||
|
|
||||||
|
getEncombrementMax() {
|
||||||
|
return this.system.capacite_encombrement;
|
||||||
|
}
|
||||||
|
|
||||||
|
async vehicleIncDec(name, inc) {
|
||||||
|
if (!['resistance', 'structure'].includes(name)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const newValue = this.system.etat[name].value + inc;
|
||||||
|
if (0 <= newValue && newValue <= this.system.etat[name].max) {
|
||||||
|
await this.update({ [`system.etat.${name}.value`]: newValue })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -78,11 +78,7 @@ export class ChatUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async createChatWithRollMode(name, chatOptions) {
|
static async createChatWithRollMode(name, chatOptions) {
|
||||||
return await ChatUtility.createChatMessage(name, game.settings.get("core", "rollMode"), chatOptions);
|
let rollMode = game.settings.get("core", "rollMode")
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async createChatMessage(name, rollMode, chatOptions) {
|
|
||||||
switch (rollMode) {
|
switch (rollMode) {
|
||||||
case "blindroll": // GM only
|
case "blindroll": // GM only
|
||||||
if (!game.user.isGM) {
|
if (!game.user.isGM) {
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ export class DialogChronologie extends Dialog {
|
|||||||
heure: RdDTimestamp.definition(this.html.find("form.rdddialogchrono :input[name='chronologie.heure']").val()),
|
heure: RdDTimestamp.definition(this.html.find("form.rdddialogchrono :input[name='chronologie.heure']").val()),
|
||||||
minute: this.html.find("form.rdddialogchrono :input[name='chronologie.minute']").val(),
|
minute: this.html.find("form.rdddialogchrono :input[name='chronologie.minute']").val(),
|
||||||
},
|
},
|
||||||
dateReel: this.html.find("form.rdddialogchrono :input[name='dateReel']").val()
|
dateReel: this.html.find("form.rdddialogchrono :input[name='dateReel']").val().replace('T', ' ')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export class DialogCreateSigneDraconique extends Dialog {
|
|||||||
.map(actor => ({
|
.map(actor => ({
|
||||||
id: actor.id,
|
id: actor.id,
|
||||||
name: actor.name,
|
name: actor.name,
|
||||||
selected: true
|
selected: false
|
||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ export class DialogCreateSigneDraconique extends Dialog {
|
|||||||
|
|
||||||
onSelectTmr(event) {
|
onSelectTmr(event) {
|
||||||
const tmrName = this.html.find(event.currentTarget)?.data("tmr-name");
|
const tmrName = this.html.find(event.currentTarget)?.data("tmr-name");
|
||||||
const onTmr = this.tmrs.find(it => it.name == tmrName);
|
const onTmr = this.dialogData.tmrs.find(it => it.name == tmrName);
|
||||||
if (onTmr){
|
if (onTmr){
|
||||||
onTmr.selected = event.currentTarget.checked;
|
onTmr.selected = event.currentTarget.checked;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,20 +7,19 @@ import { RdDUtility } from "./rdd-utility.js";
|
|||||||
*/
|
*/
|
||||||
export class DialogValidationEncaissement extends Dialog {
|
export class DialogValidationEncaissement extends Dialog {
|
||||||
|
|
||||||
static async validerEncaissement(actor, rollData, armure, show, attackerId, onEncaisser) {
|
static async validerEncaissement(actor, rollData, armure, onEncaisser) {
|
||||||
let encaissement = await RdDUtility.jetEncaissement(rollData, armure, { showDice: HIDE_DICE });
|
let encaissement = await RdDUtility.jetEncaissement(rollData, armure, { showDice: HIDE_DICE });
|
||||||
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html', {
|
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html', {
|
||||||
actor: actor,
|
actor: actor,
|
||||||
rollData: rollData,
|
rollData: rollData,
|
||||||
encaissement: encaissement,
|
encaissement: encaissement
|
||||||
show: show
|
|
||||||
});
|
});
|
||||||
const dialog = new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, show, attackerId, onEncaisser);
|
const dialog = new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, onEncaisser);
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
constructor(html, actor, rollData, armure, encaissement, show, attackerId, onEncaisser) {
|
constructor(html, actor, rollData, armure, encaissement, onEncaisser) {
|
||||||
// Common conf
|
// Common conf
|
||||||
let buttons = {
|
let buttons = {
|
||||||
"valider": { label: "Valider", callback: html => this.onValider() },
|
"valider": { label: "Valider", callback: html => this.onValider() },
|
||||||
@@ -47,8 +46,6 @@ export class DialogValidationEncaissement extends Dialog {
|
|||||||
this.rollData = rollData;
|
this.rollData = rollData;
|
||||||
this.armure = armure;
|
this.armure = armure;
|
||||||
this.encaissement = encaissement;
|
this.encaissement = encaissement;
|
||||||
this.show = show;
|
|
||||||
this.attackerId = attackerId;
|
|
||||||
this.onEncaisser = onEncaisser;
|
this.onEncaisser = onEncaisser;
|
||||||
this.forceDiceResult = {total: encaissement.roll.result };
|
this.forceDiceResult = {total: encaissement.roll.result };
|
||||||
}
|
}
|
||||||
@@ -67,6 +64,6 @@ export class DialogValidationEncaissement extends Dialog {
|
|||||||
|
|
||||||
async onValider() {
|
async onValider() {
|
||||||
this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult});
|
this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult});
|
||||||
this.onEncaisser(this.encaissement, this.show, this.attackerId)
|
this.onEncaisser(this.encaissement)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,14 +20,14 @@ 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 == TYPES.arme || RdDItemCompetenceCreature.getCategorieAttaque(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getArme(arme) {
|
static getArme(arme) {
|
||||||
switch (arme ? arme.type : '') {
|
switch (arme ? arme.type : '') {
|
||||||
case 'arme': return arme;
|
case TYPES.arme: return arme;
|
||||||
case 'competencecreature':
|
case TYPES.competencecreature:
|
||||||
return RdDItemCompetenceCreature.armeCreature(arme);
|
return RdDItemCompetenceCreature.armeCreature(arme);
|
||||||
}
|
}
|
||||||
return RdDItemArme.mainsNues();
|
return RdDItemArme.mainsNues();
|
||||||
@@ -68,14 +68,14 @@ export class RdDItemArme extends Item {
|
|||||||
return armeData.system.categorie_parade;
|
return armeData.system.categorie_parade;
|
||||||
}
|
}
|
||||||
// pour compatibilité avec des personnages existants
|
// pour compatibilité avec des personnages existants
|
||||||
if (armeData.type == 'competencecreature' || armeData.system.categorie == 'creature') {
|
if (armeData.type == TYPES.competencecreature || armeData.system.categorie == 'creature') {
|
||||||
return armeData.system.categorie_parade || (armeData.system.isparade ? 'armes-naturelles' : '');
|
return armeData.system.categorie_parade || (armeData.system.isparade ? 'armes-naturelles' : '');
|
||||||
}
|
}
|
||||||
if (!armeData.type.match(/arme|competencecreature/)) {
|
if (!armeData.type.match(/arme|competencecreature/)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
if (armeData.system.competence == undefined) {
|
if (armeData.system.competence == undefined) {
|
||||||
return 'competencecreature';
|
return TYPES.competencecreature;
|
||||||
}
|
}
|
||||||
let compname = armeData.system.competence.toLowerCase();
|
let compname = armeData.system.competence.toLowerCase();
|
||||||
if (compname.match(/^(dague de jet|javelot|fouet|arc|arbalête|fronde|hache de jet|fléau)$/)) return '';
|
if (compname.match(/^(dague de jet|javelot|fouet|arc|arbalête|fronde|hache de jet|fléau)$/)) return '';
|
||||||
@@ -157,23 +157,33 @@ export class RdDItemArme extends Item {
|
|||||||
}
|
}
|
||||||
return armeData;
|
return armeData;
|
||||||
}
|
}
|
||||||
|
static competence2Mains(arme) {
|
||||||
|
return arme.system.competence.replace(" 1 main", " 2 mains");
|
||||||
|
}
|
||||||
|
|
||||||
|
static competence1Mains(arme) {
|
||||||
|
return arme.system.competence.replace(" 2 mains", " 1 main");
|
||||||
|
}
|
||||||
|
|
||||||
static isArmeUtilisable(arme) {
|
static isArmeUtilisable(arme) {
|
||||||
return arme.type == 'arme' && arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0);
|
return arme.type == 'arme' && arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ajoutCorpsACorps(armes, competences, carac) {
|
static ajoutCorpsACorps(armes, actor) {
|
||||||
let corpsACorps = competences.find(it => it.name == 'Corps à corps') ?? { system: { niveau: -6 } };
|
armes.push(RdDItemArme.mainsNues(actor));
|
||||||
let init = RdDCombatManager.calculInitiative(corpsACorps.system.niveau, carac['melee'].value);
|
armes.push(RdDItemArme.empoignade(actor));
|
||||||
armes.push(RdDItemArme.mainsNues({ niveau: corpsACorps.system.niveau, initiative: init }));
|
|
||||||
armes.push(RdDItemArme.empoignade({ niveau: corpsACorps.system.niveau, initiative: init }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static corpsACorps(mainsNuesActor) {
|
static corpsACorps(actor) {
|
||||||
const corpsACorps = {
|
let competence = actor?.getCompetenceCorpsACorps() ?? { system: { niveau: -6 } };
|
||||||
|
let melee = actor? actor.system.carac['melee'].value : 0
|
||||||
|
return {
|
||||||
|
_id: competence?.id,
|
||||||
name: 'Corps à corps',
|
name: 'Corps à corps',
|
||||||
|
type: TYPES.arme,
|
||||||
img: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp',
|
img: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp',
|
||||||
system: {
|
system: {
|
||||||
|
initiative: RdDCombatManager.calculInitiative(competence.system.niveau, melee),
|
||||||
equipe: true,
|
equipe: true,
|
||||||
rapide: true,
|
rapide: true,
|
||||||
force: 0,
|
force: 0,
|
||||||
@@ -181,23 +191,22 @@ export class RdDItemArme extends Item {
|
|||||||
dommagesReels: 0,
|
dommagesReels: 0,
|
||||||
mortalite: 'non-mortel',
|
mortalite: 'non-mortel',
|
||||||
competence: 'Corps à corps',
|
competence: 'Corps à corps',
|
||||||
|
deuxmains: true,
|
||||||
categorie_parade: 'sans-armes'
|
categorie_parade: 'sans-armes'
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
mergeObject(corpsACorps.system, mainsNuesActor ?? {}, { overwrite: false });
|
|
||||||
return corpsACorps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static mainsNues(mainsNuesActor) {
|
static mainsNues(actor) {
|
||||||
const mainsNues = RdDItemArme.corpsACorps(mainsNuesActor)
|
const mainsNues = RdDItemArme.corpsACorps(actor)
|
||||||
mainsNues.name = 'Mains nues'
|
mainsNues.name = 'Mains nues'
|
||||||
mainsNues.system.cac = 'pugilat'
|
mainsNues.system.cac = 'pugilat'
|
||||||
mainsNues.system.baseInit = 4
|
mainsNues.system.baseInit = 4
|
||||||
return mainsNues;
|
return mainsNues;
|
||||||
}
|
}
|
||||||
|
|
||||||
static empoignade(mainsNuesActor) {
|
static empoignade(actor) {
|
||||||
const empoignade = RdDItemArme.corpsACorps(mainsNuesActor)
|
const empoignade = RdDItemArme.corpsACorps(actor)
|
||||||
empoignade.name = 'Empoignade'
|
empoignade.name = 'Empoignade'
|
||||||
empoignade.system.cac = 'empoignade'
|
empoignade.system.cac = 'empoignade'
|
||||||
empoignade.system.baseInit = 3
|
empoignade.system.baseInit = 3
|
||||||
|
|||||||
@@ -8,18 +8,18 @@ const xp_par_niveau = [5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15, 20, 20, 20, 20,
|
|||||||
const niveau_max = xp_par_niveau.length - 10;
|
const niveau_max = xp_par_niveau.length - 10;
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
const limitesArchetypes = [
|
const limitesArchetypes = [
|
||||||
{ "niveau": 0, "nombreMax": 100, "reste": 100 },
|
{ niveau: 0, nombreMax: 100 },
|
||||||
{ "niveau": 1, "nombreMax": 10, "reste": 10 },
|
{ niveau: 1, nombreMax: 10 },
|
||||||
{ "niveau": 2, "nombreMax": 9, "reste": 9 },
|
{ niveau: 2, nombreMax: 9 },
|
||||||
{ "niveau": 3, "nombreMax": 8, "reste": 8 },
|
{ niveau: 3, nombreMax: 8 },
|
||||||
{ "niveau": 4, "nombreMax": 7, "reste": 7 },
|
{ niveau: 4, nombreMax: 7 },
|
||||||
{ "niveau": 5, "nombreMax": 6, "reste": 6 },
|
{ niveau: 5, nombreMax: 6 },
|
||||||
{ "niveau": 6, "nombreMax": 5, "reste": 5 },
|
{ niveau: 6, nombreMax: 5 },
|
||||||
{ "niveau": 7, "nombreMax": 4, "reste": 4 },
|
{ niveau: 7, nombreMax: 4 },
|
||||||
{ "niveau": 8, "nombreMax": 3, "reste": 3 },
|
{ niveau: 8, nombreMax: 3 },
|
||||||
{ "niveau": 9, "nombreMax": 2, "reste": 2 },
|
{ niveau: 9, nombreMax: 2 },
|
||||||
{ "niveau": 10, "nombreMax": 1, "reste": 1 },
|
{ niveau: 10, nombreMax: 1 },
|
||||||
{ "niveau": 11, "nombreMax": 1, "reste": 1 }
|
{ niveau: 11, nombreMax: 1 },
|
||||||
];
|
];
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -79,10 +79,9 @@ export class RdDItemCompetence extends Item {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static isCompetenceArme(competence) {
|
static isCompetenceArme(competence) {
|
||||||
if (competence.isCompetence()) {
|
if (competence.isCompetence() && !competence.isCorpsACorps() && !competence.isEsquive()) {
|
||||||
switch (competence.system.categorie) {
|
switch (competence.system.categorie) {
|
||||||
case 'melee':
|
case 'melee':
|
||||||
return !Grammar.toLowerCaseNoAccent(competence.name).includes('esquive');
|
|
||||||
case 'tir':
|
case 'tir':
|
||||||
case 'lancer':
|
case 'lancer':
|
||||||
return true;
|
return true;
|
||||||
@@ -93,10 +92,10 @@ export class RdDItemCompetence extends Item {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static isArmeUneMain(competence) {
|
static isArmeUneMain(competence) {
|
||||||
return RdDItemCompetence.isCompetenceArme(competence) && competence.name.toLowerCase().includes("1 main");
|
return competence.isCompetenceArme() && competence.name.toLowerCase().includes("1 main");
|
||||||
}
|
}
|
||||||
static isArme2Main(competence) {
|
static isArme2Main(competence) {
|
||||||
return RdDItemCompetence.isCompetenceArme(competence) && competence.name.toLowerCase().includes("2 main");
|
return competence.isCompetenceArme() && competence.name.toLowerCase().includes("2 main");
|
||||||
}
|
}
|
||||||
|
|
||||||
static isThanatos(competence) {
|
static isThanatos(competence) {
|
||||||
@@ -259,13 +258,17 @@ export class RdDItemCompetence extends Item {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static computeResumeArchetype(competences) {
|
static computeResumeArchetype(competences) {
|
||||||
const computed = duplicate(limitesArchetypes);
|
const computed = duplicate(limitesArchetypes);
|
||||||
|
computed.forEach(it => { it.nombre = 0; it.reste = it.nombreMax; });
|
||||||
|
|
||||||
competences.map(it => Math.max(0, it.system.niveau_archetype))
|
competences.map(it => Math.max(0, it.system.niveau_archetype))
|
||||||
.filter(n => n > 0)
|
.filter(n => n > 0)
|
||||||
.forEach(n => {
|
.forEach(n => {
|
||||||
computed[n] = computed[n] ?? { niveau: n, nombreMax: 0, reste: 0 };
|
computed[n] = computed[n] ?? { niveau: n, nombreMax: 0, reste: 0, nombre: 0 };
|
||||||
computed[n].reste = computed[n].reste - 1;
|
computed[n].reste--;
|
||||||
|
computed[n].nombre++;
|
||||||
|
|
||||||
});
|
});
|
||||||
return computed.filter(it => it.reste > 0 && it.niveau > 0);
|
return computed.filter(it => it.niveau > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
import { RdDItem, TYPES } from "./item.js";
|
import { TYPES } from "./item.js";
|
||||||
import { RdDCombatManager } from "./rdd-combat.js";
|
import { RdDCombatManager } from "./rdd-combat.js";
|
||||||
|
|
||||||
const categories = {
|
const categories = {
|
||||||
@@ -55,6 +55,20 @@ export class RdDItemCompetenceCreature extends Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
static isCompetenceAttaque(item) {
|
||||||
|
if (item.type == TYPES.competencecreature) {
|
||||||
|
switch (item.system.categorie) {
|
||||||
|
case "melee":
|
||||||
|
case "tir":
|
||||||
|
case "lancer":
|
||||||
|
case "naturelle":
|
||||||
|
case "possession":
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
static getCategorieAttaque(item) {
|
static getCategorieAttaque(item) {
|
||||||
if (item.type == TYPES.competencecreature) {
|
if (item.type == TYPES.competencecreature) {
|
||||||
switch (item.system.categorie) {
|
switch (item.system.categorie) {
|
||||||
@@ -63,6 +77,7 @@ export class RdDItemCompetenceCreature extends Item {
|
|||||||
case "lancer":
|
case "lancer":
|
||||||
case "naturelle":
|
case "naturelle":
|
||||||
case "possession":
|
case "possession":
|
||||||
|
case "parade":
|
||||||
return item.system.categorie
|
return item.system.categorie
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { RdDItemCompetence } from "./item-competence.js";
|
|||||||
import { RdDHerbes } from "./rdd-herbes.js";
|
import { RdDHerbes } from "./rdd-herbes.js";
|
||||||
import { RdDGemme } from "./rdd-gemme.js";
|
import { RdDGemme } from "./rdd-gemme.js";
|
||||||
import { HtmlUtility } from "./html-utility.js";
|
import { HtmlUtility } from "./html-utility.js";
|
||||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||||
import { SYSTEM_RDD } from "./constants.js";
|
import { SYSTEM_RDD } from "./constants.js";
|
||||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
||||||
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||||
@@ -113,7 +113,7 @@ export class RdDItemSheet extends ItemSheet {
|
|||||||
formData.competences = competences;
|
formData.competences = competences;
|
||||||
}
|
}
|
||||||
if (this.item.type == 'arme') {
|
if (this.item.type == 'arme') {
|
||||||
formData.competences = competences.filter(it => RdDItemCompetence.isCompetenceArme(it))
|
formData.competences = competences.filter(it => it.isCompetenceArme())
|
||||||
}
|
}
|
||||||
if (['sort', 'sortreserve'].includes(this.item.type)) {
|
if (['sort', 'sortreserve'].includes(this.item.type)) {
|
||||||
formData.competences = competences.filter(it => RdDItemCompetence.isDraconic(it));
|
formData.competences = competences.filter(it => RdDItemCompetence.isDraconic(it));
|
||||||
@@ -157,7 +157,7 @@ export class RdDItemSheet extends ItemSheet {
|
|||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
this.html = html;
|
this.html = html;
|
||||||
|
|
||||||
HtmlUtility.showControlWhen(this.html.find(".item-cout"), ReglesOptionelles.isUsing('afficher-prix-joueurs')
|
HtmlUtility.showControlWhen(this.html.find(".item-cout"), ReglesOptionnelles.isUsing('afficher-prix-joueurs')
|
||||||
|| game.user.isGM
|
|| game.user.isGM
|
||||||
|| !this.item.isOwned);
|
|| !this.item.isOwned);
|
||||||
HtmlUtility.showControlWhen(this.html.find(".item-magique"), this.item.isMagique());
|
HtmlUtility.showControlWhen(this.html.find(".item-magique"), this.item.isMagique());
|
||||||
@@ -195,7 +195,7 @@ export class RdDItemSheet extends ItemSheet {
|
|||||||
|
|
||||||
this.html.find('.creer-tache-livre').click((event) => this._getEventActor(event).creerTacheDepuisLivre(this.item));
|
this.html.find('.creer-tache-livre').click((event) => this._getEventActor(event).creerTacheDepuisLivre(this.item));
|
||||||
this.html.find('.consommer-potion').click((event) => this._getEventActor(event).consommerPotion(this.item, this.getActionRenderItem()));
|
this.html.find('.consommer-potion').click((event) => this._getEventActor(event).consommerPotion(this.item, this.getActionRenderItem()));
|
||||||
this.html.find('.creer-potion-base').click((event) => this._getEventActor(event).dialogFabriquerPotion(this.item));
|
this.html.find('.creer-potion-base').click((event) => this._getEventActor(event).actionHerbe(this.item));
|
||||||
|
|
||||||
this.html.find('.alchimie-tache a').click((event) => {
|
this.html.find('.alchimie-tache a').click((event) => {
|
||||||
let actor = this._getEventActor(event);
|
let actor = this._getEventActor(event);
|
||||||
|
|||||||
@@ -220,6 +220,32 @@ 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) }
|
||||||
|
isEsquive() {
|
||||||
|
return (this.isCompetence()
|
||||||
|
&& this.system.categorie == 'melee'
|
||||||
|
&& Grammar.includesLowerCaseNoAccent(this.name, 'Esquive'));
|
||||||
|
}
|
||||||
|
|
||||||
|
isCorpsACorps() {
|
||||||
|
return (this.isCompetence()
|
||||||
|
&& this.system.categorie == 'melee'
|
||||||
|
&& Grammar.includesLowerCaseNoAccent(this.name, 'Corps à Corps'));
|
||||||
|
}
|
||||||
|
|
||||||
|
isCompetenceArme() {
|
||||||
|
if (this.isCompetence()) {
|
||||||
|
switch (this.system.categorie) {
|
||||||
|
case 'melee':
|
||||||
|
return !this.isCorpsACorps() && !this.isEsquive()
|
||||||
|
case 'tir':
|
||||||
|
case 'lancer':
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
isCompetencePossession() { return TYPES.competencecreature == this.type && this.system.categorie == "possession" }
|
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) }
|
||||||
@@ -395,6 +421,16 @@ export class RdDItem extends Item {
|
|||||||
return Math.max(this.system.encombrement ?? 0, 0);
|
return Math.max(this.system.encombrement ?? 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getEncContenu() {
|
||||||
|
return this.getContenu()
|
||||||
|
.map(it => it.getRecursiveEnc())
|
||||||
|
.reduce(Misc.sum(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
getRecursiveEnc() {
|
||||||
|
return this.getEncTotal() + this.getEncContenu()
|
||||||
|
}
|
||||||
|
|
||||||
getEncHerbe() {
|
getEncHerbe() {
|
||||||
switch (this.system.categorie) {
|
switch (this.system.categorie) {
|
||||||
case 'Repos': case 'Soin': case 'Alchimie':
|
case 'Repos': case 'Soin': case 'Alchimie':
|
||||||
@@ -404,6 +440,18 @@ export class RdDItem extends Item {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getContenu() {
|
||||||
|
if (this.isConteneur()) {
|
||||||
|
return this.system.contenu.map(idContenu => this.actor.getItem(idContenu));
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
isConteneurContenu(conteneur) {
|
||||||
|
return this.getContenu()
|
||||||
|
.find(it => it.id == conteneur.id || it.isConteneurContenu(conteneur))
|
||||||
|
}
|
||||||
|
|
||||||
valeurTotale() {
|
valeurTotale() {
|
||||||
return (this.isService() ? 1 : this.getQuantite()) * this.valeur()
|
return (this.isService() ? 1 : this.getQuantite()) * this.valeur()
|
||||||
}
|
}
|
||||||
@@ -450,11 +498,11 @@ export class RdDItem extends Item {
|
|||||||
if (this.actor?.isPersonnage()) {
|
if (this.actor?.isPersonnage()) {
|
||||||
const warn = options.warnIfNot;
|
const warn = options.warnIfNot;
|
||||||
if (this.getUtilisationCuisine() == 'brut') {
|
if (this.getUtilisationCuisine() == 'brut') {
|
||||||
return 'Utiliser';
|
return 'Cuisiner';
|
||||||
}
|
}
|
||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
case TYPES.nourritureboisson: return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn);
|
case TYPES.nourritureboisson: return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn);
|
||||||
case TYPES.potion: return this._actionOrWarnQuantiteZero('Boire', warn);
|
case TYPES.potion: return this._actionOrWarnQuantiteZero('Consommer', warn);
|
||||||
case TYPES.livre: return this._actionOrWarnQuantiteZero('Lire', warn);
|
case TYPES.livre: return this._actionOrWarnQuantiteZero('Lire', warn);
|
||||||
case TYPES.herbe: return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
|
case TYPES.herbe: return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
|
||||||
case TYPES.queue: case TYPES.ombre: return this.system.refoulement > 0 ? 'Refouler' : undefined;
|
case TYPES.queue: case TYPES.ombre: return this.system.refoulement > 0 ? 'Refouler' : undefined;
|
||||||
@@ -465,19 +513,8 @@ export class RdDItem extends Item {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async actionPrincipale(actor, onActionItem = async () => { }) {
|
async actionPrincipale(actor, onActionItem = async () => { }) {
|
||||||
if (!this.getActionPrincipale()) {
|
if (!this.getActionPrincipale()) { return }
|
||||||
return;
|
await actor?.actionPrincipale(this, onActionItem);
|
||||||
}
|
|
||||||
if (await actor.actionNourritureboisson(this, onActionItem)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (this.type) {
|
|
||||||
case TYPES.potion: return await actor.consommerPotion(this, onActionItem);
|
|
||||||
case TYPES.livre: return await actor.actionLire(this);
|
|
||||||
case TYPES.conteneur: return await this.sheet.render(true);
|
|
||||||
case TYPES.herbe: return await actor.actionHerbe(this, onActionItem);
|
|
||||||
case TYPES.queue: case TYPES.ombre: return await actor.actionRefoulement(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_actionOrWarnQuantiteZero(actionName, warn) {
|
_actionOrWarnQuantiteZero(actionName, warn) {
|
||||||
@@ -675,7 +712,7 @@ export class RdDItem extends Item {
|
|||||||
_armeChatData() {
|
_armeChatData() {
|
||||||
return [
|
return [
|
||||||
`<b>Compétence</b>: ${this.system.competence}`,
|
`<b>Compétence</b>: ${this.system.competence}`,
|
||||||
`<b>Dommages</b>: ${this.system.dommages}`,
|
`<b>Dommages</b>: ${this.system.dommages} ${this.system.mortalite == 'non-mortel' ? '(Non mortel)' : ''}`,
|
||||||
`<b>Force minimum</b>: ${this.system.force}`,
|
`<b>Force minimum</b>: ${this.system.force}`,
|
||||||
`<b>Resistance</b>: ${this.system.resistance}`,
|
`<b>Resistance</b>: ${this.system.resistance}`,
|
||||||
...this._inventaireTemplateChatData()
|
...this._inventaireTemplateChatData()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { RdDItem } from "../item.js";
|
import { RdDItem } from "../item.js";
|
||||||
import { Misc } from "../misc.js";
|
import { Misc } from "../misc.js";
|
||||||
import { ReglesOptionelles } from "../settings/regles-optionelles.js";
|
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
|
||||||
|
|
||||||
export class RdDItemArmure extends RdDItem {
|
export class RdDItemArmure extends RdDItem {
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ export class RdDItemArmure extends RdDItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deteriorerArmure(dmg) {
|
deteriorerArmure(dmg) {
|
||||||
if (!ReglesOptionelles.isUsing('deteriorationArmure') || this.system.protection == '0') {
|
if (!ReglesOptionnelles.isUsing('deteriorationArmure') || this.system.protection == '0') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let deterioration = (this.system.deterioration ?? 0) + dmg;
|
let deterioration = (this.system.deterioration ?? 0) + dmg;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export class Misc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static typeName(type, subType) {
|
static typeName(type, subType) {
|
||||||
return subType ? game.i18n.localize(`${type.toUpperCase()}.Type${Misc.upperFirst(subType)}`)
|
return subType ? game.i18n.localize(`TYPES.${type}.${Misc.upperFirst(subType)}`)
|
||||||
: '';
|
: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,8 +63,8 @@ export class Misc {
|
|||||||
|
|
||||||
static keepDecimals(num, decimals) {
|
static keepDecimals(num, decimals) {
|
||||||
if (decimals <= 0 || decimals > 6) return num;
|
if (decimals <= 0 || decimals > 6) return num;
|
||||||
const decimal = Math.pow(10, parseInt(decimals));
|
const power10n = Math.pow(10, parseInt(decimals));
|
||||||
return Math.round(num * decimal) / decimal;
|
return Math.round(num * power10n) / power10n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static getFractionHtml(diviseur) {
|
static getFractionHtml(diviseur) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
|
|
||||||
const tableCaracDerivee = {
|
const TABLE_CARACTERISTIQUES_DERIVEES = {
|
||||||
// xp: coût pour passer du niveau inférieur à ce niveau
|
// xp: coût pour passer du niveau inférieur à ce niveau
|
||||||
1: { xp: 3, poids: "moins de 1kg", plusdom: -5, sconst: 0.5, sust: 0.1 },
|
1: { xp: 3, poids: "moins de 1kg", plusdom: -5, sconst: 0.5, sust: 0.1 },
|
||||||
2: { xp: 3, poids: "1-5", plusdom: -4, sconst: 0.5, sust: 0.3 },
|
2: { xp: 3, poids: "1-5", plusdom: -4, sconst: 0.5, sust: 0.3 },
|
||||||
@@ -58,6 +58,10 @@ export class RdDCarac {
|
|||||||
selectedCarac?.label.match(/(Apparence|Force|Agilité|Dextérité|Vue|Ouïe|Odorat-Goût|Empathie|Dérobée|Mêlée|Tir|Lancer)/);
|
selectedCarac?.label.match(/(Apparence|Force|Agilité|Dextérité|Vue|Ouïe|Odorat-Goût|Empathie|Dérobée|Mêlée|Tir|Lancer)/);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getCaracDerivee(value) {
|
||||||
|
return TABLE_CARACTERISTIQUES_DERIVEES[Math.min(Math.max(Number(value), 1), 32)];
|
||||||
|
}
|
||||||
|
|
||||||
static computeTotal(carac, beaute = undefined) {
|
static computeTotal(carac, beaute = undefined) {
|
||||||
const total = Object.values(carac ?? {}).filter(c => !c.derivee)
|
const total = Object.values(carac ?? {}).filter(c => !c.derivee)
|
||||||
.map(it => parseInt(it.value))
|
.map(it => parseInt(it.value))
|
||||||
@@ -73,7 +77,7 @@ export class RdDCarac {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static calculSConst(constitution) {
|
static calculSConst(constitution) {
|
||||||
return Number(tableCaracDerivee[Number(constitution)].sconst);
|
return RdDCarac.getCaracDerivee(constitution).sconst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -84,7 +88,7 @@ export class RdDCarac {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static getCaracXp(targetValue) {
|
static getCaracXp(targetValue) {
|
||||||
return tableCaracDerivee[targetValue]?.xp ?? 200;
|
return RdDCarac.getCaracDerivee(targetValue)?.xp ?? 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -97,37 +101,4 @@ export class RdDCarac {
|
|||||||
return Grammar.toLowerCaseNoAccent(selectedCarac?.label)?.match(/(apparence|force|agilite|dexterite|vue|ouie|odorat|empathie|melee|tir|lancer|derobee)/);
|
return Grammar.toLowerCaseNoAccent(selectedCarac?.label)?.match(/(apparence|force|agilite|dexterite|vue|ouie|odorat|empathie|melee|tir|lancer|derobee)/);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static computeCarac(system) {
|
|
||||||
system.carac.force.value = Math.min(system.carac.force.value, parseInt(system.carac.taille.value) + 4);
|
|
||||||
|
|
||||||
system.carac.derobee.value = Math.floor(parseInt(((21 - system.carac.taille.value)) + parseInt(system.carac.agilite.value)) / 2);
|
|
||||||
let bonusDomKey = Math.floor((parseInt(system.carac.force.value) + parseInt(system.carac.taille.value)) / 2);
|
|
||||||
bonusDomKey = Math.min(Math.max(bonusDomKey, 0), 32); // Clamp de securite
|
|
||||||
|
|
||||||
let tailleData = tableCaracDerivee[bonusDomKey];
|
|
||||||
system.attributs.plusdom.value = tailleData.plusdom;
|
|
||||||
|
|
||||||
system.attributs.sconst.value = RdDCarac.calculSConst(system.carac.constitution.value);
|
|
||||||
system.attributs.sust.value = tableCaracDerivee[Number(system.carac.taille.value)].sust;
|
|
||||||
|
|
||||||
system.attributs.encombrement.value = (parseInt(system.carac.force.value) + parseInt(system.carac.taille.value)) / 2;
|
|
||||||
system.carac.melee.value = Math.floor((parseInt(system.carac.force.value) + parseInt(system.carac.agilite.value)) / 2);
|
|
||||||
system.carac.tir.value = Math.floor((parseInt(system.carac.vue.value) + parseInt(system.carac.dexterite.value)) / 2);
|
|
||||||
system.carac.lancer.value = Math.floor((parseInt(system.carac.tir.value) + parseInt(system.carac.force.value)) / 2);
|
|
||||||
|
|
||||||
system.sante.vie.max = Math.ceil((parseInt(system.carac.taille.value) + parseInt(system.carac.constitution.value)) / 2);
|
|
||||||
|
|
||||||
system.sante.vie.value = Math.min(system.sante.vie.value, system.sante.vie.max)
|
|
||||||
system.sante.endurance.max = Math.max(parseInt(system.carac.taille.value) + parseInt(system.carac.constitution.value), parseInt(system.sante.vie.max) + parseInt(system.carac.volonte.value));
|
|
||||||
system.sante.endurance.value = Math.min(system.sante.endurance.value, system.sante.endurance.max);
|
|
||||||
system.sante.fatigue.max = system.sante.endurance.max * 2;
|
|
||||||
system.sante.fatigue.value = Math.min(system.sante.fatigue.value, system.sante.fatigue.max);
|
|
||||||
|
|
||||||
//Compteurs
|
|
||||||
system.reve.reve.max = system.carac.reve.value;
|
|
||||||
system.compteurs.chance.max = system.carac.chance.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { RdDBonus } from "./rdd-bonus.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 { RdDRollTables } from "./rdd-rolltables.js";
|
import { RdDRollTables } from "./rdd-rolltables.js";
|
||||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||||
import { STATUSES } from "./settings/status-effects.js";
|
import { STATUSES } from "./settings/status-effects.js";
|
||||||
import { Targets } from "./targets.js";
|
import { Targets } from "./targets.js";
|
||||||
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
||||||
@@ -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 => RdDItemCompetenceCreature.isCompetenceAttaque(it))
|
||||||
if (competence) {
|
if (competence) {
|
||||||
rollFormula = RdDCombatManager.formuleInitiative(2, competence.system.carac_value, competence.system.niveau, 0);
|
rollFormula = RdDCombatManager.formuleInitiative(2, competence.system.carac_value, competence.system.niveau, 0);
|
||||||
}
|
}
|
||||||
@@ -171,8 +171,7 @@ export class RdDCombatManager extends Combat {
|
|||||||
if (arme.system.unemain && arme.system.deuxmains && !dommages.includes("/")) {
|
if (arme.system.unemain && arme.system.deuxmains && !dommages.includes("/")) {
|
||||||
ui.notifications.info("Les dommages de l'arme à 1/2 mains " + arme.name + " ne sont pas corrects (ie sous la forme X/Y)");
|
ui.notifications.info("Les dommages de l'arme à 1/2 mains " + arme.name + " ne sont pas corrects (ie sous la forme X/Y)");
|
||||||
}
|
}
|
||||||
if ((arme.system.unemain && arme.system.competence) ||
|
if (arme.system.unemain && arme.system.competence) {
|
||||||
(arme.system.competence.toLowerCase().includes("corps à corps"))) {
|
|
||||||
actions.push(RdDCombatManager.$prepareAttaqueArme({
|
actions.push(RdDCombatManager.$prepareAttaqueArme({
|
||||||
arme: arme,
|
arme: arme,
|
||||||
infoMain: "(1 main)",
|
infoMain: "(1 main)",
|
||||||
@@ -187,7 +186,7 @@ export class RdDCombatManager extends Combat {
|
|||||||
arme: arme,
|
arme: arme,
|
||||||
infoMain: "(2 mains)",
|
infoMain: "(2 mains)",
|
||||||
dommagesReel: Number(tableauDommages[1]),
|
dommagesReel: Number(tableauDommages[1]),
|
||||||
competence: arme.system.competence.replace(" 1 main", " 2 mains"),
|
competence: RdDItemArme.competence2Mains(arme),
|
||||||
carac: carac,
|
carac: carac,
|
||||||
competences: competences
|
competences: competences
|
||||||
}));
|
}));
|
||||||
@@ -230,7 +229,9 @@ 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))
|
||||||
|
.map(it => RdDItemCompetenceCreature.armeCreature(it))
|
||||||
.filter(it => it != undefined);
|
.filter(it => it != undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,11 +259,10 @@ export class RdDCombatManager extends Combat {
|
|||||||
actions = RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']);
|
actions = RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']);
|
||||||
} else if (actor.isPersonnage()) {
|
} else if (actor.isPersonnage()) {
|
||||||
// Recupération des items 'arme'
|
// Recupération des items 'arme'
|
||||||
const armes = actor.itemTypes['arme'].filter(it => RdDItemArme.isArmeUtilisable(it))
|
|
||||||
.concat(RdDItemArme.empoignade())
|
|
||||||
.concat(RdDItemArme.mainsNues());
|
|
||||||
|
|
||||||
const competences = actor.itemTypes['competence'];
|
const competences = actor.itemTypes['competence'];
|
||||||
|
const armes = actor.itemTypes['arme'].filter(it => RdDItemArme.isArmeUtilisable(it))
|
||||||
|
.concat(RdDItemArme.empoignade(actor))
|
||||||
|
.concat(RdDItemArme.mainsNues(actor));
|
||||||
actions = RdDCombatManager.listActionsArmes(armes, competences, actor.system.carac);
|
actions = RdDCombatManager.listActionsArmes(armes, competences, actor.system.carac);
|
||||||
|
|
||||||
if (actor.system.attributs.hautrevant.value) {
|
if (actor.system.attributs.hautrevant.value) {
|
||||||
@@ -450,7 +450,7 @@ export class RdDCombat {
|
|||||||
if (Misc.isUniqueConnectedGM()) {
|
if (Misc.isUniqueConnectedGM()) {
|
||||||
let turn = combat.turns.find(t => t.token?.id == combat.current.tokenId);
|
let turn = combat.turns.find(t => t.token?.id == combat.current.tokenId);
|
||||||
if (turn?.actor) {
|
if (turn?.actor) {
|
||||||
RdDCombat.displayActorCombatStatus(combat, turn.actor);
|
RdDCombat.displayActorCombatStatus(combat, turn.actor, turn.token.id);
|
||||||
// TODO Playaudio for player??
|
// TODO Playaudio for player??
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -514,8 +514,12 @@ export class RdDCombat {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static _callJetDeVie(event) {
|
static _callJetDeVie(event) {
|
||||||
let actorId = event.currentTarget.attributes['data-actorId'].value;
|
let actorId = event.currentTarget.attributes['data-actorId'].value;
|
||||||
let actor = game.actors.get(actorId);
|
let tokenId = event.currentTarget.attributes['data-tokenId'].value;
|
||||||
actor.jetVie();
|
let token = canvas.tokens.placeables.find(t => t.id == tokenId)
|
||||||
|
const actor = token?.actor ?? game.actors.get(actorId);
|
||||||
|
if (actor?.isOwner) {
|
||||||
|
actor.jetVie();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -541,7 +545,7 @@ export class RdDCombat {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
html.on("click", '#chat-jet-vie', event => {
|
html.on("click", 'a.chat-jet-vie', event => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
RdDCombat._callJetDeVie(event);
|
RdDCombat._callJetDeVie(event);
|
||||||
});
|
});
|
||||||
@@ -789,8 +793,7 @@ export class RdDCombat {
|
|||||||
let rollData = {
|
let rollData = {
|
||||||
passeArme: randomID(16),
|
passeArme: randomID(16),
|
||||||
mortalite: arme?.system.mortalite,
|
mortalite: arme?.system.mortalite,
|
||||||
coupsNonMortels: false,
|
competence: competence,
|
||||||
competence: competence.clone(),
|
|
||||||
surprise: this.attacker.getSurprise(true),
|
surprise: this.attacker.getSurprise(true),
|
||||||
surpriseDefenseur: this.defender.getSurprise(true),
|
surpriseDefenseur: this.defender.getSurprise(true),
|
||||||
targetToken: Targets.extractTokenData(this.target),
|
targetToken: Targets.extractTokenData(this.target),
|
||||||
@@ -821,8 +824,8 @@ export class RdDCombat {
|
|||||||
// finesse seulement en mélée, pour l'empoignade, ou si la difficulté libre est de -1 minimum
|
// finesse seulement en mélée, pour l'empoignade, ou si la difficulté libre est de -1 minimum
|
||||||
// rapidité seulement en mêlée, si l'arme le permet, et si la difficulté libre est de -1 minimum
|
// rapidité seulement en mêlée, si l'arme le permet, et si la difficulté libre est de -1 minimum
|
||||||
const isForce = !rollData.arme.system.empoignade;
|
const isForce = !rollData.arme.system.empoignade;
|
||||||
const isFinesse = rollData.arme.system.empoignade || isMeleeDiffNegative;
|
const isFinesse = rollData.tactique != 'charge' && (rollData.arme.system.empoignade || isMeleeDiffNegative);
|
||||||
const isRapide = !rollData.arme.system.empoignade && isMeleeDiffNegative && rollData.arme.system.rapide;
|
const isRapide = rollData.tactique != 'charge' && !rollData.arme.system.empoignade && isMeleeDiffNegative && rollData.arme.system.rapide;
|
||||||
// si un seul choix possible, le prendre
|
// si un seul choix possible, le prendre
|
||||||
if (isForce && !isFinesse && !isRapide) {
|
if (isForce && !isFinesse && !isRapide) {
|
||||||
return await this.choixParticuliere(rollData, "force");
|
return await this.choixParticuliere(rollData, "force");
|
||||||
@@ -886,8 +889,8 @@ export class RdDCombat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// # utilisation esquive
|
// # utilisation esquive
|
||||||
const corpsACorps = this.defender.getCompetence("Corps à corps", { onMessage: it => console.info(it, this.defender) });
|
const corpsACorps = this.defender.getCompetenceCorpsACorps({ onMessage: it => console.info(it, this.defender) });
|
||||||
const esquives = duplicate(this.defender.getCompetences("esquive", { onMessage: it => console.info(it, this.defender) }))
|
const esquives = duplicate(this.defender.getCompetencesEsquive())
|
||||||
esquives.forEach(e => e.system.nbUsage = e?._id ? this.defender.getItemUse(e._id) : 0);
|
esquives.forEach(e => e.system.nbUsage = e?._id ? this.defender.getItemUse(e._id) : 0);
|
||||||
|
|
||||||
const paramChatDefense = {
|
const paramChatDefense = {
|
||||||
@@ -1045,10 +1048,10 @@ 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: ReglesOptionnelles.isUsing('categorieParade') && RdDItemArme.needParadeSignificative(attackerRoll.arme, armeParade),
|
||||||
needResist: RdDItemArme.needArmeResist(attackerRoll.arme, armeParade),
|
needResist: RdDItemArme.needArmeResist(attackerRoll.arme, armeParade),
|
||||||
carac: this.defender.system.carac,
|
carac: this.defender.system.carac,
|
||||||
show: {}
|
show: {}
|
||||||
@@ -1126,7 +1129,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,
|
||||||
@@ -1166,7 +1169,7 @@ export class RdDCombat {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async computeDeteriorationArme(defenderRoll) {
|
async computeDeteriorationArme(defenderRoll) {
|
||||||
if (!ReglesOptionelles.isUsing('resistanceArmeParade')) {
|
if (!ReglesOptionnelles.isUsing('resistanceArmeParade')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const attackerRoll = defenderRoll.attackerRoll;
|
const attackerRoll = defenderRoll.attackerRoll;
|
||||||
@@ -1215,7 +1218,7 @@ export class RdDCombat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Si l'arme de parade n'est pas un bouclier, jet de désarmement (p.132)
|
// Si l'arme de parade n'est pas un bouclier, jet de désarmement (p.132)
|
||||||
if (ReglesOptionelles.isUsing('defenseurDesarme') && resistance > 0 && RdDItemArme.getCategorieParade(defenderRoll.arme) != 'boucliers') {
|
if (ReglesOptionnelles.isUsing('defenseurDesarme') && resistance > 0 && RdDItemArme.getCategorieParade(defenderRoll.arme) != 'boucliers') {
|
||||||
let desarme = await RdDResolutionTable.rollData({
|
let desarme = await RdDResolutionTable.rollData({
|
||||||
caracValue: this.defender.getForce(),
|
caracValue: this.defender.getForce(),
|
||||||
finalLevel: Misc.toInt(defenderRoll.competence.system.niveau) - dmg,
|
finalLevel: Misc.toInt(defenderRoll.competence.system.niveau) - dmg,
|
||||||
@@ -1230,7 +1233,7 @@ export class RdDCombat {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async computeRecul(defenderRoll) { // Calcul du recul (p. 132)
|
async computeRecul(defenderRoll) { // Calcul du recul (p. 132)
|
||||||
const attackerRoll = defenderRoll.attackerRoll;
|
const attackerRoll = defenderRoll.attackerRoll;
|
||||||
if (ReglesOptionelles.isUsing('recul') && this._isForceOuCharge(attackerRoll)) {
|
if (ReglesOptionnelles.isUsing('recul') && this._isForceOuCharge(attackerRoll)) {
|
||||||
const impact = this._computeImpactRecul(attackerRoll);
|
const impact = this._computeImpactRecul(attackerRoll);
|
||||||
const rollRecul = await RdDResolutionTable.rollData({ caracValue: 10, finalLevel: impact });
|
const rollRecul = await RdDResolutionTable.rollData({ caracValue: 10, finalLevel: impact });
|
||||||
if (rollRecul.rolled.isSuccess) {
|
if (rollRecul.rolled.isSuccess) {
|
||||||
@@ -1295,7 +1298,7 @@ export class RdDCombat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async displayActorCombatStatus(combat, actor) {
|
static async displayActorCombatStatus(combat, actor, tokenId) {
|
||||||
let formData = {
|
let formData = {
|
||||||
combatId: combat._id,
|
combatId: combat._id,
|
||||||
alias: actor.name,
|
alias: actor.name,
|
||||||
@@ -1304,12 +1307,18 @@ export class RdDCombat {
|
|||||||
blessuresStatus: actor.computeResumeBlessure(),
|
blessuresStatus: actor.computeResumeBlessure(),
|
||||||
SConst: actor.getSConst(),
|
SConst: actor.getSConst(),
|
||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
|
tokenId: tokenId,
|
||||||
isGrave: actor.countBlessures(it => it.isGrave()) > 0,
|
isGrave: actor.countBlessures(it => it.isGrave()) > 0,
|
||||||
isCritique: actor.countBlessures(it => it.isCritique()) > 0
|
isCritique: actor.countBlessures(it => it.isCritique()) > 0
|
||||||
}
|
}
|
||||||
|
await ChatMessage.create({
|
||||||
ChatUtility.createChatWithRollMode(actor.name, {
|
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-acteur.hbs`, formData),
|
||||||
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-summary.html`, formData)
|
alias: actor.name
|
||||||
|
});
|
||||||
|
await ChatMessage.create({
|
||||||
|
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-sante.hbs`, formData),
|
||||||
|
whisper: ChatUtility.getWhisperRecipientsAndGMs(actor.name),
|
||||||
|
alias: actor.name
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||||
|
|
||||||
export class RdDConfirm {
|
export class RdDConfirm {
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static confirmer(options, autresActions) {
|
static confirmer(options, autresActions) {
|
||||||
options.bypass = options.bypass || !(options.settingConfirmer == undefined || ReglesOptionelles.isUsing(options.settingConfirmer));
|
options.bypass = options.bypass || !(options.settingConfirmer == undefined || ReglesOptionnelles.isUsing(options.settingConfirmer));
|
||||||
if (options.bypass) {
|
if (options.bypass) {
|
||||||
options.onAction();
|
options.onAction();
|
||||||
}
|
}
|
||||||
@@ -47,7 +47,7 @@ export class RdDConfirm {
|
|||||||
icon: '<i class="fas fa-user-check"></i>',
|
icon: '<i class="fas fa-user-check"></i>',
|
||||||
label: options.buttonLabel + "<br>et ne plus demander",
|
label: options.buttonLabel + "<br>et ne plus demander",
|
||||||
callback: () => {
|
callback: () => {
|
||||||
ReglesOptionelles.set(options.settingConfirmer, false);
|
ReglesOptionnelles.set(options.settingConfirmer, false);
|
||||||
options.onAction();
|
options.onAction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { RdDRoll } from "./rdd-roll.js";
|
|||||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||||
import { ChatUtility } from "./chat-utility.js";
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
import { STATUSES } from "./settings/status-effects.js";
|
import { STATUSES } from "./settings/status-effects.js";
|
||||||
|
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||||
|
import { TYPES } from "./item.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
@@ -14,6 +16,47 @@ export class RdDEmpoignade {
|
|||||||
static init() {
|
static init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static registerChatCallbacks(html) {
|
||||||
|
html.on("click", '.defense-empoignade-cac', event => {
|
||||||
|
const chatMessage = ChatUtility.getChatMessage(event);
|
||||||
|
const rollData = RdDEmpoignade.$readRollEmpoignade(chatMessage);
|
||||||
|
let defenseMode = event.currentTarget.attributes['data-defense-mode'].value
|
||||||
|
RdDEmpoignade.onDefenseEmpoignade(rollData, defenseMode, "Corps à corps", "melee")
|
||||||
|
});
|
||||||
|
html.on("click", '.defense-empoignade-esquive', event => {
|
||||||
|
const chatMessage = ChatUtility.getChatMessage(event);
|
||||||
|
const rollData = RdDEmpoignade.$readRollEmpoignade(chatMessage);
|
||||||
|
let defenseMode = event.currentTarget.attributes['data-defense-mode'].value
|
||||||
|
RdDEmpoignade.onDefenseEmpoignade(rollData, defenseMode, "Esquive", "derobee")
|
||||||
|
});
|
||||||
|
html.on("click", '.empoignade-poursuivre', event => {
|
||||||
|
let attackerId = event.currentTarget.attributes['data-attackerId'].value
|
||||||
|
let defenderId = event.currentTarget.attributes['data-defenderId'].value
|
||||||
|
RdDEmpoignade.onAttaqueEmpoignadeValidee(game.actors.get(attackerId), game.actors.get(defenderId))
|
||||||
|
});
|
||||||
|
html.on("click", '.empoignade-entrainer-sol', event => {
|
||||||
|
const chatMessage = ChatUtility.getChatMessage(event);
|
||||||
|
const rollData = RdDEmpoignade.$readRollEmpoignade(chatMessage);
|
||||||
|
RdDEmpoignade.entrainerAuSol(rollData)
|
||||||
|
ChatUtility.removeChatMessageId(chatMessage.id)
|
||||||
|
});
|
||||||
|
html.on("click", '.empoignade-projeter-sol', event => {
|
||||||
|
const chatMessage = ChatUtility.getChatMessage(event);
|
||||||
|
const rollData = RdDEmpoignade.$readRollEmpoignade(chatMessage);
|
||||||
|
RdDEmpoignade.projeterAuSol(rollData)
|
||||||
|
ChatUtility.removeChatMessageId(chatMessage.id)
|
||||||
|
});
|
||||||
|
html.on("change", '.empoignade-perte-endurance', event => {
|
||||||
|
const chatMessage = ChatUtility.getChatMessage(event);
|
||||||
|
const rollData = RdDEmpoignade.$readRollEmpoignade(chatMessage);
|
||||||
|
if (event.currentTarget.value && event.currentTarget.value != "none") {
|
||||||
|
RdDEmpoignade.perteEndurance(rollData, event.currentTarget.value)
|
||||||
|
ChatUtility.removeChatMessageId(chatMessage.id)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static checkEmpoignadeEnCours(actor) {
|
static checkEmpoignadeEnCours(actor) {
|
||||||
// TODO: autoriser la perception? la comédie/séduction?
|
// TODO: autoriser la perception? la comédie/séduction?
|
||||||
@@ -24,74 +67,92 @@ export class RdDEmpoignade {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static $storeRollEmpoignade(msg, rollData) {
|
||||||
|
RdDEmpoignade.$reduceActorToIds(rollData);
|
||||||
|
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData);
|
||||||
|
}
|
||||||
|
|
||||||
|
static $reduceActorToIds(rollData) {
|
||||||
|
rollData.attacker = { id: rollData.attacker.id };
|
||||||
|
rollData.defender = { id: rollData.defender.id };
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static $readRollEmpoignade(msg) {
|
||||||
|
const rollData = ChatUtility.getMessageData(msg, 'empoignade-roll-data');
|
||||||
|
RdDEmpoignade.$replaceIdsWithActors(rollData);
|
||||||
|
return rollData
|
||||||
|
}
|
||||||
|
|
||||||
|
static $replaceIdsWithActors(rollData) {
|
||||||
|
rollData.attacker = game.actors.get(rollData.attacker.id);
|
||||||
|
rollData.defender = game.actors.get(rollData.defender.id);
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static isEmpoignadeEnCours(actor) {
|
static isEmpoignadeEnCours(actor) {
|
||||||
return actor.itemTypes['empoignade'].find(it => it.system.pointsemp > 0)
|
return actor.itemTypes[TYPES.empoignade].find(it => it.system.pointsemp > 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getEmpoignadeById(actor, id) {
|
static getEmpoignadeById(actor, id) {
|
||||||
let emp = actor.itemTypes['empoignade'].find(it => it.system.empoignadeid == id)
|
let emp = actor.itemTypes[TYPES.empoignade].find(it => it.system.empoignadeid == id)
|
||||||
return emp && duplicate(emp) || undefined;
|
return emp && duplicate(emp) || undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getEmpoignade(attacker, defender) {
|
static getEmpoignade(attacker, defender) {
|
||||||
let emp = attacker.itemTypes['empoignade'].find(it => it.system.empoigneurid == attacker.id && it.system.empoigneid == defender.id)
|
let emp = attacker.itemTypes[TYPES.empoignade].find(it =>
|
||||||
if (!emp) {
|
(it.system.empoigneurid == attacker.id && it.system.empoigneid == defender.id) ||
|
||||||
emp = attacker.itemTypes['empoignade'].find(it => it.system.empoigneurid == defender.id && it.system.empoigneid == attacker.id)
|
(it.system.empoigneurid == defender.id && it.system.empoigneid == attacker.id)
|
||||||
}
|
)
|
||||||
if (emp) {
|
if (emp) {
|
||||||
return duplicate(emp);
|
return duplicate(emp);
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getMalusTaille(emp, attacker, defender) {
|
static getMalusTaille(emp, attacker, defender) {
|
||||||
// Si pas empoigné, alors 0
|
// Si pas empoigné, alors 0
|
||||||
if (emp.system.pointsemp == 0) {
|
if (emp.system.pointsemp == 0) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
// Malus de -1 si différence de taille de 2 ou plus (p 135)
|
// p135: Malus de -1 par point de taille de différence de taille au delà de 1 (donc -2 pour une différence de 3, ...)
|
||||||
if (attacker.system.carac.taille.value < defender.system.carac.taille.value - 1) {
|
const diffTaille = attacker.system.carac.taille.value - defender.system.carac.taille.value;
|
||||||
return attacker.system.carac.taille.value - (defender.system.carac.taille.value - 1)
|
const diffTailleAbs = Math.abs(diffTaille)
|
||||||
|
const signDiff = diffTaille > 0 ? 1 : -1
|
||||||
|
|
||||||
|
if (diffTailleAbs > 2) {
|
||||||
|
return signDiff * (diffTailleAbs - 1)
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
static isActionAutorisee(mode, attacker, defender) {
|
||||||
static async onAttaqueEmpoignadeValidee(attacker, defender) {
|
const acting = RdDEmpoignade.isActionDefenseur(mode) ? defender : attacker;
|
||||||
let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
|
if (acting.getUserLevel(game.user) < CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) {
|
||||||
const isNouvelle = empoignade == undefined;
|
ui.notifications.warn(`Vous n'êtes pas autorisé à choisir l'action de ${acting.name}`)
|
||||||
empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender))
|
return false;
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
let mode = (empoignade && empoignade.system.empoigneurid == attacker.id) ? "empoigner" : "liberer"
|
static isActionDefenseur(mode) {
|
||||||
|
switch (mode) {
|
||||||
let rollData = {
|
case "liberer":
|
||||||
mode: mode,
|
case "contrer-empoigner":
|
||||||
isEmpoignade: true,
|
return true;
|
||||||
competence: attacker.getCompetence("Corps à corps").clone(),
|
|
||||||
selectedCarac: attacker.system.carac.melee,
|
|
||||||
empoignade: empoignade,
|
|
||||||
attackerId: attacker.id,
|
|
||||||
attackerName: attacker.name,
|
|
||||||
defenderName: defender.name,
|
|
||||||
defenderId: defender.id,
|
|
||||||
malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender)
|
|
||||||
}
|
|
||||||
if (attacker.isCreatureEntite()) {
|
|
||||||
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
|
||||||
}
|
|
||||||
if (empoignade.system.pointsemp >= 2) {
|
|
||||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-actions.html');
|
|
||||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
|
||||||
} else {
|
|
||||||
await RdDEmpoignade.$rollAttaqueEmpoignade(attacker, rollData, isNouvelle);
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async onAttaqueEmpoignade(attacker, defender) {
|
static async onAttaqueEmpoignade(attacker, defender) {
|
||||||
|
if (!RdDEmpoignade.isActionAutorisee("empoigner", attacker, defender)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
|
let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
|
||||||
const isNouvelle = empoignade == undefined;
|
const isNouvelle = empoignade == undefined;
|
||||||
empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender))
|
empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender))
|
||||||
@@ -105,6 +166,38 @@ export class RdDEmpoignade {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async onAttaqueEmpoignadeValidee(attacker, defender) {
|
||||||
|
let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
|
||||||
|
const isNouvelle = empoignade == undefined;
|
||||||
|
empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender))
|
||||||
|
|
||||||
|
let mode = (empoignade && empoignade.system.empoigneurid == attacker.id) ? "empoigner" : "liberer"
|
||||||
|
|
||||||
|
if (!RdDEmpoignade.isActionAutorisee(mode, attacker, defender)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let rollData = {
|
||||||
|
mode, empoignade, attacker, defender,
|
||||||
|
isEmpoignade: true,
|
||||||
|
competence: attacker.getCompetenceCorpsACorps(),
|
||||||
|
selectedCarac: attacker.system.carac.melee,
|
||||||
|
malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender)
|
||||||
|
}
|
||||||
|
if (attacker.isCreatureEntite()) {
|
||||||
|
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
||||||
|
}
|
||||||
|
if (empoignade.system.pointsemp >= 2) {
|
||||||
|
if (!empoignade.system.ausol) {
|
||||||
|
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-entrainer.html');
|
||||||
|
RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await RdDEmpoignade.$rollAttaqueEmpoignade(attacker, rollData, isNouvelle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async onAttaqueEmpoignadeFromItem(empoignade) {
|
static async onAttaqueEmpoignadeFromItem(empoignade) {
|
||||||
let attacker = game.actors.get(empoignade.system.empoigneurid)
|
let attacker = game.actors.get(empoignade.system.empoigneurid)
|
||||||
@@ -112,6 +205,20 @@ export class RdDEmpoignade {
|
|||||||
await this.onAttaqueEmpoignadeValidee(attacker, defender)
|
await this.onAttaqueEmpoignadeValidee(attacker, defender)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async onImmobilisation(attacker, defender, empoignade) {
|
||||||
|
const rollData = {
|
||||||
|
mode: "immobilise",
|
||||||
|
empoignade, attacker, defender,
|
||||||
|
isEmpoignade: true,
|
||||||
|
competence: attacker.getCompetenceCorpsACorps()
|
||||||
|
}
|
||||||
|
const msg = await ChatMessage.create({
|
||||||
|
whisper: ChatUtility.getWhisperRecipientsAndGMs(attacker.name),
|
||||||
|
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-immobilise.html`, rollData)
|
||||||
|
})
|
||||||
|
RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async $rollAttaqueEmpoignade(attacker, rollData, isNouvelle = false) {
|
static async $rollAttaqueEmpoignade(attacker, rollData, isNouvelle = false) {
|
||||||
const dialog = await RdDRoll.create(attacker, rollData,
|
const dialog = await RdDRoll.create(attacker, rollData,
|
||||||
@@ -119,35 +226,40 @@ export class RdDEmpoignade {
|
|||||||
{
|
{
|
||||||
name: 'jet-empoignade',
|
name: 'jet-empoignade',
|
||||||
label: 'Empoigner',
|
label: 'Empoigner',
|
||||||
callbacks: [
|
callbacks: [{ action: async (r) => await RdDEmpoignade.$onRollEmpoignade(r, isNouvelle) },]
|
||||||
{ condition: r => (r.rolled.isSuccess), action: async (r) => await RdDEmpoignade.$onRollEmpoignade(r, true, isNouvelle) },
|
|
||||||
{ condition: r => (r.rolled.isEchec), action: async (r) => await RdDEmpoignade.$onRollEmpoignade(r, false, isNouvelle) },
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async $onRollEmpoignade(rollData, isSuccess, isNouvelle = false) {
|
static async $onRollEmpoignade(rollData, isNouvelle = false) {
|
||||||
let attacker = game.actors.get(rollData.attackerId)
|
let attacker = game.actors.get(rollData.attacker.id)
|
||||||
let defender = game.actors.get(rollData.defenderId)
|
let defender = game.actors.get(rollData.defender.id)
|
||||||
|
|
||||||
let empoignade = rollData.empoignade
|
|
||||||
empoignade.isSuccess = isSuccess;
|
|
||||||
|
|
||||||
if (isSuccess && isNouvelle) {
|
if (rollData.rolled.isSuccess && isNouvelle) {
|
||||||
|
const objectEmpoignade = rollData.empoignade.toObject();
|
||||||
// Creer l'empoignade sur attaquant/defenseur
|
// Creer l'empoignade sur attaquant/defenseur
|
||||||
await attacker.createEmbeddedDocuments('Item', [empoignade.toObject()])
|
attacker.creerObjetParMJ(objectEmpoignade);
|
||||||
await defender.createEmbeddedDocuments('Item', [empoignade.toObject()])
|
defender.creerObjetParMJ(objectEmpoignade);
|
||||||
|
}
|
||||||
|
|
||||||
|
rollData.empoignade.isSuccess = rollData.rolled.isSuccess;
|
||||||
|
if (rollData.rolled.isPart) {
|
||||||
|
rollData.particuliere = "finesse";
|
||||||
}
|
}
|
||||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-resultat.html');
|
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-resultat.html');
|
||||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async onDefenseEmpoignade(rollData, defenseMode, competenceName = "Corps à corps", carac = "melee") {
|
static async onDefenseEmpoignade(attackerRoll, mode, competenceName = "Corps à corps", carac = "melee") {
|
||||||
let attacker = game.actors.get(rollData.attackerId)
|
let attacker = game.actors.get(attackerRoll.attacker.id)
|
||||||
let defender = game.actors.get(rollData.defenderId)
|
let defender = game.actors.get(attackerRoll.defender.id)
|
||||||
|
if (!RdDEmpoignade.isActionAutorisee(mode, attacker, defender)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let empoignade = this.getEmpoignade(attacker, defender)
|
let empoignade = this.getEmpoignade(attacker, defender)
|
||||||
|
|
||||||
if (!empoignade) {
|
if (!empoignade) {
|
||||||
@@ -156,18 +268,23 @@ export class RdDEmpoignade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
empoignade = duplicate(empoignade)
|
empoignade = duplicate(empoignade)
|
||||||
rollData.mode = defenseMode
|
let defenderRoll = {
|
||||||
rollData.empoignade = empoignade
|
mode, attacker, defender, empoignade, attackerRoll,
|
||||||
rollData.competence = defender.getCompetence(competenceName),
|
diffLibre: attackerRoll.diffLibre,
|
||||||
rollData.selectedCarac = defender.system.carac[carac],
|
attaqueParticuliere: attackerRoll.particuliere,
|
||||||
rollData.malusTaille = RdDEmpoignade.getMalusTaille(empoignade, defender, attacker)
|
competence: defender.getCompetence(competenceName),
|
||||||
|
surprise: defender.getSurprise(true),
|
||||||
await RdDEmpoignade.$rollDefenseEmpoignade(defender, rollData);
|
carac: defender.system.carac,
|
||||||
|
selectedCarac: defender.system.carac[carac],
|
||||||
|
malusTaille: RdDEmpoignade.getMalusTaille(empoignade, defender, attacker),
|
||||||
|
show: {}
|
||||||
|
};
|
||||||
|
await RdDEmpoignade.$rollDefenseEmpoignade(defender, defenderRoll);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async $rollDefenseEmpoignade(defender, rollData) {
|
static async $rollDefenseEmpoignade(defender, defenderRoll) {
|
||||||
const dialog = await RdDRoll.create(defender, rollData,
|
const dialog = await RdDRoll.create(defender, defenderRoll,
|
||||||
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-empoignade.html' },
|
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-empoignade.html' },
|
||||||
{
|
{
|
||||||
name: 'empoignade',
|
name: 'empoignade',
|
||||||
@@ -183,7 +300,7 @@ export class RdDEmpoignade {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async $onRollContrerLiberer(rollData) {
|
static async $onRollContrerLiberer(rollData) {
|
||||||
let empoignade = rollData.empoignade
|
let empoignade = rollData.empoignade
|
||||||
|
|
||||||
if (rollData.mode == "contrer-empoigner" && !rollData.rolled.isSuccess) {
|
if (rollData.mode == "contrer-empoigner" && !rollData.rolled.isSuccess) {
|
||||||
empoignade.system.pointsemp++
|
empoignade.system.pointsemp++
|
||||||
RdDEmpoignade.$updateEtatEmpoignade(empoignade)
|
RdDEmpoignade.$updateEtatEmpoignade(empoignade)
|
||||||
@@ -192,13 +309,12 @@ export class RdDEmpoignade {
|
|||||||
empoignade.system.pointsemp--
|
empoignade.system.pointsemp--
|
||||||
RdDEmpoignade.$updateEtatEmpoignade(empoignade)
|
RdDEmpoignade.$updateEtatEmpoignade(empoignade)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empoignade.system.pointsemp >= 2) {
|
|
||||||
let attacker = game.actors.get(empoignade.system.empoigneurid)
|
|
||||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-actions.html');
|
|
||||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
|
||||||
}
|
|
||||||
await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-empoignade-resultat.html')
|
await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-empoignade-resultat.html')
|
||||||
|
if (empoignade.system.pointsemp >= 2) {
|
||||||
|
let msg = await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-empoignade-entrainer.html');
|
||||||
|
RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -223,16 +339,15 @@ export class RdDEmpoignade {
|
|||||||
let defender = game.actors.get(empoignade.system.empoigneid)
|
let defender = game.actors.get(empoignade.system.empoigneid)
|
||||||
let emp = RdDEmpoignade.getEmpoignadeById(defender, empoignade.system.empoignadeid)
|
let emp = RdDEmpoignade.getEmpoignadeById(defender, empoignade.system.empoignadeid)
|
||||||
await defender.deleteEmbeddedDocuments('Item', [emp._id])
|
await defender.deleteEmbeddedDocuments('Item', [emp._id])
|
||||||
|
|
||||||
//let attacker = game.actors.get(empoignade.system.empoigneurid)
|
|
||||||
//emp = RdDEmpoignade.getEmpoignadeById(attacker, empoignade.system.empoignadeid)
|
|
||||||
//await attacker.deleteEmbeddedDocuments('Item', [emp._id])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async entrainerAuSol(rollData) {
|
static async entrainerAuSol(rollData) {
|
||||||
let attacker = game.actors.get(rollData.attackerId)
|
let attacker = game.actors.get(rollData.attacker.id)
|
||||||
let defender = game.actors.get(rollData.defenderId)
|
let defender = game.actors.get(rollData.defender.id)
|
||||||
|
if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
let empoignade = this.getEmpoignade(attacker, defender)
|
let empoignade = this.getEmpoignade(attacker, defender)
|
||||||
|
|
||||||
empoignade.system.ausol = true
|
empoignade.system.ausol = true
|
||||||
@@ -242,25 +357,32 @@ export class RdDEmpoignade {
|
|||||||
await defender.setEffect(STATUSES.StatusProne, true);
|
await defender.setEffect(STATUSES.StatusProne, true);
|
||||||
|
|
||||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-entrainer-sol.html');
|
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-entrainer-sol.html');
|
||||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async projeterAuSol(rollData) {
|
static async projeterAuSol(rollData) {
|
||||||
let attacker = game.actors.get(rollData.attackerId)
|
let attacker = game.actors.get(rollData.attacker.id)
|
||||||
let defender = game.actors.get(rollData.defenderId)
|
let defender = game.actors.get(rollData.defender.id)
|
||||||
|
if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
let empoignade = this.getEmpoignade(attacker, defender)
|
let empoignade = this.getEmpoignade(attacker, defender)
|
||||||
|
|
||||||
await defender.setEffect(STATUSES.StatusProne, true);
|
await defender.setEffect(STATUSES.StatusProne, true);
|
||||||
await this.$deleteEmpoignade(empoignade)
|
await this.$deleteEmpoignade(empoignade)
|
||||||
|
|
||||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-projeter-sol.html');
|
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-projeter-sol.html');
|
||||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async perteEndurance(rollData, perteMode) {
|
static async perteEndurance(rollData, perteMode) {
|
||||||
let attacker = game.actors.get(rollData.attackerId)
|
let attacker = game.actors.get(rollData.attacker.id)
|
||||||
let defender = game.actors.get(rollData.defenderId)
|
let defender = game.actors.get(rollData.defender.id)
|
||||||
|
if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
let empoignade = this.getEmpoignade(attacker, defender)
|
let empoignade = this.getEmpoignade(attacker, defender)
|
||||||
|
|
||||||
//console.log("Perte d'endurance :!!!", perteMode)
|
//console.log("Perte d'endurance :!!!", perteMode)
|
||||||
@@ -278,7 +400,7 @@ export class RdDEmpoignade {
|
|||||||
await defender.santeIncDec("endurance", -(3 * Math.floor(endValue / 4)));
|
await defender.santeIncDec("endurance", -(3 * Math.floor(endValue / 4)));
|
||||||
}
|
}
|
||||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-perte-endurance.html');
|
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-perte-endurance.html');
|
||||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
|
import { RdDItemArme } from "./item-arme.js";
|
||||||
|
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||||
|
import { TYPES } from "./item.js";
|
||||||
|
|
||||||
export class RdDHotbar {
|
export class RdDHotbar {
|
||||||
|
|
||||||
static async addToHotbar(item, slot) {
|
static async createItemMacro(item, slot, armeCompetence = undefined) {
|
||||||
let command = `game.system.rdd.RdDHotbar.rollMacro("${item.name}", "${item.type}");`;
|
const itemName = item.name;
|
||||||
let macro = game.macros.contents.find(m => (m.name === item.name) && (m.command === command));
|
let macroName = itemName + RdDHotbar.$macroNameSuffix(armeCompetence);
|
||||||
|
let command = `game.system.rdd.RdDHotbar.rollMacro("${itemName}", "${item.type}", "${armeCompetence}");`
|
||||||
|
let macro = game.macros.contents.find(m => (m.name === itemName) && (m.command === command));
|
||||||
if (!macro) {
|
if (!macro) {
|
||||||
macro = await Macro.create({
|
macro = await Macro.create({
|
||||||
name: item.name,
|
name: macroName,
|
||||||
type: "script",
|
type: "script",
|
||||||
img: item.img,
|
img: item.img,
|
||||||
command: command
|
command: command
|
||||||
@@ -15,6 +20,59 @@ export class RdDHotbar {
|
|||||||
await game.user.assignHotbarMacro(macro, slot);
|
await game.user.assignHotbarMacro(macro, slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static $macroNameSuffix(armeCompetence) {
|
||||||
|
switch (armeCompetence) {
|
||||||
|
case 'unemain': return ' (1 main)';
|
||||||
|
case 'deuxmains': return ' (2 main)';
|
||||||
|
case 'tir': return ' (tir)';
|
||||||
|
case 'lancer': return ' (lancer)';
|
||||||
|
case 'pugilat': return ' (pugilat)';
|
||||||
|
case 'empoignade': return ' (empoignade)';
|
||||||
|
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
static async addToHotbar(item, slot) {
|
||||||
|
switch (item?.type ?? '') {
|
||||||
|
case TYPES.arme:
|
||||||
|
{
|
||||||
|
// Les armes peuvent avoir plusieurs usages
|
||||||
|
if (item.system.competence != '') {
|
||||||
|
if (item.system.unemain) {
|
||||||
|
await this.createItemMacro(item, slot++, 'unemain')
|
||||||
|
}
|
||||||
|
if (item.system.deuxmains) {
|
||||||
|
await this.createItemMacro(item, slot++, 'deuxmains')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (item.system.lancer != '') {
|
||||||
|
await this.createItemMacro(item, slot++, 'lancer')
|
||||||
|
}
|
||||||
|
if (item.system.tir != '') {
|
||||||
|
await this.createItemMacro(item, slot++, 'lancer')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
case TYPES.competencecreature:
|
||||||
|
const categorie = RdDItemCompetenceCreature.getCategorieAttaque(item) ?? 'competence';
|
||||||
|
await this.createItemMacro(item, slot, categorie)
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
case TYPES.competence:
|
||||||
|
await this.createItemMacro(item, slot++, 'competence')
|
||||||
|
if (item.isCorpsACorps()) {
|
||||||
|
await this.createItemMacro(item, slot++, 'pugilat')
|
||||||
|
await this.createItemMacro(item, slot++, 'empoignade')
|
||||||
|
}
|
||||||
|
if (item.isCompetenceArme()) {
|
||||||
|
ui.notifications.info(`${item.name} est une compétence d'arme, la macro n'est pas liée à un arme.<br>
|
||||||
|
Créez la macro depuis l'arme ou l'onglet combat pour garder les automatisations de combat.`);
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a macro when dropping an entity on the hotbar
|
* Create a macro when dropping an entity on the hotbar
|
||||||
* Item - open roll dialog for item
|
* Item - open roll dialog for item
|
||||||
@@ -23,20 +81,19 @@ export class RdDHotbar {
|
|||||||
*/
|
*/
|
||||||
static initDropbar() {
|
static initDropbar() {
|
||||||
|
|
||||||
Hooks.on("hotbarDrop", (bar, documentData, slot) => {
|
Hooks.on('hotbarDrop', (bar, documentData, slot) => {
|
||||||
|
|
||||||
// Create item macro if rollable item - weapon, spell, prayer, trait, or skill
|
// Create item macro if rollable item - weapon, spell, prayer, trait, or skill
|
||||||
if (documentData.type == "Item") {
|
if (documentData.type == 'Item') {
|
||||||
let item = fromUuidSync(documentData.uuid)
|
const item = fromUuidSync(documentData.uuid) ?? this.actor.items.get(documentData.uuid)
|
||||||
if (item == undefined) {
|
console.log('DROP', documentData, item)
|
||||||
item = this.actor.items.get(documentData.uuid)
|
switch (item?.type) {
|
||||||
|
case TYPES.arme:
|
||||||
|
case TYPES.competence:
|
||||||
|
case TYPES.competencecreature:
|
||||||
|
this.addToHotbar(item, slot)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
console.log("DROP", documentData, item)
|
|
||||||
if (!item || (item.type != "arme" && item.type != "competence")) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
this.addToHotbar(item, slot)
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@@ -44,12 +101,14 @@ export class RdDHotbar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Roll macro */
|
/** Roll macro */
|
||||||
static rollMacro(itemName, itemType, bypassData) {
|
static rollMacro(itemName, itemType, categorieArme = 'competence') {
|
||||||
const speaker = ChatMessage.getSpeaker();
|
const speaker = ChatMessage.getSpeaker();
|
||||||
let actor;
|
let actor;
|
||||||
if (speaker.token) actor = game.actors.tokens[speaker.token];
|
if (speaker.token) actor = game.actors.tokens[speaker.token];
|
||||||
if (!actor) actor = game.actors.get(speaker.actor);
|
if (!actor) actor = game.actors.get(speaker.actor);
|
||||||
|
if (!actor) {
|
||||||
|
return ui.notifications.warn(`Impossible de trouver le personnage concerné`);
|
||||||
|
}
|
||||||
let item = actor?.items.find(it => it.name === itemName && it.type == itemType) ?? undefined;
|
let item = actor?.items.find(it => it.name === itemName && it.type == itemType) ?? undefined;
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return ui.notifications.warn(`Impossible de trouver l'objet de cette macro`);
|
return ui.notifications.warn(`Impossible de trouver l'objet de cette macro`);
|
||||||
@@ -57,10 +116,23 @@ export class RdDHotbar {
|
|||||||
|
|
||||||
// Trigger the item roll
|
// Trigger the item roll
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
case "arme":
|
case TYPES.arme:
|
||||||
return actor.rollArme(item);
|
return actor.rollArme(item, categorieArme);
|
||||||
case "competence":
|
case TYPES.competence:
|
||||||
return actor.rollCompetence(itemName);
|
if (item.isCorpsACorps()) {
|
||||||
|
switch (categorieArme) {
|
||||||
|
case 'pugilat':
|
||||||
|
return actor.rollArme(RdDItemArme.mainsNues(actor), 'competence');
|
||||||
|
case 'empoignade':
|
||||||
|
return actor.rollArme(RdDItemArme.empoignade(actor), 'competence');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actor.rollCompetence(item);
|
||||||
|
case TYPES.competencecreature:
|
||||||
|
return item.system.iscombat && !item.system.isparade
|
||||||
|
? actor.rollArme(item, categorieArme)
|
||||||
|
: actor.rollCompetence(item);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { RdDCombatManager, RdDCombat } from "./rdd-combat.js";
|
|||||||
import { ChatUtility } from "./chat-utility.js";
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
import { StatusEffects } from "./settings/status-effects.js";
|
import { StatusEffects } from "./settings/status-effects.js";
|
||||||
import { RdDCompendiumOrganiser } from "./rdd-compendium-organiser.js";
|
import { RdDCompendiumOrganiser } from "./rdd-compendium-organiser.js";
|
||||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||||
import { RdDHotbar } from "./rdd-hotbar-drop.js"
|
import { RdDHotbar } from "./rdd-hotbar-drop.js"
|
||||||
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
||||||
import { RdDHerbes } from "./rdd-herbes.js";
|
import { RdDHerbes } from "./rdd-herbes.js";
|
||||||
@@ -29,11 +29,13 @@ import { Environnement } from "./environnement.js";
|
|||||||
import { RdDActor } from "./actor.js";
|
import { RdDActor } from "./actor.js";
|
||||||
import { RdDBaseActor } from "./actor/base-actor.js";
|
import { RdDBaseActor } from "./actor/base-actor.js";
|
||||||
import { RdDCommerce } from "./actor/commerce.js";
|
import { RdDCommerce } from "./actor/commerce.js";
|
||||||
|
import { RdDEntite } from "./actor/entite.js";
|
||||||
|
import { RdDVehicule } from "./actor/vehicule.js";
|
||||||
import { RdDActorSheet } from "./actor-sheet.js";
|
import { RdDActorSheet } from "./actor-sheet.js";
|
||||||
import { RdDCommerceSheet } from "./actor/commerce-sheet.js";
|
import { RdDCommerceSheet } from "./actor/commerce-sheet.js";
|
||||||
import { RdDActorCreatureSheet } from "./actor-creature-sheet.js";
|
import { RdDCreatureSheet } from "./actor/creature-sheet.js";
|
||||||
import { RdDActorVehiculeSheet } from "./actor-vehicule-sheet.js";
|
import { RdDActorEntiteSheet } from "./actor/entite-sheet.js";
|
||||||
import { RdDActorEntiteSheet } from "./actor-entite-sheet.js";
|
import { RdDActorVehiculeSheet } from "./actor/vehicule-sheet.js";
|
||||||
|
|
||||||
import { RdDItem } from "./item.js";
|
import { RdDItem } from "./item.js";
|
||||||
import { RdDItemBlessure } from "./item/blessure.js";
|
import { RdDItemBlessure } from "./item/blessure.js";
|
||||||
@@ -59,6 +61,8 @@ import { RdDSigneDraconiqueItemSheet } from "./item/sheet-signedraconique.js";
|
|||||||
import { RdDItemInventaireSheet } from "./item/sheet-base-inventaire.js";
|
import { RdDItemInventaireSheet } from "./item/sheet-base-inventaire.js";
|
||||||
import { AppAstrologie } from "./sommeil/app-astrologie.js";
|
import { AppAstrologie } from "./sommeil/app-astrologie.js";
|
||||||
import { RdDItemArmure } from "./item/armure.js";
|
import { RdDItemArmure } from "./item/armure.js";
|
||||||
|
import { AutoAdjustDarkness as AutoAdjustDarkness } from "./time/auto-adjust-darkness.js";
|
||||||
|
import { RdDCreature } from "./actor/creature.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RdD system
|
* RdD system
|
||||||
@@ -90,10 +94,10 @@ export class SystemReveDeDragon {
|
|||||||
}
|
}
|
||||||
this.actorClasses = {
|
this.actorClasses = {
|
||||||
commerce: RdDCommerce,
|
commerce: RdDCommerce,
|
||||||
creature: RdDActor,
|
creature: RdDCreature,
|
||||||
entite: RdDActor,
|
entite: RdDEntite,
|
||||||
personnage: RdDActor,
|
personnage: RdDActor,
|
||||||
vehicule: RdDActor,
|
vehicule: RdDVehicule,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +153,7 @@ export class SystemReveDeDragon {
|
|||||||
Actors.unregisterSheet("core", ActorSheet);
|
Actors.unregisterSheet("core", ActorSheet);
|
||||||
Actors.registerSheet(SYSTEM_RDD, RdDCommerceSheet, { types: ["commerce"], makeDefault: true });
|
Actors.registerSheet(SYSTEM_RDD, RdDCommerceSheet, { types: ["commerce"], makeDefault: true });
|
||||||
Actors.registerSheet(SYSTEM_RDD, RdDActorSheet, { types: ["personnage"], makeDefault: true });
|
Actors.registerSheet(SYSTEM_RDD, RdDActorSheet, { types: ["personnage"], makeDefault: true });
|
||||||
Actors.registerSheet(SYSTEM_RDD, RdDActorCreatureSheet, { types: ["creature"], makeDefault: true });
|
Actors.registerSheet(SYSTEM_RDD, RdDCreatureSheet, { types: ["creature"], makeDefault: true });
|
||||||
Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true });
|
Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true });
|
||||||
Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true });
|
Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true });
|
||||||
Items.unregisterSheet("core", ItemSheet);
|
Items.unregisterSheet("core", ItemSheet);
|
||||||
@@ -182,11 +186,12 @@ export class SystemReveDeDragon {
|
|||||||
CONFIG.Combat.documentClass = RdDCombatManager;
|
CONFIG.Combat.documentClass = RdDCombatManager;
|
||||||
|
|
||||||
// préparation des différents modules
|
// préparation des différents modules
|
||||||
|
AutoAdjustDarkness.init();
|
||||||
RdDTimestamp.init();
|
RdDTimestamp.init();
|
||||||
RdDCalendrier.init();
|
RdDCalendrier.init();
|
||||||
SystemCompendiums.init();
|
SystemCompendiums.init();
|
||||||
DialogChronologie.init();
|
DialogChronologie.init();
|
||||||
ReglesOptionelles.init();
|
ReglesOptionnelles.init();
|
||||||
RdDUtility.init();
|
RdDUtility.init();
|
||||||
RdDDice.init();
|
RdDDice.init();
|
||||||
RdDCommands.init();
|
RdDCommands.init();
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export class RdDPossession {
|
|||||||
let rollData = {
|
let rollData = {
|
||||||
mode: "attaque",
|
mode: "attaque",
|
||||||
isECNIDefender: false,
|
isECNIDefender: false,
|
||||||
competence: competence.clone(),
|
competence: competence,
|
||||||
possession: possession,
|
possession: possession,
|
||||||
attacker: attacker,
|
attacker: attacker,
|
||||||
defender: defender,
|
defender: defender,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ChatUtility } from "./chat-utility.js";
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
import { RdDDice } from "./rdd-dice.js";
|
import { RdDDice } from "./rdd-dice.js";
|
||||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* difficultés au delà de -10
|
* difficultés au delà de -10
|
||||||
@@ -28,7 +28,7 @@ const reussites = [
|
|||||||
|
|
||||||
const reussiteInsuffisante = { code: "notSign", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: false, isETotal: false, ptTache: 0, ptQualite: -2, quality: "Réussite insuffisante", condition: (target, roll) => false }
|
const reussiteInsuffisante = { code: "notSign", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: false, isETotal: false, ptTache: 0, ptQualite: -2, quality: "Réussite insuffisante", condition: (target, roll) => false }
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
const caracMaximumResolution = 60;
|
const CARAC_MAXIMUM_RESOLUTION = 40;
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RdDResolutionTable {
|
export class RdDResolutionTable {
|
||||||
static resolutionTable = this.build()
|
static resolutionTable = this.build()
|
||||||
@@ -36,7 +36,7 @@ export class RdDResolutionTable {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static build() {
|
static build() {
|
||||||
let table = []
|
let table = []
|
||||||
for (var caracValue = 0; caracValue <= caracMaximumResolution; caracValue++) {
|
for (var caracValue = 0; caracValue <= CARAC_MAXIMUM_RESOLUTION; caracValue++) {
|
||||||
table[caracValue] = this._computeRow(caracValue);
|
table[caracValue] = this._computeRow(caracValue);
|
||||||
}
|
}
|
||||||
return table;
|
return table;
|
||||||
@@ -91,13 +91,17 @@ export class RdDResolutionTable {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.html') {
|
static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.html') {
|
||||||
return await ChatUtility.createChatWithRollMode(actor?.userName ?? game.user.name, {
|
return await ChatUtility.createChatWithRollMode(RdDResolutionTable.actorChatName(actor), {
|
||||||
content: await RdDResolutionTable.buildRollDataHtml(rollData, actor, template)
|
content: await RdDResolutionTable.buildRollDataHtml(rollData, template)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static actorChatName(actor) {
|
||||||
|
return actor?.userName ?? game.user.name;
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async buildRollDataHtml(rollData, actor, template = 'chat-resultat-general.html') {
|
static async buildRollDataHtml(rollData, template = 'chat-resultat-general.html') {
|
||||||
rollData.show = rollData.show || {};
|
rollData.show = rollData.show || {};
|
||||||
return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData);
|
return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData);
|
||||||
}
|
}
|
||||||
@@ -122,7 +126,7 @@ export class RdDResolutionTable {
|
|||||||
rolled.bonus = rollData.bonus;
|
rolled.bonus = rollData.bonus;
|
||||||
rolled.factorHtml = Misc.getFractionHtml(rollData.diviseurSignificative);
|
rolled.factorHtml = Misc.getFractionHtml(rollData.diviseurSignificative);
|
||||||
|
|
||||||
if (ReglesOptionelles.isUsing("afficher-colonnes-reussite")) {
|
if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) {
|
||||||
rolled.niveauNecessaire = this.findNiveauNecessaire(caracValue, rolled.roll);
|
rolled.niveauNecessaire = this.findNiveauNecessaire(caracValue, rolled.roll);
|
||||||
rolled.ajustementNecessaire = rolled.niveauNecessaire - finalLevel;
|
rolled.ajustementNecessaire = rolled.niveauNecessaire - finalLevel;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ export class RdDRollResolutionTable extends Dialog {
|
|||||||
async updateRollResult() {
|
async updateRollResult() {
|
||||||
let rollData = this.rollData;
|
let rollData = this.rollData;
|
||||||
rollData.caracValue = parseInt(rollData.selectedCarac.value)
|
rollData.caracValue = parseInt(rollData.selectedCarac.value)
|
||||||
rollData.finalLevel = this._computeFinalLevel(rollData);
|
rollData.finalLevel = Misc.toInt(rollData.diffConditions) + Misc.toInt(rollData.diffLibre);
|
||||||
|
|
||||||
const htmlTable = await RdDResolutionTable.buildHTMLTable({
|
const htmlTable = await RdDResolutionTable.buildHTMLTable({
|
||||||
carac: rollData.caracValue,
|
carac: rollData.caracValue,
|
||||||
@@ -129,12 +129,6 @@ export class RdDRollResolutionTable extends Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_computeFinalLevel(rollData) {
|
|
||||||
const diffConditions = Misc.toInt(rollData.diffConditions);
|
|
||||||
const diffLibre = Misc.toInt(rollData.diffLibre);
|
|
||||||
|
|
||||||
return diffLibre + diffConditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
async close() {
|
async close() {
|
||||||
await super.close();
|
await super.close();
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ 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 { RdDResolutionTable } from "./rdd-resolution-table.js";
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extend the base Dialog entity to select roll parameters
|
* Extend the base Dialog entity to select roll parameters
|
||||||
@@ -22,7 +22,7 @@ export class RdDRoll extends Dialog {
|
|||||||
|
|
||||||
const html = await renderTemplate(dialogConfig.html, rollData);
|
const html = await renderTemplate(dialogConfig.html, rollData);
|
||||||
|
|
||||||
let options = { classes: ["rdd-roll-dialog"], width: 600, height: 'fit-content', 'z-index': 99999, close: html => {} };
|
let options = { classes: ["rdd-roll-dialog"], width: 650, height: 'fit-content', 'z-index': 99999, close: html => {} };
|
||||||
if (dialogConfig.close) {
|
if (dialogConfig.close) {
|
||||||
options.close = dialogConfig.close;
|
options.close = dialogConfig.close;
|
||||||
}
|
}
|
||||||
@@ -50,8 +50,6 @@ export class RdDRoll extends Dialog {
|
|||||||
encTotal: true
|
encTotal: true
|
||||||
},
|
},
|
||||||
isMalusEncombrementTotal: RdDItemCompetence.isMalusEncombrementTotal(rollData.competence),
|
isMalusEncombrementTotal: RdDItemCompetence.isMalusEncombrementTotal(rollData.competence),
|
||||||
malusArmureValue: actor.getMalusArmure(),
|
|
||||||
surencMalusValue: actor.computeMalusSurEncombrement(),
|
|
||||||
encTotal: actor.getEncTotal(),
|
encTotal: actor.getEncTotal(),
|
||||||
ajustementAstrologique: actor.ajustementAstrologique(),
|
ajustementAstrologique: actor.ajustementAstrologique(),
|
||||||
surprise: actor.getSurprise(false),
|
surprise: actor.getSurprise(false),
|
||||||
@@ -85,7 +83,7 @@ export class RdDRoll extends Dialog {
|
|||||||
if (RdDBonus.isDefenseAttaqueFinesse(rollData)) {
|
if (RdDBonus.isDefenseAttaqueFinesse(rollData)) {
|
||||||
facteurSign *= 2;
|
facteurSign *= 2;
|
||||||
}
|
}
|
||||||
if (!ReglesOptionelles.isUsing('tripleSignificative')) {
|
if (!ReglesOptionnelles.isUsing('tripleSignificative')) {
|
||||||
facteurSign = Math.min(facteurSign, 4);
|
facteurSign = Math.min(facteurSign, 4);
|
||||||
}
|
}
|
||||||
return facteurSign;
|
return facteurSign;
|
||||||
@@ -187,7 +185,7 @@ export class RdDRoll extends Dialog {
|
|||||||
console.log("RdDRollSelectDialog - Cout reve", ptreve);
|
console.log("RdDRollSelectDialog - Cout reve", ptreve);
|
||||||
this.updateRollResult(html);
|
this.updateRollResult(html);
|
||||||
});
|
});
|
||||||
this.html.find("[name='coupsNonMortels']").change((event) => {
|
this.html.find("input.check-mortalite").change((event) => {
|
||||||
this.rollData.dmg.mortalite = event.currentTarget.checked ? "non-mortel" : "mortel";
|
this.rollData.dmg.mortalite = event.currentTarget.checked ? "non-mortel" : "mortel";
|
||||||
this.updateRollResult(html);
|
this.updateRollResult(html);
|
||||||
});
|
});
|
||||||
@@ -291,36 +289,31 @@ export class RdDRoll extends Dialog {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async updateRollResult(html) {
|
async updateRollResult(html) {
|
||||||
let rollData = this.rollData;
|
const rollData = this.rollData;
|
||||||
|
|
||||||
rollData.dmg = rollData.attackerRoll?.dmg ?? RdDBonus.dmg(rollData, this.actor.getBonusDegat())
|
rollData.dmg = rollData.attackerRoll?.dmg ?? RdDBonus.dmg(rollData, this.actor.getBonusDegat())
|
||||||
rollData.caracValue = parseInt(rollData.selectedCarac.value)
|
rollData.caracValue = parseInt(rollData.selectedCarac.value)
|
||||||
rollData.mortalite = rollData.attackerRoll?.dmg.mortalite ?? rollData.dmg.mortalite ?? 'mortel';
|
rollData.dmg.mortalite = rollData.dmg.mortalite ?? 'mortel';
|
||||||
rollData.coupsNonMortels = (rollData.attackerRoll?.dmg.mortalite ?? rollData.dmg.mortalite) == 'non-mortel';
|
|
||||||
rollData.use.appelAuMoral = this.actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac);
|
rollData.use.appelAuMoral = this.actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac);
|
||||||
let dmgText = Misc.toSignedString(rollData.dmg.total);
|
|
||||||
|
|
||||||
switch (rollData.mortalite) {
|
|
||||||
case 'non-mortel': dmgText = `(${dmgText}) non-mortel`; break;
|
|
||||||
case 'empoignade': dmgText = `empoignade`; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
RollDataAjustements.calcul(rollData, this.actor);
|
RollDataAjustements.calcul(rollData, this.actor);
|
||||||
rollData.finalLevel = this._computeFinalLevel(rollData);
|
|
||||||
|
|
||||||
const resolutionTable = await RdDResolutionTable.buildHTMLTable(RdDResolutionTable.subTable(rollData.caracValue, rollData.finalLevel))
|
const resolutionTable = await RdDResolutionTable.buildHTMLTable(RdDResolutionTable.subTable(rollData.caracValue, rollData.finalLevel))
|
||||||
const adjustements = await this.buildAjustements(rollData);
|
const adjustements = await this.buildAjustements(rollData);
|
||||||
|
|
||||||
HtmlUtility.showControlWhen(this.html.find(".use-encTotal"), rollData.ajustements.encTotal.visible && RdDCarac.isAgiliteOuDerobee(rollData.selectedCarac));
|
HtmlUtility.showControlWhen(this.html.find(".use-encTotal"), rollData.ajustements.encTotal.visible && RdDCarac.isAgiliteOuDerobee(rollData.selectedCarac));
|
||||||
HtmlUtility.showControlWhen(this.html.find(".use-surenc"), rollData.ajustements.surenc.visible && RdDCarac.isActionPhysique(rollData.selectedCarac));
|
HtmlUtility.showControlWhen(this.html.find(".use-surenc"), rollData.ajustements.surenc.visible && RdDCarac.isActionPhysique(rollData.selectedCarac));
|
||||||
HtmlUtility.showControlWhen(this.html.find(".utilisation-moral"), rollData.use.appelAuMoral);
|
HtmlUtility.showControlWhen(this.html.find(".utilisation-moral"), rollData.use.appelAuMoral);
|
||||||
HtmlUtility.showControlWhen(this.html.find(".divAppelAuMoral"), rollData.use.appelAuMoral);
|
HtmlUtility.showControlWhen(this.html.find(".divAppelAuMoral"), rollData.use.appelAuMoral);
|
||||||
HtmlUtility.showControlWhen(this.html.find(".diffMoral"), rollData.ajustements.moralTotal.used);
|
// HtmlUtility.showControlWhen(this.html.find(".diffMoral"), rollData.ajustements.moral.used);
|
||||||
|
|
||||||
// Mise à jour valeurs
|
// Mise à jour valeurs
|
||||||
this.html.find(".dialog-roll-title").text(this._getTitle(rollData));
|
this.html.find(".dialog-roll-title").text(this._getTitle(rollData));
|
||||||
this.html.find("[name='coupsNonMortels']").prop('checked', rollData.mortalite == 'non-mortel');
|
this.html.find("input.check-mortalite").prop('checked', rollData.dmg.mortalite == 'non-mortel');
|
||||||
this.html.find(".dmg-arme-actor").text(dmgText);
|
this.html.find("label.dmg-arme-actor").text(rollData.dmg.mortalite == 'empoignade'? 'empoignade': Misc.toSignedString(rollData.dmg.total) );
|
||||||
|
this.html.find("label.arme-mortalite").text(rollData.dmg.mortalite);
|
||||||
|
// this.html.find("[name='dmg-arme-actor']").text(rollData.dmg.mortalite == 'empoignade'? 'empoignade': Misc.toSignedString(rollData.dmg.total) );
|
||||||
|
// this.html.find("[name='arme-mortalite']").text(rollData.dmg.mortalite);
|
||||||
this.html.find("div.placeholder-ajustements").empty().append(adjustements);
|
this.html.find("div.placeholder-ajustements").empty().append(adjustements);
|
||||||
this.html.find("div.placeholder-resolution").empty().append(resolutionTable)
|
this.html.find("div.placeholder-resolution").empty().append(resolutionTable)
|
||||||
}
|
}
|
||||||
@@ -331,30 +324,6 @@ export class RdDRoll extends Dialog {
|
|||||||
return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.html`, rollData);
|
return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.html`, rollData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
_computeFinalLevel(rollData) {
|
|
||||||
return RollDataAjustements.sum(rollData.ajustements);
|
|
||||||
}
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
_computeDiffCompetence(rollData) {
|
|
||||||
if (rollData.competence) {
|
|
||||||
return Misc.toInt(rollData.competence.system.niveau);
|
|
||||||
}
|
|
||||||
if (rollData.draconicList) {
|
|
||||||
return Misc.toInt(rollData.competence.system.niveau);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
_computeMalusArmure(rollData) {
|
|
||||||
let malusArmureValue = 0;
|
|
||||||
if (rollData.malusArmureValue && (rollData.selectedCarac.label == "Agilité" || rollData.selectedCarac.label == "Dérobée")) {
|
|
||||||
malusArmureValue = rollData.malusArmureValue;
|
|
||||||
}
|
|
||||||
return malusArmureValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_getTitle(rollData) {
|
_getTitle(rollData) {
|
||||||
const carac = rollData.selectedCarac.label;
|
const carac = rollData.selectedCarac.label;
|
||||||
@@ -362,16 +331,19 @@ export class RdDRoll extends Dialog {
|
|||||||
return carac;
|
return carac;
|
||||||
}
|
}
|
||||||
const compName = rollData.competence.name;
|
const compName = rollData.competence.name;
|
||||||
if (rollData.draconicList && rollData.selectedSort) {
|
|
||||||
return compName + " - " + rollData.selectedSort.name;
|
|
||||||
}
|
|
||||||
// If a weapon is there, add it in the title
|
|
||||||
const niveau = Misc.toSignedString(rollData.competence.system.niveau)
|
const niveau = Misc.toSignedString(rollData.competence.system.niveau)
|
||||||
if (compName == carac) {
|
if (compName == carac) {
|
||||||
// cas des créatures
|
// cas des créatures
|
||||||
return carac + " Niveau " + niveau
|
return `${carac} Niveau ${niveau}`
|
||||||
}
|
}
|
||||||
const armeTitle = (rollData.arme) ? " (" + rollData.arme.name + ") " : "";
|
if (rollData.draconicList && rollData.selectedSort) {
|
||||||
return carac + "/" + compName + armeTitle + " Niveau " + niveau
|
// cas de lancer de sort
|
||||||
|
return `${rollData.competence.name} Niveau ${niveau} ${rollData.selectedSort.name}`
|
||||||
|
}
|
||||||
|
if (rollData.arme && rollData.arme.name != compName) {
|
||||||
|
// ajouter l'arme au titre si son nom n'est pas la compétence
|
||||||
|
return `${carac} / ${compName} (${rollData.arme.name}) Niveau ${niveau}`
|
||||||
|
}
|
||||||
|
return `${carac} / ${compName} Niveau ${niveau}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { SHOW_DICE } from "./constants.js";
|
|||||||
import { RollDataAjustements } from "./rolldata-ajustements.js";
|
import { RollDataAjustements } from "./rolldata-ajustements.js";
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
import { TMRUtility } from "./tmr-utility.js";
|
import { TMRUtility } from "./tmr-utility.js";
|
||||||
import { tmrConstants } from "./tmr-constants.js";
|
|
||||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||||
import { RdDTMRRencontreDialog } from "./rdd-tmr-rencontre-dialog.js";
|
import { RdDTMRRencontreDialog } from "./rdd-tmr-rencontre-dialog.js";
|
||||||
import { ChatUtility } from "./chat-utility.js";
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
@@ -12,7 +11,7 @@ import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
|||||||
import { PixiTMR } from "./tmr/pixi-tmr.js";
|
import { PixiTMR } from "./tmr/pixi-tmr.js";
|
||||||
import { Draconique } from "./tmr/draconique.js";
|
import { Draconique } from "./tmr/draconique.js";
|
||||||
import { HtmlUtility } from "./html-utility.js";
|
import { HtmlUtility } from "./html-utility.js";
|
||||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||||
import { RdDDice } from "./rdd-dice.js";
|
import { RdDDice } from "./rdd-dice.js";
|
||||||
import { STATUSES } from "./settings/status-effects.js";
|
import { STATUSES } from "./settings/status-effects.js";
|
||||||
import { RdDRencontre } from "./item/rencontre.js";
|
import { RdDRencontre } from "./item/rencontre.js";
|
||||||
@@ -39,14 +38,16 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
title: "Terres Médianes de Rêve",
|
title: "Terres Médianes de Rêve",
|
||||||
content: html,
|
content: html,
|
||||||
buttons: {
|
buttons: {
|
||||||
closeButton: { label: "Fermer", callback: html => this.close(html) }
|
closeButton: {
|
||||||
|
label: "Fermer", callback: html => this.close()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
default: "closeButton"
|
default: "closeButton"
|
||||||
}
|
}
|
||||||
|
|
||||||
const dialogOptions = {
|
const dialogOptions = {
|
||||||
classes: ["tmrdialog"],
|
classes: ["tmrdialog"],
|
||||||
width: 920, height: 980,
|
width: 920, maxheight: 1024, height: 'fit-content',
|
||||||
'z-index': 40
|
'z-index': 40
|
||||||
}
|
}
|
||||||
super(dialogConf, dialogOptions);
|
super(dialogConf, dialogOptions);
|
||||||
@@ -55,15 +56,15 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
this.actor.tmrApp = this; // reference this app in the actor structure
|
this.actor.tmrApp = this; // reference this app in the actor structure
|
||||||
this.viewOnly = tmrData.mode == "visu"
|
this.viewOnly = tmrData.mode == "visu"
|
||||||
this.fatigueParCase = this.viewOnly || !ReglesOptionelles.isUsing("appliquer-fatigue") ? 0 : this.actor.getTMRFatigue();
|
this.fatigueParCase = this.viewOnly ? 0 : this.actor.getCoutFatigueTMR();
|
||||||
this.cumulFatigue = 0;
|
this.cumulFatigue = 0;
|
||||||
this.loadRencontres();
|
this.loadRencontres();
|
||||||
this.loadCasesSpeciales();
|
this.loadCasesSpeciales();
|
||||||
this.allTokens = [];
|
this.allTokens = [];
|
||||||
this.rencontreState = 'aucune';
|
this.rencontreState = 'aucune';
|
||||||
this.pixiApp = new PIXI.Application({ width: 720, height: 860 });
|
this.pixiApp = new PIXI.Application({ width: 720, height: 860 });
|
||||||
|
|
||||||
this.pixiTMR = new PixiTMR(this, this.pixiApp);
|
this.pixiTMR = new PixiTMR(this, this.pixiApp);
|
||||||
|
this.subdialog = undefined
|
||||||
|
|
||||||
this.callbacksOnAnimate = [];
|
this.callbacksOnAnimate = [];
|
||||||
if (!this.viewOnly) {
|
if (!this.viewOnly) {
|
||||||
@@ -74,6 +75,31 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
this.pixiTMR.load((loader, resources) => this.createPixiSprites());
|
this.pixiTMR.load((loader, resources) => this.createPixiSprites());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async forceTMRDisplay() {
|
||||||
|
this.bringToTop();
|
||||||
|
if (this.subdialog) {
|
||||||
|
this.subdialog.bringToTop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async restoreTMRAfterAction() {
|
||||||
|
this.subdialog = undefined
|
||||||
|
await this.maximize();
|
||||||
|
this.bringToTop();
|
||||||
|
}
|
||||||
|
|
||||||
|
forceTMRContinueAction() {
|
||||||
|
ui.notifications.warn('Vous devez finir votre action avant de continuer dans les TMR');
|
||||||
|
this.subdialog.bringToTop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTMRPendingAction(dialog) {
|
||||||
|
this.subdialog = dialog
|
||||||
|
if (dialog instanceof Application) {
|
||||||
|
dialog.bringToTop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
isDemiReveCache() {
|
isDemiReveCache() {
|
||||||
return !game.user.isGM && this.actor.isTMRCache();
|
return !game.user.isGM && this.actor.isTMRCache();
|
||||||
}
|
}
|
||||||
@@ -175,6 +201,9 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async moveFromKey(move) {
|
async moveFromKey(move) {
|
||||||
|
if (this.subdialog) {
|
||||||
|
return this.forceTMRContinueAction();
|
||||||
|
}
|
||||||
let oddq = TMRUtility.coordTMRToOddq(this._getActorCoord());
|
let oddq = TMRUtility.coordTMRToOddq(this._getActorCoord());
|
||||||
|
|
||||||
if (move == 'top') oddq.row -= 1;
|
if (move == 'top') oddq.row -= 1;
|
||||||
@@ -199,7 +228,9 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
this.html = html;
|
this.html = html;
|
||||||
|
|
||||||
document.getElementById("tmrrow1").insertCell(0).append(this.pixiApp.view);
|
document.getElementsByClassName("tmr-row")
|
||||||
|
.item(0)
|
||||||
|
.insertCell(0).append(this.pixiApp.view);
|
||||||
|
|
||||||
if (this.viewOnly) {
|
if (this.viewOnly) {
|
||||||
this.html.find('.lancer-sort').remove();
|
this.html.find('.lancer-sort').remove();
|
||||||
@@ -207,9 +238,13 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HtmlUtility.showControlWhen(this.html.find(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue"));
|
HtmlUtility.showControlWhen(this.html.find(".appliquerFatigue"), ReglesOptionnelles.isUsing("appliquer-fatigue"));
|
||||||
HtmlUtility.showControlWhen(this.html.find(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(this._getActorCoord()));
|
HtmlUtility.showControlWhen(this.html.find(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(this._getActorCoord()));
|
||||||
|
|
||||||
|
this.html.find('tr.tmr-row *').click((event) => {
|
||||||
|
this.subdialog?.bringToTop();
|
||||||
|
});
|
||||||
|
|
||||||
// Roll Sort
|
// Roll Sort
|
||||||
this.html.find('.lancer-sort').click((event) => {
|
this.html.find('.lancer-sort').click((event) => {
|
||||||
this.actor.rollUnSort(this._getActorCoord());
|
this.actor.rollUnSort(this._getActorCoord());
|
||||||
@@ -227,11 +262,8 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
|
|
||||||
// Gestion du cout de montée en points de rêve
|
// Gestion du cout de montée en points de rêve
|
||||||
let reveCout = ((this.tmrdata.isRapide && !EffetsDraconiques.isDeplacementAccelere(this.actor)) ? -2 : -1) - this.actor.countMonteeLaborieuse();
|
let reveCout = ((this.tmrdata.isRapide && !EffetsDraconiques.isDeplacementAccelere(this.actor)) ? -2 : -1) - this.actor.countMonteeLaborieuse();
|
||||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
|
||||||
this.cumulFatigue += this.fatigueParCase;
|
|
||||||
}
|
|
||||||
await this.actor.reveActuelIncDec(reveCout);
|
await this.actor.reveActuelIncDec(reveCout);
|
||||||
|
this.cumulFatigue += this.fatigueParCase;
|
||||||
// Le reste...
|
// Le reste...
|
||||||
this.updateValuesDisplay();
|
this.updateValuesDisplay();
|
||||||
let tmr = TMRUtility.getTMR(this._getActorCoord());
|
let tmr = TMRUtility.getTMR(this._getActorCoord());
|
||||||
@@ -263,7 +295,7 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
let refoulement = document.getElementById("tmr-refoulement-value");
|
let refoulement = document.getElementById("tmr-refoulement-value");
|
||||||
refoulement.innerHTML = this.actor.system.reve.refoulement.value;
|
refoulement.innerHTML = this.actor.system.reve.refoulement.value;
|
||||||
|
|
||||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||||
let fatigueItem = document.getElementById("tmr-fatigue-table");
|
let fatigueItem = document.getElementById("tmr-fatigue-table");
|
||||||
fatigueItem.innerHTML = "<table class='table-fatigue'>" + RdDUtility.makeHTMLfatigueMatrix(this.actor.system.sante.fatigue.value, this.actor.system.sante.endurance.max).html() + "</table>";
|
fatigueItem.innerHTML = "<table class='table-fatigue'>" + RdDUtility.makeHTMLfatigueMatrix(this.actor.system.sante.fatigue.value, this.actor.system.sante.endurance.max).html() + "</table>";
|
||||||
}
|
}
|
||||||
@@ -271,6 +303,10 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async close() {
|
async close() {
|
||||||
|
if (this.subdialog) {
|
||||||
|
return this.forceTMRContinueAction()
|
||||||
|
}
|
||||||
|
|
||||||
this.descenteTMR = true;
|
this.descenteTMR = true;
|
||||||
if (this.actor.tmrApp) {
|
if (this.actor.tmrApp) {
|
||||||
this.actor.tmrApp = undefined; // Cleanup reference
|
this.actor.tmrApp = undefined; // Cleanup reference
|
||||||
@@ -278,7 +314,8 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
await this.actor.setEffect(STATUSES.StatusDemiReve, false)
|
await this.actor.setEffect(STATUSES.StatusDemiReve, false)
|
||||||
this._tellToGM(this.actor.name + " a quitté les terres médianes");
|
this._tellToGM(this.actor.name + " a quitté les terres médianes");
|
||||||
}
|
}
|
||||||
await this.actor.santeIncDec("fatigue", this.cumulFatigue)
|
await this.actor.santeIncDec((ReglesOptionnelles.isUsing("appliquer-fatigue") ? "fatigue" : "endurance"),
|
||||||
|
this.cumulFatigue)
|
||||||
}
|
}
|
||||||
await super.close();
|
await super.close();
|
||||||
}
|
}
|
||||||
@@ -293,6 +330,7 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
switch (action) {
|
switch (action) {
|
||||||
case 'derober':
|
case 'derober':
|
||||||
await this.derober();
|
await this.derober();
|
||||||
|
this.restoreTMRAfterAction();
|
||||||
return;
|
return;
|
||||||
case 'refouler':
|
case 'refouler':
|
||||||
await this.refouler();
|
await this.refouler();
|
||||||
@@ -305,6 +343,7 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
await this.postRencontre(tmr);
|
await this.postRencontre(tmr);
|
||||||
|
this.restoreTMRAfterAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
async derober() {
|
async derober() {
|
||||||
@@ -360,18 +399,21 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
checkQuitterTMR() {
|
checkQuitterTMR() {
|
||||||
|
|
||||||
if (this.actor.isDead()) {
|
if (this.actor.isDead()) {
|
||||||
this._tellToGM("Vous êtes mort : vous quittez les Terres médianes !");
|
this._tellToGM("Vous êtes mort : vous quittez les Terres médianes !");
|
||||||
this.close();
|
this.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const resteAvantInconscience = this.actor.getFatigueMax() - this.actor.getFatigueActuelle() - this.cumulFatigue;
|
|
||||||
if (ReglesOptionelles.isUsing("appliquer-fatigue") && resteAvantInconscience <= 0) {
|
if (ReglesOptionnelles.isUsing("appliquer-fatigue")
|
||||||
|
? (this.actor.getFatigueRestante() <= this.cumulFatigue)
|
||||||
|
: (this.actor.getEnduranceActuelle() <= this.cumulFatigue)
|
||||||
|
) {
|
||||||
this._tellToGM("Vous vous écroulez de fatigue : vous quittez les Terres médianes !");
|
this._tellToGM("Vous vous écroulez de fatigue : vous quittez les Terres médianes !");
|
||||||
this.quitterLesTMRInconscient();
|
this.quitterLesTMRInconscient();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.actor.getReveActuel() == 0) {
|
if (this.actor.getReveActuel() == 0) {
|
||||||
this._tellToGM("Vos Points de Rêve sont à 0 : vous quittez les Terres médianes !");
|
this._tellToGM("Vos Points de Rêve sont à 0 : vous quittez les Terres médianes !");
|
||||||
this.quitterLesTMRInconscient();
|
this.quitterLesTMRInconscient();
|
||||||
@@ -451,7 +493,7 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// TODO: remplacer par une boucle while(this.currentRencontre) ?
|
// TODO: remplacer par une boucle while(this.currentRencontre) ?
|
||||||
rencData.nbRounds++;
|
rencData.nbRounds++;
|
||||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||||
this.cumulFatigue += this.fatigueParCase;
|
this.cumulFatigue += this.fatigueParCase;
|
||||||
}
|
}
|
||||||
this._tentativeMaitrise(rencData);
|
this._tentativeMaitrise(rencData);
|
||||||
@@ -531,8 +573,9 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
await this.maitriserRencontre();
|
await this.maitriserRencontre();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let dialog = new RdDTMRRencontreDialog(this, this.currentRencontre, tmr);
|
const dialog = new RdDTMRRencontreDialog(this.actor, this.currentRencontre, tmr);
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
|
this.setTMRPendingAction(dialog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -544,9 +587,12 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
_presentCite(tmr) {
|
_presentCite(tmr) {
|
||||||
const presentCite = this.casesSpeciales.find(c => EffetsDraconiques.presentCites.isCase(c, tmr.coord));
|
const presentCite = this.casesSpeciales.find(c => EffetsDraconiques.presentCites.isCase(c, tmr.coord));
|
||||||
if (presentCite) {
|
if (presentCite) {
|
||||||
this.minimize();
|
|
||||||
const caseData = presentCite;
|
const caseData = presentCite;
|
||||||
EffetsDraconiques.presentCites.choisirUnPresent(caseData, (present => this._utiliserPresentCite(presentCite, present, tmr)));
|
const dialog = EffetsDraconiques.presentCites.choisirUnPresent(caseData, present => {
|
||||||
|
this._utiliserPresentCite(presentCite, present, tmr)
|
||||||
|
this.restoreTMRAfterAction();
|
||||||
|
});
|
||||||
|
this.setTMRPendingAction(dialog);
|
||||||
}
|
}
|
||||||
return presentCite;
|
return presentCite;
|
||||||
}
|
}
|
||||||
@@ -572,8 +618,6 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
presentCite: presentCite
|
presentCite: presentCite
|
||||||
};
|
};
|
||||||
await this._tentativeMaitrise(rencontreData);
|
await this._tentativeMaitrise(rencontreData);
|
||||||
|
|
||||||
this.maximize();
|
|
||||||
this.postRencontre(tmr);
|
this.postRencontre(tmr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -587,7 +631,10 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
? TMRUtility.getTMRType(tmr.coord) + " ??"
|
? TMRUtility.getTMRType(tmr.coord) + " ??"
|
||||||
: tmr.label + " (" + tmr.coord + ")");
|
: tmr.label + " (" + tmr.coord + ")");
|
||||||
|
|
||||||
|
const fakeDialogRencontre = { bringToTop: () => { } };
|
||||||
|
this.setTMRPendingAction(fakeDialogRencontre)
|
||||||
let myRoll = await RdDDice.rollTotal("1dt", { showDice: SHOW_DICE });
|
let myRoll = await RdDDice.rollTotal("1dt", { showDice: SHOW_DICE });
|
||||||
|
this.restoreTMRAfterAction()
|
||||||
if (myRoll == 7) {
|
if (myRoll == 7) {
|
||||||
this._tellToUser(myRoll + ": Rencontre en " + locTMR);
|
this._tellToUser(myRoll + ": Rencontre en " + locTMR);
|
||||||
return await game.system.rdd.rencontresTMR.getRencontreAleatoire(tmr, this.actor.isMauvaiseRencontre())
|
return await game.system.rdd.rencontresTMR.getRencontreAleatoire(tmr, this.actor.isMauvaiseRencontre())
|
||||||
@@ -777,22 +824,22 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async _maitriserTMR(rollData, callbackMaitrise) {
|
async _maitriserTMR(rollData, callbackMaitrise) {
|
||||||
this.minimize(); // Hide
|
|
||||||
rollData.isTMRCache = rollData.actor.isTMRCache();
|
rollData.isTMRCache = rollData.actor.isTMRCache();
|
||||||
const dialog = await RdDRoll.create(this.actor, rollData,
|
const dialog = await RdDRoll.create(this.actor, rollData,
|
||||||
{
|
{
|
||||||
html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-maitrise-tmr.html',
|
html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-maitrise-tmr.html',
|
||||||
close: html => { this.maximize(); } // Re-display TMR
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: rollData.maitrise.verbe, label: rollData.maitrise.action,
|
name: rollData.maitrise.verbe, label: rollData.maitrise.action,
|
||||||
callbacks: [
|
callbacks: [
|
||||||
this.actor.createCallbackExperience(),
|
this.actor.createCallbackExperience(),
|
||||||
|
{ action: r => { this.restoreTMRAfterAction() } },
|
||||||
{ action: callbackMaitrise }
|
{ action: callbackMaitrise }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
|
this.setTMRPendingAction(dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -862,7 +909,8 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
nettoyerRencontre() {
|
nettoyerRencontre() {
|
||||||
if (!this.currentRencontre) return; // Sanity check
|
if (!this.currentRencontre) return; // Sanity check
|
||||||
if (this.currentRencontre.graphics) {
|
if (this.currentRencontre.graphics) {
|
||||||
for (let drawRect of this.currentRencontre.graphics) { // Suppression des dessins des zones possibles
|
for (let drawRect of this.currentRencontre.graphics) {
|
||||||
|
// Suppression des dessins des zones possibles
|
||||||
this.pixiApp.stage.removeChild(drawRect);
|
this.pixiApp.stage.removeChild(drawRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -895,8 +943,8 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
isConnaissanceFleuve(currentTMR, nextTMR) {
|
isConnaissanceFleuve(tmrApp, nextTMR) {
|
||||||
return TMRUtility.getTMR(currentTMR).type == 'fleuve' &&
|
return TMRUtility.getTMR(tmrApp).type == 'fleuve' &&
|
||||||
TMRUtility.getTMR(nextTMR).type == 'fleuve' &&
|
TMRUtility.getTMR(nextTMR).type == 'fleuve' &&
|
||||||
EffetsDraconiques.isConnaissanceFleuve(this.actor);
|
EffetsDraconiques.isConnaissanceFleuve(this.actor);
|
||||||
}
|
}
|
||||||
@@ -906,15 +954,15 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
if (this.viewOnly) {
|
if (this.viewOnly) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let clickOddq = RdDTMRDialog._computeEventOddq(event.data.originalEvent);
|
if (this.subdialog) {
|
||||||
await this._onClickTMRPos(clickOddq); // Vérifier l'état des compteurs reve/fatigue/vie
|
return this.forceTMRContinueAction()
|
||||||
}
|
}
|
||||||
|
let clickOddq = TMRUtility.computeEventOddq(event);
|
||||||
/* -------------------------------------------- */
|
|
||||||
async _onClickTMRPos(clickOddq) {
|
|
||||||
let currentOddq = TMRUtility.coordTMRToOddq(this._getActorCoord());
|
let currentOddq = TMRUtility.coordTMRToOddq(this._getActorCoord());
|
||||||
|
|
||||||
let targetCoord = TMRUtility.oddqToCoordTMR(clickOddq);
|
let targetCoord = TMRUtility.oddqToCoordTMR(clickOddq);
|
||||||
let currentCoord = TMRUtility.oddqToCoordTMR(currentOddq);
|
let currentCoord = TMRUtility.oddqToCoordTMR(currentOddq);
|
||||||
|
|
||||||
// Validation de la case de destination (gestion du cas des rencontres qui peuvent téléporter)
|
// Validation de la case de destination (gestion du cas des rencontres qui peuvent téléporter)
|
||||||
let deplacementType = this._calculDeplacement(targetCoord, currentCoord, currentOddq, clickOddq);
|
let deplacementType = this._calculDeplacement(targetCoord, currentCoord, currentOddq, clickOddq);
|
||||||
|
|
||||||
@@ -946,7 +994,7 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
await this._messagerDemiReve(targetCoord);
|
await this._messagerDemiReve(targetCoord);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ui.notifications.error("Vous ne pouvez pas vous déplacer que sur des cases adjacentes à votre position ou valides dans le cas d'une rencontre");
|
ui.notifications.error("Vous ne pouvez vous déplacer que sur des cases adjacentes à votre position ou valides dans le cas d'une rencontre");
|
||||||
console.log("STATUS :", this.rencontreState, this.currentRencontre);
|
console.log("STATUS :", this.rencontreState, this.currentRencontre);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -975,9 +1023,11 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async _messagerDemiReve(targetCoord) {
|
async _messagerDemiReve(targetCoord) {
|
||||||
/*
|
/*
|
||||||
TODO: si la case a un sort en réserve, lancer ce sort.
|
TODO:
|
||||||
|
Si la case a un sort en réserve, lancer ce sort.
|
||||||
Si la case est le demi-rêve, ne pas lancer de sort.
|
Si la case est le demi-rêve, ne pas lancer de sort.
|
||||||
Si un lancement de sort est en cours, trouver un moyen de réafficher cette fenêtre si on essaie de lancer un sort (ou bloquer le lancer de sort)
|
Si un lancement de sort est en cours, trouver un moyen de réafficher cette fenêtre
|
||||||
|
si on essaie de lancer un sort (ou bloquer le lancer de sort)
|
||||||
*/
|
*/
|
||||||
this.notifierResonanceSigneDraconique(targetCoord);
|
this.notifierResonanceSigneDraconique(targetCoord);
|
||||||
await this.actor.rollUnSort(targetCoord);
|
await this.actor.rollUnSort(targetCoord);
|
||||||
@@ -994,6 +1044,9 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async _deplacerDemiReve(targetCoord, deplacementType) {
|
async _deplacerDemiReve(targetCoord, deplacementType) {
|
||||||
|
if (this.subdialog) {
|
||||||
|
return this.forceTMRContinueAction()
|
||||||
|
}
|
||||||
if (this.currentRencontre != 'normal') {
|
if (this.currentRencontre != 'normal') {
|
||||||
this.nettoyerRencontre();
|
this.nettoyerRencontre();
|
||||||
}
|
}
|
||||||
@@ -1004,7 +1057,7 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
await this.actor.updateCoordTMR(tmr.coord);
|
await this.actor.updateCoordTMR(tmr.coord);
|
||||||
|
|
||||||
this.forceDemiRevePositionView();
|
this.forceDemiRevePositionView();
|
||||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||||
this.cumulFatigue += this.fatigueParCase;
|
this.cumulFatigue += this.fatigueParCase;
|
||||||
}
|
}
|
||||||
this.updateValuesDisplay();
|
this.updateValuesDisplay();
|
||||||
@@ -1043,25 +1096,16 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async positionnerDemiReve(coord) {
|
async positionnerDemiReve(coord) {
|
||||||
|
if (this.subdialog) {
|
||||||
|
return this.forceTMRContinueAction()
|
||||||
|
}
|
||||||
|
|
||||||
await this.actor.updateCoordTMR(coord);
|
await this.actor.updateCoordTMR(coord);
|
||||||
this.forceDemiRevePositionView();
|
this.forceDemiRevePositionView();
|
||||||
let tmr = TMRUtility.getTMR(coord);
|
let tmr = TMRUtility.getTMR(coord);
|
||||||
await this.postRencontre(tmr);
|
await this.postRencontre(tmr);
|
||||||
return tmr;
|
return tmr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static _computeEventOddq(origEvent) {
|
|
||||||
console.log("EVENT", origEvent)
|
|
||||||
let canvasRect = origEvent.target.getBoundingClientRect();
|
|
||||||
let x = origEvent.clientX - canvasRect.left;
|
|
||||||
let y = origEvent.clientY - canvasRect.top;
|
|
||||||
let col = Math.floor(x / tmrConstants.cellw); // [From 0 -> 12]
|
|
||||||
y -= col % 2 == 0 ? tmrConstants.col1_y : tmrConstants.col2_y;
|
|
||||||
let row = Math.floor(y / tmrConstants.cellh); // [From 0 -> 14]
|
|
||||||
return { col: col, row: row };
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/** Retourne les coordonnées x, h, w, h du rectangle d'une case donnée */
|
/** Retourne les coordonnées x, h, w, h du rectangle d'une case donnée */
|
||||||
_getCaseRectangleCoord(coord) {
|
_getCaseRectangleCoord(coord) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
export class RdDTMRRencontreDialog extends Dialog {
|
export class RdDTMRRencontreDialog extends Dialog {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
constructor(tmrApp, rencontre, tmr) {
|
constructor(actor, rencontre, tmr) {
|
||||||
const dialogConf = {
|
const dialogConf = {
|
||||||
title: "Rencontre en TMR!",
|
title: "Rencontre en TMR!",
|
||||||
content: "Vous rencontrez un " + rencontre.name + " de force " + rencontre.system.force + "<br>",
|
content: "Vous rencontrez un " + rencontre.name + " de force " + rencontre.system.force + "<br>",
|
||||||
@@ -28,23 +28,30 @@ export class RdDTMRRencontreDialog extends Dialog {
|
|||||||
|
|
||||||
this.toClose = false;
|
this.toClose = false;
|
||||||
this.tmr = tmr;
|
this.tmr = tmr;
|
||||||
this.tmrApp = tmrApp;
|
this.actor = actor;
|
||||||
this.rencontre = rencontre;
|
this.rencontre = rencontre;
|
||||||
this.tmrApp.minimize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async onButtonAction(action) {
|
async onButtonAction(action) {
|
||||||
this.toClose = true;
|
this.toClose = true;
|
||||||
this.tmrApp.onActionRencontre(action, this.tmr, this.rencontre)
|
await this.actor.tmrApp?.restoreTMRAfterAction();
|
||||||
|
this.actor.tmrApp?.onActionRencontre(action, this.tmr, this.rencontre)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
close() {
|
async close() {
|
||||||
if (this.toClose) {
|
if (this.actor.tmrApp){
|
||||||
this.tmrApp.maximize();
|
if (this.toClose) {
|
||||||
return super.close();
|
return await super.close();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ui.notifications.info("Vous devez résoudre la rencontre.");
|
||||||
|
return this.actor.tmrApp.forceTMRContinueAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return await super.close();
|
||||||
}
|
}
|
||||||
ui.notifications.info("Vous devez résoudre la rencontre.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Misc } from "./misc.js";
|
|||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { TMRUtility } from "./tmr-utility.js";
|
import { TMRUtility } from "./tmr-utility.js";
|
||||||
import { DialogItemAchat } from "./dialog-item-achat.js";
|
import { DialogItemAchat } from "./dialog-item-achat.js";
|
||||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||||
import { RdDDice } from "./rdd-dice.js";
|
import { RdDDice } from "./rdd-dice.js";
|
||||||
import { RdDItem } from "./item.js";
|
import { RdDItem } from "./item.js";
|
||||||
import { RdDPossession } from "./rdd-possession.js";
|
import { RdDPossession } from "./rdd-possession.js";
|
||||||
@@ -28,7 +28,7 @@ const ajustementsEncaissement = Misc.intArray(-10, 26);
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
function _buildAllSegmentsFatigue(max) {
|
function _buildAllSegmentsFatigue(max) {
|
||||||
const cycle = [5, 2, 4, 1, 3, 0];
|
const cycle = [5, 2, 4, 1, 3, 0];
|
||||||
let fatigue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]];
|
const fatigue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]];
|
||||||
for (let i = 0; i <= max; i++) {
|
for (let i = 0; i <= max; i++) {
|
||||||
const ligneFatigue = duplicate(fatigue[i]);
|
const ligneFatigue = duplicate(fatigue[i]);
|
||||||
const caseIncrementee = cycle[i % 6];
|
const caseIncrementee = cycle[i % 6];
|
||||||
@@ -55,7 +55,8 @@ function _cumulSegmentsFatigue(matrix) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
const fatigueMatrix = _buildAllSegmentsFatigue(60);
|
export const MAX_ENDURANCE_FATIGUE = 60;
|
||||||
|
const fatigueMatrix = _buildAllSegmentsFatigue(MAX_ENDURANCE_FATIGUE);
|
||||||
const cumulFatigueMatrix = _cumulSegmentsFatigue(fatigueMatrix);
|
const cumulFatigueMatrix = _cumulSegmentsFatigue(fatigueMatrix);
|
||||||
|
|
||||||
const fatigueMalus = [0, 0, 0, -1, -1, -1, -2, -3, -4, -5, -6, -7]; // Provides the malus for each segment of fatigue
|
const fatigueMalus = [0, 0, 0, -1, -1, -1, -2, -3, -4, -5, -6, -7]; // Provides the malus for each segment of fatigue
|
||||||
@@ -121,6 +122,7 @@ export class RdDUtility {
|
|||||||
'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-entitee.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-entitee.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor/header-effects.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/header-effects.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor/header-hautreve.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/header-hautreve.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/archetype.hbs',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-main.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-main.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-derivee.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-derivee.html',
|
||||||
@@ -179,24 +181,25 @@ export class RdDUtility {
|
|||||||
'systems/foundryvtt-reve-de-dragon/templates/item-queue-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item-queue-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/header-item.html',
|
'systems/foundryvtt-reve-de-dragon/templates/header-item.html',
|
||||||
// partial enums
|
// partial enums
|
||||||
'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-aspect-tarot.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/enum-base-competence.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/enum-caracteristiques.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-categories.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categories.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-ingredient.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-ingredient.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-parade.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-parade.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-potion.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-potion.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-queue.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-vehicule.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-vehicule.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-competence.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-competence.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/enum-draconic.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-heures.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-heures.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-initpremierround.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-initpremierround.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/enum-mortalite.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-niveau-ethylisme.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-niveau-ethylisme.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-rarete.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-queue.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-draconic.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-type.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-periode.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-periode.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/enum-rarete.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-effet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-effet.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-type.html',
|
||||||
// Partials
|
// Partials
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/tirage/liste-resultats-recherche.hbs',
|
'systems/foundryvtt-reve-de-dragon/templates/tirage/liste-resultats-recherche.hbs',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/time/horloge.hbs',
|
'systems/foundryvtt-reve-de-dragon/templates/time/horloge.hbs',
|
||||||
@@ -243,7 +246,8 @@ export class RdDUtility {
|
|||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-description.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-description.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-summary.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-acteur.hbs',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-sante.hbs',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html',
|
||||||
@@ -278,7 +282,7 @@ export class RdDUtility {
|
|||||||
Handlebars.registerHelper('timestamp-formulesPeriode', () => RdDTimestamp.formulesPeriode());
|
Handlebars.registerHelper('timestamp-formulesPeriode', () => RdDTimestamp.formulesPeriode());
|
||||||
|
|
||||||
Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1)));
|
Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1)));
|
||||||
Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionelles.isUsing(option));
|
Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionnelles.isUsing(option));
|
||||||
Handlebars.registerHelper('trier', list => list.sort((a, b) => a.name.localeCompare(b.name)));
|
Handlebars.registerHelper('trier', list => list.sort((a, b) => a.name.localeCompare(b.name)));
|
||||||
Handlebars.registerHelper('filtreTriCompetences', competences => RdDItemCompetence.triVisible(competences));
|
Handlebars.registerHelper('filtreTriCompetences', competences => RdDItemCompetence.triVisible(competences));
|
||||||
Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name));
|
Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name));
|
||||||
@@ -457,18 +461,15 @@ export class RdDUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getSegmentsFatigue(maxEnd) {
|
static getSegmentsFatigue(maxEndurance) {
|
||||||
maxEnd = Math.max(maxEnd, 1);
|
return fatigueMatrix[Math.min(Math.max(maxEndurance, 1), fatigueMatrix.length)];
|
||||||
maxEnd = Math.min(maxEnd, fatigueMatrix.length);
|
|
||||||
return fatigueMatrix[maxEnd];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static calculMalusFatigue(fatigue, maxEnd) {
|
static calculMalusFatigue(fatigue, endurance) {
|
||||||
maxEnd = Math.max(maxEnd, 1);
|
endurance = Math.min(Math.max(endurance, 1), cumulFatigueMatrix.length);
|
||||||
maxEnd = Math.min(maxEnd, cumulFatigueMatrix.length);
|
let segments = cumulFatigueMatrix[endurance];
|
||||||
let segments = cumulFatigueMatrix[maxEnd];
|
for (let i = 0; i < segments.length; i++) {
|
||||||
for (let i = 0; i < 12; i++) {
|
|
||||||
if (fatigue <= segments[i]) {
|
if (fatigue <= segments[i]) {
|
||||||
return fatigueMalus[i]
|
return fatigueMalus[i]
|
||||||
}
|
}
|
||||||
@@ -478,7 +479,7 @@ export class RdDUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static calculFatigueHtml(fatigue, endurance) {
|
static calculFatigueHtml(fatigue, endurance) {
|
||||||
return ReglesOptionelles.isUsing("appliquer-fatigue") ? {
|
return ReglesOptionnelles.isUsing("appliquer-fatigue") ? {
|
||||||
malus: RdDUtility.calculMalusFatigue(fatigue, endurance),
|
malus: RdDUtility.calculMalusFatigue(fatigue, endurance),
|
||||||
html: "<table class='table-fatigue'>" + RdDUtility.makeHTMLfatigueMatrix(fatigue, endurance).html() + "</table>"
|
html: "<table class='table-fatigue'>" + RdDUtility.makeHTMLfatigueMatrix(fatigue, endurance).html() + "</table>"
|
||||||
} : { malus: 0, html: '' };
|
} : { malus: 0, html: '' };
|
||||||
@@ -488,7 +489,7 @@ export class RdDUtility {
|
|||||||
// Build the nice (?) html table used to manage fatigue.
|
// Build the nice (?) html table used to manage fatigue.
|
||||||
// max should be the endurance max value
|
// max should be the endurance max value
|
||||||
static makeHTMLfatigueMatrix(fatigue, maxEndurance) {
|
static makeHTMLfatigueMatrix(fatigue, maxEndurance) {
|
||||||
let segments = this.getSegmentsFatigue(maxEndurance);
|
const segments = this.getSegmentsFatigue(maxEndurance);
|
||||||
return this.makeHTMLfatigueMatrixForSegment(fatigue, segments);
|
return this.makeHTMLfatigueMatrixForSegment(fatigue, segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,14 +555,14 @@ export class RdDUtility {
|
|||||||
let formula = "2d10";
|
let formula = "2d10";
|
||||||
|
|
||||||
// Chaque dé fait au minmum la difficulté libre
|
// Chaque dé fait au minmum la difficulté libre
|
||||||
if (ReglesOptionelles.isUsing('degat-minimum-malus-libre')) {
|
if (ReglesOptionnelles.isUsing('degat-minimum-malus-libre')) {
|
||||||
if (rollData.diffLibre < 0) {
|
if (rollData.diffLibre < 0) {
|
||||||
let valeurMin = Math.abs(rollData.diffLibre);
|
let valeurMin = Math.abs(rollData.diffLibre);
|
||||||
formula += "min" + valeurMin;
|
formula += "min" + valeurMin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Chaque dé fait au minmum la difficulté libre
|
// Chaque dé fait au minmum la difficulté libre
|
||||||
if (ReglesOptionelles.isUsing('degat-ajout-malus-libre')) {
|
if (ReglesOptionnelles.isUsing('degat-ajout-malus-libre')) {
|
||||||
if (rollData.diffLibre < 0) {
|
if (rollData.diffLibre < 0) {
|
||||||
let valeurMin = Math.abs(rollData.diffLibre);
|
let valeurMin = Math.abs(rollData.diffLibre);
|
||||||
formula += "+" + valeurMin;
|
formula += "+" + valeurMin;
|
||||||
@@ -571,7 +572,7 @@ export class RdDUtility {
|
|||||||
let roll = await RdDDice.roll(formula, options);
|
let roll = await RdDDice.roll(formula, options);
|
||||||
|
|
||||||
// 1 dé fait au minmum la difficulté libre
|
// 1 dé fait au minmum la difficulté libre
|
||||||
if (ReglesOptionelles.isUsing('degat-minimum-malus-libre-simple')) {
|
if (ReglesOptionnelles.isUsing('degat-minimum-malus-libre-simple')) {
|
||||||
if (rollData.diffLibre < 0) {
|
if (rollData.diffLibre < 0) {
|
||||||
let valeurMin = Math.abs(rollData.diffLibre);
|
let valeurMin = Math.abs(rollData.diffLibre);
|
||||||
if (roll.terms[0].results[0].result < valeurMin) {
|
if (roll.terms[0].results[0].result < valeurMin) {
|
||||||
@@ -622,25 +623,6 @@ export class RdDUtility {
|
|||||||
return perte.total;
|
return perte.total;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static currentFatigueMalus(value, max) {
|
|
||||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
|
||||||
max = Math.max(1, Math.min(max, 60));
|
|
||||||
value = Math.min(max * 2, Math.max(0, value));
|
|
||||||
|
|
||||||
let fatigueTab = fatigueMatrix[max];
|
|
||||||
let fatigueRem = value;
|
|
||||||
for (let idx = 0; idx < fatigueTab.length; idx++) {
|
|
||||||
fatigueRem -= fatigueTab[idx];
|
|
||||||
if (fatigueRem <= 0) {
|
|
||||||
return fatigueMalus[idx];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -7; // This is the max !
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async responseNombreAstral(callData) {
|
static async responseNombreAstral(callData) {
|
||||||
let actor = game.actors.get(callData.id);
|
let actor = game.actors.get(callData.id);
|
||||||
@@ -668,6 +650,7 @@ export class RdDUtility {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async chatListeners(html) {
|
static async chatListeners(html) {
|
||||||
RdDCombat.registerChatCallbacks(html);
|
RdDCombat.registerChatCallbacks(html);
|
||||||
|
RdDEmpoignade.registerChatCallbacks(html);
|
||||||
|
|
||||||
// Gestion spécifique message passeurs
|
// Gestion spécifique message passeurs
|
||||||
html.on("click", '.tmr-passeur-coord a', event => {
|
html.on("click", '.tmr-passeur-coord a', event => {
|
||||||
@@ -694,44 +677,6 @@ export class RdDUtility {
|
|||||||
RdDPossession.onDefensePossession(attackerId, defenderId, possessionId)
|
RdDPossession.onDefensePossession(attackerId, defenderId, possessionId)
|
||||||
});
|
});
|
||||||
|
|
||||||
html.on("click", '.defense-empoignade-cac', event => {
|
|
||||||
const chatMessage = ChatUtility.getChatMessage(event);
|
|
||||||
const rollData = ChatUtility.getMessageData(chatMessage, 'empoignade-roll-data');
|
|
||||||
let defenseMode = event.currentTarget.attributes['data-defense-mode'].value
|
|
||||||
RdDEmpoignade.onDefenseEmpoignade(rollData, defenseMode, "Corps à corps", "melee")
|
|
||||||
});
|
|
||||||
html.on("click", '.defense-empoignade-esquive', event => {
|
|
||||||
const chatMessage = ChatUtility.getChatMessage(event);
|
|
||||||
const rollData = ChatUtility.getMessageData(chatMessage, 'empoignade-roll-data');
|
|
||||||
let defenseMode = event.currentTarget.attributes['data-defense-mode'].value
|
|
||||||
RdDEmpoignade.onDefenseEmpoignade(rollData, defenseMode, "Esquive", "derobee")
|
|
||||||
});
|
|
||||||
html.on("click", '.empoignade-poursuivre', event => {
|
|
||||||
let attackerId = event.currentTarget.attributes['data-attackerId'].value
|
|
||||||
let defenderId = event.currentTarget.attributes['data-defenderId'].value
|
|
||||||
RdDEmpoignade.onAttaqueEmpoignadeValidee(game.actors.get(attackerId), game.actors.get(defenderId))
|
|
||||||
});
|
|
||||||
html.on("click", '.empoignade-entrainer-sol', event => {
|
|
||||||
const chatMessage = ChatUtility.getChatMessage(event);
|
|
||||||
const rollData = ChatUtility.getMessageData(chatMessage, 'empoignade-roll-data');
|
|
||||||
RdDEmpoignade.entrainerAuSol(rollData)
|
|
||||||
ChatUtility.removeChatMessageId(chatMessage.id)
|
|
||||||
});
|
|
||||||
html.on("click", '.empoignade-projeter-sol', event => {
|
|
||||||
const chatMessage = ChatUtility.getChatMessage(event);
|
|
||||||
const rollData = ChatUtility.getMessageData(chatMessage, 'empoignade-roll-data');
|
|
||||||
RdDEmpoignade.projeterAuSol(rollData)
|
|
||||||
ChatUtility.removeChatMessageId(chatMessage.id)
|
|
||||||
});
|
|
||||||
html.on("change", '.empoignade-perte-endurance', event => {
|
|
||||||
const chatMessage = ChatUtility.getChatMessage(event);
|
|
||||||
const rollData = ChatUtility.getMessageData(chatMessage, 'empoignade-roll-data');
|
|
||||||
if (event.currentTarget.value && event.currentTarget.value != "none") {
|
|
||||||
RdDEmpoignade.perteEndurance(rollData, event.currentTarget.value)
|
|
||||||
ChatUtility.removeChatMessageId(chatMessage.id)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// gestion bouton tchat Acheter
|
// gestion bouton tchat Acheter
|
||||||
html.on("click", '.button-acheter', event => {
|
html.on("click", '.button-acheter', event => {
|
||||||
const venteData = DialogItemAchat.preparerAchat(event.currentTarget);
|
const venteData = DialogItemAchat.preparerAchat(event.currentTarget);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ 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 { 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 { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tous les ajustements pouvant s'appliquer.
|
* tous les ajustements pouvant s'appliquer.
|
||||||
@@ -69,8 +69,8 @@ export const referenceAjustements = {
|
|||||||
getValue: (rollData, actor) => -actor.getEncTotal()
|
getValue: (rollData, actor) => -actor.getEncTotal()
|
||||||
},
|
},
|
||||||
surenc: {
|
surenc: {
|
||||||
isVisible: (rollData, actor) => actor.isSurenc(),
|
isVisible: (rollData, actor) => RdDCarac.isActionPhysique(rollData.selectedCarac) && actor.isSurenc(),
|
||||||
isUsed: (rollData, actor) => rollData.use?.surenc,
|
isUsed: (rollData, actor) => rollData.use?.surenc && RdDCarac.isActionPhysique(rollData.selectedCarac),
|
||||||
getLabel: (rollData, actor) => 'Sur-encombrement',
|
getLabel: (rollData, actor) => 'Sur-encombrement',
|
||||||
getValue: (rollData, actor) => actor.computeMalusSurEncombrement()
|
getValue: (rollData, actor) => actor.computeMalusSurEncombrement()
|
||||||
},
|
},
|
||||||
@@ -86,7 +86,7 @@ export const referenceAjustements = {
|
|||||||
getValue: (rollData, actor) => actor.getMoralTotal()
|
getValue: (rollData, actor) => actor.getMoralTotal()
|
||||||
},
|
},
|
||||||
astrologique: {
|
astrologique: {
|
||||||
isUsed: (rollData, actor) => ReglesOptionelles.isUsing("astrologie") && RdDBonus.isAjustementAstrologique(rollData),
|
isUsed: (rollData, actor) => ReglesOptionnelles.isUsing("astrologie") && RdDBonus.isAjustementAstrologique(rollData),
|
||||||
getLabel: (rollData, actor) => 'Astrologique',
|
getLabel: (rollData, actor) => 'Astrologique',
|
||||||
getValue: (rollData, actor) => actor.ajustementAstrologique()
|
getValue: (rollData, actor) => actor.ajustementAstrologique()
|
||||||
},
|
},
|
||||||
@@ -164,7 +164,7 @@ export class RollDataAjustements {
|
|||||||
descr: reference.getDescr && reference.getDescr(rollData, actor)
|
descr: reference.getDescr && reference.getDescr(rollData, actor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rollData.finalLevel = RollDataAjustements.sum(rollData.ajustements);
|
rollData.finalLevel = RollDataAjustements.sum(rollData.ajustements)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|||||||
@@ -1,119 +0,0 @@
|
|||||||
import { SYSTEM_RDD } from "../constants.js";
|
|
||||||
import { Misc } from "../misc.js";
|
|
||||||
|
|
||||||
const listeReglesOptionelles = [
|
|
||||||
{ group: 'Règles de combat', name: 'recul', descr: "Appliquer le recul en cas de particulière en force ou de charge" },
|
|
||||||
{ group: 'Règles de combat', name: 'resistanceArmeParade', descr: "Faire le jet de résistance des armes lors de parades pouvant les endommager" },
|
|
||||||
{ group: 'Règles de combat', name: 'deteriorationArmure', descr: "Tenir compte de la détérioration des armures" },
|
|
||||||
{ group: 'Règles de combat', name: 'defenseurDesarme', descr: "Le défenseur peut être désarmé en parant une particulière en force ou une charge avec une arme autre qu'un bouclier" },
|
|
||||||
{ group: 'Règles de combat', name: 'categorieParade', descr: "Le défenseur doit obtenir une significative en cas de parade avec des armes de catégories différentes" },
|
|
||||||
{ group: 'Règles de combat', name: 'tripleSignificative', descr: "En cas de demi-surprise, d'attaque particulière en finesse, et de catégories d'armes différentes, le défenseur doit obtenir 1/8 des chances de succès" },
|
|
||||||
{ group: 'Règles de combat', name: 'degat-minimum-malus-libre-simple', descr: "Le malus libre d'attaque remplace une des valeurs de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, si le plus petit dé est inférieur à 4, alors il devient 4.", default: false },
|
|
||||||
{ group: 'Règles de combat', name: 'degat-minimum-malus-libre', descr: "Le malus libre d'attaque remplace une valeur de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, tout résultat inférieur à 4 devient 4.", default: false },
|
|
||||||
{ group: 'Règles de combat', name: 'degat-ajout-malus-libre', descr: "Le malus libre d'attaque s'ajoute au jet d'encaissement et aux autres bonus. Exemple : la difficulté libre de l'attaquant est de -4. Le jet d'encaissement est effectué à 2d10+4, plus les bonus de situation et d'armes.", default: false },
|
|
||||||
{ group: 'Règles de combat', name: 'validation-encaissement-gr', descr: "Le Gardien des Rêves doit valider les jets d'encaissement et peut les changer.", default: false },
|
|
||||||
|
|
||||||
{ group: 'Règles générales', name: 'astrologie', descr: "Appliquer les ajustements astrologiques aux jets de chance et aux rituels"},
|
|
||||||
{ group: 'Règles générales', name: 'afficher-prix-joueurs', descr: "Afficher le prix de l'équipement des joueurs", uniquementJoueur: true},
|
|
||||||
{ group: 'Règles générales', name: 'appliquer-fatigue', descr: "Appliquer les règles de fatigue"},
|
|
||||||
{ group: 'Règles générales', name: 'afficher-colonnes-reussite', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false },
|
|
||||||
{ group: 'Règles générales', name: 'chateau-dormant-gardien', descr: "Saisie des heures de sommeil/jets de moral par le gardien des rêves", default: true },
|
|
||||||
|
|
||||||
{ group: 'Confirmations', name: 'confirmer-combat-sans-cible', descr: "Confirmer avant une attaque sans cible", scope: "client"},
|
|
||||||
{ group: 'Confirmations', name: 'confirmation-tmr', descr: "Confirmer pour monter dans les TMR", scope: "client"},
|
|
||||||
{ group: 'Confirmations', name: 'confirmation-refouler', descr: "Confirmer avant de refouler", scope: "client"},
|
|
||||||
{ group: 'Confirmations', name: 'confirmation-vider', descr: "Confirmer pour vider l'équipement", scope: "client"},
|
|
||||||
{ group: 'Confirmations', name: 'confirmation-supprimer-lien-acteur', descr: "Confirmer pour détacher un animal/suivant/véhicule", scope: "client"},
|
|
||||||
{ group: 'Confirmations', name: 'confirmation-supprimer-equipement', descr: "Confirmer la suppression des équipements", scope: "client"},
|
|
||||||
{ group: 'Confirmations', name: 'confirmation-supprimer-oeuvre', descr: "Confirmer la suppression des oeuvres", scope: "client"},
|
|
||||||
{ group: 'Confirmations', name: 'confirmation-supprimer-connaissance', descr: "Confirmer la suppression des connaissances", scope: "client"},
|
|
||||||
{ group: 'Confirmations', name: 'confirmation-supprimer-draconique', descr: "Confirmer la suppression des queues, souffles, têtes", scope: "client"},
|
|
||||||
{ group: 'Confirmations', name: 'confirmation-supprimer-effet', descr: "Confirmer la suppression des effets", scope: "client"},
|
|
||||||
{ group: 'Confirmations', name: 'confirmation-supprimer-competence', descr: "Confirmer la suppression des compétences", scope: "client"},
|
|
||||||
{ group: 'Confirmations', name: 'confirmation-supprimer-autres', descr: "Confirmer la suppression des autres types d'Objets", scope: "client"},
|
|
||||||
];
|
|
||||||
|
|
||||||
const uniquementJoueur = listeReglesOptionelles.filter(it => it.uniquementJoueur).map(it=>it.name);
|
|
||||||
|
|
||||||
export class ReglesOptionelles extends FormApplication {
|
|
||||||
static init() {
|
|
||||||
for (const regle of listeReglesOptionelles) {
|
|
||||||
const name = regle.name;
|
|
||||||
const id = ReglesOptionelles._getIdRegle(name);
|
|
||||||
game.settings.register(SYSTEM_RDD, id, { name: id, scope: regle.scope ?? "world", config: false, default: regle.default == undefined ? true : regle.default, type: Boolean });
|
|
||||||
}
|
|
||||||
|
|
||||||
game.settings.registerMenu(SYSTEM_RDD, "rdd-options-regles", {
|
|
||||||
name: "Choisir les règles optionelles",
|
|
||||||
label: "Règles optionelles",
|
|
||||||
hint: "Ouvre la fenêtre de sélection des règles optionelles",
|
|
||||||
icon: "fas fa-bars",
|
|
||||||
type: ReglesOptionelles
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(...args) {
|
|
||||||
super(...args);
|
|
||||||
}
|
|
||||||
|
|
||||||
static _getIdRegle(name) {
|
|
||||||
return `rdd-option-${name}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get defaultOptions() {
|
|
||||||
const options = super.defaultOptions;
|
|
||||||
mergeObject(options, {
|
|
||||||
id: "regles-optionelles",
|
|
||||||
template: "systems/foundryvtt-reve-de-dragon/templates/settings/regles-optionelles.html",
|
|
||||||
height: 600,
|
|
||||||
width: 450,
|
|
||||||
minimizable: false,
|
|
||||||
closeOnSubmit: true,
|
|
||||||
title: "Règles optionnelles"
|
|
||||||
});
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
getData() {
|
|
||||||
let formData = super.getData();
|
|
||||||
const regles = listeReglesOptionelles.filter(it => game.user.isGM || it.scope == "client").map(it => {
|
|
||||||
it = duplicate(it);
|
|
||||||
it.id = ReglesOptionelles._getIdRegle(it.name);
|
|
||||||
it.active = ReglesOptionelles.isSet(it.name);
|
|
||||||
return it;
|
|
||||||
});
|
|
||||||
formData.regles = regles;
|
|
||||||
formData.groups = Misc.classify(regles, it => it.group);
|
|
||||||
return formData;
|
|
||||||
}
|
|
||||||
|
|
||||||
static isUsing(name) {
|
|
||||||
if (game.user.isGM && uniquementJoueur.includes(name)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return ReglesOptionelles.isSet(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static isSet(name) {
|
|
||||||
return game.settings.get(SYSTEM_RDD, ReglesOptionelles._getIdRegle(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
static set(name, value) {
|
|
||||||
return game.settings.set(SYSTEM_RDD, ReglesOptionelles._getIdRegle(name), value ? true: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
activateListeners(html) {
|
|
||||||
html.find(".select-option").click((event) => {
|
|
||||||
if (event.currentTarget.attributes.name) {
|
|
||||||
let id = event.currentTarget.attributes.name.value;
|
|
||||||
let isChecked = event.currentTarget.checked;
|
|
||||||
game.settings.set(SYSTEM_RDD, id, isChecked);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async _updateObject(event, formData) {
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
128
module/settings/regles-optionnelles.js
Normal file
128
module/settings/regles-optionnelles.js
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
import { SYSTEM_RDD } from "../constants.js";
|
||||||
|
import { Misc } from "../misc.js";
|
||||||
|
|
||||||
|
const listeReglesOptionnelles = [
|
||||||
|
{ group: 'Règles générales', name: 'appliquer-fatigue', descr: "Appliquer les règles de fatigue"},
|
||||||
|
{ group: 'Règles générales', name: 'astrologie', descr: "Appliquer les ajustements astrologiques aux jets de chance et aux rituels"},
|
||||||
|
{ group: 'Récupération', name: 'transformation-stress', descr: "Transformer le stress durant Château Dormant"},
|
||||||
|
{ group: 'Récupération', name: 'recuperation-chance', descr: "Récupérer la chance durant Château Dormant"},
|
||||||
|
{ group: 'Récupération', name: 'recuperation-ethylisme', descr: "Récupérer l'éthylisme"},
|
||||||
|
{ group: 'Récupération', name: 'recuperation-reve', descr: "Récupérer le rêve pendant la nuit (les jets sont toujours faits pour les Rêves de Dragons)"},
|
||||||
|
{ group: 'Récupération', name: 'recuperation-moral', descr: "Le moral revient vers 0 durant Château Dormant"},
|
||||||
|
|
||||||
|
|
||||||
|
{ group: 'Règles de combat', name: 'recul', descr: "Appliquer le recul en cas de particulière en force ou de charge" },
|
||||||
|
{ group: 'Règles de combat', name: 'resistanceArmeParade', descr: "Faire le jet de résistance des armes lors de parades pouvant les endommager" },
|
||||||
|
{ group: 'Règles de combat', name: 'deteriorationArmure', descr: "Tenir compte de la détérioration des armures" },
|
||||||
|
{ group: 'Règles de combat', name: 'defenseurDesarme', descr: "Le défenseur peut être désarmé en parant une particulière en force ou une charge avec une arme autre qu'un bouclier" },
|
||||||
|
{ group: 'Règles de combat', name: 'categorieParade', descr: "Le défenseur doit obtenir une significative en cas de parade avec des armes de catégories différentes" },
|
||||||
|
{ group: 'Règles de combat', name: 'tripleSignificative', descr: "En cas de demi-surprise, d'attaque particulière en finesse, et de catégories d'armes différentes, le défenseur doit obtenir 1/8 des chances de succès" },
|
||||||
|
{ group: 'Règles de combat', name: 'validation-encaissement-gr', descr: "Le Gardien des Rêves doit valider les jets d'encaissement et peut les changer.", default: false },
|
||||||
|
|
||||||
|
{ group: 'Automatisation', name: 'chateau-dormant-gardien', descr: "Saisie des heures de sommeil/jets de moral par le gardien des rêves", default: true },
|
||||||
|
|
||||||
|
{ group: 'Affichage', name: 'afficher-colonnes-reussite', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false },
|
||||||
|
{ group: 'Affichage', name: 'afficher-prix-joueurs', descr: "Afficher le prix de l'équipement des joueurs", uniquementJoueur: true},
|
||||||
|
|
||||||
|
{ group: 'Confirmations', name: 'confirmer-combat-sans-cible', descr: "Confirmer avant une attaque sans cible", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-tmr', descr: "Confirmer pour monter dans les TMR", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-refouler', descr: "Confirmer avant de refouler", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-vider', descr: "Confirmer pour vider l'équipement", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-lien-acteur', descr: "Confirmer pour détacher un animal/suivant/véhicule", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-equipement', descr: "Confirmer la suppression des équipements", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-oeuvre', descr: "Confirmer la suppression des oeuvres", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-connaissance', descr: "Confirmer la suppression des connaissances", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-draconique', descr: "Confirmer la suppression des queues, souffles, têtes", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-effet', descr: "Confirmer la suppression des effets", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-competence', descr: "Confirmer la suppression des compétences", scope: "client"},
|
||||||
|
{ group: 'Confirmations', name: 'confirmation-supprimer-autres', descr: "Confirmer la suppression des autres types d'Objets", scope: "client"},
|
||||||
|
|
||||||
|
{ group: 'Options alternatives', name: 'degat-minimum-malus-libre-simple', descr: "Le malus libre d'attaque remplace une des valeurs de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, si le plus petit dé est inférieur à 4, alors il devient 4.", default: false },
|
||||||
|
{ group: 'Options alternatives', name: 'degat-minimum-malus-libre', descr: "Le malus libre d'attaque remplace une valeur de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, tout résultat inférieur à 4 devient 4.", default: false },
|
||||||
|
{ group: 'Options alternatives', name: 'degat-ajout-malus-libre', descr: "Le malus libre d'attaque s'ajoute au jet d'encaissement et aux autres bonus. Exemple : la difficulté libre de l'attaquant est de -4. Le jet d'encaissement est effectué à 2d10+4, plus les bonus de situation et d'armes.", default: false },
|
||||||
|
];
|
||||||
|
|
||||||
|
const uniquementJoueur = listeReglesOptionnelles.filter(it => it.uniquementJoueur).map(it=>it.name);
|
||||||
|
|
||||||
|
export class ReglesOptionnelles extends FormApplication {
|
||||||
|
static init() {
|
||||||
|
for (const regle of listeReglesOptionnelles) {
|
||||||
|
const name = regle.name;
|
||||||
|
const id = ReglesOptionnelles._getIdRegle(name);
|
||||||
|
game.settings.register(SYSTEM_RDD, id, { name: id, scope: regle.scope ?? "world", config: false, default: regle.default == undefined ? true : regle.default, type: Boolean });
|
||||||
|
}
|
||||||
|
|
||||||
|
game.settings.registerMenu(SYSTEM_RDD, "rdd-options-regles", {
|
||||||
|
name: "Choisir les règles optionnelles",
|
||||||
|
label: "Règles optionnelles",
|
||||||
|
hint: "Ouvre la fenêtre de sélection des règles optionnelles",
|
||||||
|
icon: "fas fa-bars",
|
||||||
|
type: ReglesOptionnelles
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(...args) {
|
||||||
|
super(...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static _getIdRegle(name) {
|
||||||
|
return `rdd-option-${name}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get defaultOptions() {
|
||||||
|
const options = super.defaultOptions;
|
||||||
|
mergeObject(options, {
|
||||||
|
id: "regles-optionnelles",
|
||||||
|
template: "systems/foundryvtt-reve-de-dragon/templates/settings/regles-optionnelles.html",
|
||||||
|
height: 600,
|
||||||
|
width: 450,
|
||||||
|
minimizable: false,
|
||||||
|
closeOnSubmit: true,
|
||||||
|
title: "Règles optionnelles"
|
||||||
|
});
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
getData() {
|
||||||
|
let formData = super.getData();
|
||||||
|
const regles = listeReglesOptionnelles.filter(it => game.user.isGM || it.scope == "client").map(it => {
|
||||||
|
it = duplicate(it);
|
||||||
|
it.id = ReglesOptionnelles._getIdRegle(it.name);
|
||||||
|
it.active = ReglesOptionnelles.isSet(it.name);
|
||||||
|
return it;
|
||||||
|
});
|
||||||
|
formData.regles = regles;
|
||||||
|
formData.groups = Misc.classify(regles, it => it.group);
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
static isUsing(name) {
|
||||||
|
if (game.user.isGM && uniquementJoueur.includes(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return ReglesOptionnelles.isSet(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static isSet(name) {
|
||||||
|
return game.settings.get(SYSTEM_RDD, ReglesOptionnelles._getIdRegle(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
static set(name, value) {
|
||||||
|
return game.settings.set(SYSTEM_RDD, ReglesOptionnelles._getIdRegle(name), value ? true: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
html.find(".select-option").click((event) => {
|
||||||
|
if (event.currentTarget.attributes.name) {
|
||||||
|
let id = event.currentTarget.attributes.name.value;
|
||||||
|
let isChecked = event.currentTarget.checked;
|
||||||
|
game.settings.set(SYSTEM_RDD, id, isChecked);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async _updateObject(event, formData) {
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -47,6 +47,7 @@ export class SystemCompendiums extends FormApplication {
|
|||||||
label: "Compendiums système",
|
label: "Compendiums système",
|
||||||
hint: "Ouvre la fenêtre de sélection des compendiums système",
|
hint: "Ouvre la fenêtre de sélection des compendiums système",
|
||||||
icon: "fas fa-bars",
|
icon: "fas fa-bars",
|
||||||
|
restricted: true,
|
||||||
type: SystemCompendiums
|
type: SystemCompendiums
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ export class AppAstrologie extends Application {
|
|||||||
this.selectHeureNaissance(event.currentTarget.attributes['data-heure-naissance'].value);
|
this.selectHeureNaissance(event.currentTarget.attributes['data-heure-naissance'].value);
|
||||||
})
|
})
|
||||||
this.html.find('[name="jet-astrologie"]').click(event => this.requestJetAstrologie());
|
this.html.find('[name="jet-astrologie"]').click(event => this.requestJetAstrologie());
|
||||||
this.html.find('[name="rebuild-nombres-astraux"]').click(event => this.rebuildNombresAstraux());
|
this.html.find('[name="rebuild-nombres-astraux"]').click(event => this.onRebuild());
|
||||||
|
|
||||||
this.onCalculThemeAstral();
|
this.onCalculThemeAstral();
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ export class AppAstrologie extends Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async rebuildNombresAstraux() {
|
async onRebuild() {
|
||||||
game.system.rdd.calendrier.resetNombresAstraux();
|
game.system.rdd.calendrier.resetNombresAstraux();
|
||||||
|
|
||||||
await game.system.rdd.calendrier.rebuildNombresAstraux();
|
await game.system.rdd.calendrier.rebuildNombresAstraux();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ReglesOptionelles } from "../settings/regles-optionelles.js";
|
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
|
||||||
import { EffetsDraconiques } from "../tmr/effets-draconiques.js";
|
import { EffetsDraconiques } from "../tmr/effets-draconiques.js";
|
||||||
|
|
||||||
export class DialogRepos extends Dialog {
|
export class DialogRepos extends Dialog {
|
||||||
@@ -7,7 +7,7 @@ export class DialogRepos extends Dialog {
|
|||||||
if (!actor.isPersonnage()) {
|
if (!actor.isPersonnage()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!ReglesOptionelles.isUsing("chateau-dormant-gardien") || !actor.hasPlayerOwner) {
|
if (!ReglesOptionnelles.isUsing("chateau-dormant-gardien") || !actor.hasPlayerOwner) {
|
||||||
actor.system.sommeil = {
|
actor.system.sommeil = {
|
||||||
"nouveaujour": true,
|
"nouveaujour": true,
|
||||||
"insomnie": EffetsDraconiques.isSujetInsomnie(actor),
|
"insomnie": EffetsDraconiques.isSujetInsomnie(actor),
|
||||||
|
|||||||
34
module/time/auto-adjust-darkness.js
Normal file
34
module/time/auto-adjust-darkness.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { SYSTEM_RDD } from "../constants.js";
|
||||||
|
|
||||||
|
export const AUTO_ADJUST_DARKNESS = "auto-adjust-darkness";
|
||||||
|
|
||||||
|
export class AutoAdjustDarkness {
|
||||||
|
|
||||||
|
static init() {
|
||||||
|
game.settings.register(SYSTEM_RDD, AUTO_ADJUST_DARKNESS, {
|
||||||
|
name: AUTO_ADJUST_DARKNESS,
|
||||||
|
scope: "world",
|
||||||
|
config: false,
|
||||||
|
default: true,
|
||||||
|
type: Boolean
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async adjust(darkness) {
|
||||||
|
if (AutoAdjustDarkness.isAuto()) {
|
||||||
|
const scene = game.scenes.viewed;
|
||||||
|
if (scene.globalLight && scene.tokenVision) {
|
||||||
|
await scene.update({ darkness });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static isAuto() {
|
||||||
|
return game.settings.get(SYSTEM_RDD, AUTO_ADJUST_DARKNESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async toggle() {
|
||||||
|
const previous = AutoAdjustDarkness.isAuto();
|
||||||
|
await game.settings.set(SYSTEM_RDD, AUTO_ADJUST_DARKNESS, !previous)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,10 +5,11 @@ import { RdDUtility } from "../rdd-utility.js";
|
|||||||
import { RdDDice } from "../rdd-dice.js";
|
import { RdDDice } from "../rdd-dice.js";
|
||||||
import { Misc } from "../misc.js";
|
import { Misc } from "../misc.js";
|
||||||
import { DialogChronologie } from "../dialog-chronologie.js";
|
import { DialogChronologie } from "../dialog-chronologie.js";
|
||||||
import { HIDE_DICE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "../constants.js";
|
import { HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "../constants.js";
|
||||||
import { ReglesOptionelles } from "../settings/regles-optionelles.js";
|
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
|
||||||
import { DialogChateauDormant } from "../sommeil/dialog-chateau-dormant.js";
|
import { DialogChateauDormant } from "../sommeil/dialog-chateau-dormant.js";
|
||||||
import { APP_ASTROLOGIE_REFRESH, AppAstrologie } from "../sommeil/app-astrologie.js";
|
import { APP_ASTROLOGIE_REFRESH, AppAstrologie } from "../sommeil/app-astrologie.js";
|
||||||
|
import { AutoAdjustDarkness } from "./auto-adjust-darkness.js";
|
||||||
|
|
||||||
const TEMPLATE_CALENDRIER = "systems/foundryvtt-reve-de-dragon/templates/time/calendar.hbs";
|
const TEMPLATE_CALENDRIER = "systems/foundryvtt-reve-de-dragon/templates/time/calendar.hbs";
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ export class RdDCalendrier extends Application {
|
|||||||
if (Misc.isUniqueConnectedGM()) { // Uniquement si GM
|
if (Misc.isUniqueConnectedGM()) { // Uniquement si GM
|
||||||
RdDTimestamp.setWorldTime(this.timestamp);
|
RdDTimestamp.setWorldTime(this.timestamp);
|
||||||
this.nombresAstraux = this.getNombresAstraux();
|
this.nombresAstraux = this.getNombresAstraux();
|
||||||
this.rebuildNombresAstraux(HIDE_DICE); // Ensure always up-to-date
|
this.rebuildNombresAstraux(); // Ensure always up-to-date
|
||||||
}
|
}
|
||||||
Hooks.on('updateSetting', async (setting, update, options, id) => this.onUpdateSetting(setting, update, options, id));
|
Hooks.on('updateSetting', async (setting, update, options, id) => this.onUpdateSetting(setting, update, options, id));
|
||||||
}
|
}
|
||||||
@@ -84,33 +85,22 @@ export class RdDCalendrier extends Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
display() {
|
display() {
|
||||||
|
AutoAdjustDarkness.adjust(RdDTimestamp.getWorldTime().darkness);
|
||||||
const pos = this.getSavePosition()
|
const pos = this.getSavePosition()
|
||||||
this.render(true, { left: pos.left, top: pos.top });
|
this.render(true, { left: pos.left, top: pos.top });
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
_getHeaderButtons() {
|
_getHeaderButtons() {
|
||||||
const buttons = [];
|
|
||||||
if (game.user.isGM) {
|
if (game.user.isGM) {
|
||||||
buttons.unshift({
|
return [
|
||||||
class: "calendar-astrologie",
|
{ class: "calendar-astrologie", icon: "fa-solid fa-moon-over-sun", onclick: ev => this.showAstrologieEditor() },
|
||||||
icon: "fa-solid fa-moon-over-sun",
|
{ class: "calendar-set-datetime", icon: "fa-solid fa-calendar-pen", onclick: ev => this.showCalendarEditor() },
|
||||||
onclick: ev => this.showAstrologieEditor()
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
class: "calendar-set-datetime",
|
|
||||||
icon: "fa-solid fa-calendar-pen",
|
|
||||||
onclick: ev => this.showCalendarEditor()
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return buttons
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
/*async maximize() {
|
|
||||||
await super.maximize()
|
|
||||||
this.render(true)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
async close() { }
|
async close() { }
|
||||||
|
|
||||||
async onUpdateSetting(setting, update, options, id) {
|
async onUpdateSetting(setting, update, options, id) {
|
||||||
@@ -134,6 +124,7 @@ export class RdDCalendrier extends Application {
|
|||||||
formData.isGM = game.user.isGM;
|
formData.isGM = game.user.isGM;
|
||||||
formData.heures = RdDTimestamp.definitions()
|
formData.heures = RdDTimestamp.definitions()
|
||||||
formData.horlogeAnalogique = this.horlogeAnalogique;
|
formData.horlogeAnalogique = this.horlogeAnalogique;
|
||||||
|
formData.autoDarkness = AutoAdjustDarkness.isAuto()
|
||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +135,7 @@ export class RdDCalendrier extends Application {
|
|||||||
this.html = html;
|
this.html = html;
|
||||||
this.html.find('.ajout-chronologie').click(ev => DialogChronologie.create());
|
this.html.find('.ajout-chronologie').click(ev => DialogChronologie.create());
|
||||||
this.html.find('.toggle-horloge-analogique').click(ev => this.onToggleHorlogeAnalogique())
|
this.html.find('.toggle-horloge-analogique').click(ev => this.onToggleHorlogeAnalogique())
|
||||||
|
this.html.find('.toggle-auto-darkness').click(ev => this.onToggleAutoDarkness())
|
||||||
this.html.find('.calendar-btn').click(ev => this.onCalendarButton(ev));
|
this.html.find('.calendar-btn').click(ev => this.onCalendarButton(ev));
|
||||||
this.html.find('.horloge-roue .horloge-heure').click(event => {
|
this.html.find('.horloge-roue .horloge-heure').click(event => {
|
||||||
const h = this.html.find(event.currentTarget)?.data('heure');
|
const h = this.html.find(event.currentTarget)?.data('heure');
|
||||||
@@ -229,15 +221,8 @@ export class RdDCalendrier extends Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async ajouterNombreAstral(indexDate, showDice = SHOW_DICE) {
|
async ajouterNombreAstral(indexDate) {
|
||||||
const nombreAstral = await RdDDice.rollTotal("1dh", { showDice: showDice, rollMode: "selfroll" });
|
const nombreAstral = await RdDDice.rollTotal("1dh", { showDice: HIDE_DICE, rollMode: "selfroll" });
|
||||||
const dateFuture = RdDTimestamp.formatIndexDate(indexDate);
|
|
||||||
if (showDice != HIDE_DICE) {
|
|
||||||
ChatMessage.create({
|
|
||||||
whisper: ChatMessage.getWhisperRecipients("GM"),
|
|
||||||
content: `Le chiffre astrologique du ${dateFuture} sera le ${nombreAstral}`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
nombreAstral: nombreAstral,
|
nombreAstral: nombreAstral,
|
||||||
valeursFausses: [],
|
valeursFausses: [],
|
||||||
@@ -272,9 +257,8 @@ export class RdDCalendrier extends Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async rebuildNombresAstraux(showDice = HIDE_DICE) {
|
async rebuildNombresAstraux() {
|
||||||
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;
|
||||||
@@ -282,7 +266,7 @@ export class RdDCalendrier extends Application {
|
|||||||
if (na) {
|
if (na) {
|
||||||
newList[i] = na;
|
newList[i] = na;
|
||||||
} else {
|
} else {
|
||||||
newList[i] = await this.ajouterNombreAstral(dayIndex, showDice);
|
newList[i] = await this.ajouterNombreAstral(dayIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.nombresAstraux = newList;
|
this.nombresAstraux = newList;
|
||||||
@@ -305,7 +289,7 @@ export class RdDCalendrier extends Application {
|
|||||||
const oldTimestamp = this.timestamp;
|
const oldTimestamp = this.timestamp;
|
||||||
await Promise.all(game.actors.map(async actor => await actor.onTimeChanging(oldTimestamp, newTimestamp)));
|
await Promise.all(game.actors.map(async actor => await actor.onTimeChanging(oldTimestamp, newTimestamp)));
|
||||||
RdDTimestamp.setWorldTime(newTimestamp);
|
RdDTimestamp.setWorldTime(newTimestamp);
|
||||||
if (oldTimestamp.indexDate + 1 == newTimestamp.indexDate && ReglesOptionelles.isUsing("chateau-dormant-gardien")) {
|
if (oldTimestamp.indexDate + 1 == newTimestamp.indexDate && ReglesOptionnelles.isUsing("chateau-dormant-gardien")) {
|
||||||
await DialogChateauDormant.create();
|
await DialogChateauDormant.create();
|
||||||
}
|
}
|
||||||
this.timestamp = newTimestamp;
|
this.timestamp = newTimestamp;
|
||||||
@@ -380,7 +364,7 @@ export class RdDCalendrier extends Application {
|
|||||||
if (request.rolled.isSuccess) {
|
if (request.rolled.isSuccess) {
|
||||||
if (request.rolled.isPart) {
|
if (request.rolled.isPart) {
|
||||||
// Gestion expérience (si existante)
|
// Gestion expérience (si existante)
|
||||||
request.competence = actor.getCompetence("astrologie")
|
request.competence = actor.getCompetence('Astrologie')
|
||||||
request.selectedCarac = actor.system.carac["vue"];
|
request.selectedCarac = actor.system.carac["vue"];
|
||||||
actor.appliquerAjoutExperience(request, 'hide');
|
actor.appliquerAjoutExperience(request, 'hide');
|
||||||
}
|
}
|
||||||
@@ -452,4 +436,9 @@ export class RdDCalendrier extends Application {
|
|||||||
async showAstrologieEditor() {
|
async showAstrologieEditor() {
|
||||||
await AppAstrologie.create();
|
await AppAstrologie.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async onToggleAutoDarkness() {
|
||||||
|
await AutoAdjustDarkness.toggle()
|
||||||
|
this.display()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { SHOW_DICE, SYSTEM_RDD } from "../constants.js";
|
|||||||
import { Grammar } from "../grammar.js";
|
import { Grammar } from "../grammar.js";
|
||||||
import { Misc } from "../misc.js";
|
import { Misc } from "../misc.js";
|
||||||
import { RdDDice } from "../rdd-dice.js";
|
import { RdDDice } from "../rdd-dice.js";
|
||||||
|
import { AutoAdjustDarkness } from "./auto-adjust-darkness.js";
|
||||||
|
|
||||||
export const WORLD_TIMESTAMP_SETTING = "calendrier";
|
export const WORLD_TIMESTAMP_SETTING = "calendrier";
|
||||||
|
|
||||||
@@ -15,18 +16,18 @@ export const RDD_MINUTES_PAR_JOUR = 1440; //RDD_HEURES_PAR_JOUR * RDD_MINUTES_PA
|
|||||||
const ROUNDS_PAR_MINUTE = 10;
|
const ROUNDS_PAR_MINUTE = 10;
|
||||||
|
|
||||||
const DEFINITION_HEURES = [
|
const DEFINITION_HEURES = [
|
||||||
{ key: "vaisseau", label: "Vaisseau", lettreFont: 'v', saison: "Printemps" },
|
{ key: "vaisseau", label: "Vaisseau", lettreFont: 'v', saison: "Printemps" , darkness: 0.7},
|
||||||
{ key: "sirene", label: "Sirène", lettreFont: 'i', saison: "Printemps" },
|
{ key: "sirene", label: "Sirène", lettreFont: 'i', saison: "Printemps" , darkness: 0.4},
|
||||||
{ key: "faucon", label: "Faucon", lettreFont: 'f', saison: "Printemps" },
|
{ key: "faucon", label: "Faucon", lettreFont: 'f', saison: "Printemps" , darkness: 0},
|
||||||
{ key: "couronne", label: "Couronne", lettreFont: '', saison: "Eté" },
|
{ key: "couronne", label: "Couronne", lettreFont: '', saison: "Eté" , darkness: 0},
|
||||||
{ key: "dragon", label: "Dragon", lettreFont: 'd', saison: "Eté" },
|
{ key: "dragon", label: "Dragon", lettreFont: 'd', saison: "Eté", darkness: 0 },
|
||||||
{ key: "epees", label: "Epées", lettreFont: 'e', saison: "Eté" },
|
{ key: "epees", label: "Epées", lettreFont: 'e', saison: "Eté", darkness: 0},
|
||||||
{ key: "lyre", label: "Lyre", lettreFont: 'l', saison: "Automne" },
|
{ key: "lyre", label: "Lyre", lettreFont: 'l', saison: "Automne", darkness: 0.4 },
|
||||||
{ key: "serpent", label: "Serpent", lettreFont: 's', saison: "Automne" },
|
{ key: "serpent", label: "Serpent", lettreFont: 's', saison: "Automne", darkness: 0.7 },
|
||||||
{ key: "poissonacrobate", label: "Poisson Acrobate", lettreFont: 'p', saison: "Automne" },
|
{ key: "poissonacrobate", label: "Poisson Acrobate", lettreFont: 'p', saison: "Automne", darkness: 1 },
|
||||||
{ key: "araignee", label: "Araignée", lettreFont: 'a', saison: "Hiver" },
|
{ key: "araignee", label: "Araignée", lettreFont: 'a', saison: "Hiver", darkness: 1 },
|
||||||
{ key: "roseau", label: "Roseau", lettreFont: 'r', saison: "Hiver" },
|
{ key: "roseau", label: "Roseau", lettreFont: 'r', saison: "Hiver", darkness: 1 },
|
||||||
{ key: "chateaudormant", label: "Château Dormant", lettreFont: 'c', saison: "Hiver" },
|
{ key: "chateaudormant", label: "Château Dormant", lettreFont: 'c', saison: "Hiver", darkness: 1 },
|
||||||
]
|
]
|
||||||
|
|
||||||
const FORMULES_DUREE = [
|
const FORMULES_DUREE = [
|
||||||
@@ -58,6 +59,7 @@ export class RdDTimestamp {
|
|||||||
type: Object
|
type: Object
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
for (let i = 0; i < DEFINITION_HEURES.length; i++) {
|
for (let i = 0; i < DEFINITION_HEURES.length; i++) {
|
||||||
DEFINITION_HEURES[i].heure = i;
|
DEFINITION_HEURES[i].heure = i;
|
||||||
DEFINITION_HEURES[i].hh = RdDTimestamp.hh(i);
|
DEFINITION_HEURES[i].hh = RdDTimestamp.hh(i);
|
||||||
@@ -66,7 +68,6 @@ export class RdDTimestamp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static hh(heure) {
|
static hh(heure) {
|
||||||
return heure < 9 ? `0${heure + 1}` : `${heure + 1}`;
|
return heure < 9 ? `0${heure + 1}` : `${heure + 1}`;
|
||||||
}
|
}
|
||||||
@@ -156,7 +157,9 @@ export class RdDTimestamp {
|
|||||||
fields.minute.change(async (event) => await onChangeTimestamp(fields, path));
|
fields.minute.change(async (event) => await onChangeTimestamp(fields, path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static defHeure(heure) {
|
||||||
|
return DEFINITION_HEURES.find(it => (it.heure) == heure % RDD_HEURES_PAR_JOUR);
|
||||||
|
}
|
||||||
static findHeure(heure) {
|
static findHeure(heure) {
|
||||||
heure = Grammar.toLowerCaseNoAccentNoSpace(heure);
|
heure = Grammar.toLowerCaseNoAccentNoSpace(heure);
|
||||||
let parHeureOuLabel = DEFINITION_HEURES.filter(it => (it.heure) == parseInt(heure) % RDD_HEURES_PAR_JOUR || Grammar.toLowerCaseNoAccentNoSpace(it.label) == heure);
|
let parHeureOuLabel = DEFINITION_HEURES.filter(it => (it.heure) == parseInt(heure) % RDD_HEURES_PAR_JOUR || Grammar.toLowerCaseNoAccentNoSpace(it.label) == heure);
|
||||||
@@ -237,6 +240,13 @@ export class RdDTimestamp {
|
|||||||
get angleHeure() { return this.indexMinute / RDD_MINUTES_PAR_JOUR * 360 - 45 }
|
get angleHeure() { return this.indexMinute / RDD_MINUTES_PAR_JOUR * 360 - 45 }
|
||||||
get angleMinute() { return this.indexMinute / RDD_MINUTES_PAR_HEURES * 360 + 45 }
|
get angleMinute() { return this.indexMinute / RDD_MINUTES_PAR_HEURES * 360 + 45 }
|
||||||
|
|
||||||
|
get darkness() {
|
||||||
|
const darknessDebut = RdDTimestamp.definition(this.heure).darkness *100
|
||||||
|
const darknessFin = RdDTimestamp.definition(this.heure + 1).darkness *100
|
||||||
|
const darknessMinute = Math.round((darknessFin - darknessDebut) * this.minute / RDD_MINUTES_PAR_HEURES);
|
||||||
|
return (darknessDebut + darknessMinute)/100
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convertit le timestamp en une structure avec les informations utiles
|
* Convertit le timestamp en une structure avec les informations utiles
|
||||||
* pour afficher la date et l'heure
|
* pour afficher la date et l'heure
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { RdDDice } from "./rdd-dice.js";
|
import { RdDDice } from "./rdd-dice.js";
|
||||||
|
import { tmrConstants } from "./tmr-constants.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
const TMRMapping = {
|
const TMRMapping = {
|
||||||
@@ -163,7 +164,7 @@ const TMRMapping = {
|
|||||||
C12: { type: "lac", label: "Lac de Fricassa" },
|
C12: { type: "lac", label: "Lac de Fricassa" },
|
||||||
D12: { type: "collines", label: "Collines d’Huaï" },
|
D12: { type: "collines", label: "Collines d’Huaï" },
|
||||||
E12: { type: "monts", label: "Monts Ajourés" },
|
E12: { type: "monts", label: "Monts Ajourés" },
|
||||||
F12: { type: "necropole", label: "Nécropole de Troat" },
|
F12: { type: "necropole", label: "Nécropole de Throat" },
|
||||||
G12: { type: "plaines", label: "Plaines de Lufmil" },
|
G12: { type: "plaines", label: "Plaines de Lufmil" },
|
||||||
H12: { type: "collines", label: "Collines de Tooth" },
|
H12: { type: "collines", label: "Collines de Tooth" },
|
||||||
I12: { type: "gouffre", label: "Gouffre Abimeux" },
|
I12: { type: "gouffre", label: "Gouffre Abimeux" },
|
||||||
@@ -199,7 +200,7 @@ const TMRMapping = {
|
|||||||
K14: { type: "necropole", label: "Nécropole d’Antinéar" },
|
K14: { type: "necropole", label: "Nécropole d’Antinéar" },
|
||||||
L14: { type: "plaines", label: "Plaines de Jislith" },
|
L14: { type: "plaines", label: "Plaines de Jislith" },
|
||||||
M14: { type: "desolation", label: "Désolation d’Après" },
|
M14: { type: "desolation", label: "Désolation d’Après" },
|
||||||
|
|
||||||
A15: { type: "cite", label: "Cité de Mielh" },
|
A15: { type: "cite", label: "Cité de Mielh" },
|
||||||
C15: { type: "plaines", label: "Plaines de Toué" },
|
C15: { type: "plaines", label: "Plaines de Toué" },
|
||||||
E15: { type: "foret", label: "Forêt des Furies" },
|
E15: { type: "foret", label: "Forêt des Furies" },
|
||||||
@@ -274,11 +275,11 @@ export class TMRUtility {
|
|||||||
const tmr = TMRUtility.getTMR(coord);
|
const tmr = TMRUtility.getTMR(coord);
|
||||||
return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label;
|
return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label;
|
||||||
}
|
}
|
||||||
|
|
||||||
static findTMRLike(type, options = {inclusMauvaise:true}) {
|
static findTMRLike(type, options = { inclusMauvaise: true }) {
|
||||||
const choix = [...Object.values(TMRType)]
|
const choix = [...Object.values(TMRType)]
|
||||||
if (options.inclusMauvaise){
|
if (options.inclusMauvaise) {
|
||||||
choix.push({name: 'Mauvaise'});
|
choix.push({ name: 'Mauvaise' });
|
||||||
}
|
}
|
||||||
const selection = Misc.findAllLike(type, choix).map(it => it.name);
|
const selection = Misc.findAllLike(type, choix).map(it => it.name);
|
||||||
if (selection.length == 0) {
|
if (selection.length == 0) {
|
||||||
@@ -297,7 +298,7 @@ export class TMRUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static buildSelectionTypesTMR(typesTMR) {
|
static buildSelectionTypesTMR(typesTMR) {
|
||||||
typesTMR = typesTMR?? [];
|
typesTMR = typesTMR ?? [];
|
||||||
return Object.values(TMRType).map(value => Misc.upperFirst(value.name))
|
return Object.values(TMRType).map(value => Misc.upperFirst(value.name))
|
||||||
.sort()
|
.sort()
|
||||||
.map(name => { return { name: name, selected: typesTMR.includes(name) } });
|
.map(name => { return { name: name, selected: typesTMR.includes(name) } });
|
||||||
@@ -375,6 +376,36 @@ export class TMRUtility {
|
|||||||
return caseList;
|
return caseList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// /* -------------------------------------------- */
|
||||||
|
static computeEventPosition(event) {
|
||||||
|
if (!event.nativeEvent.target.getBoundingClientRect) {
|
||||||
|
return { x: 0, y: 0 }
|
||||||
|
}
|
||||||
|
const canvasRect = event.nativeEvent.target.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
x: event.nativeEvent.clientX - canvasRect.left,
|
||||||
|
y: event.nativeEvent.clientY - canvasRect.top
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static computeEventOddq(event) {
|
||||||
|
var { x, y } = TMRUtility.computeEventPosition(event);
|
||||||
|
return TMRUtility.computeOddq(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static computeOddq(x, y) {
|
||||||
|
const col = Math.floor(x / tmrConstants.cellw); // [From 0 -> 12]
|
||||||
|
const decallageColonne = col % 2 == 0 ? tmrConstants.col1_y : tmrConstants.col2_y;
|
||||||
|
const row = Math.floor((y - decallageColonne) / tmrConstants.cellh); // [From 0 -> 14]
|
||||||
|
return { col, row };
|
||||||
|
}
|
||||||
|
|
||||||
|
static computeEventCoord(event) {
|
||||||
|
const oddq = TMRUtility.computeEventOddq(event);
|
||||||
|
return TMRUtility.oddqToCoordTMR(oddq);
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
// https://www.redblobgames.com/grids/hexagons/#distances
|
// https://www.redblobgames.com/grids/hexagons/#distances
|
||||||
// TMR Letter-row correspond to "odd-q" grid (letter => col, numeric => row )
|
// TMR Letter-row correspond to "odd-q" grid (letter => col, numeric => row )
|
||||||
@@ -400,7 +431,7 @@ export class TMRUtility {
|
|||||||
col >= 0 && col < 13 &&
|
col >= 0 && col < 13 &&
|
||||||
row >= 0 &&
|
row >= 0 &&
|
||||||
(row + col % 2 <= 14)
|
(row + col % 2 <= 14)
|
||||||
);
|
);
|
||||||
// if (x >= 0 && x < 13 && y >= 0 && y < 14) return true;
|
// if (x >= 0 && x < 13 && y >= 0 && y < 14) return true;
|
||||||
// if (x >= 0 && x < 13 && x % 2 == 0 && y == 14) return true;
|
// if (x >= 0 && x < 13 && x % 2 == 0 && y == 14) return true;
|
||||||
// return false;
|
// return false;
|
||||||
@@ -444,7 +475,7 @@ export class TMRUtility {
|
|||||||
|
|
||||||
static axial_subtract(a, b) {
|
static axial_subtract(a, b) {
|
||||||
return {
|
return {
|
||||||
q: a.q- b.q,
|
q: a.q - b.q,
|
||||||
r: a.r - b.r
|
r: a.r - b.r
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -456,7 +487,7 @@ export class TMRUtility {
|
|||||||
// return Cube(q, r, s)
|
// return Cube(q, r, s)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
// /* -------------------------------------------- */
|
// /* -------------------------------------------- */
|
||||||
// static computeRealPictureCoordinates(coordOddq) {
|
// static computeRealPictureCoordinates(coordOddq) {
|
||||||
// let decallagePairImpair = (coordOddq.col % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
|
// let decallagePairImpair = (coordOddq.col % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,9 +13,25 @@ export class CarteTmr extends Draconique {
|
|||||||
async onActorCreateOwned(actor, item) { }
|
async onActorCreateOwned(actor, item) { }
|
||||||
|
|
||||||
code() { return 'tmr' }
|
code() { return 'tmr' }
|
||||||
img() { return 'systems/foundryvtt-reve-de-dragon/styles/img/ui/tmp_main_r1.webp' }
|
img() { return 'systems/foundryvtt-reve-de-dragon/styles/img/ui/tmr.webp' }
|
||||||
|
|
||||||
createSprite(pixiTMR) {
|
createSprite(pixiTMR) {
|
||||||
return pixiTMR.carteTmr(this.code());
|
|
||||||
|
const img = PixiTMR.getImgFromCode(this.code())
|
||||||
|
const sprite = new PIXI.Sprite(PIXI.utils.TextureCache[img]);
|
||||||
|
// Setup the position of the TMR
|
||||||
|
sprite.x = 0;
|
||||||
|
sprite.y = 0;
|
||||||
|
sprite.width = 722;
|
||||||
|
sprite.height = 860;
|
||||||
|
// Rotate around the center
|
||||||
|
sprite.anchor.set(0);
|
||||||
|
sprite.buttonMode = true;
|
||||||
|
sprite.tmrObject = pixiTMR;
|
||||||
|
|
||||||
|
pixiTMR.addTooltip(sprite, (e,s) => this.computeTooltip(e,s));
|
||||||
|
pixiTMR.pixiApp.stage.addChild(sprite);
|
||||||
|
return sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const registeredEffects = [
|
|||||||
export class Draconique {
|
export class Draconique {
|
||||||
static isCaseTMR(item) { return item.type == TYPES.casetmr; }
|
static isCaseTMR(item) { return item.type == TYPES.casetmr; }
|
||||||
static isQueueDragon(item) { return item.isQueueDragon(); }
|
static isQueueDragon(item) { return item.isQueueDragon(); }
|
||||||
static isSouffleDragon(item) {return item.type == TYPES.souffle; }
|
static isSouffleDragon(item) { return item.type == TYPES.souffle; }
|
||||||
static isTeteDragon(item) { return item.type == TYPES.tete; }
|
static isTeteDragon(item) { return item.type == TYPES.tete; }
|
||||||
static isQueueSouffle(item) { return Draconique.isQueueDragon(item) || Draconique.isSouffleDragon(item); }
|
static isQueueSouffle(item) { return Draconique.isQueueDragon(item) || Draconique.isSouffleDragon(item); }
|
||||||
|
|
||||||
@@ -78,25 +78,45 @@ export class Draconique {
|
|||||||
/**
|
/**
|
||||||
* @param {*} img l'url du fichier image à utiliser pour le token. Si indéfini (et si createSprite n'est pas surchargé),
|
* @param {*} img l'url du fichier image à utiliser pour le token. Si indéfini (et si createSprite n'est pas surchargé),
|
||||||
* un disque est utilisé.
|
* un disque est utilisé.
|
||||||
*/
|
*/
|
||||||
img() { return undefined }
|
img() { return undefined }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* factory d'élément graphique PIXI correpsondant à l'objet draconique
|
* factory d'élément graphique PIXI correspondant à l'objet draconique
|
||||||
* @param {*} pixiTMR instance de PixiTMR qui gère les tooltips, les méthodes de création de sprite standard, les clicks.
|
* @param {*} pixiTMR instance de PixiTMR qui gère les tooltips, les méthodes de création de sprite standard, les clicks.
|
||||||
*/
|
*/
|
||||||
token(pixiTMR, linkData, coordTMR, type = undefined) {
|
token(pixiTMR, linkData, coordTMR, type = undefined) {
|
||||||
const token = {
|
const token = {
|
||||||
sprite: this.createSprite(pixiTMR),
|
sprite: this.createSprite(pixiTMR),
|
||||||
coordTMR: coordTMR
|
coordTMR: coordTMR
|
||||||
};
|
};
|
||||||
token[type ?? this.code()] = linkData;
|
token[type ?? this.code()] = linkData;
|
||||||
console.log("SPRITE: ", token.sprite)
|
this.linkData = linkData;
|
||||||
//PixiTMR.getImgFromCode()
|
if (this.tooltip(linkData)) {
|
||||||
pixiTMR.addTooltip(token.sprite, this.tooltip(linkData));
|
pixiTMR.addTooltip(token.sprite, (e, s) => this.computeTooltip(e, s));
|
||||||
|
}
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* methode en charge de recalculer le tooltip lorsque la souris bouge
|
||||||
|
* @param {*} event evenement contenant les coordonnées
|
||||||
|
* @param {*} sprite sprite pour laquelle calculer le tooltip
|
||||||
|
*/
|
||||||
|
computeTooltip(event, sprite) {
|
||||||
|
if (sprite.isOver) {
|
||||||
|
const oddq = TMRUtility.computeEventOddq(event);
|
||||||
|
const coord = TMRUtility.oddqToCoordTMR(oddq);
|
||||||
|
const tmr = TMRUtility.getTMR(coord)
|
||||||
|
if (tmr){
|
||||||
|
const label = TMRUtility.getTMRLabel(coord);
|
||||||
|
const text = this.tooltip(this.linkData);
|
||||||
|
return text ? `${coord}: ${label}\n${text}` : `${coord}: ${label}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* factory d'élément graphique PIXI correpsondant à l'objet draconique
|
* factory d'élément graphique PIXI correpsondant à l'objet draconique
|
||||||
* @param {*} pixiTMR instance de PixiTMR qui gère les tooltips, les méthodes de création de sprite standard, les clicks.
|
* @param {*} pixiTMR instance de PixiTMR qui gère les tooltips, les méthodes de création de sprite standard, les clicks.
|
||||||
@@ -118,11 +138,11 @@ export class Draconique {
|
|||||||
isCase(item, coord = undefined) {
|
isCase(item, coord = undefined) {
|
||||||
return Draconique.isCaseTMR(item) && item.system.specific == this.code() && (coord ? item.system.coord == coord : true);
|
return Draconique.isCaseTMR(item) && item.system.specific == this.code() && (coord ? item.system.coord == coord : true);
|
||||||
}
|
}
|
||||||
|
|
||||||
find(list, coord = undefined) {
|
find(list, coord = undefined) {
|
||||||
return list.find(c => this.isCase(c, coord));
|
return list.find(c => this.isCase(c, coord));
|
||||||
}
|
}
|
||||||
|
|
||||||
async createCaseTmr(actor, label, tmr, sourceId = undefined) {
|
async createCaseTmr(actor, label, tmr, sourceId = undefined) {
|
||||||
const casetmrData = {
|
const casetmrData = {
|
||||||
name: label, type: 'casetmr', img: this.img(),
|
name: label, type: 'casetmr', img: this.img(),
|
||||||
@@ -130,12 +150,12 @@ export class Draconique {
|
|||||||
};
|
};
|
||||||
await actor.createEmbeddedDocuments('Item', [casetmrData]);
|
await actor.createEmbeddedDocuments('Item', [casetmrData]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteCasesTmr(actor, draconique) {
|
async deleteCasesTmr(actor, draconique) {
|
||||||
let caseTmrs = actor.items.filter(it => this.isCaseForSource(it, draconique));
|
let caseTmrs = actor.items.filter(it => this.isCaseForSource(it, draconique));
|
||||||
await actor.deleteEmbeddedDocuments('Item', caseTmrs.map(it => it.id));
|
await actor.deleteEmbeddedDocuments('Item', caseTmrs.map(it => it.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
isCaseForSource(item, draconique) {
|
isCaseForSource(item, draconique) {
|
||||||
return Draconique.isCaseTMR(item) && item.system.specific == this.code() && item.system.sourceid == draconique.id;
|
return Draconique.isCaseTMR(item) && item.system.specific == this.code() && item.system.sourceid == draconique.id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { ExperienceLog, XP_TOPIC } from "../actor/experience-log.js";
|
|||||||
import { ChatUtility } from "../chat-utility.js";
|
import { ChatUtility } from "../chat-utility.js";
|
||||||
import { Poetique } from "../poetique.js";
|
import { Poetique } from "../poetique.js";
|
||||||
import { RdDDice } from "../rdd-dice.js";
|
import { RdDDice } from "../rdd-dice.js";
|
||||||
|
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
|
||||||
import { TMRUtility } from "../tmr-utility.js";
|
import { TMRUtility } from "../tmr-utility.js";
|
||||||
|
|
||||||
export class EffetsRencontre {
|
export class EffetsRencontre {
|
||||||
@@ -9,7 +10,7 @@ export class EffetsRencontre {
|
|||||||
static messager = async (dialog, context) => {
|
static messager = async (dialog, context) => {
|
||||||
dialog.setRencontreState('messager', TMRUtility.getTMRPortee(context.tmr.coord, context.rencontre.system.force));
|
dialog.setRencontreState('messager', TMRUtility.getTMRPortee(context.tmr.coord, context.rencontre.system.force));
|
||||||
}
|
}
|
||||||
|
|
||||||
static passeur = async (dialog, context) => {
|
static passeur = async (dialog, context) => {
|
||||||
dialog.setRencontreState('passeur', TMRUtility.getTMRPortee(context.tmr.coord, context.rencontre.system.force));
|
dialog.setRencontreState('passeur', TMRUtility.getTMRPortee(context.tmr.coord, context.rencontre.system.force));
|
||||||
}
|
}
|
||||||
@@ -26,16 +27,25 @@ export class EffetsRencontre {
|
|||||||
static reve_plus_1 = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, 1) }
|
static reve_plus_1 = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, 1) }
|
||||||
static reve_moins_force = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, -context.rencontre.system.force) }
|
static reve_moins_force = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, -context.rencontre.system.force) }
|
||||||
static reve_moins_1 = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, -1) }
|
static reve_moins_1 = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, -1) }
|
||||||
static $reve_plus = async (actor, valeur) => { await actor.reveActuelIncDec(valeur) }
|
static $reve_plus = async (actor, reve) => {
|
||||||
|
if (!ReglesOptionnelles.isUsing("recuperation-reve") && reve < 0) {
|
||||||
|
ChatMessage.create({
|
||||||
|
whisper: ChatUtility.getWhisperRecipientsAndGMs(actor.name),
|
||||||
|
content: `Pas de récupération de rêve (${reve} points ignorés)`
|
||||||
|
});
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await actor.reveActuelIncDec(reve)
|
||||||
|
}
|
||||||
|
|
||||||
static vie_moins_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -1) }
|
static vie_moins_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -1) }
|
||||||
static vie_moins_force = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -context.rencontre.system.force) }
|
static vie_moins_force = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -context.rencontre.system.force) }
|
||||||
static $vie_plus = async (actor, valeur) => { await actor.santeIncDec("vie", valeur) }
|
static $vie_plus = async (actor, valeur) => { await actor.santeIncDec("vie", valeur) }
|
||||||
|
|
||||||
static moral_plus_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, 1) }
|
static moral_plus_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, 1) }
|
||||||
static moral_moins_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -1) }
|
static moral_moins_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -1) }
|
||||||
static $moral_plus = async (actor, valeur) => { await actor.moralIncDec(valeur) }
|
static $moral_plus = async (actor, valeur) => { await actor.moralIncDec(valeur) }
|
||||||
|
|
||||||
static end_moins_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -1) }
|
static end_moins_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -1) }
|
||||||
static end_moins_force = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -context.rencontre.system.force) }
|
static end_moins_force = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -context.rencontre.system.force) }
|
||||||
static $end_plus = async (actor, valeur) => { await actor.santeIncDec("endurance", valeur) }
|
static $end_plus = async (actor, valeur) => { await actor.santeIncDec("endurance", valeur) }
|
||||||
@@ -50,8 +60,8 @@ export class EffetsRencontre {
|
|||||||
const perte = context.rolled.isETotal ? context.rencontre.system.force : 1;
|
const perte = context.rolled.isETotal ? context.rencontre.system.force : 1;
|
||||||
await context.actor.chanceActuelleIncDec("fatigue", -perte);
|
await context.actor.chanceActuelleIncDec("fatigue", -perte);
|
||||||
}
|
}
|
||||||
|
|
||||||
static xp_sort_force = async (dialog, context) => {
|
static xp_sort_force = async (dialog, context) => {
|
||||||
let competence = context.competence;
|
let competence = context.competence;
|
||||||
if (competence) {
|
if (competence) {
|
||||||
const fromXpSort = Number(competence.system.xp_sort);
|
const fromXpSort = Number(competence.system.xp_sort);
|
||||||
@@ -60,7 +70,7 @@ export class EffetsRencontre {
|
|||||||
await ExperienceLog.add(this, XP_TOPIC.XPSORT, fromXpSort, toXpSort, `${competence.name} - ${context.rencontre.name} en TMR`);
|
await ExperienceLog.add(this, XP_TOPIC.XPSORT, fromXpSort, toXpSort, `${competence.name} - ${context.rencontre.name} en TMR`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static stress_plus_1 = async (dialog, context) => {
|
static stress_plus_1 = async (dialog, context) => {
|
||||||
await context.actor.addCompteurValue('stress', 1, `Rencontre d'un ${context.rencontre.name} en TMR`);
|
await context.actor.addCompteurValue('stress', 1, `Rencontre d'un ${context.rencontre.name} en TMR`);
|
||||||
}
|
}
|
||||||
@@ -75,7 +85,7 @@ export class EffetsRencontre {
|
|||||||
|
|
||||||
static demireve_rompu = async (dialog, context) => {
|
static demireve_rompu = async (dialog, context) => {
|
||||||
dialog.close()
|
dialog.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
static sort_aleatoire = async (dialog, context) => {
|
static sort_aleatoire = async (dialog, context) => {
|
||||||
context.sortReserve = await RdDDice.rollOneOf(context.actor.itemTypes['sortreserve']);
|
context.sortReserve = await RdDDice.rollOneOf(context.actor.itemTypes['sortreserve']);
|
||||||
@@ -128,7 +138,7 @@ export class EffetsRencontre {
|
|||||||
|
|
||||||
static regain_seuil = async (dialog, context) => {
|
static regain_seuil = async (dialog, context) => {
|
||||||
await context.actor.regainPointDeSeuil()
|
await context.actor.regainPointDeSeuil()
|
||||||
}
|
}
|
||||||
|
|
||||||
static async $reinsertion(dialog, actor, filter) {
|
static async $reinsertion(dialog, actor, filter) {
|
||||||
const newTMR = await TMRUtility.getTMRAleatoire(filter);
|
const newTMR = await TMRUtility.getTMRAleatoire(filter);
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
import { RdDTMRDialog } from "../rdd-tmr-dialog.js";
|
||||||
import { tmrConstants, tmrTokenZIndex } from "../tmr-constants.js";
|
import { tmrConstants, tmrTokenZIndex } from "../tmr-constants.js";
|
||||||
|
import { TMRUtility } from "../tmr-utility.js";
|
||||||
|
|
||||||
const tooltipStyle = new PIXI.TextStyle({
|
export const tooltipStyle = new PIXI.TextStyle({
|
||||||
fontFamily: 'CaslonAntique',
|
fontFamily: 'CaslonAntique',
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fill: '#FFFFFF',
|
fill: '#FFFFFF',
|
||||||
@@ -20,7 +22,7 @@ export class PixiTMR {
|
|||||||
this.callbacksOnAnimate = [];
|
this.callbacksOnAnimate = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
async load( onLoad = (loader, resources) => {} ) {
|
async load(onLoad = (loader, resources) => { }) {
|
||||||
// WIP - Deprecated since v7 : let loader = new PIXI.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)) {
|
||||||
const texture = await PIXI.Assets.load(img);
|
const texture = await PIXI.Assets.load(img);
|
||||||
@@ -40,40 +42,17 @@ export class PixiTMR {
|
|||||||
PixiTMR.textures[name] = img;
|
PixiTMR.textures[name] = img;
|
||||||
}
|
}
|
||||||
|
|
||||||
animate(animation = pixiApp=>{})
|
animate(animation = pixiApp => { }) {
|
||||||
{
|
|
||||||
this.callbacksOnAnimate.push(() => animation(this.pixiApp));
|
this.callbacksOnAnimate.push(() => animation(this.pixiApp));
|
||||||
}
|
}
|
||||||
|
|
||||||
carteTmr(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;
|
|
||||||
carteTmr.width = 720;
|
|
||||||
carteTmr.height = 860;
|
|
||||||
// Rotate around the center
|
|
||||||
carteTmr.anchor.set(0);
|
|
||||||
carteTmr.eventMode = 'dynamic'; // PIXI 7 : Not sure ..
|
|
||||||
// This one is deprecated ; carteTmr.interactive = true;
|
|
||||||
carteTmr.buttonMode = true;
|
|
||||||
carteTmr.tmrObject = this;
|
|
||||||
if (!this.tmrObject.viewOnly) {
|
|
||||||
carteTmr.on('pointerdown', event => this.onClickBackground(event));
|
|
||||||
}
|
|
||||||
this.pixiApp.stage.addChild(carteTmr);
|
|
||||||
return carteTmr;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprite(code, options = {}) {
|
sprite(code, options = {}) {
|
||||||
let img = PixiTMR.getImgFromCode(code)
|
let img = PixiTMR.getImgFromCode(code)
|
||||||
const texture = PIXI.utils.TextureCache[img];
|
const texture = PIXI.utils.TextureCache[img];
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
console.error("Texture manquante", code, PIXI.utils.TextureCache)
|
console.error("Texture manquante", code, PIXI.utils.TextureCache)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let sprite = new PIXI.Sprite(texture);
|
let sprite = new PIXI.Sprite(texture);
|
||||||
sprite.width = options.taille ?? tmrConstants.half;
|
sprite.width = options.taille ?? tmrConstants.half;
|
||||||
sprite.height = options.taille ?? tmrConstants.half;
|
sprite.height = options.taille ?? tmrConstants.half;
|
||||||
@@ -81,13 +60,13 @@ export class PixiTMR {
|
|||||||
if (options.color) {
|
if (options.color) {
|
||||||
sprite.tint = options.color;
|
sprite.tint = options.color;
|
||||||
}
|
}
|
||||||
sprite.zIndex = options.zIndex ?? tmrTokenZIndex.casehumide+1;
|
sprite.zIndex = options.zIndex ?? tmrTokenZIndex.casehumide + 1;
|
||||||
sprite.alpha = options.alpha ?? 0.75;
|
sprite.alpha = options.alpha ?? 0.75;
|
||||||
sprite.decallage = options.decallage ?? tmrConstants.center;
|
sprite.decallage = options.decallage ?? tmrConstants.center;
|
||||||
this.pixiApp.stage.addChild(sprite);
|
this.pixiApp.stage.addChild(sprite);
|
||||||
return sprite;
|
return sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
circle(name, options = {}) {
|
circle(name, options = {}) {
|
||||||
let sprite = new PIXI.Graphics();
|
let sprite = new PIXI.Graphics();
|
||||||
sprite.beginFill(options.color, options.opacity);
|
sprite.beginFill(options.color, options.opacity);
|
||||||
@@ -98,27 +77,37 @@ export class PixiTMR {
|
|||||||
return sprite;
|
return sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
addTooltip(sprite, text) {
|
addTooltip(sprite, computeTooltip) {
|
||||||
if (text) {
|
sprite.tooltip = new PIXI.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.eventMode = 'static';
|
||||||
// Deprecated : sprite.interactive = true;
|
sprite
|
||||||
sprite.eventMode = 'dynamic'; // PIXI 7 To be checked
|
.on('pointermove', event => this.onPointerMove(event, sprite, computeTooltip))
|
||||||
sprite.on('pointerdown', event => this.onClickBackground(event))
|
.on('pointerdown', event => this.onClickBackground(event))
|
||||||
.on('pointerover', () => this.onShowTooltip(sprite))
|
.on('pointerover', event => this.onShowTooltip(event, sprite))
|
||||||
.on('pointerout', () => this.onHideTooltip(sprite));
|
.on('pointerout', event => this.onHideTooltip(event, sprite));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
onClickBackground(event) {
|
onClickBackground(event) {
|
||||||
this.tmrObject.onClickTMR(event)
|
if (!this.viewOnly) {
|
||||||
|
this.tmrObject.onClickTMR(event)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onShowTooltip(sprite) {
|
onPointerMove(event, sprite, computeTooltip) {
|
||||||
if (sprite.tooltip) {
|
if (sprite.isOver && sprite.tooltip) {
|
||||||
|
var { x, y } = TMRUtility.computeEventPosition(event);
|
||||||
|
const oddq = TMRUtility.computeOddq(x, y);
|
||||||
|
|
||||||
|
sprite.tooltip.x = x + (oddq.col > 8 ? - 3 * tmrConstants.full : tmrConstants.half)
|
||||||
|
sprite.tooltip.y = y + (oddq.row > 10 ? - tmrConstants.half : tmrConstants.half)
|
||||||
|
sprite.tooltip.text = computeTooltip(event, sprite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onShowTooltip(event, sprite) {
|
||||||
|
if (sprite.tooltip) {
|
||||||
if (!sprite.isOver) {
|
if (!sprite.isOver) {
|
||||||
sprite.tooltip.x = sprite.x;
|
sprite.tooltip.x = sprite.x;
|
||||||
sprite.tooltip.y = sprite.y;
|
sprite.tooltip.y = sprite.y;
|
||||||
@@ -128,7 +117,7 @@ export class PixiTMR {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onHideTooltip(sprite) {
|
onHideTooltip(event, sprite) {
|
||||||
if (sprite.tooltip) {
|
if (sprite.tooltip) {
|
||||||
if (sprite.isOver) {
|
if (sprite.isOver) {
|
||||||
this.pixiApp.stage.removeChild(sprite.tooltip);
|
this.pixiApp.stage.removeChild(sprite.tooltip);
|
||||||
@@ -137,7 +126,7 @@ export class PixiTMR {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setPosition( sprite, oddq) {
|
setPosition(sprite, oddq) {
|
||||||
let decallagePairImpair = (oddq.col % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
|
let decallagePairImpair = (oddq.col % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
|
||||||
let dx = (sprite.decallage == undefined) ? 0 : sprite.decallage.x;
|
let dx = (sprite.decallage == undefined) ? 0 : sprite.decallage.x;
|
||||||
let dy = (sprite.decallage == undefined) ? 0 : sprite.decallage.y;
|
let dy = (sprite.decallage == undefined) ? 0 : sprite.decallage.y;
|
||||||
|
|||||||
@@ -49,12 +49,13 @@ export class PresentCites extends Draconique {
|
|||||||
const presents = await game.system.rdd.rencontresTMR.getPresentsCite()
|
const presents = await game.system.rdd.rencontresTMR.getPresentsCite()
|
||||||
const buttons = {};
|
const buttons = {};
|
||||||
presents.forEach(r => buttons['present'+r.id] = { icon: '<i class="fas fa-check"></i>', label: r.name, callback: async () => onChoixPresent(r) });
|
presents.forEach(r => buttons['present'+r.id] = { icon: '<i class="fas fa-check"></i>', label: r.name, callback: async () => onChoixPresent(r) });
|
||||||
let d = new Dialog({
|
let dialog = new Dialog({
|
||||||
title: "Présent des cités",
|
title: "Présent des cités",
|
||||||
content: `La ${this.tmrLabel(casetmr)} vous offre un présent, faites votre choix`,
|
content: `La ${this.tmrLabel(casetmr)} vous offre un présent, faites votre choix`,
|
||||||
buttons: buttons
|
buttons: buttons
|
||||||
});
|
});
|
||||||
d.render(true);
|
dialog.render(true);
|
||||||
|
return dialog
|
||||||
}
|
}
|
||||||
|
|
||||||
async ouvrirLePresent(actor, casetmr) {
|
async ouvrirLePresent(actor, casetmr) {
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 313 KiB |
BIN
styles/img/ui/tmr.webp
Normal file
BIN
styles/img/ui/tmr.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 637 KiB |
@@ -171,6 +171,9 @@ i:is(.fas, .far) {
|
|||||||
width: fit-content;
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tmr-dialog table {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .sheet-header div.tmr-buttons {
|
.system-foundryvtt-reve-de-dragon .sheet-header div.tmr-buttons {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -287,6 +290,16 @@ table {border: 1px solid #7a7971;}
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.grid-competence-archetype {
|
||||||
|
display: grid;
|
||||||
|
grid-column: span 3 / span 3;
|
||||||
|
grid-template-columns: 2fr 2fr 1fr;
|
||||||
|
gap: 0.5rem;
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.grid-3col {
|
.grid-3col {
|
||||||
grid-column: span 3 / span 3;
|
grid-column: span 3 / span 3;
|
||||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
@@ -1898,34 +1911,51 @@ div.calendar-timestamp-edit select.calendar-signe-heure {
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-card-button {
|
.chat-card-button, .chat-card-button-pushed {
|
||||||
box-shadow: inset 0px 1px 0px 0px #a6827e;
|
border-radius: 0.2rem;
|
||||||
background: var(--background-custom-button);
|
|
||||||
background-color: #7d5d3b00;
|
|
||||||
border-radius: 3px;
|
|
||||||
border: 2px ridge #846109;
|
|
||||||
display: inline-block;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: #ffffff;
|
|
||||||
font-family: CaslonPro;
|
font-family: CaslonPro;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
padding: 4px 12px 0px 12px;
|
padding: 0.2rem 0.4rem 0rem 0.4rem;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
text-shadow: 0px 1px 0px #4d3534;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
margin:5px;
|
margin: 0.3rem;
|
||||||
|
|
||||||
|
border: 2px ridge #846109;
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chat-card-button{
|
||||||
|
text-shadow: 1px 1px #4d3534;
|
||||||
|
box-shadow: inset 1x 1px #a6827e;
|
||||||
|
color: var(--major-button-color);
|
||||||
|
background: var(--background-custom-button);
|
||||||
|
background-color: #7d5d3b00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-card-button-pushed {
|
||||||
|
text-shadow: 1px 1px hsla(202, 30%, 70%, 0.5);
|
||||||
|
box-shadow: inset -1px -1px #a6827e;
|
||||||
|
color: hsla(202, 42%, 14%, 0.7);
|
||||||
|
background: var(--major-button-color);
|
||||||
|
background-color: #7d5d3b00;
|
||||||
|
}
|
||||||
|
|
||||||
.chat-card-button:hover {
|
.chat-card-button:hover {
|
||||||
background: var(--background-custom-button-hover);
|
background: var(--background-custom-button-hover);
|
||||||
background-color: red;
|
background-color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-card-button:active {
|
.chat-card-button-pushed:hover {
|
||||||
|
background: var(--background-custom-button-hover);
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-card-button:active, .chat-card-button-pushed:active {
|
||||||
position:relative;
|
position:relative;
|
||||||
top:1px;
|
top:1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dropdown Content (Hidden by Default) */
|
/* Dropdown Content (Hidden by Default) */
|
||||||
.button-dropdown-content {
|
.button-dropdown-content {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
104
system.json
104
system.json
@@ -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": "11.0.7",
|
"version": "11.1.2",
|
||||||
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-11.0.7.zip",
|
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-11.1.2.zip",
|
||||||
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v11/system.json",
|
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v11/system.json",
|
||||||
|
"changelog": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/branch/v11/changelog.md",
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"minimum": "11",
|
"minimum": "11",
|
||||||
"verified": "11",
|
"verified": "11"
|
||||||
"maximum": "11"
|
|
||||||
},
|
},
|
||||||
"description": "Rêve de Dragon RPG for FoundryVTT",
|
"description": "Rêve de Dragon RPG for FoundryVTT",
|
||||||
"authors": [
|
"authors": [
|
||||||
@@ -82,7 +82,8 @@
|
|||||||
"path": "packs/arts-et-divertissements.db",
|
"path": "packs/arts-et-divertissements.db",
|
||||||
"type": "Item",
|
"type": "Item",
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"PLAYER": "OBSERVER"
|
"PLAYER": "OBSERVER",
|
||||||
|
"ASSISTANT": "OWNER"
|
||||||
},
|
},
|
||||||
"flags": {}
|
"flags": {}
|
||||||
},
|
},
|
||||||
@@ -117,7 +118,8 @@
|
|||||||
"path": "packs/sorts-oniros.db",
|
"path": "packs/sorts-oniros.db",
|
||||||
"type": "Item",
|
"type": "Item",
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"PLAYER": "OBSERVER"
|
"PLAYER": "OBSERVER",
|
||||||
|
"ASSISTANT": "OWNER"
|
||||||
},
|
},
|
||||||
"flags": {}
|
"flags": {}
|
||||||
},
|
},
|
||||||
@@ -128,7 +130,8 @@
|
|||||||
"path": "packs/sorts-hypnos.db",
|
"path": "packs/sorts-hypnos.db",
|
||||||
"type": "Item",
|
"type": "Item",
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"PLAYER": "OBSERVER"
|
"PLAYER": "OBSERVER",
|
||||||
|
"ASSISTANT": "OWNER"
|
||||||
},
|
},
|
||||||
"flags": {}
|
"flags": {}
|
||||||
},
|
},
|
||||||
@@ -139,7 +142,8 @@
|
|||||||
"path": "packs/sorts-narcos.db",
|
"path": "packs/sorts-narcos.db",
|
||||||
"type": "Item",
|
"type": "Item",
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"PLAYER": "OBSERVER"
|
"PLAYER": "OBSERVER",
|
||||||
|
"ASSISTANT": "OWNER"
|
||||||
},
|
},
|
||||||
"flags": {}
|
"flags": {}
|
||||||
},
|
},
|
||||||
@@ -150,7 +154,8 @@
|
|||||||
"path": "packs/sorts-thanatos.db",
|
"path": "packs/sorts-thanatos.db",
|
||||||
"type": "Item",
|
"type": "Item",
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"PLAYER": "OBSERVER"
|
"PLAYER": "OBSERVER",
|
||||||
|
"ASSISTANT": "OWNER"
|
||||||
},
|
},
|
||||||
"flags": {}
|
"flags": {}
|
||||||
},
|
},
|
||||||
@@ -161,7 +166,8 @@
|
|||||||
"path": "packs/equipement.db",
|
"path": "packs/equipement.db",
|
||||||
"type": "Item",
|
"type": "Item",
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"PLAYER": "OBSERVER"
|
"PLAYER": "OBSERVER",
|
||||||
|
"ASSISTANT": "OWNER"
|
||||||
},
|
},
|
||||||
"flags": {}
|
"flags": {}
|
||||||
},
|
},
|
||||||
@@ -184,7 +190,8 @@
|
|||||||
"path": "packs/rappel-des-regles.db",
|
"path": "packs/rappel-des-regles.db",
|
||||||
"type": "JournalEntry",
|
"type": "JournalEntry",
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"PLAYER": "OBSERVER"
|
"PLAYER": "OBSERVER",
|
||||||
|
"ASSISTANT": "OBSERVER"
|
||||||
},
|
},
|
||||||
"flags": {}
|
"flags": {}
|
||||||
},
|
},
|
||||||
@@ -195,7 +202,8 @@
|
|||||||
"path": "packs/macros.db",
|
"path": "packs/macros.db",
|
||||||
"type": "Macro",
|
"type": "Macro",
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"PLAYER": "OBSERVER"
|
"PLAYER": "OBSERVER",
|
||||||
|
"ASSISTANT": "OWNER"
|
||||||
},
|
},
|
||||||
"flags": {}
|
"flags": {}
|
||||||
},
|
},
|
||||||
@@ -242,7 +250,8 @@
|
|||||||
"path": "packs/tarot-draconique.db",
|
"path": "packs/tarot-draconique.db",
|
||||||
"type": "Item",
|
"type": "Item",
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"PLAYER": "OBSERVER"
|
"PLAYER": "OBSERVER",
|
||||||
|
"ASSISTANT": "OWNER"
|
||||||
},
|
},
|
||||||
"flags": {}
|
"flags": {}
|
||||||
},
|
},
|
||||||
@@ -253,7 +262,8 @@
|
|||||||
"path": "packs/extrait-poetique.db",
|
"path": "packs/extrait-poetique.db",
|
||||||
"type": "Item",
|
"type": "Item",
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"PLAYER": "OBSERVER"
|
"PLAYER": "OBSERVER",
|
||||||
|
"ASSISTANT": "OWNER"
|
||||||
},
|
},
|
||||||
"flags": {}
|
"flags": {}
|
||||||
},
|
},
|
||||||
@@ -438,6 +448,72 @@
|
|||||||
"flags": {}
|
"flags": {}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"packFolders": [
|
||||||
|
{
|
||||||
|
"name": "Rêve de Dragon",
|
||||||
|
"sorting": "m",
|
||||||
|
"packs": [
|
||||||
|
"rappel-des-regles"
|
||||||
|
],
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"name": "Personnages",
|
||||||
|
"sorting": "m",
|
||||||
|
"packs": [
|
||||||
|
"voyageurs",
|
||||||
|
"archetypes",
|
||||||
|
"humanoides",
|
||||||
|
"equipement",
|
||||||
|
"competences",
|
||||||
|
"arts-et-divertissements",
|
||||||
|
"meditations-et-ecrits",
|
||||||
|
"recettes-alchimiques"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Le Haut-rêve",
|
||||||
|
"sorting": "m",
|
||||||
|
"packs": [
|
||||||
|
"tetes-de-dragon-pour-tous-personnages",
|
||||||
|
"sorts-oniros",
|
||||||
|
"sorts-hypnos",
|
||||||
|
"sorts-narcos",
|
||||||
|
"sorts-thanatos",
|
||||||
|
"invocations",
|
||||||
|
"rencontres",
|
||||||
|
"queues-de-dragon",
|
||||||
|
"ombres-de-thanatos",
|
||||||
|
"souffles-de-dragon",
|
||||||
|
"tetes-de-dragon-pour-haut-revants"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Découverte du monde",
|
||||||
|
"sorting": "m",
|
||||||
|
"packs": [
|
||||||
|
"animaux",
|
||||||
|
"vehicules",
|
||||||
|
"entites",
|
||||||
|
"faune-flore-mineraux",
|
||||||
|
"competences-creatures",
|
||||||
|
"competences-entites",
|
||||||
|
"maladies-et-poisons"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Outils du Gardien",
|
||||||
|
"sorting": "m",
|
||||||
|
"packs": [
|
||||||
|
"scenes-rdd",
|
||||||
|
"tables-diverses",
|
||||||
|
"macros",
|
||||||
|
"tarot-draconique",
|
||||||
|
"extrait-poetique"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"socket": true,
|
"socket": true,
|
||||||
"gridDistance": 1,
|
"gridDistance": 1,
|
||||||
"gridUnits": "m",
|
"gridUnits": "m",
|
||||||
|
|||||||
@@ -393,12 +393,6 @@
|
|||||||
"label": "Encombrement",
|
"label": "Encombrement",
|
||||||
"derivee": true
|
"derivee": true
|
||||||
},
|
},
|
||||||
"malusarmure": {
|
|
||||||
"type": "number",
|
|
||||||
"value": 0,
|
|
||||||
"label": "Malus Armure",
|
|
||||||
"derivee": true
|
|
||||||
},
|
|
||||||
"protection": {
|
"protection": {
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"value": 0,
|
"value": 0,
|
||||||
@@ -594,7 +588,8 @@
|
|||||||
"iscombat": false,
|
"iscombat": false,
|
||||||
"isnaturelle": true,
|
"isnaturelle": true,
|
||||||
"ispossession": false,
|
"ispossession": false,
|
||||||
"dommages": 0
|
"dommages": 0,
|
||||||
|
"mortalite": "mortel"
|
||||||
},
|
},
|
||||||
"empoignade": {
|
"empoignade": {
|
||||||
"templates": ["description"],
|
"templates": ["description"],
|
||||||
@@ -671,6 +666,7 @@
|
|||||||
"resistance": 0,
|
"resistance": 0,
|
||||||
"categorie_parade": "",
|
"categorie_parade": "",
|
||||||
"dommages": "0",
|
"dommages": "0",
|
||||||
|
"mortalite": "mortel",
|
||||||
"penetration": 0,
|
"penetration": 0,
|
||||||
"force": "0",
|
"force": "0",
|
||||||
"competence": "",
|
"competence": "",
|
||||||
|
|||||||
@@ -53,7 +53,9 @@
|
|||||||
{{#if options.isObserver}}{{!-- Compétences Tab --}}
|
{{#if options.isObserver}}{{!-- Compétences Tab --}}
|
||||||
<div class="tab competences" data-group="primary" data-tab="competences">
|
<div class="tab competences" data-group="primary" data-tab="competences">
|
||||||
<div class="flexrow">
|
<div class="flexrow">
|
||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html"}}
|
<span>
|
||||||
|
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html"}}
|
||||||
|
</span>
|
||||||
<span class="flexrow"><a class="show-hide-competences">
|
<span class="flexrow"><a class="show-hide-competences">
|
||||||
{{#if options.showCompNiveauBase}}
|
{{#if options.showCompNiveauBase}}
|
||||||
<i class="fa-regular fa-filter-slash"></i> Montrer tout
|
<i class="fa-regular fa-filter-slash"></i> Montrer tout
|
||||||
@@ -65,9 +67,17 @@
|
|||||||
<input class="recherche flex-grow" type="text" value="{{options.recherche.text}}" name="recherche" size="8" data-dtype="String" placeholder=""/>
|
<input class="recherche flex-grow" type="text" value="{{options.recherche.text}}" name="recherche" size="8" data-dtype="String" placeholder=""/>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
|
{{#if options.vueDetaillee}}
|
||||||
|
|
||||||
|
{{#if @root.options.vueArchetype}}
|
||||||
|
<a class="competence-archetype toggle-archetype chat-card-button-pushed"><i class="fa-solid fa-up-right-from-square"></i>Incarnation</a>
|
||||||
|
{{else}}
|
||||||
|
<a class="competence-archetype toggle-archetype chat-card-button"><i class="fa-solid fa-people-line"></i>Archétype</a>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-2col">
|
<div class="grid {{#if (and options.vueDetaillee options.vueArchetype)}}grid-competence-archetype{{else}}grid-2col{{/if}}">
|
||||||
<div class="competence-column">
|
<div class="competence-column">
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.generale) categorie="Compétences générales"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.generale) categorie="Compétences générales"}}
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.particuliere) categorie="Compétences Particulières"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.particuliere) categorie="Compétences Particulières"}}
|
||||||
@@ -83,6 +93,11 @@
|
|||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.draconic) categorie="Draconic"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.draconic) categorie="Draconic"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
{{#if (and options.vueDetaillee options.vueArchetype)}}
|
||||||
|
<div>
|
||||||
|
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/archetype.hbs"}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|||||||
21
templates/actor/archetype.hbs
Normal file
21
templates/actor/archetype.hbs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<div>
|
||||||
|
<ul class="item-list">
|
||||||
|
{{#if @root.options.isGM}}
|
||||||
|
<li>
|
||||||
|
<a class="nouvelle-incarnation chat-card-button"><i class="fa-solid fa-person-circle-plus"></i> Nouvelle incarnation</a>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
<li><hr></li>
|
||||||
|
<li>Niveaux d'archétype</li>
|
||||||
|
{{#if calc.comptageArchetype}}
|
||||||
|
{{#each calc.comptageArchetype as |archetype|}}
|
||||||
|
|
||||||
|
<li class="item flexrow">
|
||||||
|
<label class="generic-label">
|
||||||
|
Niveaux {{numberFormat archetype.niveau decimals=0 sign=true}} : {{archetype.nombre}} / {{archetype.nombreMax}}
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
{{/if}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
</li>
|
</li>
|
||||||
<li class="caracteristique flexrow list-item" >
|
<li class="caracteristique flexrow list-item" >
|
||||||
<label class="carac-label">Malus armure</label>
|
<label class="carac-label">Malus armure</label>
|
||||||
<input class="derivee-value" type="number" disabled value="{{system.attributs.malusarmure.value}}" data-dtype="number"/>
|
<input class="derivee-value" type="number" disabled value="{{calc.malusArmure}}" data-dtype="number"/>
|
||||||
</li>
|
</li>
|
||||||
<li class="caracteristique flexrow list-item">
|
<li class="caracteristique flexrow list-item">
|
||||||
<label class="carac-label" for="system.attributs.protection.value" >Protection naturelle</label>
|
<label class="carac-label" for="system.attributs.protection.value" >Protection naturelle</label>
|
||||||
|
|||||||
@@ -14,12 +14,13 @@
|
|||||||
|
|
||||||
<input class="competence-value" type="text" compname="{{name}}" name="comp-value-{{name}}"
|
<input class="competence-value" type="text" compname="{{name}}" name="comp-value-{{name}}"
|
||||||
value="{{numberFormat system.niveau decimals=0 sign=true}}" data-dtype="number"
|
value="{{numberFormat system.niveau decimals=0 sign=true}}" data-dtype="number"
|
||||||
{{#unless @root.options.vueDetaillee}}disabled{{/unless}} />
|
{{#if (or (not @root.options.vueDetaillee) @root.options.vueArchetype)}}disabled{{/if}} />
|
||||||
|
|
||||||
{{#if @root.options.vueDetaillee}}
|
{{#if @root.options.vueDetaillee}}
|
||||||
<span class="competence-xp {{#unless system.isLevelUp}}tooltip{{/unless}}">
|
<span class="competence-xp {{#unless system.isLevelUp}}tooltip{{/unless}}">
|
||||||
<input class="competence-xp " type="text" compname="{{name}}" name="comp-xp-{{name}}"
|
<input class="competence-xp " type="text" compname="{{name}}" name="comp-xp-{{name}}"
|
||||||
value="{{numberFormat system.xp decimals=0 sign=false}}" data-dtype="number"/>
|
value="{{numberFormat system.xp decimals=0 sign=false}}" data-dtype="number"
|
||||||
|
{{#if (or (not @root.options.vueDetaillee) @root.options.vueArchetype)}}disabled{{/if}} />
|
||||||
{{#unless system.isLevelUp}}
|
{{#unless system.isLevelUp}}
|
||||||
<span class="tooltiptext left-competence ttt-xp">Vous devez acquérir {{system.xpNext}} points d'Experience pour augmenter de 1 votre compétence {{name}}</span>
|
<span class="tooltiptext left-competence ttt-xp">Vous devez acquérir {{system.xpNext}} points d'Experience pour augmenter de 1 votre compétence {{name}}</span>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
@@ -28,7 +29,7 @@
|
|||||||
{{#if (eq system.categorie 'draconic')}}
|
{{#if (eq system.categorie 'draconic')}}
|
||||||
<input class="competence-xp-sort" type="text" compname="{{name}}" name="comp-xp-sort-{{name}}"
|
<input class="competence-xp-sort" type="text" compname="{{name}}" name="comp-xp-sort-{{name}}"
|
||||||
value="{{numberFormat system.xp_sort decimals=0 sign=false}}" data-dtype="number"
|
value="{{numberFormat system.xp_sort decimals=0 sign=false}}" data-dtype="number"
|
||||||
{{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
|
{{#if (or (not @root.options.vueDetaillee) @root.options.vueArchetype)}}disabled{{/if}} />
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if @root.options.vueDetaillee}}
|
{{#if @root.options.vueDetaillee}}
|
||||||
<div class="item-controls">
|
<div class="item-controls">
|
||||||
@@ -41,7 +42,8 @@
|
|||||||
<i class="far fa-circle"></i>
|
<i class="far fa-circle"></i>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<input class="competence-archetype niveau-archetype" type="text" compname="{{name}}" name="comp-archetype-{{name}}"
|
<input class="competence-archetype niveau-archetype" type="text" compname="{{name}}" name="comp-archetype-{{name}}"
|
||||||
value="{{numberFormat system.niveau_archetype decimals=0 sign=true}}" data-dtype="number"/>
|
value="{{numberFormat system.niveau_archetype decimals=0 sign=true}}" data-dtype="number"
|
||||||
|
{{#if (not @root.options.vueArchetype)}}disabled{{/if}} />
|
||||||
<a class="item-edit" title="Modifier"><i class="fas fa-edit"></i></a>
|
<a class="item-edit" title="Modifier"><i class="fas fa-edit"></i></a>
|
||||||
{{#if @root.options.isGM}}
|
{{#if @root.options.isGM}}
|
||||||
<a class="item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
<a class="item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||||
|
|||||||
@@ -13,18 +13,7 @@
|
|||||||
<span class="generic-label">Total XP compétences</span>
|
<span class="generic-label">Total XP compétences</span>
|
||||||
<span class="competence-value">{{calc.competenceXPTotal}}</span>
|
<span class="competence-value">{{calc.competenceXPTotal}}</span>
|
||||||
</li>
|
</li>
|
||||||
{{#if calc.comptageArchetype}}
|
{{/if}}
|
||||||
<li><hr></li>
|
|
||||||
<li>Niveaux d'archétype à répartir</li>
|
|
||||||
{{#each calc.comptageArchetype as |archetype key|}}
|
|
||||||
{{#if (gt archetype.reste 0)}}
|
|
||||||
<li class="item flexrow">
|
|
||||||
<label class="generic-label">Reste {{archetype.reste}} niveaux {{numberFormat archetype.niveau decimals=0 sign=true}} sur {{archetype.nombreMax}}</label>
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
{{/each}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
<li> </li>
|
<li> </li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
1
templates/chat-actor-turn-acteur.hbs
Normal file
1
templates/chat-actor-turn-acteur.hbs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<h4>C'est au tour de {{alias}} !</h4>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<h4>C'est au tour de {{alias}} !</h4>
|
<h4>Résumé de santé pour {{alias}}</h4>
|
||||||
<div data-combatid="{{combatId}}" data-combatmessage="actor-turn-summary">{{blessuresStatus}}</div>
|
<div data-combatid="{{combatId}}" data-combatmessage="actor-turn-summary">{{blessuresStatus}}</div>
|
||||||
<div>Son état général est de : {{etatGeneral}} {{#if isSonne}} et est <strong>sonné</strong>{{/if}}</div>
|
<div>Son état général est de : {{etatGeneral}} {{#if isSonne}} et est <strong>sonné</strong>{{/if}}</div>
|
||||||
{{#if isGrave}}
|
{{#if isGrave}}
|
||||||
@@ -6,5 +6,7 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if isCritique}}
|
{{#if isCritique}}
|
||||||
<div>{{alias}} souffre d'une <strong>Blessure Critique</strong> : faites un
|
<div>{{alias}} souffre d'une <strong>Blessure Critique</strong> : faites un
|
||||||
<a id="chat-jet-vie" class="chat-card-button" data-actorId="{{actorId}}">Jet de Vie.<a></div>
|
<a class="chat-card-button chat-jet-vie"
|
||||||
|
data-tokenId="{{tokenId}}"
|
||||||
|
data-actorId="{{actorId}}">Jet de Vie.<a></div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" />
|
|
||||||
<h4>
|
|
||||||
{{attackerName}} a empoigné {{defenderName}}
|
|
||||||
</h4>
|
|
||||||
<hr>
|
|
||||||
<div>
|
|
||||||
|
|
||||||
<span class='chat-card-button-area'>
|
|
||||||
Au round suivant l'acquisition des 2 points d'Emp, {{attackerName}} peut faire perdre autant de points d'Endurance qu'il souhaite à {{defenderName}}
|
|
||||||
<br>
|
|
||||||
<a class='empoignade-perte-endurance chat-card-button'>
|
|
||||||
<select class='empoignade-perte-endurance'>
|
|
||||||
<option value="none">Faire perdre de l'endurance (selectionnez)</option>
|
|
||||||
<option value="end0">Endurance à 0</option>
|
|
||||||
<option value="end1">Endurance à 1</option>
|
|
||||||
<option value="endmoitie">La moitié de l'endurance</option>
|
|
||||||
<option value="endquart">Le quart de l'endurance</option>
|
|
||||||
</select>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{{#if empoignade.system.ausol}}
|
|
||||||
|
|
||||||
{{else}}
|
|
||||||
<br>
|
|
||||||
Dès l'acquisition des 2 points d'Emp, {{attackerName}} peut entraîner {{defenderName}} au sol. Les deux protagonistes restent empoignés.
|
|
||||||
<br>
|
|
||||||
<a class='empoignade-entrainer-sol chat-card-button'>
|
|
||||||
Entraîner au sol
|
|
||||||
</a>
|
|
||||||
<br>
|
|
||||||
A la fin du round ou les 2 points d'Emp sont acquis, {{attackerName}} peut projeter {{defenderName}} au sol. Les deux protagonistes ne sont plus empoignés.
|
|
||||||
<br>
|
|
||||||
<a class='empoignade-projeter-sol chat-card-button'>
|
|
||||||
Projeter au sol
|
|
||||||
</a>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" />
|
<img class="chat-icon" src="{{competence.img}}" />
|
||||||
<h4>
|
<h4>
|
||||||
{{attackerName}} a entraîné {{defenderName}} au sol. L'empoignade peut continuer.
|
{{attacker.name}} a entraîné {{defender.name}} au sol
|
||||||
</h4>
|
</h4>
|
||||||
<hr>
|
<hr>
|
||||||
<div>
|
<div>
|
||||||
|
L'empoignade peut continuer.
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
16
templates/chat-empoignade-entrainer.html
Normal file
16
templates/chat-empoignade-entrainer.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<img class="chat-icon" src="{{competence.img}}" />
|
||||||
|
<h4>
|
||||||
|
{{attacker.name}} a empoigné {{defender.name}}
|
||||||
|
</h4>
|
||||||
|
<hr>
|
||||||
|
<div>
|
||||||
|
<span class='chat-card-button-area'>
|
||||||
|
{{attacker.name}} vient d'obtenir 2 points d'Emp, et peut
|
||||||
|
entraîner {{defender.name}} au sol. Les deux protagonistes
|
||||||
|
restent empoignés.
|
||||||
|
<br>
|
||||||
|
<a class='empoignade-entrainer-sol chat-card-button'>
|
||||||
|
Entraîner au sol
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
35
templates/chat-empoignade-immobilise.html
Normal file
35
templates/chat-empoignade-immobilise.html
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<img class="chat-icon" src="{{competence.img}}" />
|
||||||
|
<h4>
|
||||||
|
{{attacker.name}} a empoigné {{defender.name}}
|
||||||
|
</h4>
|
||||||
|
<hr>
|
||||||
|
<div>
|
||||||
|
<span class='chat-card-button-area'>
|
||||||
|
<p>
|
||||||
|
{{attacker.name}} a obtenu 2 points d'Emp à la fin du round précédent, et peut:
|
||||||
|
|
||||||
|
<ul><li>
|
||||||
|
faire perdre des points d'Endurance à {{defender.name}}
|
||||||
|
<br>
|
||||||
|
<a class='empoignade-perte-endurance chat-card-button'>
|
||||||
|
<select class='empoignade-perte-endurance'>
|
||||||
|
<option value="none">Faire perdre de l'endurance (selectionnez)</option>
|
||||||
|
<option value="end0">Endurance à 0</option>
|
||||||
|
<option value="end1">Endurance à 1</option>
|
||||||
|
<option value="endmoitie">La moitié de l'endurance</option>
|
||||||
|
<option value="endquart">Le quart de l'endurance</option>
|
||||||
|
</select>
|
||||||
|
</a>
|
||||||
|
{{#if empoignade.system.ausol}}
|
||||||
|
{{else}}
|
||||||
|
</li><li>
|
||||||
|
projeter {{defender.name}} au sol. Les deux protagonistes ne sont plus empoignés.
|
||||||
|
<br>
|
||||||
|
<a class='empoignade-projeter-sol chat-card-button'>
|
||||||
|
Projeter au sol
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
</li></ul>
|
||||||
|
</p>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" />
|
<img class="chat-icon" src="{{competence.img}}" />
|
||||||
<h4>
|
<h4>
|
||||||
{{attackerName}} a fait perdre de l'endurance à {{defenderName}}, qui reste immobilisé. L'empoignade peut continuer.
|
{{attacker.name}} a fait perdre de l'endurance à {{defender.name}}
|
||||||
</h4>
|
</h4>
|
||||||
<hr>
|
<hr>
|
||||||
<div>
|
<div>
|
||||||
|
{{defender.name}} reste immobilisé. L'empoignade peut continuer.
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" />
|
<img class="chat-icon" src="{{competence.img}}" />
|
||||||
<h4>
|
<h4>
|
||||||
{{attackerName}} a projeté {{defenderName}} au sol. L'empoignade est terminée et a été supprimée.
|
{{attacker.name}} a projeté {{defender.name}} au sol
|
||||||
</h4>
|
</h4>
|
||||||
<hr>
|
<hr>
|
||||||
<div>
|
<div>
|
||||||
|
L'empoignade est terminée et a été supprimée.
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" />
|
<img class="chat-icon" src="{{competence.img}}" />
|
||||||
<h4>
|
<h4>
|
||||||
|
{{log 'rollData' this}}
|
||||||
{{#if (eq mode "empoigner")}}
|
{{#if (eq mode "empoigner")}}
|
||||||
{{attackerName}} tente d'empoigner {{defenderName}}
|
{{attacker.name}} tente d'empoigner {{defender.name}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (eq mode "contrer-empoigner")}}
|
{{#if (eq mode "contrer-empoigner")}}
|
||||||
{{defenderName}} tente de contrer l'empoignade de {{attackerName}}
|
{{defender.name}} tente de contrer l'empoignade de {{attacker.name}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (eq mode "liberer")}}
|
{{#if (eq mode "liberer")}}
|
||||||
{{attackerName}} tente de se libérer de l'empoignade de {{defenderName}}
|
{{attacker.name}} tente de se libérer de l'empoignade de {{defender.name}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (eq mode "contrer-liberer")}}
|
{{#if (eq mode "contrer-liberer")}}
|
||||||
{{defenderName}} tente de contrer la libération de {{attackerName}}
|
{{defender.name}} tente de contrer la libération de {{attacker.name}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</h4>
|
</h4>
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
||||||
@@ -20,7 +21,7 @@
|
|||||||
|
|
||||||
{{#if (gte empoignade.system.pointsemp 2)}}
|
{{#if (gte empoignade.system.pointsemp 2)}}
|
||||||
|
|
||||||
<br><strong>{{defenderName}} est empoigné et immobilisé par {{attackerName}} !</strong>
|
<br><strong>{{defender.name}} est empoigné et immobilisé par {{attacker.name}} !</strong>
|
||||||
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<span class='chat-card-button-area'>
|
<span class='chat-card-button-area'>
|
||||||
@@ -29,16 +30,12 @@
|
|||||||
{{#if (eq mode "empoigner")}}
|
{{#if (eq mode "empoigner")}}
|
||||||
{{#if empoignade.isSuccess}}
|
{{#if empoignade.isSuccess}}
|
||||||
<a class='defense-empoignade-cac chat-card-button'
|
<a class='defense-empoignade-cac chat-card-button'
|
||||||
data-attackerId='{{attacker.id}}'
|
|
||||||
data-defenderId='{{defender.id}}'
|
|
||||||
data-diff-libre='{{diffLibre}}'
|
data-diff-libre='{{diffLibre}}'
|
||||||
data-defense-mode="contrer-empoigner">
|
data-defense-mode="contrer-empoigner">
|
||||||
Contrer l'empoignade (Corps à Corps)
|
Contrer l'empoignade (Corps à Corps)
|
||||||
</a>
|
</a>
|
||||||
{{#if (eq empoignade.system.pointsemp 0)}}
|
{{#if (eq empoignade.system.pointsemp 0)}}
|
||||||
<a class='defense-empoignade-esquive chat-card-button'
|
<a class='defense-empoignade-esquive chat-card-button'
|
||||||
data-attackerId='{{attacker.id}}'
|
|
||||||
data-defenderId='{{defender.id}}'
|
|
||||||
data-diff-libre='{{diffLibre}}'
|
data-diff-libre='{{diffLibre}}'
|
||||||
data-defense-mode="contrer-empoigner">
|
data-defense-mode="contrer-empoigner">
|
||||||
Contrer l'empoignade (Esquive)
|
Contrer l'empoignade (Esquive)
|
||||||
@@ -52,8 +49,6 @@
|
|||||||
{{#if (eq mode "liberer")}}
|
{{#if (eq mode "liberer")}}
|
||||||
{{#if empoignade.isSuccess}}
|
{{#if empoignade.isSuccess}}
|
||||||
<a class='defense-empoignade-cac chat-card-button'
|
<a class='defense-empoignade-cac chat-card-button'
|
||||||
data-attackerId='{{attacker.id}}'
|
|
||||||
data-defenderId='{{defender.id}}'
|
|
||||||
data-diff-libre='{{diffLibre}}'
|
data-diff-libre='{{diffLibre}}'
|
||||||
data-defense-mode="contrer-liberer">
|
data-defense-mode="contrer-liberer">
|
||||||
Contrer la libération (Corps à Corps)
|
Contrer la libération (Corps à Corps)
|
||||||
@@ -78,8 +73,7 @@
|
|||||||
La tentative de contrer la libération est un échec!
|
La tentative de contrer la libération est un échec!
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
</span>
|
||||||
<br>Points d'Emp: {{empoignade.system.pointsemp}}
|
<br>Points d'Emp: {{empoignade.system.pointsemp}}
|
||||||
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" />
|
<img class="chat-icon" src="{{competence.img}}" />
|
||||||
<h4>
|
<h4>
|
||||||
{{attackerName}} tente d'empoigner {{defenderName}}
|
{{attacker.name}} tente d'empoigner {{defender.name}}
|
||||||
</h4>
|
</h4>
|
||||||
<hr>
|
<hr>
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<span class='chat-card-button-area'>
|
<span class='chat-card-button-area'>
|
||||||
<br>
|
<br>
|
||||||
<strong>{{attacker.name}} tente d'empoigner {{defender.name}}, qui est équipé d'une arme de mêlée. {{defender.name}}
|
<strong>{{attacker.name}} tente d'empoigner {{defender.name}}, qui est équipé d'une arme de mêlée. {{defender.name}}
|
||||||
@@ -16,5 +15,5 @@
|
|||||||
data-defenderId='{{defender.id}}'>
|
data-defenderId='{{defender.id}}'>
|
||||||
Poursuivre l'empoignade
|
Poursuivre l'empoignade
|
||||||
</a>
|
</a>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{{#if use.moral}}
|
{{#if use.moral}}
|
||||||
<span>
|
<span>
|
||||||
Vous avez fait appel {{#if (gt moral 0)}}au moral{{else}}à l'énergie du déspoir{{/if}}
|
Vous avez fait appel {{#if (gt moral 0)}}au moral{{else}}à l'énergie du désespoir{{/if}}
|
||||||
{{#if (eq perteMoralEchec 'dissolution')}}et échoué, cous marquez un point de dissolution!.
|
{{#if (eq perteMoralEchec 'dissolution')}}et échoué, cous marquez un point de dissolution!.
|
||||||
{{else if (eq perteMoralEchec 'perte')}}et échoué, votre moral baisse à {{moral}}.
|
{{else if (eq perteMoralEchec 'perte')}}et échoué, votre moral baisse à {{moral}}.
|
||||||
{{else}}et réussi, votre moral reste de {{moral}}.
|
{{else}}et réussi, votre moral reste de {{moral}}.
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" alt="{{oeuvre.system.competence}}" />
|
<img class="chat-icon" src="{{competence.img}}" alt="{{oeuvre.system.competence}}" />
|
||||||
<h4>
|
<h4>
|
||||||
{{alias}} tente de chanter : {{oeuvre.name}} (niveau {{oeuvre.system.niveau}})
|
{{alias}} {{#if rolled.isSuccess}}chante{{else}}tente de chanter{{/if}} {{oeuvre.name}} (niveau {{oeuvre.system.niveau}})
|
||||||
</h4>
|
</h4>
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
||||||
<hr>
|
<hr>
|
||||||
<div>
|
<div>
|
||||||
{{#if rolled.isSuccess}}
|
{{#if rolled.isSuccess}}
|
||||||
{{alias}} réussi son interprétation avec une qualité de {{qualiteFinale}} .
|
{{alias}} réussit son interprétation avec une qualité de {{qualiteFinale}} .
|
||||||
{{else}}
|
{{else}}
|
||||||
{{alias}} est peu inspiré(e) et son interprétation a une qualité de {{qualiteFinale}}.
|
{{alias}} manque d'inspiration, son interprétation a une qualité de {{qualiteFinale}}.
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" alt="{{oeuvre.system.competence}}" />
|
<img class="chat-icon" src="{{competence.img}}" alt="{{oeuvre.system.competence}}" />
|
||||||
<h4>
|
<h4>
|
||||||
{{alias}} tente de danser : {{oeuvre.name}} (niveau {{oeuvre.system.niveau}})
|
{{alias}} {{#if rolled.isSuccess}}danse{{else}}tente de danser{{/if}} {{oeuvre.name}} (niveau {{oeuvre.system.niveau}})
|
||||||
</h4>
|
</h4>
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
||||||
<hr>
|
<hr>
|
||||||
<div>
|
<div>
|
||||||
{{#if rolled.isSuccess}}
|
{{#if rolled.isSuccess}}
|
||||||
{{alias}} réussi son interprétation avec une qualité de {{qualiteFinale}} .
|
{{alias}} réussit son interprétation avec une qualité de {{qualiteFinale}} .
|
||||||
{{else}}
|
{{else}}
|
||||||
{{alias}} est peu inspiré(e) et son interprétation a une qualité de {{qualiteFinale}}.
|
{{alias}} manque d'inspiration, son interprétation a une qualité de {{qualiteFinale}}.
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
{{#if (eq dmg.mortalite 'entiteincarnee')}}subit le coup
|
{{#if (eq dmg.mortalite 'entiteincarnee')}}subit le coup
|
||||||
{{else if mort}}vient de mourir
|
{{else if mort}}vient de mourir
|
||||||
{{else if blessure}}
|
{{else if blessure}}
|
||||||
{{#if (gt blessure.system.gravite 0)}}subit une blessure {{blessure.system.labelGravite}}
|
{{#if (gt blessure.system.gravite 0)}}subit une blessure {{blessure.system.label}}
|
||||||
{{else}}subit une contusion
|
{{else}}subit une contusion
|
||||||
{{~/if~}}
|
{{~/if~}}
|
||||||
{{else}}s'en sort sans une égratignure
|
{{else}}s'en sort sans une égratignure
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
{{#if (ne dmg.mortalite 'entiteincarnee')}}
|
{{#if (ne dmg.mortalite 'entiteincarnee')}}
|
||||||
{{#if (gt endurance 1)}}et
|
{{#if (gt endurance 1)}}et
|
||||||
{{#if sonne}}est <strong>sonné</strong><img class="chat-icon" src="icons/svg/stoned.svg" alt="charge" height="16" width="16" /> jusqu'à la fin du prochain round{{else}}n'est pas sonné{{/if}}!
|
{{#if sonne}}est <strong>sonné</strong><img class="chat-icon" src="icons/svg/stoned.svg" alt="charge" height="16" width="16" /> jusqu'à la fin du prochain round{{else}}n'est pas sonné{{/if}}!
|
||||||
{{#if hasPlayerOwner}}Jet d'endurance : Jet d'endurance : {{jetEndurance}} / {{resteEndurance}}{{/if}}
|
{{#if hasPlayerOwner}}Jet d'endurance : {{jetEndurance}} / {{resteEndurance}}{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" alt="{{oeuvre.system.competence}}" />
|
<img class="chat-icon" src="{{competence.img}}" alt="{{oeuvre.system.competence}}" />
|
||||||
<h4>
|
<h4>
|
||||||
{{alias}} tente de jouer le morceau : {{oeuvre.name}} (niveau {{oeuvre.system.niveau}})
|
{{alias}} {{#if rolled.isSuccess}}interprete{{else}}tente de jouer{{/if}} le morceau : {{oeuvre.name}} (niveau {{oeuvre.system.niveau}})
|
||||||
</h4>
|
</h4>
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
||||||
<hr>
|
<hr>
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
{{#if rolled.isSuccess}}
|
{{#if rolled.isSuccess}}
|
||||||
{{alias}} réussit son interprétation avec une qualité de {{qualiteFinale}} .
|
{{alias}} réussit son interprétation avec une qualité de {{qualiteFinale}} .
|
||||||
{{else}}
|
{{else}}
|
||||||
{{alias}} est peu inspiré(e) et son interprétation a une qualité de {{qualiteFinale}}.
|
{{alias}} manque d'inspiration, son interprétation a une qualité de {{qualiteFinale}}.
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
<hr>
|
<hr>
|
||||||
<div>
|
<div>
|
||||||
{{#if rolled.isSuccess}}
|
{{#if rolled.isSuccess}}
|
||||||
{{alias}} réussi son interprétation avec une qualité de {{qualiteFinale}} .
|
{{alias}} réussit son interprétation avec une qualité de {{qualiteFinale}} .
|
||||||
{{else}}
|
{{else}}
|
||||||
{{alias}} est peu inspiré(e) et son interprétation a une qualité de {{qualiteFinale}}.
|
{{alias}} manque d'inspiration, son interprétation a une qualité de {{qualiteFinale}}.
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<img class="chat-icon" src="{{competence.img}}" alt="{{oeuvre.system.competence}}" />
|
<img class="chat-icon" src="{{competence.img}}" alt="{{oeuvre.system.competence}}" />
|
||||||
<h4>
|
<h4>
|
||||||
{{alias}} tente de cuisiner la recette : {{oeuvre.name}} (niveau {{oeuvre.system.niveau}})
|
{{alias}} {{#if rolled.isSuccess}}réalise{{else}}tente de cuisiner{{/if}} la recette : {{oeuvre.name}} (niveau {{oeuvre.system.niveau}})
|
||||||
</h4>
|
</h4>
|
||||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
||||||
<hr>
|
<hr>
|
||||||
|
|||||||
@@ -1,13 +1,29 @@
|
|||||||
<form class="skill-roll-dialog">
|
<form class="skill-roll-dialog">
|
||||||
|
<img class="chat-icon" src="{{competence.img}}" alt="{{competence.name}}"/>
|
||||||
<h2 class="dialog-roll-title"></h2>
|
<h2 class="dialog-roll-title"></h2>
|
||||||
|
|
||||||
<div class="grid grid-2col">
|
<div class="grid grid-2col">
|
||||||
<div class="flex-group-left">
|
<div class="flex-group-left">
|
||||||
<img class="chat-icon" src="{{competence.img}}" alt="{{competence.name}}"/>
|
|
||||||
<div class="flexrow">
|
<div class="flexrow">
|
||||||
<label>Caractéristique</label>
|
<label>Caractéristique</label>
|
||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-select-carac.html"}}
|
<span>
|
||||||
|
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-select-carac.html"}}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
{{#if targetToken}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<label>Cible:</label>
|
||||||
|
<label>
|
||||||
|
<img class="sheet-competence-img" src="{{targetToken.img}}" title="{{targetToken.name}}" />
|
||||||
|
{{targetToken.name}}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if ajustements.attaqueDefenseurSurpris.used}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<label>{{ajustements.attaqueDefenseurSurpris.label}}</label>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
{{#if arme}}
|
{{#if arme}}
|
||||||
{{#if attackerRoll}}
|
{{#if attackerRoll}}
|
||||||
{{#if attackerRoll.tactique}}
|
{{#if attackerRoll.tactique}}
|
||||||
@@ -27,41 +43,28 @@
|
|||||||
<div class="tooltiptext ttt-ajustements">
|
<div class="tooltiptext ttt-ajustements">
|
||||||
<div>
|
<div>
|
||||||
<strong>Charge</strong> : Les longueurs d'armes n'interviennent pas dans la charge, il faut gérer une initiative aléatoire dans ce cas.
|
<strong>Charge</strong> : Les longueurs d'armes n'interviennent pas dans la charge, il faut gérer une initiative aléatoire dans ce cas.
|
||||||
<br><strong>Feinte</strong> : Vous devez avoir l'initative sur votre adversaire et y renoncer.
|
<br>
|
||||||
|
<strong>Feinte</strong> : Vous devez avoir l'initative sur votre adversaire et y renoncer.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
|
||||||
{{#if targetToken}}
|
|
||||||
<div class="flexrow">
|
|
||||||
Cible: {{targetToken.name}}
|
|
||||||
<img class="sheet-competence-img" src="{{targetToken.img}}" title="{{targetToken.name}}" />
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
{{#if ajustements.attaqueDefenseurSurpris.used}}
|
|
||||||
<div class="flexrow">
|
|
||||||
<label>{{ajustements.attaqueDefenseurSurpris.label}}</label>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#unless attackerRoll}}
|
|
||||||
<div class="flexrow">
|
<div class="flexrow">
|
||||||
<label>Dégats:</label>
|
<label>Dégats:</label>
|
||||||
{{#if (eq arme.system.mortalite 'non-mortel')}}
|
{{#if (eq arme.system.mortalite 'empoignade')}}
|
||||||
<label class="dmg-arme-actor"></label>
|
|
||||||
{{else if (eq arme.system.mortalite 'empoignade')}}
|
|
||||||
<label>Empoignade</label>
|
<label>Empoignade</label>
|
||||||
{{else}}
|
{{else}}
|
||||||
<span>
|
<span>
|
||||||
<input class="attribute-value" type="checkbox" name="coupsNonMortels" {{#unless (eq mortalite 'mortel')}}checked{{/unless}} />
|
{{#unless (eq arme.system.mortalite 'non-mortel')}}
|
||||||
<label class="dmg-arme-actor"></label>
|
<input class="attribute-value check-mortalite" type="checkbox" name="mortalite" {{#unless (eq mortalite 'mortel')}}checked{{/unless}} />
|
||||||
|
{{/unless}}
|
||||||
|
<label class="dmg-arme-actor" name="dmg-arme-actor"></label> (<label class="arme-mortalite" name="arme-mortalite"></label>)
|
||||||
</span>
|
</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/unless}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
<div class="flexrow"></div>
|
||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-surenc.html"}}
|
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-surenc.html"}}
|
||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-enctotal.html"}}
|
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-enctotal.html"}}
|
||||||
</div>
|
</div>
|
||||||
@@ -75,6 +78,7 @@
|
|||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffCondition.html"}}
|
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffCondition.html"}}
|
||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-forcer.html"}}
|
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-forcer.html"}}
|
||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-moral.html"}}
|
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-moral.html"}}
|
||||||
|
<div class="flexrow"></div>
|
||||||
<div class="placeholder-ajustements" class="flexrow"></div>
|
<div class="placeholder-ajustements" class="flexrow"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<form class="skill-roll-dialog">
|
<form class="skill-roll-dialog">
|
||||||
<h2>
|
<h2>
|
||||||
{{defenderName}} tente de contrer l'empoignade de {{attackerName}}
|
{{defender.name}} tente de contrer l'empoignade de {{attacker.name}}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="grid grid-2col">
|
<div class="grid grid-2col">
|
||||||
<div class="flex-group-left">
|
<div class="flex-group-left">
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
<form class="tmr-dialog">
|
<form class="tmr-dialog">
|
||||||
<h2 class="comptmrdialog" id="tmrDialogTitle"></h2>
|
<h2 class="comptmrdialog" id="tmrDialogTitle" style="visibility: hidden;"></h2>
|
||||||
|
<table>
|
||||||
<table id="tmrsheet">
|
<tr class="tmr-row">
|
||||||
<tr id="tmrrow1">
|
|
||||||
<td>
|
<td>
|
||||||
{{#if (eq mode "visu")}}
|
{{#if (eq mode "visu")}}
|
||||||
<div class="flex-group-center">
|
<div class="flex-group-center">
|
||||||
@@ -54,6 +53,5 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
3
templates/enum-mortalite.html
Normal file
3
templates/enum-mortalite.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<option value="mortel">Mortel</option>
|
||||||
|
<option value="non-mortel">Non mortel</option>
|
||||||
|
<option value="empoignade">Empoignade</option>
|
||||||
@@ -37,6 +37,14 @@
|
|||||||
<label for="system.dommages">Dommages </label>
|
<label for="system.dommages">Dommages </label>
|
||||||
<input class="attribute-value" type="text" name="system.dommages" value="{{system.dommages}}" data-dtype="String"/>
|
<input class="attribute-value" type="text" name="system.dommages" value="{{system.dommages}}" data-dtype="String"/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="system.mortalite">Mortalité</label>
|
||||||
|
<select name="system.mortalite" data-dtype="String">
|
||||||
|
{{#select system.mortalite}}
|
||||||
|
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-mortalite.html"}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="system.resistance">Résistance </label>
|
<label for="system.resistance">Résistance </label>
|
||||||
<input class="attribute-value" type="text" name="system.resistance" value="{{system.resistance}}" data-dtype="Number"/>
|
<input class="attribute-value" type="text" name="system.resistance" value="{{system.resistance}}" data-dtype="Number"/>
|
||||||
|
|||||||
@@ -27,6 +27,14 @@
|
|||||||
<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>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="system.mortalite">Mortalité</label>
|
||||||
|
<select name="system.mortalite" data-dtype="String">
|
||||||
|
{{#select system.mortalite}}
|
||||||
|
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-mortalite.html"}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if isparade}}
|
{{#if isparade}}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div class="horloge-digitale">
|
<div class="horloge-digitale">
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
<a class="toggle-horloge-analogique">
|
<a class="toggle-horloge-analogique">
|
||||||
{{#if horlogeAnalogique}}
|
{{#if horlogeAnalogique}}
|
||||||
@@ -33,6 +34,15 @@
|
|||||||
{{#if isGM}}
|
{{#if isGM}}
|
||||||
<span class="calendar-minute-texte">{{minute}} minutes</span>
|
<span class="calendar-minute-texte">{{minute}} minutes</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
{{#if isGM}}
|
||||||
|
<span class="toggle-auto-darkness">
|
||||||
|
{{#if autoDarkness}}
|
||||||
|
<i class="fa-solid fa-lightbulb"></i>
|
||||||
|
{{else}}
|
||||||
|
<i class="fa-regular fa-lightbulb"></i>
|
||||||
|
{{/if}}
|
||||||
|
</span>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<div class="horloge-analogique {{#unless horlogeAnalogique}}horloge-analogique-hidden{{/unless}}">
|
<div class="horloge-analogique {{#unless horlogeAnalogique}}horloge-analogique-hidden{{/unless}}">
|
||||||
{{> 'systems/foundryvtt-reve-de-dragon/templates/time/horloge.hbs' }}
|
{{> 'systems/foundryvtt-reve-de-dragon/templates/time/horloge.hbs' }}
|
||||||
|
|||||||
Reference in New Issue
Block a user