Compare commits
81 Commits
foundryvtt
...
foundryvtt
Author | SHA1 | Date | |
---|---|---|---|
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 |
89
changelog.md
89
changelog.md
@ -1,4 +1,93 @@
|
||||
# v11.0
|
||||
## 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
|
||||
|
@ -7,7 +7,7 @@ import { Misc } from "./misc.js";
|
||||
import { RdDCombatManager } from "./rdd-combat.js";
|
||||
import { RdDCarac } from "./rdd-carac.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 { STATUSES } from "./settings/status-effects.js";
|
||||
import { MAINS_DIRECTRICES } from "./actor.js";
|
||||
@ -33,7 +33,8 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
|
||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }],
|
||||
showCompNiveauBase: false,
|
||||
vueDetaillee: false
|
||||
vueDetaillee: false,
|
||||
vueArchetype: false,
|
||||
});
|
||||
}
|
||||
|
||||
@ -56,6 +57,7 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
||||
resumeBlessures: this.actor.computeResumeBlessure(this.actor.system.blessures),
|
||||
caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute),
|
||||
surEncombrementMessage: this.actor.getMessageSurEncombrement(),
|
||||
malusArmure: this.actor.getMalusArmure()
|
||||
})
|
||||
|
||||
this.timerRecherche = undefined;
|
||||
@ -79,9 +81,12 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
||||
});
|
||||
|
||||
// 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.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.combat = RdDCombatManager.listActionsArmes(formData.combat, formData.competences, formData.system.carac);
|
||||
formData.empoignades = this.actor.getEmpoignades();
|
||||
@ -114,7 +119,7 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
||||
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
|
||||
if (!this.options.editable) return;
|
||||
@ -353,12 +358,19 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
||||
let compName = event.currentTarget.attributes.compname.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
|
||||
this.html.find('.competence-archetype').change(async event => {
|
||||
let compName = event.currentTarget.attributes.compname.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.options.showCompNiveauBase = !this.options.showCompNiveauBase;
|
||||
|
239
module/actor.js
239
module/actor.js
@ -18,7 +18,7 @@ import { RdDAlchimie } from "./rdd-alchimie.js";
|
||||
import { STATUSES, StatusEffects } from "./settings/status-effects.js";
|
||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||
import { RdDItemSigneDraconique } from "./item/signedraconique.js";
|
||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
||||
import { Draconique } from "./tmr/draconique.js";
|
||||
import { RdDCarac } from "./rdd-carac.js";
|
||||
@ -95,7 +95,6 @@ export class RdDActor extends RdDBaseActor {
|
||||
this.computeIsHautRevant();
|
||||
await this.cleanupConteneurs();
|
||||
await this.computeEncTotal();
|
||||
await this.computeMalusArmure();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -134,7 +133,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getFatigueActuelle() {
|
||||
if (ReglesOptionelles.isUsing("appliquer-fatigue") && this.isPersonnage()) {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && this.isPersonnage()) {
|
||||
return this.system.sante.fatigue?.value;
|
||||
}
|
||||
return 0;
|
||||
@ -218,7 +217,12 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getMalusArmure() {
|
||||
return Misc.toInt(this.system.attributs?.malusarmure?.value)
|
||||
if (this.isPersonnage()) {
|
||||
return this.itemTypes[TYPES.armure].filter(it => it.system.equipe)
|
||||
.map(it => it.system.malus)
|
||||
.reduce(Misc.sum(), 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -228,12 +232,21 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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")
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getTache(id) {
|
||||
return this.findItemLike(id, 'tache');
|
||||
@ -261,7 +274,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getDraconicList() {
|
||||
return this.items.filter(it => it.isCompetencePersonnage() && it.system.categorie == 'draconic')
|
||||
return this.itemTypes[TYPES.competence].filter(it => it.system.categorie == 'draconic')
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getBestDraconic() {
|
||||
@ -271,26 +284,26 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
|
||||
getDraconicOuPossession() {
|
||||
const possession = this.items.filter(it => it.type == TYPES.competencecreature && it.system.categorie == 'possession')
|
||||
const possession = this.itemTypes[TYPES.competencecreature].filter(it => it.system.categorie == 'possession')
|
||||
.sort(Misc.descending(it => it.system.niveau))
|
||||
.find(it => true);
|
||||
if (possession) {
|
||||
return possession.clone();
|
||||
return possession;
|
||||
}
|
||||
const draconics = [...this.getDraconicList().filter(it => it.system.niveau >= 0).map(it => it.clone()),
|
||||
const draconics = [...this.getDraconicList().filter(it => it.system.niveau >= 0),
|
||||
POSSESSION_SANS_DRACONIC]
|
||||
.sort(Misc.descending(it => it.system.niveau));
|
||||
return draconics[0];
|
||||
}
|
||||
|
||||
getPossession(possessionId) {
|
||||
return this.items.find(it => it.type == TYPES.possession && it.system.possessionid == possessionId);
|
||||
return this.itemTypes[TYPES.possession].find(it => it.system.possessionid == possessionId);
|
||||
}
|
||||
getPossessions() {
|
||||
return this.items.filter(it => it.type == TYPES.possession);
|
||||
return this.itemTypes[TYPES.possession];
|
||||
}
|
||||
getEmpoignades() {
|
||||
return this.items.filter(it => it.type == TYPES.empoignade);
|
||||
return this.itemTypes[TYPES.empoignade];
|
||||
}
|
||||
getDemiReve() {
|
||||
return this.system.reve.tmrpos.coord;
|
||||
@ -365,7 +378,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
async _openRollDialog({ name, label, template, rollData, callbackAction }) {
|
||||
const dialog = await RdDRoll.create(this, rollData,
|
||||
{ html: template },
|
||||
{ html: template, close: html => { this.tmrApp?.restoreTMRAfterAction() } },
|
||||
{
|
||||
name: name,
|
||||
label: label,
|
||||
@ -376,6 +389,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
]
|
||||
});
|
||||
dialog.render(true);
|
||||
return dialog
|
||||
}
|
||||
|
||||
|
||||
@ -387,6 +401,14 @@ export class RdDActor extends RdDBaseActor {
|
||||
await this.distribuerStress('stress', consigne.stress.valeur, consigne.stress.motif);
|
||||
}
|
||||
await this.update({ 'system.sommeil': consigne.sommeil })
|
||||
const player = this.findPlayer();
|
||||
if (player) {
|
||||
ChatUtility.notifyUser(player.id, 'info', `Vous pouvez gérer la nuit de ${this.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
findPlayer() {
|
||||
return game.users.players.find(player => player.active && player.character?.id == this.id);
|
||||
}
|
||||
|
||||
async onTimeChanging(oldTimestamp, newTimestamp) {
|
||||
@ -457,7 +479,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async dormirChateauDormant() {
|
||||
if (!ReglesOptionelles.isUsing("chateau-dormant-gardien") || !this.system.sommeil || this.system.sommeil.nouveaujour) {
|
||||
if (!ReglesOptionnelles.isUsing("chateau-dormant-gardien") || !this.system.sommeil || this.system.sommeil.nouveaujour) {
|
||||
const message = {
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
|
||||
content: ""
|
||||
@ -533,7 +555,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
/* -------------------------------------------- */
|
||||
async _recuperationBlessures(message, isMaladeEmpoisonne) {
|
||||
const timestamp = game.system.rdd.calendrier.getTimestamp()
|
||||
const blessures = this.filterItems(it => it.system.gravite > 0, 'blessure').sort(Misc.ascending(it => it.system.gravite))
|
||||
const blessures = this.filterItems(it => it.system.gravite > 0, TYPES.blessure).sort(Misc.ascending(it => it.system.gravite))
|
||||
|
||||
await Promise.all(blessures.map(b => b.recuperationBlessure({
|
||||
actor: this,
|
||||
@ -547,7 +569,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
|
||||
async supprimerBlessures(filterToDelete) {
|
||||
const toDelete = this.filterItems(filterToDelete, 'blessure')
|
||||
const toDelete = this.filterItems(filterToDelete, TYPES.blessure)
|
||||
.map(it => it.id);
|
||||
await this.deleteEmbeddedDocuments('Item', toDelete);
|
||||
}
|
||||
@ -555,7 +577,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
/* -------------------------------------------- */
|
||||
async _recupererVie(message, isMaladeEmpoisonne) {
|
||||
const tData = this.system
|
||||
let blessures = this.filterItems(it => it.system.gravite > 0, 'blessure');
|
||||
let blessures = this.filterItems(it => it.system.gravite > 0, TYPES.blessure);
|
||||
if (blessures.length > 0) {
|
||||
return
|
||||
}
|
||||
@ -621,21 +643,22 @@ export class RdDActor extends RdDBaseActor {
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
|
||||
content: this.name + ': '
|
||||
};
|
||||
await this.recupereEndurance(message);
|
||||
if (this.system.sommeil?.insomnie || heures == 0) {
|
||||
const insomnie = this.system.sommeil?.insomnie || heures == 0;
|
||||
await this.recupereEndurance({ message: message, demi: insomnie });
|
||||
if (insomnie) {
|
||||
message.content += 'Vous ne trouvez pas le sommeil';
|
||||
}
|
||||
else {
|
||||
let jetsReve = [];
|
||||
let dormi = await this.dormirDesHeures(jetsReve, message, heures, options);
|
||||
message.content += `Vous dormez ${dormi.heures <= 1 ? 'une heure' : (dormi.heures + ' heures')}. `;
|
||||
if (jetsReve.length > 0) {
|
||||
message.content += `Vous récupérez ${jetsReve.filter(it => it >= 0).reduce(Misc.joining("+"))} Points de rêve. `;
|
||||
message.content += `Vous récupérez ${jetsReve.map(it => it < 0 ? '(dragon)' : it).reduce(Misc.joining("+"))} Points de rêve. `;
|
||||
}
|
||||
if (dormi.etat == 'eveil') {
|
||||
message.content += 'Vous êtes réveillé par un Rêve de Dragon.'
|
||||
await this.reveilReveDeDragon(message, dormi.heures);
|
||||
}
|
||||
options.chateauDormant = options.chateauDormant && dormi.heures >= heures;
|
||||
message.content += `Vous avez dormi ${dormi.heures <= 1 ? 'une heure' : (dormi.heures + ' heures')}. `;
|
||||
}
|
||||
|
||||
if (!options.grisReve) {
|
||||
@ -649,6 +672,14 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
}
|
||||
|
||||
async reveilReveDeDragon(message, heures) {
|
||||
message.content += 'Vous êtes réveillé par un Rêve de Dragon.';
|
||||
const restant = Math.max(this.system.sommeil?.heures - heures, 0)
|
||||
if (restant > 0) {
|
||||
await this.update({ 'system.sommeil': { heures: restant } });
|
||||
}
|
||||
}
|
||||
|
||||
async dormirDesHeures(jetsReve, message, heures, options) {
|
||||
const dormi = { heures: 0, etat: 'dort' };
|
||||
for (; dormi.heures < heures && dormi.etat == 'dort'; dormi.heures++) {
|
||||
@ -702,8 +733,13 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async recupereEndurance(message) {
|
||||
const manquant = this._computeEnduranceMax() - this.system.sante.endurance.value;
|
||||
async recupereEndurance({ message, demi }) {
|
||||
let max = this._computeEnduranceMax();
|
||||
if (demi) {
|
||||
max = Math.floor(max / 2);
|
||||
}
|
||||
const manquant = max - this.system.sante.endurance.value;
|
||||
|
||||
if (manquant > 0) {
|
||||
await this.santeIncDec("endurance", manquant);
|
||||
message.content += `Vous récuperez ${manquant} points d'endurance. `;
|
||||
@ -712,7 +748,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async recupererFatigue(message) {
|
||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||
let fatigue = this.system.sante.fatigue.value;
|
||||
const fatigueMin = this._computeFatigueMin();
|
||||
if (fatigue <= fatigueMin) {
|
||||
@ -820,7 +856,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
system: { sortid: sort._id, draconic: (draconic?.name ?? sort.system.draconic), ptreve: ptreve, coord: coord, heurecible: 'Vaisseau' }
|
||||
}],
|
||||
{ renderSheet: false });
|
||||
this.currentTMR.updateTokens();
|
||||
this.tmrApp.updateTokens();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -1092,7 +1128,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
case 'entite': case 'vehicule':
|
||||
return 0;
|
||||
}
|
||||
return Math.min(0, this.getEncombrementMax() - Math.ceil(Number(this.getEncTotal())));
|
||||
return Math.min(0, Math.floor(this.getEncombrementMax() - this.encTotal));
|
||||
}
|
||||
|
||||
getMessageSurEncombrement() {
|
||||
@ -1120,20 +1156,6 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async computeMalusArmure() {
|
||||
if (this.isPersonnage()) {
|
||||
const malusArmure = this.filterItems(it => it.type == 'armure' && it.system.equipe)
|
||||
.map(it => it.system.malus ?? 0)
|
||||
.reduce(Misc.sum(), 0);
|
||||
// Mise à jour éventuelle du malus armure
|
||||
if (this.system.attributs?.malusarmure?.value != malusArmure) {
|
||||
await this.updateAttributeValue("malusarmure", malusArmure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
computeResumeBlessure() {
|
||||
const blessures = this.filterItems(it => it.system.gravite > 0, 'blessure')
|
||||
@ -1178,7 +1200,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
// Pour les autres
|
||||
let state = Math.min(this.system.sante.vie.value - this.system.sante.vie.max, 0);
|
||||
if (ReglesOptionelles.isUsing("appliquer-fatigue") && this.system.sante.fatigue) {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && this.system.sante.fatigue) {
|
||||
state += RdDUtility.currentFatigueMalus(this.system.sante.fatigue.value, this.system.sante.endurance.max);
|
||||
}
|
||||
// Ajout de l'éthylisme
|
||||
@ -1395,9 +1417,9 @@ export class RdDActor extends RdDBaseActor {
|
||||
await this.deleteEmbeddedDocuments('Item', obsoletes);
|
||||
}
|
||||
|
||||
async $finDeRoundEmpoignade(){
|
||||
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,
|
||||
immobilisations.forEach(emp => RdDEmpoignade.onImmobilisation(this,
|
||||
game.actors.get(emp.system.empoigneid),
|
||||
emp
|
||||
))
|
||||
@ -1505,7 +1527,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async santeIncDec(name, inc, isCritique = false) {
|
||||
if (name == 'fatigue' && !ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
||||
if (name == 'fatigue' && !ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||
return;
|
||||
}
|
||||
const sante = duplicate(this.system.sante)
|
||||
@ -1547,7 +1569,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
compteur.value = result.newValue;
|
||||
// If endurance lost, then the same amount of fatigue cannot be recovered
|
||||
if (ReglesOptionelles.isUsing("appliquer-fatigue") && sante.fatigue && fatigue > 0) {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && sante.fatigue && fatigue > 0) {
|
||||
sante.fatigue.value = Math.max(sante.fatigue.value + fatigue, this._computeFatigueMin());
|
||||
}
|
||||
await this.update({ "system.sante": sante })
|
||||
@ -1706,6 +1728,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
await this.rollTache(tache.id);
|
||||
}
|
||||
}
|
||||
|
||||
async actionHerbe(item, onActionItem = async () => { }) {
|
||||
if (item.isHerbeAPotion()) {
|
||||
return DialogFabriquerPotion.create(this, item, onActionItem);
|
||||
@ -1728,6 +1751,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
async consommerNourritureboisson(itemId, choix = { doses: 1, seForcer: false, supprimerSiZero: false }, userId = undefined) {
|
||||
if (userId != undefined && userId != game.user.id) {
|
||||
RdDBaseActor.remoteActorCall({
|
||||
tokenId: this.token?.id,
|
||||
actorId: this.id,
|
||||
method: 'consommerNourritureboisson',
|
||||
args: [itemId, choix, userId]
|
||||
@ -2124,12 +2148,11 @@ export class RdDActor extends RdDBaseActor {
|
||||
ui.notifications.info(`Aucun sort disponible en ${TMRUtility.getTMR(coord).label} !`);
|
||||
return;
|
||||
}
|
||||
if (this.currentTMR) this.currentTMR.minimize(); // Hide
|
||||
|
||||
const draconicList = this.computeDraconicAndSortIndex(sorts);
|
||||
const reve = duplicate(this.system.carac.reve);
|
||||
|
||||
await this._openRollDialog({
|
||||
const dialog = await this._openRollDialog({
|
||||
name: 'lancer-un-sort',
|
||||
label: 'Lancer un sort',
|
||||
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html',
|
||||
@ -2145,8 +2168,12 @@ export class RdDActor extends RdDBaseActor {
|
||||
diffLibre: RdDItemSort.getDifficulte(sorts[0], -7), // Per default at startup
|
||||
coutreve: Array(30).fill().map((item, index) => 1 + index),
|
||||
},
|
||||
callbackAction: r => this._rollUnSortResult(r)
|
||||
callbackAction: async r => {
|
||||
await this._rollUnSortResult(r);
|
||||
if (!r.isSortReserve) this.tmrApp?.close();
|
||||
}
|
||||
});
|
||||
this.tmrApp?.setTMRPendingAction(dialog);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -2237,17 +2264,11 @@ export class RdDActor extends RdDBaseActor {
|
||||
reveActuel = Math.max(reveActuel - rollData.depenseReve, 0);
|
||||
await this.update({ "system.reve.reve.value": reveActuel });
|
||||
|
||||
if (rollData.isSortReserve) {
|
||||
this.currentTMR.maximize(); // Re-display TMR
|
||||
} else {
|
||||
this.currentTMR.close(); // Close TMR !
|
||||
}
|
||||
// Final chat message
|
||||
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-sort.html');
|
||||
|
||||
if (reveActuel == 0) { // 0 points de reve
|
||||
ChatMessage.create({ content: this.name + " est réduit à 0 Points de Rêve, et tombe endormi !" });
|
||||
closeTMR = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2322,16 +2343,14 @@ export class RdDActor extends RdDBaseActor {
|
||||
/* -------------------------------------------- */
|
||||
async rollCompetence(idOrName, options = { tryTarget: true }) {
|
||||
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||
let rollData = {
|
||||
carac: this.system.carac,
|
||||
competence: this.getCompetence(idOrName)
|
||||
}
|
||||
if (rollData.competence.type == TYPES.competencecreature) {
|
||||
const arme = RdDItemCompetenceCreature.armeCreature(rollData.competence)
|
||||
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, rollData.competence)
|
||||
RdDPossession.onAttaquePossession(target, this, competence)
|
||||
}
|
||||
else {
|
||||
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme)
|
||||
@ -2345,7 +2364,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
await this._openRollDialog({
|
||||
name: 'jet-competence',
|
||||
label: 'Jet ' + Grammar.apostrophe('de', rollData.competence.name),
|
||||
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)
|
||||
@ -2449,7 +2468,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
/* -------------------------------------------- */
|
||||
async _tacheResult(rollData, options) {
|
||||
// Mise à jour de la tache
|
||||
rollData.appliquerFatigue = ReglesOptionelles.isUsing("appliquer-fatigue");
|
||||
rollData.appliquerFatigue = ReglesOptionnelles.isUsing("appliquer-fatigue");
|
||||
rollData.tache = duplicate(rollData.tache);
|
||||
rollData.tache.system.points_de_tache_courant += rollData.rolled.ptTache;
|
||||
if (rollData.rolled.isETotal) {
|
||||
@ -2709,8 +2728,6 @@ export class RdDActor extends RdDBaseActor {
|
||||
ui.notifications.info(`Aucun signe draconiques en ${coord} !`);
|
||||
return;
|
||||
}
|
||||
if (this.currentTMR) this.currentTMR.minimize(); // Hide
|
||||
|
||||
let draconicList = this.getDraconicList()
|
||||
.map(draconic => {
|
||||
let draconicLecture = duplicate(draconic);
|
||||
@ -2733,7 +2750,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
const dialog = await RdDRoll.create(this, rollData,
|
||||
{
|
||||
html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-signedraconique.html',
|
||||
close: html => { this.currentTMR.maximize() } // Re-display TMR
|
||||
close: html => { this.tmrApp?.restoreTMRAfterAction() }
|
||||
},
|
||||
{
|
||||
name: 'lire-signe-draconique',
|
||||
@ -2745,6 +2762,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
);
|
||||
dialog.render(true);
|
||||
this.tmrApp?.setTMRPendingAction(dialog);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -2763,7 +2781,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
await this.deleteEmbeddedDocuments("Item", [rollData.signe._id]);
|
||||
await RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-lecture-signedraconique.html');
|
||||
this.currentTMR.close();
|
||||
this.tmrApp.close();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -2998,8 +3016,8 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
refreshTMRView() {
|
||||
if (this.currentTMR) {
|
||||
this.currentTMR.externalRefresh();
|
||||
if (this.tmrApp) {
|
||||
this.tmrApp.externalRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3007,6 +3025,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
async displayTMR(mode = "normal") {
|
||||
if (this.tmrApp) {
|
||||
ui.notifications.warn("Vous êtes déja dans les TMR....");
|
||||
this.tmrApp.forceTMRDisplay();
|
||||
return
|
||||
}
|
||||
if (mode != 'visu' && this.getEffect(STATUSES.StatusDemiReve)) {
|
||||
@ -3052,34 +3071,59 @@ export class RdDActor extends RdDBaseActor {
|
||||
hasPlayerOwner: this.hasPlayerOwner
|
||||
}
|
||||
|
||||
this.currentTMR = await RdDTMRDialog.create(this, tmrFormData);
|
||||
this.currentTMR.render(true);
|
||||
this.tmrApp = await RdDTMRDialog.create(this, tmrFormData);
|
||||
this.tmrApp.render(true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
rollArme(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
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/**
|
||||
*
|
||||
* @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 compétence ${arme.system.competence} sans choisir de cible valide?
|
||||
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(arme.system.competence, { tryTarget: false })
|
||||
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(arme.system.competence)
|
||||
const competence = this.getCompetence(compToUse)
|
||||
//console.log("RollArme", competence, arme)
|
||||
if (competence.isCompetencePossession()) {
|
||||
return RdDPossession.onAttaquePossession(target, this, competence);
|
||||
}
|
||||
@ -3108,7 +3152,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
async onRollTachePremiersSoins(blessureId, rollData) {
|
||||
if (!this.isOwner) {
|
||||
return RdDBaseActor.remoteActorCall({ actorId: this.id, method: 'onRollTachePremiersSoins', args: [blessureId, rollData] });
|
||||
return RdDBaseActor.remoteActorCall({ tokenId: this.token?.id, actorId: this.id, method: 'onRollTachePremiersSoins', args: [blessureId, rollData] });
|
||||
}
|
||||
const blessure = this.getItem(blessureId, 'blessure')
|
||||
console.log('TODO update blessure', this, blessureId, rollData, rollData.tache);
|
||||
@ -3138,7 +3182,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
async onRollSoinsComplets(blessureId, rollData) {
|
||||
if (!this.isOwner) {
|
||||
return RdDBaseActor.remoteActorCall({ actorId: this.id, method: 'onRollSoinsComplets', args: [blessureId, rollData] });
|
||||
return RdDBaseActor.remoteActorCall({ tokenId: this.token?.id, actorId: this.id, method: 'onRollSoinsComplets', args: [blessureId, rollData] });
|
||||
}
|
||||
const blessure = this.getItem(blessureId, 'blessure')
|
||||
if (blessure && blessure.system.premierssoins.done && !blessure.system.soinscomplets.done) {
|
||||
@ -3230,8 +3274,9 @@ export class RdDActor extends RdDBaseActor {
|
||||
return;
|
||||
}
|
||||
const attackerId = attacker?.id;
|
||||
if (ReglesOptionelles.isUsing('validation-encaissement-gr') && !game.user.isGM) {
|
||||
if (ReglesOptionnelles.isUsing('validation-encaissement-gr') && !game.user.isGM) {
|
||||
RdDBaseActor.remoteActorCall({
|
||||
tokenId: this.token?.id,
|
||||
actorId: this.id,
|
||||
method: 'appliquerEncaissement',
|
||||
args: [rollData, show, attackerId]
|
||||
@ -3243,7 +3288,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
async appliquerEncaissement(rollData, show, attackerId) {
|
||||
const armure = await this.computeArmure(rollData);
|
||||
if (ReglesOptionelles.isUsing('validation-encaissement-gr')) {
|
||||
if (ReglesOptionnelles.isUsing('validation-encaissement-gr')) {
|
||||
DialogValidationEncaissement.validerEncaissement(this, rollData, armure, show, attackerId, (encaissement, show, attackerId) => this._appliquerEncaissement(encaissement, show, attackerId));
|
||||
}
|
||||
else {
|
||||
@ -3830,5 +3875,39 @@ export class RdDActor extends RdDBaseActor {
|
||||
content: `${this.name} a reçu un/une ${item.type}: ${item.name}, qui ${manualMessage ? "n'est pas" : "est"} géré(e) automatiquement. ${manualMessage ? manualMessage : ''}`
|
||||
});
|
||||
}
|
||||
|
||||
async nouvelleIncarnation() {
|
||||
let incarnation = this.toObject();
|
||||
|
||||
incarnation.items = Array.from(this.items.filter(it => it.type == TYPES.competence),
|
||||
it => {
|
||||
it = it.toObject();
|
||||
it.id = undefined;
|
||||
it.system.niveau = it.system.base;
|
||||
it.system.niveau_archetype = Math.max(it.system.niveau + (it.system.xp > 0 ? 1 : 0), it.system.niveau_archetype);
|
||||
it.system.xp = 0;
|
||||
it.system.xp_sort = 0;
|
||||
it.system.default_diffLibre = 0;
|
||||
return it;
|
||||
});
|
||||
|
||||
incarnation.name = 'Réincarnation de ' + incarnation.name
|
||||
incarnation.system = {
|
||||
carac: duplicate(this.system.carac),
|
||||
heure: RdDTimestamp.defHeure(await RdDDice.rollTotal("1dh", { rollMode: "selfroll", showDice: SHOW_DICE })).key,
|
||||
age: 18,
|
||||
biographie: '',
|
||||
notes: '',
|
||||
experiencelog: [],
|
||||
'compteurs.experience.value': 3000,
|
||||
'reve.seuil.value': this.system.carac.reve.value,
|
||||
'reve.reve.value': this.system.carac.reve.value,
|
||||
subacteurs: { suivants: [], montures: [], vehicules: [] },
|
||||
}
|
||||
incarnation = await RdDBaseActor.create(incarnation);
|
||||
await incarnation.deleteEmbeddedDocuments('ActiveEffect', incarnation.getEmbeddedCollection("ActiveEffect").map(it => it.id));
|
||||
await incarnation.remiseANeuf();
|
||||
incarnation.sheet.render(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,13 @@ export class RdDBaseActor extends Actor {
|
||||
|
||||
static onRemoteActorCall(callData, userId) {
|
||||
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
|
||||
const args = callData.args;
|
||||
console.info(`RdDBaseActor.onRemoteActorCall: pour l'Actor ${callData.actorId}, appel de RdDBaseActor.${callData.method}(`, ...args, ')');
|
||||
@ -119,7 +125,7 @@ export class RdDBaseActor extends Actor {
|
||||
}
|
||||
|
||||
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) {
|
||||
return this.getItem(idOrName, type)
|
||||
?? Misc.findFirstLike(idOrName, this.listItems(type), { description: Misc.typeName('Item', type) });
|
||||
@ -144,9 +150,10 @@ export class RdDBaseActor extends Actor {
|
||||
.forEach(async it => await it.onFinPeriodeTemporel(oldTimestamp, newTimestamp))
|
||||
}
|
||||
|
||||
async creerObjetParMJ(object){
|
||||
async creerObjetParMJ(object) {
|
||||
if (!Misc.isUniqueConnectedGM()) {
|
||||
RdDBaseActor.remoteActorCall({
|
||||
tokenId: this.token?.id,
|
||||
actorId: this.id,
|
||||
method: 'creerObjetParMJ',
|
||||
args: [object]
|
||||
@ -220,6 +227,7 @@ export class RdDBaseActor extends Actor {
|
||||
if (fromActorId && !game.user.isGM) {
|
||||
RdDBaseActor.remoteActorCall({
|
||||
userId: Misc.connectedGMOrUser(),
|
||||
tokenId: this.token?.id,
|
||||
actorId: this.id,
|
||||
method: 'ajouterSols', args: [sols, fromActorId]
|
||||
});
|
||||
@ -262,10 +270,10 @@ export class RdDBaseActor extends Actor {
|
||||
const quantite = (achat.choix.nombreLots ?? 1) * (achat.vente.tailleLot);
|
||||
const itemVendu = vendeur?.getItem(achat.vente.item._id) ?? game.items.get(achat.vente.item._id);
|
||||
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;
|
||||
}
|
||||
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} !`);
|
||||
return
|
||||
}
|
||||
@ -318,7 +326,7 @@ export class RdDBaseActor extends Actor {
|
||||
}
|
||||
|
||||
verifierQuantite(item, quantiteDemande) {
|
||||
const disponible = item?.getQuantite();
|
||||
const disponible = this.getQuantiteDisponible(item);
|
||||
return disponible == undefined || disponible >= quantiteDemande;
|
||||
}
|
||||
|
||||
@ -447,62 +455,33 @@ export class RdDBaseActor extends Actor {
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
conteneurPeutContenir(dest, item) {
|
||||
conteneurPeutContenir(dest, moved) {
|
||||
if (!dest) {
|
||||
return true;
|
||||
}
|
||||
if (!dest.isConteneur()) {
|
||||
return false;
|
||||
}
|
||||
const destData = dest
|
||||
if (this._isConteneurContenu(item, dest)) {
|
||||
ui.notifications.warn(`Impossible de déplacer un conteneur parent (${item.name}) dans un de ses contenus ${destData.name} !`);
|
||||
return false; // Loop detected !
|
||||
if (moved.isConteneurContenu(dest)) {
|
||||
ui.notifications.warn(`Impossible de déplacer un conteneur parent (${moved.name}) dans un de ses contenus ${dest.name} !`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calculer le total actuel des contenus
|
||||
let encContenu = this.getRecursiveEnc(dest) - Number(destData.system.encombrement);
|
||||
let newEnc = this.getRecursiveEnc(item); // Calculer le total actuel du nouvel objet
|
||||
const encContenu = dest.getEncContenu();
|
||||
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
|
||||
if (Number(destData.system.capacite) < encContenu + newEnc) {
|
||||
if (placeDisponible < 0) {
|
||||
ui.notifications.warn(
|
||||
`Le conteneur ${dest.name} a une capacité de ${destData.system.capacite}, et contient déjà ${encContenu}.
|
||||
Impossible d'y ranger: ${item.name} d'encombrement ${newEnc}!`);
|
||||
`Le conteneur ${dest.name} a une capacité de ${dest.system.capacite}, et contient déjà ${encContenu}.
|
||||
Impossible d'y ranger: ${moved.name} d'encombrement ${newEnc}!`);
|
||||
return false;
|
||||
}
|
||||
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
|
||||
* de leurs ID */
|
||||
|
@ -28,6 +28,7 @@ export class RdDCommerce extends RdDBaseActor {
|
||||
verifierFortune(cout) {
|
||||
return this.system.illimite || super.verifierFortune(cout);
|
||||
}
|
||||
|
||||
async depenserSols(cout) {
|
||||
if (this.system.illimite) {
|
||||
return
|
||||
|
@ -114,7 +114,7 @@ export class DialogChronologie extends Dialog {
|
||||
heure: RdDTimestamp.definition(this.html.find("form.rdddialogchrono :input[name='chronologie.heure']").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', ' ')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ export class DialogCreateSigneDraconique extends Dialog {
|
||||
|
||||
onSelectTmr(event) {
|
||||
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){
|
||||
onTmr.selected = event.currentTarget.checked;
|
||||
}
|
||||
|
@ -20,14 +20,14 @@ const nomCategorieParade = {
|
||||
export class RdDItemArme extends Item {
|
||||
|
||||
static isArme(item) {
|
||||
return RdDItemCompetenceCreature.getCategorieAttaque(item) || item.type == 'arme';
|
||||
return RdDItemCompetenceCreature.getCategorieAttaque(item) || item.type == TYPES.arme;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getArme(arme) {
|
||||
switch (arme ? arme.type : '') {
|
||||
case 'arme': return arme;
|
||||
case 'competencecreature':
|
||||
case TYPES.arme: return arme;
|
||||
case TYPES.competencecreature:
|
||||
return RdDItemCompetenceCreature.armeCreature(arme);
|
||||
}
|
||||
return RdDItemArme.mainsNues();
|
||||
@ -68,14 +68,14 @@ export class RdDItemArme extends Item {
|
||||
return armeData.system.categorie_parade;
|
||||
}
|
||||
// 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' : '');
|
||||
}
|
||||
if (!armeData.type.match(/arme|competencecreature/)) {
|
||||
return '';
|
||||
}
|
||||
if (armeData.system.competence == undefined) {
|
||||
return 'competencecreature';
|
||||
return TYPES.competencecreature;
|
||||
}
|
||||
let compname = armeData.system.competence.toLowerCase();
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
return arme.type == 'arme' && arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0);
|
||||
}
|
||||
|
||||
static ajoutCorpsACorps(armes, competences, carac) {
|
||||
let corpsACorps = competences.find(it => it.name == 'Corps à corps') ?? { system: { niveau: -6 } };
|
||||
let init = RdDCombatManager.calculInitiative(corpsACorps.system.niveau, carac['melee'].value);
|
||||
armes.push(RdDItemArme.mainsNues({ niveau: corpsACorps.system.niveau, initiative: init }));
|
||||
armes.push(RdDItemArme.empoignade({ niveau: corpsACorps.system.niveau, initiative: init }));
|
||||
static ajoutCorpsACorps(armes, actor) {
|
||||
armes.push(RdDItemArme.mainsNues(actor));
|
||||
armes.push(RdDItemArme.empoignade(actor));
|
||||
}
|
||||
|
||||
static corpsACorps(mainsNuesActor) {
|
||||
const corpsACorps = {
|
||||
static corpsACorps(actor) {
|
||||
let competence = actor?.getCompetenceCorpsACorps() ?? { system: { niveau: -6 } };
|
||||
let melee = actor? actor.system.carac['melee'].value : 0
|
||||
return {
|
||||
_id: competence?.id,
|
||||
name: 'Corps à corps',
|
||||
type: TYPES.arme,
|
||||
img: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp',
|
||||
system: {
|
||||
initiative: RdDCombatManager.calculInitiative(competence.system.niveau, melee),
|
||||
equipe: true,
|
||||
rapide: true,
|
||||
force: 0,
|
||||
@ -181,23 +191,22 @@ export class RdDItemArme extends Item {
|
||||
dommagesReels: 0,
|
||||
mortalite: 'non-mortel',
|
||||
competence: 'Corps à corps',
|
||||
deuxmains: true,
|
||||
categorie_parade: 'sans-armes'
|
||||
}
|
||||
};
|
||||
mergeObject(corpsACorps.system, mainsNuesActor ?? {}, { overwrite: false });
|
||||
return corpsACorps;
|
||||
}
|
||||
}
|
||||
|
||||
static mainsNues(mainsNuesActor) {
|
||||
const mainsNues = RdDItemArme.corpsACorps(mainsNuesActor)
|
||||
static mainsNues(actor) {
|
||||
const mainsNues = RdDItemArme.corpsACorps(actor)
|
||||
mainsNues.name = 'Mains nues'
|
||||
mainsNues.system.cac = 'pugilat'
|
||||
mainsNues.system.baseInit = 4
|
||||
return mainsNues;
|
||||
}
|
||||
|
||||
static empoignade(mainsNuesActor) {
|
||||
const empoignade = RdDItemArme.corpsACorps(mainsNuesActor)
|
||||
|
||||
static empoignade(actor) {
|
||||
const empoignade = RdDItemArme.corpsACorps(actor)
|
||||
empoignade.name = 'Empoignade'
|
||||
empoignade.system.cac = 'empoignade'
|
||||
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 limitesArchetypes = [
|
||||
{ "niveau": 0, "nombreMax": 100, "reste": 100 },
|
||||
{ "niveau": 1, "nombreMax": 10, "reste": 10 },
|
||||
{ "niveau": 2, "nombreMax": 9, "reste": 9 },
|
||||
{ "niveau": 3, "nombreMax": 8, "reste": 8 },
|
||||
{ "niveau": 4, "nombreMax": 7, "reste": 7 },
|
||||
{ "niveau": 5, "nombreMax": 6, "reste": 6 },
|
||||
{ "niveau": 6, "nombreMax": 5, "reste": 5 },
|
||||
{ "niveau": 7, "nombreMax": 4, "reste": 4 },
|
||||
{ "niveau": 8, "nombreMax": 3, "reste": 3 },
|
||||
{ "niveau": 9, "nombreMax": 2, "reste": 2 },
|
||||
{ "niveau": 10, "nombreMax": 1, "reste": 1 },
|
||||
{ "niveau": 11, "nombreMax": 1, "reste": 1 }
|
||||
{ niveau: 0, nombreMax: 100 },
|
||||
{ niveau: 1, nombreMax: 10 },
|
||||
{ niveau: 2, nombreMax: 9 },
|
||||
{ niveau: 3, nombreMax: 8 },
|
||||
{ niveau: 4, nombreMax: 7 },
|
||||
{ niveau: 5, nombreMax: 6 },
|
||||
{ niveau: 6, nombreMax: 5 },
|
||||
{ niveau: 7, nombreMax: 4 },
|
||||
{ niveau: 8, nombreMax: 3 },
|
||||
{ niveau: 9, nombreMax: 2 },
|
||||
{ niveau: 10, nombreMax: 1 },
|
||||
{ niveau: 11, nombreMax: 1 },
|
||||
];
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -79,10 +79,9 @@ export class RdDItemCompetence extends Item {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static isCompetenceArme(competence) {
|
||||
if (competence.isCompetence()) {
|
||||
if (competence.isCompetence() && !competence.isCorpsACorps() && !competence.isEsquive()) {
|
||||
switch (competence.system.categorie) {
|
||||
case 'melee':
|
||||
return !Grammar.toLowerCaseNoAccent(competence.name).includes('esquive');
|
||||
case 'tir':
|
||||
case 'lancer':
|
||||
return true;
|
||||
@ -93,10 +92,10 @@ export class RdDItemCompetence extends Item {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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) {
|
||||
return RdDItemCompetence.isCompetenceArme(competence) && competence.name.toLowerCase().includes("2 main");
|
||||
return competence.isCompetenceArme() && competence.name.toLowerCase().includes("2 main");
|
||||
}
|
||||
|
||||
static isThanatos(competence) {
|
||||
@ -259,13 +258,17 @@ export class RdDItemCompetence extends Item {
|
||||
/* -------------------------------------------- */
|
||||
static computeResumeArchetype(competences) {
|
||||
const computed = duplicate(limitesArchetypes);
|
||||
computed.forEach(it => { it.nombre = 0; it.reste = it.nombreMax; });
|
||||
|
||||
competences.map(it => Math.max(0, it.system.niveau_archetype))
|
||||
.filter(n => n > 0)
|
||||
.forEach(n => {
|
||||
computed[n] = computed[n] ?? { niveau: n, nombreMax: 0, reste: 0 };
|
||||
computed[n].reste = computed[n].reste - 1;
|
||||
computed[n] = computed[n] ?? { niveau: n, nombreMax: 0, reste: 0, nombre: 0 };
|
||||
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";
|
||||
|
||||
const categories = {
|
||||
|
@ -5,7 +5,7 @@ import { RdDItemCompetence } from "./item-competence.js";
|
||||
import { RdDHerbes } from "./rdd-herbes.js";
|
||||
import { RdDGemme } from "./rdd-gemme.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 { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
||||
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||
@ -113,7 +113,7 @@ export class RdDItemSheet extends ItemSheet {
|
||||
formData.competences = competences;
|
||||
}
|
||||
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)) {
|
||||
formData.competences = competences.filter(it => RdDItemCompetence.isDraconic(it));
|
||||
@ -157,7 +157,7 @@ export class RdDItemSheet extends ItemSheet {
|
||||
super.activateListeners(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
|
||||
|| !this.item.isOwned);
|
||||
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('.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) => {
|
||||
let actor = this._getEventActor(event);
|
||||
|
@ -220,6 +220,32 @@ export class RdDItem extends Item {
|
||||
isService() { return this.type == TYPES.service; }
|
||||
|
||||
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" }
|
||||
isTemporel() { return typesObjetsTemporels.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);
|
||||
}
|
||||
|
||||
getEncContenu() {
|
||||
return this.getContenu()
|
||||
.map(it => it.getRecursiveEnc())
|
||||
.reduce(Misc.sum(), 0);
|
||||
}
|
||||
|
||||
getRecursiveEnc() {
|
||||
return this.getEncTotal() + this.getEncContenu()
|
||||
}
|
||||
|
||||
getEncHerbe() {
|
||||
switch (this.system.categorie) {
|
||||
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() {
|
||||
return (this.isService() ? 1 : this.getQuantite()) * this.valeur()
|
||||
}
|
||||
@ -675,7 +723,7 @@ export class RdDItem extends Item {
|
||||
_armeChatData() {
|
||||
return [
|
||||
`<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>Resistance</b>: ${this.system.resistance}`,
|
||||
...this._inventaireTemplateChatData()
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { RdDItem } from "../item.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 {
|
||||
|
||||
@ -9,7 +9,7 @@ export class RdDItemArmure extends RdDItem {
|
||||
}
|
||||
|
||||
deteriorerArmure(dmg) {
|
||||
if (!ReglesOptionelles.isUsing('deteriorationArmure') || this.system.protection == '0') {
|
||||
if (!ReglesOptionnelles.isUsing('deteriorationArmure') || this.system.protection == '0') {
|
||||
return;
|
||||
}
|
||||
let deterioration = (this.system.deterioration ?? 0) + dmg;
|
||||
|
@ -42,7 +42,7 @@ export class Misc {
|
||||
}
|
||||
|
||||
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)}`)
|
||||
: '';
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ import { RdDBonus } from "./rdd-bonus.js";
|
||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||
import { RdDRoll } from "./rdd-roll.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 { Targets } from "./targets.js";
|
||||
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
||||
@ -171,8 +171,7 @@ export class RdDCombatManager extends Combat {
|
||||
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)");
|
||||
}
|
||||
if ((arme.system.unemain && arme.system.competence) ||
|
||||
(arme.system.competence.toLowerCase().includes("corps à corps"))) {
|
||||
if (arme.system.unemain && arme.system.competence) {
|
||||
actions.push(RdDCombatManager.$prepareAttaqueArme({
|
||||
arme: arme,
|
||||
infoMain: "(1 main)",
|
||||
@ -187,7 +186,7 @@ export class RdDCombatManager extends Combat {
|
||||
arme: arme,
|
||||
infoMain: "(2 mains)",
|
||||
dommagesReel: Number(tableauDommages[1]),
|
||||
competence: arme.system.competence.replace(" 1 main", " 2 mains"),
|
||||
competence: RdDItemArme.competence2Mains(arme),
|
||||
carac: carac,
|
||||
competences: competences
|
||||
}));
|
||||
@ -258,11 +257,10 @@ export class RdDCombatManager extends Combat {
|
||||
actions = RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']);
|
||||
} else if (actor.isPersonnage()) {
|
||||
// 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 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);
|
||||
|
||||
if (actor.system.attributs.hautrevant.value) {
|
||||
@ -450,7 +448,7 @@ export class RdDCombat {
|
||||
if (Misc.isUniqueConnectedGM()) {
|
||||
let turn = combat.turns.find(t => t.token?.id == combat.current.tokenId);
|
||||
if (turn?.actor) {
|
||||
RdDCombat.displayActorCombatStatus(combat, turn.actor);
|
||||
RdDCombat.displayActorCombatStatus(combat, turn.actor, turn.token.id);
|
||||
// TODO Playaudio for player??
|
||||
}
|
||||
}
|
||||
@ -514,8 +512,12 @@ export class RdDCombat {
|
||||
/* -------------------------------------------- */
|
||||
static _callJetDeVie(event) {
|
||||
let actorId = event.currentTarget.attributes['data-actorId'].value;
|
||||
let actor = game.actors.get(actorId);
|
||||
actor.jetVie();
|
||||
let tokenId = event.currentTarget.attributes['data-tokenId'].value;
|
||||
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 +543,7 @@ export class RdDCombat {
|
||||
}
|
||||
});
|
||||
}
|
||||
html.on("click", '#chat-jet-vie', event => {
|
||||
html.on("click", 'a.chat-jet-vie', event => {
|
||||
event.preventDefault();
|
||||
RdDCombat._callJetDeVie(event);
|
||||
});
|
||||
@ -789,8 +791,7 @@ export class RdDCombat {
|
||||
let rollData = {
|
||||
passeArme: randomID(16),
|
||||
mortalite: arme?.system.mortalite,
|
||||
coupsNonMortels: false,
|
||||
competence: competence.clone(),
|
||||
competence: competence,
|
||||
surprise: this.attacker.getSurprise(true),
|
||||
surpriseDefenseur: this.defender.getSurprise(true),
|
||||
targetToken: Targets.extractTokenData(this.target),
|
||||
@ -886,8 +887,8 @@ export class RdDCombat {
|
||||
}
|
||||
|
||||
// # utilisation esquive
|
||||
const corpsACorps = this.defender.getCompetence("Corps à corps", { onMessage: it => console.info(it, this.defender) });
|
||||
const esquives = duplicate(this.defender.getCompetences("esquive", { onMessage: it => console.info(it, this.defender) }))
|
||||
const corpsACorps = this.defender.getCompetenceCorpsACorps({ 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);
|
||||
|
||||
const paramChatDefense = {
|
||||
@ -1045,10 +1046,10 @@ export class RdDCombat {
|
||||
passeArme: attackerRoll.passeArme,
|
||||
diffLibre: attackerRoll.diffLibre,
|
||||
attackerRoll: attackerRoll,
|
||||
competence: this.defender.getCompetence(competenceParade).clone(),
|
||||
competence: this.defender.getCompetence(competenceParade),
|
||||
arme: armeParade,
|
||||
surprise: this.defender.getSurprise(true),
|
||||
needParadeSignificative: ReglesOptionelles.isUsing('categorieParade') && RdDItemArme.needParadeSignificative(attackerRoll.arme, armeParade),
|
||||
needParadeSignificative: ReglesOptionnelles.isUsing('categorieParade') && RdDItemArme.needParadeSignificative(attackerRoll.arme, armeParade),
|
||||
needResist: RdDItemArme.needArmeResist(attackerRoll.arme, armeParade),
|
||||
carac: this.defender.system.carac,
|
||||
show: {}
|
||||
@ -1126,7 +1127,7 @@ export class RdDCombat {
|
||||
passeArme: attackerRoll.passeArme,
|
||||
diffLibre: attackerRoll.diffLibre,
|
||||
attackerRoll: attackerRoll,
|
||||
competence: competence.clone(),
|
||||
competence: competence,
|
||||
surprise: this.defender.getSurprise(true),
|
||||
surpriseDefenseur: this.defender.getSurprise(true),
|
||||
carac: this.defender.system.carac,
|
||||
@ -1166,7 +1167,7 @@ export class RdDCombat {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async computeDeteriorationArme(defenderRoll) {
|
||||
if (!ReglesOptionelles.isUsing('resistanceArmeParade')) {
|
||||
if (!ReglesOptionnelles.isUsing('resistanceArmeParade')) {
|
||||
return;
|
||||
}
|
||||
const attackerRoll = defenderRoll.attackerRoll;
|
||||
@ -1215,7 +1216,7 @@ export class RdDCombat {
|
||||
}
|
||||
}
|
||||
// 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({
|
||||
caracValue: this.defender.getForce(),
|
||||
finalLevel: Misc.toInt(defenderRoll.competence.system.niveau) - dmg,
|
||||
@ -1230,7 +1231,7 @@ export class RdDCombat {
|
||||
/* -------------------------------------------- */
|
||||
async computeRecul(defenderRoll) { // Calcul du recul (p. 132)
|
||||
const attackerRoll = defenderRoll.attackerRoll;
|
||||
if (ReglesOptionelles.isUsing('recul') && this._isForceOuCharge(attackerRoll)) {
|
||||
if (ReglesOptionnelles.isUsing('recul') && this._isForceOuCharge(attackerRoll)) {
|
||||
const impact = this._computeImpactRecul(attackerRoll);
|
||||
const rollRecul = await RdDResolutionTable.rollData({ caracValue: 10, finalLevel: impact });
|
||||
if (rollRecul.rolled.isSuccess) {
|
||||
@ -1295,7 +1296,7 @@ export class RdDCombat {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async displayActorCombatStatus(combat, actor) {
|
||||
static async displayActorCombatStatus(combat, actor, tokenId) {
|
||||
let formData = {
|
||||
combatId: combat._id,
|
||||
alias: actor.name,
|
||||
@ -1304,12 +1305,18 @@ export class RdDCombat {
|
||||
blessuresStatus: actor.computeResumeBlessure(),
|
||||
SConst: actor.getSConst(),
|
||||
actorId: actor.id,
|
||||
tokenId: tokenId,
|
||||
isGrave: actor.countBlessures(it => it.isGrave()) > 0,
|
||||
isCritique: actor.countBlessures(it => it.isCritique()) > 0
|
||||
}
|
||||
|
||||
ChatUtility.createChatWithRollMode(actor.name, {
|
||||
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-summary.html`, formData)
|
||||
await ChatMessage.create({
|
||||
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-acteur.hbs`, 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 { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||
|
||||
export class RdDConfirm {
|
||||
/* -------------------------------------------- */
|
||||
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) {
|
||||
options.onAction();
|
||||
}
|
||||
@ -47,7 +47,7 @@ export class RdDConfirm {
|
||||
icon: '<i class="fas fa-user-check"></i>',
|
||||
label: options.buttonLabel + "<br>et ne plus demander",
|
||||
callback: () => {
|
||||
ReglesOptionelles.set(options.settingConfirmer, false);
|
||||
ReglesOptionnelles.set(options.settingConfirmer, false);
|
||||
options.onAction();
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import { RdDRoll } from "./rdd-roll.js";
|
||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { STATUSES } from "./settings/status-effects.js";
|
||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||
import { TYPES } from "./item.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -181,7 +181,7 @@ export class RdDEmpoignade {
|
||||
let rollData = {
|
||||
mode, empoignade, attacker, defender,
|
||||
isEmpoignade: true,
|
||||
competence: attacker.getCompetence("Corps à corps").clone(),
|
||||
competence: attacker.getCompetenceCorpsACorps(),
|
||||
selectedCarac: attacker.system.carac.melee,
|
||||
malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender)
|
||||
}
|
||||
@ -210,7 +210,7 @@ export class RdDEmpoignade {
|
||||
mode: "immobilise",
|
||||
empoignade, attacker, defender,
|
||||
isEmpoignade: true,
|
||||
competence: attacker.getCompetence("Corps à corps").clone()
|
||||
competence: attacker.getCompetenceCorpsACorps()
|
||||
}
|
||||
const msg = await ChatMessage.create({
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(attacker.name),
|
||||
@ -272,7 +272,7 @@ export class RdDEmpoignade {
|
||||
mode, attacker, defender, empoignade, attackerRoll,
|
||||
diffLibre: attackerRoll.diffLibre,
|
||||
attaqueParticuliere: attackerRoll.particuliere,
|
||||
competence: defender.getCompetence(competenceName).clone(),
|
||||
competence: defender.getCompetence(competenceName),
|
||||
surprise: defender.getSurprise(true),
|
||||
carac: defender.system.carac,
|
||||
selectedCarac: defender.system.carac[carac],
|
||||
|
@ -1,12 +1,17 @@
|
||||
import { RdDItemArme } from "./item-arme.js";
|
||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||
import { TYPES } from "./item.js";
|
||||
|
||||
export class RdDHotbar {
|
||||
|
||||
static async addToHotbar(item, slot) {
|
||||
let command = `game.system.rdd.RdDHotbar.rollMacro("${item.name}", "${item.type}");`;
|
||||
let macro = game.macros.contents.find(m => (m.name === item.name) && (m.command === command));
|
||||
static async createItemMacro(item, slot, armeCompetence = undefined) {
|
||||
const itemName = item.name;
|
||||
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) {
|
||||
macro = await Macro.create({
|
||||
name: item.name,
|
||||
name: macroName,
|
||||
type: "script",
|
||||
img: item.img,
|
||||
command: command
|
||||
@ -15,6 +20,59 @@ export class RdDHotbar {
|
||||
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
|
||||
* Item - open roll dialog for item
|
||||
@ -23,20 +81,19 @@ export class RdDHotbar {
|
||||
*/
|
||||
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
|
||||
if (documentData.type == "Item") {
|
||||
let item = fromUuidSync(documentData.uuid)
|
||||
if (item == undefined) {
|
||||
item = this.actor.items.get(documentData.uuid)
|
||||
if (documentData.type == 'Item') {
|
||||
const item = fromUuidSync(documentData.uuid) ?? this.actor.items.get(documentData.uuid)
|
||||
console.log('DROP', documentData, item)
|
||||
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
|
||||
@ -44,12 +101,14 @@ export class RdDHotbar {
|
||||
}
|
||||
|
||||
/** Roll macro */
|
||||
static rollMacro(itemName, itemType, bypassData) {
|
||||
static rollMacro(itemName, itemType, categorieArme = 'competence') {
|
||||
const speaker = ChatMessage.getSpeaker();
|
||||
let actor;
|
||||
if (speaker.token) actor = game.actors.tokens[speaker.token];
|
||||
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;
|
||||
if (!item) {
|
||||
return ui.notifications.warn(`Impossible de trouver l'objet de cette macro`);
|
||||
@ -57,10 +116,23 @@ export class RdDHotbar {
|
||||
|
||||
// Trigger the item roll
|
||||
switch (item.type) {
|
||||
case "arme":
|
||||
return actor.rollArme(item);
|
||||
case "competence":
|
||||
return actor.rollCompetence(itemName);
|
||||
case TYPES.arme:
|
||||
return actor.rollArme(item, categorieArme);
|
||||
case TYPES.competence:
|
||||
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 { StatusEffects } from "./settings/status-effects.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 { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
||||
import { RdDHerbes } from "./rdd-herbes.js";
|
||||
@ -59,6 +59,7 @@ import { RdDSigneDraconiqueItemSheet } from "./item/sheet-signedraconique.js";
|
||||
import { RdDItemInventaireSheet } from "./item/sheet-base-inventaire.js";
|
||||
import { AppAstrologie } from "./sommeil/app-astrologie.js";
|
||||
import { RdDItemArmure } from "./item/armure.js";
|
||||
import { AutoAdjustDarkness as AutoAdjustDarkness } from "./time/auto-adjust-darkness.js";
|
||||
|
||||
/**
|
||||
* RdD system
|
||||
@ -182,11 +183,12 @@ export class SystemReveDeDragon {
|
||||
CONFIG.Combat.documentClass = RdDCombatManager;
|
||||
|
||||
// préparation des différents modules
|
||||
AutoAdjustDarkness.init();
|
||||
RdDTimestamp.init();
|
||||
RdDCalendrier.init();
|
||||
SystemCompendiums.init();
|
||||
DialogChronologie.init();
|
||||
ReglesOptionelles.init();
|
||||
ReglesOptionnelles.init();
|
||||
RdDUtility.init();
|
||||
RdDDice.init();
|
||||
RdDCommands.init();
|
||||
|
@ -39,7 +39,7 @@ export class RdDPossession {
|
||||
let rollData = {
|
||||
mode: "attaque",
|
||||
isECNIDefender: false,
|
||||
competence: competence.clone(),
|
||||
competence: competence,
|
||||
possession: possession,
|
||||
attacker: attacker,
|
||||
defender: defender,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { Misc } from "./misc.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
|
||||
@ -126,7 +126,7 @@ export class RdDResolutionTable {
|
||||
rolled.bonus = rollData.bonus;
|
||||
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.ajustementNecessaire = rolled.niveauNecessaire - finalLevel;
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ export class RdDRollResolutionTable extends Dialog {
|
||||
async updateRollResult() {
|
||||
let rollData = this.rollData;
|
||||
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({
|
||||
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() {
|
||||
await super.close();
|
||||
|
@ -6,7 +6,7 @@ import { Misc } from "./misc.js";
|
||||
import { RdDBonus } from "./rdd-bonus.js";
|
||||
import { RdDCarac } from "./rdd-carac.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
|
||||
@ -22,7 +22,7 @@ export class RdDRoll extends Dialog {
|
||||
|
||||
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) {
|
||||
options.close = dialogConfig.close;
|
||||
}
|
||||
@ -50,8 +50,6 @@ export class RdDRoll extends Dialog {
|
||||
encTotal: true
|
||||
},
|
||||
isMalusEncombrementTotal: RdDItemCompetence.isMalusEncombrementTotal(rollData.competence),
|
||||
malusArmureValue: actor.getMalusArmure(),
|
||||
surencMalusValue: actor.computeMalusSurEncombrement(),
|
||||
encTotal: actor.getEncTotal(),
|
||||
ajustementAstrologique: actor.ajustementAstrologique(),
|
||||
surprise: actor.getSurprise(false),
|
||||
@ -85,7 +83,7 @@ export class RdDRoll extends Dialog {
|
||||
if (RdDBonus.isDefenseAttaqueFinesse(rollData)) {
|
||||
facteurSign *= 2;
|
||||
}
|
||||
if (!ReglesOptionelles.isUsing('tripleSignificative')) {
|
||||
if (!ReglesOptionnelles.isUsing('tripleSignificative')) {
|
||||
facteurSign = Math.min(facteurSign, 4);
|
||||
}
|
||||
return facteurSign;
|
||||
@ -187,7 +185,7 @@ export class RdDRoll extends Dialog {
|
||||
console.log("RdDRollSelectDialog - Cout reve", ptreve);
|
||||
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.updateRollResult(html);
|
||||
});
|
||||
@ -291,36 +289,31 @@ export class RdDRoll extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async updateRollResult(html) {
|
||||
let rollData = this.rollData;
|
||||
const rollData = this.rollData;
|
||||
|
||||
rollData.dmg = rollData.attackerRoll?.dmg ?? RdDBonus.dmg(rollData, this.actor.getBonusDegat())
|
||||
rollData.caracValue = parseInt(rollData.selectedCarac.value)
|
||||
rollData.mortalite = rollData.attackerRoll?.dmg.mortalite ?? rollData.dmg.mortalite ?? 'mortel';
|
||||
rollData.coupsNonMortels = (rollData.attackerRoll?.dmg.mortalite ?? rollData.dmg.mortalite) == 'non-mortel';
|
||||
rollData.dmg.mortalite = rollData.dmg.mortalite ?? 'mortel';
|
||||
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);
|
||||
rollData.finalLevel = this._computeFinalLevel(rollData);
|
||||
|
||||
const resolutionTable = await RdDResolutionTable.buildHTMLTable(RdDResolutionTable.subTable(rollData.caracValue, rollData.finalLevel))
|
||||
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-surenc"), rollData.ajustements.surenc.visible && RdDCarac.isActionPhysique(rollData.selectedCarac));
|
||||
HtmlUtility.showControlWhen(this.html.find(".utilisation-moral"), 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
|
||||
this.html.find(".dialog-roll-title").text(this._getTitle(rollData));
|
||||
this.html.find("[name='coupsNonMortels']").prop('checked', rollData.mortalite == 'non-mortel');
|
||||
this.html.find(".dmg-arme-actor").text(dmgText);
|
||||
this.html.find("input.check-mortalite").prop('checked', rollData.dmg.mortalite == 'non-mortel');
|
||||
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-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);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_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) {
|
||||
const carac = rollData.selectedCarac.label;
|
||||
@ -362,16 +331,19 @@ export class RdDRoll extends Dialog {
|
||||
return carac;
|
||||
}
|
||||
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)
|
||||
if (compName == carac) {
|
||||
// cas des créatures
|
||||
return carac + " Niveau " + niveau
|
||||
return `${carac} Niveau ${niveau}`
|
||||
}
|
||||
const armeTitle = (rollData.arme) ? " (" + rollData.arme.name + ") " : "";
|
||||
return carac + "/" + compName + armeTitle + " Niveau " + niveau
|
||||
if (rollData.draconicList && rollData.selectedSort) {
|
||||
// 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 { RdDUtility } from "./rdd-utility.js";
|
||||
import { TMRUtility } from "./tmr-utility.js";
|
||||
import { tmrConstants } from "./tmr-constants.js";
|
||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||
import { RdDTMRRencontreDialog } from "./rdd-tmr-rencontre-dialog.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 { Draconique } from "./tmr/draconique.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 { STATUSES } from "./settings/status-effects.js";
|
||||
import { RdDRencontre } from "./item/rencontre.js";
|
||||
@ -39,14 +38,16 @@ export class RdDTMRDialog extends Dialog {
|
||||
title: "Terres Médianes de Rêve",
|
||||
content: html,
|
||||
buttons: {
|
||||
closeButton: { label: "Fermer", callback: html => this.close(html) }
|
||||
closeButton: {
|
||||
label: "Fermer", callback: html => this.close()
|
||||
}
|
||||
},
|
||||
default: "closeButton"
|
||||
}
|
||||
|
||||
const dialogOptions = {
|
||||
classes: ["tmrdialog"],
|
||||
width: 920, height: 980,
|
||||
width: 920, maxheight: 1024, height: 'fit-content',
|
||||
'z-index': 40
|
||||
}
|
||||
super(dialogConf, dialogOptions);
|
||||
@ -55,15 +56,15 @@ export class RdDTMRDialog extends Dialog {
|
||||
this.actor = actor;
|
||||
this.actor.tmrApp = this; // reference this app in the actor structure
|
||||
this.viewOnly = tmrData.mode == "visu"
|
||||
this.fatigueParCase = this.viewOnly || !ReglesOptionelles.isUsing("appliquer-fatigue") ? 0 : this.actor.getTMRFatigue();
|
||||
this.fatigueParCase = this.viewOnly || !ReglesOptionnelles.isUsing("appliquer-fatigue") ? 0 : this.actor.getTMRFatigue();
|
||||
this.cumulFatigue = 0;
|
||||
this.loadRencontres();
|
||||
this.loadCasesSpeciales();
|
||||
this.allTokens = [];
|
||||
this.rencontreState = 'aucune';
|
||||
this.pixiApp = new PIXI.Application({ width: 720, height: 860 });
|
||||
|
||||
this.pixiTMR = new PixiTMR(this, this.pixiApp);
|
||||
this.subdialog = undefined
|
||||
|
||||
this.callbacksOnAnimate = [];
|
||||
if (!this.viewOnly) {
|
||||
@ -74,6 +75,31 @@ export class RdDTMRDialog extends Dialog {
|
||||
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() {
|
||||
return !game.user.isGM && this.actor.isTMRCache();
|
||||
}
|
||||
@ -175,6 +201,9 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async moveFromKey(move) {
|
||||
if (this.subdialog) {
|
||||
return this.forceTMRContinueAction();
|
||||
}
|
||||
let oddq = TMRUtility.coordTMRToOddq(this._getActorCoord());
|
||||
|
||||
if (move == 'top') oddq.row -= 1;
|
||||
@ -199,7 +228,9 @@ export class RdDTMRDialog extends Dialog {
|
||||
super.activateListeners(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) {
|
||||
this.html.find('.lancer-sort').remove();
|
||||
@ -207,9 +238,13 @@ export class RdDTMRDialog extends Dialog {
|
||||
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()));
|
||||
|
||||
this.html.find('tr.tmr-row *').click((event) => {
|
||||
this.subdialog?.bringToTop();
|
||||
});
|
||||
|
||||
// Roll Sort
|
||||
this.html.find('.lancer-sort').click((event) => {
|
||||
this.actor.rollUnSort(this._getActorCoord());
|
||||
@ -227,11 +262,10 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
// 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();
|
||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||
this.cumulFatigue += this.fatigueParCase;
|
||||
}
|
||||
await this.actor.reveActuelIncDec(reveCout);
|
||||
|
||||
// Le reste...
|
||||
this.updateValuesDisplay();
|
||||
let tmr = TMRUtility.getTMR(this._getActorCoord());
|
||||
@ -263,7 +297,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
let refoulement = document.getElementById("tmr-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");
|
||||
fatigueItem.innerHTML = "<table class='table-fatigue'>" + RdDUtility.makeHTMLfatigueMatrix(this.actor.system.sante.fatigue.value, this.actor.system.sante.endurance.max).html() + "</table>";
|
||||
}
|
||||
@ -271,6 +305,10 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async close() {
|
||||
if (this.subdialog) {
|
||||
return this.forceTMRContinueAction()
|
||||
}
|
||||
|
||||
this.descenteTMR = true;
|
||||
if (this.actor.tmrApp) {
|
||||
this.actor.tmrApp = undefined; // Cleanup reference
|
||||
@ -293,6 +331,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
switch (action) {
|
||||
case 'derober':
|
||||
await this.derober();
|
||||
this.restoreTMRAfterAction();
|
||||
return;
|
||||
case 'refouler':
|
||||
await this.refouler();
|
||||
@ -305,6 +344,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
break;
|
||||
}
|
||||
await this.postRencontre(tmr);
|
||||
this.restoreTMRAfterAction();
|
||||
}
|
||||
|
||||
async derober() {
|
||||
@ -360,14 +400,13 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
checkQuitterTMR() {
|
||||
|
||||
if (this.actor.isDead()) {
|
||||
this._tellToGM("Vous êtes mort : vous quittez les Terres médianes !");
|
||||
this.close();
|
||||
return true;
|
||||
}
|
||||
const resteAvantInconscience = this.actor.getFatigueMax() - this.actor.getFatigueActuelle() - this.cumulFatigue;
|
||||
if (ReglesOptionelles.isUsing("appliquer-fatigue") && resteAvantInconscience <= 0) {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && resteAvantInconscience <= 0) {
|
||||
this._tellToGM("Vous vous écroulez de fatigue : vous quittez les Terres médianes !");
|
||||
this.quitterLesTMRInconscient();
|
||||
return true;
|
||||
@ -451,7 +490,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
setTimeout(() => {
|
||||
// TODO: remplacer par une boucle while(this.currentRencontre) ?
|
||||
rencData.nbRounds++;
|
||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||
this.cumulFatigue += this.fatigueParCase;
|
||||
}
|
||||
this._tentativeMaitrise(rencData);
|
||||
@ -531,8 +570,9 @@ export class RdDTMRDialog extends Dialog {
|
||||
await this.maitriserRencontre();
|
||||
}
|
||||
else {
|
||||
let dialog = new RdDTMRRencontreDialog(this, this.currentRencontre, tmr);
|
||||
const dialog = new RdDTMRRencontreDialog(this.actor, this.currentRencontre, tmr);
|
||||
dialog.render(true);
|
||||
this.setTMRPendingAction(dialog);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -544,9 +584,12 @@ export class RdDTMRDialog extends Dialog {
|
||||
_presentCite(tmr) {
|
||||
const presentCite = this.casesSpeciales.find(c => EffetsDraconiques.presentCites.isCase(c, tmr.coord));
|
||||
if (presentCite) {
|
||||
this.minimize();
|
||||
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;
|
||||
}
|
||||
@ -572,8 +615,6 @@ export class RdDTMRDialog extends Dialog {
|
||||
presentCite: presentCite
|
||||
};
|
||||
await this._tentativeMaitrise(rencontreData);
|
||||
|
||||
this.maximize();
|
||||
this.postRencontre(tmr);
|
||||
}
|
||||
|
||||
@ -587,7 +628,10 @@ export class RdDTMRDialog extends Dialog {
|
||||
? TMRUtility.getTMRType(tmr.coord) + " ??"
|
||||
: tmr.label + " (" + tmr.coord + ")");
|
||||
|
||||
const fakeDialogRencontre = { bringToTop: () => { } };
|
||||
this.setTMRPendingAction(fakeDialogRencontre)
|
||||
let myRoll = await RdDDice.rollTotal("1dt", { showDice: SHOW_DICE });
|
||||
this.restoreTMRAfterAction()
|
||||
if (myRoll == 7) {
|
||||
this._tellToUser(myRoll + ": Rencontre en " + locTMR);
|
||||
return await game.system.rdd.rencontresTMR.getRencontreAleatoire(tmr, this.actor.isMauvaiseRencontre())
|
||||
@ -777,22 +821,22 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _maitriserTMR(rollData, callbackMaitrise) {
|
||||
this.minimize(); // Hide
|
||||
rollData.isTMRCache = rollData.actor.isTMRCache();
|
||||
const dialog = await RdDRoll.create(this.actor, rollData,
|
||||
{
|
||||
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,
|
||||
callbacks: [
|
||||
this.actor.createCallbackExperience(),
|
||||
{ action: r => { this.restoreTMRAfterAction() } },
|
||||
{ action: callbackMaitrise }
|
||||
]
|
||||
}
|
||||
);
|
||||
dialog.render(true);
|
||||
this.setTMRPendingAction(dialog);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -862,7 +906,8 @@ export class RdDTMRDialog extends Dialog {
|
||||
nettoyerRencontre() {
|
||||
if (!this.currentRencontre) return; // Sanity check
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -895,8 +940,8 @@ export class RdDTMRDialog extends Dialog {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
isConnaissanceFleuve(currentTMR, nextTMR) {
|
||||
return TMRUtility.getTMR(currentTMR).type == 'fleuve' &&
|
||||
isConnaissanceFleuve(tmrApp, nextTMR) {
|
||||
return TMRUtility.getTMR(tmrApp).type == 'fleuve' &&
|
||||
TMRUtility.getTMR(nextTMR).type == 'fleuve' &&
|
||||
EffetsDraconiques.isConnaissanceFleuve(this.actor);
|
||||
}
|
||||
@ -906,15 +951,15 @@ export class RdDTMRDialog extends Dialog {
|
||||
if (this.viewOnly) {
|
||||
return;
|
||||
}
|
||||
let clickOddq = RdDTMRDialog._computeEventOddq(event.data.originalEvent);
|
||||
await this._onClickTMRPos(clickOddq); // Vérifier l'état des compteurs reve/fatigue/vie
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _onClickTMRPos(clickOddq) {
|
||||
if (this.subdialog) {
|
||||
return this.forceTMRContinueAction()
|
||||
}
|
||||
let clickOddq = TMRUtility.computeEventOddq(event);
|
||||
let currentOddq = TMRUtility.coordTMRToOddq(this._getActorCoord());
|
||||
|
||||
let targetCoord = TMRUtility.oddqToCoordTMR(clickOddq);
|
||||
let currentCoord = TMRUtility.oddqToCoordTMR(currentOddq);
|
||||
|
||||
// Validation de la case de destination (gestion du cas des rencontres qui peuvent téléporter)
|
||||
let deplacementType = this._calculDeplacement(targetCoord, currentCoord, currentOddq, clickOddq);
|
||||
|
||||
@ -946,7 +991,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
await this._messagerDemiReve(targetCoord);
|
||||
break;
|
||||
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);
|
||||
}
|
||||
|
||||
@ -975,9 +1020,11 @@ export class RdDTMRDialog extends Dialog {
|
||||
/* -------------------------------------------- */
|
||||
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 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);
|
||||
await this.actor.rollUnSort(targetCoord);
|
||||
@ -994,6 +1041,9 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _deplacerDemiReve(targetCoord, deplacementType) {
|
||||
if (this.subdialog) {
|
||||
return this.forceTMRContinueAction()
|
||||
}
|
||||
if (this.currentRencontre != 'normal') {
|
||||
this.nettoyerRencontre();
|
||||
}
|
||||
@ -1004,7 +1054,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
await this.actor.updateCoordTMR(tmr.coord);
|
||||
|
||||
this.forceDemiRevePositionView();
|
||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||
this.cumulFatigue += this.fatigueParCase;
|
||||
}
|
||||
this.updateValuesDisplay();
|
||||
@ -1043,25 +1093,16 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async positionnerDemiReve(coord) {
|
||||
if (this.subdialog) {
|
||||
return this.forceTMRContinueAction()
|
||||
}
|
||||
|
||||
await this.actor.updateCoordTMR(coord);
|
||||
this.forceDemiRevePositionView();
|
||||
let tmr = TMRUtility.getTMR(coord);
|
||||
await this.postRencontre(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 */
|
||||
_getCaseRectangleCoord(coord) {
|
||||
|
@ -2,7 +2,7 @@
|
||||
export class RdDTMRRencontreDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
constructor(tmrApp, rencontre, tmr) {
|
||||
constructor(actor, rencontre, tmr) {
|
||||
const dialogConf = {
|
||||
title: "Rencontre en TMR!",
|
||||
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.tmr = tmr;
|
||||
this.tmrApp = tmrApp;
|
||||
this.actor = actor;
|
||||
this.rencontre = rencontre;
|
||||
this.tmrApp.minimize();
|
||||
}
|
||||
|
||||
async onButtonAction(action) {
|
||||
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() {
|
||||
if (this.toClose) {
|
||||
this.tmrApp.maximize();
|
||||
return super.close();
|
||||
async close() {
|
||||
if (this.actor.tmrApp){
|
||||
if (this.toClose) {
|
||||
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 { TMRUtility } from "./tmr-utility.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 { RdDItem } from "./item.js";
|
||||
import { RdDPossession } from "./rdd-possession.js";
|
||||
@ -121,6 +121,7 @@ export class RdDUtility {
|
||||
'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-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/carac-main.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-derivee.html',
|
||||
@ -179,24 +180,25 @@ export class RdDUtility {
|
||||
'systems/foundryvtt-reve-de-dragon/templates/item-queue-sheet.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/header-item.html',
|
||||
// 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-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-categorie-ingredient.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-queue.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-draconic.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-mortalite.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-rarete.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-effet.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-type.html',
|
||||
// Partials
|
||||
'systems/foundryvtt-reve-de-dragon/templates/tirage/liste-resultats-recherche.hbs',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/time/horloge.hbs',
|
||||
@ -243,7 +245,8 @@ export class RdDUtility {
|
||||
'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-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-carac-xp.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html',
|
||||
@ -278,7 +281,7 @@ export class RdDUtility {
|
||||
Handlebars.registerHelper('timestamp-formulesPeriode', () => RdDTimestamp.formulesPeriode());
|
||||
|
||||
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('filtreTriCompetences', competences => RdDItemCompetence.triVisible(competences));
|
||||
Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name));
|
||||
@ -478,7 +481,7 @@ export class RdDUtility {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static calculFatigueHtml(fatigue, endurance) {
|
||||
return ReglesOptionelles.isUsing("appliquer-fatigue") ? {
|
||||
return ReglesOptionnelles.isUsing("appliquer-fatigue") ? {
|
||||
malus: RdDUtility.calculMalusFatigue(fatigue, endurance),
|
||||
html: "<table class='table-fatigue'>" + RdDUtility.makeHTMLfatigueMatrix(fatigue, endurance).html() + "</table>"
|
||||
} : { malus: 0, html: '' };
|
||||
@ -554,14 +557,14 @@ export class RdDUtility {
|
||||
let formula = "2d10";
|
||||
|
||||
// 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) {
|
||||
let valeurMin = Math.abs(rollData.diffLibre);
|
||||
formula += "min" + valeurMin;
|
||||
}
|
||||
}
|
||||
// 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) {
|
||||
let valeurMin = Math.abs(rollData.diffLibre);
|
||||
formula += "+" + valeurMin;
|
||||
@ -571,7 +574,7 @@ export class RdDUtility {
|
||||
let roll = await RdDDice.roll(formula, options);
|
||||
|
||||
// 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) {
|
||||
let valeurMin = Math.abs(rollData.diffLibre);
|
||||
if (roll.terms[0].results[0].result < valeurMin) {
|
||||
@ -624,7 +627,7 @@ export class RdDUtility {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static currentFatigueMalus(value, max) {
|
||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||
max = Math.max(1, Math.min(max, 60));
|
||||
value = Math.min(max * 2, Math.max(0, value));
|
||||
|
||||
|
@ -7,7 +7,7 @@ import { RdDBonus } from "./rdd-bonus.js";
|
||||
import { RdDCarac } from "./rdd-carac.js";
|
||||
import { RdDPossession } from "./rdd-possession.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||
|
||||
/**
|
||||
* tous les ajustements pouvant s'appliquer.
|
||||
@ -69,8 +69,8 @@ export const referenceAjustements = {
|
||||
getValue: (rollData, actor) => -actor.getEncTotal()
|
||||
},
|
||||
surenc: {
|
||||
isVisible: (rollData, actor) => actor.isSurenc(),
|
||||
isUsed: (rollData, actor) => rollData.use?.surenc,
|
||||
isVisible: (rollData, actor) => RdDCarac.isActionPhysique(rollData.selectedCarac) && actor.isSurenc(),
|
||||
isUsed: (rollData, actor) => rollData.use?.surenc && RdDCarac.isActionPhysique(rollData.selectedCarac),
|
||||
getLabel: (rollData, actor) => 'Sur-encombrement',
|
||||
getValue: (rollData, actor) => actor.computeMalusSurEncombrement()
|
||||
},
|
||||
@ -86,7 +86,7 @@ export const referenceAjustements = {
|
||||
getValue: (rollData, actor) => actor.getMoralTotal()
|
||||
},
|
||||
astrologique: {
|
||||
isUsed: (rollData, actor) => ReglesOptionelles.isUsing("astrologie") && RdDBonus.isAjustementAstrologique(rollData),
|
||||
isUsed: (rollData, actor) => ReglesOptionnelles.isUsing("astrologie") && RdDBonus.isAjustementAstrologique(rollData),
|
||||
getLabel: (rollData, actor) => 'Astrologique',
|
||||
getValue: (rollData, actor) => actor.ajustementAstrologique()
|
||||
},
|
||||
@ -164,7 +164,7 @@ export class RollDataAjustements {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
122
module/settings/regles-optionnelles.js
Normal file
122
module/settings/regles-optionnelles.js
Normal file
@ -0,0 +1,122 @@
|
||||
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è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",
|
||||
hint: "Ouvre la fenêtre de sélection des compendiums système",
|
||||
icon: "fas fa-bars",
|
||||
restricted: true,
|
||||
type: SystemCompendiums
|
||||
})
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ export class AppAstrologie extends Application {
|
||||
this.selectHeureNaissance(event.currentTarget.attributes['data-heure-naissance'].value);
|
||||
})
|
||||
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();
|
||||
}
|
||||
@ -144,7 +144,7 @@ export class AppAstrologie extends Application {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rebuildNombresAstraux() {
|
||||
async onRebuild() {
|
||||
game.system.rdd.calendrier.resetNombresAstraux();
|
||||
|
||||
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";
|
||||
|
||||
export class DialogRepos extends Dialog {
|
||||
@ -7,7 +7,7 @@ export class DialogRepos extends Dialog {
|
||||
if (!actor.isPersonnage()) {
|
||||
return
|
||||
}
|
||||
if (!ReglesOptionelles.isUsing("chateau-dormant-gardien") || !actor.hasPlayerOwner) {
|
||||
if (!ReglesOptionnelles.isUsing("chateau-dormant-gardien") || !actor.hasPlayerOwner) {
|
||||
actor.system.sommeil = {
|
||||
"nouveaujour": true,
|
||||
"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 { Misc } from "../misc.js";
|
||||
import { DialogChronologie } from "../dialog-chronologie.js";
|
||||
import { HIDE_DICE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "../constants.js";
|
||||
import { ReglesOptionelles } from "../settings/regles-optionelles.js";
|
||||
import { HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "../constants.js";
|
||||
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
|
||||
import { DialogChateauDormant } from "../sommeil/dialog-chateau-dormant.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";
|
||||
|
||||
@ -51,7 +52,7 @@ export class RdDCalendrier extends Application {
|
||||
if (Misc.isUniqueConnectedGM()) { // Uniquement si GM
|
||||
RdDTimestamp.setWorldTime(this.timestamp);
|
||||
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));
|
||||
}
|
||||
@ -84,33 +85,22 @@ export class RdDCalendrier extends Application {
|
||||
}
|
||||
|
||||
display() {
|
||||
AutoAdjustDarkness.adjust(RdDTimestamp.getWorldTime().darkness);
|
||||
const pos = this.getSavePosition()
|
||||
this.render(true, { left: pos.left, top: pos.top });
|
||||
return this;
|
||||
}
|
||||
|
||||
_getHeaderButtons() {
|
||||
const buttons = [];
|
||||
if (game.user.isGM) {
|
||||
buttons.unshift({
|
||||
class: "calendar-astrologie",
|
||||
icon: "fa-solid fa-moon-over-sun",
|
||||
onclick: ev => this.showAstrologieEditor()
|
||||
},
|
||||
{
|
||||
class: "calendar-set-datetime",
|
||||
icon: "fa-solid fa-calendar-pen",
|
||||
onclick: ev => this.showCalendarEditor()
|
||||
});
|
||||
return [
|
||||
{ class: "calendar-astrologie", icon: "fa-solid fa-moon-over-sun", 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 onUpdateSetting(setting, update, options, id) {
|
||||
@ -134,6 +124,7 @@ export class RdDCalendrier extends Application {
|
||||
formData.isGM = game.user.isGM;
|
||||
formData.heures = RdDTimestamp.definitions()
|
||||
formData.horlogeAnalogique = this.horlogeAnalogique;
|
||||
formData.autoDarkness = AutoAdjustDarkness.isAuto()
|
||||
return formData;
|
||||
}
|
||||
|
||||
@ -144,6 +135,7 @@ export class RdDCalendrier extends Application {
|
||||
this.html = html;
|
||||
this.html.find('.ajout-chronologie').click(ev => DialogChronologie.create());
|
||||
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('.horloge-roue .horloge-heure').click(event => {
|
||||
const h = this.html.find(event.currentTarget)?.data('heure');
|
||||
@ -229,15 +221,8 @@ export class RdDCalendrier extends Application {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async ajouterNombreAstral(indexDate, showDice = SHOW_DICE) {
|
||||
const nombreAstral = await RdDDice.rollTotal("1dh", { showDice: showDice, 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}`
|
||||
});
|
||||
}
|
||||
async ajouterNombreAstral(indexDate) {
|
||||
const nombreAstral = await RdDDice.rollTotal("1dh", { showDice: HIDE_DICE, rollMode: "selfroll" });
|
||||
return {
|
||||
nombreAstral: nombreAstral,
|
||||
valeursFausses: [],
|
||||
@ -272,9 +257,8 @@ export class RdDCalendrier extends Application {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rebuildNombresAstraux(showDice = HIDE_DICE) {
|
||||
async rebuildNombresAstraux() {
|
||||
if (Misc.isUniqueConnectedGM()) {
|
||||
console.log("Astral rebuild")
|
||||
let newList = [];
|
||||
for (let i = 0; i < MAX_NOMBRE_ASTRAL; i++) {
|
||||
let dayIndex = this.timestamp.indexDate + i;
|
||||
@ -282,7 +266,7 @@ export class RdDCalendrier extends Application {
|
||||
if (na) {
|
||||
newList[i] = na;
|
||||
} else {
|
||||
newList[i] = await this.ajouterNombreAstral(dayIndex, showDice);
|
||||
newList[i] = await this.ajouterNombreAstral(dayIndex);
|
||||
}
|
||||
}
|
||||
this.nombresAstraux = newList;
|
||||
@ -305,7 +289,7 @@ export class RdDCalendrier extends Application {
|
||||
const oldTimestamp = this.timestamp;
|
||||
await Promise.all(game.actors.map(async actor => await actor.onTimeChanging(oldTimestamp, 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();
|
||||
}
|
||||
this.timestamp = newTimestamp;
|
||||
@ -380,7 +364,7 @@ export class RdDCalendrier extends Application {
|
||||
if (request.rolled.isSuccess) {
|
||||
if (request.rolled.isPart) {
|
||||
// Gestion expérience (si existante)
|
||||
request.competence = actor.getCompetence("astrologie")
|
||||
request.competence = actor.getCompetence('Astrologie')
|
||||
request.selectedCarac = actor.system.carac["vue"];
|
||||
actor.appliquerAjoutExperience(request, 'hide');
|
||||
}
|
||||
@ -452,4 +436,9 @@ export class RdDCalendrier extends Application {
|
||||
async showAstrologieEditor() {
|
||||
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 { Misc } from "../misc.js";
|
||||
import { RdDDice } from "../rdd-dice.js";
|
||||
import { AutoAdjustDarkness } from "./auto-adjust-darkness.js";
|
||||
|
||||
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 DEFINITION_HEURES = [
|
||||
{ key: "vaisseau", label: "Vaisseau", lettreFont: 'v', saison: "Printemps" },
|
||||
{ key: "sirene", label: "Sirène", lettreFont: 'i', saison: "Printemps" },
|
||||
{ key: "faucon", label: "Faucon", lettreFont: 'f', saison: "Printemps" },
|
||||
{ key: "couronne", label: "Couronne", lettreFont: '', saison: "Eté" },
|
||||
{ key: "dragon", label: "Dragon", lettreFont: 'd', saison: "Eté" },
|
||||
{ key: "epees", label: "Epées", lettreFont: 'e', saison: "Eté" },
|
||||
{ key: "lyre", label: "Lyre", lettreFont: 'l', saison: "Automne" },
|
||||
{ key: "serpent", label: "Serpent", lettreFont: 's', saison: "Automne" },
|
||||
{ key: "poissonacrobate", label: "Poisson Acrobate", lettreFont: 'p', saison: "Automne" },
|
||||
{ key: "araignee", label: "Araignée", lettreFont: 'a', saison: "Hiver" },
|
||||
{ key: "roseau", label: "Roseau", lettreFont: 'r', saison: "Hiver" },
|
||||
{ key: "chateaudormant", label: "Château Dormant", lettreFont: 'c', saison: "Hiver" },
|
||||
{ key: "vaisseau", label: "Vaisseau", lettreFont: 'v', saison: "Printemps" , darkness: 0.7},
|
||||
{ key: "sirene", label: "Sirène", lettreFont: 'i', saison: "Printemps" , darkness: 0.4},
|
||||
{ key: "faucon", label: "Faucon", lettreFont: 'f', saison: "Printemps" , darkness: 0},
|
||||
{ key: "couronne", label: "Couronne", lettreFont: '', saison: "Eté" , darkness: 0},
|
||||
{ key: "dragon", label: "Dragon", lettreFont: 'd', saison: "Eté", darkness: 0 },
|
||||
{ key: "epees", label: "Epées", lettreFont: 'e', saison: "Eté", darkness: 0},
|
||||
{ key: "lyre", label: "Lyre", lettreFont: 'l', saison: "Automne", darkness: 0.4 },
|
||||
{ key: "serpent", label: "Serpent", lettreFont: 's', saison: "Automne", darkness: 0.7 },
|
||||
{ key: "poissonacrobate", label: "Poisson Acrobate", lettreFont: 'p', saison: "Automne", darkness: 1 },
|
||||
{ key: "araignee", label: "Araignée", lettreFont: 'a', saison: "Hiver", darkness: 1 },
|
||||
{ key: "roseau", label: "Roseau", lettreFont: 'r', saison: "Hiver", darkness: 1 },
|
||||
{ key: "chateaudormant", label: "Château Dormant", lettreFont: 'c', saison: "Hiver", darkness: 1 },
|
||||
]
|
||||
|
||||
const FORMULES_DUREE = [
|
||||
@ -58,6 +59,7 @@ export class RdDTimestamp {
|
||||
type: Object
|
||||
});
|
||||
|
||||
|
||||
for (let i = 0; i < DEFINITION_HEURES.length; i++) {
|
||||
DEFINITION_HEURES[i].heure = i;
|
||||
DEFINITION_HEURES[i].hh = RdDTimestamp.hh(i);
|
||||
@ -66,7 +68,6 @@ export class RdDTimestamp {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static hh(heure) {
|
||||
return heure < 9 ? `0${heure + 1}` : `${heure + 1}`;
|
||||
}
|
||||
@ -156,7 +157,9 @@ export class RdDTimestamp {
|
||||
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) {
|
||||
heure = Grammar.toLowerCaseNoAccentNoSpace(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 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
|
||||
* pour afficher la date et l'heure
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Misc } from "./misc.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
import { tmrConstants } from "./tmr-constants.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const TMRMapping = {
|
||||
@ -163,7 +164,7 @@ const TMRMapping = {
|
||||
C12: { type: "lac", label: "Lac de Fricassa" },
|
||||
D12: { type: "collines", label: "Collines d’Huaï" },
|
||||
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" },
|
||||
H12: { type: "collines", label: "Collines de Tooth" },
|
||||
I12: { type: "gouffre", label: "Gouffre Abimeux" },
|
||||
@ -199,7 +200,7 @@ const TMRMapping = {
|
||||
K14: { type: "necropole", label: "Nécropole d’Antinéar" },
|
||||
L14: { type: "plaines", label: "Plaines de Jislith" },
|
||||
M14: { type: "desolation", label: "Désolation d’Après" },
|
||||
|
||||
|
||||
A15: { type: "cite", label: "Cité de Mielh" },
|
||||
C15: { type: "plaines", label: "Plaines de Toué" },
|
||||
E15: { type: "foret", label: "Forêt des Furies" },
|
||||
@ -274,11 +275,11 @@ export class TMRUtility {
|
||||
const tmr = TMRUtility.getTMR(coord);
|
||||
return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label;
|
||||
}
|
||||
|
||||
static findTMRLike(type, options = {inclusMauvaise:true}) {
|
||||
|
||||
static findTMRLike(type, options = { inclusMauvaise: true }) {
|
||||
const choix = [...Object.values(TMRType)]
|
||||
if (options.inclusMauvaise){
|
||||
choix.push({name: 'Mauvaise'});
|
||||
if (options.inclusMauvaise) {
|
||||
choix.push({ name: 'Mauvaise' });
|
||||
}
|
||||
const selection = Misc.findAllLike(type, choix).map(it => it.name);
|
||||
if (selection.length == 0) {
|
||||
@ -297,7 +298,7 @@ export class TMRUtility {
|
||||
}
|
||||
|
||||
static buildSelectionTypesTMR(typesTMR) {
|
||||
typesTMR = typesTMR?? [];
|
||||
typesTMR = typesTMR ?? [];
|
||||
return Object.values(TMRType).map(value => Misc.upperFirst(value.name))
|
||||
.sort()
|
||||
.map(name => { return { name: name, selected: typesTMR.includes(name) } });
|
||||
@ -375,6 +376,36 @@ export class TMRUtility {
|
||||
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
|
||||
// TMR Letter-row correspond to "odd-q" grid (letter => col, numeric => row )
|
||||
@ -400,7 +431,7 @@ export class TMRUtility {
|
||||
col >= 0 && col < 13 &&
|
||||
row >= 0 &&
|
||||
(row + col % 2 <= 14)
|
||||
);
|
||||
);
|
||||
// if (x >= 0 && x < 13 && y >= 0 && y < 14) return true;
|
||||
// if (x >= 0 && x < 13 && x % 2 == 0 && y == 14) return true;
|
||||
// return false;
|
||||
@ -444,7 +475,7 @@ export class TMRUtility {
|
||||
|
||||
static axial_subtract(a, b) {
|
||||
return {
|
||||
q: a.q- b.q,
|
||||
q: a.q - b.q,
|
||||
r: a.r - b.r
|
||||
};
|
||||
}
|
||||
@ -456,7 +487,7 @@ export class TMRUtility {
|
||||
// return Cube(q, r, s)
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// /* -------------------------------------------- */
|
||||
// static computeRealPictureCoordinates(coordOddq) {
|
||||
// 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 {
|
||||
|
||||
constructor() {
|
||||
console.log("Sprite create 1!!!!")
|
||||
super();
|
||||
}
|
||||
|
||||
@ -14,9 +13,25 @@ export class CarteTmr extends Draconique {
|
||||
async onActorCreateOwned(actor, item) { }
|
||||
|
||||
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) {
|
||||
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 {
|
||||
static isCaseTMR(item) { return item.type == TYPES.casetmr; }
|
||||
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 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é),
|
||||
* un disque est utilisé.
|
||||
*/
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
*/
|
||||
token(pixiTMR, linkData, coordTMR, type = undefined) {
|
||||
const token = {
|
||||
sprite: this.createSprite(pixiTMR),
|
||||
coordTMR: coordTMR
|
||||
};
|
||||
token[type ?? this.code()] = linkData;
|
||||
console.log("SPRITE: ", token.sprite)
|
||||
//PixiTMR.getImgFromCode()
|
||||
pixiTMR.addTooltip(token.sprite, this.tooltip(linkData));
|
||||
this.linkData = linkData;
|
||||
if (this.tooltip(linkData)) {
|
||||
pixiTMR.addTooltip(token.sprite, (e, s) => this.computeTooltip(e, s));
|
||||
}
|
||||
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
|
||||
* @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) {
|
||||
return Draconique.isCaseTMR(item) && item.system.specific == this.code() && (coord ? item.system.coord == coord : true);
|
||||
}
|
||||
|
||||
|
||||
find(list, coord = undefined) {
|
||||
return list.find(c => this.isCase(c, coord));
|
||||
}
|
||||
|
||||
|
||||
async createCaseTmr(actor, label, tmr, sourceId = undefined) {
|
||||
const casetmrData = {
|
||||
name: label, type: 'casetmr', img: this.img(),
|
||||
@ -130,12 +150,12 @@ export class Draconique {
|
||||
};
|
||||
await actor.createEmbeddedDocuments('Item', [casetmrData]);
|
||||
}
|
||||
|
||||
|
||||
async deleteCasesTmr(actor, draconique) {
|
||||
let caseTmrs = actor.items.filter(it => this.isCaseForSource(it, draconique));
|
||||
await actor.deleteEmbeddedDocuments('Item', caseTmrs.map(it => it.id));
|
||||
}
|
||||
|
||||
|
||||
isCaseForSource(item, draconique) {
|
||||
return Draconique.isCaseTMR(item) && item.system.specific == this.code() && item.system.sourceid == draconique.id;
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { RdDTMRDialog } from "../rdd-tmr-dialog.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',
|
||||
fontSize: 18,
|
||||
fill: '#FFFFFF',
|
||||
@ -20,7 +22,7 @@ export class PixiTMR {
|
||||
this.callbacksOnAnimate = [];
|
||||
}
|
||||
|
||||
async load( onLoad = (loader, resources) => {} ) {
|
||||
async load(onLoad = (loader, resources) => { }) {
|
||||
// WIP - Deprecated since v7 : let loader = new PIXI.Loader();
|
||||
for (const [name, img] of Object.entries(PixiTMR.textures)) {
|
||||
const texture = await PIXI.Assets.load(img);
|
||||
@ -40,40 +42,17 @@ export class PixiTMR {
|
||||
PixiTMR.textures[name] = img;
|
||||
}
|
||||
|
||||
animate(animation = pixiApp=>{})
|
||||
{
|
||||
animate(animation = 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 = {}) {
|
||||
let img = PixiTMR.getImgFromCode(code)
|
||||
const texture = PIXI.utils.TextureCache[img];
|
||||
if (!texture) {
|
||||
console.error("Texture manquante", code, PIXI.utils.TextureCache)
|
||||
return;
|
||||
}
|
||||
}
|
||||
let sprite = new PIXI.Sprite(texture);
|
||||
sprite.width = options.taille ?? tmrConstants.half;
|
||||
sprite.height = options.taille ?? tmrConstants.half;
|
||||
@ -81,13 +60,13 @@ export class PixiTMR {
|
||||
if (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.decallage = options.decallage ?? tmrConstants.center;
|
||||
this.pixiApp.stage.addChild(sprite);
|
||||
return sprite;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
circle(name, options = {}) {
|
||||
let sprite = new PIXI.Graphics();
|
||||
sprite.beginFill(options.color, options.opacity);
|
||||
@ -98,27 +77,37 @@ export class PixiTMR {
|
||||
return sprite;
|
||||
}
|
||||
|
||||
addTooltip(sprite, text) {
|
||||
if (text) {
|
||||
sprite.tooltip = new PIXI.Text(text, tooltipStyle);
|
||||
sprite.tooltip.zIndex = tmrTokenZIndex.tooltip;
|
||||
sprite.isOver = false;
|
||||
// Deprecated : sprite.interactive = true;
|
||||
sprite.eventMode = 'dynamic'; // PIXI 7 To be checked
|
||||
sprite.on('pointerdown', event => this.onClickBackground(event))
|
||||
.on('pointerover', () => this.onShowTooltip(sprite))
|
||||
.on('pointerout', () => this.onHideTooltip(sprite));
|
||||
}
|
||||
addTooltip(sprite, computeTooltip) {
|
||||
sprite.tooltip = new PIXI.Text('', tooltipStyle);
|
||||
sprite.tooltip.zIndex = tmrTokenZIndex.tooltip;
|
||||
sprite.isOver = false;
|
||||
sprite.eventMode = 'static';
|
||||
sprite
|
||||
.on('pointermove', event => this.onPointerMove(event, sprite, computeTooltip))
|
||||
.on('pointerdown', event => this.onClickBackground(event))
|
||||
.on('pointerover', event => this.onShowTooltip(event, sprite))
|
||||
.on('pointerout', event => this.onHideTooltip(event, sprite));
|
||||
}
|
||||
|
||||
|
||||
onClickBackground(event) {
|
||||
this.tmrObject.onClickTMR(event)
|
||||
if (!this.viewOnly) {
|
||||
this.tmrObject.onClickTMR(event)
|
||||
}
|
||||
}
|
||||
|
||||
onShowTooltip(sprite) {
|
||||
if (sprite.tooltip) {
|
||||
onPointerMove(event, sprite, computeTooltip) {
|
||||
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) {
|
||||
sprite.tooltip.x = sprite.x;
|
||||
sprite.tooltip.y = sprite.y;
|
||||
@ -128,7 +117,7 @@ export class PixiTMR {
|
||||
}
|
||||
}
|
||||
|
||||
onHideTooltip(sprite) {
|
||||
onHideTooltip(event, sprite) {
|
||||
if (sprite.tooltip) {
|
||||
if (sprite.isOver) {
|
||||
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 dx = (sprite.decallage == undefined) ? 0 : sprite.decallage.x;
|
||||
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 buttons = {};
|
||||
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",
|
||||
content: `La ${this.tmrLabel(casetmr)} vous offre un présent, faites votre choix`,
|
||||
buttons: buttons
|
||||
});
|
||||
d.render(true);
|
||||
dialog.render(true);
|
||||
return dialog
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
.tmr-dialog table {
|
||||
border: none;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .sheet-header div.tmr-buttons {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
@ -287,6 +290,16 @@ table {border: 1px solid #7a7971;}
|
||||
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-column: span 3 / span 3;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
@ -1898,34 +1911,51 @@ div.calendar-timestamp-edit select.calendar-signe-heure {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.chat-card-button {
|
||||
box-shadow: inset 0px 1px 0px 0px #a6827e;
|
||||
background: var(--background-custom-button);
|
||||
background-color: #7d5d3b00;
|
||||
border-radius: 3px;
|
||||
border: 2px ridge #846109;
|
||||
display: inline-block;
|
||||
.chat-card-button, .chat-card-button-pushed {
|
||||
border-radius: 0.2rem;
|
||||
cursor: pointer;
|
||||
color: #ffffff;
|
||||
font-family: CaslonPro;
|
||||
font-size: 0.9rem;
|
||||
padding: 4px 12px 0px 12px;
|
||||
padding: 0.2rem 0.4rem 0rem 0.4rem;
|
||||
text-decoration: none;
|
||||
text-shadow: 0px 1px 0px #4d3534;
|
||||
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 {
|
||||
background: var(--background-custom-button-hover);
|
||||
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;
|
||||
top:1px;
|
||||
}
|
||||
|
||||
/* Dropdown Content (Hidden by Default) */
|
||||
.button-dropdown-content {
|
||||
display: none;
|
||||
|
@ -1,14 +1,13 @@
|
||||
{
|
||||
"id": "foundryvtt-reve-de-dragon",
|
||||
"title": "Rêve de Dragon",
|
||||
"version": "11.0.8",
|
||||
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-11.0.8.zip",
|
||||
"version": "11.0.28",
|
||||
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-11.0.28.zip",
|
||||
"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": {
|
||||
"minimum": "11",
|
||||
"verified": "11",
|
||||
"maximum": "11"
|
||||
"verified": "11"
|
||||
},
|
||||
"description": "Rêve de Dragon RPG for FoundryVTT",
|
||||
"authors": [
|
||||
|
@ -393,12 +393,6 @@
|
||||
"label": "Encombrement",
|
||||
"derivee": true
|
||||
},
|
||||
"malusarmure": {
|
||||
"type": "number",
|
||||
"value": 0,
|
||||
"label": "Malus Armure",
|
||||
"derivee": true
|
||||
},
|
||||
"protection": {
|
||||
"type": "number",
|
||||
"value": 0,
|
||||
@ -594,7 +588,8 @@
|
||||
"iscombat": false,
|
||||
"isnaturelle": true,
|
||||
"ispossession": false,
|
||||
"dommages": 0
|
||||
"dommages": 0,
|
||||
"mortalite": "mortel"
|
||||
},
|
||||
"empoignade": {
|
||||
"templates": ["description"],
|
||||
@ -671,6 +666,7 @@
|
||||
"resistance": 0,
|
||||
"categorie_parade": "",
|
||||
"dommages": "0",
|
||||
"mortalite": "mortel",
|
||||
"penetration": 0,
|
||||
"force": "0",
|
||||
"competence": "",
|
||||
|
@ -53,7 +53,9 @@
|
||||
{{#if options.isObserver}}{{!-- Compétences Tab --}}
|
||||
<div class="tab competences" data-group="primary" data-tab="competences">
|
||||
<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">
|
||||
{{#if options.showCompNiveauBase}}
|
||||
<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=""/>
|
||||
</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>
|
||||
</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">
|
||||
{{> "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"}}
|
||||
@ -83,6 +93,11 @@
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.draconic) categorie="Draconic"}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#if (and options.vueDetaillee options.vueArchetype)}}
|
||||
<div>
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/archetype.hbs"}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{/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 class="caracteristique flexrow list-item" >
|
||||
<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 class="caracteristique flexrow list-item">
|
||||
<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}}"
|
||||
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}}
|
||||
<span class="competence-xp {{#unless system.isLevelUp}}tooltip{{/unless}}">
|
||||
<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}}
|
||||
<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}}
|
||||
@ -28,7 +29,7 @@
|
||||
{{#if (eq system.categorie 'draconic')}}
|
||||
<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"
|
||||
{{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
|
||||
{{#if (or (not @root.options.vueDetaillee) @root.options.vueArchetype)}}disabled{{/if}} />
|
||||
{{/if}}
|
||||
{{#if @root.options.vueDetaillee}}
|
||||
<div class="item-controls">
|
||||
@ -41,7 +42,8 @@
|
||||
<i class="far fa-circle"></i>
|
||||
{{/if}}
|
||||
<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>
|
||||
{{#if @root.options.isGM}}
|
||||
<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="competence-value">{{calc.competenceXPTotal}}</span>
|
||||
</li>
|
||||
{{#if calc.comptageArchetype}}
|
||||
<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}}
|
||||
{{/if}}
|
||||
<li> </li>
|
||||
</ul>
|
||||
</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>Son état général est de : {{etatGeneral}} {{#if isSonne}} et est <strong>sonné</strong>{{/if}}</div>
|
||||
{{#if isGrave}}
|
||||
@ -6,5 +6,7 @@
|
||||
{{/if}}
|
||||
{{#if isCritique}}
|
||||
<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}}
|
@ -1,6 +1,6 @@
|
||||
{{#if use.moral}}
|
||||
<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!.
|
||||
{{else if (eq perteMoralEchec 'perte')}}et échoué, votre moral baisse à {{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}}" />
|
||||
<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>
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
||||
<hr>
|
||||
<div>
|
||||
{{#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}}
|
||||
{{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}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
|
||||
</div>
|
||||
|
@ -1,14 +1,14 @@
|
||||
<img class="chat-icon" src="{{competence.img}}" alt="{{oeuvre.system.competence}}" />
|
||||
<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>
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
||||
<hr>
|
||||
<div>
|
||||
{{#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}}
|
||||
{{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}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
|
||||
</div>
|
||||
|
@ -26,7 +26,7 @@
|
||||
{{#if (eq dmg.mortalite 'entiteincarnee')}}subit le coup
|
||||
{{else if mort}}vient de mourir
|
||||
{{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
|
||||
{{~/if~}}
|
||||
{{else}}s'en sort sans une égratignure
|
||||
|
@ -1,6 +1,6 @@
|
||||
<img class="chat-icon" src="{{competence.img}}" alt="{{oeuvre.system.competence}}" />
|
||||
<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>
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
||||
<hr>
|
||||
@ -8,7 +8,7 @@
|
||||
{{#if rolled.isSuccess}}
|
||||
{{alias}} réussit son interprétation avec une qualité de {{qualiteFinale}} .
|
||||
{{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}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
|
||||
</div>
|
||||
|
@ -7,9 +7,9 @@
|
||||
<hr>
|
||||
<div>
|
||||
{{#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}}
|
||||
{{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}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html"}}
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<img class="chat-icon" src="{{competence.img}}" alt="{{oeuvre.system.competence}}" />
|
||||
<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>
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
|
||||
<hr>
|
||||
|
@ -1,13 +1,29 @@
|
||||
<form class="skill-roll-dialog">
|
||||
<img class="chat-icon" src="{{competence.img}}" alt="{{competence.name}}"/>
|
||||
<h2 class="dialog-roll-title"></h2>
|
||||
|
||||
<div class="grid grid-2col">
|
||||
<div class="flex-group-left">
|
||||
<img class="chat-icon" src="{{competence.img}}" alt="{{competence.name}}"/>
|
||||
<div class="flexrow">
|
||||
<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>
|
||||
{{#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 attackerRoll}}
|
||||
{{#if attackerRoll.tactique}}
|
||||
@ -27,41 +43,28 @@
|
||||
<div class="tooltiptext ttt-ajustements">
|
||||
<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.
|
||||
<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>
|
||||
</span>
|
||||
</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">
|
||||
<label>Dégats:</label>
|
||||
{{#if (eq arme.system.mortalite 'non-mortel')}}
|
||||
<label class="dmg-arme-actor"></label>
|
||||
{{else if (eq arme.system.mortalite 'empoignade')}}
|
||||
{{#if (eq arme.system.mortalite 'empoignade')}}
|
||||
<label>Empoignade</label>
|
||||
{{else}}
|
||||
<span>
|
||||
<input class="attribute-value" type="checkbox" name="coupsNonMortels" {{#unless (eq mortalite 'mortel')}}checked{{/unless}} />
|
||||
<label class="dmg-arme-actor"></label>
|
||||
{{#unless (eq arme.system.mortalite 'non-mortel')}}
|
||||
<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>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
<div class="flexrow"></div>
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-surenc.html"}}
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-enctotal.html"}}
|
||||
</div>
|
||||
@ -75,6 +78,7 @@
|
||||
{{>"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-moral.html"}}
|
||||
<div class="flexrow"></div>
|
||||
<div class="placeholder-ajustements" class="flexrow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,8 +1,7 @@
|
||||
<form class="tmr-dialog">
|
||||
<h2 class="comptmrdialog" id="tmrDialogTitle"></h2>
|
||||
|
||||
<table id="tmrsheet">
|
||||
<tr id="tmrrow1">
|
||||
<h2 class="comptmrdialog" id="tmrDialogTitle" style="visibility: hidden;"></h2>
|
||||
<table>
|
||||
<tr class="tmr-row">
|
||||
<td>
|
||||
{{#if (eq mode "visu")}}
|
||||
<div class="flex-group-center">
|
||||
@ -54,6 +53,5 @@
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</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>
|
||||
<input class="attribute-value" type="text" name="system.dommages" value="{{system.dommages}}" data-dtype="String"/>
|
||||
</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">
|
||||
<label for="system.resistance">Résistance </label>
|
||||
<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>
|
||||
<input class="attribute-value" type="text" name="system.dommages" value="{{system.dommages}}" data-dtype="Number"/>
|
||||
</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 isparade}}
|
||||
<div class="form-group">
|
||||
|
@ -16,6 +16,7 @@
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="horloge-digitale">
|
||||
|
||||
<span>
|
||||
<a class="toggle-horloge-analogique">
|
||||
{{#if horlogeAnalogique}}
|
||||
@ -33,6 +34,15 @@
|
||||
{{#if isGM}}
|
||||
<span class="calendar-minute-texte">{{minute}} minutes</span>
|
||||
{{/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 class="horloge-analogique {{#unless horlogeAnalogique}}horloge-analogique-hidden{{/unless}}">
|
||||
{{> 'systems/foundryvtt-reve-de-dragon/templates/time/horloge.hbs' }}
|
||||
|
Reference in New Issue
Block a user