2020-05-22 22:37:02 +02:00
import { RdDUtility } from "./rdd-utility.js" ;
2020-07-25 10:29:28 +02:00
import { TMRUtility } from "./tmr-utility.js" ;
2020-12-06 20:11:30 +01:00
import { RdDRollDialogEthylisme } from "./rdd-roll-ethylisme.js" ;
2020-12-06 19:29:10 +01:00
import { RdDRoll } from "./rdd-roll.js" ;
2020-07-05 21:45:25 +02:00
import { RdDTMRDialog } from "./rdd-tmr-dialog.js" ;
2020-11-14 03:16:03 +01:00
import { Misc } from "./misc.js" ;
2020-12-11 08:29:24 +01:00
import { RdDAstrologieJoueur } from "./rdd-astrologie-joueur.js" ;
2020-11-12 16:35:51 +01:00
import { RdDResolutionTable } from "./rdd-resolution-table.js" ;
2020-11-16 04:32:42 +01:00
import { RdDDice } from "./rdd-dice.js" ;
import { RdDRollTables } from "./rdd-rolltables.js" ;
2020-11-24 15:20:05 +01:00
import { ChatUtility } from "./chat-utility.js" ;
2020-12-04 20:52:04 +01:00
import { RdDItemSort } from "./item-sort.js" ;
2020-12-08 03:04:00 +01:00
import { Grammar } from "./grammar.js" ;
2020-12-27 19:55:51 +01:00
import { RdDEncaisser } from "./rdd-roll-encaisser.js" ;
2021-01-26 19:43:37 +01:00
import { RdDCombat } from "./rdd-combat.js" ;
2021-01-02 00:04:27 +01:00
import { RdDAudio } from "./rdd-audio.js" ;
2021-01-01 22:25:32 +01:00
import { RdDItemCompetence } from "./item-competence.js" ;
2021-01-04 00:17:22 +01:00
import { RdDItemArme } from "./item-arme.js" ;
2021-01-07 20:04:10 +01:00
import { RdDAlchimie } from "./rdd-alchimie.js" ;
2022-09-17 22:36:43 +02:00
import { STATUSES , StatusEffects } from "./status-effects.js" ;
2021-01-13 23:47:12 +01:00
import { RdDItemCompetenceCreature } from "./item-competencecreature.js" ;
2021-05-10 19:18:11 +02:00
import { RdDItemSigneDraconique } from "./item-signedraconique.js" ;
2021-01-26 19:43:37 +01:00
import { ReglesOptionelles } from "./regles-optionelles.js" ;
2021-02-06 23:58:15 +01:00
import { TMRRencontres } from "./tmr-rencontres.js" ;
import { Poetique } from "./poetique.js" ;
2021-02-11 02:48:27 +01:00
import { EffetsDraconiques } from "./tmr/effets-draconiques.js" ;
import { Draconique } from "./tmr/draconique.js" ;
2021-03-17 01:21:37 +01:00
import { RdDCarac } from "./rdd-carac.js" ;
2021-03-19 22:20:01 +01:00
import { Monnaie } from "./item-monnaie.js" ;
2021-05-18 01:04:27 +02:00
import { DialogConsommer } from "./dialog-item-consommer.js" ;
2021-04-10 21:07:53 +02:00
import { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js" ;
2021-05-18 01:04:27 +02:00
import { RollDataAjustements } from "./rolldata-ajustements.js" ;
2021-06-05 01:14:29 +02:00
import { DialogItemAchat } from "./dialog-item-achat.js" ;
2021-06-08 00:32:27 +02:00
import { RdDItem } from "./item.js" ;
2021-11-11 09:18:25 +01:00
import { RdDPossession } from "./rdd-possession.js" ;
2022-07-22 21:38:15 +02:00
import { ENTITE _BLURETTE , ENTITE _INCARNE , ENTITE _NONINCARNE , SYSTEM _RDD , SYSTEM _SOCKET _ID } from "./constants.js" ;
2022-10-04 23:23:43 +02:00
import { RdDConfirm } from "./rdd-confirm.js" ;
2022-07-22 21:38:15 +02:00
2022-09-07 18:47:56 +02:00
const POSSESSION _SANS _DRACONIC = {
img : 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp' ,
name : 'Sans draconic' ,
system : {
niveau : 0 ,
defaut _carac : "reve" ,
}
} ;
2021-11-11 09:18:25 +01:00
2022-09-19 20:15:01 +02:00
const PAS _DE _BLESSURE = { "active" : false , "psdone" : false , "scdone" : false , "premiers_soins" : 0 , "soins_complets" : 0 , "jours" : 0 , "loc" : "" } ;
2020-12-31 00:55:02 +01:00
/* -------------------------------------------- */
2020-12-15 23:54:05 +01:00
/ * *
* Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system .
* @ extends { Actor }
* /
2020-05-22 00:48:43 +02:00
export class RdDActor extends Actor {
2021-01-10 00:30:37 +01:00
/* -------------------------------------------- */
static init ( ) {
2021-03-29 23:41:08 +02:00
Hooks . on ( "preUpdateItem" , ( item , change , options , id ) => RdDActor . getParentActor ( item ) ? . onPreUpdateItem ( item , change , options , id ) ) ;
Hooks . on ( "createItem" , ( item , options , id ) => RdDActor . getParentActor ( item ) ? . onCreateItem ( item , options , id ) ) ;
Hooks . on ( "deleteItem" , ( item , options , id ) => RdDActor . getParentActor ( item ) ? . onDeleteItem ( item , options , id ) ) ;
2021-03-29 20:11:32 +02:00
Hooks . on ( "updateActor" , ( actor , change , options , actorId ) => actor . onUpdateActor ( change , options , actorId ) ) ;
2021-03-29 20:09:25 +02:00
}
2021-04-15 00:13:50 +02:00
static onSocketMessage ( sockmsg ) {
switch ( sockmsg . msg ) {
case "msg_remote_actor_call" :
return RdDActor . onRemoteActorCall ( sockmsg . data ) ;
2021-06-26 00:55:54 +02:00
case "msg_reset_nombre_astral" :
2021-06-01 21:58:40 +02:00
console . log ( "RESET ASTRAL" , game . user . character ) ;
game . user . character . resetNombreAstral ( ) ;
return ;
2021-04-15 00:13:50 +02:00
}
}
2022-09-07 18:47:56 +02:00
static remoteActorCall ( callData , canExecuteLocally = ( ) => Misc . isUniqueConnectedGM ( ) ) {
2022-01-29 18:49:06 +01:00
if ( canExecuteLocally ( ) ) {
2022-09-07 18:47:56 +02:00
RdDActor . onRemoteActorCall ( callData ) ;
2022-01-29 18:49:06 +01:00
return false ;
2021-05-27 01:47:34 +02:00
}
2021-05-27 19:40:45 +02:00
else {
2022-09-07 18:47:56 +02:00
game . socket . emit ( SYSTEM _SOCKET _ID , { msg : "msg_remote_actor_call" , data : callData } ) ;
2022-01-29 18:49:06 +01:00
return true ;
2021-05-27 01:47:34 +02:00
}
2021-04-15 00:13:50 +02:00
}
2022-09-07 18:47:56 +02:00
static onRemoteActorCall ( callData ) {
const actor = game . actors . get ( callData ? . actorId ) ;
2022-01-29 18:49:06 +01:00
if ( Misc . isOwnerPlayerOrUniqueConnectedGM ( actor ) ) { // Seul le joueur choisi effectue l'appel: le joueur courant si propriétaire de l'actor, ou le MJ sinon
2022-09-07 18:47:56 +02:00
const args = callData . args ;
console . info ( ` RdDActor.onRemoteActorCall: pour l'Actor ${ callData . actorId } , appel de RdDActor. ${ callData . method } ( ` , ... args , ')' ) ;
actor [ callData . method ] ( ... args ) ;
2021-04-15 00:13:50 +02:00
}
}
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-03-29 23:41:08 +02:00
static getParentActor ( document ) {
2021-03-29 20:09:25 +02:00
return document ? . parent instanceof Actor ? document . parent : undefined
2021-01-10 00:30:37 +01:00
}
2021-01-13 03:42:13 +01:00
2020-05-24 20:19:57 +02:00
/* -------------------------------------------- */
/ * *
* Override the create ( ) function to provide additional RdD functionality .
*
2021-04-28 23:25:48 +02:00
* This overrided create ( ) function adds initial items
* Namely : Basic skills , money ,
2020-05-24 20:19:57 +02:00
*
2022-09-07 18:47:56 +02:00
* @ param { Object } actorData Barebones actor template data which this function adds onto .
* @ param { Object } options Additional options which customize the creation workflow .
2020-05-24 20:19:57 +02:00
*
* /
2021-04-01 00:01:10 +02:00
static async create ( actorData , options ) {
2020-11-18 16:33:12 +01:00
// Case of compendium global import
2021-04-01 00:01:10 +02:00
if ( actorData instanceof Array ) {
return super . create ( actorData , options ) ;
2020-12-01 17:36:13 +01:00
}
2021-03-19 22:20:01 +01:00
2021-04-01 00:01:10 +02:00
const isPersonnage = actorData . type == "personnage" ;
2020-05-24 20:19:57 +02:00
// If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
2021-04-01 00:01:10 +02:00
if ( actorData . items ) {
2021-06-02 18:19:47 +02:00
let actor = await super . create ( actorData , options ) ;
2021-03-19 22:20:01 +01:00
if ( isPersonnage ) {
2022-09-07 18:47:56 +02:00
await actor . checkMonnaiePresence ( ) ;
2021-01-05 11:47:22 +01:00
}
2021-01-08 22:23:50 +01:00
return actor ;
2020-05-24 20:19:57 +02:00
}
2021-01-09 19:33:19 +01:00
2021-03-19 22:20:01 +01:00
if ( isPersonnage ) {
2022-07-17 01:54:01 +02:00
const competences = await RdDUtility . loadCompendium ( RdDItemCompetence . actorCompendium ( actorData . type ) ) ;
actorData . items = competences . map ( i => i . toObject ( ) ) ;
2021-04-01 00:01:10 +02:00
actorData . items = actorData . items . concat ( Monnaie . monnaiesData ( ) ) ;
2021-01-09 19:33:19 +01:00
}
2022-07-17 01:54:01 +02:00
else {
actorData . items = [ ] ;
}
2021-04-01 00:01:10 +02:00
return super . create ( actorData , options ) ;
2020-09-20 16:36:39 +02:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2020-05-22 00:48:43 +02:00
prepareData ( ) {
super . prepareData ( ) ;
2020-05-22 19:28:01 +02:00
2020-11-11 14:42:11 +01:00
// Dynamic computing fields
2020-12-20 21:54:09 +01:00
this . encTotal = 0 ;
2020-11-11 14:42:11 +01:00
2020-05-22 00:48:43 +02:00
// Make separate methods for each Actor type (character, npc, etc.) to keep
// things organized.
2022-06-12 08:17:59 +02:00
if ( this . type === 'personnage' ) this . _prepareCharacterData ( this )
if ( this . type === 'creature' ) this . _prepareCreatureData ( this )
if ( this . type === 'vehicule' ) this . _prepareVehiculeData ( this )
2021-01-08 16:57:10 +01:00
}
2021-02-26 23:54:17 +01:00
/* -------------------------------------------- */
2021-03-15 00:05:56 +01:00
setRollWindowsOpened ( flag ) {
2021-02-26 23:54:17 +01:00
this . rollWindowsOpened = flag ;
}
/* -------------------------------------------- */
2021-03-15 00:05:56 +01:00
isRollWindowsOpened ( ) {
2021-02-26 23:54:17 +01:00
return this . rollWindowsOpened ;
}
2021-01-08 16:57:10 +01:00
/* -------------------------------------------- */
2021-01-24 19:52:02 +01:00
_prepareCreatureData ( actorData ) {
2021-01-08 16:57:10 +01:00
this . computeEncombrementTotalEtMalusArmure ( ) ;
this . computeEtatGeneral ( ) ;
2020-05-22 00:48:43 +02:00
}
2021-01-10 22:12:07 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
_prepareVehiculeData ( actorData ) {
2021-01-10 22:12:07 +01:00
this . computeEncombrementTotalEtMalusArmure ( ) ;
}
2020-06-03 21:35:18 +02:00
/* -------------------------------------------- */
2020-05-22 00:48:43 +02:00
/ * *
* Prepare Character type specific data
* /
2021-01-01 21:11:56 +01:00
async _prepareCharacterData ( actorData ) {
2020-05-24 20:19:57 +02:00
// Initialize empty items
2022-06-12 08:17:59 +02:00
RdDCarac . computeCarac ( actorData . system )
2021-04-01 21:33:43 +02:00
this . computeIsHautRevant ( ) ;
2021-05-28 18:30:05 +02:00
await this . cleanupConteneurs ( ) ;
2021-04-20 00:49:01 +02:00
await this . computeEncombrementTotalEtMalusArmure ( ) ;
2021-01-29 23:17:18 +01:00
this . computePrixTotalEquipement ( ) ;
2020-06-07 23:16:29 +02:00
this . computeEtatGeneral ( ) ;
2021-01-05 11:25:28 +01:00
// Sanity check
2022-09-07 18:47:56 +02:00
await this . checkMonnaiePresence ( ) ;
2020-05-22 00:48:43 +02:00
}
2020-12-31 00:55:02 +01:00
2021-05-28 18:30:05 +02:00
/* -------------------------------------------- */
async cleanupConteneurs ( ) {
let updates = this . listItemsData ( 'conteneur' )
2022-06-12 08:17:59 +02:00
. filter ( c => c . system . contenu . filter ( id => this . getObjet ( id ) == undefined ) . length > 0 )
2022-09-07 09:01:23 +02:00
. map ( c => { return { _id : c . _id , 'system.contenu' : c . system . contenu . filter ( id => this . getObjet ( id ) != undefined ) } } ) ;
2021-05-28 18:30:05 +02:00
if ( updates . length > 0 ) {
await this . updateEmbeddedDocuments ( "Item" , updates )
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2022-09-07 18:47:56 +02:00
async checkMonnaiePresence ( ) { // Ajout opportuniste si les pièces n'existent pas.
if ( ! this . items ) return ; // Sanity check during import
2022-09-19 20:16:16 +02:00
let manquantes = Monnaie . monnaiesManquantes ( this ) ;
2021-03-19 22:20:01 +01:00
if ( manquantes . length > 0 ) {
2021-03-25 03:18:27 +01:00
await this . createEmbeddedDocuments ( 'Item' , manquantes , { renderSheet : false } ) ;
2020-12-31 10:55:40 +01:00
}
}
2021-01-09 19:33:19 +01:00
2020-12-12 21:58:44 +01:00
/* -------------------------------------------- */
isCreature ( ) {
2022-04-30 19:15:55 +02:00
return this . type == 'creature' || this . type == 'entite' ;
2020-12-12 21:58:44 +01:00
}
2020-12-18 23:57:28 +01:00
/* -------------------------------------------- */
isPersonnage ( ) {
2022-04-30 19:15:55 +02:00
return this . type == 'personnage' ;
2020-12-18 23:57:28 +01:00
}
2021-02-02 19:17:59 +01:00
/* -------------------------------------------- */
2021-04-04 00:16:49 +02:00
isHautRevant ( ) {
2022-06-12 12:14:55 +02:00
return this . isPersonnage ( ) && this . system . attributs . hautrevant . value != ""
2021-04-04 00:16:49 +02:00
}
/* -------------------------------------------- */
2021-02-02 19:17:59 +01:00
getFatigueActuelle ( ) {
2021-05-08 20:08:56 +02:00
if ( ReglesOptionelles . isUsing ( "appliquer-fatigue" ) && this . isPersonnage ( ) ) {
2022-06-12 08:17:59 +02:00
return this . system . sante . fatigue ? . value ;
2021-02-02 19:17:59 +01:00
}
2021-05-08 20:08:56 +02:00
return 0 ;
2021-02-02 19:17:59 +01:00
}
/* -------------------------------------------- */
getFatigueMax ( ) {
if ( ! this . isPersonnage ( ) ) {
return 1 ;
}
2022-04-30 19:15:55 +02:00
return Misc . toInt ( this . system . sante . fatigue ? . max ) ;
2021-02-02 19:17:59 +01:00
}
2020-07-14 22:19:29 +02:00
/* -------------------------------------------- */
2020-11-16 04:01:36 +01:00
getReveActuel ( ) {
2022-06-12 08:17:59 +02:00
return Misc . toInt ( this . system . reve ? . reve ? . value ? ? this . carac . reve . value ) ;
2020-07-14 22:19:29 +02:00
}
2021-01-23 18:36:30 +01:00
/* -------------------------------------------- */
2020-12-06 19:29:10 +01:00
getChanceActuel ( ) {
2022-04-30 19:15:55 +02:00
return Misc . toInt ( this . system . compteurs . chance ? . value ? ? 10 ) ;
2020-12-06 19:29:10 +01:00
}
2020-12-15 02:20:24 +01:00
/* -------------------------------------------- */
2021-01-23 18:36:30 +01:00
getTaille ( ) {
2022-04-30 19:15:55 +02:00
return Misc . toInt ( this . system . carac . taille ? . value ) ;
2021-01-23 18:36:30 +01:00
}
/* -------------------------------------------- */
getForce ( ) {
2022-07-22 21:38:15 +02:00
if ( this . isEntite ( ) ) {
2022-04-30 19:15:55 +02:00
return Misc . toInt ( this . system . carac . reve ? . value ) ;
2021-01-23 18:36:30 +01:00
}
2022-04-30 19:15:55 +02:00
return Misc . toInt ( this . system . carac . force ? . value ) ;
2021-01-23 18:36:30 +01:00
}
/* -------------------------------------------- */
getAgilite ( ) {
2022-06-12 12:14:55 +02:00
switch ( this . type ) {
2022-04-30 19:15:55 +02:00
case 'personnage' : return Misc . toInt ( this . system . carac . agilite ? . value ) ;
case 'creature' : return Misc . toInt ( this . system . carac . force ? . value ) ;
case 'entite' : return Misc . toInt ( this . system . carac . reve ? . value ) ;
2021-01-23 18:36:30 +01:00
}
return 10 ;
2021-01-05 18:43:13 +01:00
}
2021-01-29 01:02:57 +01:00
/* -------------------------------------------- */
getChance ( ) {
2022-04-30 19:15:55 +02:00
return Misc . toInt ( this . system . carac . chance ? . value ? ? 10 ) ;
2021-01-29 01:02:57 +01:00
}
2021-01-05 18:43:13 +01:00
getMoralTotal ( ) {
2022-04-30 19:15:55 +02:00
return Misc . toInt ( this . system . compteurs . moral ? . value ) ;
2020-12-12 21:58:44 +01:00
}
2020-12-15 02:20:24 +01:00
/* -------------------------------------------- */
getBonusDegat ( ) {
2020-12-16 23:02:15 +01:00
// TODO: gérer séparation et +dom créature/entité indépendament de la compétence
2022-04-30 19:15:55 +02:00
return Misc . toInt ( this . system . attributs . plusdom . value ) ;
2020-12-15 18:36:18 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2020-12-15 18:36:18 +01:00
getProtectionNaturelle ( ) {
2022-04-30 19:15:55 +02:00
return Misc . toInt ( this . system . attributs . protection . value ) ;
2020-12-15 02:20:24 +01:00
}
2021-05-07 00:01:07 +02:00
2021-01-13 16:34:24 +01:00
/* -------------------------------------------- */
2021-04-06 23:39:27 +02:00
getEtatGeneral ( options = { ethylisme : false } ) {
2022-06-12 08:17:59 +02:00
let etatGeneral = Misc . toInt ( this . system . compteurs . etat ? . value )
2021-04-06 23:39:27 +02:00
if ( options . ethylisme ) {
// Pour les jets d'Ethylisme, on ignore le degré d'éthylisme (p.162)
2022-06-12 08:17:59 +02:00
etatGeneral -= Math . min ( 0 , this . system . compteurs . ethylisme . value )
2021-04-06 23:39:27 +02:00
}
2022-06-12 08:17:59 +02:00
return etatGeneral
2021-01-05 18:43:13 +01:00
}
2021-11-08 07:47:21 +01:00
/* -------------------------------------------- */
2021-12-05 01:50:09 +01:00
getActivePoisons ( ) {
2022-04-30 19:15:55 +02:00
return duplicate ( this . items . filter ( item => item . type == 'poison' && item . system . active ) )
2021-11-08 07:47:21 +01:00
}
2021-12-05 01:50:09 +01:00
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-01-05 18:43:13 +01:00
getMalusArmure ( ) {
2022-06-12 08:17:59 +02:00
return Misc . toInt ( this . system . attributs ? . malusarmure ? . value )
2021-01-05 18:43:13 +01:00
}
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-01-05 18:43:13 +01:00
getEncTotal ( ) {
return Math . floor ( this . encTotal ? ? 0 ) ;
}
2021-05-07 00:01:07 +02:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-12-05 01:50:09 +01:00
getCompetence ( idOrName , options = { } ) {
2022-06-12 08:17:59 +02:00
return RdDItemCompetence . findCompetence ( this . items , idOrName , options )
2021-01-09 19:33:19 +01:00
}
2021-11-20 01:04:22 +01:00
getCompetences ( name ) {
2022-06-12 08:17:59 +02:00
return RdDItemCompetence . findCompetences ( this . items , name )
2021-11-20 01:04:22 +01:00
}
2021-01-05 18:43:13 +01:00
/* -------------------------------------------- */
2021-03-29 09:17:00 +02:00
getObjet ( id ) {
2022-04-30 19:15:55 +02:00
return id ? this . items . find ( it => it . id == id ) : undefined ;
2021-03-29 09:17:00 +02:00
}
2021-11-20 01:04:22 +01:00
2021-04-01 00:01:10 +02:00
listItemsData ( type ) {
2022-09-07 18:47:56 +02:00
return this . itemTypes [ type ] ;
2021-04-01 00:01:10 +02:00
}
2022-09-07 18:47:56 +02:00
2021-05-04 15:18:32 +02:00
filterItems ( filter ) {
2022-09-07 18:47:56 +02:00
return this . items . filter ( filter ) ;
2021-05-04 15:18:32 +02:00
}
2021-11-20 01:04:22 +01:00
getItemOfType ( idOrName , type ) {
2022-04-30 19:15:55 +02:00
return this . items . find ( it => it . id == idOrName && it . type == type )
? ? Misc . findFirstLike ( idOrName , this . items , { filter : it => it . type == type , description : type } ) ;
2021-03-29 09:17:00 +02:00
}
2021-11-20 01:04:22 +01:00
2021-03-29 18:08:18 +02:00
getMonnaie ( id ) {
return this . getItemOfType ( id , 'monnaie' ) ;
}
2021-01-09 19:33:19 +01:00
getTache ( id ) {
2021-03-29 09:17:00 +02:00
return this . getItemOfType ( id , 'tache' ) ;
2021-01-05 18:43:13 +01:00
}
2021-01-09 19:33:19 +01:00
getMeditation ( id ) {
2021-03-29 09:17:00 +02:00
return this . getItemOfType ( id , 'meditation' ) ;
2020-12-12 21:58:44 +01:00
}
2021-01-27 23:35:45 +01:00
getChant ( id ) {
2021-03-29 09:17:00 +02:00
return this . getItemOfType ( id , 'chant' ) ;
2021-01-27 23:35:45 +01:00
}
getDanse ( id ) {
2021-03-29 09:17:00 +02:00
return this . getItemOfType ( id , 'danse' ) ;
2021-01-27 23:35:45 +01:00
}
getMusique ( id ) {
2021-03-29 09:17:00 +02:00
return this . getItemOfType ( id , 'musique' ) ;
2021-01-27 23:35:45 +01:00
}
2021-02-06 01:34:01 +01:00
getOeuvre ( id , type = 'oeuvre' ) {
2021-03-29 23:41:08 +02:00
return this . getItemOfType ( id , type ) ;
2021-02-06 01:34:01 +01:00
}
2021-01-27 23:35:45 +01:00
getJeu ( id ) {
2021-03-29 09:17:00 +02:00
return this . getItemOfType ( id , 'jeu' ) ;
2021-01-27 23:35:45 +01:00
}
getRecetteCuisine ( id ) {
2021-03-29 09:17:00 +02:00
return this . getItemOfType ( id , 'recettecuisine' ) ;
2021-01-27 23:35:45 +01:00
}
2020-07-14 22:19:29 +02:00
/* -------------------------------------------- */
2021-03-29 18:08:18 +02:00
getDraconicList ( ) {
2022-04-30 19:15:55 +02:00
return this . items . filter ( it => it . type == 'competence' && it . system . categorie == 'draconic' )
2021-03-29 18:08:18 +02:00
}
/* -------------------------------------------- */
2020-07-14 22:19:29 +02:00
getBestDraconic ( ) {
2022-04-30 19:15:55 +02:00
const list = this . getDraconicList ( )
2022-09-07 18:47:56 +02:00
. sort ( Misc . descending ( it => it . system . niveau ) )
2022-04-30 19:15:55 +02:00
return duplicate ( list [ 0 ] )
2021-06-26 00:09:28 +02:00
}
2022-09-07 18:47:56 +02:00
2022-07-02 01:41:55 +02:00
getDraconicOuPossession ( ) {
2022-07-02 09:02:31 +02:00
const possessions = this . items . filter ( it => it . type == 'competencecreature' && it . system . ispossession )
. sort ( Misc . descending ( it => it . system . niveau ) ) ;
2022-07-22 22:53:48 +02:00
if ( possessions . length > 0 ) {
2022-07-02 01:41:55 +02:00
return duplicate ( possessions [ 0 ] ) ;
2021-01-09 19:33:19 +01:00
}
2022-09-07 18:47:56 +02:00
const draconics = [ ... this . getDraconicList ( ) . filter ( it => it . system . niveau >= 0 ) ,
POSSESSION _SANS _DRACONIC ]
. sort ( Misc . descending ( it => it . system . niveau ) ) ;
return duplicate ( draconics [ 0 ] ) ;
2022-07-02 01:41:55 +02:00
}
2022-09-07 18:47:56 +02:00
2022-07-02 01:41:55 +02:00
getPossession ( possessionId ) {
2022-07-02 09:02:31 +02:00
return this . items . find ( it => it . type == 'possession' && it . system . possessionid == possessionId ) ;
2021-01-09 19:33:19 +01:00
}
2022-07-03 15:32:20 +02:00
getPossessions ( ) {
return this . items . filter ( it => it . type == 'possession' ) ;
}
2021-06-26 00:09:28 +02:00
2021-02-28 01:50:46 +01:00
getDemiReve ( ) {
2022-04-30 19:15:55 +02:00
return this . system . reve . tmrpos . coord ;
2021-02-28 01:50:46 +01:00
}
2021-04-11 18:43:32 +02:00
2021-04-09 15:23:48 +02:00
/* -------------------------------------------- */
async verifierPotionsEnchantees ( ) {
2022-09-07 18:47:56 +02:00
let potionsEnchantees = this . filterItems ( it => it . type == 'potion' && it . system . categorie . toLowerCase ( ) . includes ( 'enchant' ) ) ;
2021-04-11 18:43:32 +02:00
for ( let potion of potionsEnchantees ) {
2022-06-12 08:17:59 +02:00
if ( ! potion . system . prpermanent ) {
2021-04-09 15:23:48 +02:00
console . log ( potion ) ;
2022-06-12 08:17:59 +02:00
let newPr = ( potion . system . pr > 0 ) ? potion . system . pr - 1 : 0 ;
2022-09-07 09:01:23 +02:00
let update = { _id : potion . _id , 'system.pr' : newPr } ;
2021-04-09 15:23:48 +02:00
const updated = await this . updateEmbeddedDocuments ( 'Item' , [ update ] ) ; // Updates one EmbeddedEntity
let messageData = {
2021-04-11 18:43:32 +02:00
pr : newPr ,
alias : this . name ,
potionName : potion . name ,
potionImg : potion . img
2021-04-09 15:23:48 +02:00
}
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name ) ,
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html ` , messageData )
} ) ;
}
}
}
2021-03-29 09:17:00 +02:00
2020-12-14 10:38:43 +01:00
/* -------------------------------------------- */
2021-01-31 19:37:21 +01:00
getSurprise ( isCombat = undefined ) {
2022-09-17 22:36:43 +02:00
let niveauSurprise = this . getEffects ( )
2022-06-12 12:14:55 +02:00
. map ( effect => StatusEffects . valeurSurprise ( effect , isCombat ) )
2021-03-29 18:08:18 +02:00
. reduce ( Misc . sum ( ) , 0 ) ;
2021-02-11 02:48:27 +01:00
if ( niveauSurprise > 1 ) {
2021-01-13 03:42:13 +01:00
return 'totale' ;
}
2021-06-30 01:01:24 +02:00
if ( niveauSurprise == 1 ) {
2020-12-12 21:58:44 +01:00
return 'demi' ;
}
return '' ;
}
2021-06-26 00:55:54 +02:00
/* -------------------------------------------- */
async grisReve ( nGrisReve ) {
let message = {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( this . name ) ,
content : ` ${ nGrisReve } jours de gris rêve sont passés. `
} ;
for ( let i = 0 ; i < nGrisReve ; i ++ ) {
await this . dormir ( 6 , { grisReve : true } ) ;
2022-04-30 19:15:55 +02:00
const blessures = duplicate ( this . system . blessures ) ;
2021-06-26 00:55:54 +02:00
await this . _recupererBlessures ( message , "legere" , blessures . legeres . liste . filter ( b => b . active ) , [ ] ) ;
await this . _recupererBlessures ( message , "grave" , blessures . graves . liste . filter ( b => b . active ) , blessures . legeres . liste ) ;
await this . _recupererBlessures ( message , "critique" , blessures . critiques . liste . filter ( b => b . active ) , blessures . graves . liste ) ;
2022-06-12 19:40:44 +02:00
await this . update ( { "system.blessures" : blessures } ) ;
2021-06-26 00:55:54 +02:00
await this . _recupererVie ( message ) ;
2022-04-30 19:15:55 +02:00
const moralActuel = Misc . toInt ( this . system . compteurs . moral . value ) ;
2021-06-26 00:55:54 +02:00
if ( moralActuel != 0 ) {
await this . moralIncDec ( - Math . sign ( moralActuel ) ) ;
}
await this . _recupereChance ( ) ;
await this . transformerStress ( ) ;
this . bonusRecuperationPotion = 0 ; // Reset potion
}
ChatMessage . create ( message ) ;
this . sheet . render ( true ) ;
}
2020-12-04 20:52:04 +01:00
/* -------------------------------------------- */
2020-11-24 18:54:13 +01:00
async dormirChateauDormant ( ) {
2021-01-09 19:33:19 +01:00
let message = {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( this . name ) ,
content : ""
2020-11-24 18:54:13 +01:00
} ;
2020-12-19 01:14:02 +01:00
2022-06-12 08:17:59 +02:00
const blessures = duplicate ( this . system . blessures )
2020-11-24 18:54:13 +01:00
await this . _recupererBlessures ( message , "legere" , blessures . legeres . liste . filter ( b => b . active ) , [ ] ) ;
await this . _recupererBlessures ( message , "grave" , blessures . graves . liste . filter ( b => b . active ) , blessures . legeres . liste ) ;
2020-12-27 20:23:14 +01:00
await this . _recupererBlessures ( message , "critique" , blessures . critiques . liste . filter ( b => b . active ) , blessures . graves . liste ) ;
2022-06-12 19:40:44 +02:00
await this . update ( { "system.blessures" : blessures } ) ;
2020-11-24 18:54:13 +01:00
await this . _recupererVie ( message ) ;
2021-11-07 21:36:11 +01:00
await this . _jetDeMoralChateauDormant ( message ) ;
2021-03-20 00:09:29 +01:00
await this . _recupereChance ( ) ;
await this . transformerStress ( ) ;
await this . retourSeuilDeReve ( message ) ;
2021-04-11 18:43:32 +02:00
this . bonusRecuperationPotion = 0 ; // Reset potion
2021-04-06 23:44:57 +02:00
await this . retourSust ( message ) ;
2021-04-09 15:23:48 +02:00
await this . verifierPotionsEnchantees ( ) ;
2021-06-26 00:55:54 +02:00
if ( message . content != "" ) {
message . content = ` A la fin Chateau Dormant, ${ message . content } <br>Un nouveau jour se lève ` ;
ChatMessage . create ( message ) ;
}
2021-06-01 20:02:26 +02:00
this . sheet . render ( true ) ;
2021-03-20 00:09:29 +01:00
}
2021-02-17 11:16:27 +01:00
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-03-20 00:09:29 +01:00
async _recupereChance ( ) {
2021-02-17 11:16:27 +01:00
// On ne récupère un point de chance que si aucun appel à la chance dans la journée
2022-01-29 22:49:34 +01:00
if ( this . getChanceActuel ( ) < this . getChance ( ) && ! this . getFlag ( SYSTEM _RDD , 'utilisationChance' ) ) {
2021-02-17 11:16:27 +01:00
await this . chanceActuelleIncDec ( 1 ) ;
}
2021-03-30 23:01:09 +02:00
// Nouveau jour, suppression du flag
2022-01-29 22:49:34 +01:00
await this . unsetFlag ( SYSTEM _RDD , 'utilisationChance' ) ;
2020-11-24 18:54:13 +01:00
}
2021-11-07 21:36:11 +01:00
async _jetDeMoralChateauDormant ( message ) {
const jetMoral = await this . _jetDeMoral ( 'neutre' ) ;
message . content += jetMoral . ajustement == 0 ? ' -- le moral reste stable' : ' -- le moral retourne vers 0' ;
}
2020-12-04 20:52:04 +01:00
/* -------------------------------------------- */
2020-11-24 18:54:13 +01:00
async _recupererBlessures ( message , type , liste , moindres ) {
2021-04-04 23:07:13 +02:00
if ( ! this . bonusRecuperationPotion ) this . bonusRecuperationPotion = 0 ;
2020-11-24 18:54:13 +01:00
let count = 0 ;
const definitions = RdDUtility . getDefinitionsBlessures ( ) ;
2021-01-09 19:33:19 +01:00
let definition = definitions . find ( d => d . type == type ) ;
2020-11-24 18:54:13 +01:00
for ( let blessure of liste ) {
if ( blessure . jours >= definition . facteur ) {
2021-04-11 18:43:32 +02:00
let rolled = await this . _jetRecuperationConstitution ( Misc . toInt ( blessure . soins _complets ) + this . bonusRecuperationPotion , message ) ;
2020-11-24 18:54:13 +01:00
blessure . soins _complets = 0 ;
if ( rolled . isSuccess && this . _retrograderBlessure ( type , blessure , moindres ) ) {
2021-01-09 19:33:19 +01:00
message . content += ` -- une blessure ${ type } cicatrise ` ;
count ++ ;
2020-11-24 18:54:13 +01:00
}
else if ( rolled . isETotal ) {
2021-01-09 19:33:19 +01:00
message . content += ` -- une blessure ${ type } s'infecte (temps de guérison augmenté de ${ definition . facteur } jours, perte de vie) ` ;
blessure . jours = 0 ;
await this . santeIncDec ( "vie" , - 1 ) ;
2020-11-24 18:54:13 +01:00
}
else {
2021-10-07 22:36:20 +02:00
blessure . jours ++ ;
2021-01-09 19:33:19 +01:00
message . content += ` -- une blessure ${ type } reste stable ` ;
2020-11-24 18:54:13 +01:00
}
}
else {
blessure . jours ++ ;
}
}
}
2020-12-05 21:24:31 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
_retrograderBlessure ( type , blessure , blessuresMoindres ) {
2020-11-24 18:54:13 +01:00
if ( type != "legere" ) {
let retrograde = blessuresMoindres . find ( b => ! b . active ) ;
if ( ! retrograde ) {
return false ;
}
2021-10-29 22:37:27 +02:00
mergeObject ( retrograde , { "active" : true , "psdone" : blessure . psdone , "scdone" : blessure . scdone , "premiers_soins" : 0 , "soins_complets" : 0 , "jours" : 0 , "loc" : blessure . loc } ) ;
2020-11-24 18:54:13 +01:00
}
2020-12-01 01:17:18 +01:00
this . _supprimerBlessure ( blessure ) ;
2020-11-24 18:54:13 +01:00
return true ;
}
2021-01-09 19:33:19 +01:00
2020-12-05 21:24:31 +01:00
/* -------------------------------------------- */
2020-12-01 01:17:18 +01:00
_supprimerBlessure ( blessure ) {
2022-09-19 20:15:01 +02:00
mergeObject ( blessure , PAS _DE _BLESSURE ) ;
2020-12-01 01:17:18 +01:00
}
2020-12-05 21:24:31 +01:00
/* -------------------------------------------- */
2020-11-24 18:54:13 +01:00
async _recupererVie ( message ) {
2022-06-12 09:46:58 +02:00
const tData = this . system
2021-03-22 20:10:37 +01:00
let blessures = [ ] . concat ( tData . blessures . legeres . liste ) . concat ( tData . blessures . graves . liste ) . concat ( tData . blessures . critiques . liste ) ;
2020-11-24 18:54:13 +01:00
let nbBlessures = blessures . filter ( b => b . active ) ;
2021-03-22 20:10:37 +01:00
let vieManquante = tData . sante . vie . max - tData . sante . vie . value ;
2021-01-09 19:33:19 +01:00
if ( nbBlessures == 0 && vieManquante > 0 ) {
2020-11-24 18:54:13 +01:00
let bonusSoins = 0 ;
2021-01-09 19:33:19 +01:00
for ( let b of blessures ) {
2020-11-24 18:54:13 +01:00
bonusSoins = Math . max ( bonusSoins , Misc . toInt ( b . soins _complets ) ) ;
}
let rolled = await this . _jetRecuperationConstitution ( bonusSoins , message )
if ( rolled . isSuccess ) {
const gain = Math . min ( rolled . isPart ? 2 : 1 , vieManquante ) ;
2021-01-09 19:33:19 +01:00
message . content += " -- récupération de vie: " + gain ;
2020-11-24 18:54:13 +01:00
await this . santeIncDec ( "vie" , gain ) ;
}
else if ( rolled . isETotal ) {
message . content += " -- perte de vie: 1" ;
await this . santeIncDec ( "vie" , - 1 ) ;
}
2021-01-09 19:33:19 +01:00
else {
message . content += " -- vie stationnaire " ;
2020-11-24 18:54:13 +01:00
}
}
}
2020-12-05 21:24:31 +01:00
/* -------------------------------------------- */
2020-11-24 18:54:13 +01:00
async _jetRecuperationConstitution ( bonusSoins , message = undefined ) {
2022-06-12 09:46:58 +02:00
const tData = this . system ;
2021-03-22 20:10:37 +01:00
let difficulte = Misc . toInt ( bonusSoins ) + Math . min ( 0 , tData . sante . vie . value - tData . sante . vie . max ) ;
let rolled = await RdDResolutionTable . roll ( tData . carac . constitution . value , difficulte ) ;
2020-11-24 18:54:13 +01:00
if ( message ) {
message . content += RdDResolutionTable . explain ( rolled ) . replace ( /Jet :/ , "Constitution :" ) ;
}
return rolled ;
}
2020-12-05 21:24:31 +01:00
/* -------------------------------------------- */
2020-12-01 01:17:18 +01:00
async remiseANeuf ( ) {
2022-07-22 21:38:15 +02:00
if ( this . isEntite ( [ ENTITE _NONINCARNE ] ) ) {
return ;
}
2022-09-19 20:15:01 +02:00
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( this . name ) ,
content : 'Remise à neuf de ' + this . name
} ) ;
const updates = {
'system.sante.endurance.value' : this . system . sante . endurance . max
} ;
if ( ! this . isEntite ( [ ENTITE _INCARNE , ENTITE _BLURETTE ] ) ) {
2022-06-12 09:46:58 +02:00
if ( this . system . blessures ) {
2022-09-19 20:15:01 +02:00
updates [ 'system.blessures.legeres.liste' ] = [ PAS _DE _BLESSURE , PAS _DE _BLESSURE , PAS _DE _BLESSURE , PAS _DE _BLESSURE , PAS _DE _BLESSURE ] ;
updates [ 'system.blessures.graves.liste' ] = [ PAS _DE _BLESSURE , PAS _DE _BLESSURE ] ;
updates [ 'system.blessures.critiques.liste' ] = [ PAS _DE _BLESSURE ] ;
2020-12-01 01:17:18 +01:00
}
2022-09-19 20:15:01 +02:00
updates [ 'system.sante.vie.value' ] = this . system . sante . vie . max ;
updates [ 'system.sante.fatigue.value' ] = 0 ;
2021-01-19 22:32:08 +01:00
if ( this . isPersonnage ( ) ) {
2022-09-19 20:15:01 +02:00
updates [ 'system.compteurs.ethylisme' ] = { value : 1 , nb _doses : 0 , jet _moral : false } ;
2020-12-27 19:55:51 +01:00
}
2020-12-15 02:20:24 +01:00
}
2022-09-19 20:15:01 +02:00
await this . update ( updates ) ;
await this . removeEffects ( e => e . flags . core . statusId !== STATUSES . StatusDemiReve ) ;
2020-12-01 01:17:18 +01:00
}
2020-11-17 16:30:03 +01:00
/* -------------------------------------------- */
2021-06-26 00:55:54 +02:00
async dormir ( heures , options = { grisReve : false } ) {
2021-01-09 19:33:19 +01:00
let message = {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( this . name ) ,
2021-06-26 00:55:54 +02:00
content : ""
2020-11-24 15:43:03 +01:00
} ;
2020-11-20 11:38:27 +01:00
await this . recupereEndurance ( message ) ;
2021-06-26 00:55:54 +02:00
let sep = ""
let recuperationReve = "" ;
let i = 0 ;
for ( ; i < heures ; i ++ ) {
2020-12-19 01:14:02 +01:00
await this . _recupererEthylisme ( message ) ;
2020-11-20 11:38:27 +01:00
await this . recupererFatigue ( message ) ;
2021-06-26 00:55:54 +02:00
if ( ! options . grisReve ) {
let r = await this . recuperationReve ( message ) ;
if ( r >= 0 ) {
recuperationReve += sep + r ;
sep = "+" ;
}
if ( r >= 0 && EffetsDraconiques . isDonDoubleReve ( this ) ) {
r = await this . recuperationReve ( message ) ;
if ( r >= 0 ) {
recuperationReve += sep + r ;
}
}
if ( r < 0 ) {
i ++ ; // rêve de dragon pendant l'heure en cours
break ;
}
2021-02-03 20:39:52 +01:00
}
2020-11-16 04:32:42 +01:00
}
2021-06-26 00:55:54 +02:00
if ( ! options . grisReve ) {
message . content = ` ${ this . name } : Vous dormez ${ i == 0 ? 'une' : i } heure ${ i == 1 ? '' : 's' } . `
+ ( recuperationReve == "" ? "" : ` Vous récupérez ${ recuperationReve } Points de rêve. ` )
+ message . content ;
ChatMessage . create ( message ) ;
}
2021-06-01 20:02:26 +02:00
this . sheet . render ( true ) ;
2021-06-26 00:55:54 +02:00
return i ;
2020-11-16 04:32:42 +01:00
}
2021-01-11 20:42:10 +01:00
/* -------------------------------------------- */
2020-12-19 01:14:02 +01:00
async _recupererEthylisme ( message ) {
2022-06-12 09:46:58 +02:00
let ethylisme = duplicate ( this . system . compteurs . ethylisme ) ;
2020-12-29 01:34:15 +01:00
ethylisme . nb _doses = 0 ;
ethylisme . jet _moral = false ;
2021-01-09 19:33:19 +01:00
if ( ethylisme . value < 1 ) {
2020-12-19 01:14:02 +01:00
ethylisme . value = Math . min ( ethylisme . value + 1 , 1 ) ;
if ( ethylisme . value <= 0 ) {
2021-02-06 23:53:14 +01:00
message . content += ` Vous dégrisez un peu ( ${ RdDUtility . getNomEthylisme ( ethylisme . value ) } ). ` ;
2020-12-19 01:14:02 +01:00
}
}
2022-06-12 19:40:44 +02:00
await this . update ( { "system.compteurs.ethylisme" : ethylisme } ) ;
2020-12-19 01:14:02 +01:00
}
2020-11-17 16:30:03 +01:00
/* -------------------------------------------- */
2020-11-20 11:38:27 +01:00
async recupereEndurance ( message ) {
2022-06-12 09:46:58 +02:00
const manquant = this . _computeEnduranceMax ( ) - this . system . sante . endurance . value ;
2020-11-20 11:38:27 +01:00
if ( manquant > 0 ) {
await this . santeIncDec ( "endurance" , manquant ) ;
2021-02-06 23:53:14 +01:00
message . content += "Vous récuperez " + manquant + " points d'endurance. " ;
2020-11-17 13:08:52 +01:00
}
}
2020-11-17 16:30:03 +01:00
/* -------------------------------------------- */
2020-11-20 11:38:27 +01:00
async recupererFatigue ( message ) {
2021-05-08 20:08:56 +02:00
if ( ReglesOptionelles . isUsing ( "appliquer-fatigue" ) ) {
2022-06-12 09:46:58 +02:00
let fatigue = this . system . sante . fatigue . value ;
2021-05-08 20:08:56 +02:00
const fatigueMin = this . _computeFatigueMin ( ) ;
if ( fatigue <= fatigueMin ) {
return ;
}
fatigue = Math . max ( fatigueMin , this . _calculRecuperationSegment ( fatigue ) ) ;
2022-06-12 19:40:44 +02:00
await this . update ( { "system.sante.fatigue.value" : fatigue } ) ;
2021-05-08 20:08:56 +02:00
if ( fatigue == 0 ) {
message . content += "Vous êtes complêtement reposé. " ;
}
2020-11-20 11:38:27 +01:00
}
}
2020-11-21 08:27:28 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
_calculRecuperationSegment ( actuel ) {
2022-06-12 09:46:58 +02:00
const segments = RdDUtility . getSegmentsFatigue ( this . system . sante . endurance . max ) ;
2020-11-17 13:08:52 +01:00
let cumul = 0 ;
let i ;
2021-01-09 19:33:19 +01:00
for ( i = 0 ; i < 11 ; i ++ ) {
2020-11-17 13:08:52 +01:00
cumul += segments [ i ] ;
2020-11-20 11:38:27 +01:00
let diff = cumul - actuel ;
2021-01-09 19:33:19 +01:00
if ( diff >= 0 ) {
2020-11-17 13:08:52 +01:00
const limit2Segments = Math . floor ( segments [ i ] / 2 ) ;
if ( diff > limit2Segments && i > 0 ) {
2021-01-09 19:33:19 +01:00
cumul -= segments [ i - 1 ] ; // le segment est à moins de la moitié, il est récupéré
2020-11-16 04:32:42 +01:00
}
2020-11-17 13:08:52 +01:00
cumul -= segments [ i ] ;
break ;
}
2020-11-20 11:38:27 +01:00
} ;
return cumul ;
2020-11-17 13:08:52 +01:00
}
2020-11-24 15:45:41 +01:00
2020-11-17 16:30:03 +01:00
/* -------------------------------------------- */
2021-06-26 00:55:54 +02:00
async recuperationReve ( message ) {
2022-06-12 09:46:58 +02:00
const seuil = this . system . reve . seuil . value ;
2020-11-25 00:49:21 +01:00
const reveActuel = this . getReveActuel ( ) ;
2021-06-26 00:55:54 +02:00
if ( reveActuel < seuil ) {
2021-05-11 21:45:43 +02:00
let deRecuperation = await RdDDice . rollTotal ( "1dr" ) ;
2020-11-17 13:08:52 +01:00
console . log ( "recuperationReve" , deRecuperation ) ;
2021-01-09 19:33:19 +01:00
if ( deRecuperation >= 7 ) {
2020-11-17 13:08:52 +01:00
// Rêve de Dragon !
2021-06-26 00:55:54 +02:00
message . content += ` Vous faites un <strong>Rêve de Dragon</strong> de ${ deRecuperation } Points de rêve qui vous réveille! ` ;
2021-02-06 23:53:14 +01:00
await this . combattreReveDeDragon ( deRecuperation ) ;
2021-06-26 00:55:54 +02:00
return - 1 ;
2020-11-16 04:32:42 +01:00
}
2021-01-09 19:33:19 +01:00
else {
2020-11-25 00:49:21 +01:00
await this . reveActuelIncDec ( deRecuperation ) ;
2021-06-26 00:55:54 +02:00
return deRecuperation ;
2020-11-17 13:08:52 +01:00
}
}
2021-06-26 00:55:54 +02:00
return 0 ;
2020-11-16 04:32:42 +01:00
}
2020-12-05 21:24:31 +01:00
/* -------------------------------------------- */
2020-11-24 18:54:13 +01:00
async retourSeuilDeReve ( message ) {
2022-06-12 09:46:58 +02:00
const seuil = this . system . reve . seuil . value ;
2020-11-24 18:54:13 +01:00
const reveActuel = this . getReveActuel ( ) ;
if ( reveActuel > seuil ) {
2021-01-09 19:33:19 +01:00
message . content += ` <br>Votre rêve redescend vers son seuil naturel ( ${ seuil } , nouveau rêve actuel ${ ( reveActuel - 1 ) } ) ` ;
2020-11-24 18:54:13 +01:00
await this . reveActuelIncDec ( - 1 ) ;
}
}
2020-11-16 04:32:42 +01:00
2021-04-06 23:44:57 +02:00
async retourSust ( message ) {
2022-06-12 09:46:58 +02:00
const tplData = this . system ;
2021-04-06 23:44:57 +02:00
const sustNeeded = tplData . attributs . sust . value ;
const sustConsomme = tplData . compteurs . sust . value ;
const eauConsomme = tplData . compteurs . eau . value ;
2021-11-11 02:43:38 +01:00
if ( game . settings . get ( SYSTEM _RDD , "appliquer-famine-soif" ) . includes ( 'famine' ) && sustConsomme < sustNeeded ) {
2021-04-06 23:44:57 +02:00
const perte = sustConsomme < Math . min ( 0.5 , sustNeeded ) ? 3 : ( sustConsomme <= ( sustNeeded / 2 ) ? 2 : 1 ) ;
message . content += ` <br>Vous ne vous êtes sustenté que de ${ sustConsomme } pour un appétit de ${ sustNeeded } , vous avez faim!
La famine devrait vous faire $ { perte } points d 'endurance non récupérables, notez le cumul de côté et ajustez l' endurance ` ;
}
2021-11-11 02:43:38 +01:00
if ( game . settings . get ( SYSTEM _RDD , "appliquer-famine-soif" ) . includes ( 'soif' ) && eauConsomme < sustNeeded ) {
2021-04-06 23:44:57 +02:00
const perte = eauConsomme < Math . min ( 0.5 , sustNeeded ) ? 12 : ( eauConsomme <= ( sustNeeded / 2 ) ? 6 : 3 ) ;
message . content += ` <br>Vous n'avez bu que ${ eauConsomme } doses de liquide pour une soif de ${ sustNeeded } , vous avez soif!
La soif devrait vous faire $ { perte } points d 'endurance non récupérables, notez le cumul de côté et ajustez l' endurance ` ;
}
await this . updateCompteurValue ( 'sust' , 0 ) ;
await this . updateCompteurValue ( 'eau' , 0 ) ;
}
2020-11-17 16:30:03 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
async combattreReveDeDragon ( force ) {
2021-02-06 23:58:15 +01:00
let rollData = {
actor : this ,
2022-07-02 01:41:55 +02:00
competence : duplicate ( this . getDraconicOuPossession ( ) ) ,
2021-02-06 23:58:15 +01:00
canClose : false ,
rencontre : duplicate ( TMRRencontres . getRencontre ( 'rdd' ) ) ,
tmr : true ,
2021-02-11 02:48:27 +01:00
use : { libre : false , conditions : false } ,
2021-02-06 23:58:15 +01:00
forceCarac : { 'reve-actuel' : { label : "Rêve Actuel" , value : this . getReveActuel ( ) } }
}
rollData . rencontre . force = force ;
2022-06-12 12:14:55 +02:00
rollData . competence . system . defaut _carac = 'reve-actuel' ;
2021-02-06 23:58:15 +01:00
const dialog = await RdDRoll . create ( this , rollData ,
2021-02-11 02:48:27 +01:00
{
2021-02-06 23:58:15 +01:00
html : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-reve-de-dragon.html' ,
options : { height : 400 }
} ,
{
name : 'maitrise' ,
label : 'Maîtriser le Rêve de Dragon' ,
callbacks : [
this . createCallbackExperience ( ) ,
2021-06-26 00:55:54 +02:00
{ action : async r => this . resultCombatReveDeDragon ( r ) }
2021-02-06 23:58:15 +01:00
]
}
) ;
dialog . render ( true ) ;
}
2021-04-04 22:34:59 +02:00
/* -------------------------------------------- */
2021-02-06 23:58:15 +01:00
async resultCombatReveDeDragon ( rollData ) {
rollData . queues = [ ] ;
if ( rollData . rolled . isEchec ) {
2022-07-22 22:53:48 +02:00
rollData . queues . push ( await this . ajouterQueue ( ) ) ;
2021-02-06 23:58:15 +01:00
}
if ( rollData . rolled . isETotal ) {
2022-06-12 09:46:58 +02:00
rollData . queues . push ( await this . ajouterQueue ( ) ) ;
2021-02-06 23:58:15 +01:00
}
if ( rollData . rolled . isSuccess ) {
await this . updatePointDeSeuil ( ) ;
await this . reveActuelIncDec ( rollData . rencontre . force ) ;
}
if ( rollData . rolled . isPart ) {
// TODO: un dialogue pour demander le type de tête?
rollData . tete = true ;
}
2021-05-11 21:45:43 +02:00
rollData . poesie = await Poetique . getExtrait ( ) ;
2021-02-06 23:58:15 +01:00
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name ) ,
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html ` , rollData )
} ) ;
2020-11-16 04:32:42 +01:00
}
2020-11-15 11:15:36 +01:00
/* -------------------------------------------- */
2022-09-17 16:07:38 +02:00
async sortMisEnReserve ( sort , draconic , coord , ptreve ) {
await this . createEmbeddedDocuments ( "Item" , [ {
type : 'sortreserve' ,
name : sort . name ,
img : sort . img ,
system : { sortid : sort . id , draconic : ( draconic ? ? sort . system . draconic ) , ptreve : ptreve , coord : coord , heurecible : 'Vaisseau' } } ] ,
{ renderSheet : false } ) ;
2021-02-11 02:48:27 +01:00
this . currentTMR . updateTokens ( ) ;
2020-11-14 03:16:03 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async updateCarac ( caracName , caracValue ) {
2021-01-14 20:51:32 +01:00
if ( caracName == "force" ) {
2021-02-11 02:48:27 +01:00
if ( Number ( caracValue ) > this . getTaille ( ) + 4 ) {
2021-01-14 20:51:32 +01:00
ui . notifications . warn ( "Votre FORCE doit être au maximum de TAILLE+4" ) ;
return ;
}
}
2020-11-18 18:38:21 +01:00
if ( caracName == "reve" ) {
2022-06-12 08:17:59 +02:00
if ( caracValue > Misc . toInt ( this . system . reve . seuil . value ) ) {
2020-11-18 18:38:21 +01:00
this . setPointsDeSeuil ( caracValue ) ;
2020-11-16 04:32:42 +01:00
}
}
2021-01-11 17:54:24 +01:00
if ( caracName == "chance" ) {
2022-06-12 08:17:59 +02:00
if ( caracValue > Misc . toInt ( this . system . compteurs . chance . value ) ) {
2021-01-11 17:54:24 +01:00
this . setPointsDeChance ( caracValue ) ;
}
}
2022-06-12 08:17:59 +02:00
await this . update ( { [ ` system.carac. ${ caracName } .value ` ] : caracValue } ) ;
2020-05-24 20:19:57 +02:00
}
2021-01-03 18:19:18 +01:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async updateCaracXP ( caracName , caracXP ) {
2021-01-23 18:36:30 +01:00
if ( caracName == 'Taille' ) {
return ;
}
2021-01-09 19:33:19 +01:00
this . checkCaracXP ( caracName ) ;
2021-01-03 18:19:18 +01:00
}
2021-05-28 08:28:14 +02:00
/* -------------------------------------------- */
2021-05-28 00:55:22 +02:00
async updateCaracXPAuto ( caracName ) {
if ( caracName == 'Taille' ) {
return ;
}
2022-06-12 09:46:58 +02:00
let carac = RdDActor . _findCaracByName ( this . system . carac , caracName ) ;
2021-05-28 00:55:22 +02:00
if ( carac ) {
carac = duplicate ( carac ) ;
let xp = Number ( carac . xp ) ;
let value = Number ( carac . value ) ;
while ( xp >= RdDCarac . getCaracNextXp ( value ) && xp > 0 ) {
xp -= RdDCarac . getCaracNextXp ( value ) ;
value ++ ;
}
carac . xp = xp ;
carac . value = value ;
2022-06-12 19:40:44 +02:00
await this . update ( { [ ` system.carac. ${ caracName } ` ] : carac } ) ;
2021-05-28 08:28:14 +02:00
this . updateExperienceLog ( "Carac +" , xp , caracName + " passée à " + value ) ;
2021-05-28 00:55:22 +02:00
}
}
2021-05-28 08:28:14 +02:00
/* -------------------------------------------- */
2021-11-23 02:04:00 +01:00
async updateCompetenceXPAuto ( idOrName ) {
let competence = this . getCompetence ( idOrName ) ;
2021-05-28 00:55:22 +02:00
if ( competence ) {
2022-06-12 09:46:58 +02:00
let xp = Number ( competence . system . xp ) ;
let niveau = Number ( competence . system . niveau ) ;
2021-05-28 00:55:22 +02:00
while ( xp >= RdDItemCompetence . getCompetenceNextXp ( niveau ) && xp > 0 ) {
xp -= RdDItemCompetence . getCompetenceNextXp ( niveau ) ;
niveau ++ ;
}
2021-11-23 02:04:00 +01:00
await competence . update ( {
2022-06-12 19:40:44 +02:00
"system.xp" : xp ,
"system.niveau" : niveau ,
2021-05-28 00:55:22 +02:00
} ) ;
2021-11-23 02:04:00 +01:00
this . updateExperienceLog ( "Compétence +" , xp , competence . name + " passée à " + niveau ) ;
2021-05-28 00:55:22 +02:00
}
}
2021-01-03 18:19:18 +01:00
2021-11-23 02:11:24 +01:00
async updateCompetenceStress ( idOrName ) {
const competence = this . getCompetence ( idOrName ) ;
if ( ! competence ) {
return ;
}
2022-09-16 02:20:00 +02:00
const stress = this . system . compteurs . experience . value ;
2022-06-12 09:46:58 +02:00
const niveau = Number ( competence . system . niveau ) ;
2022-09-16 02:20:00 +02:00
const xpSuivant = RdDItemCompetence . getCompetenceNextXp ( niveau ) ;
const xpRequis = xpSuivant - competence . system . xp ;
if ( stress <= 0 || niveau >= competence . system . niveau _archetype ) {
2021-11-23 02:11:24 +01:00
ui . notifications . info ( ` La compétence ne peut pas augmenter!
2022-09-16 02:20:00 +02:00
stress disponible : $ { stress }
2021-11-23 02:11:24 +01:00
expérience requise : $ { xpRequis }
niveau : $ { niveau }
2022-06-12 09:46:58 +02:00
archétype : $ { competence . system . niveau _archetype } ` );
2021-11-23 02:11:24 +01:00
return ;
}
2022-09-16 02:20:00 +02:00
const xpUtilise = Math . max ( 0 , Math . min ( stress , xpRequis ) ) ;
const gainNiveau = ( xpUtilise >= xpRequis || xpRequis <= 0 ) ? 1 : 0 ;
2021-11-23 02:11:24 +01:00
const nouveauNiveau = niveau + gainNiveau ;
2022-09-16 02:20:00 +02:00
const nouveauXp = gainNiveau > 0 ? Math . max ( competence . system . xp - xpSuivant , 0 ) : ( competence . system . xp + xpUtilise ) ;
2021-11-23 02:11:24 +01:00
await competence . update ( {
2022-06-12 09:46:58 +02:00
"system.xp" : nouveauXp ,
"system.niveau" : nouveauNiveau ,
2021-11-23 02:11:24 +01:00
} ) ;
2022-09-16 02:20:00 +02:00
const stressTransformeRestant = Math . max ( 0 , stress - xpUtilise ) ;
2022-06-12 09:46:58 +02:00
await this . update ( { "system.compteurs.experience.value" : stressTransformeRestant } ) ;
2021-12-05 01:50:09 +01:00
this . updateExperienceLog ( 'Dépense stress' , xpUtilise , ` Stress en ${ competence . name } ${ gainNiveau ? "pour passer à " + nouveauNiveau : "" } ` ) ;
2021-11-23 02:11:24 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-11-23 02:04:00 +01:00
async updateCreatureCompetence ( idOrName , fieldName , compValue ) {
let competence = this . getCompetence ( idOrName ) ;
if ( competence ) {
const update = { _id : competence . id }
2020-09-20 17:38:21 +02:00
if ( fieldName == "niveau" )
2022-06-12 19:40:44 +02:00
update [ 'system.niveau' ] = compValue ;
2020-09-20 17:38:21 +02:00
else if ( fieldName == "dommages" )
2022-06-12 19:40:44 +02:00
update [ 'system.dommages' ] = compValue ;
2021-01-09 19:33:19 +01:00
else
2022-06-12 19:40:44 +02:00
update [ 'system.carac_value' ] = compValue ;
2021-11-23 02:04:00 +01:00
await this . updateEmbeddedDocuments ( 'Item' , [ update ] ) ; // updates one EmbeddedEntity
2020-09-20 17:38:21 +02:00
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-11-23 02:04:00 +01:00
async updateCompetence ( idOrName , compValue ) {
let competence = this . getCompetence ( idOrName ) ;
if ( competence ) {
2022-06-12 09:46:58 +02:00
let nouveauNiveau = compValue ? ? RdDItemCompetence . getNiveauBase ( competence . system . categorie ) ;
2022-03-22 23:36:46 +01:00
const tronc = RdDItemCompetence . getListTronc ( competence . name ) . filter ( it => {
const comp = this . getCompetence ( it ) ;
2022-07-22 22:53:48 +02:00
const niveauTr = competence ? competence . system . niveau : 0 ;
2022-03-22 23:36:46 +01:00
return niveauTr < 0 && niveauTr < nouveauNiveau ;
} ) ;
if ( tronc . length > 0 ) {
2020-09-05 22:56:33 +02:00
let message = "Vous avez modifié une compétence 'tronc'. Vérifiez que les compétences suivantes évoluent ensemble jusqu'au niveau 0 : " ;
2022-03-22 23:36:46 +01:00
for ( let troncName of tronc ) {
2020-09-05 22:56:33 +02:00
message += "<br>" + troncName ;
2020-08-13 22:28:56 +02:00
}
2021-01-09 19:33:19 +01:00
ChatMessage . create ( {
whisper : ChatMessage . getWhisperRecipients ( game . user . name ) ,
content : message
} ) ;
2020-08-13 22:28:56 +02:00
}
2022-06-12 19:40:44 +02:00
const update = { _id : competence . id , 'system.niveau' : nouveauNiveau } ;
2021-03-29 23:41:08 +02:00
await this . updateEmbeddedDocuments ( 'Item' , [ update ] ) ; // Updates one EmbeddedEntity
2020-06-12 22:46:04 +02:00
} else {
2021-11-23 02:04:00 +01:00
console . log ( "Competence not found" , idOrName ) ;
2020-06-12 22:46:04 +02:00
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-11-23 02:04:00 +01:00
async updateCompetenceXP ( idOrName , newXp ) {
let competence = this . getCompetence ( idOrName ) ;
if ( competence ) {
2021-06-26 00:55:54 +02:00
if ( isNaN ( newXp ) || typeof ( newXp ) != 'number' ) newXp = 0 ;
2021-11-23 02:04:00 +01:00
this . checkCompetenceXP ( idOrName , newXp ) ;
2022-09-07 09:01:23 +02:00
const update = { _id : competence . id , 'system.xp' : newXp } ;
2021-03-29 23:41:08 +02:00
await this . updateEmbeddedDocuments ( 'Item' , [ update ] ) ; // Updates one EmbeddedEntity
2021-11-23 02:04:00 +01:00
this . updateExperienceLog ( "XP" , newXp , "XP modifié en " + competence . name ) ;
2020-06-01 23:50:10 +02:00
} else {
2021-11-23 02:04:00 +01:00
console . log ( "Competence not found" , idOrName ) ;
2020-06-01 23:50:10 +02:00
}
2021-11-23 02:04:00 +01:00
RdDUtility . checkThanatosXP ( idOrName ) ;
2020-06-01 23:50:10 +02:00
}
2021-01-03 19:19:02 +01:00
2021-02-11 02:48:27 +01:00
/* -------------------------------------------- */
2021-11-23 02:04:00 +01:00
async updateCompetenceXPSort ( idOrName , compValue ) {
let competence = this . getCompetence ( idOrName ) ;
if ( competence ) {
2021-06-26 00:55:54 +02:00
if ( isNaN ( compValue ) || typeof ( compValue ) != 'number' ) compValue = 0 ;
2022-06-12 19:40:44 +02:00
const update = { _id : competence . id , 'system.xp_sort' : compValue } ;
2021-03-29 23:41:08 +02:00
await this . updateEmbeddedDocuments ( 'Item' , [ update ] ) ; // Updates one EmbeddedEntity
2021-11-23 02:04:00 +01:00
this . updateExperienceLog ( "XP Sort" , compValue , "XP modifié en sort de " + competence . name ) ;
2021-02-11 02:48:27 +01:00
} else {
2021-11-23 02:04:00 +01:00
console . log ( "Competence not found" , idOrName ) ;
2021-02-03 23:27:55 +01:00
}
2021-02-11 02:48:27 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-11-23 02:04:00 +01:00
async updateCompetenceArchetype ( idOrName , compValue ) {
let competence = this . getCompetence ( idOrName ) ;
if ( competence ) {
2021-03-15 00:07:53 +01:00
compValue = compValue ? ? 0 ;
2022-06-12 19:40:44 +02:00
const update = { _id : competence . id , 'system.niveau_archetype' : compValue } ;
2021-03-29 23:41:08 +02:00
await this . updateEmbeddedDocuments ( 'Item' , [ update ] ) ; // Updates one EmbeddedEntity
2021-01-03 19:19:02 +01:00
} else {
2021-11-23 02:04:00 +01:00
console . log ( "Competence not found" , idOrName ) ;
2021-01-03 19:19:02 +01:00
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-05-27 19:40:45 +02:00
async updateExperienceLog ( modeXP , valeurXP , raisonXP = 'Inconnue' ) {
2021-05-19 23:22:07 +02:00
let d = new Date ( ) ;
2022-06-12 09:46:58 +02:00
let expLog = duplicate ( this . system . experiencelog ) ;
2021-05-27 19:40:45 +02:00
expLog . push ( {
mode : Misc . upperFirst ( modeXP ) , valeur : valeurXP , raison : Misc . upperFirst ( raisonXP ) ,
2022-09-28 01:24:20 +02:00
daterdd : game . system . rdd . calendrier . getDateFromIndex ( ) ,
datereel : ` ${ d . getDate ( ) } / ${ d . getMonth ( ) + 1 } / ${ d . getFullYear ( ) } `
2021-05-27 19:40:45 +02:00
} ) ;
2022-06-12 19:40:44 +02:00
await this . update ( { [ ` system.experiencelog ` ] : expLog } ) ;
2021-05-19 23:22:07 +02:00
}
2022-09-28 01:24:20 +02:00
async deleteExperienceLog ( from , count ) {
if ( from >= 0 && count > 0 ) {
let expLog = duplicate ( this . system . experiencelog ) ;
expLog . splice ( from , count ) ;
await this . update ( { [ ` system.experiencelog ` ] : expLog } ) ;
}
}
2021-05-19 23:22:07 +02:00
/* -------------------------------------------- */
async updateCompteurValue ( fieldName , fieldValue , raison = 'Inconnue' ) {
2022-06-12 19:40:44 +02:00
await this . update ( { [ ` system.compteurs. ${ fieldName } .value ` ] : fieldValue } ) ;
2021-12-05 01:50:09 +01:00
await this . addStressExperienceLog ( fieldName , fieldValue , 'forcé: ' + raison ) ;
2020-08-29 22:52:41 +02:00
}
2021-05-19 22:44:14 +02:00
/* -------------------------------------------- */
2021-05-19 23:22:07 +02:00
async addCompteurValue ( fieldName , fieldValue , raison = 'Inconnue' ) {
2022-06-12 09:46:58 +02:00
let oldValue = this . system . compteurs [ fieldName ] . value ;
2022-06-12 19:40:44 +02:00
await this . update ( { [ ` system.compteurs. ${ fieldName } .value ` ] : Number ( oldValue ) + Number ( fieldValue ) } ) ;
2021-10-08 23:28:55 +02:00
await this . addStressExperienceLog ( fieldName , fieldValue , raison ) ;
}
async addStressExperienceLog ( fieldName , fieldValue , raison ) {
switch ( fieldName ) {
case 'stress' : case 'experience' :
await this . updateExperienceLog ( fieldName , fieldValue , raison ) ;
}
}
/* -------------------------------------------- */
distribuerStress ( compteur , stress , motif ) {
if ( game . user . isGM && this . hasPlayerOwner && this . isPersonnage ( ) ) {
switch ( compteur ) {
2021-12-05 01:50:09 +01:00
case 'stress' : case 'experience' :
const message = ` ${ this . name } a reçu ${ stress } points ${ compteur == 'stress' ? "de stress" : "d'expérience" } (raison : ${ motif } ) ` ;
this . addCompteurValue ( compteur , stress , motif ) ;
ui . notifications . info ( message ) ;
game . users . players . filter ( player => player . active && player . character ? . id == this . id )
2021-10-08 23:28:55 +02:00
. forEach ( player => ChatUtility . notifyUser ( player . id , 'info' , message ) ) ;
}
2021-05-19 23:22:07 +02:00
}
2021-05-19 22:44:14 +02:00
}
2021-05-27 19:40:45 +02:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-03-22 20:10:37 +01:00
async updateAttributeValue ( fieldName , fieldValue ) {
2022-06-12 19:40:44 +02:00
await this . update ( { [ ` system.attributs. ${ fieldName } .value ` ] : fieldValue } ) ;
2020-12-18 01:10:03 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-04-14 21:51:29 +02:00
_isConteneurContenu ( item , conteneur ) {
if ( item ? . isConteneur ( ) ) { // Si c'est un conteneur, il faut vérifier qu'on ne le déplace pas vers un sous-conteneur lui appartenant
2022-09-23 00:45:42 +02:00
for ( let id of item . system . contenu ) {
2021-03-29 09:17:00 +02:00
let subObjet = this . getObjet ( id ) ;
2021-04-14 21:51:29 +02:00
if ( subObjet ? . id == conteneur . id ) {
2021-03-29 09:17:00 +02:00
return true ; // Loop detected !
2021-01-08 09:58:15 +01:00
}
2021-04-14 21:51:29 +02:00
if ( subObjet ? . isConteneur ( ) ) {
return this . _isConteneurContenu ( subObjet , conteneur ) ;
2021-01-08 09:58:15 +01:00
}
}
}
2021-03-29 09:17:00 +02:00
return false ;
2021-01-08 09:58:15 +01:00
}
2021-01-29 20:42:40 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
getRecursiveEnc ( objet ) {
2021-03-29 09:17:00 +02:00
if ( ! objet ) {
return 0 ;
}
2022-06-12 09:46:58 +02:00
const tplData = objet . system ;
2021-03-29 09:17:00 +02:00
if ( objet . type != 'conteneur' ) {
return Number ( tplData . encombrement ) * Number ( tplData . quantite ) ;
}
const encContenus = tplData . contenu . map ( idContenu => this . getRecursiveEnc ( this . getObjet ( idContenu ) ) ) ;
2021-03-29 18:08:18 +02:00
return encContenus . reduce ( Misc . sum ( ) , 0 )
2021-03-29 09:17:00 +02:00
+ Number ( tplData . encombrement ) /* TODO? Number(tplData.quantite) -- on pourrait avoir plusieurs conteneurs...*/
}
2021-01-10 02:28:45 +01:00
/* -------------------------------------------- */
buildSubConteneurObjetList ( conteneurId , deleteList ) {
2021-03-29 09:17:00 +02:00
let conteneur = this . getObjet ( conteneurId ) ;
if ( conteneur ? . type == 'conteneur' ) { // Si c'est un conteneur
2022-09-23 00:45:42 +02:00
for ( let subId of conteneur . system . contenu ) {
2021-03-29 09:17:00 +02:00
let subObj = this . getObjet ( subId ) ;
if ( subObj ) {
if ( subObj . type == 'conteneur' ) {
this . buildSubConteneurObjetList ( subId , deleteList ) ;
}
2021-02-11 02:48:27 +01:00
deleteList . push ( { id : subId , conteneurId : conteneurId } ) ;
2021-03-29 09:17:00 +02:00
}
2021-01-08 18:58:37 +01:00
}
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2022-09-17 16:07:38 +02:00
async deleteAllConteneur ( itemId , options ) {
2021-01-08 18:58:37 +01:00
let list = [ ] ;
2021-02-11 02:48:27 +01:00
list . push ( { id : itemId , conteneurId : undefined } ) ; // Init list
2021-01-09 19:33:19 +01:00
this . buildSubConteneurObjetList ( itemId , list ) ;
2022-09-17 16:07:38 +02:00
await this . deleteEmbeddedDocuments ( 'Item' , list . map ( it => it . id ) , options ) ;
2021-01-08 18:58:37 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-04-28 23:25:48 +02:00
/ * * S u p p r i m e u n i t e m d ' u n c o n t e n e u r , s u r l a b a s e
2020-11-12 14:43:08 +01:00
* de leurs ID * /
2021-12-05 01:50:09 +01:00
async enleverDeConteneur ( item , conteneur , onEnleverDeConteneur ) {
2021-05-07 01:47:51 +02:00
if ( conteneur ? . isConteneur ( ) ) {
2022-09-25 17:51:57 +02:00
item . estContenu = false ;
await this . updateEmbeddedDocuments ( 'Item' , [ {
_id : conteneur . id ,
'system.contenu' : conteneur . system . contenu . filter ( id => id != item . id )
} ] ) ;
2021-12-05 01:50:09 +01:00
onEnleverDeConteneur ( ) ;
2020-11-12 14:43:08 +01:00
}
}
2022-09-25 17:51:57 +02:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-04-28 23:25:48 +02:00
/ * * A j o u t e u n i t e m d a n s u n c o n t e n e u r , s u r l a b a s e
2020-11-12 14:43:08 +01:00
* de leurs ID * /
2021-12-05 01:50:09 +01:00
async ajouterDansConteneur ( item , conteneur , onAjouterDansConteneur ) {
2022-09-25 17:51:57 +02:00
if ( ! conteneur ) {
// TODO: afficher
item . estContenu = false ;
}
else if ( conteneur . isConteneur ( ) ) {
item . estContenu = true ;
await this . updateEmbeddedDocuments ( 'Item' , [ {
_id : conteneur . id ,
'system.contenu' : [ ... conteneur . system . contenu , item . id ]
} ] ) ;
2021-12-05 16:48:18 +01:00
onAjouterDansConteneur ( item . id , conteneur . id ) ;
2020-11-12 14:43:08 +01:00
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-01-08 11:56:10 +01:00
/** Fonction de remise à plat de l'équipement (ie vide les champs 'contenu') */
2021-01-09 19:33:19 +01:00
async nettoyerConteneurs ( ) {
2022-10-04 23:23:43 +02:00
RdDConfirm . confirmer ( {
settingConfirmer : "confirmation-vider" ,
2022-10-04 01:53:18 +02:00
content : ` <p>Etes vous certain de vouloir vider tous les conteneurs ?</p> ` ,
title : 'Vider les conteneurs' ,
buttonLabel : 'Vider' ,
onAction : async ( ) => {
const corrections = [ ] ;
for ( let item of this . items ) {
if ( item . estContenu ) {
item . estContenu = undefined ;
}
if ( item . type == 'conteneur' && item . system . contenu . length > 0 ) {
corrections . push ( { _id : item . id , 'system.contenu' : [ ] } ) ;
}
}
if ( corrections . length > 0 ) {
await this . updateEmbeddedDocuments ( 'Item' , corrections ) ;
}
2021-05-25 23:41:53 +02:00
}
2022-10-04 01:53:18 +02:00
} ) ;
2021-01-08 11:56:10 +01:00
}
2021-12-05 16:48:18 +01:00
async processDropItem ( params ) {
2021-12-05 01:50:09 +01:00
const targetActorId = this . id ;
const sourceActorId = params . sourceActorId ;
const itemId = params . itemId ;
const destId = params . destId ;
const srcId = params . srcId ;
if ( sourceActorId && sourceActorId != targetActorId ) {
console . log ( "Moving objects" , sourceActorId , targetActorId , itemId ) ;
this . moveItemsBetweenActors ( itemId , sourceActorId ) ;
2021-05-07 01:47:51 +02:00
return false ;
}
let result = true ;
const item = this . getObjet ( itemId ) ;
2021-12-05 01:50:09 +01:00
if ( item ? . isEquipement ( ) && sourceActorId == targetActorId ) {
2021-05-25 23:41:53 +02:00
// rangement
if ( srcId != destId && itemId != destId ) { // déplacement de l'objet
const src = this . getObjet ( srcId ) ;
2022-09-25 17:51:57 +02:00
const dest = this . getObjet ( destId ) ;
const cible = this . getContenantOrParent ( dest ) ;
const messageEquipementDifferent = item . messageEquipementDifferent ( dest ) ;
if ( dest && ! messageEquipementDifferent ) {
await this . regrouperEquipementsSimilaires ( item , dest ) ;
result = false ;
}
2021-05-25 23:41:53 +02:00
// changer de conteneur
2022-09-25 17:51:57 +02:00
else if ( ! cible || this . conteneurPeutContenir ( cible , item ) ) {
2021-12-05 01:50:09 +01:00
await this . enleverDeConteneur ( item , src , params . onEnleverConteneur ) ;
2022-09-25 17:51:57 +02:00
await this . ajouterDansConteneur ( item , cible , params . onAjouterDansConteneur ) ;
2021-05-25 23:41:53 +02:00
}
2022-09-25 17:51:57 +02:00
else {
ui . notifications . info ( messageEquipementDifferent ) ;
2021-04-13 21:30:02 +02:00
}
}
2021-04-13 22:42:39 +02:00
}
2021-05-07 17:27:02 +02:00
await this . computeEncombrementTotalEtMalusArmure ( ) ;
2021-05-07 01:47:51 +02:00
return result ;
2021-04-13 22:42:39 +02:00
}
2021-05-25 23:41:53 +02:00
2022-09-25 17:51:57 +02:00
getContenantOrParent ( dest ) {
if ( ! dest || dest . isConteneur ( ) ) {
return dest ;
}
return this . getContenant ( dest ) ;
}
getContenant ( item ) {
return this . itemTypes [ 'conteneur' ] . find ( it => it . system . contenu . includes ( item . id ) ) ;
}
2021-05-07 01:47:51 +02:00
/* -------------------------------------------- */
2021-04-13 22:42:39 +02:00
conteneurPeutContenir ( dest , item ) {
2021-05-25 23:41:53 +02:00
if ( ! dest ) {
return true ;
}
if ( ! dest . isConteneur ( ) ) {
return false ;
}
2022-06-12 09:46:58 +02:00
const destData = dest
2021-04-14 21:51:29 +02:00
if ( this . _isConteneurContenu ( item , dest ) ) {
2021-04-13 22:42:39 +02:00
ui . notifications . warn ( ` Impossible de déplacer un conteneur parent ( ${ item . name } ) dans un de ses contenus ${ destData . name } ! ` ) ;
return false ; // Loop detected !
}
// Calculer le total actuel des contenus
2022-06-12 09:46:58 +02:00
let encContenu = this . getRecursiveEnc ( dest ) - Number ( destData . system . encombrement ) ;
2021-04-13 22:42:39 +02:00
let newEnc = this . getRecursiveEnc ( item ) ; // Calculer le total actuel du nouvel objet
// Teste si le conteneur de destination a suffisament de capacité pour recevoir le nouvel objet
2022-06-12 09:46:58 +02:00
if ( Number ( destData . system . capacite ) < encContenu + newEnc ) {
2021-04-13 22:42:39 +02:00
ui . notifications . warn (
2022-06-12 09:46:58 +02:00
` Le conteneur ${ dest . name } a une capacité de ${ destData . system . capacite } , et contient déjà ${ encContenu } .
2021-04-13 22:42:39 +02:00
Impossible d 'y ranger: ${item.name} d' encombrement $ { newEnc } ! ` );
return false ;
2021-04-13 21:30:02 +02:00
}
return true ;
2021-04-13 22:42:39 +02:00
2021-04-13 21:30:02 +02:00
}
2021-01-10 02:28:45 +01:00
/* -------------------------------------------- */
async moveItemsBetweenActors ( itemId , sourceActorId ) {
2021-01-09 09:54:08 +01:00
let itemsList = [ ]
2021-02-11 02:48:27 +01:00
let sourceActor = game . actors . get ( sourceActorId ) ;
itemsList . push ( { id : itemId , conteneurId : undefined } ) ; // Init list
sourceActor . buildSubConteneurObjetList ( itemId , itemsList ) ; // Get itemId list
2021-01-10 11:35:11 +01:00
2021-06-09 22:23:11 +02:00
const itemsDataToCreate = itemsList . map ( it => sourceActor . getObjet ( it . id ) )
2022-06-12 09:46:58 +02:00
. map ( it => duplicate ( it ) )
. map ( it => { it . system . contenu = [ ] ; return it ; } ) ;
2021-06-09 22:23:11 +02:00
let newItems = await this . createEmbeddedDocuments ( 'Item' , itemsDataToCreate ) ;
2022-04-23 00:26:56 +02:00
let itemMap = this . _buildMapOldNewId ( itemsList , newItems ) ;
2021-06-09 22:23:11 +02:00
2021-01-22 10:05:30 +01:00
for ( let item of itemsList ) { // Second boucle pour traiter la remise en conteneurs
2021-01-10 11:35:11 +01:00
// gestion conteneur/contenu
2021-02-11 02:48:27 +01:00
if ( item . conteneurId ) { // l'Objet était dans un conteneur
2021-01-22 10:05:30 +01:00
let newConteneurId = itemMap [ item . conteneurId ] ; // Get conteneur
2021-04-01 00:01:10 +02:00
let newConteneur = this . getObjet ( newConteneurId ) ;
2021-02-11 02:48:27 +01:00
2021-01-22 10:05:30 +01:00
let newItemId = itemMap [ item . id ] ; // Get newItem
2021-02-11 02:48:27 +01:00
console . log ( 'New conteneur filling!' , newConteneur , newItemId , item ) ;
2022-09-24 01:05:32 +02:00
let contenu = duplicate ( newConteneur . system . contenu ) ;
2021-02-11 02:48:27 +01:00
contenu . push ( newItemId ) ;
2022-06-12 19:40:44 +02:00
await this . updateEmbeddedDocuments ( 'Item' , [ { _id : newConteneurId , 'system.contenu' : contenu } ] ) ;
2021-01-10 11:35:11 +01:00
}
2021-01-09 09:54:08 +01:00
}
2021-02-11 02:48:27 +01:00
for ( let item of itemsList ) {
2021-03-29 23:41:08 +02:00
await sourceActor . deleteEmbeddedDocuments ( 'Item' , [ item . id ] ) ;
2021-01-09 09:54:08 +01:00
}
}
2022-04-23 00:26:56 +02:00
_buildMapOldNewId ( itemsList , newItems ) {
let itemMap = { } ;
for ( let i = 0 ; i < itemsList . length ; i ++ ) {
itemMap [ itemsList [ i ] . id ] = newItems [ i ] . id ; // Pour garder le lien ancien / nouveau
}
return itemMap ;
}
2021-04-13 22:42:39 +02:00
async regrouperEquipementsSimilaires ( item , dest ) {
2022-06-12 09:46:58 +02:00
await dest . quantiteIncDec ( item . system . quantite ) ;
2021-05-08 03:52:19 +02:00
await item . delete ( ) ;
2021-04-13 22:42:39 +02:00
}
2021-01-10 02:28:45 +01:00
/* -------------------------------------------- */
2021-11-04 23:33:52 +01:00
computeMalusSurEncombrement ( ) {
2022-01-07 23:12:30 +01:00
switch ( this . type ) {
case 'entite' : case 'vehicule' :
return 0 ;
}
2021-11-04 23:33:52 +01:00
return Math . min ( 0 , this . getEncombrementMax ( ) - Math . ceil ( Number ( this . getEncTotal ( ) ) ) ) ;
2021-04-01 21:31:13 +02:00
}
2022-07-22 22:53:48 +02:00
getMessageSurEncombrement ( ) {
return this . computeMalusSurEncombrement ( ) < 0 ? "Sur-Encombrement!" : "" ;
2021-12-05 21:18:00 +01:00
}
2021-04-06 23:36:35 +02:00
2022-06-12 08:17:59 +02:00
/* -------------------------------------------- */
2021-04-01 21:31:13 +02:00
getEncombrementMax ( ) {
2022-07-22 22:53:48 +02:00
switch ( this . type ) {
case 'vehicule' :
2022-04-30 19:15:55 +02:00
return this . system . capacite _encombrement ;
2022-01-07 23:12:30 +01:00
case 'entite' :
2022-07-22 22:53:48 +02:00
return 0 ;
2022-01-07 23:12:30 +01:00
default :
2022-06-12 08:17:59 +02:00
return this . system . attributs . encombrement . value
2022-01-07 23:12:30 +01:00
}
2021-04-01 21:31:13 +02:00
}
2021-04-01 21:33:43 +02:00
/* -------------------------------------------- */
2021-04-20 00:52:06 +02:00
computeIsHautRevant ( ) {
2021-05-11 21:45:43 +02:00
if ( this . isPersonnage ( ) ) {
2022-04-30 19:15:55 +02:00
this . system . attributs . hautrevant . value = this . hasItemNamed ( 'tete' , 'don de haut-reve' )
2021-05-11 00:52:25 +02:00
? "Haut rêvant"
: "" ;
}
}
hasItemNamed ( type , name ) {
name = Grammar . toLowerCaseNoAccent ( name ) ;
return this . listItemsData ( type ) . find ( it => Grammar . toLowerCaseNoAccent ( it . name ) == name ) ;
2020-11-11 14:42:11 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async computeEncombrementTotalEtMalusArmure ( ) {
2022-07-22 22:53:48 +02:00
if ( ! this . pack ) {
2021-12-18 10:06:24 +01:00
await this . computeMalusArmure ( ) ;
return this . computeEncombrement ( ) ;
}
return 0 ;
2021-04-01 21:31:13 +02:00
}
2021-03-20 00:09:29 +01:00
2021-04-01 21:31:13 +02:00
/* -------------------------------------------- */
computeEncombrement ( ) {
2021-05-27 22:40:12 +02:00
this . encTotal = this . items . map ( it => it . getEncTotal ( ) ) . reduce ( Misc . sum ( ) , 0 ) ;
2021-04-20 00:49:01 +02:00
return this . encTotal ;
2021-04-01 21:31:13 +02:00
}
2021-03-20 00:09:29 +01:00
2021-04-01 21:31:13 +02:00
/* -------------------------------------------- */
async computeMalusArmure ( ) {
2022-09-07 18:47:56 +02:00
const newMalusArmure = this . filterItems ( it => it . type == 'armure' && it . system . equipe )
2022-04-30 19:15:55 +02:00
. map ( it => it . system . malus ? ? 0 )
2022-06-12 08:17:59 +02:00
. reduce ( Misc . sum ( ) , 0 ) ;
2020-12-02 14:00:54 +01:00
// Mise à jour éventuelle du malus armure
2022-04-30 19:15:55 +02:00
if ( this . system . attributs ? . malusarmure ? . value != newMalusArmure ) {
2022-06-12 08:17:59 +02:00
await this . updateAttributeValue ( "malusarmure" , newMalusArmure ) ;
2020-12-02 14:00:54 +01:00
}
2022-06-12 08:17:59 +02:00
return newMalusArmure ;
2020-11-11 11:43:13 +01:00
}
2021-02-11 02:48:27 +01:00
2021-01-29 23:17:18 +01:00
/* -------------------------------------------- */
2021-04-01 21:31:13 +02:00
computePrixTotalEquipement ( ) {
2022-10-04 01:58:49 +02:00
const deniers = this . items . filter ( it => it . isEquipement ( ) )
. map ( it => it . prixTotalDeniers ( ) )
2021-04-06 23:36:35 +02:00
. reduce ( Misc . sum ( ) , 0 ) ;
2022-10-04 01:58:49 +02:00
return deniers / 100 ;
2021-01-29 23:17:18 +01:00
}
2020-11-11 11:43:13 +01:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-03-22 20:10:37 +01:00
computeResumeBlessure ( blessures = undefined ) {
2022-06-12 09:46:58 +02:00
blessures = blessures ? ? this . system . blessures ;
2022-09-07 18:47:56 +02:00
if ( ! blessures ) {
return "Pas de blessures possibles" ;
}
2021-01-09 19:33:19 +01:00
let nbLegeres = this . countBlessures ( blessures . legeres . liste ) ;
let nbGraves = this . countBlessures ( blessures . graves . liste ) ;
let nbCritiques = this . countBlessures ( blessures . critiques . liste ) ;
2020-12-05 02:22:37 +01:00
let resume = "Blessures:" ;
if ( nbCritiques > 0 || nbGraves > 0 || nbLegeres > 0 ) {
if ( nbLegeres > 0 ) {
2021-03-20 00:09:29 +01:00
resume += " " + nbLegeres + " légère" + ( nbLegeres > 1 ? "s" : "" ) ;
2020-12-05 02:22:37 +01:00
}
if ( nbGraves > 0 ) {
if ( nbLegeres > 0 )
resume += "," ;
2021-03-20 00:09:29 +01:00
resume += " " + nbGraves + " grave" + ( nbGraves > 1 ? "s" : "" ) ;
2020-12-05 02:22:37 +01:00
}
if ( nbCritiques > 0 ) {
if ( nbGraves > 0 || nbLegeres > 0 )
resume += "," ;
resume += " une CRITIQUE !" ;
}
2022-09-07 18:47:56 +02:00
return resume ;
2020-12-05 02:22:37 +01:00
}
else {
2022-09-07 18:47:56 +02:00
return "Aucune blessure" ;
2020-12-05 02:22:37 +01:00
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
computeEtatGeneral ( ) {
2020-11-15 11:15:36 +01:00
// Pas d'état général pour les entités forçage à 0
2022-06-12 08:17:59 +02:00
if ( this . type == 'entite' ) {
2022-06-12 19:40:44 +02:00
this . system . compteurs . etat . value = 0 ;
2022-06-12 08:17:59 +02:00
return
2020-11-15 11:15:36 +01:00
}
// Pour les autres
2022-06-12 08:17:59 +02:00
let sante = this . system . sante
let compteurs = this . system . compteurs
let state = Math . min ( sante . vie . value - sante . vie . max , 0 ) ;
if ( ReglesOptionelles . isUsing ( "appliquer-fatigue" ) && sante . fatigue ) {
state += RdDUtility . currentFatigueMalus ( sante . fatigue . value , sante . endurance . max ) ;
2021-01-09 19:33:19 +01:00
}
2021-01-04 14:10:21 +01:00
// Ajout de l'éthylisme
2022-06-12 08:17:59 +02:00
state += Math . min ( 0 , ( compteurs . ethylisme ? . value ? ? 0 ) ) ;
2021-01-04 14:10:21 +01:00
2022-06-12 08:17:59 +02:00
compteurs . etat . value = state ;
if ( compteurs ? . surenc ) {
compteurs . surenc . value = this . computeMalusSurEncombrement ( ) ;
2020-12-08 21:40:41 +01:00
}
2020-05-29 00:43:16 +02:00
}
2021-02-11 02:48:27 +01:00
2022-09-16 23:27:26 +02:00
/* -------------------------------------------- */
async actionRefoulement ( item ) {
const refoulement = item ? . system . refoulement ? ? 0 ;
if ( refoulement > 0 ) {
await this . ajouterRefoulement ( refoulement ) ;
await item . delete ( ) ;
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async ajouterRefoulement ( value = 1 ) {
2022-06-12 09:46:58 +02:00
let refoulement = this . system . reve . refoulement . value + value ;
2022-06-12 08:17:59 +02:00
let total = await RdDDice . rollTotal ( "1d20" ) ;
2021-03-20 00:09:29 +01:00
if ( total <= refoulement ) {
refoulement = 0 ;
await this . ajouterSouffle ( { chat : true } ) ;
2020-07-17 22:04:35 +02:00
}
2022-06-12 19:40:44 +02:00
await this . update ( { "system.reve.refoulement.value" : refoulement } ) ;
2021-03-20 00:09:29 +01:00
return refoulement == 0 ? "souffle" : "none" ;
2020-07-17 22:04:35 +02:00
}
2020-11-16 04:32:42 +01:00
2020-11-17 16:30:03 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
async ajouterSouffle ( options = { chat : false } ) {
2022-06-12 12:14:55 +02:00
let souffle = await RdDRollTables . getSouffle ( )
//souffle.id = undefined; //TBC
2021-03-25 03:18:27 +01:00
await this . createEmbeddedDocuments ( 'Item' , [ souffle ] ) ;
2021-01-09 19:33:19 +01:00
if ( options . chat ) {
2020-12-17 02:20:03 +01:00
ChatMessage . create ( {
2021-02-03 20:40:16 +01:00
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name ) ,
2020-12-17 02:20:03 +01:00
content : this . name + " subit un Souffle de Dragon : " + souffle . name
} ) ;
}
return souffle ;
2020-11-16 04:32:42 +01:00
}
2020-11-17 16:30:03 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
async ajouterQueue ( options = { chat : false } ) {
2022-06-12 08:17:59 +02:00
let queue ;
2022-06-12 09:46:58 +02:00
if ( this . system . reve . reve . thanatosused ) {
queue = await RdDRollTables . getOmbre ( ) ;
2022-06-12 19:40:44 +02:00
await this . update ( { "system.reve.reve.thanatosused" : false } ) ;
2020-11-16 04:32:42 +01:00
}
else {
2022-06-12 09:46:58 +02:00
queue = await RdDRollTables . getQueue ( ) ;
2020-11-16 04:32:42 +01:00
}
2022-06-12 08:17:59 +02:00
await this . createEmbeddedDocuments ( 'Item' , [ queue ] ) ;
2021-01-09 19:33:19 +01:00
if ( options . chat ) {
2020-12-17 02:20:03 +01:00
ChatMessage . create ( {
2021-02-03 20:40:16 +01:00
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name ) ,
2020-12-17 02:20:03 +01:00
content : this . name + " subit une Queue de Dragon : " + queue . name
} ) ;
}
2021-02-06 23:58:15 +01:00
return queue ;
2020-11-16 04:32:42 +01:00
}
2021-01-09 19:33:19 +01:00
2021-04-25 10:08:40 +02:00
/* -------------------------------------------- */
2022-09-30 01:55:04 +02:00
/* -------------------------------------------- */
async changeTMRVisible ( ) {
await this . setTMRVisible ( this . system . reve . tmrpos . cache ? true : false ) ;
2021-04-25 10:08:40 +02:00
}
2022-09-30 01:55:04 +02:00
async setTMRVisible ( newState ) {
await this . update ( { 'system.reve.tmrpos.cache' : ! newState } ) ;
this . notifyRefreshTMR ( ) ;
2021-04-25 10:08:40 +02:00
}
2022-09-30 01:55:04 +02:00
2021-05-04 15:17:26 +02:00
isTMRCache ( ) {
2022-06-12 08:17:59 +02:00
return this . system . reve . tmrpos . cache ;
2021-04-25 10:08:40 +02:00
}
2022-06-25 17:49:19 +02:00
notifyRefreshTMR ( ) {
2022-01-29 22:49:34 +01:00
game . socket . emit ( SYSTEM _SOCKET _ID , {
2021-04-28 00:48:39 +02:00
msg : "msg_tmr_move" , data : {
2022-06-12 08:17:59 +02:00
actorId : this . _id ,
2022-06-12 12:14:55 +02:00
tmrPos : this . system . reve . tmrpos
2021-04-28 00:48:39 +02:00
}
} ) ;
}
2021-04-25 10:08:40 +02:00
2021-02-12 01:44:27 +01:00
/* -------------------------------------------- */
2022-06-25 17:49:19 +02:00
async reinsertionAleatoire ( raison , accessible = tmr => true ) {
const innaccessible = this . buildTMRInnaccessible ( ) ;
let tmr = await TMRUtility . getTMRAleatoire ( tmr => accessible ( tmr ) && ! innaccessible . includes ( tmr . coord ) ) ;
2021-02-12 01:44:27 +01:00
ChatMessage . create ( {
content : ` ${ raison } : ré-insertion aléatoire. ` ,
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name )
} ) ;
2022-06-25 17:49:19 +02:00
await this . forcerPositionTMRInconnue ( tmr ) ;
2021-02-12 01:44:27 +01:00
return tmr ;
}
2022-06-25 17:49:19 +02:00
async forcerPositionTMRInconnue ( tmr ) {
2022-09-30 01:55:04 +02:00
await this . setTMRVisible ( false ) ;
2022-06-25 17:49:19 +02:00
await this . updateCoordTMR ( tmr . coord ) ;
this . notifyRefreshTMR ( ) ;
}
2021-04-25 10:08:40 +02:00
/* -------------------------------------------- */
2021-02-12 01:44:27 +01:00
buildTMRInnaccessible ( ) {
2022-09-07 18:47:56 +02:00
const tmrInnaccessibles = this . filterItems ( it => Draconique . isCaseTMR ( it ) &&
2021-02-12 01:44:27 +01:00
EffetsDraconiques . isInnaccessible ( it ) ) ;
2022-06-12 12:14:55 +02:00
return tmrInnaccessibles . map ( it => it . system . coord ) ;
2021-02-12 01:44:27 +01:00
}
2021-02-11 02:48:27 +01:00
/* -------------------------------------------- */
getTMRRencontres ( ) {
2022-06-12 09:46:58 +02:00
return this . system . reve . rencontre . list ;
2020-12-30 15:56:17 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async deleteTMRRencontreAtPosition ( ) {
2021-03-20 00:09:29 +01:00
let rencontres = this . getTMRRencontres ( ) ;
let newRencontres = rencontres . filter ( it => it . coord != this . getDemiReve ( ) ) ;
if ( newRencontres . length != rencontres . length ) {
2022-06-12 19:40:44 +02:00
await this . update ( { "system.reve.rencontre.list" : newRencontres } ) ;
2020-07-21 23:51:24 +02:00
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async addTMRRencontre ( currentRencontre ) {
2021-03-20 00:09:29 +01:00
let rencontres = this . getTMRRencontres ( ) ;
let newRencontres = rencontres . filter ( it => it . coord != this . getDemiReve ( ) ) ;
if ( newRencontres . length == rencontres . length ) {
newRencontres . push ( currentRencontre ) ;
2022-06-12 19:40:44 +02:00
await this . update ( { "system.reve.rencontre.list" : newRencontres } ) ;
2020-07-21 23:51:24 +02:00
}
}
2020-11-17 16:30:03 +01:00
2021-02-08 14:15:18 +01:00
/* -------------------------------------------- */
async deleteTMRRencontre ( rencontreKey ) {
2022-04-30 19:15:55 +02:00
let list = duplicate ( this . system . reve . rencontre . list ) ;
2021-02-08 14:15:18 +01:00
let newList = [ ] ;
for ( let i = 0 ; i < list . length ; i ++ ) {
2021-03-15 00:05:56 +01:00
if ( i != rencontreKey )
newList . push ( list [ i ] ) ;
2021-02-08 14:15:18 +01:00
}
2022-06-12 08:17:59 +02:00
await this . update ( { "system.reve.rencontre.list" : newList } ) ;
2021-02-08 14:15:18 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async updateCoordTMR ( coord ) {
2021-05-28 10:25:34 +02:00
//console.log("UPDATE TMR", coord);
2022-06-12 08:17:59 +02:00
await this . update ( { "system.reve.tmrpos.coord" : coord } ) ;
2020-11-17 16:30:03 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async reveActuelIncDec ( value ) {
2022-04-30 19:15:55 +02:00
let reve = Math . max ( this . system . reve . reve . value + value , 0 ) ;
2022-06-12 08:17:59 +02:00
await this . update ( { "system.reve.reve.value" : reve } ) ;
2020-07-17 22:04:35 +02:00
}
2021-01-09 19:33:19 +01:00
2020-11-17 16:30:03 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
async updatePointDeSeuil ( value = 1 ) {
2022-04-30 19:15:55 +02:00
const seuil = Misc . toInt ( this . system . reve . seuil . value ) ;
const reve = Misc . toInt ( this . system . carac . reve . value ) ;
2020-11-16 03:52:34 +01:00
if ( seuil < reve ) {
2021-01-09 19:33:19 +01:00
await this . setPointsDeSeuil ( Math . min ( seuil + value , reve ) ) ;
2020-11-16 03:52:34 +01:00
}
}
2021-01-09 19:33:19 +01:00
2020-11-17 16:30:03 +01:00
/* -------------------------------------------- */
2021-03-20 00:09:29 +01:00
async setPointsDeSeuil ( seuil ) {
2022-06-12 08:17:59 +02:00
await this . update ( { "system.reve.seuil.value" : seuil } ) ;
2020-11-16 03:52:34 +01:00
}
2021-01-11 17:54:24 +01:00
/* -------------------------------------------- */
2021-03-20 00:09:29 +01:00
async setPointsDeChance ( chance ) {
2022-06-12 08:17:59 +02:00
await this . updateCompteurValue ( "chance" , chance ) ;
2021-01-11 17:54:24 +01:00
}
2021-02-11 02:48:27 +01:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-01-03 15:40:48 +01:00
getSonne ( ) {
2022-09-17 22:36:43 +02:00
return this . getEffect ( STATUSES . StatusStunned ) ;
2021-01-03 15:40:48 +01:00
}
2021-02-17 11:16:27 +01:00
/* -------------------------------------------- */
2021-12-05 01:50:09 +01:00
async finDeRound ( options = { terminer : false } ) {
2022-09-17 22:36:43 +02:00
for ( let effect of this . getEffects ( ) ) {
2021-06-30 01:01:24 +02:00
if ( effect . duration . type !== 'none' && ( effect . duration . remaining <= 0 || options . terminer ) ) {
2022-06-12 12:14:55 +02:00
if ( effect . system . origin ) {
2021-06-30 01:01:24 +02:00
await effect . update ( { 'disabled' : true } ) ;
}
else {
await effect . delete ( ) ;
}
2022-06-12 12:14:55 +02:00
ChatMessage . create ( { content : ` ${ this . name } n'est plus ${ Misc . lowerFirst ( game . i18n . localize ( effect . system . label ) ) } ! ` } ) ;
2021-02-17 11:16:27 +01:00
}
}
2021-12-05 01:50:09 +01:00
if ( this . type == 'personnage' ) {
2021-10-29 15:34:40 +02:00
// Gestion blessure graves : -1 pt endurance
2021-12-05 01:50:09 +01:00
let nbGraves = this . countBlessuresNonSoigneeByName ( 'graves' ) ;
if ( nbGraves > 0 ) {
await this . santeIncDec ( "endurance" , - 1 ) ;
2021-10-29 15:34:40 +02:00
}
}
2021-02-17 11:16:27 +01:00
}
/* -------------------------------------------- */
2021-01-13 03:42:13 +01:00
async setSonne ( sonne = true ) {
2022-07-22 21:38:15 +02:00
if ( this . isEntite ( ) ) {
2021-01-13 03:42:13 +01:00
return ;
}
2021-12-05 01:50:09 +01:00
if ( ! game . combat && sonne ) {
2021-06-30 01:01:24 +02:00
ui . notifications . info ( "Le personnage est hors combat, il ne reste donc pas sonné" ) ;
return ;
}
2022-09-17 22:36:43 +02:00
await this . setEffect ( STATUSES . StatusStunned , sonne ) ;
2021-01-13 03:42:13 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-01-03 15:40:48 +01:00
getSConst ( ) {
2022-07-22 21:38:15 +02:00
if ( this . isEntite ( ) ) {
2021-01-13 03:42:13 +01:00
return 0 ;
2021-01-03 15:40:48 +01:00
}
2022-06-12 08:17:59 +02:00
return RdDCarac . calculSConst ( this . system . carac . constitution . value )
2021-01-03 15:40:48 +01:00
}
2020-07-27 16:27:41 +02:00
2021-03-20 00:09:29 +01:00
async ajoutXpConstitution ( xp ) {
2022-06-12 08:17:59 +02:00
await this . update ( { "system.carac.constitution.xp" : Misc . toInt ( this . system . carac . constitution . xp ) + xp } ) ;
2021-03-20 00:09:29 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
countBlessures ( blessuresListe ) {
2020-11-25 00:50:20 +01:00
return blessuresListe . filter ( b => b . active ) . length
2020-07-27 16:27:41 +02:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
countBlessuresByName ( name ) {
2022-04-30 19:15:55 +02:00
return this . countBlessures ( this . system . blessures [ name ] . liste ) ;
2021-01-03 15:40:48 +01:00
}
2021-01-09 19:33:19 +01:00
2021-10-29 20:58:57 +02:00
countBlessuresNonSoigneeByName ( name ) {
2022-09-07 18:47:56 +02:00
if ( this . system . blessures ) {
let blessures = this . system . blessures [ name ] . liste ;
return blessures . filter ( b => b . active && ! b . psdone ) . length ;
}
return 0 ;
2021-10-29 20:58:57 +02:00
}
2021-05-11 21:45:43 +02:00
2021-01-29 16:58:45 +01:00
/* -------------------------------------------- */
2021-06-30 01:01:24 +02:00
async testSiSonne ( endurance ) {
2021-05-11 21:45:43 +02:00
const result = await this . _jetEndurance ( endurance ) ;
if ( result . roll . total == 1 ) {
ChatMessage . create ( { content : await this . _gainXpConstitutionJetEndurance ( ) } ) ;
}
return result ;
}
2021-01-29 16:58:45 +01:00
2021-05-11 21:45:43 +02:00
/* -------------------------------------------- */
async jetEndurance ( ) {
2022-04-30 19:15:55 +02:00
const endurance = this . system . sante . endurance . value ;
2021-05-11 21:45:43 +02:00
2022-04-30 19:15:55 +02:00
const result = await this . _jetEndurance ( this . system . sante . endurance . value )
2021-01-29 16:58:45 +01:00
const message = {
2021-05-11 21:45:43 +02:00
content : "Jet d'Endurance : " + result . roll . total + " / " + endurance + "<br>" ,
2021-01-29 16:58:45 +01:00
whisper : ChatMessage . getWhisperRecipients ( game . user . name )
} ;
2021-05-11 21:45:43 +02:00
if ( result . sonne ) {
message . content += ` ${ this . name } a échoué son Jet d'Endurance et devient Sonné ` ;
}
else if ( result . roll . total == 1 ) {
message . content += await this . _gainXpConstitutionJetEndurance ( ) ;
}
else {
message . content += ` ${ this . name } a réussi son Jet d'Endurance ! ` ;
}
2021-01-29 16:58:45 +01:00
ChatMessage . create ( message ) ;
}
2021-05-11 21:45:43 +02:00
async _gainXpConstitutionJetEndurance ( ) {
await this . ajoutXpConstitution ( 1 ) ; // +1 XP !
return ` ${ this . name } a obtenu 1 sur son Jet d'Endurance et a gagné 1 point d'Expérience en Constitution. Ce point d'XP a été ajouté automatiquement. ` ;
}
async _jetEndurance ( endurance ) {
2021-12-03 22:53:38 +01:00
const roll = await RdDDice . roll ( "1d20" ) ;
2021-05-11 21:45:43 +02:00
let result = {
roll : roll ,
sonne : roll . total > endurance || roll . total == 20 // 20 is always a failure
}
if ( result . sonne ) {
await this . setSonne ( ) ;
}
return result ;
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2020-12-06 21:39:55 +01:00
async jetVie ( ) {
2021-12-03 22:53:38 +01:00
let roll = await RdDDice . roll ( "1d20" ) ;
2022-04-30 19:15:55 +02:00
let msgText = "Jet de Vie : " + roll . total + " / " + this . system . sante . vie . value + "<br>" ;
if ( roll . total <= this . system . sante . vie . value ) {
2020-12-06 21:39:55 +01:00
msgText += "Jet réussi, pas de perte de point de vie (prochain jet dans 1 round pour 1 critique, SC minutes pour une grave)" ;
2021-05-11 21:45:43 +02:00
if ( roll . total == 1 ) {
2020-12-06 21:39:55 +01:00
msgText += "La durée entre 2 jets de vie est multipliée par 20 (20 rounds pour une critique, SCx20 minutes pour une grave)" ;
}
} else {
msgText += "Jet échoué, vous perdez 1 point de vie" ;
await this . santeIncDec ( "vie" , - 1 ) ;
2021-05-11 21:45:43 +02:00
if ( roll . total == 20 ) {
2020-12-06 21:39:55 +01:00
msgText += "Votre personnage est mort !!!!!" ;
}
}
const message = {
content : msgText ,
whisper : ChatMessage . getWhisperRecipients ( game . user . name )
} ;
2021-01-09 19:33:19 +01:00
ChatMessage . create ( message ) ;
2020-12-06 21:39:55 +01:00
}
2020-08-29 22:52:41 +02:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-06-30 01:01:24 +02:00
async santeIncDec ( name , inc , isCritique = false ) {
2021-05-10 18:39:35 +02:00
if ( name == 'fatigue' && ! ReglesOptionelles . isUsing ( "appliquer-fatigue" ) ) {
2021-05-08 20:08:56 +02:00
return ;
}
2022-06-12 08:17:59 +02:00
const sante = duplicate ( this . system . sante )
2021-01-13 03:04:33 +01:00
let compteur = sante [ name ] ;
if ( ! compteur ) {
2021-02-11 02:48:27 +01:00
return ;
2020-12-01 17:36:13 +01:00
}
2021-01-09 19:38:24 +01:00
let result = {
sonne : false ,
} ;
2021-02-11 02:48:27 +01:00
let minValue = name == "vie" ? - this . getSConst ( ) - 1 : 0 ;
2020-12-01 00:21:53 +01:00
2021-01-13 03:04:33 +01:00
result . newValue = Math . max ( minValue , Math . min ( compteur . value + inc , compteur . max ) ) ;
2021-01-09 19:38:24 +01:00
//console.log("New value ", inc, minValue, result.newValue);
2021-01-13 03:04:33 +01:00
let fatigue = 0 ;
2022-07-22 21:38:15 +02:00
if ( name == "endurance" && ! this . isEntite ( ) ) {
2021-06-30 01:01:24 +02:00
if ( result . newValue == 0 && inc < 0 && ! isCritique ) { // perte endurance et endurance devient 0 (sauf critique) -> -1 vie
2021-02-11 02:48:27 +01:00
sante . vie . value -- ;
2021-05-08 13:56:03 +02:00
result . perteVie = true ;
2020-05-31 23:06:25 +02:00
}
2021-01-09 19:38:24 +01:00
result . newValue = Math . max ( 0 , result . newValue ) ;
if ( inc > 0 ) { // le max d'endurance s'applique seulement à la récupération
2021-01-10 02:28:45 +01:00
result . newValue = Math . min ( result . newValue , this . _computeEnduranceMax ( ) )
2020-11-20 11:38:27 +01:00
}
2021-01-13 03:04:33 +01:00
const perte = compteur . value - result . newValue ;
2021-05-08 13:56:03 +02:00
result . perte = perte ;
2021-06-30 01:01:24 +02:00
if ( perte > 1 ) {
2021-01-09 19:38:24 +01:00
// Peut-être sonné si 2 points d'endurance perdus d'un coup
2021-06-30 01:01:24 +02:00
const testIsSonne = await this . testSiSonne ( result . newValue ) ;
2021-01-09 19:38:24 +01:00
result . sonne = testIsSonne . sonne ;
result . jetEndurance = testIsSonne . roll . total ;
2021-01-13 03:04:33 +01:00
} else if ( inc > 0 ) {
await this . setSonne ( false ) ;
}
if ( sante . fatigue && inc < 0 ) { // Each endurance lost -> fatigue lost
fatigue = perte ;
2020-05-31 23:06:25 +02:00
}
}
2021-01-13 03:04:33 +01:00
compteur . value = result . newValue ;
// If endurance lost, then the same amount of fatigue cannot be recovered
2021-05-08 20:08:56 +02:00
if ( ReglesOptionelles . isUsing ( "appliquer-fatigue" ) && sante . fatigue && fatigue > 0 ) {
2021-01-13 23:46:12 +01:00
sante . fatigue . value = Math . max ( sante . fatigue . value + fatigue , this . _computeFatigueMin ( ) ) ;
}
2022-06-12 08:17:59 +02:00
await this . update ( { "system.sante" : sante } )
2021-02-02 19:17:59 +01:00
if ( this . isDead ( ) ) {
2022-09-17 22:36:43 +02:00
await this . setEffect ( STATUSES . StatusComma , true ) ;
2021-01-24 19:52:02 +01:00
}
2021-01-09 19:38:24 +01:00
return result ;
2020-06-07 23:16:29 +02:00
}
2020-08-29 22:52:41 +02:00
2021-02-02 19:17:59 +01:00
isDead ( ) {
2022-07-22 22:53:48 +02:00
return ! this . isEntite ( ) && this . system . sante . vie . value < - this . getSConst ( )
2021-02-02 19:17:59 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2020-11-20 11:38:27 +01:00
_computeFatigueMin ( ) {
2022-04-30 19:15:55 +02:00
return this . system . sante . endurance . max - this . system . sante . endurance . value ;
2020-11-20 11:38:27 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2020-11-20 11:38:27 +01:00
_computeEnduranceMax ( ) {
2022-04-30 23:42:55 +02:00
let blessures = this . system . blessures ;
let diffVie = this . system . sante . vie . max - this . system . sante . vie . value ;
let maxEndVie = this . system . sante . endurance . max - ( diffVie * 2 ) ;
2020-11-25 00:50:20 +01:00
let nbGraves = this . countBlessures ( blessures . graves . liste ) ;
let nbCritiques = this . countBlessures ( blessures . critiques . liste ) ;
2022-04-30 23:42:55 +02:00
let maxEndGraves = Math . floor ( this . system . sante . endurance . max / ( 2 * nbGraves ) ) ;
let maxEndCritiques = nbCritiques > 0 ? 1 : this . system . sante . endurance . max ;
2020-11-20 11:38:27 +01:00
return Math . max ( 0 , Math . min ( maxEndVie , maxEndGraves , maxEndCritiques ) ) ;
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-03-20 00:09:29 +01:00
async manageBlessureFromSheet ( gravite , index ) {
2022-04-30 19:15:55 +02:00
let listBlessures = duplicate ( this . system . blessures ) ;
2021-03-20 00:09:29 +01:00
let blessure = listBlessures [ gravite + "s" ] . liste [ index ] ;
2020-07-20 12:02:07 +02:00
blessure . active = ! blessure . active ;
2021-01-09 19:33:19 +01:00
if ( ! blessure . active ) {
2021-03-20 00:09:29 +01:00
this . _supprimerBlessure ( blessure ) ;
2020-07-27 16:27:41 +02:00
}
2022-06-12 19:40:44 +02:00
await this . update ( { 'system.blessures' : listBlessures } ) ;
2020-07-20 12:02:07 +02:00
}
2020-07-27 16:27:41 +02:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-10-29 22:37:27 +02:00
async setDataBlessureFromSheet ( gravite , index , psoins , pcomplets , jours , loc , psdone , scdone ) {
2022-04-30 19:15:55 +02:00
let listBlessures = duplicate ( this . system . blessures ) ;
2021-03-20 00:09:29 +01:00
let blessure = listBlessures [ gravite + "s" ] . liste [ index ] ;
2021-10-29 22:37:27 +02:00
blessure . psdone = psdone ;
blessure . scdone = scdone ;
2020-07-27 16:27:41 +02:00
blessure . premiers _soins = psoins ;
blessure . soins _complets = pcomplets ;
blessure . jours = jours ;
2020-12-15 02:20:24 +01:00
blessure . loc = loc ;
2022-06-12 19:40:44 +02:00
await this . update ( { 'system.blessures' : listBlessures } ) ;
2020-07-27 16:27:41 +02:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-05-08 13:56:03 +02:00
async jetDeMoral ( situation , messageReussi = undefined , messageManque = undefined ) {
2021-11-07 21:36:11 +01:00
const jetMoral = await this . _jetDeMoral ( situation ) ;
2021-12-05 01:50:09 +01:00
const finMessage = ( jetMoral . succes ? messageReussi : messageManque ) ? ? ( jetMoral . ajustement == 0 ? "Vous gardez votre moral" : jetMoral . ajustement > 0 ? "Vous gagnez du moral" : "Vous perdez du moral" ) ;
2021-11-07 21:36:11 +01:00
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name ) ,
content : ` ${ finMessage } - jet ${ jetMoral . succes ? "réussi" : "manqué" } en situation ${ situation } ( ${ jetMoral . jet } / ${ jetMoral . difficulte } ). `
} ) ;
2021-05-18 01:04:27 +02:00
return jetMoral . ajustement ;
}
2021-11-07 21:36:11 +01:00
async _jetDeMoral ( situation ) {
2022-04-30 19:15:55 +02:00
const moralActuel = Misc . toInt ( this . system . compteurs . moral . value ) ;
2021-12-03 22:53:38 +01:00
const jet = await RdDDice . rollTotal ( "1d20" ) ;
2021-05-18 01:04:27 +02:00
const difficulte = 10 + moralActuel ;
const succes = jet <= difficulte ;
const jetMoral = {
actuel : moralActuel ,
jet : jet ,
situation : situation ,
difficulte : difficulte ,
succes : succes ,
ajustement : this . _calculAjustementMoral ( succes , moralActuel , situation )
} ;
await this . moralIncDec ( jetMoral . ajustement ) ;
return jetMoral ;
2020-12-29 01:34:15 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2020-12-29 01:34:15 +01:00
async moralIncDec ( ajustementMoral ) {
2020-12-16 02:54:28 +01:00
if ( ajustementMoral != 0 ) {
2022-04-30 19:15:55 +02:00
let moral = Misc . toInt ( this . system . compteurs . moral . value ) + ajustementMoral
2021-03-20 00:09:29 +01:00
if ( moral > 3 ) { // exaltation
2022-04-30 19:15:55 +02:00
const exaltation = Misc . toInt ( this . system . compteurs . exaltation . value ) + moral - 3 ;
2021-03-22 20:10:37 +01:00
await this . updateCompteurValue ( 'exaltation' , exaltation ) ;
2020-12-16 02:54:28 +01:00
}
2021-03-20 00:09:29 +01:00
if ( moral < - 3 ) { // dissolution
2022-04-30 19:15:55 +02:00
const dissolution = Misc . toInt ( this . system . compteurs . dissolution . value ) + 3 - moral ;
2021-03-22 20:10:37 +01:00
await this . updateCompteurValue ( 'dissolution' , dissolution ) ;
2020-12-16 02:54:28 +01:00
}
2021-03-20 00:09:29 +01:00
moral = Math . max ( - 3 , Math . min ( moral , 3 ) ) ;
2021-03-22 20:10:37 +01:00
await this . updateCompteurValue ( 'moral' , moral ) ;
2020-12-16 02:54:28 +01:00
}
2022-04-30 19:15:55 +02:00
return this . system . compteurs . moral . value ;
2020-12-16 02:54:28 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2020-12-21 22:13:13 +01:00
_calculAjustementMoral ( succes , moral , situation ) {
2020-12-16 02:54:28 +01:00
switch ( situation ) {
2021-04-06 23:39:27 +02:00
case 'heureux' : case 'heureuse' : return succes ? 1 : 0 ;
case 'malheureuse' : case 'malheureux' : return succes ? 0 : - 1 ;
2020-12-16 02:54:28 +01:00
case 'neutre' :
if ( succes && moral <= 0 ) return 1 ;
if ( ! succes && moral > 0 ) return - 1 ;
}
return 0 ;
}
2021-01-03 18:19:18 +01:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2020-12-29 01:34:15 +01:00
async setEthylisme ( degre ) {
2022-04-30 19:15:55 +02:00
let ethylisme = duplicate ( this . system . compteurs . ethylisme ) ;
2020-12-29 01:34:15 +01:00
ethylisme . value = degre ;
ethylisme . nb _doses = 0 ;
if ( degre == 1 ) {
ethylisme . jet _moral = false ;
}
2022-06-12 19:40:44 +02:00
await this . update ( { "system.compteurs.ethylisme" : ethylisme } ) ;
2020-12-29 01:34:15 +01:00
}
2020-12-06 20:11:30 +01:00
/* -------------------------------------------- */
2021-05-18 01:04:27 +02:00
async jetEthylisme ( ) {
2021-01-09 19:33:19 +01:00
let rollData = {
2022-04-30 19:15:55 +02:00
vie : this . system . sante . vie . max ,
2021-05-18 01:04:27 +02:00
forceAlcool : 0 ,
2021-04-06 23:39:27 +02:00
etat : this . getEtatGeneral ( { ethylisme : true } ) ,
2022-06-12 08:17:59 +02:00
diffNbDoses : - Number ( this . system . compteurs . ethylisme . nb _doses || 0 ) ,
2020-12-06 20:11:30 +01:00
finalLevel : 0 ,
2021-04-21 19:40:48 +02:00
diffConditions : 0 ,
ajustementsForce : CONFIG . RDD . difficultesLibres ,
2020-12-06 20:11:30 +01:00
}
let html = await renderTemplate ( 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-ethylisme.html' , rollData ) ;
2021-05-18 01:04:27 +02:00
new RdDRollDialogEthylisme ( html , rollData , this , r => this . saouler ( r . forceAlcool ) ) . render ( true ) ;
2020-12-06 20:11:30 +01:00
}
2021-04-06 23:44:57 +02:00
/* -------------------------------------------- */
2022-07-22 22:53:48 +02:00
async actionItem ( item , onActionItem = async ( ) => { } ) {
2021-04-12 00:16:23 +02:00
if ( ! item . getActionPrincipale ( ) ) return ;
2022-06-12 08:17:59 +02:00
switch ( item . type ) {
2021-12-05 01:50:09 +01:00
case 'nourritureboisson' : return await this . actionNourritureboisson ( item , onActionItem ) ;
case 'potion' : return await this . consommerPotion ( item , onActionItem ) ;
2021-05-04 15:18:32 +02:00
case 'livre' : return await this . actionLire ( item ) ;
2021-12-05 16:48:18 +01:00
case 'conteneur' : return await item . sheet . render ( true ) ;
2021-12-05 23:30:57 +01:00
case 'herbe' : {
2022-07-22 22:53:48 +02:00
if ( item . isHerbeAPotion ( ) ) {
2021-12-05 23:30:57 +01:00
return this . dialogFabriquerPotion ( item ) ;
}
return ;
}
2022-09-16 23:27:26 +02:00
case 'queue' : case 'ombre' : return await this . actionRefoulement ( item ) ;
2021-04-12 01:03:37 +02:00
}
}
2021-12-05 01:50:09 +01:00
async actionNourritureboisson ( item , onActionItem ) {
const dialog = await DialogConsommer . create ( this , item , onActionItem ) ;
2021-04-12 01:03:37 +02:00
dialog . render ( true ) ;
}
2021-04-16 00:29:08 +02:00
2021-05-04 15:18:32 +02:00
async actionLire ( item ) {
const tache = await this . creerTacheDepuisLivre ( item , { renderSheet : false } ) ;
if ( tache ) {
await this . rollTache ( tache . id ) ;
}
}
2021-04-06 23:44:57 +02:00
2021-04-11 23:01:10 +02:00
/* -------------------------------------------- */
async consommer ( item , choix ) {
2022-06-12 08:17:59 +02:00
switch ( item . type ) {
2021-04-11 23:01:10 +02:00
case 'nourritureboisson' :
return await this . consommerNourritureboisson ( item , choix ) ;
case 'potion' :
return await this . consommerPotion ( item )
}
}
/* -------------------------------------------- */
2021-06-21 23:37:33 +02:00
async consommerNourritureboisson ( item , choix = { doses : 1 , seForcer : false , supprimerSiZero : false } ) {
2022-09-07 18:47:56 +02:00
if ( item . type != 'nourritureboisson' ) {
2021-04-11 23:01:10 +02:00
return ;
}
2022-09-07 18:47:56 +02:00
if ( choix . doses > item . system . quantite ) {
ui . notifications . warn ( ` Il n'y a pas assez de ${ item . name } pour manger ${ choix . doses } ` )
2021-04-11 23:01:10 +02:00
return ;
}
2022-09-07 18:47:56 +02:00
if ( ! this . _apprecierCuisine ( item , choix . seForcer ) ) {
ui . notifications . info ( ` ${ this . name } ne n'arrive pas à manger de ${ item . name } ` )
2021-04-11 23:01:10 +02:00
return ;
}
await this . manger ( item , choix . doses , { diminuerQuantite : false } ) ;
await this . boire ( item , choix . doses , { diminuerQuantite : false } ) ;
2021-06-21 23:37:33 +02:00
await item . diminuerQuantite ( choix . doses , choix ) ;
2021-04-11 23:01:10 +02:00
}
2022-09-07 18:47:56 +02:00
async _apprecierCuisine ( item , seForcer ) {
const surmonteExotisme = await this . _surmonterExotisme ( item , seForcer ) ;
2021-11-10 22:49:01 +01:00
if ( surmonteExotisme ) {
2022-09-07 18:47:56 +02:00
await this . apprecier ( 'gout' , 'cuisine' , item . system . qualite , item . system . boisson ? "apprécie la boisson" : "apprécie le plat" ) ;
2021-11-10 22:49:01 +01:00
}
else if ( seForcer ) {
await this . jetDeMoral ( 'malheureux' ) ;
}
else {
return false ;
}
return true ;
}
2021-04-11 23:01:10 +02:00
/* -------------------------------------------- */
2022-09-07 18:47:56 +02:00
async _surmonterExotisme ( item ) {
const exotisme = Math . min ( item . system . exotisme , item . system . qualite , 0 ) ;
2021-11-10 22:49:01 +01:00
if ( exotisme < 0 ) {
2022-09-07 18:47:56 +02:00
const rolled = await this . rollCaracCompetence ( 'volonte' , 'cuisine' , exotisme , { title : ` tente de surmonter l'exotisme de ${ item . name } ` } ) ;
2021-11-10 22:49:01 +01:00
return rolled . isSuccess ;
}
return true ;
}
/* -------------------------------------------- */
async apprecier ( carac , compName , qualite , title ) {
const rolled = await this . rollCaracCompetence ( carac , compName , qualite , { title : title , apprecier : true } ) ;
if ( rolled ? . isSuccess ) {
await this . jetDeMoral ( 'heureux' ) ;
}
}
/* -------------------------------------------- */
2021-12-05 01:50:09 +01:00
async manger ( item , doses , options = { diminuerQuantite : true } ) {
2022-06-12 08:17:59 +02:00
const sust = item . system . sust
2021-04-06 23:44:57 +02:00
if ( sust > 0 ) {
2022-04-30 19:15:55 +02:00
await this . updateCompteurValue ( 'sust' , Misc . keepDecimals ( this . system . compteurs . sust . value + sust * doses , 1 ) ) ;
2021-04-06 23:44:57 +02:00
}
2021-04-11 23:01:10 +02:00
await item . diminuerQuantite ( doses , options ) ;
2021-04-06 23:44:57 +02:00
}
2021-04-12 01:03:37 +02:00
2021-04-11 23:01:10 +02:00
/* -------------------------------------------- */
async boire ( item , doses , options = { diminuerQuantite : true } ) {
2022-09-07 18:47:56 +02:00
const desaltere = item . system . desaltere ;
2021-04-11 23:01:10 +02:00
if ( desaltere > 0 ) {
2022-04-30 19:15:55 +02:00
await this . updateCompteurValue ( 'eau' , Misc . keepDecimals ( this . system . compteurs . eau . value + desaltere * doses , 1 ) ) ;
2021-04-11 23:01:10 +02:00
}
if ( item . isAlcool ( ) ) {
for ( let i = 0 ; i < doses ; i ++ ) {
2022-09-07 18:47:56 +02:00
await this . saouler ( item . system . force , item ) ;
2021-04-11 23:01:10 +02:00
}
2021-04-06 23:44:57 +02:00
}
2021-04-11 23:01:10 +02:00
await item . diminuerQuantite ( doses , options ) ;
2021-04-06 23:44:57 +02:00
}
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-05-18 01:04:27 +02:00
async saouler ( forceAlcool , alcool = undefined ) {
2022-04-30 19:15:55 +02:00
let ethylisme = duplicate ( this . system . compteurs . ethylisme ) ;
2021-05-20 02:44:34 +02:00
2021-05-18 01:04:27 +02:00
const etat = this . getEtatGeneral ( { ethylisme : true } ) ;
2022-04-30 19:15:55 +02:00
const nbDoses = Number ( this . system . compteurs . ethylisme . nb _doses || 0 ) ;
2021-05-18 01:04:27 +02:00
const ethylismeData = {
2022-06-12 08:17:59 +02:00
alias : this . name ,
actor : this ,
2022-04-30 19:15:55 +02:00
vie : this . system . sante . vie . max ,
2022-06-12 09:46:58 +02:00
alcool : alcool ,
2021-05-18 01:04:27 +02:00
jetVie : {
forceAlcool : forceAlcool ,
nbDoses : nbDoses ,
2022-04-30 19:15:55 +02:00
selectedCarac : this . system . sante . vie ,
2022-06-12 08:17:59 +02:00
carac : this . system . carac ,
2022-04-30 19:15:55 +02:00
caracValue : this . system . sante . vie . max ,
2021-12-03 22:53:38 +01:00
finalLevel : etat + forceAlcool - nbDoses
2021-05-18 01:04:27 +02:00
} ,
}
await RdDResolutionTable . rollData ( ethylismeData . jetVie ) ;
2021-05-19 23:23:50 +02:00
this . _appliquerExperienceRollData ( ethylismeData . jetVie ) ;
2021-05-18 01:04:27 +02:00
RollDataAjustements . calcul ( ethylismeData . jetVie , this ) ;
if ( ethylismeData . jetVie . rolled . isSuccess ) {
ethylisme . nb _doses ++ ;
} else {
ethylisme . value = Math . max ( ethylisme . value - 1 , - 7 ) ;
ethylisme . nb _doses = 0 ;
2021-05-20 02:44:34 +02:00
2021-12-03 22:53:38 +01:00
let perte = await RdDDice . rollTotal ( "1d6" ) ;
2021-06-30 01:01:24 +02:00
ethylismeData . perteEndurance = await this . santeIncDec ( "endurance" , - perte ) ;
2021-05-20 02:44:34 +02:00
2021-05-18 01:04:27 +02:00
if ( ! ethylisme . jet _moral ) {
2021-11-07 21:36:11 +01:00
ethylismeData . jetMoral = await this . _jetDeMoral ( 'heureuse' ) ;
2021-05-18 01:04:27 +02:00
if ( ethylismeData . jetMoral . ajustement == 1 ) {
2021-05-20 02:44:34 +02:00
ethylismeData . moralAlcool = 'heureux' ;
2021-05-18 01:04:27 +02:00
ethylisme . jet _moral = true ;
} else if ( ethylisme . value == - 1 ) {
ethylismeData . jetMoral . ajustement = - 1 ;
2021-05-20 02:44:34 +02:00
ethylismeData . moralAlcool = 'triste' ;
2021-05-18 01:04:27 +02:00
ethylisme . jet _moral = true ;
await this . moralIncDec ( - 1 ) ;
}
}
2021-05-20 02:44:34 +02:00
if ( ethylisme . value < 0 ) {
2021-05-18 01:04:27 +02:00
// Qui a bu boira (p 164)
ethylismeData . jetVolonte = {
2022-04-30 19:15:55 +02:00
selectedCarac : this . system . carac . volonte ,
caracValue : this . system . carac . volonte . value ,
2021-05-18 01:04:27 +02:00
ethylisme : ethylisme . value ,
2022-04-30 19:15:55 +02:00
finalLevel : ethylisme . value + this . system . compteurs . moral . value
2021-05-18 01:04:27 +02:00
}
await RdDResolutionTable . rollData ( ethylismeData . jetVolonte ) ;
2021-05-19 23:23:50 +02:00
this . _appliquerExperienceRollData ( ethylismeData . jetVolonte ) ;
2021-05-18 01:04:27 +02:00
RollDataAjustements . calcul ( ethylismeData . jetVolonte , this ) ;
}
}
2021-05-20 02:44:34 +02:00
ethylismeData . ajustementEthylique = ethylisme . value ;
ethylismeData . nomEthylisme = RdDUtility . getNomEthylisme ( ethylisme . value ) ;
2021-05-18 01:04:27 +02:00
ethylismeData . doses = ethylisme . nb _doses ;
2021-05-20 02:44:34 +02:00
2022-06-12 08:17:59 +02:00
await this . update ( { 'system.compteurs.ethylisme' : ethylisme } ) ;
2021-05-18 01:04:27 +02:00
await RdDResolutionTable . displayRollData ( ethylismeData , this , 'chat-resultat-ethylisme.html' ) ;
2021-04-06 23:44:57 +02:00
}
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-04-06 23:44:57 +02:00
async jetGoutCuisine ( ) {
console . info ( 'Jet de Gout/Cuisine' ) ;
return true ;
}
2020-11-12 16:35:51 +01:00
/* -------------------------------------------- */
2021-01-29 12:08:02 +01:00
async transformerStress ( ) {
2022-04-30 19:15:55 +02:00
const stress = Misc . toInt ( this . system . compteurs . stress . value ) ;
2021-01-09 19:33:19 +01:00
if ( stress <= 0 ) {
2021-01-29 12:08:02 +01:00
return ;
2020-11-24 18:54:13 +01:00
}
2021-02-11 02:48:27 +01:00
2021-01-29 12:08:02 +01:00
const stressRoll = await this . _stressRoll ( this . getReveActuel ( ) ) ;
2021-02-11 02:48:27 +01:00
2021-01-29 12:08:02 +01:00
const conversion = Math . floor ( stress * stressRoll . factor / 100 ) ;
2022-04-30 19:15:55 +02:00
let dissolution = Math . max ( 0 , Misc . toInt ( this . system . compteurs . dissolution . value ) ) ;
let exaltation = Math . max ( 0 , Misc . toInt ( this . system . compteurs . exaltation . value ) ) ;
2020-12-19 01:45:03 +01:00
const annule = Math . min ( dissolution , exaltation ) ;
dissolution -= annule ;
exaltation -= annule ;
2021-01-29 12:08:02 +01:00
const perteDissolution = Math . max ( 0 , Math . min ( dissolution , conversion ) ) ;
let stressRollData = {
alias : this . name ,
2022-04-30 19:15:55 +02:00
selectedCarac : this . system . carac . reve ,
2021-01-29 12:08:02 +01:00
rolled : stressRoll ,
stress : stress ,
perte : Math . min ( conversion , stress ) ,
convertis : conversion - perteDissolution ,
2021-02-11 02:48:27 +01:00
xp : conversion - perteDissolution + exaltation ,
2021-01-29 12:08:02 +01:00
dissolution : dissolution ,
exaltation : exaltation
} ;
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name ) ,
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-resultat-transformer-stress.html ` , stressRollData )
} ) ;
2021-02-11 02:48:27 +01:00
2022-04-30 19:15:55 +02:00
let compteurs = duplicate ( this . system . compteurs ) ;
2021-01-29 12:08:02 +01:00
compteurs . stress . value = Math . max ( stress - stressRollData . perte - 1 , 0 ) ;
compteurs . experience . value += stressRollData . xp ;
compteurs . dissolution . value = dissolution - perteDissolution ;
2020-12-19 01:45:03 +01:00
compteurs . exaltation . value = 0 ;
2022-06-12 08:17:59 +02:00
await this . update ( { "system.compteurs" : compteurs } ) ;
2021-05-27 19:40:45 +02:00
this . updateExperienceLog ( 'XP' , stressRollData . xp , "Transformation du stress" ) ;
2020-08-29 22:52:41 +02:00
}
2020-11-14 21:34:34 +01:00
/* -------------------------------------------- */
2021-01-29 12:08:02 +01:00
async _stressRoll ( reveActuel ) {
2020-11-25 00:49:21 +01:00
let result = await RdDResolutionTable . roll ( reveActuel , 0 ) ;
2021-01-29 12:08:02 +01:00
if ( result . isPart ) {
result . second = await RdDResolutionTable . roll ( reveActuel , 0 ) ;
}
result . factor = this . _getFacteurStress ( result ) ;
return result ;
}
2021-02-11 02:48:27 +01:00
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-01-29 12:08:02 +01:00
_getFacteurStress ( stressRoll ) {
switch ( stressRoll . code ) {
case "sign" : return 75 ;
case "norm" : return 50 ;
case "echec" : return 20 ;
case "epart" : return 10 ;
case "etotal" : return 0 ;
2020-11-17 16:30:03 +01:00
case "part" :
2021-02-11 02:48:27 +01:00
if ( stressRoll . second . isSign ) {
stressRoll . quality = "Double Particulière" ;
return 150 ;
}
return 100 ;
2020-11-17 16:30:03 +01:00
}
2021-01-29 12:08:02 +01:00
return 0 ;
2020-11-12 16:35:51 +01:00
}
2020-11-17 11:35:05 +01:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2020-12-12 21:58:44 +01:00
createCallbackExperience ( ) {
2020-12-06 23:31:23 +01:00
return {
condition : r => r . rolled . isPart && r . finalLevel < 0 && game . settings . get ( "core" , "rollMode" ) != 'selfroll' ,
2022-09-07 00:09:17 +02:00
action : r => this . appliquerAjoutExperience ( r )
2020-12-06 23:31:23 +01:00
} ;
}
2021-03-15 00:05:56 +01:00
2021-02-09 23:23:40 +01:00
/* -------------------------------------------- */
2021-02-11 20:31:04 +01:00
createCallbackAppelAuMoral ( ) { /* Si l'appel au moral est utilisé, on l'affiche dans le chat et on diminue éventuellement le moral */
2021-02-09 23:23:40 +01:00
return {
condition : r => r . use . appelAuMoral && game . settings . get ( "core" , "rollMode" ) != 'selfroll' ,
2021-03-15 00:10:29 +01:00
action : r => this . _appliquerAppelMoral ( r )
2021-02-09 23:23:40 +01:00
} ;
}
2021-03-15 00:05:56 +01:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-05-27 19:40:45 +02:00
async checkCaracXP ( caracName , display = true ) {
2022-06-12 09:46:58 +02:00
let carac = RdDActor . _findCaracByName ( this . system . carac , caracName ) ;
2021-01-03 18:19:18 +01:00
if ( carac && carac . xp > 0 ) {
2021-05-27 19:40:45 +02:00
const niveauSuivant = Number ( carac . value ) + 1 ;
let xpNeeded = RdDCarac . getCaracNextXp ( niveauSuivant ) ;
2021-01-09 19:33:19 +01:00
if ( carac . xp >= xpNeeded ) {
2021-01-03 18:19:18 +01:00
carac = duplicate ( carac ) ;
2021-05-27 19:40:45 +02:00
carac . value = niveauSuivant ;
2021-01-03 18:19:18 +01:00
2021-05-27 19:40:45 +02:00
let checkXp = {
2021-01-09 19:33:19 +01:00
alias : this . name ,
2021-01-03 18:19:18 +01:00
carac : caracName ,
2021-05-27 19:40:45 +02:00
value : niveauSuivant ,
2021-01-03 18:19:18 +01:00
xp : carac . xp
}
2021-05-28 00:55:22 +02:00
if ( display ) {
2021-10-07 22:41:22 +02:00
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( this . name ) ,
2021-05-27 19:40:45 +02:00
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.html ` , checkXp )
} ) ;
}
return checkXp ;
2021-01-03 18:19:18 +01:00
}
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-05-27 19:40:45 +02:00
async checkCompetenceXP ( compName , newXP , display = true ) {
2022-06-12 09:46:58 +02:00
let compData = this . getCompetence ( compName ) ;
if ( compData && newXP && newXP == compData . system . xp ) { // Si édition, mais sans changement XP
2022-06-12 08:17:59 +02:00
return ;
2021-01-14 15:29:47 +01:00
}
2022-06-12 09:46:58 +02:00
newXP = ( newXP ) ? newXP : compData . system . xp ;
2021-04-20 00:52:06 +02:00
if ( compData && newXP > 0 ) {
2022-06-12 09:46:58 +02:00
let xpNeeded = RdDItemCompetence . getCompetenceNextXp ( compData . system . niveau + 1 ) ;
2021-01-14 15:29:47 +01:00
if ( newXP >= xpNeeded ) {
2022-06-12 08:17:59 +02:00
let newCompData = duplicate ( compData ) ;
2022-06-12 09:46:58 +02:00
newCompData . system . niveau += 1 ;
newCompData . system . xp = newXP ;
2021-05-27 19:40:45 +02:00
let checkXp = {
2021-01-09 19:33:19 +01:00
alias : this . name ,
2021-04-20 00:52:06 +02:00
competence : newCompData . name ,
2022-06-12 09:46:58 +02:00
niveau : newCompData . system . niveau ,
xp : newCompData . system . xp ,
archetype : newCompData . system . niveau _archetype ,
archetypeWarning : newCompData . system . niveau > compData . system . niveau _archetype
2021-01-03 18:19:18 +01:00
}
2021-05-27 19:40:45 +02:00
if ( display ) {
2021-10-07 22:41:22 +02:00
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( this . name ) ,
2021-05-27 19:40:45 +02:00
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.html ` , checkXp )
} ) ;
}
return checkXp ;
2021-01-03 18:19:18 +01:00
}
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2022-09-07 00:09:17 +02:00
async appliquerAjoutExperience ( rollData , hideChatMessage = 'show' ) {
2021-01-05 18:43:13 +01:00
if ( ! this . isPersonnage ( ) ) return ;
2022-09-07 00:09:17 +02:00
hideChatMessage = hideChatMessage == 'hide' || ( game . settings . get ( "core" , "rollMode" ) != 'blindroll' && ! game . user . isGM )
2021-05-27 19:40:45 +02:00
let xpData = await this . _appliquerExperience ( rollData . rolled , rollData . selectedCarac . label , rollData . competence ) ;
2022-09-07 00:09:17 +02:00
if ( xpData && ! hideChatMessage ) {
2021-10-07 22:41:22 +02:00
ChatMessage . create ( {
2021-09-03 22:05:37 +02:00
whisper : ChatUtility . getWhisperRecipientsAndGMs ( this . name ) ,
2021-05-27 19:40:45 +02:00
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-actor-gain-xp.html ` , xpData )
2021-10-07 22:41:22 +02:00
} ) ;
2020-12-14 10:38:43 +01:00
}
2021-03-15 00:05:56 +01:00
}
2021-02-09 23:23:40 +01:00
/* -------------------------------------------- */
2021-06-30 01:02:01 +02:00
async _appliquerAppelMoral ( rollData ) {
2021-02-09 23:23:40 +01:00
if ( ! this . isPersonnage ( ) ) return ;
2021-03-18 00:41:26 +01:00
if ( ! rollData . useMoral ) return ;
if ( rollData . rolled . isEchec ||
( rollData . ajustements . diviseurSignificative && ( rollData . rolled . roll * rollData . ajustements . diviseurSignificative > rollData . score ) ) ) {
2021-03-19 22:20:01 +01:00
rollData . perteMoralEchec = rollData . moral <= - 3 ? 'dissolution' : 'perte' ;
2021-03-18 00:41:26 +01:00
rollData . moral = await this . moralIncDec ( - 1 ) ; /* L'appel au moral a échoué. Le personnage perd un point de moral */
2021-03-15 00:10:29 +01:00
}
2020-12-06 23:31:23 +01:00
}
2021-02-02 07:56:45 +01:00
/* -------------------------------------------- */
filterSortList ( sortList , coord ) {
2021-02-11 02:48:27 +01:00
let tmr = TMRUtility . getTMR ( coord ) ;
2021-02-02 07:56:45 +01:00
let letfilteredList = [ ]
2021-02-11 02:48:27 +01:00
for ( let sort of sortList ) {
2022-06-12 12:14:55 +02:00
if ( sort . system . caseTMR . toLowerCase ( ) . includes ( 'variable' ) ) {
2021-02-11 02:48:27 +01:00
letfilteredList . push ( sort ) ;
2022-06-12 12:14:55 +02:00
} else if ( sort . system . caseTMRspeciale . toLowerCase ( ) . includes ( 'variable' ) ) {
2021-02-11 02:48:27 +01:00
letfilteredList . push ( sort ) ;
2022-06-12 12:14:55 +02:00
} else if ( sort . system . caseTMR . toLowerCase ( ) == tmr . type ) {
2021-02-11 02:48:27 +01:00
letfilteredList . push ( sort ) ;
2022-06-12 12:14:55 +02:00
} else if ( sort . system . caseTMR . toLowerCase ( ) . includes ( 'special' ) && sort . system . caseTMRspeciale . toLowerCase ( ) . includes ( coord . toLowerCase ( ) ) ) {
2021-02-11 02:48:27 +01:00
letfilteredList . push ( sort ) ;
2021-02-02 07:56:45 +01:00
}
}
return letfilteredList ;
}
/* -------------------------------------------- */
2021-04-24 00:50:20 +02:00
computeDraconicAndSortIndex ( sortList ) {
2021-06-04 01:44:31 +02:00
let draconicList = this . getDraconicList ( )
. map ( it => {
2022-06-12 09:46:58 +02:00
it = duplicate ( it )
2022-06-12 12:14:55 +02:00
it . system . defaut _carac = "reve" ;
2021-06-04 01:44:31 +02:00
return it ;
2021-06-26 00:55:54 +02:00
} ) ;
2021-02-11 02:48:27 +01:00
for ( let sort of sortList ) {
2021-04-24 00:50:20 +02:00
let draconicsSort = this . getDraconicsSort ( draconicList , sort ) . map ( it => it . name ) ;
2022-06-12 09:46:58 +02:00
for ( let index = 0 ; index < draconicList . length && sort . system . listIndex == undefined ; index ++ ) {
2021-05-04 15:17:26 +02:00
if ( draconicsSort . includes ( draconicList [ index ] . name ) ) {
2022-06-12 09:46:58 +02:00
sort . system . listIndex = index ;
2021-04-24 00:50:20 +02:00
}
2021-02-02 07:56:45 +01:00
}
}
2021-04-24 00:50:20 +02:00
return draconicList ;
}
2021-05-01 19:12:55 +02:00
/* -------------------------------------------- */
2021-04-24 00:50:20 +02:00
getDraconicsSort ( draconicList , sort ) {
//console.log(draconicList, bestDraconic, draconic, voie);
switch ( Grammar . toLowerCaseNoAccent ( sort . name ) ) {
case "lecture d'aura" :
case "detection d'aura" :
return draconicList ;
case "annulation de magie" :
2022-06-12 09:46:58 +02:00
return draconicList . filter ( it => ! Grammar . toLowerCaseNoAccent ( it . name ) . includes ( 'thanatos' ) ) ;
2021-04-24 00:50:20 +02:00
}
2022-06-12 12:14:55 +02:00
return [ RdDItemCompetence . getVoieDraconic ( draconicList , sort . system . draconic ) ] ;
2021-02-02 07:56:45 +01:00
}
2020-12-08 23:07:41 +01:00
/* -------------------------------------------- */
async rollUnSort ( coord ) {
let sortList = duplicate ( this . getSortList ( ) ) ; // Duplication car les pts de reve sont modifiés dans le sort
2021-01-09 19:33:19 +01:00
if ( ! sortList || sortList . length == 0 ) {
2020-12-08 23:07:41 +01:00
ui . notifications . info ( "Aucun sort disponible!" ) ;
return ;
}
2021-02-02 07:56:45 +01:00
sortList = this . filterSortList ( sortList , coord ) ;
if ( ! sortList || sortList . length == 0 ) {
ui . notifications . info ( "Aucun sort disponible pour cette case !" ) ;
return ;
}
2021-02-12 18:31:49 +01:00
if ( EffetsDraconiques . isSortImpossible ( this ) ) {
ui . notifications . error ( "Une queue ou un souffle vous empèche de lancer de sort!" ) ;
2021-02-12 01:44:27 +01:00
return ;
}
2021-01-09 19:33:19 +01:00
if ( this . currentTMR ) this . currentTMR . minimize ( ) ; // Hide
2021-04-24 00:50:20 +02:00
let draconicList = this . computeDraconicAndSortIndex ( sortList ) ;
2022-06-12 09:46:58 +02:00
const reve = duplicate ( this . system . carac . reve ) ;
2021-01-09 19:33:19 +01:00
let rollData = {
2021-05-10 18:39:35 +02:00
carac : { 'reve' : reve } ,
forceCarac : { 'reve' : reve } ,
selectedCarac : reve ,
2021-02-02 07:56:45 +01:00
draconicList : draconicList ,
2021-02-11 02:48:27 +01:00
competence : draconicList [ 0 ] ,
2021-06-04 01:44:31 +02:00
sortList : sortList ,
2020-12-08 23:07:41 +01:00
selectedSort : sortList [ 0 ] ,
2021-02-06 02:29:58 +01:00
tmr : TMRUtility . getTMR ( coord ) ,
2021-03-29 18:08:18 +02:00
diffLibre : RdDItemSort . getDifficulte ( sortList [ 0 ] , - 7 ) , // Per default at startup
2021-03-22 20:10:37 +01:00
coutreve : Array ( 30 ) . fill ( ) . map ( ( item , index ) => 1 + index ) ,
2020-12-08 23:07:41 +01:00
}
const dialog = await RdDRoll . create ( this , rollData ,
2021-02-11 02:48:27 +01:00
{
html : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html' ,
2021-04-24 00:50:20 +02:00
options : { height : 600 } ,
2020-12-28 10:17:40 +01:00
close : html => { this . currentTMR . maximize ( ) } // Re-display TMR
} ,
2020-12-08 23:07:41 +01:00
{
name : 'lancer-un-sort' ,
label : 'Lancer un sort' ,
callbacks : [
2020-12-12 21:58:44 +01:00
this . createCallbackExperience ( ) ,
2021-04-24 00:50:20 +02:00
{ action : r => this . _rollUnSortResult ( r ) }
2020-12-08 23:07:41 +01:00
]
2021-04-24 00:50:20 +02:00
}
2020-12-08 23:07:41 +01:00
) ;
dialog . render ( true ) ;
}
2020-12-30 15:18:58 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
isRencontreSpeciale ( ) { // Gestion queue/souffle 'Mauvaise Rencontre en Perpective'
2020-12-30 16:33:56 +01:00
let addMsg = "" ;
2022-04-23 01:02:03 +02:00
let rencSpecial = EffetsDraconiques . mauvaiseRencontre ( this ) ;
2021-01-09 19:33:19 +01:00
if ( rencSpecial ) {
2021-02-06 01:34:49 +01:00
if ( rencSpecial . type != 'souffle' ) {
2022-04-23 01:02:03 +02:00
this . deleteEmbeddedDocuments ( 'Item' , [ rencSpecial . id ] ) ; // Suppression dans la liste des queues
2020-12-30 16:33:56 +01:00
addMsg = " La queue a été supprimée de votre fiche automatiquement" ;
} else {
2022-04-23 01:02:03 +02:00
addMsg = " Vous devez gérer manuellement le décompte de mauvaises rencontres." ;
2021-01-09 19:33:19 +01:00
}
ChatMessage . create ( {
2020-12-30 16:33:56 +01:00
content : "Vous êtes sous le coup d'une Mauvaise Rencontre en Persective." + addMsg ,
2021-01-09 19:33:19 +01:00
whisper : ChatMessage . getWhisperRecipients ( game . user . name )
} ) ;
2020-12-30 15:18:58 +01:00
}
return rencSpecial ;
}
2020-12-30 15:31:43 +01:00
/* -------------------------------------------- */
getTMRFatigue ( ) { // Pour l'instant uniquement Inertie Draconique
2021-02-11 02:48:27 +01:00
let countInertieDraconique = EffetsDraconiques . countInertieDraconique ( this ) ;
if ( countInertieDraconique > 0 ) {
2021-01-09 19:33:19 +01:00
ChatMessage . create ( {
2021-02-12 18:31:49 +01:00
content : ` Vous êtes sous le coup d'Inertie Draconique : vous perdrez ${ countInertieDraconique + 1 } cases de Fatigue par déplacement au lieu d'une. ` ,
2021-01-09 19:33:19 +01:00
whisper : ChatMessage . getWhisperRecipients ( game . user . name )
} ) ;
2020-12-30 15:31:43 +01:00
}
2021-02-06 01:34:49 +01:00
return countInertieDraconique + 1 ;
2020-12-30 16:49:07 +01:00
}
2020-12-30 16:57:47 +01:00
/* -------------------------------------------- */
2021-02-12 18:31:49 +01:00
async checkSoufflePeage ( tmr ) {
2022-06-12 12:14:55 +02:00
if ( ( tmr . type == 'pont' || tmr . type == 'cite' ) && EffetsDraconiques . isPeage ( this ) ) {
2021-01-09 19:33:19 +01:00
await this . reveActuelIncDec ( - 1 ) ;
ChatMessage . create ( {
2021-02-11 02:48:27 +01:00
content : "Vous êtes sous le coup d'un Péage : l'entrée sur cette case vous a coûté 1 Point de Rêve (déduit automatiquement)." ,
2021-01-09 19:33:19 +01:00
whisper : ChatMessage . getWhisperRecipients ( game . user . name )
} ) ;
2020-12-30 16:33:56 +01:00
}
}
2020-12-17 09:29:09 +01:00
/* -------------------------------------------- */
2021-04-24 00:50:20 +02:00
async _rollUnSortResult ( rollData ) {
2020-12-08 23:07:41 +01:00
let rolled = rollData . rolled ;
2020-12-31 02:20:52 +01:00
let selectedSort = rollData . selectedSort ;
2022-06-12 12:14:55 +02:00
rollData . isSortReserve = rollData . mettreEnReserve && ! selectedSort . system . isrituel ;
2020-12-31 02:20:52 +01:00
rollData . show = { }
2022-06-12 12:14:55 +02:00
rollData . depenseReve = Number ( selectedSort . system . ptreve _reel ) ;
2020-12-11 20:37:00 +01:00
2021-06-01 00:01:41 +02:00
if ( rollData . competence . name . includes ( 'Thanatos' ) ) { // Si Thanatos
2022-06-12 19:40:44 +02:00
await this . update ( { "system.reve.reve.thanatosused" : true } ) ;
2021-06-01 00:01:41 +02:00
}
2022-06-12 09:46:58 +02:00
let reveActuel = this . system . reve . reve . value ;
2020-12-08 23:07:41 +01:00
if ( rolled . isSuccess ) { // Réussite du sort !
if ( rolled . isPart ) {
2020-12-31 02:20:52 +01:00
rollData . depenseReve = Math . max ( Math . floor ( rollData . depenseReve / 2 ) , 1 ) ;
2020-12-08 23:07:41 +01:00
}
if ( rollData . isSortReserve ) {
2020-12-31 02:20:52 +01:00
rollData . depenseReve ++ ;
2020-12-08 23:07:41 +01:00
}
2021-03-22 20:10:37 +01:00
if ( reveActuel > rollData . depenseReve ) {
2020-12-08 23:07:41 +01:00
// Incrémenter/gére le bonus de case
2021-02-11 02:48:27 +01:00
RdDItemSort . incrementBonusCase ( this , selectedSort , rollData . tmr . coord ) ;
2021-01-09 19:33:19 +01:00
2020-12-08 23:07:41 +01:00
if ( rollData . isSortReserve ) {
2022-09-17 16:07:38 +02:00
await this . sortMisEnReserve ( selectedSort , rollData . competence , rollData . tmr . coord , Number ( selectedSort . system . ptreve _reel ) ) ;
2020-12-08 23:07:41 +01:00
}
}
else {
2020-12-31 02:20:52 +01:00
rollData . depenseReve = 0 ;
rollData . show . reveInsuffisant = true ;
2021-01-09 19:33:19 +01:00
mergeObject ( rollData . rolled , RdDResolutionTable . getResultat ( "echec" ) , { overwrite : true } ) ;
2020-12-08 23:07:41 +01:00
}
} else {
if ( rolled . isETotal ) { // Echec total !
2021-03-22 20:10:37 +01:00
rollData . depenseReve = Math . min ( reveActuel , Math . floor ( rollData . depenseReve * 1.5 ) )
2020-12-08 23:07:41 +01:00
// TODO: mise en réserve d'un échec total...
2022-09-17 16:07:38 +02:00
// await dialog mse en réserve, pour traitement échec total
2020-12-08 23:07:41 +01:00
} else {
2020-12-31 02:20:52 +01:00
rollData . depenseReve = 0
2020-12-08 23:07:41 +01:00
}
}
2021-03-22 20:10:37 +01:00
reveActuel = Math . max ( reveActuel - rollData . depenseReve , 0 ) ;
2022-06-12 19:40:44 +02:00
await this . update ( { "system.reve.reve.value" : reveActuel } ) ;
2021-01-09 19:33:19 +01:00
2021-04-24 00:50:20 +02:00
if ( rollData . isSortReserve ) {
2020-12-08 23:07:41 +01:00
this . currentTMR . maximize ( ) ; // Re-display TMR
2021-04-24 00:50:20 +02:00
} else {
this . currentTMR . close ( ) ; // Close TMR !
2020-12-08 23:07:41 +01:00
}
// Final chat message
2022-01-29 18:50:37 +01:00
await RdDResolutionTable . displayRollData ( rollData , this , 'chat-resultat-sort.html' ) ;
2020-12-31 02:20:52 +01:00
2021-03-22 20:10:37 +01:00
if ( reveActuel == 0 ) { // 0 points de reve
2020-12-31 02:20:52 +01:00
ChatMessage . create ( { content : this . name + " est réduit à 0 Points de Rêve, et tombe endormi !" } ) ;
closeTMR = true ;
}
2020-12-08 23:07:41 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async rollCarac ( caracName ) {
2021-01-02 14:10:43 +01:00
let rollData = { selectedCarac : this . getCaracByName ( caracName ) } ;
2020-12-06 23:31:23 +01:00
const dialog = await RdDRoll . create ( this , rollData ,
2021-01-09 19:33:19 +01:00
{ html : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html' } ,
2020-12-06 23:31:23 +01:00
{
2021-01-09 19:33:19 +01:00
name : 'jet-' + caracName ,
2020-12-08 03:04:00 +01:00
label : 'Jet ' + Grammar . apostrophe ( 'de' , rollData . selectedCarac . label ) ,
2020-12-06 23:31:23 +01:00
callbacks : [
2020-12-12 21:58:44 +01:00
this . createCallbackExperience ( ) ,
2021-03-15 00:10:29 +01:00
this . createCallbackAppelAuMoral ( ) ,
2021-01-05 18:43:13 +01:00
{ action : r => this . _onRollCaracResult ( r ) }
2020-12-06 23:31:23 +01:00
]
}
) ;
dialog . render ( true ) ;
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-01-02 04:28:43 +01:00
async _onRollCaracResult ( rollData ) {
2020-12-06 23:31:23 +01:00
// Final chat message
2022-01-29 18:50:37 +01:00
await RdDResolutionTable . displayRollData ( rollData , this , 'chat-resultat-general.html' ) ;
2020-12-06 18:41:54 +01:00
}
2021-12-05 01:50:09 +01:00
async rollCaracCompetence ( caracName , compName , diff , options = { title : "" , apprecier : false } ) {
2021-03-25 00:14:56 +01:00
const carac = this . getCaracByName ( caracName ) ;
if ( ! carac ) {
ui . notifications . warn ( ` ${ this . name } n'a pas de caractéristique correspondant à ${ caracName } ` )
return ;
}
2022-06-12 09:46:58 +02:00
const competence = this . getCompetence ( compName ) ;
2021-12-05 01:50:09 +01:00
if ( options . apprecier && competence ) {
2022-06-12 09:46:58 +02:00
const minQualite = Math . max ( 0 , competence . system . niveau ) ;
2021-11-10 22:49:01 +01:00
if ( diff <= minQualite ) {
2022-06-12 09:46:58 +02:00
ui . notifications . info ( ` ${ this . name } a un niveau ${ competence . system . niveau } en ${ competence . name } , trop élevé pour apprécier la qualité de ${ diff } ` )
2021-11-10 22:49:01 +01:00
return ;
}
2021-03-25 00:14:56 +01:00
}
let rollData = {
alias : this . name ,
caracValue : Number ( carac . value ) ,
selectedCarac : carac ,
competence : competence ,
diffLibre : diff ,
2021-04-06 23:44:57 +02:00
show : { title : options ? . title ? ? '' }
2021-03-25 00:14:56 +01:00
} ;
2021-11-10 23:12:00 +01:00
RollDataAjustements . calcul ( rollData , this ) ;
2021-03-25 00:14:56 +01:00
await RdDResolutionTable . rollData ( rollData ) ;
2021-04-20 00:52:25 +02:00
this . _appliquerExperienceRollData ( rollData ) ;
2022-01-29 18:50:37 +01:00
await RdDResolutionTable . displayRollData ( rollData , this )
2021-04-06 23:44:57 +02:00
return rollData . rolled ;
2021-03-25 00:14:56 +01:00
}
2021-05-10 19:18:11 +02:00
2021-04-20 00:52:25 +02:00
/* -------------------------------------------- */
_appliquerExperienceRollData ( rollData ) {
const callback = this . createCallbackExperience ( ) ;
2021-05-20 02:44:34 +02:00
if ( callback . condition ( rollData ) ) {
callback . action ( rollData ) ;
}
2021-04-20 00:52:25 +02:00
}
2021-03-25 00:14:56 +01:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-11-23 02:04:00 +01:00
async rollCompetence ( idOrName ) {
2022-06-12 09:46:58 +02:00
let rollData = { competence : this . getCompetence ( idOrName ) }
2021-02-11 02:48:27 +01:00
2020-12-08 03:04:00 +01:00
if ( rollData . competence . type == 'competencecreature' ) {
2022-06-12 09:46:58 +02:00
if ( rollData . competence . system . iscombat ) {
if ( rollData . competence . system . ispossession ) {
2022-07-02 01:41:55 +02:00
RdDPossession . onAttaquePossession ( this , rollData . competence )
2022-06-12 08:17:59 +02:00
} else {
2022-07-03 15:32:20 +02:00
const arme = RdDItemCompetenceCreature . toActionArme ( rollData . competence )
2022-06-12 08:17:59 +02:00
RdDCombat . createUsingTarget ( this ) ? . attaque ( competence , arme )
}
return
2021-01-19 23:39:35 +01:00
}
2020-12-08 03:04:00 +01:00
// Fake competence pour créature
2022-06-12 08:17:59 +02:00
RdDItemCompetenceCreature . setRollDataCreature ( rollData )
} else {
rollData . carac = this . system . carac
2020-12-08 03:04:00 +01:00
}
2020-12-12 21:58:44 +01:00
console . log ( "rollCompetence !!!" , rollData ) ;
2020-12-08 03:04:00 +01:00
2021-10-30 01:34:57 +02:00
const dialog = await RdDRoll . create ( this , rollData , { html : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' } , {
2021-01-09 19:33:19 +01:00
name : 'jet-competence' ,
2021-11-23 02:04:00 +01:00
label : 'Jet ' + Grammar . apostrophe ( 'de' , rollData . competence . name ) ,
2021-01-09 19:33:19 +01:00
callbacks : [
this . createCallbackExperience ( ) ,
2021-03-15 00:10:29 +01:00
this . createCallbackAppelAuMoral ( ) ,
2021-01-09 19:33:19 +01:00
{ action : r => this . _competenceResult ( r ) }
]
2022-06-12 08:17:59 +02:00
} ) ;
dialog . render ( true ) ;
}
/* -------------------------------------------- */
conjurerPossession ( possession ) {
2022-07-02 01:41:55 +02:00
let draconic = this . getDraconicOuPossession ( ) ;
RdDPossession . onAttaquePossession ( this , draconic , possession )
2021-01-09 19:33:19 +01:00
}
2021-05-11 21:45:43 +02:00
2021-05-10 19:18:11 +02:00
/* -------------------------------------------- */
async _competenceResult ( rollData ) {
2022-01-29 18:50:37 +01:00
await RdDResolutionTable . displayRollData ( rollData , this , 'chat-resultat-competence.html' )
2021-05-10 19:18:11 +02:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-05-04 15:18:32 +02:00
async creerTacheDepuisLivre ( item , options = { renderSheet : true } ) {
2022-09-07 18:47:56 +02:00
const nomTache = "Lire " + item . name ;
2021-05-04 15:18:32 +02:00
const filterTacheLecture = it => it . type == 'tache' && it . name == nomTache ;
let tachesExistantes = this . filterItems ( filterTacheLecture ) ;
if ( tachesExistantes . length == 0 ) {
const tache = {
name : nomTache , type : 'tache' ,
2022-06-12 13:58:55 +02:00
system : {
2021-05-04 15:18:32 +02:00
carac : 'intellect' ,
competence : 'Ecriture' ,
2022-09-07 18:47:56 +02:00
difficulte : item . system . difficulte ,
2021-05-04 15:18:32 +02:00
periodicite : "60 minutes" ,
fatigue : 2 ,
2022-09-07 18:47:56 +02:00
points _de _tache : item . system . points _de _tache ,
2021-05-04 15:18:32 +02:00
points _de _tache _courant : 0 ,
2022-09-07 18:47:56 +02:00
description : "Lecture du livre " + item . name + " - XP : " + item . system . xp + " - Compétences : " + item . system . competence
2021-05-04 15:18:32 +02:00
}
2021-01-09 19:33:19 +01:00
}
2021-05-04 15:18:32 +02:00
await this . createEmbeddedDocuments ( 'Item' , [ tache ] , options ) ;
tachesExistantes = this . filterItems ( filterTacheLecture ) ;
2021-01-09 19:33:19 +01:00
}
2021-05-04 15:18:32 +02:00
return tachesExistantes . length > 0 ? tachesExistantes [ 0 ] : undefined ;
2021-01-09 19:33:19 +01:00
}
/* -------------------------------------------- */
async rollTache ( id ) {
2022-06-12 09:46:58 +02:00
const tacheData = this . getTache ( id )
const compData = this . getCompetence ( tacheData . system . competence )
compData . system . defaut _carac = tacheData . system . carac ; // Patch !
2021-03-29 18:08:18 +02:00
2020-12-15 08:37:52 +01:00
let rollData = {
2021-03-29 18:08:18 +02:00
competence : compData ,
tache : tacheData ,
2022-06-12 09:46:58 +02:00
diffLibre : tacheData . system . difficulte ,
2021-05-27 01:13:42 +02:00
diffConditions : 0 ,
use : { libre : false , conditions : true } ,
2021-01-09 19:33:19 +01:00
carac : { }
2021-01-02 14:10:43 +01:00
} ;
2022-06-12 09:46:58 +02:00
rollData . carac [ tacheData . system . carac ] = duplicate ( this . system . carac [ tacheData . system . carac ] ) ; // Single carac
2021-01-02 14:10:43 +01:00
console . log ( "rollTache !!!" , rollData ) ;
2020-12-15 08:37:52 +01:00
2021-10-30 01:34:57 +02:00
const dialog = await RdDRoll . create ( this , rollData , { html : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' } , {
2021-01-09 19:33:19 +01:00
name : 'jet-competence' ,
2021-03-29 18:08:18 +02:00
label : 'Jet de Tâche ' + tacheData . name ,
2021-01-09 19:33:19 +01:00
callbacks : [
this . createCallbackExperience ( ) ,
2021-03-15 00:10:29 +01:00
this . createCallbackAppelAuMoral ( ) ,
2021-01-09 19:33:19 +01:00
{ action : r => this . _tacheResult ( r ) }
]
} ) ;
2022-06-12 08:17:59 +02:00
dialog . render ( true ) ;
2020-12-15 08:37:52 +01:00
}
/* -------------------------------------------- */
2021-01-01 03:25:48 +01:00
async _tacheResult ( rollData ) {
2020-12-15 21:28:55 +01:00
// Mise à jour de la tache
2022-06-12 08:17:59 +02:00
rollData . appliquerFatigue = ReglesOptionelles . isUsing ( "appliquer-fatigue" ) ;
rollData . tache = duplicate ( rollData . tache ) ;
2022-06-12 09:46:58 +02:00
rollData . tache . system . points _de _tache _courant += rollData . rolled . ptTache ;
2021-05-07 01:47:51 +02:00
if ( rollData . rolled . isETotal ) {
2022-06-12 09:46:58 +02:00
rollData . tache . system . difficulte -- ;
2021-05-04 15:18:32 +02:00
}
2021-10-30 09:16:28 +02:00
if ( rollData . rolled . isSuccess ) {
2022-06-12 09:46:58 +02:00
rollData . tache . system . nb _jet _succes ++ ;
2021-10-30 09:16:28 +02:00
} else {
2022-06-12 09:46:58 +02:00
rollData . tache . system . nb _jet _echec ++ ;
2021-10-30 09:16:28 +02:00
}
2022-06-12 09:46:58 +02:00
rollData . tache . system . tentatives = rollData . tache . system . nb _jet _succes + rollData . tache . system . nb _jet _echec ;
2021-11-23 02:12:23 +01:00
2022-06-12 08:17:59 +02:00
this . updateEmbeddedDocuments ( 'Item' , [ rollData . tache ] ) ;
2022-06-12 09:46:58 +02:00
this . santeIncDec ( "fatigue" , rollData . tache . system . fatigue ) ;
2020-12-15 21:28:55 +01:00
2022-06-12 08:17:59 +02:00
await RdDResolutionTable . displayRollData ( rollData , this , 'chat-resultat-tache.html' ) ;
2020-12-15 08:37:52 +01:00
}
2021-01-27 23:35:45 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
async _rollArt ( artData , selected , oeuvre , callBackResult = r => this . _resultArt ( r ) ) {
2021-04-21 00:59:10 +02:00
mergeObject ( artData ,
{
oeuvre : oeuvre ,
art : oeuvre . type ,
2022-06-12 08:17:59 +02:00
competence : duplicate ( this . getCompetence ( artData . compName ? ? oeuvre . system . competence ? ? artData . art ) ) ,
2022-05-01 23:37:52 +02:00
diffLibre : - ( oeuvre . system . niveau ? ? 0 ) ,
2021-04-21 00:59:10 +02:00
diffConditions : 0 ,
use : { libre : false , conditions : true } ,
2022-04-30 19:15:55 +02:00
selectedCarac : duplicate ( this . system . carac [ selected ] )
2021-04-21 00:59:10 +02:00
} ,
{ overwrite : false } ) ;
2022-07-22 22:53:48 +02:00
artData . competence . system . defaut _carac = selected ;
2021-03-15 00:05:56 +01:00
if ( ! artData . forceCarac ) {
2021-02-14 18:31:00 +01:00
artData . forceCarac = { } ;
2022-04-30 19:15:55 +02:00
artData . forceCarac [ selected ] = duplicate ( this . system . carac [ selected ] ) ;
2021-02-14 18:31:00 +01:00
}
2021-02-06 01:34:01 +01:00
console . log ( "rollArt !!!" , artData ) ;
2021-01-27 23:35:45 +01:00
2021-04-21 22:02:17 +02:00
const dialog = await RdDRoll . create ( this , artData ,
{
html : ` systems/foundryvtt-reve-de-dragon/templates/dialog-roll- ${ oeuvre . type } .html ` ,
options : { height : 500 , }
} ,
{
name : ` jet- ${ artData . art } ` ,
label : ` ${ artData . verbe } ${ oeuvre . name } ` ,
callbacks : [
this . createCallbackExperience ( ) ,
this . createCallbackAppelAuMoral ( ) ,
{ action : r => callBackResult ( r ) }
]
} ) ;
2021-01-27 23:35:45 +01:00
dialog . render ( true ) ;
}
2021-01-31 21:37:41 +01:00
2021-01-27 23:35:45 +01:00
/* -------------------------------------------- */
2021-01-31 21:37:41 +01:00
async _resultArt ( artData ) {
2022-05-01 23:37:52 +02:00
const baseQualite = ( artData . rolled . isSuccess ? artData . oeuvre . system . niveau : artData . competence . system . niveau ) ;
artData . qualiteFinale = Math . min ( baseQualite , artData . oeuvre . system . niveau ) + artData . rolled . ptQualite ;
2021-01-31 21:37:41 +01:00
2022-01-29 18:50:37 +01:00
await RdDResolutionTable . displayRollData ( artData , this . name , ` chat-resultat- ${ artData . art } .html ` ) ;
2021-01-27 23:35:45 +01:00
}
2021-02-06 01:34:01 +01:00
/* -------------------------------------------- */
async rollChant ( id ) {
const artData = { art : 'chant' , verbe : 'Chanter' } ;
const oeuvre = duplicate ( this . getChant ( id ) ) ;
await this . _rollArt ( artData , "ouie" , oeuvre ) ;
}
2021-02-14 18:31:00 +01:00
2021-01-27 23:35:45 +01:00
/* -------------------------------------------- */
2021-01-31 21:37:41 +01:00
async rollDanse ( id ) {
2021-02-14 18:31:00 +01:00
const artData = { art : 'danse' , verbe : 'Danser' , forceCarac : { } } ;
2021-03-29 09:17:00 +02:00
const oeuvre = duplicate ( this . getItemOfType ( id , artData . art ) ) ;
2022-05-01 23:37:52 +02:00
if ( oeuvre . system . agilite ) {
2022-04-30 19:15:55 +02:00
artData . forceCarac [ 'agilite' ] = duplicate ( this . system . carac . agilite ) ;
2021-02-14 18:31:00 +01:00
}
2022-05-01 23:37:52 +02:00
if ( oeuvre . system . apparence ) {
2022-04-30 19:15:55 +02:00
artData . forceCarac [ 'apparence' ] = duplicate ( this . system . carac . apparence ) ;
2021-02-14 18:31:00 +01:00
}
2021-04-21 00:59:10 +02:00
const selectedCarac = this . _getCaracDanse ( oeuvre ) ;
2021-02-06 01:34:01 +01:00
await this . _rollArt ( artData , selectedCarac , oeuvre ) ;
2021-01-31 21:37:41 +01:00
}
2021-01-27 23:35:45 +01:00
2021-02-14 18:31:00 +01:00
/* -------------------------------------------- */
2021-03-15 00:05:56 +01:00
_getCaracDanse ( oeuvre ) {
2022-05-01 23:37:52 +02:00
if ( oeuvre . system . agilite ) { return "agilite" ; }
else if ( oeuvre . system . apparence ) { return "apparence" ; }
2022-06-12 12:14:55 +02:00
const compData = this . getCompetence ( oeuvre . system . competence ) ;
2022-06-12 08:17:59 +02:00
return compData . system . defaut _carac ;
2021-01-31 21:37:41 +01:00
}
2021-01-27 23:35:45 +01:00
2021-01-31 21:37:41 +01:00
/* -------------------------------------------- */
async rollMusique ( id ) {
const artData = { art : 'musique' , verbe : 'Jouer' } ;
2022-06-12 08:17:59 +02:00
const oeuvre = this . getItemOfType ( id , artData . art ) ;
2021-02-06 01:34:01 +01:00
await this . _rollArt ( artData , "ouie" , oeuvre ) ;
2021-01-27 23:35:45 +01:00
}
2021-01-31 21:37:41 +01:00
2021-01-27 23:35:45 +01:00
/* -------------------------------------------- */
2021-01-31 21:37:41 +01:00
async rollRecetteCuisine ( id ) {
2022-06-12 08:17:59 +02:00
const oeuvre = this . getRecetteCuisine ( id ) ;
2021-04-08 20:36:02 +02:00
const artData = {
verbe : 'Cuisiner' ,
2021-04-23 02:47:18 +02:00
compName : 'cuisine' ,
2021-04-08 20:36:02 +02:00
proportions : 1 ,
ajouterEquipement : false
} ;
2021-02-11 02:48:27 +01:00
await this . _rollArt ( artData , 'odoratgout' , oeuvre , r => this . _resultRecetteCuisine ( r ) ) ;
2021-01-31 21:37:41 +01:00
}
2021-02-06 01:34:01 +01:00
/* -------------------------------------------- */
async _resultRecetteCuisine ( artData ) {
2022-05-01 23:37:52 +02:00
const baseQualite = ( artData . rolled . isSuccess ? artData . oeuvre . system . niveau : artData . competence . system . niveau ) ;
const sust = artData . oeuvre . system . sust * artData . proportions ;
artData . qualiteFinale = Math . min ( baseQualite , artData . oeuvre . system . niveau ) + artData . rolled . ptQualite ;
artData . exotismeFinal = Math . min ( Math . min ( artData . qualiteFinale , artData . oeuvre . system . exotisme ? ? 0 ) , 0 ) ;
2022-06-12 19:40:44 +02:00
//console.log("OEUVRE", artData.art, artData)
2021-04-08 20:36:02 +02:00
const platCuisine = {
name : artData . oeuvre . name ,
type : 'nourritureboisson' ,
img : 'systems/foundryvtt-reve-de-dragon/icons/objets/provision_cuite.webp' ,
2022-06-12 19:40:44 +02:00
system : {
2022-05-01 23:37:52 +02:00
"description" : artData . oeuvre . system . description ,
2021-04-08 20:36:02 +02:00
"sust" : Math . min ( sust , 1 ) ,
2021-04-16 00:29:08 +02:00
"qualite" : artData . qualiteFinale ,
"exotisme" : artData . exotismeFinal ,
2021-04-08 20:36:02 +02:00
"encombrement" : 0.1 ,
"quantite" : Math . max ( 1 , Math . floor ( sust ) ) ,
2021-04-16 00:29:08 +02:00
"cout" : Math . max ( artData . qualiteFinale ) * 0.01
2021-04-08 20:36:02 +02:00
}
} ;
2021-04-11 18:43:32 +02:00
if ( artData . ajouterEquipement ) {
2021-04-08 20:36:02 +02:00
await this . createEmbeddedDocuments ( 'Item' , [ platCuisine ] ) ;
2022-05-01 23:37:52 +02:00
ui . notifications . info ( ` ${ platCuisine . system . quantite } rations de ${ platCuisine . name } ont été ajoutés à votre équipement ` ) ;
2021-04-08 20:36:02 +02:00
}
artData . platCuisine = platCuisine ;
2022-01-29 18:50:37 +01:00
await RdDResolutionTable . displayRollData ( artData , this . name , ` chat-resultat- ${ artData . art } .html ` ) ;
2021-02-06 01:34:01 +01:00
}
2021-01-31 21:37:41 +01:00
/* -------------------------------------------- */
async rollJeu ( id ) {
2022-06-12 08:17:59 +02:00
const oeuvre = this . getJeu ( id ) ;
2021-04-21 00:59:10 +02:00
2022-05-01 23:37:52 +02:00
const listCarac = oeuvre . system . caraccomp . toLowerCase ( ) . split ( /[.,:\/-]/ ) . map ( it => it . trim ( ) ) ;
2021-04-21 00:59:10 +02:00
const carac = listCarac . length > 0 ? listCarac [ 0 ] : 'chance'
2021-01-31 21:37:41 +01:00
const artData = {
art : 'jeu' , verbe : 'Jeu' ,
use : { libre : true , conditions : true , } ,
2022-06-12 08:17:59 +02:00
competence : duplicate ( this . getCompetence ( 'jeu' ) ) ,
2021-04-21 00:59:10 +02:00
forceCarac : { }
2021-01-31 21:37:41 +01:00
} ;
2022-04-30 19:15:55 +02:00
listCarac . forEach ( c => artData . forceCarac [ c ] = this . system . carac [ c ] ) ;
2022-05-01 23:37:52 +02:00
artData . competence . system . niveauReel = artData . competence . system . niveau ;
artData . competence . system . niveau = Math . max ( artData . competence . system . niveau , oeuvre . system . base ) ;
2021-04-21 00:59:10 +02:00
await this . _rollArt ( artData , carac , oeuvre ) ;
2021-01-31 21:37:41 +01:00
}
2021-01-27 23:35:45 +01:00
2021-02-06 01:34:01 +01:00
async rollOeuvre ( id ) {
2022-06-12 08:17:59 +02:00
const artData = { art : 'oeuvre' , verbe : 'Interpréter' }
const oeuvre = duplicate ( this . getItemOfType ( id , artData . art ) )
await this . _rollArt ( artData , oeuvre . system . default _carac , oeuvre )
2021-01-27 23:35:45 +01:00
}
2021-01-04 22:03:00 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
async rollMeditation ( id ) {
2022-06-12 08:17:59 +02:00
const meditation = duplicate ( this . getMeditation ( id ) ) ;
const competence = duplicate ( this . getCompetence ( meditation . system . competence ) ) ;
2022-05-01 23:37:52 +02:00
competence . system . defaut _carac = "intellect" ; // Meditation = toujours avec intellect
2021-01-04 22:03:00 +01:00
let meditationData = {
2021-05-18 19:51:12 +02:00
competence : competence ,
meditation : meditation ,
2021-05-10 19:18:11 +02:00
conditionMeditation : { isHeure : false , isVeture : false , isComportement : false , isPurification : false } ,
2021-01-04 22:03:00 +01:00
diffConditions : 0 ,
2021-01-13 03:11:03 +01:00
use : { libre : false , conditions : true , } ,
2022-04-30 19:15:55 +02:00
carac : { "intellect" : this . system . carac . intellect }
2021-01-04 22:03:00 +01:00
} ;
2021-04-21 20:43:03 +02:00
const dialog = await RdDRoll . create ( this , meditationData ,
{
html : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-meditation.html' ,
options : { height : 575 , }
} ,
{
name : 'jet-meditation' ,
label : "Jet de méditation" ,
callbacks : [
this . createCallbackExperience ( ) ,
2021-05-10 18:41:45 +02:00
{ condition : r => r . rolled . isEPart , action : r => this . _meditationEPart ( r ) } ,
2021-04-21 20:43:03 +02:00
{ action : r => this . _meditationResult ( r ) }
]
} ) ;
2021-01-04 22:03:00 +01:00
dialog . render ( true ) ;
}
/* -------------------------------------------- */
2022-06-12 08:17:59 +02:00
async _meditationResult ( meditationRoll ) {
2021-01-09 19:33:19 +01:00
this . santeIncDec ( "fatigue" , 2 ) ;
2022-06-12 08:17:59 +02:00
if ( meditationRoll . rolled . isSuccess ) {
await this . createEmbeddedDocuments ( "Item" , [ RdDItemSigneDraconique . prepareSigneDraconiqueMeditation ( meditationRoll . meditation , meditationRoll . rolled ) ] ) ;
2021-05-10 19:18:11 +02:00
}
2021-01-04 22:03:00 +01:00
2022-06-12 08:17:59 +02:00
await RdDResolutionTable . displayRollData ( meditationRoll , this . name , 'chat-resultat-meditation.html' ) ;
2021-01-04 22:03:00 +01:00
}
2021-01-09 19:33:19 +01:00
2021-01-04 22:03:00 +01:00
/* -------------------------------------------- */
2022-06-12 08:17:59 +02:00
_meditationEPart ( meditationRoll ) {
2022-09-07 09:01:23 +02:00
this . updateEmbeddedDocuments ( 'Item' , [ { _id : meditationRoll . meditation . _id , 'system.malus' : meditationRoll . meditation . system . malus - 1 } ] ) ;
2021-05-10 19:18:11 +02:00
}
/* -------------------------------------------- */
_getSignesDraconiques ( coord ) {
const type = TMRUtility . getTMRType ( coord ) ;
2022-06-12 12:14:55 +02:00
return this . listItemsData ( "signedraconique" ) . filter ( it => it . system . typesTMR . includes ( type ) ) ;
2021-01-04 22:03:00 +01:00
}
2021-01-09 19:33:19 +01:00
2020-12-11 08:29:24 +01:00
/* -------------------------------------------- */
2021-05-10 19:18:11 +02:00
isResonanceSigneDraconique ( coord ) {
return this . _getSignesDraconiques ( coord ) . length > 0 ;
2020-12-08 03:04:00 +01:00
}
2021-05-10 19:18:11 +02:00
/* -------------------------------------------- */
async rollLireSigneDraconique ( coord ) {
if ( ! this . isHautRevant ( ) ) {
ui . notifications . info ( "Seul un haut rêvant peut lire un signe draconique!" ) ;
return ;
}
let signes = this . _getSignesDraconiques ( coord ) ;
if ( signes . length == 0 ) {
ui . notifications . info ( ` Aucun signe draconiques en ${ coord } ! ` ) ;
return ;
}
if ( this . currentTMR ) this . currentTMR . minimize ( ) ; // Hide
let draconicList = this . getDraconicList ( )
2022-09-07 18:47:56 +02:00
. map ( draconic => {
let draconicLecture = duplicate ( draconic ) ;
draconicLecture . system . defaut _carac = "intellect" ;
return draconicLecture ;
} ) ;
2021-05-10 19:18:11 +02:00
2022-04-30 19:15:55 +02:00
const intellect = this . system . carac . intellect ;
2021-05-10 19:18:11 +02:00
let rollData = {
carac : { 'intellect' : intellect } ,
selectedCarac : intellect ,
competence : draconicList [ 0 ] ,
draconicList : draconicList ,
signe : signes [ 0 ] ,
signes : signes ,
tmr : TMRUtility . getTMR ( coord ) ,
2022-06-12 08:17:59 +02:00
diffLibre : signes [ 0 ] . system . difficulte ,
2021-05-10 19:18:11 +02:00
}
const dialog = await RdDRoll . create ( this , rollData ,
{
html : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-signedraconique.html' ,
options : { height : 600 } ,
close : html => { this . currentTMR . maximize ( ) } // Re-display TMR
} ,
{
name : 'lire-signe-draconique' ,
label : 'Lire le signe draconique' ,
callbacks : [
this . createCallbackExperience ( ) ,
{ action : r => this . _rollLireSigneDraconique ( r ) }
]
}
) ;
dialog . render ( true ) ;
}
/* -------------------------------------------- */
async _rollLireSigneDraconique ( rollData ) {
const compData = rollData . competence ;
if ( ! RdDItemCompetence . isDraconic ( compData ) ) {
ui . notifications . error ( ` La compétence ${ compData . name } n'est pas une compétence draconique ` ) ;
return ;
}
rollData . xpSort = RdDItemSigneDraconique . getXpSortSigneDraconique ( rollData . rolled . code , rollData . signe ) ;
if ( rollData . xpSort > 0 ) {
2022-06-12 19:40:44 +02:00
await this . updateEmbeddedDocuments ( "Item" , [ { _id : compData . _id , 'system.xp_sort' : Misc . toInt ( compData . system . xp _sort ) + rollData . xpSort } ] ) ;
2021-06-20 22:01:36 +02:00
await this . updateExperienceLog ( "XP Sort" , rollData . xpSort , "Signe draconique en " + rollData . competence . name ) ;
2021-05-10 19:18:11 +02:00
}
await this . deleteEmbeddedDocuments ( "Item" , [ rollData . signe . _id ] ) ;
2022-01-29 18:50:37 +01:00
await RdDResolutionTable . displayRollData ( rollData , this . name , 'chat-resultat-lecture-signedraconique.html' ) ;
2021-05-10 19:18:11 +02:00
this . currentTMR . close ( ) ;
2021-02-09 23:23:40 +01:00
}
2021-05-07 00:01:07 +02:00
2020-12-06 21:11:30 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
async rollAppelChance ( onSuccess = ( ) => { } , onEchec = ( ) => { } ) {
2021-02-17 11:16:27 +01:00
// Stocke si utilisation de la chance
2021-01-02 14:10:43 +01:00
let rollData = { selectedCarac : this . getCaracByName ( 'chance-actuelle' ) , surprise : '' } ;
2020-12-06 23:31:23 +01:00
const dialog = await RdDRoll . create ( this , rollData ,
2021-01-09 19:33:19 +01:00
{ html : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html' } ,
2020-11-15 02:07:41 +01:00
{
2020-12-06 19:29:10 +01:00
name : 'appelChance' ,
label : 'Appel à la chance' ,
callbacks : [
2020-12-12 21:58:44 +01:00
this . createCallbackExperience ( ) ,
2021-01-07 01:54:38 +01:00
{ action : r => this . _appelChanceResult ( r , onSuccess , onEchec ) } ,
2020-12-06 19:29:10 +01:00
]
2020-11-15 02:07:41 +01:00
}
2021-01-09 19:33:19 +01:00
) ;
dialog . render ( true ) ;
}
/* -------------------------------------------- */
async _appelChanceResult ( rollData , onSuccess = ( ) => { } , onEchec = ( ) => { } ) {
await RdDResolutionTable . displayRollData ( rollData , this , 'chat-resultat-appelchance.html' )
if ( rollData . rolled . isSuccess ) {
2022-01-29 22:49:34 +01:00
await this . setFlag ( SYSTEM _RDD , 'utilisationChance' , true ) ;
2021-01-29 01:02:57 +01:00
await this . chanceActuelleIncDec ( - 1 ) ;
2021-01-09 19:33:19 +01:00
onSuccess ( ) ;
}
else {
onEchec ( ) ;
2020-11-15 02:07:41 +01:00
}
2020-12-06 19:29:10 +01:00
}
2021-01-09 19:33:19 +01:00
2020-12-06 21:11:30 +01:00
/* -------------------------------------------- */
2021-03-30 23:01:09 +02:00
async chanceActuelleIncDec ( value ) {
const chance = Math . min ( this . getChance ( ) , Math . max ( this . getChanceActuel ( ) + value , 0 ) ) ;
2021-03-22 20:10:37 +01:00
await this . updateCompteurValue ( "chance" , chance ) ;
2020-12-06 19:29:10 +01:00
}
2021-01-09 19:33:19 +01:00
2021-01-07 00:29:38 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
async appelDestinee ( onSuccess = ( ) => { } , onEchec = ( ) => { } ) {
2022-04-30 19:15:55 +02:00
let destinee = this . system . compteurs . destinee ? . value ? ? 0 ;
2021-03-22 20:10:37 +01:00
if ( destinee > 0 ) {
2021-01-09 19:33:19 +01:00
ChatMessage . create ( { content : ` <span class="rdd-roll-part"> ${ this . name } a fait appel à la Destinée !</span> ` } ) ;
2021-03-22 20:10:37 +01:00
destinee -- ;
2021-03-25 03:18:27 +01:00
await this . updateCompteurValue ( "destinee" , destinee ) ;
2021-01-07 00:29:38 +01:00
onSuccess ( ) ;
}
else {
onEchec ( ) ;
}
}
2021-10-11 11:09:30 +02:00
/* -------------------------------------------- */
getHeureNaissance ( ) {
if ( this . isCreature ( ) ) {
return 0 ;
}
2022-06-12 08:17:59 +02:00
return this . system . heure ;
2021-10-11 11:09:30 +02:00
}
2020-12-06 21:11:30 +01:00
/* -------------------------------------------- */
2020-12-06 19:29:10 +01:00
ajustementAstrologique ( ) {
2020-12-15 02:20:24 +01:00
if ( this . isCreature ( ) ) {
return 0 ;
}
2020-12-11 03:23:34 +01:00
// selon l'heure de naissance...
2022-06-12 08:17:59 +02:00
return game . system . rdd . calendrier . getAjustementAstrologique ( this . system . heure , this . name )
2020-12-06 19:29:10 +01:00
}
2020-12-13 23:32:16 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
checkDesirLancinant ( ) {
2022-09-07 18:47:56 +02:00
let queue = this . filterItems ( it => it . type == 'queue' || it . type == 'ombre' )
2021-04-01 00:01:10 +02:00
. filter ( it => Grammar . toLowerCaseNoAccent ( it . name ) . includes ( 'desir lancinant' ) ) ;
2020-12-14 10:38:43 +01:00
return ( queue . length > 0 ) ;
}
/* -------------------------------------------- */
2021-05-27 19:40:45 +02:00
async _appliquerExperience ( rolled , caracName , competence ) {
2021-01-31 19:37:21 +01:00
if ( ! this . isPersonnage ( ) ) return ;
2021-05-27 19:40:45 +02:00
// Pas d'XP
if ( ! rolled . isPart || rolled . finalLevel >= 0 ) {
return undefined ;
}
if ( this . checkDesirLancinant ( ) ) {
2020-12-14 10:38:43 +01:00
// Cas de désir lancinant, pas d'expérience sur particulière
2021-05-27 19:40:45 +02:00
ChatMessage . create ( {
content : ` Vous souffrez au moins d'un Désir Lancinant, vous ne pouvez pas gagner d'expérience sur une Particulière tant que le désir n'est pas assouvi ` ,
whisper : ChatMessage . getWhisperRecipients ( game . user . name )
} ) ;
return undefined ;
}
if ( caracName == 'Vie' ) caracName = 'constitution' ;
if ( caracName == 'derobee' ) caracName = 'agilite' ;
if ( caracName == 'reve-actuel' ) caracName = 'reve' ;
let xp = Math . abs ( rolled . finalLevel ) ;
// impair: arrondi inférieur en carac
let xpCarac = competence ? Math . floor ( xp / 2 ) : Math . max ( Math . floor ( xp / 2 ) , 1 ) ;
let xpData = {
alias : this . name ,
caracName : caracName , xpCarac : xpCarac ,
competence : competence , xpCompetence : competence ? xp - xpCarac : 0
} ;
await this . _xpCompetence ( xpData ) ;
await this . _xpCarac ( xpData ) ;
return xpData ;
}
2021-05-28 00:55:22 +02:00
2021-05-27 19:40:45 +02:00
/* -------------------------------------------- */
async _xpCompetence ( xpData ) {
if ( xpData . competence ) {
2022-06-12 08:17:59 +02:00
const newXp = Misc . toInt ( xpData . competence . system . xp ) + xpData . xpCompetence ;
2022-06-12 19:40:44 +02:00
let update = { _id : xpData . competence . _id , 'system.xp' : newXp } ;
2021-05-27 19:40:45 +02:00
await this . updateEmbeddedDocuments ( 'Item' , [ update ] ) ;
xpData . checkComp = await this . checkCompetenceXP ( xpData . competence . name , undefined , false ) ;
2022-09-07 00:09:17 +02:00
this . updateExperienceLog ( "XP" , xpData . xpCompetence , "XP gagné en " + xpData . competence . name ) ;
2021-05-27 19:40:45 +02:00
}
}
2021-05-28 00:55:22 +02:00
2021-05-27 19:40:45 +02:00
/* -------------------------------------------- */
async _xpCarac ( xpData ) {
if ( xpData . xpCarac > 0 ) {
2022-04-30 19:15:55 +02:00
let carac = duplicate ( this . system . carac ) ;
2021-05-27 19:40:45 +02:00
let selectedCarac = RdDActor . _findCaracByName ( carac , xpData . caracName ) ;
if ( ! selectedCarac . derivee ) {
selectedCarac . xp = Misc . toInt ( selectedCarac . xp ) + xpData . xpCarac ;
2022-06-12 19:40:44 +02:00
await this . update ( { "system.carac" : carac } ) ;
2021-05-27 19:40:45 +02:00
xpData . checkCarac = await this . checkCaracXP ( selectedCarac . label , false ) ;
2021-05-27 21:30:42 +02:00
this . updateExperienceLog ( "XP" , xpData . xpCarac , "XP gagné en " + xpData . caracName ) ;
2020-12-15 08:37:52 +01:00
} else {
2021-05-27 19:40:45 +02:00
xpData . caracRepartitionManuelle = true ;
2020-12-13 23:32:16 +01:00
}
}
}
2021-01-09 19:33:19 +01:00
2021-06-01 21:58:40 +02:00
/* -------------------------------------------- */
2022-09-07 18:47:56 +02:00
async resetNombreAstral ( ) {
2021-06-01 21:58:40 +02:00
let toDelete = this . listItemsData ( 'nombreastral' ) ;
const deletions = toDelete . map ( it => it . _id ) ;
await this . deleteEmbeddedDocuments ( "Item" , deletions ) ;
}
2021-06-26 00:55:54 +02:00
2020-12-13 23:11:58 +01:00
/* -------------------------------------------- */
2022-09-07 18:47:56 +02:00
async ajouteNombreAstral ( callData ) {
2020-12-13 23:32:16 +01:00
// Gestion expérience (si existante)
2022-09-07 18:47:56 +02:00
callData . competence = this . getCompetence ( "astrologie" )
callData . selectedCarac = this . system . carac [ "vue" ] ;
this . appliquerAjoutExperience ( callData , 'hide' ) ;
2020-12-13 23:32:16 +01:00
2020-12-13 23:11:58 +01:00
// Ajout du nombre astral
2021-01-09 19:33:19 +01:00
const item = {
2022-09-07 18:47:56 +02:00
name : "Nombre Astral" , type : "nombreastral" , system :
{ value : callData . nbAstral , istrue : callData . isvalid , jourindex : Number ( callData . date ) , jourlabel : game . system . rdd . calendrier . getDateFromIndex ( Number ( callData . date ) ) }
2021-01-09 19:33:19 +01:00
} ;
2021-03-29 23:41:08 +02:00
await this . createEmbeddedDocuments ( "Item" , [ item ] ) ;
2021-01-09 19:33:19 +01:00
2020-12-13 23:11:58 +01:00
// Suppression des anciens nombres astraux
2022-06-12 12:14:55 +02:00
let toDelete = this . listItemsData ( 'nombreastral' ) . filter ( it => it . system . jourindex < game . system . rdd . calendrier . getCurrentDayIndex ( ) ) ;
2021-03-22 20:10:37 +01:00
const deletions = toDelete . map ( it => it . _id ) ;
2021-03-29 23:41:08 +02:00
await this . deleteEmbeddedDocuments ( "Item" , deletions ) ;
2020-12-13 23:11:58 +01:00
// Affichage Dialog
this . astrologieNombresAstraux ( ) ;
2021-01-09 19:33:19 +01:00
}
2020-12-06 19:29:10 +01:00
2020-12-11 08:29:24 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
async astrologieNombresAstraux ( ) {
2020-12-11 08:29:24 +01:00
// Afficher l'interface spéciale
2021-01-09 19:33:19 +01:00
const astrologieDialog = await RdDAstrologieJoueur . create ( this , { } ) ;
2020-12-13 23:11:58 +01:00
astrologieDialog . render ( true ) ;
2020-12-11 08:29:24 +01:00
}
2020-12-06 21:11:30 +01:00
/* -------------------------------------------- */
2021-10-07 22:31:14 +02:00
getCaracByName ( name ) {
switch ( Grammar . toLowerCaseNoAccent ( name ) ) {
2021-05-27 19:40:45 +02:00
case 'reve-actuel' : case 'reve actuel' :
2020-12-06 18:41:54 +01:00
return {
2020-12-31 03:51:53 +01:00
label : 'Rêve actuel' ,
2020-12-06 18:41:54 +01:00
value : this . getReveActuel ( ) ,
2021-01-05 18:43:13 +01:00
type : "number"
2020-12-06 18:41:54 +01:00
} ;
2021-05-27 19:40:45 +02:00
case 'chance-actuelle' : case 'chance-actuelle' :
2020-12-06 18:41:54 +01:00
return {
label : 'Chance actuelle' ,
2020-12-31 03:34:37 +01:00
value : this . getChanceActuel ( ) ,
2021-01-05 18:43:13 +01:00
type : "number"
2020-12-06 18:41:54 +01:00
} ;
2020-11-15 02:07:41 +01:00
}
2022-04-30 19:15:55 +02:00
return RdDActor . _findCaracByName ( this . system . carac , name ) ;
2020-12-31 03:34:37 +01:00
}
2021-02-17 11:16:27 +01:00
/* -------------------------------------------- */
2020-12-31 03:34:37 +01:00
static _findCaracByName ( carac , name ) {
2021-03-25 00:14:56 +01:00
name = Grammar . toLowerCaseNoAccent ( name ) ;
2021-01-09 19:33:19 +01:00
switch ( name ) {
2021-10-07 22:31:14 +02:00
case 'reve-actuel' : case 'reve actuel' :
2020-12-31 03:34:37 +01:00
return carac . reve ;
case 'chance-actuelle' : case 'chance actuelle' :
return carac . chance ;
}
2021-12-05 01:50:09 +01:00
let entry = Misc . findFirstLike ( name , Object . entries ( carac ) , { mapper : it => it [ 1 ] . label , description : 'caractéristique' } ) ;
2022-07-08 01:22:53 +02:00
return entry && entry . length > 0 ? carac [ entry [ 0 ] ] : undefined ;
2020-12-06 18:41:54 +01:00
}
/* -------------------------------------------- */
getSortList ( ) {
2021-04-01 00:01:10 +02:00
return this . listItemsData ( "sort" ) ;
2020-12-06 18:41:54 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
countMonteeLaborieuse ( ) { // Return +1 par queue/ombre/souffle Montée Laborieuse présente
2022-04-23 01:02:03 +02:00
let countMonteeLaborieuse = EffetsDraconiques . countMonteeLaborieuse ( this ) ;
2021-02-11 02:48:27 +01:00
if ( countMonteeLaborieuse > 0 ) {
2021-01-09 19:33:19 +01:00
ChatMessage . create ( {
2021-02-11 02:48:27 +01:00
content : ` Vous êtes sous le coup d'une Montée Laborieuse : vos montées en TMR coûtent ${ countMonteeLaborieuse } Point de Rêve de plus. ` ,
2021-01-09 19:33:19 +01:00
whisper : ChatMessage . getWhisperRecipients ( game . user . name )
} ) ;
2020-12-30 15:56:17 +01:00
}
2021-02-11 02:48:27 +01:00
return countMonteeLaborieuse ;
2020-12-30 15:56:17 +01:00
}
2021-01-23 23:56:43 +01:00
/* -------------------------------------------- */
2022-06-25 17:49:19 +02:00
refreshTMRView ( ) {
2021-02-11 02:48:27 +01:00
if ( this . currentTMR ) {
2022-06-25 17:49:19 +02:00
this . currentTMR . externalRefresh ( ) ;
2021-01-23 23:56:43 +01:00
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async displayTMR ( mode = "normal" ) {
2021-05-28 09:43:15 +02:00
if ( this . tmrApp ) {
ui . notifications . warn ( "Vous êtes déja dans les TMR...." ) ;
return
}
2022-09-17 22:36:43 +02:00
if ( mode != 'visu' && this . getEffect ( STATUSES . StatusDemiReve ) ) {
2021-05-26 16:28:57 +02:00
ui . notifications . warn ( "Le joueur ou le MJ est déja dans les Terres Médianes avec ce personnage ! Visualisation uniquement" ) ;
mode = "visu" ; // bascule le mode en visu automatiquement
2021-05-24 09:39:42 +02:00
}
2022-10-04 23:23:43 +02:00
RdDConfirm . confirmer ( {
bypass : mode == 'visu' ,
settingConfirmer : "confirmation-tmr" ,
content : ` <p>Voulez vous monter dans les TMR en mode ${ mode } ?</p> ` ,
title : 'Confirmer la montée dans les TMR' ,
buttonLabel : 'Monter dans les TMR' ,
onAction : async ( ) => await this . _doDisplayTMR ( mode )
} ) ;
}
2021-05-27 19:40:45 +02:00
2022-10-04 23:23:43 +02:00
async _doDisplayTMR ( mode ) {
2021-01-09 19:33:19 +01:00
let isRapide = mode == "rapide" ;
if ( mode != "visu" ) {
2021-02-11 02:48:27 +01:00
let minReveValue = ( isRapide && ! EffetsDraconiques . isDeplacementAccelere ( this ) ? 3 : 2 ) + this . countMonteeLaborieuse ( ) ;
2021-01-09 19:33:19 +01:00
if ( this . getReveActuel ( ) < minReveValue ) {
ChatMessage . create ( {
2021-02-11 02:48:27 +01:00
content : ` Vous n'avez les ${ minReveValue } Points de Reve nécessaires pour monter dans les Terres Médianes ` ,
2021-01-09 19:33:19 +01:00
whisper : ChatMessage . getWhisperRecipients ( game . user . name )
} ) ;
2020-12-06 18:41:54 +01:00
return ;
2021-01-09 19:33:19 +01:00
}
2022-09-17 22:36:43 +02:00
await this . setEffect ( STATUSES . StatusDemiReve , true ) ;
2020-09-20 19:17:31 +02:00
}
2021-01-09 19:33:19 +01:00
2022-04-30 19:15:55 +02:00
const fatigue = this . system . sante . fatigue . value ;
const endurance = this . system . sante . endurance . max ;
2021-03-22 20:10:37 +01:00
let tmrFormData = {
2021-02-11 02:48:27 +01:00
mode : mode ,
2021-05-08 20:08:56 +02:00
fatigue : RdDUtility . calculFatigueHtml ( fatigue , endurance ) ,
2020-12-06 18:41:54 +01:00
draconic : this . getDraconicList ( ) ,
sort : this . getSortList ( ) ,
2021-05-10 19:18:11 +02:00
signes : this . listItemsData ( "signedraconique" ) ,
2022-04-30 19:15:55 +02:00
caracReve : this . system . carac . reve . value ,
2020-12-06 18:41:54 +01:00
pointsReve : this . getReveActuel ( ) ,
isRapide : isRapide
2021-01-09 19:33:19 +01:00
}
2021-05-28 09:37:22 +02:00
2021-03-22 20:10:37 +01:00
let html = await renderTemplate ( 'systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html' , tmrFormData ) ;
this . currentTMR = await RdDTMRDialog . create ( html , this , tmrFormData ) ;
2020-12-06 18:41:54 +01:00
this . currentTMR . render ( true ) ;
}
2020-12-08 03:04:00 +01:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-05-24 22:12:37 +02:00
rollArme ( arme ) {
2022-06-12 09:46:58 +02:00
let competence = this . getCompetence ( arme . system . competence )
2022-04-30 19:15:55 +02:00
if ( arme || ( competence . type == 'competencecreature' && competence . system . iscombat ) ) {
2022-06-12 09:46:58 +02:00
if ( competence . system . ispossession ) {
2022-07-02 01:41:55 +02:00
RdDPossession . onAttaquePossession ( this , competence ) ;
2021-11-11 09:18:25 +01:00
} else {
2022-06-12 08:17:59 +02:00
RdDCombat . createUsingTarget ( this ) ? . attaque ( competence , arme ) ;
2021-11-11 09:18:25 +01:00
}
2020-12-06 18:41:54 +01:00
} else {
2022-06-12 08:17:59 +02:00
this . rollCompetence ( competence . name ) ;
2020-12-06 18:41:54 +01:00
}
}
2020-12-01 17:36:13 +01:00
2020-12-17 09:29:09 +01:00
/* -------------------------------------------- */
2020-12-06 18:41:54 +01:00
_getTarget ( ) {
2020-12-01 17:36:13 +01:00
if ( game . user . targets && game . user . targets . size == 1 ) {
for ( let target of game . user . targets ) {
return target ;
}
}
return undefined ;
}
2021-01-09 19:33:19 +01:00
2021-02-09 11:17:17 +01:00
/* -------------------------------------------- */
2021-01-14 00:35:55 +01:00
getArmeParade ( armeParadeId ) {
2021-03-30 21:56:18 +02:00
const item = armeParadeId ? this . getEmbeddedDocument ( 'Item' , armeParadeId ) : undefined ;
2022-09-07 18:47:56 +02:00
return RdDItemArme . getArme ( item ) ;
2021-01-14 00:35:55 +01:00
}
2021-02-09 11:17:17 +01:00
/* -------------------------------------------- */
2022-09-07 18:47:56 +02:00
verifierForceMin ( item ) {
if ( item . type == 'arme' && item . system . force > this . system . carac . force . value ) {
2021-03-15 00:05:56 +01:00
ChatMessage . create ( {
2022-09-07 18:47:56 +02:00
content : ` <strong> ${ this . name } s'est équipé(e) de l'arme ${ item . name } , mais n'a pas une force suffisante pour l'utiliser normalement </strong>
( $ { item . system . force } nécessaire pour une Force de $ { this . system . carac . force . value } ) `
2021-03-15 00:05:56 +01:00
} ) ;
2021-02-09 11:17:17 +01:00
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async equiperObjet ( itemID ) {
2022-06-12 08:17:59 +02:00
let item = this . getEmbeddedDocument ( 'Item' , itemID ) ;
2022-06-12 09:46:58 +02:00
if ( item ? . system ) {
const isEquipe = ! item . system . equipe ;
let update = { _id : item . id , "system.equipe" : isEquipe } ;
2021-03-29 23:41:08 +02:00
await this . updateEmbeddedDocuments ( 'Item' , [ update ] ) ;
2020-12-02 14:00:54 +01:00
this . computeEncombrementTotalEtMalusArmure ( ) ; // Mise à jour encombrement
2021-01-29 23:17:18 +01:00
this . computePrixTotalEquipement ( ) ; // Mis à jour du prix total de l'équipement
2021-03-22 20:10:37 +01:00
if ( isEquipe )
2022-06-12 09:46:58 +02:00
this . verifierForceMin ( item ) ;
2020-06-24 00:22:40 +02:00
}
2020-06-23 23:34:12 +02:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-05-11 21:45:43 +02:00
async computeArmure ( attackerRoll ) {
2021-02-11 02:48:27 +01:00
let dmg = ( attackerRoll . dmg . dmgArme ? ? 0 ) + ( attackerRoll . dmg . dmgActor ? ? 0 ) ;
2021-03-22 20:10:37 +01:00
let armeData = attackerRoll . arme ;
2020-06-23 23:34:12 +02:00
let protection = 0 ;
2022-06-12 09:46:58 +02:00
const armures = this . items . filter ( it => it . type == "armure" && it . system . equipe ) ;
2022-09-07 18:47:56 +02:00
for ( const armure of armures ) {
protection += await RdDDice . rollTotal ( armure . system . protection . toString ( ) ) ;
2021-01-19 22:50:02 +01:00
if ( dmg > 0 ) {
2022-09-07 18:47:56 +02:00
this . _deteriorerArmure ( armure , dmg ) ;
2021-01-19 22:50:02 +01:00
dmg = 0 ;
2020-06-23 23:34:12 +02:00
}
}
2022-06-12 09:46:58 +02:00
const penetration = Misc . toInt ( armeData ? . system . penetration ? ? 0 ) ;
2020-12-18 01:10:03 +01:00
protection = Math . max ( protection - penetration , 0 ) ;
2020-12-15 18:36:18 +01:00
protection += this . getProtectionNaturelle ( ) ;
2021-02-17 14:52:50 +01:00
// Gestion des cas particuliers sur la fenêtre d'encaissement
2022-06-12 08:17:59 +02:00
if ( attackerRoll . dmg . encaisserSpecial == "noarmure" ) {
2021-02-17 14:52:50 +01:00
protection = 0 ;
}
2022-06-12 08:17:59 +02:00
if ( attackerRoll . dmg . encaisserSpecial == "chute" ) {
protection = Math . min ( protection , 2 ) ;
2021-02-17 14:52:50 +01:00
}
console . log ( "Final protect" , protection , attackerRoll ) ;
2020-06-23 23:34:12 +02:00
return protection ;
2020-06-07 23:16:29 +02:00
}
2020-11-11 04:21:25 +01:00
2021-02-17 14:52:50 +01:00
/* -------------------------------------------- */
2022-09-07 18:47:56 +02:00
_deteriorerArmure ( armure , dmg ) {
armure = duplicate ( armure ) ;
if ( ! ReglesOptionelles . isUsing ( 'deteriorationArmure' ) || armure . system . protection == '0' ) {
2021-01-25 08:48:03 +01:00
return ;
}
2022-09-07 18:47:56 +02:00
armure . system . deterioration = ( armure . system . deterioration ? ? 0 ) + dmg ;
if ( armure . system . deterioration >= 10 ) {
armure . system . deterioration -= 10 ;
let res = /(\d+)?d(\d+)(\-\d+)?/ . exec ( armure . system . protection ) ;
2022-06-12 08:17:59 +02:00
if ( res ) {
let malus = Misc . toInt ( res [ 3 ] ) - 1 ;
let armure = Misc . toInt ( res [ 2 ] ) ;
2022-07-22 22:53:48 +02:00
if ( armure + malus <= 0 ) {
2022-09-07 18:47:56 +02:00
armure . system . protection = 0 ;
2022-06-12 08:17:59 +02:00
} else {
2022-09-07 18:47:56 +02:00
armure . system . protection = '' + ( res [ 1 ] ? ? '1' ) + 'd' + armure + malus ;
2022-06-12 08:17:59 +02:00
}
2021-01-19 22:50:02 +01:00
}
2022-09-07 18:47:56 +02:00
else if ( /\d+/ . exec ( armure . system . protection ) ) {
armure . system . protection = "1d" + armure . system . protection ;
2021-01-19 22:50:02 +01:00
}
else {
2022-09-07 18:47:56 +02:00
ui . notifications . warn ( ` La valeur d'armure de votre ${ armure . name } est incorrecte ` ) ;
2021-01-19 22:50:02 +01:00
}
2022-09-07 18:47:56 +02:00
ChatMessage . create ( { content : "Votre armure s'est détériorée, elle protège maintenant de " + armure . system . protection } ) ;
2021-01-19 22:50:02 +01:00
}
2022-09-07 18:47:56 +02:00
this . updateEmbeddedDocuments ( 'Item' , [ armure ] ) ;
2021-01-19 22:50:02 +01:00
}
2020-12-27 22:21:08 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
async encaisser ( ) {
2022-09-07 18:47:56 +02:00
let dialogData = { ajustementsEncaissement : RdDUtility . getAjustementsEncaissement ( ) } ;
let html = await renderTemplate ( 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-encaisser.html' , dialogData ) ;
2020-12-27 22:21:08 +01:00
new RdDEncaisser ( html , this ) . render ( true ) ;
}
2020-11-11 04:21:25 +01:00
/* -------------------------------------------- */
2021-01-23 18:36:30 +01:00
async encaisserDommages ( rollData , attacker = undefined , defenderRoll = undefined ) {
2020-12-01 17:36:13 +01:00
if ( attacker && ! await attacker . accorder ( this , 'avant-encaissement' ) ) {
return ;
}
2021-01-10 00:30:37 +01:00
console . log ( "encaisserDommages" , rollData )
2020-12-15 02:20:24 +01:00
2022-06-12 09:46:58 +02:00
let santeOrig = duplicate ( this . system . sante ) ;
2021-05-11 21:45:43 +02:00
let encaissement = await this . jetEncaissement ( rollData ) ;
2021-01-06 16:24:05 +01:00
this . ajouterBlessure ( encaissement ) ; // Will upate the result table
2022-07-22 21:38:15 +02:00
const perteVie = this . isEntite ( )
2021-02-11 02:48:27 +01:00
? { newValue : 0 }
2021-01-19 23:01:14 +01:00
: await this . santeIncDec ( "vie" , - encaissement . vie ) ;
2021-06-30 01:01:24 +02:00
const perteEndurance = await this . santeIncDec ( "endurance" , - encaissement . endurance , encaissement . critiques > 0 ) ;
2021-01-10 02:28:45 +01:00
2020-06-07 23:16:29 +02:00
this . computeEtatGeneral ( ) ;
2021-01-10 02:28:45 +01:00
2021-01-23 18:36:30 +01:00
mergeObject ( encaissement , {
2021-03-22 20:10:37 +01:00
alias : this . name ,
2021-01-23 18:36:30 +01:00
hasPlayerOwner : this . hasPlayerOwner ,
2022-06-12 09:46:58 +02:00
resteEndurance : this . system . sante . endurance . value ,
2021-01-23 18:36:30 +01:00
sonne : perteEndurance . sonne ,
jetEndurance : perteEndurance . jetEndurance ,
endurance : santeOrig . endurance . value - perteEndurance . newValue ,
2022-07-22 21:38:15 +02:00
vie : this . isEntite ( ) ? 0 : ( santeOrig . vie . value - perteVie . newValue ) ,
2021-01-23 18:36:30 +01:00
show : defenderRoll ? . show ? ? { }
} ) ;
2021-01-10 02:28:45 +01:00
2022-01-29 18:50:37 +01:00
await ChatUtility . createChatWithRollMode ( this . name , {
2021-01-10 02:28:45 +01:00
roll : encaissement . roll ,
content : await renderTemplate ( 'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html' , encaissement )
} ) ;
2021-01-09 19:38:24 +01:00
if ( ! encaissement . hasPlayerOwner && encaissement . endurance != 0 ) {
encaissement = duplicate ( encaissement ) ;
encaissement . isGM = true ;
ChatMessage . create ( {
whisper : ChatMessage . getWhisperRecipients ( "GM" ) ,
content : await renderTemplate ( 'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html' , encaissement )
} ) ;
}
2020-06-07 23:16:29 +02:00
}
2020-11-07 21:06:37 +01:00
2021-01-06 16:24:05 +01:00
/* -------------------------------------------- */
2021-05-11 21:45:43 +02:00
async jetEncaissement ( rollData ) {
2021-10-29 22:37:27 +02:00
let formula = "2d10" ;
// Chaque dé fait au minmum la difficulté libre
if ( ReglesOptionelles . isUsing ( 'degat-minimum-malus-libre' ) ) {
2021-12-05 01:50:09 +01:00
if ( rollData . diffLibre < 0 ) {
2021-10-29 22:37:27 +02:00
let valeurMin = Math . abs ( rollData . diffLibre ) ;
2021-12-05 01:50:09 +01:00
formula += "min" + valeurMin ;
2021-10-29 22:37:27 +02:00
}
}
// Chaque dé fait au minmum la difficulté libre
if ( ReglesOptionelles . isUsing ( 'degat-ajout-malus-libre' ) ) {
2021-12-05 01:50:09 +01:00
if ( rollData . diffLibre < 0 ) {
2021-10-29 22:37:27 +02:00
let valeurMin = Math . abs ( rollData . diffLibre ) ;
2021-12-05 01:50:09 +01:00
formula += "+" + valeurMin ;
2021-10-29 22:37:27 +02:00
}
}
2021-10-31 19:10:35 +01:00
2021-12-03 22:53:38 +01:00
let roll = await RdDDice . roll ( formula ) ;
2021-01-06 16:24:05 +01:00
2021-10-31 19:10:35 +01:00
// 1 dé fait au minmum la difficulté libre
if ( ReglesOptionelles . isUsing ( 'degat-minimum-malus-libre-simple' ) ) {
2021-12-05 01:50:09 +01:00
if ( rollData . diffLibre < 0 ) {
2021-10-31 19:10:35 +01:00
let valeurMin = Math . abs ( rollData . diffLibre ) ;
2021-12-05 01:50:09 +01:00
if ( roll . terms [ 0 ] . results [ 0 ] . result < valeurMin ) {
2021-10-31 19:10:35 +01:00
roll . terms [ 0 ] . results [ 0 ] . result = valeurMin ;
} else if ( roll . terms [ 0 ] . results [ 1 ] . result < valeurMin ) {
roll . terms [ 0 ] . results [ 1 ] . result = valeurMin ;
}
roll . _total = roll . terms [ 0 ] . results [ 0 ] . result + roll . terms [ 0 ] . results [ 1 ] . result ;
}
2021-12-05 01:50:09 +01:00
}
2021-05-11 21:45:43 +02:00
const armure = await this . computeArmure ( rollData ) ;
2021-01-09 19:38:24 +01:00
const jetTotal = roll . total + rollData . dmg . total - armure ;
let encaissement = RdDUtility . selectEncaissement ( jetTotal , rollData . dmg . mortalite )
let over20 = Math . max ( jetTotal - 20 , 0 ) ;
encaissement . dmg = rollData . dmg ;
2022-06-12 12:14:55 +02:00
encaissement . dmg . loc = rollData . dmg . loc ? ? await RdDUtility . getLocalisation ( this . type ) ;
2021-01-09 19:38:24 +01:00
encaissement . dmg . loc . label = encaissement . dmg . loc . label ? ? 'Corps;'
2021-01-06 16:24:05 +01:00
encaissement . roll = roll ;
2021-01-09 19:38:24 +01:00
encaissement . armure = armure ;
encaissement . total = jetTotal ;
2021-05-11 21:45:43 +02:00
encaissement . vie = await RdDActor . _evaluatePerte ( encaissement . vie , over20 ) ;
encaissement . endurance = await RdDActor . _evaluatePerte ( encaissement . endurance , over20 ) ;
2022-06-12 12:14:55 +02:00
encaissement . penetration = rollData . arme ? . system . penetration ? ? 0 ;
2021-01-09 19:38:24 +01:00
2021-01-06 16:24:05 +01:00
return encaissement ;
}
2021-05-11 21:45:43 +02:00
/* -------------------------------------------- */
static async _evaluatePerte ( formula , over20 ) {
let perte = new Roll ( formula , { over20 : over20 } ) ;
await perte . evaluate ( { async : true } ) ;
return perte . total ;
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
ajouterBlessure ( encaissement ) {
2022-06-12 09:46:58 +02:00
if ( this . type == 'entite' ) return ; // Une entité n'a pas de blessures
2021-01-09 19:33:19 +01:00
if ( encaissement . legeres + encaissement . graves + encaissement . critiques == 0 ) return ;
2021-01-06 16:24:05 +01:00
2022-06-12 09:46:58 +02:00
const endActuelle = Number ( this . system . sante . endurance . value ) ;
let blessures = duplicate ( this . system . blessures ) ;
2021-01-06 16:24:05 +01:00
let count = encaissement . legeres ;
// Manage blessures
while ( count > 0 ) {
let legere = blessures . legeres . liste . find ( it => ! it . active ) ;
if ( legere ) {
this . _setBlessure ( legere , encaissement ) ;
count -- ;
}
else {
encaissement . graves += count ;
encaissement . legeres -= count ;
break ;
}
}
2021-01-09 19:33:19 +01:00
2021-01-06 16:24:05 +01:00
count = encaissement . graves ;
while ( count > 0 ) {
let grave = blessures . graves . liste . find ( it => ! it . active ) ;
if ( grave ) {
this . _setBlessure ( grave , encaissement ) ;
count -- ;
}
2021-01-09 19:33:19 +01:00
else {
2021-01-06 16:24:05 +01:00
encaissement . critiques += count ;
encaissement . graves -= count ;
2022-03-29 20:34:00 +02:00
encaissement . endurance = endActuelle ;
encaissement . vie = 4 ;
2021-01-06 16:24:05 +01:00
break ;
}
}
2021-01-09 19:33:19 +01:00
2021-01-23 17:50:57 +01:00
count = encaissement . critiques ;
2021-01-09 19:33:19 +01:00
while ( count > 0 ) {
2021-01-06 16:24:05 +01:00
let critique = blessures . critiques . liste [ 0 ] ;
2021-01-09 19:33:19 +01:00
if ( ! critique . active ) {
2021-01-06 16:24:05 +01:00
this . _setBlessure ( critique , encaissement ) ;
count -- ;
} else {
// TODO: status effect dead
2022-09-17 22:36:43 +02:00
this . setEffect ( STATUSES . StatusComma , true ) ;
2021-02-11 02:48:27 +01:00
ChatMessage . create ( {
content : ` <img class="chat-icon" src="icons/svg/skull.svg" alt="charge" />
< strong > $ { this . name } vient de succomber à une seconde blessure critique ! Que les Dragons gardent son Archétype en paix ! < / s t r o n g > `
} ) ;
2021-01-23 17:50:57 +01:00
encaissement . critiques -= count ;
2021-01-24 19:52:02 +01:00
encaissement . mort = true ;
2021-01-06 16:24:05 +01:00
break ;
}
}
encaissement . endurance = Math . max ( encaissement . endurance , - endActuelle ) ;
2022-06-12 19:40:44 +02:00
this . update ( { "system.blessures" : blessures } ) ;
2021-01-06 16:24:05 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-01-06 16:24:05 +01:00
_setBlessure ( blessure , encaissement ) {
blessure . active = true ;
2021-10-29 22:37:27 +02:00
blessure . psdone = false ;
blessure . scdone = false ;
2021-01-06 16:24:05 +01:00
blessure . loc = encaissement . locName ;
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2020-05-21 21:48:20 +02:00
/** @override */
getRollData ( ) {
2022-09-07 18:47:56 +02:00
const rollData = super . getRollData ( ) ;
return rollData ;
2020-05-21 21:48:20 +02:00
}
2021-01-09 19:33:19 +01:00
2021-02-09 09:18:52 +01:00
/* -------------------------------------------- */
2021-03-15 00:05:56 +01:00
async resetItemUse ( ) {
2022-01-29 22:49:34 +01:00
await this . unsetFlag ( SYSTEM _RDD , 'itemUse' ) ;
await this . setFlag ( SYSTEM _RDD , 'itemUse' , { } ) ;
2021-02-09 09:18:52 +01:00
}
2021-02-25 08:48:31 +01:00
/* -------------------------------------------- */
2021-03-15 00:05:56 +01:00
async incDecItemUse ( itemId , inc = 1 ) {
2022-01-29 22:49:34 +01:00
let itemUse = duplicate ( this . getFlag ( SYSTEM _RDD , 'itemUse' ) ? ? { } ) ;
2021-03-14 19:04:35 +01:00
itemUse [ itemId ] = ( itemUse [ itemId ] ? ? 0 ) + inc ;
2022-01-29 22:49:34 +01:00
await this . setFlag ( SYSTEM _RDD , 'itemUse' , itemUse ) ;
2021-03-14 19:04:35 +01:00
console . log ( "ITEM USE INC" , inc , itemUse ) ;
2021-02-09 09:18:52 +01:00
}
/* -------------------------------------------- */
2021-03-15 00:05:56 +01:00
getItemUse ( itemId ) {
2022-01-29 22:49:34 +01:00
let itemUse = this . getFlag ( SYSTEM _RDD , 'itemUse' ) ? ? { } ;
2021-02-09 09:18:52 +01:00
console . log ( "ITEM USE GET" , itemUse ) ;
2021-02-12 01:11:03 +01:00
return itemUse [ itemId ] ? ? 0 ;
2021-02-09 09:18:52 +01:00
}
2021-03-15 00:05:56 +01:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2020-12-01 17:36:13 +01:00
/* -- entites -- */
/* retourne true si on peut continuer, false si on ne peut pas continuer */
2021-01-09 19:33:19 +01:00
async targetEntiteNonAccordee ( target , when = 'avant-encaissement' ) {
if ( target ) {
2020-12-01 17:36:13 +01:00
return ! await this . accorder ( target . actor , when ) ;
}
return false ;
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async accorder ( entite , when = 'avant-encaissement' ) {
2021-11-11 02:43:38 +01:00
if ( when != game . settings . get ( SYSTEM _RDD , "accorder-entite-cauchemar" )
2022-07-22 21:38:15 +02:00
|| ! entite . isEntite ( [ ENTITE _INCARNE ] )
|| entite . isEntiteAccordee ( this ) ) {
2020-12-01 17:36:13 +01:00
return true ;
}
2022-06-12 09:46:58 +02:00
const tplData = this . system ;
let rolled = await RdDResolutionTable . roll ( this . getReveActuel ( ) , - Number ( entite . system . carac . niveau . value ) ) ;
2021-01-02 20:56:31 +01:00
const rollData = {
alias : this . name ,
rolled : rolled ,
entite : entite . name ,
2021-03-29 09:17:00 +02:00
selectedCarac : tplData . carac . reve
2020-12-01 17:36:13 +01:00
} ;
2021-01-09 19:33:19 +01:00
2020-12-01 17:36:13 +01:00
if ( rolled . isSuccess ) {
await entite . setEntiteReveAccordee ( this ) ;
}
2021-01-09 19:33:19 +01:00
2021-01-05 18:43:13 +01:00
await RdDResolutionTable . displayRollData ( rollData , this , 'chat-resultat-accorder-cauchemar.html' ) ;
2021-01-02 20:56:31 +01:00
if ( rolled . isPart ) {
2021-05-27 19:40:45 +02:00
await this . appliquerAjoutExperience ( rollData , true ) ;
2020-12-01 17:36:13 +01:00
}
return rolled . isSuccess ;
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2022-07-22 22:53:48 +02:00
isEntite ( typeentite = [ ] ) {
2022-09-11 16:14:27 +02:00
return this . type == 'entite' && ( typeentite . length == 0 || typeentite . includes ( this . system . definition . typeentite ) ) ;
2020-12-01 17:36:13 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2022-07-22 21:38:15 +02:00
isEntiteAccordee ( attaquant ) {
2022-07-22 22:53:48 +02:00
if ( ! this . isEntite ( [ ENTITE _INCARNE ] ) ) { return true ; }
2022-04-30 19:15:55 +02:00
let resonnance = this . system . sante . resonnance ;
2022-07-22 00:31:27 +02:00
return ( resonnance . actors . find ( it => it == attaquant . id ) ) ;
2020-12-01 17:36:13 +01:00
}
2020-11-14 03:16:03 +01:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async setEntiteReveAccordee ( attaquant ) {
2022-07-22 21:38:15 +02:00
if ( ! this . isEntite ( [ ENTITE _INCARNE ] ) ) {
2020-12-01 17:36:13 +01:00
ui . notifications . error ( "Impossible de s'accorder à " + this . name + ": ce n'est pas une entite de cauchemer/rêve" ) ;
return ;
}
2022-06-12 09:46:58 +02:00
let resonnance = duplicate ( this . system . sante . resonnance ) ;
2022-07-22 00:31:27 +02:00
if ( resonnance . actors . find ( it => it == attaquant . id ) ) {
2020-12-01 17:36:13 +01:00
// déjà accordé
return ;
}
2022-07-22 00:31:27 +02:00
resonnance . actors . push ( attaquant . id ) ;
2022-06-12 12:14:55 +02:00
await this . update ( { "system.sante.resonnance" : resonnance } ) ;
2020-12-01 17:36:13 +01:00
return ;
}
2021-05-07 00:01:07 +02:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-04-15 00:25:40 +02:00
getFortune ( ) {
2022-09-07 18:47:56 +02:00
let monnaies = this . itemTypes [ 'monnaie' ] ;
2021-04-15 00:25:40 +02:00
if ( monnaies . length < 4 ) {
ui . notifications . error ( "Problème de monnaies manquantes, impossible de payer correctement!" )
2022-06-12 08:17:59 +02:00
throw "Problème de monnaies manquantes, impossible de payer correctement!" ;
2021-04-15 00:25:40 +02:00
}
2022-09-07 18:47:56 +02:00
return monnaies . map ( m => Number ( m . system . valeur _deniers ) * Number ( m . system . quantite ) )
2021-04-15 00:25:40 +02:00
. reduce ( Misc . sum ( ) , 0 ) ;
}
2020-12-31 00:55:02 +01:00
2021-04-15 00:25:40 +02:00
/* -------------------------------------------- */
async optimizeArgent ( fortuneTotale ) {
2022-09-07 18:47:56 +02:00
let monnaies = this . itemTypes [ 'monnaie' ] ;
let parValeur = Misc . classifyFirst ( monnaies , it => it . system . valeur _deniers ) ;
2021-04-15 00:25:40 +02:00
let nouvelleFortune = {
1000 : Math . floor ( fortuneTotale / 1000 ) , // or
100 : Math . floor ( fortuneTotale / 100 ) % 10 , // argent
10 : Math . floor ( fortuneTotale / 10 ) % 10 , // bronze
1 : fortuneTotale % 10 // étain
2020-12-31 00:55:02 +01:00
}
2022-07-22 22:53:48 +02:00
console . log ( 'RdDActor.optimizeArgent' , fortuneTotale , 'nouvelleFortune' , nouvelleFortune , 'monnaie_par_valeur' , parValeur ) ;
2022-01-09 14:22:54 +01:00
let updates = [ ] ;
2021-04-15 00:25:40 +02:00
for ( const [ valeur , nombre ] of Object . entries ( nouvelleFortune ) ) {
2022-06-12 19:40:44 +02:00
updates . push ( { _id : parValeur [ valeur ] . id , 'system.quantite' : nombre } ) ;
2020-12-31 00:55:02 +01:00
}
2021-03-29 23:41:08 +02:00
await this . updateEmbeddedDocuments ( 'Item' , updates ) ;
2020-12-31 00:55:02 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-04-15 00:25:40 +02:00
async depenserDeniers ( depense , dataObj = undefined , quantite = 1 , toActorId ) {
depense = Number ( depense ) ;
let fortune = this . getFortune ( ) ;
console . log ( "depenserDeniers" , game . user . character , depense , fortune ) ;
2021-01-01 21:11:56 +01:00
let msg = "" ;
2021-04-15 00:25:40 +02:00
if ( depense == 0 ) {
2021-03-19 22:20:01 +01:00
if ( dataObj ) {
2022-06-12 12:14:55 +02:00
dataObj . payload . system . cout = depense / 100 ; // Mise à jour du prix en sols , avec le prix acheté
dataObj . payload . system . quantite = quantite ;
2021-03-29 09:17:00 +02:00
await this . createEmbeddedDocuments ( 'Item' , [ dataObj . payload ] ) ;
2021-04-15 00:25:40 +02:00
msg += ` <br>L'objet <strong> ${ dataObj . payload . name } </strong> a été ajouté gratuitement à votre inventaire. ` ;
}
}
else {
if ( fortune >= depense ) {
fortune -= depense ;
const toActor = game . actors . get ( toActorId )
2021-05-07 17:27:02 +02:00
await toActor ? . ajouterDeniers ( depense , this . id ) ;
2021-04-15 00:25:40 +02:00
await this . optimizeArgent ( fortune ) ;
msg = ` Vous avez payé <strong> ${ depense } Deniers</strong> ${ toActor ? " à " + toActor . name : '' } , qui ont été soustraits de votre argent. ` ;
RdDAudio . PlayContextAudio ( "argent" ) ; // Petit son
if ( dataObj ) {
2022-06-12 12:14:55 +02:00
dataObj . payload . system . cout = depense / 100 ; // Mise à jour du prix en sols , avec le prix acheté
dataObj . payload . system . quantite = quantite ;
2021-04-15 00:25:40 +02:00
await this . createEmbeddedDocuments ( 'Item' , [ dataObj . payload ] ) ;
msg += ` <br>Et l'objet <strong> ${ dataObj . payload . name } </strong> a été ajouté à votre inventaire. ` ;
}
} else {
msg = "Vous n'avez pas assez d'argent pour payer cette somme !" ;
2021-03-19 22:20:01 +01:00
}
2021-01-01 21:11:56 +01:00
}
2021-01-09 19:33:19 +01:00
let message = {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( this . name ) ,
content : msg
2021-01-01 21:11:56 +01:00
} ;
2021-01-09 19:33:19 +01:00
ChatMessage . create ( message ) ;
2020-12-31 00:55:02 +01:00
}
2021-05-07 17:27:02 +02:00
async depenser ( depense ) {
depense = Number ( depense ) ;
let fortune = this . getFortune ( ) ;
let reste = fortune - depense ;
if ( reste >= 0 ) {
fortune -= depense ;
await this . optimizeArgent ( fortune ) ;
}
return reste ;
}
2021-04-15 00:25:40 +02:00
async ajouterDeniers ( gain , fromActorId = undefined ) {
2021-06-14 23:41:46 +02:00
gain = Number . parseInt ( gain ) ;
2021-06-26 00:55:54 +02:00
if ( gain == 0 ) {
2021-06-14 23:41:46 +02:00
return ;
}
2021-04-15 00:25:40 +02:00
if ( fromActorId && ! game . user . isGM ) {
2022-01-29 18:49:06 +01:00
RdDActor . remoteActorCall ( {
userId : Misc . connectedGMOrUser ( ) ,
actorId : this . id ,
2022-07-22 22:53:48 +02:00
method : 'ajouterDeniers' , args : [ gain , fromActorId ]
} ) ;
2021-04-15 00:25:40 +02:00
}
else {
const fromActor = game . actors . get ( fromActorId )
let fortune = this . getFortune ( ) ;
2021-06-14 23:41:46 +02:00
fortune += gain ;
2021-04-15 00:25:40 +02:00
await this . optimizeArgent ( fortune ) ;
RdDAudio . PlayContextAudio ( "argent" ) ; // Petit son
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( this . name ) ,
2021-05-07 17:27:02 +02:00
content : ` Vous avez reçu <strong> ${ gain } Deniers</strong> ${ fromActor ? " de " + fromActor . name : '' } , qui ont été ajoutés à votre argent. `
2021-04-15 00:25:40 +02:00
} ) ;
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async monnaieIncDec ( id , value ) {
2021-03-29 18:08:18 +02:00
let monnaie = this . getMonnaie ( id ) ;
2021-01-09 19:33:19 +01:00
if ( monnaie ) {
2022-06-12 09:46:58 +02:00
const quantite = Math . max ( 0 , monnaie . system . quantite + value ) ;
2022-06-12 19:40:44 +02:00
await this . updateEmbeddedDocuments ( 'Item' , [ { _id : monnaie . id , 'system.quantite' : quantite } ] ) ;
2020-12-31 00:55:02 +01:00
}
}
2021-05-07 17:27:02 +02:00
/* -------------------------------------------- */
2021-06-05 01:14:29 +02:00
async achatVente ( achat ) {
if ( achat . vendeurId == achat . acheteurId ) {
2021-05-08 03:52:19 +02:00
ui . notifications . info ( "Inutile de se vendre à soi-même" ) ;
return ;
}
2021-11-26 00:45:21 +01:00
if ( ! Misc . isUniqueConnectedGM ( ) ) {
2022-01-29 18:49:06 +01:00
RdDActor . remoteActorCall ( {
actorId : achat . vendeurId ? ? achat . acheteurId ,
method : 'achatVente' ,
2022-07-22 22:53:48 +02:00
args : [ achat ]
} ,
) ;
2021-05-07 17:27:02 +02:00
return ;
}
2021-06-05 01:14:29 +02:00
const acheteur = achat . acheteurId ? game . actors . get ( achat . acheteurId ) : undefined ;
const vendeur = achat . vendeurId ? game . actors . get ( achat . vendeurId ) : undefined ;
const messageVente = game . messages . get ( achat . chatMessageIdVente ) ;
const html = await messageVente . getHTML ( ) ;
const buttonAcheter = html . find ( ".button-acheter" ) [ 0 ] ;
const vente = DialogItemAchat . prepareVenteData ( buttonAcheter , achat . vendeurId , vendeur , acheteur ) ;
const itemId = vente . item . _id ;
2022-09-07 18:47:56 +02:00
const isItemEmpilable = "quantite" in vente . item . system ;
2021-05-07 17:27:02 +02:00
2021-06-05 01:14:29 +02:00
const coutDeniers = Math . floor ( ( achat . prixTotal ? ? 0 ) * 100 ) ;
2021-06-21 23:37:33 +02:00
achat . quantiteTotal = ( achat . choix . nombreLots ? ? 1 ) * ( vente . tailleLot ) ;
2021-05-07 17:27:02 +02:00
if ( acheteur ) {
let resteAcheteur = await acheteur . depenser ( coutDeniers ) ;
if ( resteAcheteur < 0 ) {
2021-12-05 01:50:09 +01:00
ChatUtility . notifyUser ( achat . userId , 'warn' , ` Vous n'avez pas assez d'argent pour payer ${ Math . ceil ( coutDeniers / 100 ) } sols ! ` ) ;
2021-05-07 17:27:02 +02:00
return ;
}
}
2022-06-12 09:46:58 +02:00
const itemVendu = vendeur ? . getObjet ( itemId ) ;
2021-06-08 00:37:35 +02:00
if ( itemVendu ) {
2022-06-12 09:46:58 +02:00
if ( isItemEmpilable ? ( itemVendu . system . quantite < achat . quantiteTotal ) : ( achat . choix . nombreLots != 1 ) ) {
2021-05-07 17:27:02 +02:00
await acheteur ? . ajouterDeniers ( coutDeniers ) ;
2021-10-07 23:52:02 +02:00
ChatUtility . notifyUser ( achat . userId , 'warn' , ` Le vendeur n'a plus assez de ${ vente . item . name } ! ` ) ;
2021-05-07 17:27:02 +02:00
return ;
}
vendeur . ajouterDeniers ( coutDeniers ) ;
2022-06-12 09:46:58 +02:00
let resteQuantite = ( itemVendu . system . quantite ? ? 1 ) - achat . quantiteTotal ;
2021-06-05 01:14:29 +02:00
if ( resteQuantite == 0 ) {
2022-06-12 08:17:59 +02:00
vendeur . deleteEmbeddedDocuments ( "Item" , [ itemId ] )
2021-05-07 17:27:02 +02:00
}
else {
2022-06-12 19:40:44 +02:00
vendeur . updateEmbeddedDocuments ( "Item" , [ { _id : itemId , 'system.quantite' : resteQuantite } ] ) ;
2021-05-07 17:27:02 +02:00
}
}
if ( acheteur ) {
2021-06-05 01:14:29 +02:00
const achatData = {
type : vente . item . type ,
img : vente . item . img ,
name : vente . item . name ,
2022-09-07 18:47:56 +02:00
system : mergeObject ( vente . item . system , { quantite : isItemEmpilable ? achat . quantiteTotal : undefined } ) ,
2021-05-20 02:49:48 +02:00
}
2021-12-05 01:50:09 +01:00
let listeAchat = isItemEmpilable ? [ achatData ] : Array . from ( { length : achat . quantiteTotal } , ( _ , i ) => achatData )
2021-10-09 10:37:19 +02:00
let items = await acheteur . createEmbeddedDocuments ( "Item" , listeAchat )
2021-06-21 23:37:33 +02:00
if ( achat . choix . consommer && vente . item . type == 'nourritureboisson' ) {
achat . choix . doses = achat . choix . nombreLots ;
await acheteur . consommerNourritureboisson ( items [ 0 ] , achat . choix ) ;
}
2021-05-07 17:27:02 +02:00
}
if ( coutDeniers > 0 ) {
RdDAudio . PlayContextAudio ( "argent" ) ;
}
2021-06-22 21:30:16 +02:00
const chatAchatItem = duplicate ( vente ) ;
chatAchatItem . quantiteTotal = achat . quantiteTotal ;
2021-05-07 17:27:02 +02:00
ChatMessage . create ( {
2021-10-30 00:40:35 +02:00
user : achat . userId ,
2021-12-05 01:50:09 +01:00
speaker : { alias : ( acheteur ? ? vendeur ) . name } ,
2021-05-07 17:27:02 +02:00
whisper : ChatUtility . getWhisperRecipientsAndGMs ( this . name ) ,
2021-06-22 21:30:16 +02:00
content : await renderTemplate ( 'systems/foundryvtt-reve-de-dragon/templates/chat-achat-item.html' , chatAchatItem )
2021-05-07 17:27:02 +02:00
} ) ;
2021-06-05 01:14:29 +02:00
if ( ! vente . quantiteIllimite ) {
2021-06-21 23:37:33 +02:00
if ( vente . quantiteNbLots <= achat . choix . nombreLots ) {
2021-06-14 23:42:24 +02:00
ChatUtility . removeChatMessageId ( achat . chatMessageIdVente ) ;
2021-05-20 02:49:48 +02:00
}
else {
2021-06-08 00:32:27 +02:00
vente [ "properties" ] = new RdDItem ( vente . item ) . getProprietes ( ) ;
2021-06-21 23:37:33 +02:00
vente . quantiteNbLots -= achat . choix . nombreLots ;
2021-06-08 00:32:27 +02:00
vente . jsondata = JSON . stringify ( vente . item ) ;
2021-06-05 01:14:29 +02:00
messageVente . update ( { content : await renderTemplate ( 'systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html' , vente ) } ) ;
2021-05-20 02:49:48 +02:00
messageVente . render ( true ) ;
}
2021-05-07 17:27:02 +02:00
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2021-04-20 23:16:18 +02:00
async effectuerTacheAlchimie ( recetteId , tacheAlchimie , texteTache ) {
2022-06-12 09:46:58 +02:00
let recetteData = this . getItemOfType ( recetteId , 'recettealchimique' ) ;
2021-04-20 23:16:18 +02:00
if ( recetteData ) {
if ( tacheAlchimie != "couleur" && tacheAlchimie != "consistance" ) {
ui . notifications . warn ( ` L'étape alchimique ${ tacheAlchimie } - ${ texteTache } est inconnue ` ) ;
return ;
2021-01-07 20:04:10 +01:00
}
2021-01-09 19:33:19 +01:00
2022-06-12 09:46:58 +02:00
const sansCristal = tacheAlchimie == "couleur" && this . items . filter ( it => it . isCristalAlchimique ( ) ) . length == 0 ;
2021-04-20 23:16:18 +02:00
const caracTache = RdDAlchimie . getCaracTache ( tacheAlchimie ) ;
2022-06-12 09:46:58 +02:00
const alchimieData = this . getCompetence ( "alchimie" ) ;
2021-04-20 23:16:18 +02:00
let rollData = {
recette : recetteData ,
2022-06-12 09:46:58 +02:00
carac : { [ caracTache ] : this . system . carac [ caracTache ] } ,
selectedCarac : this . system . carac [ caracTache ] ,
2021-04-20 23:16:18 +02:00
competence : alchimieData ,
diffLibre : RdDAlchimie . getDifficulte ( texteTache ) ,
diffConditions : sansCristal ? - 4 : 0 ,
alchimie : {
tache : Misc . upperFirst ( tacheAlchimie ) ,
texte : texteTache ,
sansCristal : sansCristal
}
}
2022-06-12 09:46:58 +02:00
rollData . competence . system . defaut _carac = caracTache ;
2021-04-21 00:59:10 +02:00
2021-01-07 20:04:10 +01:00
const dialog = await RdDRoll . create ( this , rollData ,
2021-01-09 19:33:19 +01:00
{
html : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-alchimie.html' ,
2021-01-07 20:04:10 +01:00
} ,
{
name : 'tache-alchimique' ,
label : 'Tache Alchimique' ,
callbacks : [
this . createCallbackExperience ( ) ,
2021-03-15 00:10:29 +01:00
this . createCallbackAppelAuMoral ( ) ,
2022-01-29 18:50:37 +01:00
{ action : async r => await this . _alchimieResult ( r , false ) }
2021-01-07 20:04:10 +01:00
]
}
) ;
dialog . render ( true ) ;
}
}
2021-04-20 23:16:18 +02:00
isCristalAlchimique ( it ) {
2022-06-12 12:14:55 +02:00
return it . type == 'objet' && Grammar . toLowerCaseNoAccent ( it . name ) == 'cristal alchimique' && it . system . quantite > 0 ;
2021-04-20 23:16:18 +02:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2022-01-29 18:50:37 +01:00
async _alchimieResult ( rollData ) {
await RdDResolutionTable . displayRollData ( rollData , this , 'chat-resultat-alchimie.html' ) ;
2021-01-07 20:04:10 +01:00
}
2021-01-11 16:29:41 +01:00
/* -------------------------------------------- */
2021-03-18 23:55:26 +01:00
listeVehicules ( ) {
2022-04-30 19:15:55 +02:00
const listeVehichules = this . system . subacteurs ? . vehicules ? ? [ ] ;
2021-03-29 09:17:00 +02:00
return this . _buildActorLinksList ( listeVehichules , vehicle => RdDActor . _vehicleData ( vehicle ) ) ;
2021-01-11 16:29:41 +01:00
}
/* -------------------------------------------- */
2021-03-18 23:55:26 +01:00
listeSuivants ( ) {
2022-04-30 19:15:55 +02:00
return this . _buildActorLinksList ( this . system . subacteurs ? . suivants ? ? [ ] ) ;
2021-01-11 16:29:41 +01:00
}
/* -------------------------------------------- */
2021-03-18 23:55:26 +01:00
listeMontures ( ) {
2022-04-30 19:15:55 +02:00
return this . _buildActorLinksList ( this . system . subacteurs ? . montures ? ? [ ] ) ;
2021-01-11 16:29:41 +01:00
}
2021-01-22 02:08:49 +01:00
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-03-29 09:17:00 +02:00
_buildActorLinksList ( links , actorTransformation = it => RdDActor . _buildActorData ( it ) ) {
2021-01-22 02:08:49 +01:00
return links . map ( link => game . actors . get ( link . id ) )
. filter ( it => it != null )
. map ( actorTransformation ) ;
}
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-03-29 09:17:00 +02:00
static _vehicleData ( vehicle ) {
return {
id : vehicle . id ,
2022-06-12 08:17:59 +02:00
name : vehicle . name ,
img : vehicle . img ,
2022-09-27 00:15:34 +02:00
system : {
categorie : vehicle . system . categorie ,
etat : vehicle . system . etat
}
2021-03-29 09:17:00 +02:00
} ;
}
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-03-29 09:17:00 +02:00
static _buildActorData ( it ) {
2022-06-12 08:17:59 +02:00
return { id : it . id , name : it . name , img : it . img } ;
2021-03-29 09:17:00 +02:00
}
2021-01-11 16:29:41 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
async pushSubacteur ( actor , dataArray , dataPath , dataName ) {
2022-06-12 08:17:59 +02:00
let alreadyPresent = dataArray . find ( attached => attached . id == actor . _id ) ;
2021-02-11 02:48:27 +01:00
if ( ! alreadyPresent ) {
2021-01-11 16:29:41 +01:00
let newArray = duplicate ( dataArray ) ;
2022-06-12 08:17:59 +02:00
newArray . push ( { id : actor . _id } ) ;
2021-02-11 02:48:27 +01:00
await this . update ( { [ dataPath ] : newArray } ) ;
2021-01-11 16:29:41 +01:00
} else {
2021-02-11 02:48:27 +01:00
ui . notifications . warn ( dataName + " est déja attaché à ce Personnage." ) ;
2021-01-11 16:29:41 +01:00
}
}
/* -------------------------------------------- */
2022-09-07 00:09:17 +02:00
addSubActeur ( subActor ) {
if ( subActor ? . id == this . id ) {
ui . notifications . warn ( "Vous ne pouvez pas attacher un acteur à lui même" )
}
else if ( ! subActor ? . isOwner ) {
ui . notifications . warn ( "Vous n'avez pas les droits sur l'acteur que vous attachez." )
}
else {
if ( subActor . type == 'vehicule' ) {
2022-06-12 19:40:44 +02:00
this . pushSubacteur ( subActor , this . system . subacteurs . vehicules , 'system.subacteurs.vehicules' , 'Ce Véhicule' ) ;
2022-06-12 12:14:55 +02:00
} else if ( subActor . type == 'creature' ) {
2022-06-12 19:40:44 +02:00
this . pushSubacteur ( subActor , this . system . subacteurs . montures , 'system.subacteurs.montures' , 'Cette Monture' ) ;
2022-06-12 12:14:55 +02:00
} else if ( subActor . type == 'personnage' ) {
2022-06-12 19:40:44 +02:00
this . pushSubacteur ( subActor , this . system . subacteurs . suivants , 'system.subacteurs.suivants' , 'Ce Suivant' ) ;
2021-01-11 16:29:41 +01:00
}
}
}
2021-02-11 02:48:27 +01:00
2021-01-11 16:29:41 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
async removeSubacteur ( actorId ) {
2022-06-12 08:17:59 +02:00
let newVehicules = this . system . subacteurs . vehicules . filter ( function ( obj , index , arr ) { return obj . id != actorId } ) ;
let newSuivants = this . system . subacteurs . suivants . filter ( function ( obj , index , arr ) { return obj . id != actorId } ) ;
let newMontures = this . system . subacteurs . montures . filter ( function ( obj , index , arr ) { return obj . id != actorId } ) ;
2022-09-17 01:53:13 +02:00
await this . update ( { 'system.subacteurs.vehicules' : newVehicules } , { renderSheet : false } ) ;
await this . update ( { 'system.subacteurs.suivants' : newSuivants } , { renderSheet : false } ) ;
await this . update ( { 'system.subacteurs.montures' : newMontures } , { renderSheet : false } ) ;
2021-01-11 16:29:41 +01:00
}
2021-04-04 18:37:16 +02:00
/* -------------------------------------------- */
2021-04-11 18:43:32 +02:00
async buildPotionGuerisonList ( pointsGuerison ) {
2021-04-04 22:34:59 +02:00
let pointsGuerisonInitial = pointsGuerison ;
2022-06-12 09:46:58 +02:00
let myData = this . system ;
2021-04-04 22:34:59 +02:00
const blessures = duplicate ( myData . blessures ) ;
let guerisonData = { list : [ ] , pointsConsommes : 0 }
console . log ( blessures ) ;
for ( let critique of blessures . critiques . liste ) {
2021-04-11 18:43:32 +02:00
if ( critique . active && pointsGuerison >= 6 ) {
2021-04-04 22:34:59 +02:00
pointsGuerison -= 6 ;
critique . active = false ;
2021-04-11 18:43:32 +02:00
guerisonData . list . push ( "1 Blessure Critique (6 points)" ) ;
2021-04-04 22:34:59 +02:00
}
}
for ( let grave of blessures . graves . liste ) {
2021-04-11 18:43:32 +02:00
if ( grave . active && pointsGuerison >= 4 ) {
2021-04-04 22:34:59 +02:00
pointsGuerison -= 4 ;
grave . active = false ;
2021-04-11 18:43:32 +02:00
guerisonData . list . push ( "1 Blessure Grave (4 points)" ) ;
2021-04-04 22:34:59 +02:00
}
}
for ( let legere of blessures . legeres . liste ) {
2021-04-11 18:43:32 +02:00
if ( legere . active && pointsGuerison >= 2 ) {
2021-04-04 22:34:59 +02:00
pointsGuerison -= 2 ;
legere . active = false ;
2021-04-11 18:43:32 +02:00
guerisonData . list . push ( "1 Blessure Légère (2 points)" ) ;
2021-04-04 22:34:59 +02:00
}
}
2022-06-12 19:40:44 +02:00
await this . update ( { "system.blessures" : blessures } ) ;
2021-04-04 22:34:59 +02:00
let pvManquants = myData . sante . vie . max - myData . sante . vie . value ;
2021-04-11 18:43:32 +02:00
let pvSoignees = Math . min ( pvManquants , Math . floor ( pointsGuerison / 2 ) ) ;
pointsGuerison -= pvSoignees * 2 ;
guerisonData . list . push ( pvSoignees + " Points de Vie soignés" ) ;
2021-04-04 22:34:59 +02:00
await this . santeIncDec ( 'vie' , + pvSoignees , false ) ;
guerisonData . pointsConsommes = pointsGuerisonInitial - pointsGuerison ;
return guerisonData ;
2021-04-11 18:43:32 +02:00
}
2021-04-04 22:34:59 +02:00
2021-04-09 15:23:48 +02:00
/* -------------------------------------------- */
2021-04-04 22:34:59 +02:00
async consommerPotionSoin ( potionData ) {
2021-04-04 23:07:13 +02:00
potionData . alias = this . name ;
2021-04-12 01:03:37 +02:00
potionData . supprimer = true ;
2021-04-04 23:07:13 +02:00
2022-06-12 12:14:55 +02:00
if ( potionData . system . magique ) {
2021-04-04 22:34:59 +02:00
// Gestion de la résistance:
2021-10-09 22:04:34 +02:00
potionData . rolled = await RdDResolutionTable . roll ( this . getReveActuel ( ) , - 8 ) ;
if ( potionData . rolled . isEchec ) {
2021-04-04 22:34:59 +02:00
await this . reveActuelIncDec ( - 1 ) ;
2022-06-12 12:14:55 +02:00
potionData . guerisonData = await this . buildPotionGuerisonList ( potionData . system . puissance ) ;
2021-04-11 18:43:32 +02:00
potionData . guerisonMinutes = potionData . guerisonData . pointsConsommes * 5 ;
2021-04-04 22:34:59 +02:00
}
2021-10-09 22:04:34 +02:00
}
2022-06-12 12:14:55 +02:00
if ( ! potionData . system . magique || potionData . rolled . isSuccess ) {
this . bonusRecuperationPotion = potionData . system . herbeBonus ;
2021-04-04 22:34:59 +02:00
}
2021-10-09 22:04:34 +02:00
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name ) ,
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-soin.html ` , potionData )
} ) ;
2021-04-04 22:34:59 +02:00
}
2021-04-09 15:23:48 +02:00
/* -------------------------------------------- */
async consommerPotionRepos ( potionData ) {
potionData . alias = this . name ;
2021-04-12 01:03:37 +02:00
potionData . supprimer = true ;
2021-04-09 15:23:48 +02:00
2022-06-12 12:14:55 +02:00
if ( potionData . system . magique ) {
2021-04-09 15:23:48 +02:00
// Gestion de la résistance:
2021-10-09 22:04:34 +02:00
potionData . rolled = await RdDResolutionTable . roll ( this . getReveActuel ( ) , - 8 ) ;
if ( potionData . rolled . isEchec ) {
2021-04-09 15:23:48 +02:00
await this . reveActuelIncDec ( - 1 ) ;
let fatigueActuelle = this . getFatigueActuelle ( ) ;
2022-06-12 12:14:55 +02:00
potionData . caseFatigueReel = Math . min ( fatigueActuelle , potionData . system . puissance ) ;
potionData . guerisonDureeUnite = ( potionData . system . reposalchimique ) ? "rounds" : "minutes" ;
potionData . guerisonDureeValue = ( potionData . system . reposalchimique ) ? potionData . caseFatigueReel : potionData . caseFatigueReel * 5 ;
2021-04-09 15:23:48 +02:00
potionData . aphasiePermanente = false ;
2022-06-12 12:14:55 +02:00
if ( potionData . system . reposalchimique ) {
2021-05-11 21:45:43 +02:00
let chanceAphasie = await RdDDice . rollTotal ( "1d100" ) ;
2022-06-12 12:14:55 +02:00
if ( chanceAphasie <= potionData . system . pr ) {
2021-04-09 15:23:48 +02:00
potionData . aphasiePermanente = true ;
}
}
await this . santeIncDec ( "fatigue" , - potionData . caseFatigueReel ) ;
}
2021-10-09 22:04:34 +02:00
}
2022-06-12 12:14:55 +02:00
if ( ! potionData . system . magique || potionData . rolled . isSuccess ) {
this . bonusRepos = potionData . system . herbeBonus ;
2021-04-09 15:23:48 +02:00
}
2021-10-09 22:04:34 +02:00
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name ) ,
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-repos.html ` , potionData )
} ) ;
2021-04-09 15:23:48 +02:00
}
2021-04-10 21:07:53 +02:00
/* -------------------------------------------- */
2021-04-11 18:43:32 +02:00
dialogFabriquerPotion ( herbe ) {
2021-04-10 21:07:53 +02:00
DialogFabriquerPotion . create ( this , herbe , {
html : 'systems/foundryvtt-reve-de-dragon/templates/dialog-fabriquer-potion-base.html' ,
} , [ ] ) ;
}
/* -------------------------------------------- */
2021-04-11 23:03:55 +02:00
async fabriquerPotion ( herbeData ) {
2021-04-10 21:07:53 +02:00
let newPotion = {
2022-06-12 12:14:55 +02:00
name : ` Potion de ${ herbeData . system . categorie } ( ${ herbeData . name } ) ` , type : 'potion' ,
2021-04-10 21:07:53 +02:00
img : "systems/foundryvtt-reve-de-dragon/icons/objets/fiole_verre.webp" ,
2022-06-12 19:40:44 +02:00
system : {
2022-09-23 02:23:20 +02:00
quantite : 1 , cout : 0 , encombrement : 0.1 ,
2022-06-12 12:14:55 +02:00
categorie : herbeData . system . categorie ,
2021-04-11 23:03:55 +02:00
herbe : herbeData . name ,
2022-06-12 12:14:55 +02:00
rarete : herbeData . system . rarete ,
2021-04-11 23:03:55 +02:00
herbebrins : herbeData . nbBrins ,
2022-09-23 02:23:20 +02:00
herbebonus : herbeData . herbebonus ,
2021-04-11 18:43:32 +02:00
description : ""
}
2021-04-10 21:07:53 +02:00
}
2021-04-11 18:43:32 +02:00
await this . createEmbeddedDocuments ( 'Item' , [ newPotion ] , { renderSheet : true } ) ;
2021-04-10 21:07:53 +02:00
2022-06-12 12:14:55 +02:00
let newQuantite = herbeData . system . quantite - herbeData . nbBrins ;
2021-04-10 21:07:53 +02:00
let messageData = {
alias : this . name ,
2021-10-09 22:04:34 +02:00
nbBrinsReste : newQuantite ,
potion : newPotion ,
herbe : herbeData
2021-04-10 21:07:53 +02:00
}
2021-04-12 01:03:37 +02:00
this . diminuerQuantiteObjet ( herbeData . _id , herbeData . nbBrins ) ;
2021-04-13 22:42:39 +02:00
2021-04-10 21:07:53 +02:00
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name ) ,
2021-04-11 18:43:32 +02:00
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.html ` , messageData )
2021-04-10 21:07:53 +02:00
} ) ;
2021-04-11 18:43:32 +02:00
}
2021-04-09 15:23:48 +02:00
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-04-12 01:03:37 +02:00
async diminuerQuantiteObjet ( id , nb , options = { supprimerSiZero : false } ) {
const item = this . getObjet ( id ) ;
2021-04-13 22:42:39 +02:00
if ( item ) {
2021-04-12 01:03:37 +02:00
await item . diminuerQuantite ( nb , options ) ;
}
}
2021-04-09 17:30:32 +02:00
/* -------------------------------------------- */
2021-04-11 18:43:32 +02:00
async consommerPotionGenerique ( potionData ) {
2021-04-09 17:30:32 +02:00
potionData . alias = this . name ;
2022-06-12 12:14:55 +02:00
if ( potionData . system . magique ) {
2021-10-09 22:04:34 +02:00
// Gestion de la résistance:
potionData . rolled = await RdDResolutionTable . roll ( this . getReveActuel ( ) , - 8 ) ;
if ( potionData . rolled . isEchec ) {
await this . reveActuelIncDec ( - 1 ) ;
}
}
2021-04-09 17:30:32 +02:00
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name ) ,
2021-04-11 18:43:32 +02:00
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-generique.html ` , potionData )
2021-04-09 17:30:32 +02:00
} ) ;
2021-04-11 18:43:32 +02:00
}
2021-04-09 17:30:32 +02:00
2021-04-04 22:34:59 +02:00
/* -------------------------------------------- */
2022-07-22 22:53:48 +02:00
async consommerPotion ( potion , onActionItem = async ( ) => { } ) {
2022-06-12 09:46:58 +02:00
const potionData = potion
2021-04-04 22:34:59 +02:00
2022-06-12 12:14:55 +02:00
if ( potionData . system . categorie . includes ( 'Soin' ) ) {
2021-04-11 18:43:32 +02:00
this . consommerPotionSoin ( potionData ) ;
2022-06-12 09:46:58 +02:00
} else if ( potionData . system . categorie . includes ( 'Repos' ) ) {
2021-04-09 15:23:48 +02:00
this . consommerPotionRepos ( potionData ) ;
2021-04-04 22:34:59 +02:00
} else {
2021-04-11 18:43:32 +02:00
this . consommerPotionGenerique ( potionData ) ;
2021-04-04 22:34:59 +02:00
}
2021-12-05 01:50:09 +01:00
await this . diminuerQuantiteObjet ( potion . id , 1 , { supprimerSiZero : potionData . supprimer } ) ;
await onActionItem ( )
2021-04-04 18:37:16 +02:00
}
2021-01-13 03:42:13 +01:00
/* -------------------------------------------- */
2021-01-24 19:52:02 +01:00
async onUpdateActor ( update , options , actorId ) {
2022-06-12 08:17:59 +02:00
const updatedEndurance = update ? . system ? . sante ? . endurance
2021-01-24 19:52:02 +01:00
if ( updatedEndurance && options . diff ) {
2022-09-17 22:36:43 +02:00
await this . setEffect ( STATUSES . StatusUnconscious , updatedEndurance . value == 0 )
2021-01-13 03:42:13 +01:00
}
}
2021-01-24 19:52:02 +01:00
2021-01-13 03:42:13 +01:00
/* -------------------------------------------- */
2022-09-19 20:15:01 +02:00
getEffects ( filter = e => true ) {
return this . getEmbeddedCollection ( "ActiveEffect" ) . filter ( filter ) ;
2021-01-13 03:42:13 +01:00
}
2021-01-24 19:52:02 +01:00
2021-01-13 03:42:13 +01:00
/* -------------------------------------------- */
2022-09-17 22:36:43 +02:00
getEffect ( statusId ) {
return this . getEmbeddedCollection ( "ActiveEffect" ) . find ( it => it . flags ? . core ? . statusId == statusId ) ;
2021-01-13 03:42:13 +01:00
}
2021-01-24 19:52:02 +01:00
2021-01-13 03:42:13 +01:00
/* -------------------------------------------- */
2022-09-17 22:36:43 +02:00
async setEffect ( statusId , status ) {
2022-07-22 22:53:48 +02:00
if ( this . isEntite ( ) || this . type == 'vehicule' ) {
2021-01-13 03:42:13 +01:00
return ;
}
2022-09-17 22:36:43 +02:00
console . log ( "setEffect" , statusId , status )
2022-09-19 20:15:01 +02:00
const effect = this . getEffect ( statusId ) ;
if ( ! status && effect ) {
await this . deleteEmbeddedDocuments ( 'ActiveEffect' , [ effect . id ] ) ;
}
if ( status && ! effect ) {
await this . createEmbeddedDocuments ( "ActiveEffect" , [ StatusEffects . status ( statusId ) ] ) ;
2021-01-13 03:42:13 +01:00
}
}
2020-11-14 03:16:03 +01:00
2022-09-17 22:36:43 +02:00
async removeEffect ( statusId ) {
const effect = this . getEffect ( statusId ) ;
if ( effect ) {
await this . deleteEmbeddedDocuments ( 'ActiveEffect' , [ effect . id ] ) ;
2021-04-11 23:02:53 +02:00
}
2021-01-13 03:42:13 +01:00
}
2022-09-17 22:36:43 +02:00
2021-01-13 03:42:13 +01:00
/* -------------------------------------------- */
2022-09-19 20:15:01 +02:00
async removeEffects ( filter = e => true ) {
2021-12-05 01:50:09 +01:00
if ( game . user . isGM ) {
2022-09-19 20:15:01 +02:00
const ids = this . getEffects ( filter ) . map ( it => it . id ) ;
await this . deleteEmbeddedDocuments ( 'ActiveEffect' , ids ) ;
2021-05-27 19:40:45 +02:00
}
2021-01-13 03:42:13 +01:00
}
2021-04-16 23:07:09 +02:00
/* -------------------------------------------- */
async onPreUpdateItem ( item , change , options , id ) {
2022-06-12 08:17:59 +02:00
if ( item . type == 'competence' && item . system . defaut _carac && item . system . xp ) {
await this . checkCompetenceXP ( item . name , item . system . xp ) ;
2021-04-16 23:07:09 +02:00
}
}
2021-01-14 15:29:47 +01:00
/* -------------------------------------------- */
2021-03-29 23:41:08 +02:00
async onCreateItem ( item , options , id ) {
2021-02-11 02:48:27 +01:00
switch ( item . type ) {
case 'tete' :
case 'queue' :
case 'ombre' :
case 'souffle' :
await this . onCreateOwnedDraconique ( item , options , id ) ;
break ;
}
}
2021-03-29 23:41:08 +02:00
async onDeleteItem ( item , options , id ) {
2021-02-11 02:48:27 +01:00
switch ( item . type ) {
case 'tete' :
case 'queue' :
case 'ombre' :
case 'souffle' :
await this . onDeleteOwnedDraconique ( item , options , id ) ;
break ;
2021-02-28 01:50:15 +01:00
case 'casetmr' :
await this . onDeleteOwnedCaseTmr ( item , options , id ) ;
break ;
2021-02-11 02:48:27 +01:00
}
}
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
async onCreateOwnedDraconique ( item , options , id ) {
2021-11-26 00:45:21 +01:00
if ( Misc . isUniqueConnectedGM ( ) ) {
2021-04-16 23:07:09 +02:00
let draconique = Draconique . all ( ) . find ( it => it . match ( item ) ) ;
if ( draconique ) {
draconique . onActorCreateOwned ( this , item )
this . notifyGestionTeteSouffleQueue ( item , draconique . manualMessage ( ) ) ;
}
2021-02-11 02:48:27 +01:00
}
}
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
async onDeleteOwnedDraconique ( item , options , id ) {
2021-11-26 00:45:21 +01:00
if ( Misc . isUniqueConnectedGM ( ) ) {
2021-04-16 23:07:09 +02:00
let draconique = Draconique . all ( ) . find ( it => it . match ( item ) ) ;
if ( draconique ) {
draconique . onActorDeleteOwned ( this , item )
}
2021-02-11 02:48:27 +01:00
}
}
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-02-28 01:50:15 +01:00
async onDeleteOwnedCaseTmr ( item , options , id ) {
2021-11-26 00:45:21 +01:00
if ( Misc . isUniqueConnectedGM ( ) ) {
2021-04-16 23:07:09 +02:00
let draconique = Draconique . all ( ) . find ( it => it . isCase ( item ) ) ;
if ( draconique ) {
2022-06-12 09:46:58 +02:00
draconique . onActorDeleteCaseTmr ( this , item )
2021-04-16 23:07:09 +02:00
}
2021-02-28 01:50:15 +01:00
}
}
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-03-15 00:05:56 +01:00
notifyGestionTeteSouffleQueue ( item , manualMessage = true ) {
2021-02-11 02:48:27 +01:00
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name ) ,
2021-05-28 18:30:05 +02:00
content : ` ${ this . name } a reçu un/une ${ item . type } : ${ item . name } , qui ${ manualMessage ? "n'est pas" : "est" } géré(e) automatiquement. ${ manualMessage ? manualMessage : '' } `
2021-02-11 02:48:27 +01:00
} ) ;
2021-03-15 00:05:56 +01:00
}
}
2021-02-11 02:48:27 +01:00