2020-05-22 22:37:02 +02:00
/* Common useful functions shared between objects */
2020-11-24 15:20:05 +01:00
import { ChatUtility } from "./chat-utility.js" ;
2021-03-15 00:07:53 +01:00
import { RdDCombat } from "./rdd-combat.js" ;
2021-02-06 01:34:01 +01:00
import { Misc } from "./misc.js" ;
2021-02-06 21:53:25 +01:00
import { Grammar } from "./grammar.js" ;
2021-05-04 12:22:19 +02:00
import { TMRUtility } from "./tmr-utility.js" ;
2021-05-07 17:27:02 +02:00
import { DialogItemAchat } from "./dialog-item-achat.js" ;
2021-05-08 20:08:56 +02:00
import { ReglesOptionelles } from "./regles-optionelles.js" ;
2021-05-11 21:45:43 +02:00
import { RdDDice } from "./rdd-dice.js" ;
2021-06-02 16:04:35 +02:00
import { RdDItem } from "./item.js" ;
2021-06-02 17:39:16 +02:00
import { Monnaie } from "./item-monnaie.js" ;
2021-11-21 12:04:42 +01:00
import { RdDPossession } from "./rdd-possession.js" ;
2022-07-22 01:31:21 +02:00
import { RdDNameGen } from "./rdd-namegen.js" ;
2020-06-11 00:29:32 +02:00
2020-12-02 20:52:37 +01:00
/* -------------------------------------------- */
2020-08-13 22:28:56 +02:00
// This table starts at 0 -> niveau -10
2021-01-08 22:23:50 +01:00
const carac _array = [ "taille" , "apparence" , "constitution" , "force" , "agilite" , "dexterite" , "vue" , "ouie" , "odoratgout" , "volonte" , "intellect" , "empathie" , "reve" , "chance" , "melee" , "tir" , "lancer" , "derobee" ] ;
const difficultesLibres = [ 0 , - 1 , - 2 , - 3 , - 4 , - 5 , - 6 , - 7 , - 8 , - 9 , - 10 ] ;
const ajustementsConditions = [ - 10 , - 9 , - 8 , - 7 , - 6 , - 5 , - 4 , - 3 , - 2 , - 1 , 0 , + 1 , + 2 , + 3 , + 4 , + 5 , + 6 , + 7 , + 8 , + 9 , + 10 ] ;
const ajustementsEncaissement = [ - 10 , - 9 , - 8 , - 7 , - 6 , - 5 , - 4 , - 3 , - 2 , - 1 , 0 , + 1 , + 2 , + 3 , + 4 , + 5 , + 6 , + 7 , + 8 , + 9 , + 10 , + 11 , + 12 , + 13 , + 14 , + 15 , + 16 , + 17 , + 18 , + 19 , + 20 , + 21 , + 22 , + 23 , + 24 , + 25 ] ;
2021-01-13 22:16:23 +01:00
2020-12-02 20:52:37 +01:00
/* -------------------------------------------- */
2020-11-17 13:08:52 +01:00
function _buildAllSegmentsFatigue ( max ) {
const cycle = [ 5 , 2 , 4 , 1 , 3 , 0 ] ;
let fatigue = [ [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ] ;
2020-11-18 20:16:59 +01:00
for ( let i = 0 ; i <= max ; i ++ ) {
2021-01-08 22:23:50 +01:00
const ligneFatigue = duplicate ( fatigue [ i ] ) ;
2020-11-17 13:08:52 +01:00
const caseIncrementee = cycle [ i % 6 ] ;
ligneFatigue [ caseIncrementee ] ++ ;
ligneFatigue [ caseIncrementee + 6 ] ++ ;
ligneFatigue . fatigueMax = 2 * ( i + 1 ) ;
2021-01-08 22:23:50 +01:00
fatigue [ i + 1 ] = ligneFatigue ;
2020-11-17 13:08:52 +01:00
}
return fatigue ;
}
2020-12-02 20:52:37 +01:00
/* -------------------------------------------- */
2020-11-18 20:16:59 +01:00
function _cumulSegmentsFatigue ( matrix ) {
let cumulMatrix = [ ] ;
2021-01-08 22:23:50 +01:00
for ( let line of matrix ) {
2020-11-18 20:16:59 +01:00
let cumul = duplicate ( line ) ;
2021-01-08 22:23:50 +01:00
2020-11-18 20:16:59 +01:00
for ( let i = 1 ; i < 12 ; i ++ ) {
cumul [ i ] += cumul [ i - 1 ] ;
}
cumulMatrix . push ( cumul ) ;
}
return cumulMatrix ;
}
2020-11-17 13:08:52 +01:00
2020-12-02 20:52:37 +01:00
/* -------------------------------------------- */
2020-12-17 22:11:52 +01:00
const fatigueMatrix = _buildAllSegmentsFatigue ( 60 ) ;
2020-11-18 20:16:59 +01:00
const cumulFatigueMatrix = _cumulSegmentsFatigue ( fatigueMatrix ) ;
2020-11-17 13:08:52 +01:00
2021-01-08 22:23:50 +01:00
const fatigueMalus = [ 0 , 0 , 0 , - 1 , - 1 , - 1 , - 2 , - 3 , - 4 , - 5 , - 6 , - 7 ] ; // Provides the malus for each segment of fatigue
const fatigueLineSize = [ 3 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ] ;
const fatigueLineMalus = [ 0 , - 1 , - 2 , - 3 , - 4 , - 5 , - 6 , - 7 ] ;
const fatigueMarche = {
"aise" : { "4" : 1 , "6" : 2 , "8" : 3 , "10" : 4 , "12" : 6 } ,
"malaise" : { "4" : 2 , "6" : 3 , "8" : 4 , "10" : 6 } ,
"difficile" : { "4" : 3 , "6" : 4 , "8" : 6 } ,
"tresdifficile" : { "4" : 4 , "6" : 6 }
}
2020-12-06 21:11:30 +01:00
2020-12-02 20:52:37 +01:00
/* -------------------------------------------- */
2020-11-24 18:54:13 +01:00
const definitionsBlessures = [
{ type : "legere" , facteur : 2 } ,
2021-01-08 22:23:50 +01:00
{ type : "grave" , facteur : 4 } ,
{ type : "critique" , facteur : 6 }
2020-11-24 18:54:13 +01:00
]
2020-12-06 21:11:30 +01:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
const nomEthylisme = [ "Emeché" , "Gris" , "Pinté" , "Pas frais" , "Ivre" , "Bu" , "Complètement fait" , "Ivre mort" ] ;
2020-12-06 21:11:30 +01:00
2020-12-02 20:52:37 +01:00
/* -------------------------------------------- */
2020-11-11 04:21:25 +01:00
const definitionsEncaissement = {
"mortel" : [
2021-01-09 19:38:24 +01:00
{ minimum : undefined , maximum : 0 , endurance : "0" , vie : "0" , eraflures : 0 , legeres : 0 , graves : 0 , critiques : 0 } ,
{ minimum : 1 , maximum : 10 , endurance : "1d4" , vie : "0" , eraflures : 1 , legeres : 0 , graves : 0 , critiques : 0 } ,
{ minimum : 11 , maximum : 15 , endurance : "1d6" , vie : "0" , eraflures : 0 , legeres : 1 , graves : 0 , critiques : 0 } ,
{ minimum : 16 , maximum : 19 , endurance : "2d6" , vie : "2" , eraflures : 0 , legeres : 0 , graves : 1 , critiques : 0 } ,
{ minimum : 20 , maximum : undefined , endurance : "100" , vie : "4 + @over20" , eraflures : 0 , legeres : 0 , graves : 0 , critiques : 1 } ,
2020-11-11 04:21:25 +01:00
] ,
"non-mortel" : [
2021-01-09 19:38:24 +01:00
{ minimum : undefined , maximum : 0 , endurance : "0" , vie : "0" , eraflures : 0 , legeres : 0 , graves : 0 , critiques : 0 } ,
{ minimum : 1 , maximum : 10 , endurance : "1d4" , vie : "0" , eraflures : 1 , legeres : 0 , graves : 0 , critiques : 0 } ,
{ minimum : 11 , maximum : 15 , endurance : "1d6" , vie : "0" , eraflures : 1 , legeres : 0 , graves : 0 , critiques : 0 } ,
{ minimum : 16 , maximum : 19 , endurance : "2d6" , vie : "0" , eraflures : 0 , legeres : 1 , graves : 0 , critiques : 0 } ,
{ minimum : 20 , maximum : undefined , endurance : "100" , vie : "0" , eraflures : 0 , legeres : 1 , graves : 0 , critiques : 0 } ,
2020-11-11 04:21:25 +01:00
] ,
"cauchemar" : [
2021-01-09 19:38:24 +01:00
{ minimum : undefined , maximum : 0 , endurance : "0" , vie : "0" , eraflures : 0 , legeres : 0 , graves : 0 , critiques : 0 } ,
{ minimum : 1 , maximum : 10 , endurance : "1d4" , vie : "0" , eraflures : 1 , legeres : 0 , graves : 0 , critiques : 0 } ,
{ minimum : 11 , maximum : 15 , endurance : "1d6" , vie : "0" , eraflures : 1 , legeres : 0 , graves : 0 , critiques : 0 } ,
{ minimum : 16 , maximum : 19 , endurance : "2d6" , vie : "0" , eraflures : 1 , legeres : 0 , graves : 0 , critiques : 0 } ,
{ minimum : 20 , maximum : undefined , endurance : "3d6 + @over20" , vie : "0" , eraflures : 1 , legeres : 0 , graves : 0 , critiques : 0 } ,
2020-11-11 04:21:25 +01:00
]
} ;
2020-07-06 09:03:21 +02:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
export class RdDUtility {
2021-03-29 23:41:08 +02:00
/* -------------------------------------------- */
static async init ( ) {
Hooks . on ( "renderChatMessage" , async ( app , html , msg ) => RdDUtility . onRenderChatMessage ( app , html , msg ) ) ;
2022-09-07 18:47:56 +02:00
Hooks . on ( 'renderChatLog' , ( log , html , chatLog ) => RdDUtility . chatListeners ( html ) ) ;
2021-03-29 23:41:08 +02:00
}
2020-05-24 20:19:57 +02:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static async preloadHandlebarsTemplates ( ) {
2020-05-24 20:19:57 +02:00
const templatePaths = [
//Character Sheets
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html' ,
2020-11-04 16:29:10 +01:00
'systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.html' ,
2020-11-14 23:24:01 +01:00
'systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.html' ,
2021-01-10 22:12:07 +01:00
'systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.html' ,
2021-01-14 10:32:15 +01:00
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-competence-partial.html' ,
2021-05-04 11:38:23 +02:00
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-categorie-competences-partial.html' ,
2021-06-29 00:56:25 +02:00
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-effects-partial.html' ,
2021-05-04 11:38:23 +02:00
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-oeuvre-partial.html' ,
2021-04-27 00:30:46 +02:00
'systems/foundryvtt-reve-de-dragon/templates/actor-liste-blessures-partial.html' ,
'systems/foundryvtt-reve-de-dragon/templates/actor-blessure-partial.html' ,
2021-05-04 12:19:49 +02:00
// Conteneur/item in Actor sheet
2022-08-27 16:23:22 +02:00
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire.html' ,
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire-item.html' ,
2021-06-02 16:04:35 +02:00
"systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire-monnaie.html" ,
2022-08-27 16:23:22 +02:00
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-liens-animaux.html' ,
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-liens-suivants.html' ,
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-liens-vehicules.html' ,
2021-05-04 12:19:49 +02:00
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-editor-notes-mj.html' ,
2020-05-24 20:19:57 +02:00
//Items
2022-09-16 02:20:46 +02:00
'systems/foundryvtt-reve-de-dragon/templates/header-item.html' ,
2020-05-24 20:19:57 +02:00
'systems/foundryvtt-reve-de-dragon/templates/item-competence-sheet.html' ,
2020-09-20 16:36:39 +02:00
'systems/foundryvtt-reve-de-dragon/templates/item-competencecreature-sheet.html' ,
2020-06-07 23:16:29 +02:00
'systems/foundryvtt-reve-de-dragon/templates/item-arme-sheet.html' ,
2020-06-23 23:34:12 +02:00
'systems/foundryvtt-reve-de-dragon/templates/item-armure-sheet.html' ,
2020-06-25 23:18:14 +02:00
'systems/foundryvtt-reve-de-dragon/templates/item-objet-sheet.html' ,
'systems/foundryvtt-reve-de-dragon/templates/item-conteneur-sheet.html' ,
2020-06-26 15:47:44 +02:00
'systems/foundryvtt-reve-de-dragon/templates/item-sort-sheet.html' ,
2020-06-29 23:21:15 +02:00
'systems/foundryvtt-reve-de-dragon/templates/item-herbe-sheet.html' ,
'systems/foundryvtt-reve-de-dragon/templates/item-ingredient-sheet.html' ,
'systems/foundryvtt-reve-de-dragon/templates/item-livre-sheet.html' ,
'systems/foundryvtt-reve-de-dragon/templates/item-tache-sheet.html' ,
'systems/foundryvtt-reve-de-dragon/templates/item-potion-sheet.html' ,
2020-11-10 13:53:51 +01:00
'systems/foundryvtt-reve-de-dragon/templates/item-rencontresTMR-sheet.html' ,
2020-07-20 12:02:07 +02:00
'systems/foundryvtt-reve-de-dragon/templates/item-queue-sheet.html' ,
'systems/foundryvtt-reve-de-dragon/templates/item-souffle-sheet.html' ,
2020-11-09 23:56:25 +01:00
'systems/foundryvtt-reve-de-dragon/templates/item-tarot-sheet.html' ,
2020-07-20 12:02:07 +02:00
'systems/foundryvtt-reve-de-dragon/templates/item-tete-sheet.html' ,
'systems/foundryvtt-reve-de-dragon/templates/item-ombre-sheet.html' ,
2020-12-31 00:55:02 +01:00
'systems/foundryvtt-reve-de-dragon/templates/item-monnaie-sheet.html' ,
2021-01-03 00:44:52 +01:00
'systems/foundryvtt-reve-de-dragon/templates/item-meditation-sheet.html' ,
2021-04-06 23:43:53 +02:00
'systems/foundryvtt-reve-de-dragon/templates/item-nourritureboisson-sheet.html' ,
2021-05-10 19:17:31 +02:00
'systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html' ,
2022-06-12 08:17:59 +02:00
'systems/foundryvtt-reve-de-dragon/templates/item-possession-sheet.html' ,
2020-05-24 20:19:57 +02:00
'systems/foundryvtt-reve-de-dragon/templates/competence-carac-defaut.html' ,
'systems/foundryvtt-reve-de-dragon/templates/competence-base.html' ,
2020-11-09 23:56:25 +01:00
'systems/foundryvtt-reve-de-dragon/templates/enum-aspect-tarot.html' ,
2021-01-08 22:23:50 +01:00
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-competence.html' ,
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-ingredient.html' ,
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-parade.html' ,
2021-01-10 22:12:07 +01:00
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-vehicule.html' ,
2021-01-08 22:23:50 +01:00
'systems/foundryvtt-reve-de-dragon/templates/enum-competence.html' ,
2021-04-04 09:37:35 +02:00
'systems/foundryvtt-reve-de-dragon/templates/enum-herbesoin-ingredient.html' ,
2021-04-10 21:07:53 +02:00
'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-potion.html' ,
2021-02-05 09:36:42 +01:00
'systems/foundryvtt-reve-de-dragon/templates/enum-initpremierround.html' ,
2020-11-09 22:35:26 +01:00
'systems/foundryvtt-reve-de-dragon/templates/enum-rarete.html' ,
2020-06-26 15:47:44 +02:00
'systems/foundryvtt-reve-de-dragon/templates/sort-draconic.html' ,
'systems/foundryvtt-reve-de-dragon/templates/sort-tmr.html' ,
2020-12-18 23:35:53 +01:00
'systems/foundryvtt-reve-de-dragon/templates/niveau-ethylisme.html' ,
2020-12-30 21:17:58 +01:00
'systems/foundryvtt-reve-de-dragon/templates/casetmr-specific-list.html' ,
2020-05-24 20:19:57 +02:00
// Dialogs
2020-12-21 23:35:29 +01:00
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html' ,
2021-10-30 01:34:57 +02:00
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' ,
2020-07-05 21:45:25 +02:00
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html' ,
2020-07-23 22:09:40 +02:00
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html' ,
2020-11-10 13:53:51 +01:00
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-encaisser.html' ,
2021-01-04 22:03:00 +01:00
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-meditation.html' ,
2020-09-20 16:36:39 +02:00
'systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html' ,
2021-01-07 20:04:10 +01:00
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-alchimie.html' ,
2020-12-11 08:29:24 +01:00
'systems/foundryvtt-reve-de-dragon/templates/dialog-astrologie-joueur.html' ,
2021-04-20 23:16:18 +02:00
// Partials
2021-04-22 19:08:37 +02:00
'systems/foundryvtt-reve-de-dragon/templates/partial-description-overflow.html' ,
2021-04-24 00:50:20 +02:00
'systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.html' ,
2021-04-20 23:16:18 +02:00
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.html' ,
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffLibre.html' ,
2021-10-30 01:34:57 +02:00
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffFixe.html' ,
2021-04-20 23:16:18 +02:00
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffCondition.html' ,
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-surenc.html' ,
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-enctotal.html' ,
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-moral.html' ,
2021-10-30 01:34:57 +02:00
'systems/foundryvtt-reve-de-dragon/templates/partial-roll-forcer.html' ,
2021-05-27 22:40:12 +02:00
'systems/foundryvtt-reve-de-dragon/templates/partial-select-carac.html' ,
2021-06-29 16:03:10 +02:00
'systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html' ,
2020-09-20 16:36:39 +02:00
// Calendrier
2020-11-14 23:24:01 +01:00
'systems/foundryvtt-reve-de-dragon/templates/calendar-template.html' ,
2020-12-08 21:40:41 +01:00
'systems/foundryvtt-reve-de-dragon/templates/calendar-editor-template.html' ,
'systems/foundryvtt-reve-de-dragon/templates/heures-select-option.html' ,
2020-12-20 02:07:27 +01:00
// HUD
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.html' ,
2021-01-01 21:11:56 +01:00
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html' ,
2021-01-01 22:25:32 +01:00
// messages tchat
2021-01-02 14:10:43 +01:00
'systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html' ,
2021-06-23 11:05:38 +02:00
'systems/foundryvtt-reve-de-dragon/templates/chat-description.html' ,
2021-02-12 12:50:17 +01:00
'systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html' ,
2021-01-07 00:32:22 +01:00
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html' ,
2021-01-07 01:54:38 +01:00
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html' ,
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html' ,
2021-01-01 22:25:32 +01:00
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-appelchance.html' ,
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-attaque.html' ,
2021-01-09 19:38:24 +01:00
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html' ,
2021-01-02 04:28:43 +01:00
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-parade.html' ,
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-esquive.html' ,
2021-01-01 22:25:32 +01:00
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-competence.html' ,
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-general.html' ,
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-tache.html' ,
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-sort.html' ,
2021-01-07 20:04:10 +01:00
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-alchimie.html' ,
2021-11-21 12:04:42 +01:00
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-possession.html' ,
2021-01-03 15:40:48 +01:00
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-summary.html' ,
2021-01-03 18:19:18 +01:00
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.html' ,
2021-04-09 15:23:48 +02:00
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.html' ,
2021-04-10 21:07:53 +02:00
'systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html' ,
2021-05-11 00:52:25 +02:00
'systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.html' ,
'systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html'
2020-05-24 20:19:57 +02:00
] ;
2021-02-12 12:50:17 +01:00
Handlebars . registerHelper ( 'upperFirst' , str => Misc . upperFirst ( str ? ? 'Null' ) ) ;
2022-06-25 22:18:46 +02:00
Handlebars . registerHelper ( 'lowerFirst' , str => Misc . lowerFirst ( str ? ? 'Null' ) ) ;
2021-02-12 12:50:17 +01:00
Handlebars . registerHelper ( 'upper' , str => str ? . toUpperCase ( ) ? ? 'NULL' ) ;
Handlebars . registerHelper ( 'le' , str => Grammar . articleDetermine ( str ) ) ;
2022-06-25 22:18:46 +02:00
Handlebars . registerHelper ( 'apostrophe' , ( article , str ) => Grammar . apostrophe ( article , str ) ) ;
2021-02-12 12:50:17 +01:00
Handlebars . registerHelper ( 'un' , str => Grammar . articleIndetermine ( str ) ) ;
2021-02-25 02:00:27 +01:00
Handlebars . registerHelper ( 'accord' , ( genre , ... args ) => Grammar . accord ( genre , args ) ) ;
2021-12-05 01:50:09 +01:00
Handlebars . registerHelper ( 'buildConteneur' , ( objet ) => { return new Handlebars . SafeString ( RdDUtility . buildConteneur ( objet ) ) ; } ) ;
2021-12-05 16:48:18 +01:00
Handlebars . registerHelper ( 'buildContenu' , ( objet ) => { return new Handlebars . SafeString ( RdDUtility . buildContenu ( objet , 1 , true ) ) ; } ) ;
2021-05-04 12:22:19 +02:00
Handlebars . registerHelper ( 'caseTmr-label' , coord => TMRUtility . getTMRLabel ( coord ) ) ;
Handlebars . registerHelper ( 'caseTmr-type' , coord => TMRUtility . getTMRType ( coord ) ) ;
2021-05-18 19:51:12 +02:00
Handlebars . registerHelper ( 'typeTmr-name' , coord => TMRUtility . typeTmrName ( coord ) ) ;
2021-06-04 20:29:03 +02:00
Handlebars . registerHelper ( 'min' , ( ... args ) => Math . min ( ... args . slice ( 0 , - 1 ) ) ) ;
2021-05-28 00:55:22 +02:00
2022-09-07 00:09:17 +02:00
Handlebars . registerHelper ( 'filtreTriCompetences' , competences => competences . filter ( it => it . system . isVisible )
2022-08-27 22:48:08 +02:00
. sort ( ( a , b ) => {
if ( a . name . startsWith ( "Survie" ) && b . name . startsWith ( "Survie" ) ) {
if ( a . name . includes ( "Cité" ) ) return - 1 ;
if ( b . name . includes ( "Cité" ) ) return 1 ;
if ( a . name . includes ( "Extérieur" ) ) return - 1 ;
if ( b . name . includes ( "Extérieur" ) ) return 1 ;
return a . name . localeCompare ( b . name ) ;
}
2022-09-06 23:52:21 +02:00
if ( a . system . categorie . startsWith ( "melee" ) && b . system . categorie . startsWith ( "melee" ) ) {
2022-08-27 22:48:08 +02:00
if ( a . name . includes ( "Corps" ) ) return - 1 ;
if ( b . name . includes ( "Corps" ) ) return 1 ;
if ( a . name . includes ( "Dague" ) ) return - 1 ;
if ( b . name . includes ( "Dague" ) ) return 1 ;
if ( a . name . includes ( "Esquive" ) ) return - 1 ;
if ( b . name . includes ( "Esquive" ) ) return 1 ;
return a . name . localeCompare ( b . name ) ;
}
if ( a . name . startsWith ( "Voie" ) && b . name . startsWith ( "Voie" ) ) {
if ( a . name . includes ( "Oniros" ) ) return - 1 ;
if ( b . name . includes ( "Oniros" ) ) return 1 ;
if ( a . name . includes ( "Hypnos" ) ) return - 1 ;
if ( b . name . includes ( "Hypnos" ) ) return 1 ;
if ( a . name . includes ( "Narcos" ) ) return - 1 ;
if ( b . name . includes ( "Narcos" ) ) return 1 ;
if ( a . name . includes ( "Thanatos" ) ) return - 1 ;
if ( b . name . includes ( "Thanatos" ) ) return 1 ;
return a . name . localeCompare ( b . name ) ;
}
2021-05-13 00:37:28 +02:00
return a . name . localeCompare ( b . name ) ;
2022-08-27 22:48:08 +02:00
} )
) ;
2021-02-06 01:34:01 +01:00
2020-05-24 20:19:57 +02:00
return loadTemplates ( templatePaths ) ;
}
2020-11-18 16:57:58 +01:00
2021-06-02 16:04:35 +02:00
/* -------------------------------------------- */
static async creerObjet ( actorSheet ) {
let itemType = $ ( ".item-type" ) . val ( ) ;
await actorSheet . createItem ( 'Nouveau ' + itemType , itemType ) ;
}
/* -------------------------------------------- */
2021-12-05 16:48:18 +01:00
static async selectObjetType ( actorSheet ) {
2021-06-02 16:04:35 +02:00
let typeObjets = RdDItem . getTypeObjetsEquipement ( ) ;
let options = ` <span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type"> ` ;
for ( let typeName of typeObjets ) {
options += ` <option value=" ${ typeName } "> ${ typeName } </option> `
}
options += '</select>' ;
let d = new Dialog ( {
title : "Créer un équipement" ,
content : options ,
buttons : {
one : {
icon : '<i class="fas fa-check"></i>' ,
label : "Créer l'objet" ,
callback : ( ) => this . creerObjet ( actorSheet )
}
}
} ) ;
d . render ( true ) ;
2021-12-05 16:48:18 +01:00
}
2021-06-07 23:18:33 +02:00
2021-12-05 16:48:18 +01:00
/* -------------------------------------------- */
static async selectTypeOeuvre ( actorSheet ) {
2021-06-07 23:18:33 +02:00
let typeObjets = RdDItem . getTypesOeuvres ( ) ;
let options = ` <span class="competence-label">Selectionnez le type d'oeuvre</span><select class="item-type"> ` ;
for ( let typeName of typeObjets ) {
options += ` <option value=" ${ typeName } "> ${ typeName } </option> `
}
options += '</select>' ;
let d = new Dialog ( {
title : "Créer un équipement" ,
content : options ,
buttons : {
one : {
icon : '<i class="fas fa-check"></i>' ,
label : "Créer l'objet" ,
callback : ( ) => this . creerObjet ( actorSheet )
}
}
} ) ;
d . render ( true ) ;
2021-12-05 16:48:18 +01:00
}
2021-06-07 23:18:33 +02:00
2021-04-10 21:07:53 +02:00
/* -------------------------------------------- */
2021-04-14 22:28:49 +02:00
static buildListOptions ( min , max ) {
2021-04-10 21:07:53 +02:00
let options = ""
2021-04-14 22:28:49 +02:00
for ( let i = min ; i <= max ; i ++ ) {
2021-04-10 21:07:53 +02:00
options += ` <option value=" ${ i } "> ${ i } </option> `
}
return options ;
}
2021-02-22 21:15:10 +01:00
2021-01-08 22:23:50 +01:00
/* -------------------------------------------- */
2022-06-12 08:17:59 +02:00
static arrayOrEmpty ( items ) {
if ( items ? . length ) {
2020-11-18 16:57:58 +01:00
return items ;
}
return [ ] ;
}
2020-12-06 20:11:30 +01:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static getNomEthylisme ( niveauEthylisme ) {
2020-12-19 01:14:02 +01:00
let index = - niveauEthylisme ;
2021-01-08 22:23:50 +01:00
return index < 0 ? 'Aucun' : nomEthylisme [ index ] ;
2020-12-06 20:11:30 +01:00
}
2020-12-06 21:11:30 +01:00
2020-12-01 22:18:15 +01:00
/* -------------------------------------------- */
2022-01-01 14:01:41 +01:00
static initAfficheContenu ( ) { // persistent handling of conteneur show/hide
2021-01-08 22:23:50 +01:00
if ( ! this . afficheContenu )
2020-12-01 22:18:15 +01:00
this . afficheContenu = { } ;
}
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static toggleAfficheContenu ( conteneurId ) {
2020-12-01 22:18:15 +01:00
this . afficheContenu [ conteneurId ] = ! this . afficheContenu [ conteneurId ] ;
}
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static getAfficheContenu ( conteneurId ) {
2021-02-12 12:50:17 +01:00
if ( conteneurId )
2021-01-10 22:12:07 +01:00
return this . afficheContenu [ conteneurId ] ;
return undefined ;
2020-12-01 22:18:15 +01:00
}
2020-11-18 16:57:58 +01:00
/* -------------------------------------------- */
2021-05-07 00:07:16 +02:00
static filterItemsPerTypeForSheet ( formData ) {
2021-12-05 01:50:09 +01:00
RdDUtility . filterEquipementParType ( formData ) ;
2022-06-12 08:17:59 +02:00
formData . sorts = this . arrayOrEmpty ( formData . itemsByType [ 'sort' ] ) ;
formData . signesdraconiques = this . arrayOrEmpty ( formData . itemsByType [ 'signedraconique' ] ) ;
formData . queues = this . arrayOrEmpty ( formData . itemsByType [ 'queue' ] ) ;
formData . souffles = this . arrayOrEmpty ( formData . itemsByType [ 'souffle' ] ) ;
formData . ombres = this . arrayOrEmpty ( formData . itemsByType [ 'ombre' ] ) ;
formData . tetes = this . arrayOrEmpty ( formData . itemsByType [ 'tete' ] ) ;
formData . taches = this . arrayOrEmpty ( formData . itemsByType [ 'tache' ] ) ;
formData . meditations = this . arrayOrEmpty ( formData . itemsByType [ 'meditation' ] ) ;
formData . chants = this . arrayOrEmpty ( formData . itemsByType [ 'chant' ] ) ;
formData . danses = this . arrayOrEmpty ( formData . itemsByType [ 'danse' ] ) ;
formData . musiques = this . arrayOrEmpty ( formData . itemsByType [ 'musique' ] ) ;
formData . oeuvres = this . arrayOrEmpty ( formData . itemsByType [ 'oeuvre' ] ) ;
formData . jeux = this . arrayOrEmpty ( formData . itemsByType [ 'jeu' ] ) ;
formData . recettescuisine = this . arrayOrEmpty ( formData . itemsByType [ 'recettecuisine' ] ) ;
formData . recettesAlchimiques = this . arrayOrEmpty ( formData . itemsByType [ 'recettealchimique' ] ) ;
formData . maladies = this . arrayOrEmpty ( formData . itemsByType [ 'maladie' ] ) ;
formData . poisons = this . arrayOrEmpty ( formData . itemsByType [ 'poison' ] ) ;
formData . possessions = this . arrayOrEmpty ( formData . itemsByType [ 'possession' ] ) ;
2021-12-05 16:48:18 +01:00
formData . maladiesPoisons = formData . maladies . concat ( formData . poisons ) ;
2021-12-05 01:50:09 +01:00
formData . competences = ( formData . itemsByType . competence ? ? [ ] ) . concat ( formData . itemsByType . competencecreature ? ? [ ] ) ;
}
static filterEquipementParType ( formData ) {
2022-06-12 08:17:59 +02:00
formData . conteneurs = this . arrayOrEmpty ( formData . itemsByType [ 'conteneur' ] ) ;
formData . materiel = this . arrayOrEmpty ( formData . itemsByType [ 'objet' ] ) ;
formData . armes = this . arrayOrEmpty ( formData . itemsByType [ 'arme' ] ) ;
formData . armures = this . arrayOrEmpty ( formData . itemsByType [ 'armure' ] ) ;
formData . munitions = this . arrayOrEmpty ( formData . itemsByType [ 'munition' ] ) ;
formData . livres = this . arrayOrEmpty ( formData . itemsByType [ 'livre' ] ) ;
formData . potions = this . arrayOrEmpty ( formData . itemsByType [ 'potion' ] ) ;
formData . ingredients = this . arrayOrEmpty ( formData . itemsByType [ 'ingredient' ] ) ;
formData . herbes = this . arrayOrEmpty ( formData . itemsByType [ 'herbe' ] ) ;
formData . monnaie = this . arrayOrEmpty ( formData . itemsByType [ 'monnaie' ] ) ;
2021-12-05 01:50:09 +01:00
formData . monnaie . sort ( Monnaie . triValeurDenier ( ) ) ;
2022-06-12 08:17:59 +02:00
formData . nourritureboissons = this . arrayOrEmpty ( formData . itemsByType [ 'nourritureboisson' ] ) ;
formData . gemmes = this . arrayOrEmpty ( formData . itemsByType [ 'gemme' ] ) ;
2021-12-05 01:50:09 +01:00
formData . objets = formData . conteneurs
. concat ( formData . materiel )
2021-03-25 03:18:27 +01:00
. concat ( formData . armes )
. concat ( formData . armures )
. concat ( formData . munitions )
. concat ( formData . livres )
. concat ( formData . potions )
2021-04-06 23:43:53 +02:00
. concat ( formData . ingredients )
2021-12-05 01:50:09 +01:00
. concat ( formData . herbes )
. concat ( formData . monnaie )
2021-06-02 17:00:17 +02:00
. concat ( formData . nourritureboissons )
2021-12-05 01:50:09 +01:00
. concat ( formData . gemmes ) ;
2020-11-18 16:57:58 +01:00
}
/* -------------------------------------------- */
2021-05-07 01:47:51 +02:00
static buildArbreDeConteneurs ( conteneurs , objets ) {
2022-06-12 08:17:59 +02:00
let objetVersConteneur = { } ;
2020-11-18 16:57:58 +01:00
// Attribution des objets aux conteneurs
2021-05-07 01:47:51 +02:00
for ( let conteneur of conteneurs ) {
2022-06-12 08:17:59 +02:00
conteneur . subItems = [ ] ;
2022-05-03 09:01:10 +02:00
for ( let id of conteneur . system . contenu ? ? [ ] ) {
2022-06-12 08:17:59 +02:00
let objet = objets . find ( objet => ( id == objet . _id ) ) ;
2021-05-27 22:40:12 +02:00
if ( objet ) {
objet . estContenu = true ; // Permet de filtrer ce qui est porté dans le template
2022-06-12 08:17:59 +02:00
objetVersConteneur [ id ] = conteneur . _id ;
conteneur . subItems . push ( objet ) ;
2020-11-18 16:57:58 +01:00
}
}
}
2021-05-27 22:40:12 +02:00
for ( let conteneur of conteneurs ) {
2022-06-12 08:17:59 +02:00
conteneur . system . encTotal = RdDUtility . calculEncContenu ( conteneur , objets ) ;
2021-05-27 22:40:12 +02:00
}
2022-06-12 08:17:59 +02:00
return objetVersConteneur ;
2021-05-07 01:47:51 +02:00
}
2021-05-27 22:40:12 +02:00
2021-11-21 12:04:42 +01:00
/* -------------------------------------------- */
2021-05-27 22:40:12 +02:00
static calculEncContenu ( conteneur , objets ) {
2022-09-07 18:47:56 +02:00
const contenus = ( conteneur . system . contenu ? ? [ ] ) . filter ( id => id != undefined )
. map ( id => objets . find ( it => ( id == it . id ) ) )
2022-06-12 08:17:59 +02:00
. filter ( it => it ) ;
let enc = Number ( conteneur . system . encombrement ? ? 0 ) * Number ( conteneur . system . quantite ? ? 1 ) ;
2022-09-07 18:47:56 +02:00
for ( let contenu of contenus ) {
if ( contenu . type == 'conteneur' ) {
enc += RdDUtility . calculEncContenu ( contenu , objets ) ;
2021-05-27 22:40:12 +02:00
}
2021-12-05 16:48:18 +01:00
else {
2022-09-07 18:47:56 +02:00
enc += Number ( contenu . system . encombrement ? ? 0 ) * Number ( contenu . system . quantite ? ? 1 )
2021-05-27 22:40:12 +02:00
}
}
2022-06-12 08:17:59 +02:00
return enc
2021-05-27 22:40:12 +02:00
}
2021-11-21 12:04:42 +01:00
/* -------------------------------------------- */
2021-05-07 01:47:51 +02:00
// Construit la liste des conteneurs de niveau 1 (c'est à dire non contenu eux-même dans un conteneur)
static conteneursRacine ( conteneurs ) {
2021-05-27 22:40:12 +02:00
return conteneurs . filter ( ( conteneur , index , arr ) => ! conteneur . estContenu ) ;
2020-11-18 16:57:58 +01:00
}
2020-11-12 14:44:42 +01:00
/* -------------------------------------------- */
2020-11-12 15:06:25 +01:00
/ * * C o n s t r u i t l a s t r u c t u r e r é c u r s i v e d e s c o n t e n e u r s , a v e c i m b r i c a t i o n p o t e n t i e l l e
*
* /
2022-08-26 22:23:04 +02:00
static buildConteneur ( objet , profondeur ) {
if ( ! profondeur ) profondeur = 1 ;
objet . niveau = profondeur ;
const isConteneur = objet . type == 'conteneur' ;
const isOuvert = isConteneur && this . getAfficheContenu ( objet . _id ) ;
2022-09-06 23:52:21 +02:00
const isVide = isConteneur && objet . system . contenu . length == 0 ;
2022-08-27 16:23:22 +02:00
const conteneur = Handlebars . partials [ 'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire-item.html' ] ( {
2022-08-26 22:23:04 +02:00
item : objet ,
vide : isVide ,
ouvert : isOuvert
} ) ;
const contenu = isConteneur ? RdDUtility . buildContenu ( objet , profondeur , isOuvert ) : '' ;
return conteneur + contenu ;
2021-12-05 01:50:09 +01:00
}
2022-06-12 08:17:59 +02:00
/* -------------------------------------------- */
2022-08-26 22:23:04 +02:00
static buildContenu ( objet , profondeur , afficherContenu ) {
if ( ! profondeur ) profondeur = 1 ;
objet . niveau = profondeur ;
const display = afficherContenu ? 'item-display-show' : 'item-display-hide' ;
2021-12-05 01:50:09 +01:00
//console.log("ITEM DISPLAYED", objet );
2022-08-26 22:23:04 +02:00
let strContenu = ` <ul class='item-list alterne-list ${ display } list-item-margin ${ profondeur } '> ` ;
2021-12-05 01:50:09 +01:00
for ( let subItem of objet . subItems ) {
2022-08-26 22:23:04 +02:00
strContenu += this . buildConteneur ( subItem , profondeur + 1 ) ;
2020-11-12 14:43:08 +01:00
}
2022-08-26 22:23:04 +02:00
return strContenu + "</ul>" ;
2020-11-12 14:43:08 +01:00
}
2020-05-24 20:19:57 +02:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static getCaracArray ( ) {
2020-05-24 20:19:57 +02:00
return carac _array ;
}
2021-01-08 22:23:50 +01:00
static getDifficultesLibres ( ) {
2020-11-15 02:07:41 +01:00
return difficultesLibres ;
}
2021-01-08 22:23:50 +01:00
static getAjustementsConditions ( ) {
2020-11-15 02:07:41 +01:00
return ajustementsConditions ;
2020-05-24 20:19:57 +02:00
}
2021-01-08 22:23:50 +01:00
static getAjustementsEncaissement ( ) {
2020-12-01 00:05:18 +01:00
return ajustementsEncaissement ;
}
2020-05-24 20:19:57 +02:00
2020-11-24 18:54:13 +01:00
static getDefinitionsBlessures ( ) {
return definitionsBlessures ;
}
2020-08-13 22:28:56 +02:00
2020-11-24 16:41:15 +01:00
/* -------------------------------------------- */
2020-11-18 20:16:59 +01:00
static getSegmentsFatigue ( maxEnd ) {
maxEnd = Math . max ( maxEnd , 1 ) ;
maxEnd = Math . min ( maxEnd , fatigueMatrix . length ) ;
return fatigueMatrix [ maxEnd ] ;
2020-11-17 13:08:52 +01:00
}
2020-11-24 16:41:15 +01:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static calculMalusFatigue ( fatigue , maxEnd ) {
2020-11-18 20:16:59 +01:00
maxEnd = Math . max ( maxEnd , 1 ) ;
maxEnd = Math . min ( maxEnd , cumulFatigueMatrix . length ) ;
let segments = cumulFatigueMatrix [ maxEnd ] ;
2021-01-08 22:23:50 +01:00
for ( let i = 0 ; i < 12 ; i ++ ) {
2020-11-18 20:16:59 +01:00
if ( fatigue <= segments [ i ] ) {
return fatigueMalus [ i ]
}
2020-11-17 13:08:52 +01:00
}
2020-11-18 20:16:59 +01:00
return - 7 ;
2020-11-17 13:08:52 +01:00
}
2021-05-08 20:08:56 +02:00
2021-11-21 12:04:42 +01:00
/* -------------------------------------------- */
2021-05-08 20:08:56 +02:00
static calculFatigueHtml ( fatigue , endurance ) {
return ReglesOptionelles . isUsing ( "appliquer-fatigue" ) ? {
malus : RdDUtility . calculMalusFatigue ( fatigue , endurance ) ,
html : "<table class='table-fatigue'>" + RdDUtility . makeHTMLfatigueMatrix ( fatigue , endurance ) . html ( ) + "</table>"
2021-05-27 22:40:12 +02:00
} : { malus : 0 , html : '' } ;
2021-05-08 20:08:56 +02:00
}
2020-05-27 23:47:49 +02:00
/* -------------------------------------------- */
2020-05-29 00:43:16 +02:00
// Build the nice (?) html table used to manage fatigue.
2020-11-17 13:08:52 +01:00
// max should be the endurance max value
2021-01-08 22:23:50 +01:00
static makeHTMLfatigueMatrix ( fatigue , maxEndurance ) {
2020-11-17 13:08:52 +01:00
let segments = this . getSegmentsFatigue ( maxEndurance ) ;
return this . makeHTMLfatigueMatrixForSegment ( fatigue , segments ) ;
}
2020-05-29 00:43:16 +02:00
2021-11-21 12:04:42 +01:00
/* -------------------------------------------- */
2020-11-17 13:08:52 +01:00
static makeHTMLfatigueMatrixForSegment ( fatigue , segments ) {
fatigue = Math . max ( fatigue , 0 ) ;
fatigue = Math . min ( fatigue , segments . fatigueMax ) ;
let table = $ ( "<table/>" ) . addClass ( 'table-fatigue' ) ;
2020-05-27 23:47:49 +02:00
let segmentIdx = 0 ;
2020-05-28 23:36:09 +02:00
let fatigueCount = 0 ;
2020-11-17 13:08:52 +01:00
for ( var line = 0 ; line < fatigueLineSize . length ; line ++ ) {
2020-05-27 23:47:49 +02:00
let row = $ ( "<tr/>" ) ;
let segmentsPerLine = fatigueLineSize [ line ] ;
2020-05-28 23:36:09 +02:00
row . append ( "<td class='fatigue-malus'>" + fatigueLineMalus [ line ] + "</td>" ) ;
2020-05-27 23:47:49 +02:00
while ( segmentIdx < segmentsPerLine ) {
2020-11-17 13:08:52 +01:00
let freeSize = segments [ segmentIdx ] ;
for ( let col = 0 ; col < 5 ; col ++ ) {
if ( col < freeSize ) {
if ( fatigueCount < fatigue )
2020-12-11 19:14:24 +01:00
row . append ( "<td class='fatigue-used'>X</td>" ) ;
2020-11-17 13:08:52 +01:00
2020-05-28 23:36:09 +02:00
else
row . append ( "<td class='fatigue-free'/>" ) ;
fatigueCount ++ ;
2020-11-17 13:08:52 +01:00
} else {
2020-05-27 23:47:49 +02:00
row . append ( "<td class='fatigue-none'/>" ) ;
2020-05-28 23:36:09 +02:00
}
2020-05-27 23:47:49 +02:00
}
row . append ( "<td class='fatigue-separator'/>" ) ;
segmentIdx = segmentIdx + 1 ;
}
table . append ( row ) ;
}
return table ;
}
2020-11-17 13:08:52 +01:00
2020-05-31 23:06:25 +02:00
/* -------------------------------------------- */
2021-05-11 21:45:43 +02:00
static async getLocalisation ( type = 'personnage' ) {
let result = await RdDDice . rollTotal ( "1d20" ) ;
2020-06-07 23:16:29 +02:00
let txt = ""
2021-02-12 12:50:17 +01:00
if ( type == 'personnage' ) {
2021-02-08 16:14:43 +01:00
if ( result <= 3 ) txt = "Jambe, genou, pied, jarret" ;
else if ( result <= 7 ) txt = "Hanche, cuisse, fesse" ;
else if ( result <= 9 ) txt = "Ventre, reins" ;
else if ( result <= 12 ) txt = "Poitrine, dos" ;
else if ( result <= 14 ) txt = "Avant-bras, main, coude" ;
else if ( result <= 18 ) txt = "Epaule, bras, omoplate" ;
else if ( result == 19 ) txt = "Tête" ;
else if ( result == 20 ) txt = "Tête (visage)" ;
} else {
if ( result <= 7 ) txt = "Jambes/Pattes" ;
else if ( result <= 18 ) txt = "Corps" ;
2021-02-12 12:50:17 +01:00
else if ( result <= 20 ) txt = "Tête" ;
2021-02-08 16:14:43 +01:00
}
2021-01-08 22:23:50 +01:00
2020-06-07 23:16:29 +02:00
return { result : result , label : txt } ;
2020-05-31 23:06:25 +02:00
}
2020-11-11 04:21:25 +01:00
2020-11-11 10:38:27 +01:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static selectEncaissement ( degats , mortalite ) {
2020-11-11 04:21:25 +01:00
const table = definitionsEncaissement [ mortalite ] === undefined ? definitionsEncaissement [ "mortel" ] : definitionsEncaissement [ mortalite ] ;
for ( let encaissement of table ) {
if ( ( encaissement . minimum === undefined || encaissement . minimum <= degats )
&& ( encaissement . maximum === undefined || degats <= encaissement . maximum ) ) {
return duplicate ( encaissement ) ;
}
2020-06-07 23:16:29 +02:00
}
2020-11-11 04:21:25 +01:00
return duplicate ( table [ 0 ] ) ;
}
2020-06-12 22:46:04 +02:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static currentFatigueMalus ( value , max ) {
2021-05-08 20:08:56 +02:00
if ( ReglesOptionelles . isUsing ( "appliquer-fatigue" ) ) {
max = Math . max ( 1 , Math . min ( max , 60 ) ) ;
value = Math . min ( max * 2 , Math . max ( 0 , value ) ) ;
2021-05-27 22:40:12 +02:00
2021-05-08 20:08:56 +02:00
let fatigueTab = fatigueMatrix [ max ] ;
let fatigueRem = value ;
for ( let idx = 0 ; idx < fatigueTab . length ; idx ++ ) {
fatigueRem -= fatigueTab [ idx ] ;
if ( fatigueRem <= 0 ) {
return fatigueMalus [ idx ] ;
}
2020-05-29 00:43:16 +02:00
}
2021-05-08 20:08:56 +02:00
return - 7 ; // This is the max !
2020-05-29 00:43:16 +02:00
}
2021-05-08 20:08:56 +02:00
return 0 ;
2020-05-29 00:43:16 +02:00
}
2020-12-12 21:58:44 +01:00
2020-12-15 21:28:55 +01:00
/* -------------------------------------------- */
2021-03-25 03:18:27 +01:00
static async loadCompendiumData ( compendium ) {
2020-12-15 21:28:55 +01:00
const pack = game . packs . get ( compendium ) ;
2021-03-25 03:18:27 +01:00
return await pack ? . getDocuments ( ) ? ? [ ] ;
2020-12-15 21:28:55 +01:00
}
2021-01-12 13:18:29 +01:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static async loadCompendium ( compendium , filter = item => true ) {
2021-03-25 03:18:27 +01:00
let compendiumData = await RdDUtility . loadCompendiumData ( compendium ) ;
return compendiumData . filter ( filter ) ;
2021-01-08 22:23:50 +01:00
}
2020-12-12 23:31:19 +01:00
/* -------------------------------------------- */
2022-09-07 18:47:56 +02:00
static async responseNombreAstral ( callData ) {
let actor = game . actors . get ( callData . id ) ;
actor . ajouteNombreAstral ( callData ) ;
2020-12-12 23:31:19 +01:00
}
2020-06-17 20:31:43 +02:00
/* -------------------------------------------- */
2021-10-30 00:42:18 +02:00
static onSocketMessage ( sockmsg ) {
2021-01-08 22:23:50 +01:00
switch ( sockmsg . msg ) {
2020-11-24 15:20:05 +01:00
case "msg_gm_chat_message" :
return ChatUtility . handleGMChatMessage ( sockmsg . data ) ;
2021-01-08 22:23:50 +01:00
case "msg_sync_time" :
return game . system . rdd . calendrier . syncPlayerTime ( sockmsg . data ) ;
2020-12-12 23:31:19 +01:00
case "msg_request_nombre_astral" :
2021-01-08 22:23:50 +01:00
return game . system . rdd . calendrier . requestNombreAstral ( sockmsg . data ) ;
2020-12-12 23:31:19 +01:00
case "msg_response_nombre_astral" :
2021-01-08 22:23:50 +01:00
return RdDUtility . responseNombreAstral ( sockmsg . data ) ;
2021-02-12 12:50:17 +01:00
case "msg_tmr_move" :
2021-04-28 00:48:39 +02:00
let actor = game . actors . get ( sockmsg . data . actorId ) ;
2021-05-27 22:40:12 +02:00
if ( actor . isOwner || game . user . isGM ) {
2022-06-25 17:49:19 +02:00
actor . refreshTMRView ( ) ;
2021-02-12 12:50:17 +01:00
}
2021-04-28 00:48:39 +02:00
break ;
2020-11-24 15:20:05 +01:00
}
}
2020-06-07 23:16:29 +02:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static async chatListeners ( html ) {
2020-12-12 21:58:44 +01:00
RdDCombat . registerChatCallbacks ( html ) ;
2020-12-15 23:54:05 +01:00
2020-12-30 19:18:07 +01:00
// Gestion spécifique message passeurs
2020-11-17 16:30:03 +01:00
html . on ( "click" , '.tmr-passeur-coord a' , event => {
2021-01-08 22:23:50 +01:00
let coord = event . currentTarget . attributes [ 'data-tmr-coord' ] . value ;
2020-11-17 18:08:19 +01:00
let actorId = event . currentTarget . attributes [ 'data-actor-id' ] . value ;
2021-01-08 22:23:50 +01:00
let actor = game . actors . get ( actorId ) ;
2022-06-25 17:49:19 +02:00
actor . tmrApp . positionnerDemiReve ( coord ) ;
2020-11-17 18:08:19 +01:00
} ) ;
2020-12-31 00:55:02 +01:00
// Gestion spécifique des sorts en réserve multiples (ie têtes)
2020-12-30 19:18:07 +01:00
html . on ( "click" , '#sort-reserve' , event => {
2021-01-08 22:23:50 +01:00
let coord = event . currentTarget . attributes [ 'data-tmr-coord' ] . value ;
let sortId = event . currentTarget . attributes [ 'data-sort-id' ] . value ;
2020-12-30 19:18:07 +01:00
let actorId = event . currentTarget . attributes [ 'data-actor-id' ] . value ;
2021-01-08 22:23:50 +01:00
let actor = game . actors . get ( actorId ) ;
2020-12-30 19:18:07 +01:00
actor . tmrApp . lancerSortEnReserve ( coord , sortId ) ;
2021-01-08 22:23:50 +01:00
} ) ;
2021-05-07 17:27:02 +02:00
2022-07-02 01:41:55 +02:00
// gestion bouton tchat Possession
2021-11-21 12:04:42 +01:00
html . on ( "click" , '.defense-possession' , event => {
2022-06-12 08:17:59 +02:00
let attackerId = event . currentTarget . attributes [ 'data-attackerId' ] . value
let defenderId = event . currentTarget . attributes [ 'data-defenderId' ] . value
let possessionId = event . currentTarget . attributes [ 'data-possessionId' ] . value
RdDPossession . onDefensePossession ( attackerId , defenderId , possessionId )
2021-11-21 12:04:42 +01:00
} ) ;
2021-05-07 17:27:02 +02:00
// gestion bouton tchat Acheter
html . on ( "click" , '.button-acheter' , event => DialogItemAchat . onButtonAcheter ( event ) ) ;
2022-07-22 01:31:21 +02:00
html . on ( "click" , '.button-creer-acteur' , event => RdDNameGen . onCreerActeur ( event ) ) ;
2021-05-27 22:40:12 +02:00
2020-12-31 00:55:02 +01:00
// Gestion du bouton payer
2021-03-29 23:41:08 +02:00
html . on ( "click" , '.payer-button' , event => {
2021-04-15 00:25:40 +02:00
let sumdenier = event . currentTarget . attributes [ 'data-somme-denier' ] ? . value ? ? 0 ;
2021-04-14 22:28:49 +02:00
let quantite = event . currentTarget . attributes [ 'data-quantite' ] ? . value ? ? 1 ;
2021-04-15 00:25:40 +02:00
let fromActorId = event . currentTarget . attributes [ 'data-actor-id' ] ? . value ;
2021-01-02 00:04:27 +01:00
let jsondata = event . currentTarget . attributes [ 'data-jsondata' ]
2021-01-01 21:11:56 +01:00
let objData
2021-01-08 22:23:50 +01:00
if ( jsondata ) {
2021-01-02 00:04:27 +01:00
objData = JSON . parse ( jsondata . value )
}
2021-04-14 22:28:49 +02:00
let actor = RdDUtility . getSelectedActor ( "Pour effectuer le paiement:" ) ;
if ( actor ) {
2021-04-15 00:25:40 +02:00
actor . depenserDeniers ( sumdenier , objData , quantite , fromActorId ) ;
2021-06-01 00:10:02 +02:00
ChatUtility . removeChatMessageId ( RdDUtility . findChatMessageId ( event . currentTarget ) ) ;
2021-01-01 21:11:56 +01:00
}
2020-12-31 00:55:02 +01:00
} ) ;
2020-06-07 23:16:29 +02:00
}
2021-04-15 01:14:24 +02:00
static findChatMessageId ( current ) {
2021-05-07 17:27:02 +02:00
return RdDUtility . getChatMessageId ( RdDUtility . findChatMessage ( current ) ) ;
}
static getChatMessageId ( node ) {
return node ? . attributes . getNamedItem ( 'data-message-id' ) ? . value ;
}
static findChatMessage ( current ) {
return RdDUtility . findNodeMatching ( current , it => it . classList . contains ( 'chat-message' ) && it . attributes . getNamedItem ( 'data-message-id' ) ) ;
2021-04-15 01:14:24 +02:00
}
static findNodeMatching ( current , predicate ) {
if ( current ) {
if ( predicate ( current ) ) {
return current ;
}
return RdDUtility . findNodeMatching ( current . parentElement , predicate ) ;
}
return undefined ;
}
2021-05-07 17:27:02 +02:00
static getSelectedActor ( msgPlayer = undefined ) {
2021-04-14 22:28:49 +02:00
if ( canvas . tokens . controlled . length == 1 ) {
let token = canvas . tokens . controlled [ 0 ] ;
2022-09-07 18:47:56 +02:00
if ( token . actor ) {
2021-04-14 22:28:49 +02:00
return token . actor ;
}
2021-05-27 22:40:12 +02:00
if ( msgPlayer != undefined ) {
2021-05-07 17:27:02 +02:00
msgPlayer += "<br>le token sélectionné doit être lié à un personnage" ;
}
2021-04-14 22:28:49 +02:00
}
if ( game . user . character ) {
return game . user . character ;
}
2021-05-27 22:40:12 +02:00
if ( msgPlayer != undefined ) {
2021-05-07 17:27:02 +02:00
msgPlayer += "<br>vous pouvez sélectionner un seul token lié à un personnage" ;
msgPlayer += "<br>vous devez être connecté comme joueur avec un personnage sélectionné" ;
ui . notifications . warn ( msgPlayer ) ;
ChatMessage . create ( { content : msgPlayer , whisper : [ game . user ] } ) ;
}
2021-04-14 22:28:49 +02:00
return undefined ;
}
2020-12-31 10:55:40 +01:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static createMonnaie ( name , valeur _deniers , img = "" , enc = 0.01 ) {
let piece = {
name : name , type : 'monnaie' , img : img , _id : randomID ( 16 ) ,
2022-09-07 18:47:56 +02:00
dasystemta : {
2021-01-08 22:23:50 +01:00
quantite : 0 ,
valeur _deniers : valeur _deniers ,
encombrement : enc ,
description : ""
}
}
2020-12-31 10:55:40 +01:00
return piece ;
}
2020-12-31 00:55:02 +01:00
/* -------------------------------------------- */
static afficherDemandePayer ( som1 , som2 ) {
som1 = ( som1 ) ? som1 . toLowerCase ( ) : "0d" ;
som2 = ( som2 ) ? som2 . toLowerCase ( ) : "0d" ;
let regExp = /(\d+)(\w+)/g ;
2021-01-08 22:23:50 +01:00
let p1 = regExp . exec ( som1 ) ;
2020-12-31 00:55:02 +01:00
regExp = /(\d+)(\w+)/g ;
2021-01-08 22:23:50 +01:00
let p2 = regExp . exec ( som2 ) ;
2020-12-31 00:55:02 +01:00
let sumd = 0 ;
let sums = 0 ;
if ( p1 [ 2 ] == 'd' ) sumd += Number ( p1 [ 1 ] ) ;
if ( p1 [ 2 ] == 's' ) sums += Number ( p1 [ 1 ] ) ;
if ( p2 [ 2 ] == 'd' ) sumd += Number ( p2 [ 1 ] ) ;
if ( p2 [ 2 ] == 's' ) sums += Number ( p2 [ 1 ] ) ;
2021-01-08 22:23:50 +01:00
let sumtotald = sumd + ( sums * 100 ) ;
let msgPayer = "La somme de " + sums + " Sols et " + sumd + " Deniers est à payer, cliquer sur le lien ci-dessous si besoin.<br>" ;
2021-03-29 23:41:08 +02:00
msgPayer += "<a class='payer-button chat-card-button' data-somme-denier='" + sumtotald + "'>Payer</a>"
2021-01-08 22:23:50 +01:00
ChatMessage . create ( { content : msgPayer } ) ;
2020-12-31 00:55:02 +01:00
}
2021-01-01 21:11:56 +01:00
/* -------------------------------------------- */
static chatDataSetup ( content , modeOverride , isRoll = false , forceWhisper ) {
let chatData = {
2021-03-25 03:18:27 +01:00
user : game . user . id ,
2021-01-01 21:11:56 +01:00
rollMode : modeOverride || game . settings . get ( "core" , "rollMode" ) ,
content : content
} ;
if ( [ "gmroll" , "blindroll" ] . includes ( chatData . rollMode ) ) chatData [ "whisper" ] = ChatMessage . getWhisperRecipients ( "GM" ) . map ( u => u . id ) ;
if ( chatData . rollMode === "blindroll" ) chatData [ "blind" ] = true ;
else if ( chatData . rollMode === "selfroll" ) chatData [ "whisper" ] = [ game . user ] ;
if ( forceWhisper ) { // Final force !
chatData [ "speaker" ] = ChatMessage . getSpeaker ( ) ;
chatData [ "whisper" ] = ChatMessage . getWhisperRecipients ( forceWhisper ) ;
}
2021-02-12 12:50:17 +01:00
return chatData ;
2021-01-11 16:29:41 +01:00
}
2021-02-12 12:50:17 +01:00
/* -------------------------------------------- */
static confirmerSuppressionSubacteur ( actorSheet , li ) {
let actorId = li . data ( "actor-id" ) ;
let actor = game . actors . get ( actorId ) ;
2022-09-07 00:09:17 +02:00
let msgTxt = "<p>Etes vous certain de vouloir supprimer le lien vers ce véhicule/monture/suivant : " + actor . name + " ?</p>" ;
2021-02-12 12:50:17 +01:00
let d = new Dialog ( {
title : "Confirmer la suppression du lien" ,
content : msgTxt ,
buttons : {
2021-01-11 16:29:41 +01:00
delete : {
2021-02-12 12:50:17 +01:00
icon : '<i class="fas fa-check"></i>' ,
label : "Supprimer le lien" ,
callback : ( ) => {
console . log ( "Delete : " , actorId ) ;
actorSheet . actor . removeSubacteur ( actorId ) ;
li . slideUp ( 200 , ( ) => actorSheet . render ( false ) ) ;
}
} ,
cancel : {
icon : '<i class="fas fa-times"></i>' ,
label : "Annuler"
}
} ,
default : "cancel"
} ) ;
d . render ( true ) ;
}
2021-01-16 18:54:07 +01:00
/* -------------------------------------------- */
static async confirmerSuppression ( actorSheet , li ) {
2021-02-12 12:50:17 +01:00
let itemId = li . data ( "item-id" ) ;
2021-03-29 09:17:00 +02:00
let objet = actorSheet . actor . getObjet ( itemId ) ;
2021-06-02 17:39:16 +02:00
2022-09-16 02:22:09 +02:00
if ( Monnaie . isSystemMonnaie ( objet , actorSheet . actor . items ) ) {
2021-06-02 17:39:16 +02:00
ui . notifications . warn ( "Suppression des monnaies de base impossible" ) ;
return ;
}
2021-02-12 12:50:17 +01:00
let msgTxt = "<p>Etes vous certain de vouloir supprimer cet objet ?" ;
let buttons = {
delete : {
icon : '<i class="fas fa-check"></i>' ,
label : "Supprimer l'objet" ,
callback : ( ) => {
console . log ( "Delete : " , itemId ) ;
2021-03-29 23:41:08 +02:00
actorSheet . actor . deleteEmbeddedDocuments ( 'Item' , [ itemId ] ) ;
2021-02-12 12:50:17 +01:00
li . slideUp ( 200 , ( ) => actorSheet . render ( false ) ) ;
}
} ,
cancel : {
icon : '<i class="fas fa-times"></i>' ,
label : "Annuler"
2021-01-11 16:29:41 +01:00
}
2021-02-12 12:50:17 +01:00
}
2022-09-07 00:09:17 +02:00
if ( objet . type == 'conteneur' && objet . system . contenu . length > 0 ) {
2021-03-29 18:08:18 +02:00
msgTxt += "<br>Ce conteneur n'est pas vide. Choisissez l'option de suppression" ;
2021-02-12 12:50:17 +01:00
buttons [ 'deleteall' ] = {
icon : '<i class="fas fa-check"></i>' ,
label : "Supprimer le conteneur et tout son contenu" ,
callback : ( ) => {
console . log ( "Delete : " , itemId ) ;
actorSheet . actor . deleteAllConteneur ( itemId ) ;
li . slideUp ( 200 , ( ) => actorSheet . render ( false ) ) ;
}
}
}
msgTxt += "</p>" ;
let d = new Dialog ( {
title : "Confirmer la suppression" ,
content : msgTxt ,
buttons : buttons ,
default : "cancel"
} ) ;
d . render ( true ) ;
2021-01-16 18:54:07 +01:00
}
2021-02-12 12:50:17 +01:00
2021-01-16 18:54:07 +01:00
/* -------------------------------------------- */
2021-02-12 12:50:17 +01:00
static afficherHeuresChanceMalchance ( heureNaissance ) {
2021-12-05 16:48:18 +01:00
if ( game . user . isGM ) {
2021-06-04 18:30:06 +02:00
let heure = game . system . rdd . calendrier . findHeure ( heureNaissance ) ;
if ( heureNaissance && heure ) {
2021-06-01 20:54:27 +02:00
let ajustement = game . system . rdd . calendrier . getAjustementAstrologique ( heureNaissance ) ;
2021-06-04 18:30:06 +02:00
const current = game . system . rdd . calendrier . findHeure ( game . system . rdd . calendrier . getCurrentHeure ( ) ) ;
2021-06-01 20:54:27 +02:00
ChatMessage . create ( {
2021-06-04 18:30:06 +02:00
content : ` A l'heure de <strong> ${ current . label } </strong>, le modificateur de Chance/Malchance est de <strong> ${ Misc . toSignedString ( ajustement ) } </strong> pour l'heure de naissance <strong> ${ heure . label } </strong>. ` ,
2021-06-01 20:54:27 +02:00
whisper : ChatMessage . getWhisperRecipients ( "GM" )
} ) ;
}
2021-06-04 18:30:06 +02:00
else if ( heureNaissance ) {
2021-12-05 16:48:18 +01:00
ui . notifications . warn ( heureNaissance + " ne correspond pas à une heure de naissance" ) ;
2021-06-04 18:30:06 +02:00
}
2021-06-01 20:54:27 +02:00
else {
ui . notifications . warn ( "Pas d'heure de naissance selectionnée" ) ;
}
} else {
ui . notifications . warn ( "Vous n'avez pas accès à cette commande" ) ;
2021-01-26 19:47:18 +01:00
}
2021-01-16 18:54:07 +01:00
}
2021-02-12 12:50:17 +01:00
2021-02-10 11:24:14 +01:00
/*-------------------------------------------- */
2021-02-06 23:51:04 +01:00
static checkThanatosXP ( compName ) {
2021-02-12 12:50:17 +01:00
if ( compName . includes ( 'Thanatos' ) ) {
2021-02-06 23:51:04 +01:00
let message = "Vous avez mis des points d'Expérience dans la Voie de Thanatos !<br>Vous devez réduire manuellement d'un même montant d'XP une autre compétence Draconique." ;
ChatMessage . create ( {
whisper : ChatMessage . getWhisperRecipients ( game . user . name ) ,
content : message
} ) ;
}
}
2021-02-10 11:24:14 +01:00
/*-------------------------------------------- */
2021-02-12 12:50:17 +01:00
static async onRenderChatMessage ( app , html , msg ) {
2021-02-10 11:24:14 +01:00
// TODO
//console.log(app, html, msg);
}
2021-01-16 18:54:07 +01:00
2020-05-22 22:37:02 +02:00
}