2020-05-22 22:37:02 +02:00
/* Common useful functions shared between objects */
2020-11-11 04:31:17 +01:00
import { RdDRollTables } from "./rdd-rolltables.js" ;
2020-11-24 15:20:05 +01:00
import { ChatUtility } from "./chat-utility.js" ;
2020-12-12 21:58:44 +01:00
import { RdDCombat } from "./rdd-combat.js" ;
2021-01-02 14:10:43 +01:00
import { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js" ;
2021-01-04 00:17:22 +01:00
import { RdDItemCompetenceCreature } from "./item-competencecreature.js" ;
import { RdDItemArme } from "./item-arme.js" ;
2021-01-08 22:23:50 +01:00
import { RdDItemCompetence } from "./item-competence.js" ;
2020-06-11 00:29:32 +02:00
2020-12-02 20:52:37 +01:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
const categorieCompetences = {
"generale" : { level : "-4" , label : "Générales" } ,
"particuliere" : { level : "-8" , label : "Particulières" } ,
"specialisee" : { level : "-11" , label : "Spécialisées" } ,
"connaissance" : { level : "-11" , label : "Connaissances" } ,
"draconic" : { level : "-11" , label : "Draconics" } ,
"melee" : { level : "-6" , label : "Mêlée" } ,
"tir" : { level : "-8" , label : "Tir" } ,
"lancer" : { level : "-8" , label : "Lancer" }
2020-08-13 22:28:56 +02:00
}
2020-11-12 16:35:51 +01: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
const tableCaracDerivee = {
// xp: coût pour passer du niveau inférieur à ce niveau
1 : { xp : 3 , poids : "moins de 1kg" , plusdom : - 5 , sconst : 0.5 , sust : 0.1 } ,
2 : { xp : 3 , poids : "1-5" , plusdom : - 4 , sconst : 0.5 , sust : 0.3 } ,
3 : { xp : 4 , poids : "6-10" , plusdom : - 3 , sconst : 1 , sust : 0.5 , beaute : 'hideux' } ,
4 : { xp : 4 , poids : "11-20" , plusdom : - 3 , sconst : 1 , sust : 1 , beaute : 'repoussant' } ,
5 : { xp : 5 , poids : "21-30" , plusdom : - 2 , sconst : 1 , sust : 1 , beaute : 'franchement très laid' } ,
6 : { xp : 5 , poids : "31-40" , plusdom : - 1 , sconst : 2 , sust : 2 , beaute : 'laid' } ,
7 : { xp : 6 , poids : "41-50" , plusdom : - 1 , sconst : 2 , sust : 2 , beaute : 'très désavantagé' } ,
8 : { xp : 6 , poids : "51-60" , plusdom : 0 , sconst : 2 , sust : 2 , beaute : 'désavantagé' } ,
9 : { xp : 7 , poids : "61-65" , plusdom : 0 , sconst : 3 , sust : 2 , beaute : 'pas terrible' } ,
10 : { xp : 7 , poids : "66-70" , plusdom : 0 , sconst : 3 , sust : 3 , beaute : 'commun' } ,
11 : { xp : 8 , poids : "71-75" , plusdom : 0 , sconst : 3 , sust : 3 , beaute : 'pas mal' } ,
12 : { xp : 8 , poids : "76-80" , plusdom : + 1 , sconst : 4 , sust : 3 , beaute : 'avantagé' } ,
13 : { xp : 9 , poids : "81-90" , plusdom : + 1 , sconst : 4 , sust : 3 , beaute : 'mignon' } ,
14 : { xp : 9 , poids : "91-100" , plusdom : + 2 , sconst : 4 , sust : 4 , beaute : 'beau' } ,
15 : { xp : 10 , poids : "101-110" , plusdom : + 2 , sconst : 5 , sust : 4 , beaute : 'très beau' } ,
16 : { xp : 20 , poids : "111-120" , plusdom : + 3 , sconst : 5 , sust : 4 , beaute : 'éblouissant' } ,
17 : { xp : 30 , poids : "121-131" , plusdom : + 3 , sconst : 5 , sust : 5 } ,
18 : { xp : 40 , poids : "131-141" , plusdom : + 4 , sconst : 6 , sust : 5 } ,
19 : { xp : 50 , poids : "141-150" , plusdom : + 4 , sconst : 6 , sust : 5 } ,
20 : { xp : 60 , poids : "151-160" , plusdom : + 4 , sconst : 6 , sust : 6 } ,
21 : { xp : 70 , poids : "161-180" , plusdom : + 5 , sconst : 7 , sust : 6 } ,
22 : { xp : 80 , poids : "181-200" , plusdom : + 5 , sconst : 7 , sust : 7 } ,
23 : { xp : 90 , poids : "201-300" , plusdom : + 6 , sconst : 7 , sust : 8 } ,
24 : { xp : 100 , poids : "301-400" , plusdom : + 6 , sconst : 8 , sust : 9 } ,
25 : { xp : 110 , poids : "401-500" , plusdom : + 7 , sconst : 8 , sust : 10 } ,
26 : { xp : 120 , poids : "501-600" , plusdom : + 7 , sconst : 8 , sust : 11 } ,
27 : { xp : 130 , poids : "601-700" , plusdom : + 8 , sconst : 9 , sust : 12 } ,
28 : { xp : 140 , poids : "701-800" , plusdom : + 8 , sconst : 9 , sust : 13 } ,
29 : { xp : 150 , poids : "801-900" , plusdom : + 9 , sconst : 9 , sust : 14 } ,
30 : { xp : 160 , poids : "901-1000" , plusdom : + 9 , sconst : 10 , sust : 15 } ,
31 : { xp : 170 , poids : "1001-1500" , plusdom : + 10 , sconst : 10 , sust : 16 } ,
32 : { xp : 180 , poids : "1501-2000" , plusdom : + 11 , sconst : 10 , sust : 17 }
}
2020-12-01 00:05:18 +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-18 20:16:59 +01:00
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
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
/* Static tables for commands /table */
const table2func = {
"rdd" : { descr : "rdd: Ouvre la table de résolution" , func : RdDRollResolutionTable . open } ,
"queues" : { descr : "queues: Tire une queue de Dragon" , func : RdDRollTables . getQueue } ,
"ombre" : { descr : "ombre: Tire une Ombre de Dragon" , func : RdDRollTables . getOmbre } ,
"tetehr" : { descr : "tetehr: Tire une Tête de Dragon pour Hauts Revants" , fund : RdDRollTables . getTeteHR } ,
"tete" : { descr : "tete: Tire une Tête de Dragon" , func : RdDRollTables . getTete } ,
"souffle" : { descr : "souffle: Tire un Souffle de Dragon" , func : RdDRollTables . getSouffle } ,
"tarot" : { descr : "tarot: Tire une carte de Tarot Dracnique" , func : RdDRollTables . getTarot }
} ;
2020-07-14 22:19:29 +02: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 {
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' ,
2020-05-24 20:19:57 +02:00
//Items
'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' ,
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' ,
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
2021-01-05 18:43:13 +01:00
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-ajustements.html' ,
2020-12-21 23:35:29 +01:00
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html' ,
2020-06-12 22:46:04 +02:00
'systems/foundryvtt-reve-de-dragon/templates/dialog-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' ,
2020-11-27 12:20:13 +01:00
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-surenc.html' ,
2020-12-20 21:54:09 +01:00
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-enctotal.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' ,
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-11-12 14:43:08 +01:00
// Conteneur/item in Actor sheet
2020-12-01 20:52:05 +01:00
'systems/foundryvtt-reve-de-dragon/templates/actor-inventaire-conteneur.html' ,
2020-12-20 02:07:27 +01:00
'systems/foundryvtt-reve-de-dragon/templates/editor-notes-mj.html' ,
// 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-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-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' ,
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.html'
2020-05-24 20:19:57 +02:00
] ;
return loadTemplates ( templatePaths ) ;
}
2020-11-18 16:57:58 +01:00
2021-01-08 22:23:50 +01:00
/* -------------------------------------------- */
2020-11-18 16:57:58 +01:00
static checkNull ( items ) {
if ( items && items . length ) {
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
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static initAfficheContenu ( actorId ) { // persistent handling of conteneur show/hide
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-01-10 22:12:07 +01:00
if ( conteneurId )
return this . afficheContenu [ conteneurId ] ;
return undefined ;
2020-12-01 22:18:15 +01:00
}
2020-11-18 16:57:58 +01:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static filterItemsPerTypeForSheet ( data ) {
data . data . materiel = this . checkNull ( data . itemsByType [ 'objet' ] ) ;
data . data . conteneurs = this . checkNull ( data . itemsByType [ 'conteneur' ] ) ;
data . data . armes = this . checkNull ( data . itemsByType [ 'arme' ] ) ;
data . data . armures = this . checkNull ( data . itemsByType [ 'armure' ] ) ;
data . data . livres = this . checkNull ( data . itemsByType [ 'livre' ] ) ;
data . data . potions = this . checkNull ( data . itemsByType [ 'potion' ] ) ;
2020-11-18 16:57:58 +01:00
data . data . ingredients = this . checkNull ( data . itemsByType [ 'ingredient' ] ) ;
2021-01-08 22:23:50 +01:00
data . data . munitions = this . checkNull ( data . itemsByType [ 'munition' ] ) ;
data . data . herbes = this . checkNull ( data . itemsByType [ 'herbe' ] ) ;
data . data . sorts = this . checkNull ( data . itemsByType [ 'sort' ] ) ;
data . data . queues = this . checkNull ( data . itemsByType [ 'queue' ] ) ;
data . data . souffles = this . checkNull ( data . itemsByType [ 'souffle' ] ) ;
data . data . ombres = this . checkNull ( data . itemsByType [ 'ombre' ] ) ;
data . data . tetes = this . checkNull ( data . itemsByType [ 'tete' ] ) ;
data . data . taches = this . checkNull ( data . itemsByType [ 'tache' ] ) ;
data . data . monnaie = this . checkNull ( data . itemsByType [ 'monnaie' ] ) ;
2021-01-03 09:58:07 +01:00
data . data . meditations = this . checkNull ( data . itemsByType [ 'meditation' ] ) ;
2021-01-27 23:35:45 +01:00
data . data . chants = this . checkNull ( data . itemsByType [ 'chant' ] ) ;
data . data . danses = this . checkNull ( data . itemsByType [ 'danse' ] ) ;
data . data . musiques = this . checkNull ( data . itemsByType [ 'musique' ] ) ;
data . data . jeux = this . checkNull ( data . itemsByType [ 'jeu' ] ) ;
data . data . recettescuisine = this . checkNull ( data . itemsByType [ 'recettecuisine' ] ) ;
2021-01-07 20:04:10 +01:00
data . data . recettesAlchimiques = this . checkNull ( data . itemsByType [ 'recettealchimique' ] ) ;
2021-01-08 22:23:50 +01:00
data . data . objets = data . data . conteneurs . concat ( data . data . materiel ) . concat ( data . data . armes ) . concat ( data . data . armures ) . concat ( data . data . munitions ) . concat ( data . data . livres ) . concat ( data . data . potions ) . concat ( data . data . herbes ) . concat ( data . data . ingredients ) ;
2020-11-18 16:57:58 +01:00
}
2021-01-08 16:57:10 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
static async processItemDropEvent ( actorSheet , event ) {
2021-01-08 16:57:10 +01:00
let dragData = JSON . parse ( event . dataTransfer . getData ( "text/plain" ) ) ;
2021-01-08 23:33:44 +01:00
console . log ( dragData , actorSheet . actor . _id ) ;
2021-01-08 16:57:10 +01:00
let dropID = $ ( event . target ) . parents ( ".item" ) . attr ( "data-item-id" ) ; // Only relevant if container drop
2021-01-09 09:54:08 +01:00
let objetId = dragData . id || dragData . data . _id ;
2021-01-11 16:29:41 +01:00
if ( dragData . type == 'Item' ) {
if ( dropID ) { // Dropped over an item !!!
if ( actorSheet . objetVersConteneur [ objetId ] != dropID && objetId != dropID ) {
if ( actorSheet . actor . validateConteneur ( objetId , dropID ) && actorSheet . actor . testConteneurCapacite ( objetId , dropID ) ) {
await actorSheet . actor . enleverDeConteneur ( objetId , actorSheet . objetVersConteneur [ objetId ] ) ;
await actorSheet . actor . ajouterAConteneur ( objetId , dropID ) ;
}
2021-01-08 16:57:10 +01:00
}
}
2021-01-11 16:29:41 +01:00
if ( dragData . actorId && dragData . actorId != actorSheet . actor . _id ) { // Un acteur est à l'origine de l'item -> deplacement
console . log ( "Moving objects" ) ;
actorSheet . actor . moveItemsBetweenActors ( objetId , dragData . actorId ) ;
return false ;
}
actorSheet . actor . computeEncombrementTotalEtMalusArmure ( ) ;
} else if ( dragData . type == "Actor" ) {
actorSheet . actor . addSubacteur ( objetId ) ;
2021-01-08 16:57:10 +01:00
}
2021-01-09 09:54:08 +01:00
return true ;
2021-01-08 16:57:10 +01:00
}
2021-01-09 19:33:19 +01:00
2020-11-18 16:57:58 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
static buildArbreDeConteneur ( actorSheet , data ) {
2020-11-18 16:57:58 +01:00
actorSheet . objetVersConteneur = { } ; // Table de hash locale pour recupération rapide du conteneur parent (si existant)
// Attribution des objets aux conteneurs
for ( let conteneur of data . data . conteneurs ) {
conteneur . subItems = [ ] ;
2020-11-27 09:40:48 +01:00
if ( ! conteneur . data . encTotal ) conteneur . data . encTotal = 0 ;
//conteneur.data.encTotal = ; Deja calculé
2020-11-18 16:57:58 +01:00
if ( conteneur . data . contenu ) {
for ( let id of conteneur . data . contenu ) {
2021-01-08 22:23:50 +01:00
let objet = data . data . objets . find ( objet => ( id == objet . _id ) ) ;
2020-11-18 16:57:58 +01:00
if ( objet ) {
2020-11-27 09:40:48 +01:00
if ( ! objet . data . encombrement ) objet . data . encombrement = 0 ; // Auto-fix
objet . estContenu = true ; // Permet de filtrer ce qifui est porté dans le template
2020-11-18 16:57:58 +01:00
actorSheet . objetVersConteneur [ id ] = conteneur . _id ;
2021-01-08 22:23:50 +01:00
conteneur . data . encTotal += Number ( objet . data . encombrement ) * Number ( ( ( objet . data . quantite ) ? objet . data . quantite : 1 ) ) ;
conteneur . subItems . push ( objet ) ;
2020-11-18 16:57:58 +01:00
}
}
}
}
// Construit la liste des conteneurs de niveau 1 (c'est à dire non contenu eux-même dans un conteneur)
2021-01-08 22:23:50 +01:00
let newConteneurs = data . data . conteneurs . filter ( function ( conteneur , index , arr ) { return ! conteneur . estContenu } ) ;
2020-11-18 16:57:58 +01:00
data . data . conteneurs = newConteneurs ;
2021-01-07 23:40:20 +01:00
//console.log(newConteneurs);
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
*
* /
2021-01-08 22:23:50 +01:00
static buildConteneur ( objet , niveau ) {
2020-11-12 14:43:08 +01:00
if ( ! niveau ) niveau = 1 ;
2020-12-01 22:18:15 +01:00
objet . niveau = niveau ;
//console.log("OBJ:", objet);
2021-01-08 22:23:50 +01:00
let str = Handlebars . partials [ 'systems/foundryvtt-reve-de-dragon/templates/actor-inventaire-conteneur.html' ] ( { item : objet } ) ;
2020-11-12 14:43:08 +01:00
if ( objet . type == 'conteneur' ) {
2021-01-14 15:29:47 +01:00
//console.log("ITEM DISPLAYED", objet );
2021-01-08 22:23:50 +01:00
if ( this . getAfficheContenu ( objet . _id ) ) {
str = str + "<ul class='item-list alterne-list item-display-show list-item-margin" + niveau + "'>" ;
2020-12-01 22:18:15 +01:00
} else {
2021-01-08 22:23:50 +01:00
str = str + "<ul class='item-list alterne-list item-display-hide list-item-margin" + niveau + "'>" ;
2020-12-01 22:18:15 +01:00
}
2020-11-12 14:43:08 +01:00
for ( let subItem of objet . subItems ) {
2021-01-08 22:23:50 +01:00
str = str + this . buildConteneur ( subItem , niveau + 1 ) ;
2020-11-12 14:43:08 +01:00
}
2020-11-27 09:40:48 +01:00
str = str + "</ul>" ;
2020-11-12 14:43:08 +01:00
}
return new Handlebars . SafeString ( str ) ;
}
2020-05-24 20:19:57 +02:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static getCategorieCompetences ( ) {
return categorieCompetences ;
2020-05-24 20:19:57 +02:00
}
2021-01-08 22:23:50 +01:00
static getLevelCategory ( category ) {
return categorieCompetences [ category ] . level ;
2020-05-24 20:19:57 +02:00
}
2021-01-08 22:23:50 +01:00
static getLabelCategory ( category ) {
return categorieCompetences [ category ] . label ;
2020-12-02 20:52:37 +01: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
2021-01-03 18:19:18 +01:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static getCaracNextXp ( value ) {
2021-01-21 00:05:22 +01:00
const nextValue = Number ( value ) + 1 ;
2021-01-13 22:16:23 +01:00
// xp est le coût pour atteindre cette valeur, on regarde donc le coût de la valeur+1
2021-01-21 00:05:22 +01:00
return RdDUtility . getCaractXp ( nextValue ) ;
}
static getCaractXp ( targetValue ) {
return tableCaracDerivee [ targetValue ] . xp ;
2021-01-03 18:19:18 +01:00
}
2020-11-24 16:41:15 +01:00
/* -------------------------------------------- */
/** Retourne une liste triée d'armes avec le split arme1 main / arme 2 main */
2021-01-08 22:23:50 +01:00
static _finalizeArmeList ( armes , competences , carac ) {
2020-11-24 16:41:15 +01:00
// Gestion des armes 1/2 mains
2021-01-03 09:58:07 +01:00
let armesEquipe = [ ] ;
2021-01-08 22:23:50 +01:00
for ( const arme of armes ) {
2021-01-03 09:58:07 +01:00
if ( arme . data . equipe ) {
2021-01-08 22:23:50 +01:00
armesEquipe . push ( arme ) ;
let comp = competences . find ( c => c . name == arme . data . competence ) ;
2021-01-03 09:58:07 +01:00
arme . data . initiative = RdDUtility . calculInitiative ( arme . data . niveau , carac [ comp . data . defaut _carac ] . value ) ;
// Dupliquer les armes pouvant être à 1 main et 2 mains en patchant la compétence
2021-01-08 22:23:50 +01:00
if ( arme . data . unemain && ! arme . data . deuxmains ) {
2021-01-03 09:58:07 +01:00
arme . data . mainInfo = "(1m)" ;
2021-01-08 22:23:50 +01:00
} else if ( ! arme . data . unemain && arme . data . deuxmains ) {
2021-01-03 09:58:07 +01:00
arme . data . mainInfo = "(2m)" ;
} else if ( arme . data . unemain && arme . data . deuxmains ) {
arme . data . mainInfo = "(1m)" ;
let arme2main = duplicate ( arme ) ;
arme2main . data . mainInfo = "(2m)" ;
arme2main . data . dommages = arme2main . data . dommages . split ( "/" ) [ 1 ] ; // Existence temporaire uniquement dans la liste des armes, donc OK
arme2main . data . competence = arme2main . data . competence . replace ( " 1 main" , " 2 mains" ) ; // Replace !
2021-01-08 22:23:50 +01:00
let comp = competences . find ( c => c . name == arme2main . data . competence ) ;
2021-01-03 09:58:07 +01:00
arme2main . data . niveau = comp . data . niveau ;
arme2main . data . initiative = RdDUtility . calculInitiative ( arme2main . data . niveau , carac [ comp . data . defaut _carac ] . value ) ;
armesEquipe . push ( arme2main ) ;
}
2020-11-24 16:41:15 +01:00
}
}
2021-01-08 22:23:50 +01:00
return armesEquipe . sort ( ( a , b ) => {
2021-01-04 00:17:22 +01:00
const nameA = a . name + ( a . data . mainInfo ? ? '' ) ;
const nameB = b . name + ( b . data . mainInfo ? ? '' ) ;
2021-01-08 22:23:50 +01:00
if ( nameA > nameB ) return 1 ;
if ( nameA < nameB ) return - 1 ;
2021-01-04 00:17:22 +01:00
return 0 ;
2021-01-08 22:23:50 +01:00
} ) ;
2020-11-24 16:41:15 +01:00
}
2021-01-01 23:20:27 +01:00
/* -------------------------------------------- */
2020-12-09 00:36:38 +01:00
static calculInitiative ( niveau , caracValue ) {
2021-01-08 22:23:50 +01:00
let base = niveau + Math . floor ( caracValue / 2 ) ;
2020-12-09 00:36:38 +01:00
return "1d6" + ( base >= 0 ? "+" : "" ) + base ;
}
2020-08-14 22:24:35 +02:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static computeCarac ( data ) {
2020-11-17 13:08:52 +01:00
data . carac . force . value = Math . min ( data . carac . force . value , parseInt ( data . carac . taille . value ) + 4 ) ;
2021-01-08 22:23:50 +01:00
2020-05-24 20:19:57 +02:00
data . carac . derobee . value = Math . floor ( parseInt ( ( ( 21 - data . carac . taille . value ) ) + parseInt ( data . carac . agilite . value ) ) / 2 ) ;
2021-01-08 22:23:50 +01:00
let bonusDomKey = Math . floor ( ( parseInt ( data . carac . force . value ) + parseInt ( data . carac . taille . value ) ) / 2 ) ;
2021-01-12 13:18:29 +01:00
bonusDomKey = Math . min ( Math . max ( bonusDomKey , 0 ) , 32 ) ; // Clamp de securite
2020-11-17 13:08:52 +01:00
2021-01-13 22:16:23 +01:00
let tailleData = tableCaracDerivee [ bonusDomKey ] ;
2021-01-12 13:18:29 +01:00
data . attributs . plusdom . value = tailleData . plusdom ;
2021-01-24 19:52:02 +01:00
data . attributs . sconst . value = RdDUtility . calculSConst ( data . carac . constitution . value ) ;
2021-01-20 21:06:03 +01:00
data . attributs . sust . value = tableCaracDerivee [ Number ( data . carac . taille . value ) ] . sust ;
2021-01-08 22:23:50 +01:00
2020-05-24 20:19:57 +02:00
data . attributs . encombrement . value = ( parseInt ( data . carac . force . value ) + parseInt ( data . carac . taille . value ) ) / 2 ;
2021-01-08 22:23:50 +01:00
data . carac . melee . value = Math . floor ( ( parseInt ( data . carac . force . value ) + parseInt ( data . carac . agilite . value ) ) / 2 ) ;
data . carac . tir . value = Math . floor ( ( parseInt ( data . carac . vue . value ) + parseInt ( data . carac . dexterite . value ) ) / 2 ) ;
data . carac . lancer . value = Math . floor ( ( parseInt ( data . carac . tir . value ) + parseInt ( data . carac . force . value ) ) / 2 ) ;
data . sante . vie . max = Math . ceil ( ( parseInt ( data . carac . taille . value ) + parseInt ( data . carac . constitution . value ) ) / 2 ) ;
2020-11-17 13:08:52 +01:00
data . sante . vie . value = Math . min ( data . sante . vie . value , data . sante . vie . max )
2021-01-08 22:23:50 +01:00
data . sante . endurance . max = Math . max ( parseInt ( data . carac . taille . value ) + parseInt ( data . carac . constitution . value ) , parseInt ( data . sante . vie . max ) + parseInt ( data . carac . volonte . value ) ) ;
2020-11-17 13:08:52 +01:00
data . sante . endurance . value = Math . min ( data . sante . endurance . value , data . sante . endurance . max ) ;
2021-01-08 22:23:50 +01:00
data . sante . fatigue . max = data . sante . endurance . max * 2 ;
2020-11-17 13:08:52 +01:00
data . sante . fatigue . value = Math . min ( data . sante . fatigue . value , data . sante . fatigue . max ) ;
2021-01-08 22:23:50 +01:00
2020-05-29 00:43:16 +02:00
//Compteurs
2020-07-17 22:04:35 +02:00
data . reve . reve . max = data . carac . reve . value ;
data . compteurs . chance . max = data . carac . chance . value ;
2020-05-24 20:19:57 +02:00
}
2020-11-17 13:08:52 +01:00
2021-01-24 19:52:02 +01:00
static calculSConst ( constitution ) {
return Number ( tableCaracDerivee [ Number ( constitution ) ] . sconst ) ;
}
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
}
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
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-01-08 22:23:50 +01:00
static getLocalisation ( ) {
2021-01-06 16:24:05 +01:00
// TODO: bouger dans une RollTable du compendium et chercher dans les RoolTable puis compendium pour permettre le changement?
2020-12-04 20:52:04 +01:00
let result = new Roll ( "1d20" ) . roll ( ) . total ;
2020-06-07 23:16:29 +02:00
let txt = ""
2021-01-08 22:23:50 +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)" ;
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-11-11 10:38:27 +01:00
/* -------------------------------------------- */
2020-11-11 04:21:25 +01:00
static _evaluatePerte ( formula , over20 ) {
2021-01-09 19:33:19 +01:00
console . log ( "_evaluatePerte" , formula , over20 ) ;
let perte = new Roll ( formula , { over20 : over20 } ) ;
perte . evaluate ( ) ;
return perte . total ;
2020-06-07 23:16:29 +02:00
}
2021-01-08 22:23:50 +01:00
2020-06-12 22:46:04 +02:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static currentFatigueMalus ( value , max ) {
2021-01-05 18:43:13 +01:00
max = Math . max ( 1 , Math . min ( max , 60 ) ) ;
2021-01-08 22:23:50 +01:00
value = Math . min ( max * 2 , Math . max ( 0 , value ) ) ;
2020-05-29 00:43:16 +02:00
let fatigueTab = fatigueMatrix [ max ] ;
let fatigueRem = value ;
2021-01-08 22:23:50 +01:00
for ( let idx = 0 ; idx < fatigueTab . length ; idx ++ ) {
2020-05-29 00:43:16 +02:00
fatigueRem -= fatigueTab [ idx ] ;
2021-01-08 22:23:50 +01:00
if ( fatigueRem <= 0 ) {
2020-05-29 00:43:16 +02:00
return fatigueMalus [ idx ] ;
}
}
return - 7 ; // This is the max !
}
2020-12-12 21:58:44 +01:00
2020-12-15 21:28:55 +01:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static async loadCompendiumNames ( compendium ) {
2020-12-15 21:28:55 +01:00
const pack = game . packs . get ( compendium ) ;
let competences ;
await pack . getIndex ( ) . then ( index => competences = index ) ;
return competences ;
}
2021-01-12 13:18:29 +01:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static async loadCompendium ( compendium , filter = item => true ) {
let compendiumItems = await RdDUtility . loadCompendiumNames ( compendium ) ;
const pack = game . packs . get ( compendium ) ;
let list = [ ] ;
for ( let compendiumItem of compendiumItems ) {
await pack . getEntity ( compendiumItem . _id ) . then ( it => {
const item = it . data ;
if ( filter ( item ) ) {
list . push ( item ) ;
}
} ) ;
} ;
return list ;
}
2020-12-12 23:31:19 +01:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static async responseNombreAstral ( data ) {
let actor = game . actors . get ( data . id ) ;
2020-12-13 23:11:58 +01:00
actor . ajouteNombreAstral ( data ) ;
2020-12-12 23:31:19 +01:00
}
2020-06-17 20:31:43 +02:00
/* -------------------------------------------- */
2021-01-10 00:30:37 +01:00
static onSocketMesssage ( sockmsg ) {
2020-06-22 10:18:03 +02:00
console . log ( ">>>>> MSG RECV" , 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-01-23 23:56:43 +01:00
case "msg_tmr_move" :
if ( game . user . isGM ) {
let actor = game . actors . get ( sockmsg . data . actorId ) ;
actor . refreshTMRView ( sockmsg . data . tmrPos ) ;
}
2020-11-24 15:20:05 +01:00
}
}
2020-11-24 16:41:15 +01:00
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static rollInitiativeCompetence ( combatantId , arme ) {
2020-11-24 16:41:15 +01:00
const combatant = game . combat . getCombatant ( combatantId ) ;
2021-01-08 22:23:50 +01:00
const actor = combatant . actor ;
2021-01-13 11:35:36 +01:00
let initOffset = 0 ;
let caracForInit = 0 ;
let compNiveau = 0 ;
if ( actor . getSurprise ( ) == "totale" ) {
initOffset = - 1 ; // To force 0
} else if ( actor . getSurprise ( ) == "demi" ) {
initOffset = 0 ;
} else if ( arme . name == "Autre action" ) {
initOffset = 2 ;
2021-01-08 22:23:50 +01:00
} else if ( arme . name == "Draconic" ) {
2021-01-13 11:35:36 +01:00
initOffset = 7 ;
2020-11-24 17:41:14 +01:00
} else {
2021-01-18 11:24:39 +01:00
initOffset = 3 ; // Melée = 3.XX
2021-01-08 22:23:50 +01:00
let competence = RdDItemCompetence . findCompetence ( combatant . actor . data . items , arme . data . competence ) ;
2021-01-13 11:35:36 +01:00
compNiveau = competence . data . niveau ;
2021-01-08 22:23:50 +01:00
if ( actor . data . type == 'creature' || actor . data . type == 'entite' ) {
2020-11-24 17:47:35 +01:00
caracForInit = competence . data . carac _value ;
2021-01-18 11:32:22 +01:00
if ( competence . data . categorie == "lancer" ) {
initOffset = 5 ;
}
2020-11-24 17:41:14 +01:00
} else {
2021-01-08 22:23:50 +01:00
caracForInit = actor . data . data . carac [ competence . data . defaut _carac ] . value ;
if ( competence . data . categorie == "lancer" ) { // Offset de principe pour les armes de jet
2021-01-13 11:35:36 +01:00
initOffset = 4 ;
2021-01-08 22:23:50 +01:00
}
if ( competence . data . categorie == "tir" ) { // Offset de principe pour les armes de jet
2021-01-13 11:35:36 +01:00
initOffset = 5 ;
}
if ( competence . data . categorie == "melee" ) { // Offset de principe pour les armes de jet
initOffset = 3 ;
2021-01-08 22:23:50 +01:00
}
2020-11-24 17:41:14 +01:00
}
}
2021-01-13 11:35:36 +01:00
let malus = actor . getEtatGeneral ( ) ; // Prise en compte état général
// Cas des créatures et entités vs personnages
let rollFormula = initOffset + "+ ( (" + RdDUtility . calculInitiative ( compNiveau , caracForInit ) + " + " + malus + ") /100)" ;
game . combat . rollInitiative ( combatantId , rollFormula ) ;
2020-11-24 16:41:15 +01:00
}
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static buildListeActionsCombat ( combatant ) {
2020-12-05 00:04:40 +01:00
const actor = combatant . actor ; // Easy access
2021-01-04 00:17:22 +01:00
let items = actor . data . items ;
let actions = [ ]
2021-01-08 22:23:50 +01:00
if ( actor . isCreature ( ) ) {
2021-01-28 00:27:44 +01:00
actions = actions . concat ( items . filter ( it => RdDItemCompetenceCreature . isCompetenceAttaque ( it ) )
2021-01-04 00:17:22 +01:00
. map ( competence => RdDItemCompetenceCreature . toArme ( competence ) ) ) ;
2020-11-24 17:41:14 +01:00
} else {
// Recupération des items 'arme'
2021-01-28 00:27:44 +01:00
let armes = items . filter ( it => RdDItemArme . isArmeUtilisable ( it ) )
2021-01-04 00:17:22 +01:00
. map ( arme => duplicate ( arme ) ) /* pas de changements aux armes d'origine */
. concat ( RdDItemArme . mainsNues ( ) ) ;
2021-01-08 22:23:50 +01:00
2021-01-04 00:17:22 +01:00
let competences = items . filter ( it => it . type == 'competence' ) ;
2021-01-08 22:23:50 +01:00
actions = actions . concat ( this . _finalizeArmeList ( armes , competences , actor . data . data . carac ) ) ;
2021-01-04 00:17:22 +01:00
2021-01-08 22:23:50 +01:00
actions . push ( { name : "Draconic" , data : { initOnly : true , competence : "Draconic" } } ) ;
2021-01-04 00:17:22 +01:00
}
2021-01-08 22:23:50 +01:00
actions . push ( { name : "Autre action" , data : { initOnly : true , competence : "Autre action" } } ) ;
2021-01-04 00:17:22 +01:00
for ( let index = 0 ; index < actions . length ; index ++ ) {
actions [ index ] . index = index ;
2020-11-24 17:41:14 +01:00
}
2021-01-04 00:17:22 +01:00
return actions ;
2020-12-05 00:04:40 +01:00
}
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static displayInitiativeMenu ( html , combatantId ) {
2020-12-05 00:04:40 +01:00
const combatant = game . combat . getCombatant ( combatantId ) ;
2021-01-08 22:23:50 +01:00
let armesList = this . buildListeActionsCombat ( combatant ) ;
2020-12-05 00:04:40 +01:00
2020-11-24 17:41:14 +01:00
// Build the relevant submenu
2021-01-08 22:23:50 +01:00
if ( armesList ) {
2020-11-24 16:41:15 +01:00
let menuItems = [ ] ;
2021-01-08 22:23:50 +01:00
for ( let arme of armesList ) {
menuItems . push ( {
name : arme . data . competence ,
2020-11-24 16:41:15 +01:00
icon : "<i class='fas fa-dice-d6'></i>" ,
2021-01-08 22:23:50 +01:00
callback : target => { RdDUtility . rollInitiativeCompetence ( combatantId , arme ) }
} ) ;
2020-11-24 16:41:15 +01:00
}
2021-01-08 22:23:50 +01:00
new ContextMenu ( html , ".directory-list" , menuItems ) . render ( ) ;
2020-11-24 16:41:15 +01:00
}
}
/* -------------------------------------------- */
2021-01-08 22:23:50 +01:00
static pushInitiativeOptions ( html , options ) {
2020-11-24 16:41:15 +01:00
options . push (
{
name : "Sélectionner l'initiative..." ,
condition : true ,
icon : '<i class="far fa-question-circle"></i>' ,
2021-01-08 22:23:50 +01:00
callback : target => {
RdDUtility . displayInitiativeMenu ( html , target . data ( 'combatant-id' ) ) ;
2020-11-24 16:41:15 +01:00
}
2021-01-08 22:23:50 +01:00
} ) ;
2020-11-24 16:43:54 +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 ) ;
2020-11-17 18:08:19 +01:00
actor . tmrApp . forceDemiRevePosition ( coord ) ;
} ) ;
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
} ) ;
2020-12-31 00:55:02 +01:00
// Gestion du bouton payer
html . on ( "click" , '#payer-button' , event => {
let sumdenier = event . currentTarget . attributes [ 'data-somme-denier' ] . 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-01-08 22:23:50 +01:00
if ( game . user . character ) {
2021-01-01 21:11:56 +01:00
game . user . character . payerDenier ( sumdenier , objData ) ;
} else {
let msgPayer = "Vous devez avoir un acteur relié pour effectuer le paiement" ;
2021-01-08 22:23:50 +01:00
ChatMessage . create ( { content : msgPayer , whisper : [ game . user ] } ) ;
2021-01-01 21:11:56 +01:00
}
2020-12-31 00:55:02 +01:00
} ) ;
2020-06-07 23:16:29 +02:00
}
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 ) ,
data : {
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>" ;
msgPayer += "<a id='payer-button' class='chat-card-button' data-somme-denier='" + sumtotald + "'>Payer</a>"
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 = {
user : game . user . _id ,
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-01-11 16:29:41 +01:00
return chatData ;
}
/* -------------------------------------------- */
static confirmerSuppressionSubacteur ( actorSheet , li ) {
let actorId = li . data ( "actor-id" ) ;
let actor = game . actors . get ( actorId ) ;
let msgTxt = "<p>Etes vous certain de vouloir supprimer le lien vers ce véhicule/monture/suivant : " + actor . data . name + " ?</p>" ;
let buttons = {
delete : {
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"
}
}
let d = new Dialog ( {
title : "Confirmer la suppression du lien" ,
content : msgTxt ,
buttons : buttons ,
default : "cancel"
} ) ;
d . render ( true ) ;
}
2021-01-16 18:54:07 +01:00
/* -------------------------------------------- */
static async confirmerSuppression ( actorSheet , li ) {
2021-01-11 16:29:41 +01:00
let itemId = li . data ( "item-id" ) ;
let objet = actorSheet . actor . items . find ( item => item . _id == itemId ) ;
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 ) ;
actorSheet . actor . deleteOwnedItem ( itemId ) ;
li . slideUp ( 200 , ( ) => actorSheet . render ( false ) ) ;
}
} ,
cancel : {
icon : '<i class="fas fa-times"></i>' ,
label : "Annuler"
}
}
if ( objet . data . type == 'conteneur' && objet . data . data . contenu . length > 0 ) {
msgTxt += "<br>Cet objet est aussi un conteneur avec du contenu : choisissez l'option de suppression" ;
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-01-11 16:29:41 +01:00
2021-01-16 18:54:07 +01:00
/* -------------------------------------------- */
static afficherHeuresChanceMalchance ( heureNaissance ) {
2021-01-26 19:47:18 +01:00
if ( heureNaissance ) {
let ajustement = game . system . rdd . calendrier . getAjustementAstrologique ( heureNaissance ) ;
ChatMessage . create ( {
content : ` A l'heure ${ game . system . rdd . calendrier . getCurrentHeure ( ) } , le modificateur de Chance/Malchance pour l'heure de naissance ${ heureNaissance } est de : ${ ajustement } . ` ,
whisper : ChatMessage . getWhisperRecipients ( "MJ" )
2021-01-16 18:54:07 +01:00
} ) ;
2021-01-26 19:47:18 +01:00
}
else {
ui . notifications . warn ( "Pas d'heure de naissance selectionnée" )
}
2021-01-16 18:54:07 +01:00
}
2020-05-22 22:37:02 +02:00
}