2023-11-04 17:48:50 +01: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-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" ;
2021-01-01 22:25:32 +01:00
import { RdDItemCompetence } from "./item-competence.js" ;
2021-01-07 20:04:10 +01:00
import { RdDAlchimie } from "./rdd-alchimie.js" ;
2023-11-04 03:42:39 +01:00
import { STATUSES } from "./settings/status-effects.js" ;
2023-01-18 01:37:22 +01:00
import { RdDItemSigneDraconique } from "./item/signedraconique.js" ;
2023-06-20 23:43:24 +02:00
import { ReglesOptionnelles } from "./settings/regles-optionnelles.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-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-11-11 09:18:25 +01:00
import { RdDPossession } from "./rdd-possession.js" ;
2023-11-04 03:42:39 +01:00
import { SHOW _DICE , SYSTEM _RDD , SYSTEM _SOCKET _ID } from "./constants.js" ;
2022-10-04 23:23:43 +02:00
import { RdDConfirm } from "./rdd-confirm.js" ;
2023-01-18 01:37:22 +01:00
import { RdDRencontre } from "./item/rencontre.js" ;
2023-02-07 18:06:45 +01:00
import { DialogRepos } from "./sommeil/dialog-repos.js" ;
2022-12-28 23:36:48 +01:00
import { RdDBaseActor } from "./actor/base-actor.js" ;
2023-03-29 22:53:40 +02:00
import { RdDTimestamp } from "./time/rdd-timestamp.js" ;
2023-03-10 22:41:11 +01:00
import { RdDItemBlessure } from "./item/blessure.js" ;
import { AppAstrologie } from "./sommeil/app-astrologie.js" ;
2023-04-21 18:18:20 +02:00
import { RdDEmpoignade } from "./rdd-empoignade.js" ;
2023-05-28 21:59:11 +02:00
import { ExperienceLog , XP _TOPIC } from "./actor/experience-log.js" ;
2024-09-25 22:56:24 +02:00
import { ITEM _TYPES } from "./item.js" ;
2023-11-04 17:48:50 +01:00
import { RdDBaseActorSang } from "./actor/base-actor-sang.js" ;
2023-11-27 23:45:33 +01:00
import { RdDCoeur } from "./coeur/rdd-coeur.js" ;
2023-12-10 22:13:05 +01:00
import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js" ;
2024-11-06 23:24:53 +01:00
import { RdDItemArme } from "./item-arme.js" ;
import { RdDCombatManager } from "./rdd-combat.js" ;
2022-07-22 21:38:15 +02:00
2022-12-14 20:00:16 +01:00
export const MAINS _DIRECTRICES = [ 'Droitier' , 'Gaucher' , 'Ambidextre' ]
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 }
* /
2023-11-04 17:48:50 +01:00
export class RdDActor extends RdDBaseActorSang {
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2023-11-04 03:42:39 +01:00
/ * *
* Prepare Character type specific data
* /
prepareActorData ( ) {
this . $computeCaracDerivee ( )
2023-11-04 17:48:50 +01:00
this . $computeIsHautRevant ( )
2020-05-22 00:48:43 +02:00
}
2020-12-31 00:55:02 +01:00
2021-05-28 18:30:05 +02:00
/* -------------------------------------------- */
2023-11-04 03:42:39 +01:00
$computeCaracDerivee ( ) {
2023-12-10 22:13:05 +01:00
this . system . carac . force . value = Math . min ( this . system . carac . force . value , parseInt ( this . system . carac . taille . value ) + 4 ) ;
this . system . carac . melee . value = Math . floor ( ( parseInt ( this . system . carac . force . value ) + parseInt ( this . system . carac . agilite . value ) ) / 2 ) ;
this . system . carac . tir . value = Math . floor ( ( parseInt ( this . system . carac . vue . value ) + parseInt ( this . system . carac . dexterite . value ) ) / 2 ) ;
this . system . carac . lancer . value = Math . floor ( ( parseInt ( this . system . carac . tir . value ) + parseInt ( this . system . carac . force . value ) ) / 2 ) ;
2023-11-04 03:42:39 +01:00
this . system . carac . derobee . value = Math . floor ( parseInt ( ( ( 21 - this . system . carac . taille . value ) ) + parseInt ( this . system . carac . agilite . value ) ) / 2 ) ;
2023-12-10 22:13:05 +01:00
2023-11-04 03:42:39 +01:00
let bonusDomKey = Math . floor ( ( parseInt ( this . system . carac . force . value ) + parseInt ( this . system . carac . taille . value ) ) / 2 ) ;
let tailleData = RdDCarac . getCaracDerivee ( bonusDomKey ) ;
this . system . attributs . plusdom . value = tailleData . plusdom ;
2023-12-10 22:13:05 +01:00
this . system . attributs . encombrement . value = ( parseInt ( this . system . carac . force . value ) + parseInt ( this . system . carac . taille . value ) ) / 2 ;
2023-11-04 03:42:39 +01:00
this . system . attributs . sconst . value = RdDCarac . calculSConst ( this . system . carac . constitution . value ) ;
this . system . attributs . sust . value = RdDCarac . getCaracDerivee ( this . system . carac . taille . value ) . sust ;
this . system . sante . vie . max = Math . ceil ( ( parseInt ( this . system . carac . taille . value ) + parseInt ( this . system . carac . constitution . value ) ) / 2 ) ;
this . system . sante . vie . value = Math . min ( this . system . sante . vie . value , this . system . sante . vie . max )
this . system . sante . endurance . max = Math . max ( parseInt ( this . system . carac . taille . value ) + parseInt ( this . system . carac . constitution . value ) , parseInt ( this . system . sante . vie . max ) + parseInt ( this . system . carac . volonte . value ) ) ;
this . system . sante . endurance . value = Math . min ( this . system . sante . endurance . value , this . system . sante . endurance . max ) ;
2023-11-04 17:48:50 +01:00
this . system . sante . fatigue . max = this . getFatigueMax ( ) ;
2023-11-04 03:42:39 +01:00
this . system . sante . fatigue . value = Math . min ( this . system . sante . fatigue . value , this . system . sante . fatigue . max ) ;
//Compteurs
this . system . reve . reve . max = this . system . carac . reve . value ;
this . system . compteurs . chance . max = this . system . carac . chance . value ;
2021-05-28 18:30:05 +02:00
}
2023-11-21 16:03:26 +01:00
$computeIsHautRevant ( ) {
this . system . attributs . hautrevant . value = this . itemTypes [ 'tete' ] . find ( it => Grammar . equalsInsensitive ( it . name , 'don de haut-reve' ) )
? "Haut rêvant"
: "" ;
}
/* -------------------------------------------- */
2022-12-03 15:33:16 +01:00
canReceive ( item ) {
2024-09-25 22:56:24 +02:00
return ! [ ITEM _TYPES . competencecreature , ITEM _TYPES . tarot , ITEM _TYPES . service ] . includes ( item . type )
2022-12-03 15:33:16 +01:00
}
2024-03-09 23:12:13 +01:00
isPersonnageJoueur ( ) {
return this . hasPlayerOwner && this . prototypeToken . actorLink
}
2023-11-04 17:48:50 +01:00
isPersonnage ( ) { return true }
isHautRevant ( ) { return this . system . attributs . hautrevant . value != "" }
2023-11-04 03:42:39 +01:00
2023-11-21 16:03:26 +01:00
/* -------------------------------------------- */
2024-03-09 19:12:57 +01:00
getAgilite ( ) { return this . system . carac . agilite ? . value ? ? 0 }
getChance ( ) { return this . system . carac . chance ? . value ? ? 0 }
2023-11-04 17:48:50 +01:00
2024-03-09 19:12:57 +01:00
getReveActuel ( ) { return this . system . reve ? . reve ? . value ? ? this . carac . reve . value ? ? 0 }
getChanceActuel ( ) { return this . system . compteurs . chance ? . value ? ? 10 }
getMoralTotal ( ) { return this . system . compteurs . moral ? . value ? ? 0 }
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 } ) {
2024-03-09 19:12:57 +01:00
const etatGeneral = this . system . compteurs . etat ? . value ? ? 0
// Pour les jets d'Ethylisme, on retire le malus d'éthylisme (p.162)
const annuleMalusEthylisme = options . ethylisme ? this . malusEthylisme ( ) : 0
return etatGeneral - annuleMalusEthylisme
2021-01-05 18:43:13 +01:00
}
2023-02-07 18:06:45 +01:00
2021-11-08 07:47:21 +01:00
/* -------------------------------------------- */
2021-12-05 01:50:09 +01:00
getActivePoisons ( ) {
2024-05-02 14:08:02 +02:00
return foundry . utils . 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 ( ) {
2024-09-25 22:56:24 +02:00
return this . itemTypes [ ITEM _TYPES . armure ] . filter ( it => it . system . equipe )
2023-11-04 17:48:50 +01:00
. map ( it => it . system . malus )
. reduce ( Misc . sum ( ) , 0 ) ;
2021-01-05 18:43:13 +01:00
}
2021-05-07 00:01:07 +02:00
2024-11-06 23:24:53 +01:00
listActionsCombat ( ) {
// Recupération des armes
const actions = RdDCombatManager . listActionsArmes (
this . itemTypes [ ITEM _TYPES . arme ]
. filter ( it => RdDItemArme . isAttaque ( it ) )
2024-11-26 23:23:34 +01:00
. concat ( RdDItemArme . corpsACorps ( this ) )
2024-11-06 23:24:53 +01:00
. concat ( RdDItemArme . empoignade ( this ) )
,
this . itemTypes [ ITEM _TYPES . competence ] ,
this . system . carac )
if ( this . system . attributs . hautrevant . value ) {
actions . push ( { name : "Draconic" , action : 'haut-reve' , system : { initOnly : true , competence : "Draconic" } } ) ;
}
return actions
}
2021-01-05 18:43:13 +01:00
/* -------------------------------------------- */
2023-11-21 16:03:26 +01:00
getTache ( id ) { return this . findItemLike ( id , 'tache' ) }
getMeditation ( id ) { return this . findItemLike ( id , 'meditation' ) }
getChant ( id ) { return this . findItemLike ( id , 'chant' ) }
getDanse ( id ) { return this . findItemLike ( id , 'danse' ) }
getMusique ( id ) { return this . findItemLike ( id , 'musique' ) }
getOeuvre ( id , type = 'oeuvre' ) { return this . findItemLike ( id , type ) }
getJeu ( id ) { return this . findItemLike ( id , 'jeu' ) }
getRecetteCuisine ( id ) { return this . findItemLike ( id , 'recettecuisine' ) }
2022-09-07 18:47:56 +02:00
2023-11-21 16:03:26 +01:00
/* -------------------------------------------- */
getDemiReve ( ) { return this . system . reve . tmrpos . coord }
2024-09-25 22:56:24 +02:00
getDraconicList ( ) { return this . itemTypes [ ITEM _TYPES . competence ] . filter ( it => it . system . categorie == 'draconic' ) }
2024-05-02 14:08:02 +02:00
getBestDraconic ( ) { return foundry . utils . duplicate ( this . getDraconicList ( ) . sort ( Misc . descending ( it => it . system . niveau ) ) . find ( it => true ) ) }
2022-07-02 01:41:55 +02:00
getDraconicOuPossession ( ) {
2023-11-04 17:48:50 +01:00
return [ ... this . getDraconicList ( ) . filter ( it => it . system . niveau >= 0 ) ,
super . getDraconicOuPossession ( ) ]
2023-06-13 01:55:38 +02:00
. sort ( Misc . descending ( it => it . system . niveau ) )
2023-11-04 17:48:50 +01:00
. find ( it => true )
2022-07-02 01:41:55 +02:00
}
2022-09-07 18:47:56 +02:00
2021-04-09 15:23:48 +02:00
/* -------------------------------------------- */
2023-11-21 16:03:26 +01:00
async $perteRevePotionsEnchantees ( ) {
2024-09-25 22:56:24 +02:00
let potions = this . itemTypes [ ITEM _TYPES . potion ]
2023-12-22 20:12:45 +01:00
. filter ( it => Grammar . includesLowerCaseNoAccent ( it . system . categorie , 'enchanté' ) && ! it . system . prpermanent )
const potionUpdates = await Promise . all ( potions . map ( async it => {
const nouveauReve = Math . max ( it . system . pr - 1 , 0 )
2023-11-21 16:03:26 +01:00
ChatMessage . create ( {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
2023-12-22 20:12:45 +01:00
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html ` , {
pr : nouveauReve ,
2024-11-15 00:01:55 +01:00
alias : this . getAlias ( ) ,
2023-12-22 20:12:45 +01:00
potionName : it . name ,
potionImg : it . img
} )
} )
return {
_id : it . _id ,
'system.pr' : nouveauReve ,
'system.quantite' : nouveauReve > 0 ? it . system . quantite : 0
}
2023-11-21 16:03:26 +01:00
} ) )
2023-12-22 20:12:45 +01:00
2023-11-21 16:03:26 +01:00
await this . updateEmbeddedDocuments ( 'Item' , potionUpdates ) ;
2021-04-09 15:23:48 +02:00
}
2021-03-29 09:17:00 +02:00
2023-11-21 16:03:26 +01:00
/ * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* @ returns true si l ' acteur possède au moins 1 arme de mêlée équipée
* /
hasArmeeMeleeEquipee ( ) {
2023-04-21 22:23:40 +02:00
return this . itemTypes [ 'arme' ] . find ( it => it . system . equipe && it . system . competence != "" )
2023-04-21 18:18:20 +02:00
}
2023-02-10 02:01:43 +01:00
async prepareChateauDormant ( consigne ) {
if ( consigne . ignorer ) {
2023-02-07 18:06:45 +01:00
return ;
}
2023-02-10 02:01:43 +01:00
if ( consigne . stress . valeur > 0 ) {
await this . distribuerStress ( 'stress' , consigne . stress . valeur , consigne . stress . motif ) ;
2023-02-07 18:06:45 +01:00
}
2023-02-10 02:01:43 +01:00
await this . update ( { 'system.sommeil' : consigne . sommeil } )
2023-06-24 23:50:05 +02:00
const player = this . findPlayer ( ) ;
if ( player ) {
ChatUtility . notifyUser ( player . id , 'info' , ` Vous pouvez gérer la nuit de ${ this . name } ` ) ;
}
}
2023-02-07 18:06:45 +01:00
async onTimeChanging ( oldTimestamp , newTimestamp ) {
await super . onTimeChanging ( oldTimestamp , newTimestamp ) ;
2023-02-10 02:01:43 +01:00
await this . setInfoSommeilInsomnie ( ) ;
2023-02-07 18:06:45 +01:00
}
2022-12-17 00:21:02 +01:00
async repos ( ) {
2022-12-23 23:18:40 +01:00
await DialogRepos . create ( this ) ;
2022-12-17 00:21:02 +01:00
}
2021-06-26 00:55:54 +02:00
/* -------------------------------------------- */
2023-11-21 16:03:26 +01:00
async grisReve ( nbJours ) {
2021-06-26 00:55:54 +02:00
let message = {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
2023-11-21 16:03:26 +01:00
content : ` ${ nbJours } jours de gris rêve sont passés. `
2021-06-26 00:55:54 +02:00
} ;
2023-11-21 16:03:26 +01:00
for ( let i = 0 ; i < nbJours ; i ++ ) {
2023-02-07 18:06:45 +01:00
await this . dormir ( 4 , { grisReve : true } ) ;
2023-02-03 02:19:55 +01:00
await this . _recuperationSante ( message ) ;
2021-06-26 00:55:54 +02:00
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 ( ) ;
2023-03-14 02:38:21 +01:00
await this . setBonusPotionSoin ( 0 ) ;
2021-06-26 00:55:54 +02:00
}
2023-02-10 02:01:43 +01:00
await this . resetInfoSommeil ( )
2021-06-26 00:55:54 +02:00
ChatMessage . create ( message ) ;
this . sheet . render ( true ) ;
}
2023-02-03 02:19:55 +01:00
async _recuperationSante ( message ) {
2023-11-21 16:03:26 +01:00
const maladiesPoisons = this . getMaladiePoisons ( ) ;
2023-02-03 02:19:55 +01:00
const isMaladeEmpoisonne = maladiesPoisons . length > 0 ;
2023-02-10 02:01:43 +01:00
this . _messageRecuperationMaladiePoisons ( maladiesPoisons , message ) ;
2023-03-14 02:38:21 +01:00
2023-11-12 21:03:41 +01:00
await this . _recupererBlessures ( message , isMaladeEmpoisonne ) ;
2023-02-03 02:19:55 +01:00
await this . _recupererVie ( message , isMaladeEmpoisonne ) ;
}
2023-11-21 16:03:26 +01:00
getMaladiePoisons ( ) {
return this . items . filter ( item => item . type == 'maladie' || ( item . type == 'poison' && item . system . active ) ) ;
2023-02-03 02:19:55 +01:00
}
2023-02-10 02:01:43 +01:00
_messageRecuperationMaladiePoisons ( maladiesPoisons , message ) {
if ( maladiesPoisons . length > 0 ) {
const identifies = maladiesPoisons . filter ( it => it . system . identifie ) ;
const nonIdentifies = maladiesPoisons . filter ( it => ! it . system . identifie ) ;
2023-02-03 02:19:55 +01:00
message . content += 'Vous souffrez' ;
switch ( nonIdentifies . length ) {
case 0 : break ;
case 1 : message . content += ` d'un mal inconnu ` ; break ;
default : message . content += ` de ${ nonIdentifies . length } maux inconnus ` ; break ;
}
2023-11-21 16:03:26 +01:00
if ( identifies . length > 0 && nonIdentifies . length > 0 ) { message . content += ' et' }
2023-02-03 02:19:55 +01:00
if ( identifies . length > 0 ) {
2023-11-21 16:03:26 +01:00
message . content += ' de ' + identifies . map ( it => it . name ) . reduce ( Misc . joining ( ', ' ) ) ;
2023-02-03 02:19:55 +01:00
}
}
}
2020-12-04 20:52:04 +01:00
/* -------------------------------------------- */
2020-11-24 18:54:13 +01:00
async dormirChateauDormant ( ) {
2023-06-20 23:43:24 +02:00
if ( ! ReglesOptionnelles . isUsing ( "chateau-dormant-gardien" ) || ! this . system . sommeil || this . system . sommeil . nouveaujour ) {
2023-02-07 18:06:45 +01:00
const message = {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
2023-02-07 18:06:45 +01:00
content : ""
} ;
2020-12-19 01:14:02 +01:00
2023-02-07 18:06:45 +01:00
await this . _recuperationSante ( message )
2023-11-04 18:07:41 +01:00
await this . _recupereMoralChateauDormant ( message ) ;
2023-02-07 18:06:45 +01:00
await this . _recupereChance ( ) ;
2023-02-10 02:01:43 +01:00
await this . transformerStress ( ) ;
2023-02-07 18:06:45 +01:00
await this . retourSeuilDeReve ( message ) ;
2023-03-14 02:38:21 +01:00
await this . setBonusPotionSoin ( 0 ) ;
2023-02-07 18:06:45 +01:00
await this . retourSust ( message ) ;
2023-11-21 16:03:26 +01:00
await this . $perteRevePotionsEnchantees ( ) ;
2023-11-27 23:45:33 +01:00
await RdDCoeur . applyCoeurChateauDormant ( this , message )
2023-02-07 18:06:45 +01:00
if ( message . content != "" ) {
message . content = ` A la fin Chateau Dormant, ${ message . content } <br>Un nouveau jour se lève ` ;
ChatMessage . create ( message ) ;
}
2023-02-10 02:01:43 +01:00
await this . resetInfoSommeil ( ) ;
2023-02-07 18:06:45 +01:00
this . sheet . render ( true ) ;
2021-06-26 00:55:54 +02:00
}
2021-03-20 00:09:29 +01:00
}
2021-02-17 11:16:27 +01:00
2023-02-10 02:01:43 +01:00
async resetInfoSommeil ( ) {
await this . update ( {
'system.sommeil' : {
nouveaujour : false ,
date : game . system . rdd . calendrier . getTimestamp ( ) ,
moral : "neutre" ,
heures : 0 ,
insomnie : EffetsDraconiques . isSujetInsomnie ( this )
}
} ) ;
}
async setInfoSommeilInsomnie ( ) {
2023-11-12 00:24:42 +01:00
if ( EffetsDraconiques . isSujetInsomnie ( this ) ) {
await this . update ( { 'system.sommeil.insomnie' : true } ) ;
}
2023-02-10 02:01:43 +01:00
}
async setInfoSommeilMoral ( situationMoral ) {
await this . update ( { 'system.sommeil.moral' : situationMoral } ) ;
}
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2021-03-20 00:09:29 +01:00
async _recupereChance ( ) {
2023-11-03 20:22:41 +01:00
if ( ! ReglesOptionnelles . isUsing ( "recuperation-chance" ) ) { return }
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
}
2023-11-04 18:07:41 +01:00
async _recupereMoralChateauDormant ( message ) {
if ( ! ReglesOptionnelles . isUsing ( "recuperation-moral" ) ) { return }
2023-02-07 18:06:45 +01:00
const etatMoral = this . system . sommeil ? . moral ? ? 'neutre' ;
const jetMoral = await this . _jetDeMoral ( etatMoral ) ;
message . content += ` -- le jet de moral est ${ etatMoral } , le moral ` + this . _messageAjustementMoral ( jetMoral . ajustement ) ;
2023-02-07 18:06:15 +01:00
}
2023-02-07 18:06:45 +01:00
2023-02-07 18:06:15 +01:00
_messageAjustementMoral ( ajustement ) {
switch ( Math . sign ( ajustement ) ) {
case 1 :
return ` remonte de ${ ajustement } ` ;
case - 1 :
return ` diminue de ${ - ajustement } ` ;
case 0 :
return 'reste stable' ;
default :
console . error ( ` Le signe de l'ajustement de moral ${ ajustement } est ${ Math . sign ( ajustement ) } , ce qui est innatendu ` )
return ` est ajusté de ${ ajustement } (bizarre) ` ;
}
2021-11-07 21:36:11 +01:00
}
2020-12-04 20:52:04 +01:00
/* -------------------------------------------- */
2023-11-12 21:03:41 +01:00
async _recupererBlessures ( message , isMaladeEmpoisonne ) {
2023-03-14 02:38:21 +01:00
const timestamp = game . system . rdd . calendrier . getTimestamp ( )
2024-09-25 22:56:24 +02:00
const blessures = this . filterItems ( it => it . system . gravite > 0 , ITEM _TYPES . blessure ) . sort ( Misc . ascending ( it => it . system . gravite ) )
2020-11-24 18:54:13 +01:00
2024-05-12 22:40:37 +02:00
await Promise . all ( blessures . map ( async b => b . recuperationBlessure ( {
2023-03-14 02:38:21 +01:00
actor : this ,
timestamp ,
message ,
isMaladeEmpoisonne ,
blessures
} ) ) ) ;
2023-03-20 23:28:25 +01:00
await this . supprimerBlessures ( it => it . system . gravite <= 0 ) ;
2020-11-24 18:54:13 +01:00
}
2021-01-09 19:33:19 +01:00
2020-12-05 21:24:31 +01:00
/* -------------------------------------------- */
2023-02-03 02:19:55 +01:00
async _recupererVie ( message , isMaladeEmpoisonne ) {
2022-06-12 09:46:58 +02:00
const tData = this . system
2024-09-25 22:56:24 +02:00
let blessures = this . filterItems ( it => it . system . gravite > 0 , ITEM _TYPES . blessure ) ;
2023-03-14 02:38:21 +01:00
if ( blessures . length > 0 ) {
return
}
2021-03-22 20:10:37 +01:00
let vieManquante = tData . sante . vie . max - tData . sante . vie . value ;
2023-03-14 02:38:21 +01:00
if ( vieManquante > 0 ) {
2023-03-20 23:28:25 +01:00
let rolled = await this . jetRecuperationConstitution ( 0 , message )
2023-02-03 02:19:55 +01:00
if ( ! isMaladeEmpoisonne && rolled . isSuccess ) {
2020-11-24 18:54:13 +01:00
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
/* -------------------------------------------- */
2023-03-14 02:38:21 +01:00
async jetRecuperationConstitution ( bonusSoins , message = undefined ) {
2023-03-20 23:28:25 +01:00
let difficulte = Math . min ( 0 , this . system . sante . vie . value - this . system . sante . vie . max ) + bonusSoins + this . system . sante . bonusPotion ;
2022-12-07 14:21:48 +01:00
let rolled = await RdDResolutionTable . roll ( this . system . carac . constitution . value , difficulte ) ;
2020-11-24 18:54:13 +01:00
if ( message ) {
2022-12-07 14:21:48 +01:00
message . content = await renderTemplate ( "systems/foundryvtt-reve-de-dragon/templates/roll/explain.hbs" , {
actor : this ,
carac : this . system . carac . constitution ,
rolled
} )
2020-11-24 18:54:13 +01:00
}
return rolled ;
}
2020-12-05 21:24:31 +01:00
/* -------------------------------------------- */
2020-12-01 01:17:18 +01:00
async remiseANeuf ( ) {
2022-09-19 20:15:01 +02:00
ChatMessage . create ( {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
2022-09-19 20:15:01 +02:00
content : 'Remise à neuf de ' + this . name
} ) ;
2023-11-04 17:48:50 +01:00
await this . supprimerBlessures ( it => true ) ;
2023-12-08 23:50:16 +01:00
await this . removeEffects ( e => e . id != STATUSES . StatusDemiReve ) ;
2022-09-19 20:15:01 +02:00
const updates = {
2023-11-04 17:48:50 +01:00
'system.sante.endurance.value' : this . system . sante . endurance . max ,
'system.sante.vie.value' : this . system . sante . vie . max ,
'system.sante.fatigue.value' : 0 ,
'system.compteurs.ethylisme' : { value : 1 , nb _doses : 0 , jet _moral : false }
2022-09-19 20:15:01 +02:00
} ;
await this . update ( updates ) ;
2020-12-01 01:17:18 +01:00
}
2020-11-17 16:30:03 +01:00
/* -------------------------------------------- */
2023-02-10 02:01:43 +01:00
async dormir ( heures , options = { grisReve : false , chateauDormant : false } ) {
2023-02-07 18:06:45 +01:00
const message = {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
2023-02-10 02:01:43 +01:00
content : this . name + ': '
2020-11-24 15:43:03 +01:00
} ;
2023-06-24 00:58:45 +02:00
const insomnie = this . system . sommeil ? . insomnie || heures == 0 ;
2023-06-24 01:41:12 +02:00
await this . recupereEndurance ( { message : message , demi : insomnie } ) ;
2023-06-24 00:58:45 +02:00
if ( insomnie ) {
2023-02-10 02:01:43 +01:00
message . content += 'Vous ne trouvez pas le sommeil' ;
}
else {
let jetsReve = [ ] ;
let dormi = await this . dormirDesHeures ( jetsReve , message , heures , options ) ;
if ( jetsReve . length > 0 ) {
2024-05-13 01:49:42 +02:00
message . content += ` Vous récupérez ${ jetsReve . map ( it => it < 0 ? '0 (réveil)' : it ) . reduce ( Misc . joining ( "+" ) ) } Points de rêve. ` ;
2023-02-10 02:01:43 +01:00
}
if ( dormi . etat == 'eveil' ) {
2023-06-24 01:41:12 +02:00
await this . reveilReveDeDragon ( message , dormi . heures ) ;
2021-02-03 20:39:52 +01:00
}
2023-02-17 01:28:30 +01:00
options . chateauDormant = options . chateauDormant && dormi . heures >= heures ;
2023-06-24 00:58:45 +02:00
message . content += ` Vous avez dormi ${ dormi . heures <= 1 ? 'une heure' : ( dormi . heures + ' heures' ) } . ` ;
2020-11-16 04:32:42 +01:00
}
2023-02-10 02:01:43 +01:00
2021-06-26 00:55:54 +02:00
if ( ! options . grisReve ) {
ChatMessage . create ( message ) ;
}
2023-02-10 02:01:43 +01:00
if ( options . chateauDormant ) {
2023-02-07 18:06:45 +01:00
await this . dormirChateauDormant ( ) ;
}
else {
this . sheet . render ( true ) ;
}
2020-11-16 04:32:42 +01:00
}
2023-06-24 01:41:12 +02:00
async reveilReveDeDragon ( message , heures ) {
const restant = Math . max ( this . system . sommeil ? . heures - heures , 0 )
if ( restant > 0 ) {
await this . update ( { 'system.sommeil' : { heures : restant } } ) ;
}
}
2023-02-10 02:01:43 +01:00
async dormirDesHeures ( jetsReve , message , heures , options ) {
2023-02-17 01:28:30 +01:00
const dormi = { heures : 0 , etat : 'dort' } ;
for ( ; dormi . heures < heures && dormi . etat == 'dort' ; dormi . heures ++ ) {
2023-02-10 02:01:43 +01:00
await this . _recupererEthylisme ( message ) ;
if ( options . grisReve ) {
await this . recupererFatigue ( message ) ;
}
else if ( ! this . system . sommeil ? . insomnie ) {
await this . recupererFatigue ( message ) ;
dormi . etat = await this . jetRecuperationReve ( jetsReve , message ) ;
if ( dormi . etat == 'dort' && EffetsDraconiques . isDonDoubleReve ( this ) ) {
dormi . etat = await this . jetRecuperationReve ( jetsReve , message ) ;
}
}
}
return dormi ;
}
/* -------------------------------------------- */
async jetRecuperationReve ( jetsReve , message ) {
if ( this . getReveActuel ( ) < this . system . reve . seuil . value ) {
let reve = await RdDDice . rollTotal ( "1dr" ) ;
if ( reve >= 7 ) {
// Rêve de Dragon !
message . content += ` Vous faites un <strong>Rêve de Dragon</strong> de ${ reve } Points de rêve qui vous réveille! ` ;
await this . combattreReveDeDragon ( reve ) ;
jetsReve . push ( - 1 ) ;
return 'eveil' ;
}
2023-11-03 20:23:35 +01:00
else {
2023-11-04 03:42:39 +01:00
if ( ! ReglesOptionnelles . isUsing ( "recuperation-reve" ) ) {
2023-11-03 20:23:35 +01:00
ChatMessage . create ( {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
2023-11-03 20:23:35 +01:00
content : ` Pas de récupération de rêve ( ${ reve } points ignorés) `
} ) ;
jetsReve . push ( 0 ) ;
}
2023-11-03 20:21:17 +01:00
else {
await this . reveActuelIncDec ( reve ) ;
jetsReve . push ( reve ) ;
}
2023-02-10 02:01:43 +01:00
}
2023-11-03 20:23:35 +01:00
}
2023-02-10 02:01:43 +01:00
return 'dort' ;
}
2021-01-11 20:42:10 +01:00
/* -------------------------------------------- */
2020-12-19 01:14:02 +01:00
async _recupererEthylisme ( message ) {
2023-11-03 20:23:09 +01:00
if ( ! ReglesOptionnelles . isUsing ( "recuperation-ethylisme" ) ) { return ; }
2023-02-07 18:06:45 +01:00
let value = Math . min ( Number . parseInt ( this . system . compteurs . ethylisme . value ) + 1 , 1 ) ;
if ( value <= 0 ) {
message . content += ` Vous dégrisez un peu ( ${ RdDUtility . getNomEthylisme ( value ) } ). ` ;
2020-12-19 01:14:02 +01:00
}
2023-02-07 18:06:45 +01:00
await this . update ( {
2023-11-10 19:53:36 +01:00
'system.compteurs.ethylisme' : {
2023-02-07 18:06:45 +01:00
nb _doses : 0 ,
jet _moral : false ,
value : value
}
} ) ;
2020-12-19 01:14:02 +01:00
}
2020-11-17 16:30:03 +01:00
/* -------------------------------------------- */
2023-06-24 01:41:12 +02:00
async recupereEndurance ( { message , demi } ) {
2023-06-24 00:58:45 +02:00
let max = this . _computeEnduranceMax ( ) ;
if ( demi ) {
2023-06-24 01:41:12 +02:00
max = Math . floor ( max / 2 ) ;
2023-06-24 00:58:45 +02:00
}
const manquant = max - this . system . sante . endurance . value ;
2020-11-20 11:38:27 +01:00
if ( manquant > 0 ) {
await this . santeIncDec ( "endurance" , manquant ) ;
2023-02-07 18:06:45 +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 ) {
2023-06-20 23:43:24 +02:00
if ( ReglesOptionnelles . isUsing ( "appliquer-fatigue" ) ) {
2022-06-12 09:46:58 +02:00
let fatigue = this . system . sante . fatigue . value ;
2023-11-04 17:48:50 +01:00
const fatigueMin = this . getFatigueMin ( ) ;
2021-05-08 20:08:56 +02:00
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-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 ,
2023-06-14 01:48:32 +02:00
competence : this . getDraconicOuPossession ( ) ,
2021-02-06 23:58:15 +01:00
canClose : false ,
2022-11-28 16:00:49 +01:00
rencontre : await game . system . rdd . rencontresTMR . getReveDeDragon ( force ) ,
2021-02-06 23:58:15 +01:00
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 ( ) } }
}
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 ,
2022-11-23 22:41:49 +01:00
{ html : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-reve-de-dragon.html' } ,
2021-02-06 23:58:15 +01:00
{
name : 'maitrise' ,
label : 'Maîtriser le Rêve de Dragon' ,
callbacks : [
2022-12-05 15:29:00 +01: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 ) {
2022-11-07 00:04:43 +01:00
const result = rollData . rolled . isSuccess
? rollData . rencontre . system . succes
: rollData . rencontre . system . echec ;
2021-02-06 23:58:15 +01:00
2022-11-07 00:04:43 +01:00
RdDRencontre . appliquer ( result . effets , { } , 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" , [ {
2024-09-25 22:56:24 +02:00
type : ITEM _TYPES . sortreserve ,
2022-12-05 15:29:00 +01:00
name : sort . name ,
img : sort . img ,
system : { sortid : sort . _id , draconic : ( draconic ? . name ? ? sort . system . draconic ) , ptreve : ptreve , coord : coord , heurecible : 'Vaisseau' }
} ] ,
{ renderSheet : false } ) ;
2023-10-22 15:53:03 +02:00
this . tmrApp . updateTokens ( ) ;
2020-11-14 03:16:03 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2023-05-28 21:59:11 +02:00
async updateCarac ( caracName , to ) {
2021-01-14 20:51:32 +01:00
if ( caracName == "force" ) {
2023-05-28 21:59:11 +02:00
if ( Number ( to ) > 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" ) {
2023-05-28 21:59:11 +02:00
if ( to > Misc . toInt ( this . system . reve . seuil . value ) ) {
this . setPointsDeSeuil ( to ) ;
2020-11-16 04:32:42 +01:00
}
}
2021-01-11 17:54:24 +01:00
if ( caracName == "chance" ) {
2023-05-28 21:59:11 +02:00
if ( to > Misc . toInt ( this . system . compteurs . chance . value ) ) {
this . setPointsDeChance ( to ) ;
2021-01-11 17:54:24 +01:00
}
}
2023-12-10 22:13:05 +01:00
let selectedCarac = this . findCaracByName ( caracName ) ;
2023-05-28 21:59:11 +02:00
const from = selectedCarac . value
await this . update ( { [ ` system.carac. ${ caracName } .value ` ] : to } ) ;
await ExperienceLog . add ( this , XP _TOPIC . CARAC , from , to , caracName ) ;
2020-05-24 20:19:57 +02:00
}
2021-01-03 18:19:18 +01:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2023-05-28 21:59:11 +02:00
async updateCaracXP ( caracName , to ) {
2021-01-23 18:36:30 +01:00
if ( caracName == 'Taille' ) {
return ;
}
2023-12-10 22:13:05 +01:00
let selectedCarac = this . findCaracByName ( caracName ) ;
2023-05-28 21:59:11 +02:00
if ( ! selectedCarac . derivee ) {
const from = Number ( selectedCarac . xp ) ;
await this . update ( { [ ` system.carac. ${ caracName } .xp ` ] : to } ) ;
await ExperienceLog . add ( this , XP _TOPIC . XPCARAC , from , to , caracName ) ;
}
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 ;
}
2023-12-10 22:13:05 +01:00
let carac = this . findCaracByName ( caracName ) ;
2021-05-28 00:55:22 +02:00
if ( carac ) {
2024-05-02 14:08:02 +02:00
carac = foundry . utils . duplicate ( carac ) ;
2023-05-28 21:59:11 +02:00
const fromXp = Number ( carac . xp ) ;
const fromValue = Number ( carac . value ) ;
let toXp = fromXp ;
let toValue = fromValue ;
while ( toXp >= RdDCarac . getCaracNextXp ( toValue ) && toXp > 0 ) {
toXp -= RdDCarac . getCaracNextXp ( toValue ) ;
toValue ++ ;
}
carac . xp = toXp ;
carac . value = toValue ;
2022-06-12 19:40:44 +02:00
await this . update ( { [ ` system.carac. ${ caracName } ` ] : carac } ) ;
2023-05-28 21:59:11 +02:00
await ExperienceLog . add ( this , XP _TOPIC . XPCARAC , fromXp , toXp , caracName ) ;
await ExperienceLog . add ( this , XP _TOPIC . CARAC , fromValue , toValue , caracName ) ;
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 ) {
2023-05-28 21:59:11 +02:00
const fromXp = Number ( competence . system . xp ) ;
const fromNiveau = Number ( competence . system . niveau ) ;
let toXp = fromXp ;
let toNiveau = fromNiveau ;
while ( toXp >= RdDItemCompetence . getCompetenceNextXp ( toNiveau ) && toXp > 0 ) {
toXp -= RdDItemCompetence . getCompetenceNextXp ( toNiveau ) ;
toNiveau ++ ;
2021-05-28 00:55:22 +02:00
}
2021-11-23 02:04:00 +01:00
await competence . update ( {
2023-05-28 21:59:11 +02:00
"system.xp" : toXp ,
"system.niveau" : toNiveau ,
2021-05-28 00:55:22 +02:00
} ) ;
2023-05-28 21:59:11 +02:00
await ExperienceLog . add ( this , XP _TOPIC . XP , fromXp , toXp , competence . name ) ;
await ExperienceLog . add ( this , XP _TOPIC . NIVEAU , fromNiveau , toNiveau , competence . name ) ;
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 ;
}
2023-05-28 21:59:11 +02:00
const fromXp = competence . system . xp ;
const fromXpStress = this . system . compteurs . experience . value ;
const fromNiveau = Number ( competence . system . niveau ) ;
const xpSuivant = RdDItemCompetence . getCompetenceNextXp ( fromNiveau ) ;
const xpRequis = xpSuivant - fromXp ;
if ( fromXpStress <= 0 || fromNiveau >= competence . system . niveau _archetype ) {
2021-11-23 02:11:24 +01:00
ui . notifications . info ( ` La compétence ne peut pas augmenter!
2023-05-28 21:59:11 +02:00
stress disponible : $ { fromXpStress }
2021-11-23 02:11:24 +01:00
expérience requise : $ { xpRequis }
2023-05-28 21:59:11 +02:00
niveau : $ { fromNiveau }
2022-06-12 09:46:58 +02:00
archétype : $ { competence . system . niveau _archetype } ` );
2021-11-23 02:11:24 +01:00
return ;
}
2023-05-28 21:59:11 +02:00
const xpUtilise = Math . max ( 0 , Math . min ( fromXpStress , xpRequis ) ) ;
2022-12-05 15:29:00 +01:00
const gainNiveau = ( xpUtilise >= xpRequis || xpRequis <= 0 ) ? 1 : 0 ;
2023-05-28 21:59:11 +02:00
const toNiveau = fromNiveau + gainNiveau ;
const newXp = gainNiveau > 0 ? Math . max ( fromXp - xpSuivant , 0 ) : ( fromXp + xpUtilise ) ;
2021-11-23 02:11:24 +01:00
await competence . update ( {
2023-05-28 21:59:11 +02:00
"system.xp" : newXp ,
"system.niveau" : toNiveau ,
2021-11-23 02:11:24 +01:00
} ) ;
2023-05-28 21:59:11 +02:00
const toXpStress = Math . max ( 0 , fromXpStress - xpUtilise ) ;
await this . update ( { "system.compteurs.experience.value" : toXpStress } ) ;
await ExperienceLog . add ( this , XP _TOPIC . TRANSFORM , fromXpStress , toXpStress , ` Dépense stress ` ) ;
await ExperienceLog . add ( this , XP _TOPIC . XP , fromXp , newXp , competence . name ) ;
await ExperienceLog . add ( this , XP _TOPIC . NIVEAU , fromNiveau , toNiveau , competence . name ) ;
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 updateCompetence ( idOrName , compValue ) {
2023-06-14 22:25:11 +02:00
const competence = this . getCompetence ( idOrName ) ;
2021-11-23 02:04:00 +01:00
if ( competence ) {
2023-06-13 01:55:38 +02:00
const toNiveau = compValue ? ? RdDItemCompetence . getNiveauBase ( competence . system . categorie , competence . getCategories ( ) ) ;
2023-05-28 21:59:11 +02:00
this . notifyCompetencesTronc ( competence , toNiveau ) ;
const fromNiveau = competence . system . niveau ;
2023-11-21 16:03:26 +01:00
await competence . update ( { 'system.niveau' : toNiveau } ) ;
2023-05-28 21:59:11 +02:00
await ExperienceLog . add ( this , XP _TOPIC . NIVEAU , fromNiveau , toNiveau , competence . name , true ) ;
2020-06-12 22:46:04 +02:00
}
}
2021-01-09 19:33:19 +01:00
2023-05-28 21:59:11 +02:00
notifyCompetencesTronc ( competence , toNiveau ) {
const listTronc = RdDItemCompetence . getListTronc ( competence . name ) . filter ( it => {
const autreComp = this . getCompetence ( it ) ;
const niveauTr = autreComp ? . system . niveau ? ? 0 ;
return niveauTr < 0 && niveauTr < toNiveau ;
} ) ;
if ( listTronc . length > 0 ) {
ui . notifications . info (
"Vous avez modifié une compétence 'tronc'. Vérifiez que les compétences suivantes évoluent ensemble jusqu'au niveau 0 : <br>"
+ Misc . join ( listTronc , '<br>' ) ) ;
}
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2023-05-28 21:59:11 +02:00
async updateCompetenceXP ( idOrName , toXp ) {
2021-11-23 02:04:00 +01:00
let competence = this . getCompetence ( idOrName ) ;
if ( competence ) {
2023-05-28 21:59:11 +02:00
if ( isNaN ( toXp ) || typeof ( toXp ) != 'number' ) toXp = 0 ;
const fromXp = competence . system . xp ;
this . checkCompetenceXP ( idOrName , toXp ) ;
2023-11-21 16:03:26 +01:00
await competence . update ( { 'system.xp' : toXp } ) ;
2023-05-28 21:59:11 +02:00
await ExperienceLog . add ( this , XP _TOPIC . XP , fromXp , toXp , competence . name , true ) ;
if ( toXp > fromXp ) {
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
/* -------------------------------------------- */
2023-05-28 21:59:11 +02:00
async updateCompetenceXPSort ( idOrName , toXpSort ) {
2021-11-23 02:04:00 +01:00
let competence = this . getCompetence ( idOrName ) ;
if ( competence ) {
2023-05-28 21:59:11 +02:00
if ( isNaN ( toXpSort ) || typeof ( toXpSort ) != 'number' ) toXpSort = 0 ;
const fromXpSort = competence . system . xp _sort ;
2023-11-21 16:03:26 +01:00
await competence . update ( { 'system.xp_sort' : toXpSort } ) ;
2023-05-28 21:59:11 +02:00
await ExperienceLog . add ( this , XP _TOPIC . XPSORT , fromXpSort , toXpSort , competence . name , true ) ;
if ( toXpSort > fromXpSort ) {
RdDUtility . checkThanatosXP ( 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 ) {
2023-11-21 16:03:26 +01:00
let competence = this . getCompetence ( idOrName )
2021-11-23 02:04:00 +01:00
if ( competence ) {
2023-11-21 16:03:26 +01:00
await competence . update ( { 'system.niveau_archetype' : Math . max ( compValue ? ? 0 , 0 ) } ) ;
2021-01-03 19:19:02 +01:00
}
}
2021-01-09 19:33:19 +01:00
2022-09-28 01:24:20 +02:00
async deleteExperienceLog ( from , count ) {
if ( from >= 0 && count > 0 ) {
2024-05-02 14:08:02 +02:00
let expLog = foundry . utils . duplicate ( this . system . experiencelog ) ;
2022-09-28 01:24:20 +02:00
expLog . splice ( from , count ) ;
await this . update ( { [ ` system.experiencelog ` ] : expLog } ) ;
}
}
2021-05-19 23:22:07 +02:00
/* -------------------------------------------- */
2023-05-28 21:59:11 +02:00
async updateCompteurValue ( fieldName , to ) {
const from = this . system . compteurs [ fieldName ] . value
await this . update ( { [ ` system.compteurs. ${ fieldName } .value ` ] : to } ) ;
await this . addStressExperienceLog ( fieldName , from , to , fieldName , true ) ;
2020-08-29 22:52:41 +02:00
}
2021-05-19 22:44:14 +02:00
/* -------------------------------------------- */
2023-05-28 21:59:11 +02:00
async addCompteurValue ( fieldName , add , raison ) {
let from = this . system . compteurs [ fieldName ] . value ;
const to = Number ( from ) + Number ( add ) ;
await this . update ( { [ ` system.compteurs. ${ fieldName } .value ` ] : to } ) ;
await this . addStressExperienceLog ( fieldName , from , to , raison ) ;
2021-10-08 23:28:55 +02:00
}
2023-05-28 21:59:11 +02:00
async addStressExperienceLog ( topic , from , to , raison , manuel ) {
switch ( topic ) {
case 'stress' :
return await ExperienceLog . add ( this , XP _TOPIC . STRESS , from , to , raison , manuel )
case 'experience' :
return await ExperienceLog . add ( this , XP _TOPIC . TRANSFORM , from , to , raison , manuel )
2021-10-08 23:28:55 +02:00
}
}
/* -------------------------------------------- */
2023-02-07 18:06:45 +01:00
async distribuerStress ( compteur , stress , motif ) {
2023-11-04 17:48:50 +01:00
if ( game . user . isGM && this . hasPlayerOwner ) {
2021-10-08 23:28:55 +02:00
switch ( compteur ) {
2021-12-05 01:50:09 +01:00
case 'stress' : case 'experience' :
2023-02-07 18:06:45 +01:00
await this . addCompteurValue ( compteur , stress , motif ) ;
2021-12-05 01:50:09 +01:00
const message = ` ${ this . name } a reçu ${ stress } points ${ compteur == 'stress' ? "de stress" : "d'expérience" } (raison : ${ 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
/* -------------------------------------------- */
2023-11-04 17:48:50 +01:00
malusEthylisme ( ) {
2023-11-03 20:21:17 +01:00
return Math . min ( 0 , ( this . system . compteurs . ethylisme ? . value ? ? 0 ) ) ;
}
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 ;
2022-10-31 15:20:33 +01:00
if ( refoulement > 0 ) {
2022-10-21 02:27:16 +02:00
RdDConfirm . confirmer ( {
settingConfirmer : "confirmation-refouler" ,
content : ` <p>Prennez-vous le risque de refouler ${ item . name } pour ${ refoulement } points de refoulement ?</p> ` ,
title : 'Confirmer la refoulement' ,
buttonLabel : 'Refouler' ,
onAction : async ( ) => {
2022-10-31 15:20:33 +01:00
await this . ajouterRefoulement ( refoulement , ` une queue ${ item . name } ` ) ;
2022-10-21 02:27:16 +02:00
await item . delete ( ) ;
}
2022-10-31 15:20:33 +01:00
} ) ;
2022-09-16 23:27:26 +02:00
}
}
2022-12-05 15:29:00 +01:00
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2022-10-31 15:20:33 +01:00
async ajouterRefoulement ( value = 1 , refouler ) {
2023-12-22 02:21:00 +01:00
let refoulement = this . system . reve . refoulement . value + value ;
2022-10-31 15:20:33 +01:00
const roll = new Roll ( "1d20" ) ;
2024-05-31 21:48:19 +02:00
await roll . evaluate ( ) ;
2022-10-31 15:20:33 +01:00
await roll . toMessage ( { flavor : ` ${ this . name } refoule ${ refouler } pour ${ value } points de refoulement (total: ${ refoulement } ) ` } ) ;
if ( roll . total <= refoulement ) {
2021-03-20 00:09:29 +01:00
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 } ) ;
2022-10-31 15:20:33 +01:00
return roll ;
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 ( {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
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 ( {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
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. ` ,
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this )
2021-02-12 01:44:27 +01:00
} ) ;
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 ( ) {
2024-09-25 22:56:24 +02:00
return this . items . filter ( it => it . type == ITEM _TYPES . casetmr ) . filter ( it => EffetsDraconiques . isInnaccessible ( it ) ) . map ( it => it . system . coord )
2021-02-12 01:44:27 +01:00
}
2021-02-11 02:48:27 +01:00
/* -------------------------------------------- */
2024-05-26 22:13:47 +02:00
getRencontresTMR ( ) {
2024-09-25 22:56:24 +02:00
return this . itemTypes [ ITEM _TYPES . rencontre ] ;
2020-12-30 15:56:17 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2024-05-26 22:13:47 +02:00
async deleteRencontreTMRAtPosition ( ) {
2024-09-25 22:56:24 +02:00
const rencontreIds = this . itemTypes [ ITEM _TYPES . rencontre ] . filter ( this . filterRencontreTMRDemiReve ( ) ) . map ( it => it . id )
2022-12-05 15:29:00 +01:00
if ( rencontreIds . length > 0 ) {
2024-05-26 22:13:47 +02:00
await this . deleteEmbeddedDocuments ( 'Item' , rencontreIds )
2020-07-21 23:51:24 +02:00
}
}
2021-01-09 19:33:19 +01:00
2024-05-26 22:13:47 +02:00
getRencontreTMREnAttente ( ) {
2024-09-25 22:56:24 +02:00
return this . itemTypes [ ITEM _TYPES . rencontre ] . find ( this . filterRencontreTMRDemiReve ( ) )
2024-05-26 22:13:47 +02:00
}
filterRencontreTMRDemiReve ( ) {
const position = this . getDemiReve ( )
return it => it . system . coord == position
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async addTMRRencontre ( currentRencontre ) {
2022-11-07 00:04:43 +01:00
const toCreate = currentRencontre . toObject ( ) ;
2022-12-05 15:29:00 +01:00
console . log ( 'actor.addTMRRencontre(' , toCreate , ')' ) ;
2022-11-07 00:04:43 +01:00
this . createEmbeddedDocuments ( 'Item' , [ toCreate ] ) ;
2021-02-08 14:15:18 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
async updateCoordTMR ( 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 ) {
2023-11-03 20:23:35 +01:00
const 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
/* -------------------------------------------- */
2022-11-10 00:25:51 +01:00
async regainPointDeSeuil ( ) {
2022-04-30 19:15:55 +02:00
const seuil = Misc . toInt ( this . system . reve . seuil . value ) ;
2022-11-10 00:25:51 +01:00
const seuilMax = Misc . toInt ( this . system . carac . reve . value )
+ 2 * EffetsDraconiques . countAugmentationSeuil ( this ) ;
if ( seuil < seuilMax ) {
await this . setPointsDeSeuil ( Math . min ( seuil + 1 , seuilMax ) ) ;
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
2023-11-04 17:48:50 +01:00
async jetEndurance ( resteEndurance = undefined ) {
const result = super . jetEndurance ( resteEndurance ) ;
if ( result . jetEndurance == 1 ) {
ChatMessage . create ( { content : await this . _gainXpConstitutionJetEndurance ( ) } ) ;
2021-06-30 01:01:24 +02:00
}
2023-11-04 17:48:50 +01:00
return result ;
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-06-12 08:17:59 +02:00
return RdDCarac . calculSConst ( this . system . carac . constitution . value )
2021-01-03 15:40:48 +01: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-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. ` ;
}
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 ( {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
2021-11-07 21:36:11 +01:00
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 ) {
2023-11-21 21:07:37 +01:00
const startMoral = parseInt ( this . system . compteurs . moral . value )
const moralTheorique = startMoral + ajustementMoral
if ( moralTheorique > 3 ) { // exaltation
const ajoutExaltation = moralTheorique - 3
const exaltation = parseInt ( this . system . compteurs . exaltation . value ) + ajoutExaltation
await this . updateCompteurValue ( 'exaltation' , exaltation )
2020-12-16 02:54:28 +01:00
}
2023-11-21 21:07:37 +01:00
if ( moralTheorique < - 3 ) { // dissolution
const ajoutDissolution = - 3 - moralTheorique
const dissolution = parseInt ( this . system . compteurs . dissolution . value ) + ajoutDissolution
await this . updateCompteurValue ( 'dissolution' , dissolution )
2020-12-16 02:54:28 +01:00
}
2023-11-21 21:07:37 +01:00
await this . updateCompteurValue ( 'moral' , Math . max ( - 3 , Math . min ( moralTheorique , 3 ) ) ) ;
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' :
2023-02-07 21:37:43 +01:00
if ( succes && moral < 0 ) return 1 ;
2020-12-16 02:54:28 +01:00
if ( ! succes && moral > 0 ) return - 1 ;
}
return 0 ;
}
2021-01-03 18:19:18 +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 ,
2024-07-04 20:31:24 +02:00
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
}
2023-11-06 23:03:44 +01:00
async actionPrincipale ( item , onActionItem = async ( ) => { } ) {
let result = await super . actionPrincipale ( item , onActionItem )
if ( result ) { return result }
2023-11-10 19:53:36 +01:00
2023-11-06 23:03:44 +01:00
result = await this . actionNourritureboisson ( item , onActionItem )
if ( result ) { return result }
switch ( item . type ) {
2024-09-25 22:56:24 +02:00
case ITEM _TYPES . potion : return await this . consommerPotion ( item , onActionItem ) ;
case ITEM _TYPES . livre : return await this . actionLire ( item ) ;
case ITEM _TYPES . conteneur : return await item . sheet . render ( true ) ;
case ITEM _TYPES . herbe : return await this . actionHerbe ( item , onActionItem ) ;
case ITEM _TYPES . queue : case ITEM _TYPES . ombre : return await this . actionRefoulement ( item ) ;
2023-11-06 23:03:44 +01:00
}
return undefined
}
2022-12-03 22:32:32 +01:00
async actionNourritureboisson ( item , onActionItem ) {
2023-01-15 15:54:40 +01:00
switch ( item . getUtilisationCuisine ( ) ) {
2022-12-03 22:32:32 +01:00
case 'brut' : {
2023-11-06 23:03:44 +01:00
const utilisation = new Dialog ( {
2022-12-03 22:32:32 +01:00
title : "Nourriture brute" ,
2023-11-04 17:48:50 +01:00
content : ` Que faire de votre ${ item . name } ` ,
2022-12-03 22:32:32 +01:00
buttons : {
2023-12-10 22:19:30 +01:00
'cuisiner' : { icon : '<i class="fa-solid fa-utensils"></i>' , label : 'Cuisiner' , callback : async ( ) => await this . preparerNourriture ( item ) } ,
'manger' : { icon : '<i class="fa-solid fa-drumstick-bite"></i>' , label : 'Manger cru' , callback : async ( ) => await this . mangerNourriture ( item , onActionItem ) }
2022-12-03 22:32:32 +01:00
}
} ) ;
2023-11-06 23:03:44 +01:00
return utilisation . render ( true ) ;
2021-12-05 23:30:57 +01:00
}
2022-12-03 22:32:32 +01:00
case 'pret' :
2023-11-06 23:03:44 +01:00
return await this . mangerNourriture ( item , onActionItem ) ;
2021-04-12 01:03:37 +02:00
}
2023-11-06 23:03:44 +01:00
return undefined ;
2021-04-12 01:03:37 +02:00
}
2022-12-05 15:29:00 +01:00
async mangerNourriture ( item , onActionItem ) {
return ( await DialogConsommer . create ( this , item , onActionItem ) ) . render ( true ) ;
2021-04-12 01:03:37 +02:00
}
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 ) ;
}
}
2023-06-24 00:58:45 +02:00
2023-04-21 22:23:40 +02:00
async actionHerbe ( item , onActionItem = async ( ) => { } ) {
2022-12-03 22:32:32 +01:00
if ( item . isHerbeAPotion ( ) ) {
2023-04-21 22:23:40 +02:00
return DialogFabriquerPotion . create ( this , item , onActionItem ) ;
2022-12-03 22:32:32 +01:00
}
return ;
}
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' :
2022-12-03 22:32:32 +01:00
case 'herbe' : case 'faune' :
2022-11-13 21:56:23 +01:00
return await this . consommerNourritureboisson ( item . id , choix ) ;
2021-04-11 23:01:10 +02:00
case 'potion' :
return await this . consommerPotion ( item )
}
}
/* -------------------------------------------- */
2022-12-05 15:29:00 +01:00
async consommerNourritureboisson ( itemId , choix = { doses : 1 , seForcer : false , supprimerSiZero : false } , userId = undefined ) {
2022-11-13 21:56:23 +01:00
if ( userId != undefined && userId != game . user . id ) {
2022-12-28 23:36:48 +01:00
RdDBaseActor . remoteActorCall ( {
2023-08-15 17:24:01 +02:00
tokenId : this . token ? . id ,
2022-11-13 21:56:23 +01:00
actorId : this . id ,
method : 'consommerNourritureboisson' ,
args : [ itemId , choix , userId ]
} ,
2022-12-05 15:29:00 +01:00
userId )
2022-11-13 21:56:23 +01:00
return ;
}
2022-12-28 23:36:48 +01:00
const item = this . getItem ( itemId )
2023-01-15 15:54:40 +01:00
if ( ! item . getUtilisationCuisine ( ) ) {
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 ) {
2023-11-10 23:23:58 +01:00
const qualite = Math . min ( item . system . qualite , 0 )
const exotisme = item . system . exotisme
if ( exotisme < 0 || qualite < 0 ) {
const competence = qualite > 0 ? 'cuisine' : undefined
const difficulte = Math . min ( exotisme , qualite )
2023-11-21 16:03:26 +01:00
const rolled = await this . doRollCaracCompetence ( 'volonte' , competence , difficulte , { title : ` tente de surmonter l'exotisme de ${ item . name } ` } )
2023-11-10 23:23:58 +01:00
return rolled . isSuccess
2021-11-10 22:49:01 +01:00
}
return true ;
}
/* -------------------------------------------- */
async apprecier ( carac , compName , qualite , title ) {
2023-11-10 23:23:28 +01:00
const competence = this . getCompetence ( compName ) ;
const minQualite = Math . max ( 1 , competence ? . system . niveau ? ? 0 ) ;
if ( qualite <= minQualite ) {
ui . notifications . info ( ` ${ this . name } a un niveau ${ competence . system . niveau } en ${ competence . name } , trop élevé pour apprécier la qualité de ${ qualite } ` )
return ;
}
2023-11-10 23:23:58 +01:00
const rolled = await this . doRollCaracCompetence ( carac , undefined , 0 , { title } ) ;
2021-11-10 22:49:01 +01:00
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 ) {
2023-02-02 00:53:20 +01:00
await this . updateCompteurValue ( 'sust' , RdDActor . $calculNewSust ( this . system . compteurs . sust . value , sust , doses ) ) ;
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
2023-02-03 02:19:55 +01: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 ) {
2023-02-02 00:53:20 +01:00
await this . updateCompteurValue ( 'eau' , RdDActor . $calculNewSust ( this . system . compteurs . eau . value , desaltere , doses ) ) ;
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
}
2023-02-03 02:19:55 +01:00
2023-02-02 00:53:20 +01:00
static $calculNewSust ( value , sust , doses ) {
return Misc . keepDecimals ( Number ( value ) + Number ( sust ) * Number ( doses ) , 1 ) ;
}
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 ) {
2024-05-02 14:08:02 +02:00
let ethylisme = foundry . utils . 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 = {
2024-11-15 00:01:55 +01:00
alias : this . getAlias ( ) ,
2022-06-12 08:17:59 +02:00
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 ,
2023-01-19 01:39:25 +01:00
jetResistance : 'ethylisme' ,
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 ) ;
2024-05-13 01:49:42 +02:00
this . _gererExperience ( 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 ,
2023-01-13 01:38:14 +01:00
ethylisme : Number ( ethylisme . value ) ,
finalLevel : Number ( ethylisme . value ) + Number ( this . system . compteurs . moral . value )
2021-05-18 01:04:27 +02:00
}
await RdDResolutionTable . rollData ( ethylismeData . jetVolonte ) ;
2024-05-13 01:49:42 +02:00
this . _gererExperience ( 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 ( ) {
2023-11-03 20:04:02 +01:00
if ( ! ReglesOptionnelles . isUsing ( "transformation-stress" ) ) { return }
2023-05-28 21:59:11 +02:00
const fromStress = Number ( this . system . compteurs . stress . value ) ;
if ( this . system . sommeil ? . insomnie || fromStress <= 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
2023-05-28 21:59:11 +02:00
const conversion = Math . floor ( fromStress * stressRoll . factor / 100 ) ;
2023-01-20 01:38:21 +01:00
let dissolution = Math . max ( 0 , Number ( this . system . compteurs . dissolution . value ) ) ;
let exaltation = Math . max ( 0 , Number ( 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 = {
2024-11-15 00:01:55 +01:00
alias : this . getAlias ( ) ,
2022-04-30 19:15:55 +02:00
selectedCarac : this . system . carac . reve ,
2021-01-29 12:08:02 +01:00
rolled : stressRoll ,
2023-05-28 21:59:11 +02:00
stress : fromStress ,
perte : Math . min ( conversion , fromStress ) ,
2021-01-29 12:08:02 +01:00
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 ( {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
2021-01-29 12:08:02 +01:00
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-resultat-transformer-stress.html ` , stressRollData )
} ) ;
2021-02-11 02:48:27 +01:00
2023-05-28 21:59:11 +02:00
const toStress = Math . max ( fromStress - stressRollData . perte - 1 , 0 ) ;
const fromXpSress = Number ( this . system . compteurs . experience . value ) ;
const toXpStress = fromXpSress + Number ( stressRollData . xp ) ;
2023-01-21 00:17:36 +01:00
const updates = {
2023-05-28 21:59:11 +02:00
"system.compteurs.stress.value" : toStress ,
"system.compteurs.experience.value" : toXpStress ,
2023-01-21 00:17:36 +01:00
"system.compteurs.dissolution.value" : dissolution - perteDissolution ,
"system.compteurs.exaltation.value" : 0
}
await this . update ( updates ) ;
2023-05-28 21:59:11 +02:00
await ExperienceLog . add ( this , XP _TOPIC . STRESS , fromStress , toStress , 'Transformation' )
await ExperienceLog . add ( this , XP _TOPIC . TRANSFORM , fromXpSress , toXpStress , 'Transformation' )
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
/* -------------------------------------------- */
2023-12-10 22:13:05 +01:00
isCaracMax ( code ) {
if ( code == 'force' && parseInt ( this . system . carac . force . value ) >= parseInt ( this . system . carac . taille . value ) + 4 ) {
return true ;
}
return false
}
2021-05-27 19:40:45 +02:00
async checkCaracXP ( caracName , display = true ) {
2023-12-10 22:13:05 +01:00
let carac = this . findCaracByName ( 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 ) {
2024-05-02 14:08:02 +02:00
carac = foundry . utils . 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 = {
2024-11-15 00:01:55 +01:00
alias : this . getAlias ( ) ,
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 ( {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
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 ) {
2024-05-02 14:08:02 +02:00
let newCompData = foundry . utils . 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 = {
2024-11-15 00:01:55 +01:00
alias : this . getAlias ( ) ,
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 ( {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
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' ) {
2024-11-06 23:24:53 +01:00
if ( ! Misc . isFirstConnectedGM ( ) ) {
2024-08-30 23:56:20 +02:00
return
}
2022-12-01 01:22:25 +01:00
hideChatMessage = hideChatMessage == 'hide' || ( Misc . isRollModeHiddenToPlayer ( ) && ! game . user . isGM )
2023-01-19 01:39:25 +01:00
let xpData = await this . _appliquerExperience ( rollData . rolled , rollData . selectedCarac . label , rollData . competence , rollData . jetResistance ) ;
2023-12-10 22:13:05 +01:00
if ( xpData . length ) {
const content = await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-actor-gain-xp.html ` , {
actor : this ,
xpData
2024-05-13 01:49:42 +02:00
} )
2022-12-01 01:22:25 +01:00
if ( hideChatMessage ) {
2024-09-25 22:56:24 +02:00
ChatUtility . blindMessageToGM ( { content : content } )
2022-12-01 01:22:25 +01:00
}
2022-12-05 15:29:00 +01:00
else {
2022-12-01 01:22:25 +01:00
ChatMessage . create ( {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
2022-12-01 01:22:25 +01:00
content : content
} ) ;
}
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 ) {
2022-11-23 22:34:39 +01:00
if ( ! rollData . use . moral ) return ;
2021-03-18 00:41:26 +01:00
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
/* -------------------------------------------- */
2023-03-10 22:24:52 +01:00
$filterSortList ( sortList , coord ) {
2021-02-11 02:48:27 +01:00
let tmr = TMRUtility . getTMR ( coord ) ;
2023-03-10 22:24:52 +01:00
let filtered = [ ]
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' ) ) {
2023-03-10 22:24:52 +01:00
filtered . push ( sort ) ;
2022-06-12 12:14:55 +02:00
} else if ( sort . system . caseTMRspeciale . toLowerCase ( ) . includes ( 'variable' ) ) {
2023-03-10 22:24:52 +01:00
filtered . push ( sort ) ;
2022-06-12 12:14:55 +02:00
} else if ( sort . system . caseTMR . toLowerCase ( ) == tmr . type ) {
2023-03-10 22:24:52 +01:00
filtered . 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 ( ) ) ) {
2023-03-10 22:24:52 +01:00
filtered . push ( sort ) ;
2021-02-02 07:56:45 +01:00
}
}
2023-03-10 22:24:52 +01:00
return filtered ;
2021-02-02 07:56:45 +01:00
}
/* -------------------------------------------- */
2021-04-24 00:50:20 +02:00
computeDraconicAndSortIndex ( sortList ) {
2022-10-14 00:40:56 +02:00
let draconicList = this . getDraconicList ( ) ;
2021-02-11 02:48:27 +01:00
for ( let sort of sortList ) {
2024-09-26 00:55:08 +02:00
let draconicsSort = RdDItemSort . 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-02-02 07:56:45 +01:00
2020-12-08 23:07:41 +01:00
/* -------------------------------------------- */
async rollUnSort ( coord ) {
2023-04-21 22:27:47 +02:00
RdDEmpoignade . checkEmpoignadeEnCours ( this )
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 ;
}
2023-03-10 22:24:52 +01:00
// Duplication car les pts de reve sont modifiés dans le sort
2024-05-02 14:08:02 +02:00
let sorts = foundry . utils . duplicate ( this . $filterSortList ( this . itemTypes [ 'sort' ] , coord ) ) ;
2023-03-10 22:24:52 +01:00
if ( sorts . length == 0 ) {
ui . notifications . info ( ` Aucun sort disponible en ${ TMRUtility . getTMR ( coord ) . label } ! ` ) ;
return ;
}
2023-10-23 22:04:45 +02:00
2023-03-10 22:24:52 +01:00
const draconicList = this . computeDraconicAndSortIndex ( sorts ) ;
2024-05-02 14:08:02 +02:00
const reve = foundry . utils . duplicate ( this . system . carac . reve ) ;
2020-12-08 23:07:41 +01:00
2023-11-04 03:42:39 +01:00
const dialog = await this . openRollDialog ( {
2023-03-10 22:24:52 +01:00
name : 'lancer-un-sort' ,
label : 'Lancer un sort' ,
template : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html' ,
rollData : {
carac : { 'reve' : reve } ,
forceCarac : { 'reve' : reve } ,
selectedCarac : reve ,
draconicList : draconicList ,
competence : draconicList [ 0 ] ,
sortList : sorts ,
selectedSort : sorts [ 0 ] ,
tmr : TMRUtility . getTMR ( coord ) ,
diffLibre : RdDItemSort . getDifficulte ( sorts [ 0 ] , - 7 ) , // Per default at startup
coutreve : Array ( 30 ) . fill ( ) . map ( ( item , index ) => 1 + index ) ,
2020-12-28 10:17:40 +01:00
} ,
2023-10-24 00:30:00 +02:00
callbackAction : async r => {
await this . _rollUnSortResult ( r ) ;
if ( ! r . isSortReserve ) this . tmrApp ? . close ( ) ;
}
2023-03-10 22:24:52 +01:00
} ) ;
2023-10-22 15:53:03 +02:00
this . tmrApp ? . setTMRPendingAction ( dialog ) ;
2020-12-08 23:07:41 +01:00
}
2020-12-30 15:18:58 +01:00
/* -------------------------------------------- */
2022-11-07 00:04:43 +01:00
isMauvaiseRencontre ( ) { // 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 ,
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this )
2021-01-09 19:33:19 +01:00
} ) ;
2020-12-30 15:18:58 +01:00
}
return rencSpecial ;
}
2020-12-30 15:31:43 +01:00
/* -------------------------------------------- */
2023-11-04 03:42:39 +01:00
getCoutFatigueTMR ( ) { // 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. ` ,
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this )
2021-01-09 19:33:19 +01:00
} ) ;
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)." ,
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this )
2021-01-09 19:33:19 +01:00
} ) ;
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
}
2023-12-10 22:13:05 +01:00
let reveActuel = parseInt ( 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 ;
2024-05-01 09:13:21 +02:00
foundry . utils . 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
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 !" } ) ;
}
2020-12-08 23:07:41 +01:00
}
2023-03-10 22:25:53 +01:00
/ * *
* Méthode pour faire un jet prédéterminer sans ouvrir la fenêtre de dialogue
* @ param { * } caracName
* @ param { * } compName
* @ param { * } diff
* @ param { * } options
* @ returns
* /
2023-11-10 23:23:28 +01:00
async doRollCaracCompetence ( caracName , compName , diff , options = { title : "" } ) {
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-03-25 00:14:56 +01:00
let rollData = {
2024-11-15 00:01:55 +01:00
alias : this . getAlias ( ) ,
2021-03-25 00:14:56 +01:00
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 ) ;
2024-05-13 01:49:42 +02:00
this . _gererExperience ( 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
/* -------------------------------------------- */
2024-05-13 01:49:42 +02:00
_gererExperience ( rollData ) {
2021-04-20 00:52:25 +02:00
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-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 ;
2023-03-14 02:38:21 +01:00
const filterTacheLecture = it => it . type == 'tache' && it . name == nomTache ;
let tachesExistantes = this . filterItems ( filterTacheLecture ) ;
2021-05-04 15:18:32 +02:00
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 ) ;
2023-03-14 02:38:21 +01:00
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
}
2023-03-10 22:41:11 +01:00
blessuresASoigner ( ) {
2024-09-25 22:56:24 +02:00
return ( this . itemTypes [ ITEM _TYPES . blessure ] )
2023-12-08 18:56:59 +01:00
. filter ( it => it . system . gravite > 0 && it . system . gravite <= 6 )
. filter ( it => ! ( it . system . premierssoins . done && it . system . soinscomplets . done ) )
. sort ( Misc . descending ( b => ( b . system . premierssoins . done ? "A" : "B" ) + b . system . gravite ) )
2023-03-10 22:41:11 +01:00
}
async getTacheBlessure ( blesse , blessure ) {
const gravite = blessure ? . system . gravite ? ? 0 ;
if ( gravite > 0 ) {
2023-04-21 22:23:40 +02:00
const tache = this . itemTypes [ 'tache' ] . find ( it => it . system . itemId == blessure . id )
2023-03-10 22:41:11 +01:00
? ? await RdDItemBlessure . createTacheSoinBlessure ( this , gravite ) ;
await blessure ? . updateTacheSoinBlessure ( tache ) ;
return tache
2023-01-19 02:42:25 +01:00
}
2023-03-10 22:41:11 +01:00
return undefined ;
}
2023-03-10 22:26:38 +01:00
async rollCaracCompetence ( caracName , compName , diff , options = { title : "" } ) {
2023-04-21 22:27:47 +02:00
RdDEmpoignade . checkEmpoignadeEnCours ( this )
2023-03-10 22:26:38 +01:00
const competence = this . getCompetence ( compName ) ;
2023-11-04 03:42:39 +01:00
await this . openRollDialog ( {
2023-03-10 22:26:38 +01:00
name : 'jet-competence' ,
label : 'Jet ' + Grammar . apostrophe ( 'de' , competence . name ) ,
template : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' ,
rollData : {
2024-11-15 00:01:55 +01:00
alias : this . getAlias ( ) ,
2023-03-10 22:26:38 +01:00
carac : this . system . carac ,
selectedCarac : this . getCaracByName ( caracName ) ,
selectedCaracName : caracName ,
diffLibre : diff ,
competence : competence ,
show : { title : options ? . title ? ? '' }
} ,
2023-03-10 22:41:11 +01:00
callbackAction : r => this . $onRollCompetence ( r , options )
2023-03-10 22:26:38 +01:00
} ) ;
2023-01-19 02:42:25 +01:00
}
2021-01-09 19:33:19 +01:00
/* -------------------------------------------- */
2023-03-10 22:24:52 +01:00
async rollTache ( id , options = { } ) {
2023-04-21 22:27:47 +02:00
RdDEmpoignade . checkEmpoignadeEnCours ( this )
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
2023-11-04 03:42:39 +01:00
await this . openRollDialog ( {
2023-03-10 22:24:52 +01:00
name : 'jet-competence' ,
label : 'Jet de Tâche ' + tacheData . name ,
template : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' ,
rollData : {
competence : compData ,
tache : tacheData ,
diffLibre : tacheData . system . difficulte ,
diffConditions : 0 ,
use : { libre : false , conditions : true } ,
carac : {
2024-05-02 14:08:02 +02:00
[ tacheData . system . carac ] : foundry . utils . duplicate ( this . system . carac [ tacheData . system . carac ] )
2023-03-10 22:24:52 +01:00
}
} ,
callbackAction : r => this . _tacheResult ( r , options )
} ) ;
2020-12-15 08:37:52 +01:00
}
/* -------------------------------------------- */
2023-03-10 22:24:52 +01:00
async _tacheResult ( rollData , options ) {
2020-12-15 21:28:55 +01:00
// Mise à jour de la tache
2023-06-20 23:43:24 +02:00
rollData . appliquerFatigue = ReglesOptionnelles . isUsing ( "appliquer-fatigue" ) ;
2024-05-02 14:08:02 +02:00
rollData . tache = foundry . utils . 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' ) ;
2023-03-10 22:41:11 +01:00
if ( options ? . onRollAutomate ) {
options . onRollAutomate ( rollData ) ;
}
2020-12-15 08:37:52 +01:00
}
2021-01-27 23:35:45 +01:00
/* -------------------------------------------- */
2023-03-10 22:24:52 +01:00
async _rollArt ( artData , selected , oeuvre , callbackAction = r => this . _resultArt ( r ) ) {
2022-12-05 15:29:00 +01:00
oeuvre . system . niveau = oeuvre . system . niveau ? ? 0 ;
2024-05-01 09:13:21 +02:00
foundry . utils . mergeObject ( artData ,
2021-04-21 00:59:10 +02:00
{
oeuvre : oeuvre ,
art : oeuvre . type ,
2024-05-02 14:08:02 +02:00
competence : foundry . utils . duplicate ( this . getCompetence ( artData . compName ? ? oeuvre . system . competence ? ? artData . art ) ) ,
2022-12-05 15:29:00 +01:00
diffLibre : - oeuvre . system . niveau ,
2021-04-21 00:59:10 +02:00
diffConditions : 0 ,
2022-12-05 01:52:49 +01:00
use : { libre : false , conditions : true , surenc : false } ,
2024-05-02 14:08:02 +02:00
selectedCarac : foundry . utils . 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 = { } ;
2024-05-02 14:08:02 +02:00
artData . forceCarac [ selected ] = foundry . utils . duplicate ( this . system . carac [ selected ] ) ;
2021-02-14 18:31:00 +01:00
}
2023-03-10 22:24:52 +01:00
2023-11-04 03:42:39 +01:00
await this . openRollDialog ( {
2023-03-10 22:24:52 +01:00
name : ` jet- ${ artData . art } ` ,
label : ` ${ artData . verbe } ${ oeuvre . name } ` ,
template : ` systems/foundryvtt-reve-de-dragon/templates/dialog-roll- ${ oeuvre . type } .html ` ,
rollData : artData ,
callbackAction : callbackAction
} ) ;
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 _resultArt ( artData ) {
2022-12-03 22:32:32 +01:00
const niveau = artData . oeuvre . system . niveau ? ? 0 ;
const baseQualite = ( artData . rolled . isSuccess ? niveau : artData . competence . system . niveau ) ;
artData . qualiteFinale = Math . min ( baseQualite , 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' } ;
2024-05-02 14:08:02 +02:00
const oeuvre = foundry . utils . duplicate ( this . getChant ( id ) ) ;
2021-02-06 01:34:01 +01:00
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 : { } } ;
2024-05-02 14:08:02 +02:00
const oeuvre = foundry . utils . duplicate ( this . findItemLike ( id , artData . art ) ) ;
2022-05-01 23:37:52 +02:00
if ( oeuvre . system . agilite ) {
2024-05-02 14:08:02 +02:00
artData . forceCarac [ 'agilite' ] = foundry . utils . 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 ) {
2024-05-02 14:08:02 +02:00
artData . forceCarac [ 'apparence' ] = foundry . utils . 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-12-28 23:36:48 +01:00
const oeuvre = this . findItemLike ( 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
/* -------------------------------------------- */
2022-12-03 22:32:32 +01:00
async _resultRecetteCuisine ( cuisine ) {
const niveauRecette = cuisine . oeuvre . system . niveau ? ? 0 ;
const baseQualite = ( cuisine . rolled . isSuccess ? niveauRecette : cuisine . competence . system . niveau ) ;
cuisine . qualiteFinale = Math . min ( baseQualite , niveauRecette ) + cuisine . rolled . ptQualite ;
cuisine . exotismeFinal = Math . min ( Math . min ( cuisine . qualiteFinale , cuisine . oeuvre . system . exotisme ? ? 0 ) , 0 ) ;
cuisine . sust = cuisine . oeuvre . system . sust * Math . min ( cuisine . proportions , cuisine . proportionsMax ? ? cuisine . proportions )
2021-04-08 20:36:02 +02:00
const platCuisine = {
2022-12-03 22:32:32 +01:00
name : cuisine . oeuvre . name ,
2021-04-08 20:36:02 +02:00
type : 'nourritureboisson' ,
img : 'systems/foundryvtt-reve-de-dragon/icons/objets/provision_cuite.webp' ,
2022-06-12 19:40:44 +02:00
system : {
2022-12-03 22:32:32 +01:00
"description" : cuisine . oeuvre . system . description ,
"sust" : 1 ,
"qualite" : cuisine . qualiteFinale ,
"exotisme" : cuisine . exotismeFinal ,
"encombrement" : 0.1 ,
"quantite" : Math . max ( 1 , Math . floor ( cuisine . sust ) ) ,
"cout" : Math . max ( cuisine . qualiteFinale ) * 0.01
2021-04-08 20:36:02 +02:00
}
2022-12-03 22:32:32 +01:00
}
if ( cuisine . 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
}
2022-12-03 22:32:32 +01:00
cuisine . platCuisine = platCuisine ;
await RdDResolutionTable . displayRollData ( cuisine , this . name , ` chat-resultat- ${ cuisine . art } .html ` ) ;
}
async preparerNourriture ( item ) {
2023-01-15 15:54:40 +01:00
if ( item . getUtilisationCuisine ( ) == 'brut' ) {
2022-12-03 22:32:32 +01:00
const nourriture = {
name : 'Plat de ' + item . name ,
type : 'recettecuisine' ,
img : item . img ,
system : {
2023-11-06 23:04:35 +01:00
sust : item . system . sust ,
2022-12-03 22:32:32 +01:00
exotisme : item . system . exotisme ,
ingredients : item . name
}
} ;
const artData = {
verbe : 'Préparer' ,
compName : 'cuisine' ,
proportions : 1 ,
2023-11-06 23:04:35 +01:00
proportionsMax : Math . min ( 50 , item . system . quantite ) ,
2022-12-03 22:32:32 +01:00
ajouterEquipement : true
} ;
await this . _rollArt ( artData , 'odoratgout' , nourriture , async ( cuisine ) => {
await this . _resultRecetteCuisine ( cuisine ) ;
const remaining = Math . max ( item . system . quantite - cuisine . proportions , 0 ) ;
if ( remaining > 0 ) {
await item . update ( { 'system.quantite' : remaining } )
}
else {
await this . deleteEmbeddedDocuments ( 'Item' , [ item . id ] ) ;
}
} ) ;
}
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 , } ,
2024-05-02 14:08:02 +02:00
competence : foundry . utils . 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' }
2024-05-02 14:08:02 +02:00
const oeuvre = foundry . utils . duplicate ( this . findItemLike ( id , artData . art ) )
2022-06-12 08:17:59 +02:00
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 ) {
2024-05-02 14:08:02 +02:00
const meditation = foundry . utils . duplicate ( this . getMeditation ( id ) ) ;
const competence = foundry . utils . 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 ,
2022-11-23 22:41:49 +01:00
{ html : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-meditation.html' } ,
2021-04-21 20:43:03 +02:00
{
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 ) ;
2023-04-21 22:23:40 +02:00
return this . itemTypes [ "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 ;
}
let draconicList = this . getDraconicList ( )
2022-09-07 18:47:56 +02:00
. map ( draconic => {
2024-05-02 14:08:02 +02:00
let draconicLecture = foundry . utils . duplicate ( draconic ) ;
2022-09-07 18:47:56 +02:00
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' ,
2023-11-04 03:42:39 +01:00
close : async html => await this . _onCloseRollDialog ( html )
2021-05-10 19:18:11 +02:00
} ,
{
name : 'lire-signe-draconique' ,
label : 'Lire le signe draconique' ,
callbacks : [
this . createCallbackExperience ( ) ,
{ action : r => this . _rollLireSigneDraconique ( r ) }
]
}
) ;
dialog . render ( true ) ;
2023-10-22 15:53:03 +02:00
this . tmrApp ? . setTMRPendingAction ( dialog ) ;
2021-05-10 19:18:11 +02:00
}
2023-11-04 03:42:39 +01:00
async _onCloseRollDialog ( html ) {
this . tmrApp ? . restoreTMRAfterAction ( )
2023-11-04 17:48:50 +01:00
}
2023-11-04 03:42:39 +01:00
2021-05-10 19:18:11 +02:00
/* -------------------------------------------- */
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 ) {
2023-05-28 21:59:11 +02:00
const fromXp = Number ( compData . system . xp _sort ) ;
const toXp = fromXp + rollData . xpSort ;
await this . updateEmbeddedDocuments ( "Item" , [ { _id : compData . _id , 'system.xp_sort' : toXp } ] ) ;
await ExperienceLog . add ( this , XP _TOPIC . XPSORT , fromXp , toXp , ` ${ rollData . competence . name } : signe draconique ` ) ;
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' ) ;
2023-10-22 15:53:03 +02:00
this . tmrApp . 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
/* -------------------------------------------- */
2023-03-10 22:41:11 +01:00
async rollAppelChance ( onSuccess = ( ) => { } , onEchec = ( ) => { } ) {
2023-11-04 03:42:39 +01:00
await this . openRollDialog ( {
2023-03-10 22:24:52 +01:00
name : 'appelChance' ,
label : 'Appel à la chance' ,
template : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html' ,
rollData : { selectedCarac : this . getCaracByName ( 'chance-actuelle' ) , surprise : '' } ,
callbackAction : r => this . _appelChanceResult ( r , onSuccess , onEchec )
} ) ;
2021-01-09 19:33:19 +01:00
}
/* -------------------------------------------- */
2023-03-10 22:24:52 +01:00
async _appelChanceResult ( rollData , onSuccess , onEchec ) {
2021-01-09 19:33:19 +01:00
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 ( ) {
2023-11-04 17:48:50 +01:00
return this . system . heure ? ? 0 ;
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-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
}
2023-11-04 17:48:50 +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' )
2022-11-26 16:23:53 +01:00
. filter ( it => it . system . categorie == 'lancinant' ) ;
2020-12-14 10:38:43 +01:00
return ( queue . length > 0 ) ;
}
/* -------------------------------------------- */
2023-01-19 01:39:25 +01:00
async _appliquerExperience ( rolled , caracName , competence , jetResistance ) {
2021-05-27 19:40:45 +02:00
// Pas d'XP
if ( ! rolled . isPart || rolled . finalLevel >= 0 ) {
2024-05-13 01:49:42 +02:00
return [ ]
2021-05-27 19:40:45 +02:00
}
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 ` ,
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this )
2021-05-27 19:40:45 +02:00
} ) ;
2024-05-13 01:49:42 +02:00
return [ ]
2021-05-27 19:40:45 +02:00
}
2023-12-10 22:13:05 +01:00
2021-05-27 19:40:45 +02:00
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 ) ;
2023-01-19 01:39:25 +01:00
const xpCompetence = competence ? xp - xpCarac : 0 ;
if ( jetResistance ) {
const message = ` Jet de résistance ${ jetResistance } , l'expérience est limitée à 1 ` ;
ui . notifications . info ( message ) ;
console . log ( message )
// max 1 xp sur jets de résistance
xpCarac = Math . min ( 1 , xpCarac ) ;
}
2023-12-10 22:13:05 +01:00
return [
... ( await this . _xpCompetence ( { competence , xpCompetence } ) ) ,
... ( await this . _xpCarac ( { caracName , xpCarac } ) )
] ;
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 _xpCompetence ( xpData ) {
if ( xpData . competence ) {
2023-05-28 21:59:11 +02:00
const from = Number ( xpData . competence . system . xp ) ;
const to = from + xpData . xpCompetence ;
2023-12-10 22:13:05 +01:00
await this . updateEmbeddedDocuments ( 'Item' , [ { _id : xpData . competence . _id , 'system.xp' : to } ] ) ;
2021-05-27 19:40:45 +02:00
xpData . checkComp = await this . checkCompetenceXP ( xpData . competence . name , undefined , false ) ;
2023-05-28 21:59:11 +02:00
await ExperienceLog . add ( this , XP _TOPIC . XP , from , to , xpData . competence . name ) ;
2023-12-10 22:13:05 +01:00
return [ xpData ]
2021-05-27 19:40:45 +02:00
}
2023-12-10 22:13:05 +01:00
return [ ]
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 ) {
2024-05-02 14:08:02 +02:00
const carac = foundry . utils . duplicate ( this . system . carac )
2023-12-10 22:13:05 +01:00
const code = RdDBaseActor . _findCaracNode ( carac , xpData . caracName )
const selectedCarac = carac [ code ]
if ( this . isCaracMax ( code ) ) {
ui . notifications . info ( ` Pas d'expérience: la caractéristique ' ${ selectedCarac . label } ' est déjà au maximum pour ${ this . name } ` )
return [ ]
}
if ( selectedCarac && ! selectedCarac . derivee ) {
const from = Number ( selectedCarac . xp )
const to = from + xpData . xpCarac
selectedCarac . xp = to
await this . update ( { "system.carac" : carac } )
xpData . checkCarac = await this . checkCaracXP ( selectedCarac . label , false )
await ExperienceLog . add ( this , XP _TOPIC . XPCARAC , from , to , xpData . caracName )
return [ xpData ]
2020-12-15 08:37:52 +01:00
} else {
2023-12-10 22:13:05 +01:00
return await this . _xpCaracDerivee ( xpData )
2020-12-13 23:32:16 +01:00
}
}
2023-12-10 22:13:05 +01:00
return [ ]
}
async _xpCaracDerivee ( xpData ) {
const caracs = RdDActor . _getComposantsCaracDerivee ( xpData . caracName )
2024-06-01 01:53:14 +02:00
. map ( c => foundry . utils . mergeObject ( this . system . carac [ c ] , { isMax : this . isCaracMax ( c ) } , { inplace : false } ) )
2023-12-10 22:13:05 +01:00
switch ( caracs . filter ( it => ! it . isMax ) . length ) {
case 0 :
xpData . caracRepartitionManuelle = true ;
return [ xpData ]
case 1 :
xpData . caracName = caracs . find ( it => ! it . isMax ) . label
return this . _xpCarac ( xpData )
default :
await DialogChoixXpCarac . choix ( this , xpData , caracs )
return [ ]
}
2020-12-13 23:32:16 +01:00
}
2021-01-09 19:33:19 +01:00
2023-12-10 22:13:05 +01:00
static _getComposantsCaracDerivee ( caracName ) {
switch ( Grammar . toLowerCaseNoAccent ( caracName ) ) {
2024-05-26 22:15:10 +02:00
case 'reve-actuel' : case 'reve actuel' : return [ 'reve' ]
case 'chance-actuelle' : case 'chance actuelle' : return [ 'chance' ]
2023-12-10 22:13:05 +01:00
case 'vie' : return [ 'constitution' ]
case 'tir' : return [ 'vue' , 'dexterite' ]
case 'lancer' : return [ 'force' , 'dexterite' , 'vue' ]
case 'melee' : return [ 'force' , 'agilite' ]
case 'derobee' : return [ 'agilite' ]
}
return [ ]
}
2021-06-01 21:58:40 +02:00
/* -------------------------------------------- */
2024-05-12 22:40:06 +02:00
async deleteNombresAstraux ( ) {
2023-04-21 22:23:40 +02:00
const deletions = this . itemTypes [ 'nombreastral' ] . map ( it => it . _id ) ;
2021-06-01 21:58:40 +02:00
await this . deleteEmbeddedDocuments ( "Item" , deletions ) ;
}
2021-06-26 00:55:54 +02:00
2020-12-13 23:11:58 +01:00
/* -------------------------------------------- */
2024-05-12 22:40:06 +02:00
async ajouteNombreAstral ( date , nbAstral , isValid ) {
const indexDate = Number . parseInt ( date ) ;
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 :
2023-01-05 00:55:04 +01:00
{
2024-05-12 22:40:06 +02:00
value : nbAstral ,
istrue : isValid ,
2023-01-05 00:55:04 +01:00
jourindex : indexDate ,
jourlabel : RdDTimestamp . formatIndexDate ( indexDate )
}
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-06 19:29:10 +01:00
2022-12-29 02:31:29 +01:00
async supprimerAnciensNombresAstraux ( ) {
2023-03-08 02:02:40 +01:00
const calendrier = game . system . rdd . calendrier ;
if ( calendrier ) {
2023-04-21 22:23:40 +02:00
const toDelete = this . itemTypes [ 'nombreastral' ]
2023-03-08 02:02:40 +01:00
. filter ( it => calendrier . isAfterIndexDate ( it . system . jourindex ) )
. map ( it => it . _id ) ;
await this . deleteEmbeddedDocuments ( "Item" , toDelete ) ;
}
2022-12-29 02:31:29 +01:00
}
2020-12-11 08:29:24 +01:00
/* -------------------------------------------- */
2021-01-09 19:33:19 +01:00
async astrologieNombresAstraux ( ) {
2022-12-29 02:31:29 +01:00
await this . supprimerAnciensNombresAstraux ( ) ;
2023-03-08 02:02:40 +01:00
await AppAstrologie . create ( this ) ;
2020-12-11 08:29:24 +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. ` ,
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this )
2021-01-09 19:33:19 +01:00
} ) ;
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 ( ) {
2023-10-22 15:53:03 +02:00
if ( this . tmrApp ) {
this . tmrApp . 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 ) {
2024-05-26 22:13:47 +02:00
ui . notifications . warn ( "Vous êtes déja dans les TMR...." )
this . tmrApp . forceTMRDisplay ( )
2021-05-28 09:43:15 +02:00
return
}
2022-12-05 15:29:00 +01:00
if ( mode != 'visu' && this . getEffect ( STATUSES . StatusDemiReve ) ) {
2024-05-26 22:13:47 +02:00
ui . notifications . warn ( "Les personnage est déjà dans les Terres Médianes, elles s'affichent en visualisation" )
2021-05-26 16:28:57 +02:00
mode = "visu" ; // bascule le mode en visu automatiquement
2021-05-24 09:39:42 +02:00
}
2024-05-26 22:13:47 +02:00
if ( mode == 'visu' ) {
await this . _doDisplayTMR ( mode )
}
else {
const rencontre = this . getRencontreTMREnAttente ( ) ;
const settingConfirmer = rencontre ? "confirmation-tmr-rencontre" : "confirmation-tmr" ;
const messageRencontre = rencontre ? ` <p>Vous devrez combattre ${ rencontre . system . genre == 'f' ? 'la' : 'le' } ${ rencontre . name } de ${ rencontre . system . force } points de Rêve</p> ` : '' ;
RdDConfirm . confirmer ( {
settingConfirmer : settingConfirmer ,
content : ` <p>Voulez vous monter dans les TMR en mode ${ mode } ?</p> ` + messageRencontre ,
title : 'Confirmer la montée dans les TMR' ,
buttonLabel : 'Monter dans les TMR' ,
onAction : async ( ) => await this . _doDisplayTMR ( mode )
} )
}
2022-10-04 23:23:43 +02:00
}
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 ` ,
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this )
2021-01-09 19:33:19 +01:00
} ) ;
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 ( ) ,
2023-04-21 22:23:40 +02:00
sort : this . itemTypes [ 'sort' ] ,
signes : this . itemTypes [ 'signedraconique' ] ,
2023-12-10 22:13:05 +01:00
caracReve : parseInt ( this . system . carac . reve . value ) ,
2020-12-06 18:41:54 +01:00
pointsReve : this . getReveActuel ( ) ,
2022-11-18 03:38:17 +01:00
isRapide : isRapide ,
isGM : game . user . isGM ,
hasPlayerOwner : this . hasPlayerOwner
2021-01-09 19:33:19 +01:00
}
2021-05-28 09:37:22 +02:00
2023-10-22 15:53:03 +02:00
this . tmrApp = await RdDTMRDialog . create ( this , tmrFormData ) ;
2023-11-15 22:14:00 +01:00
await this . tmrApp . render ( true ) ;
await this . tmrApp . onDeplacement ( )
2020-12-06 18:41:54 +01:00
}
2020-12-08 03:04:00 +01:00
2023-10-04 09:07:46 +02:00
/* -------------------------------------------- */
2023-03-10 22:41:11 +01:00
async rollSoins ( blesse , blessureId ) {
const blessure = blesse . blessuresASoigner ( ) . find ( it => it . id == blessureId ) ;
if ( blessure ) {
if ( ! blessure . system . premierssoins . done ) {
const tache = await this . getTacheBlessure ( blesse , blessure ) ;
return await this . rollTache ( tache . id , {
onRollAutomate : async r => blesse . onRollTachePremiersSoins ( blessureId , r )
} ) ;
}
if ( ! blessure . system . soinscomplets . done ) {
const diff = blessure . system . difficulte + ( blessure . system . premierssoins . bonus ? ? 0 ) ;
return await this . rollCaracCompetence ( "dexterite" , "Chirurgie" , diff , {
title : "Soins complets" ,
onRollAutomate : r => blesse . onRollSoinsComplets ( blessureId , r )
} )
}
}
}
async onRollTachePremiersSoins ( blessureId , rollData ) {
if ( ! this . isOwner ) {
2023-08-15 17:24:01 +02:00
return RdDBaseActor . remoteActorCall ( { tokenId : this . token ? . id , actorId : this . id , method : 'onRollTachePremiersSoins' , args : [ blessureId , rollData ] } ) ;
2023-03-10 22:41:11 +01:00
}
const blessure = this . getItem ( blessureId , 'blessure' )
console . log ( 'TODO update blessure' , this , blessureId , rollData , rollData . tache ) ;
if ( blessure && ! blessure . system . premierssoins . done ) {
const tache = rollData . tache ;
if ( rollData . rolled . isETotal ) {
await blessure . update ( {
'system.difficulte' : blessure . system . difficulte - 1 ,
'system.premierssoins.tache' : Math . max ( 0 , tache . system . points _de _tache _courant )
} )
}
else {
const bonus = tache . system . points _de _tache _courant - tache . system . points _de _tache
await blessure . update ( {
'system.premierssoins' : {
done : ( bonus >= 0 ) ,
bonus : Math . max ( 0 , bonus ) ,
tache : Math . max ( 0 , tache . system . points _de _tache _courant )
}
} )
2023-03-14 02:38:21 +01:00
if ( bonus >= 0 ) {
await this . deleteEmbeddedDocuments ( 'Item' , [ tache . id ] )
2023-03-10 22:41:11 +01:00
}
}
}
}
async onRollSoinsComplets ( blessureId , rollData ) {
if ( ! this . isOwner ) {
2023-08-15 17:24:01 +02:00
return RdDBaseActor . remoteActorCall ( { tokenId : this . token ? . id , actorId : this . id , method : 'onRollSoinsComplets' , args : [ blessureId , rollData ] } ) ;
2023-03-10 22:41:11 +01:00
}
const blessure = this . getItem ( blessureId , 'blessure' )
if ( blessure && blessure . system . premierssoins . done && ! blessure . system . soinscomplets . done ) {
// TODO: update de la blessure: passer par le MJ!
if ( rollData . rolled . isETotal ) {
await blessure . setSoinsBlessure ( {
difficulte : blessure . system . difficulte - 1 ,
premierssoins : { done : false , bonus : 0 } , soinscomplets : { done : false , bonus : 0 } ,
} )
}
else {
// soins complets finis
await blessure . setSoinsBlessure ( {
soinscomplets : { done : true , bonus : Math . max ( 0 , rollData . rolled . ptTache ) } ,
} )
}
}
2020-12-06 18:41:54 +01:00
}
2020-12-01 17:36:13 +01:00
2020-12-17 09:29:09 +01:00
/* -------------------------------------------- */
2022-11-22 02:12:26 +01:00
conjurerPossession ( possession ) {
2023-06-14 01:48:32 +02:00
RdDPossession . onConjurerPossession ( this , possession )
2020-12-01 17:36:13 +01:00
}
2021-01-09 19:33:19 +01:00
2021-02-09 11:17:17 +01:00
/* -------------------------------------------- */
2022-09-07 18:47:56 +02:00
verifierForceMin ( item ) {
2023-12-10 22:13:05 +01:00
if ( item . type == 'arme' && item . system . force > parseInt ( 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 ) ;
2023-04-18 22:16:18 +02:00
if ( item ? . isEquipable ( ) ) {
2022-06-12 09:46:58 +02:00
const isEquipe = ! item . system . equipe ;
2023-11-21 16:03:26 +01:00
await item . update ( { "system.equipe" : isEquipe } ) ;
2023-11-04 03:42:39 +01:00
this . computeEncTotal ( ) ;
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 ( ) ) ;
2023-05-24 21:59:17 +02:00
if ( dmg > 0 && attackerRoll . dmg . encaisserSpecial != "noarmure" ) {
armure . deteriorerArmure ( 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-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 ( ) {
2024-11-03 23:31:56 +01:00
await this . unsetFlag ( 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 ) {
2024-06-11 02:48:37 +02:00
const currentItemUse = this . getFlag ( SYSTEM _RDD , 'itemUse' ) ;
let itemUse = currentItemUse ? foundry . utils . duplicate ( currentItemUse ) : { } ;
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
/* -------------------------------------------- */
2021-04-20 23:16:18 +02:00
async effectuerTacheAlchimie ( recetteId , tacheAlchimie , texteTache ) {
2022-12-28 23:36:48 +01:00
let recetteData = this . findItemLike ( 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 ,
2022-11-23 22:41:49 +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
/* -------------------------------------------- */
2023-11-21 16:03:26 +01:00
static $transformSubActeurSuivant = ( suivant , link ) => {
2024-05-01 09:13:21 +02:00
return foundry . utils . mergeObject ( RdDBaseActor . extractActorMin ( suivant ) , {
2023-11-21 21:07:37 +01:00
ephemere : ! suivant . prototypeToken . actorLink ,
2023-11-27 23:45:33 +01:00
coeur : link . coeur ? ? 0 ,
prochainCoeur : link . prochainCoeur ? ? link . coeur ? ? 0
2023-11-21 16:03:26 +01:00
} )
} ;
listeSuivants ( filter = suivant => true ) {
return RdDActor . $buildSubActorLinks (
this . system . subacteurs . suivants . filter ( filter ) , RdDActor . $transformSubActeurSuivant
)
2021-01-11 16:29:41 +01:00
}
2023-11-27 23:45:33 +01:00
getSuivant ( subActorId ) {
const suivant = this . system . subacteurs . suivants . find ( it => it . id == subActorId ) ;
2023-11-21 16:03:26 +01:00
if ( suivant ) {
2023-11-27 23:45:33 +01:00
return RdDActor . $transformSubActeurSuivant ( game . actors . get ( suivant . id ) , suivant ) ;
2023-11-21 16:03:26 +01:00
}
return undefined
2021-01-11 16:29:41 +01:00
}
2023-11-27 23:45:33 +01:00
getPointsCoeur ( subActorId ) {
return this . getSuivant ( subActorId ) ? . coeur ? ? 0 ;
2023-11-21 21:07:37 +01:00
}
2023-11-27 23:45:33 +01:00
async setPointsCoeur ( subActorId , coeurs , options = { immediat : false } ) {
2024-05-02 14:08:02 +02:00
const newSuivants = foundry . utils . duplicate ( this . system . subacteurs . suivants )
2023-11-27 23:45:33 +01:00
const amoureux = newSuivants . find ( it => it . id == subActorId ) ;
2023-11-21 21:07:37 +01:00
if ( amoureux ) {
2023-11-27 23:45:33 +01:00
amoureux [ options . immediat ? 'coeur' : 'prochainCoeur' ] = coeurs
2023-11-21 21:07:37 +01:00
await this . update ( { 'system.subacteurs.suivants' : newSuivants } ) ;
}
}
2021-01-11 16:29:41 +01:00
/* -------------------------------------------- */
2023-11-21 16:03:26 +01:00
static $transformSubActeurVehicule = ( vehicle , link ) => {
2024-05-01 09:13:21 +02:00
return foundry . utils . mergeObject ( RdDBaseActor . extractActorMin ( vehicle ) , {
2023-11-21 16:03:26 +01:00
system : { categorie : vehicle . system . categorie , etat : vehicle . system . etat }
} )
} ;
listeVehicules ( ) {
return RdDActor . $buildSubActorLinks ( this . system . subacteurs . vehicules , RdDActor . $transformSubActeurVehicule )
2021-01-11 16:29:41 +01:00
}
2021-01-22 02:08:49 +01:00
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2023-11-27 14:32:39 +01:00
static $transformSubActeurCreature = ( actor , link ) => RdDBaseActor . extractActorMin ( actor )
2023-11-21 16:03:26 +01:00
listeMontures ( ) {
return RdDActor . $buildSubActorLinks ( this . system . subacteurs . montures , RdDActor . $transformSubActeurCreature ) ;
2021-01-22 02:08:49 +01:00
}
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2023-11-21 16:03:26 +01:00
static $buildSubActorLinks ( subActors , actorTransformation = ( actor , link ) => undefined ) {
if ( ! subActors ) {
return [ ]
}
return subActors . map ( link => {
const actor = game . actors . get ( link . id )
return actor ? actorTransformation ( actor , link ) : undefined
} )
. filter ( it => it != undefined )
. sort ( Misc . ascending ( it => it . name ) )
2021-03-29 09:17:00 +02:00
}
2021-05-07 00:01:07 +02:00
/* -------------------------------------------- */
2023-11-21 16:03:26 +01:00
addSubActeur ( subActor ) {
if ( ! this . isAddSubActeurAllowed ( subActor ) ) {
return
}
const subActorOnlyId = { id : subActor . _id } ;
if ( subActor . type == 'vehicule' ) {
this . pushSubActeur ( subActorOnlyId , this . system . subacteurs . vehicules , ` system.subacteurs.vehicules ` , ` Le véhicule ${ subActor . name } ` )
} else if ( subActor . type == 'creature' ) {
this . pushSubActeur ( subActorOnlyId , this . system . subacteurs . montures , 'system.subacteurs.montures' , ` L'animal ${ subActor . name } ` )
} else if ( subActor . type == 'personnage' ) {
this . pushSubActeur ( subActorOnlyId , this . system . subacteurs . suivants , 'system.subacteurs.suivants' , ` Le compagnon ${ subActor . name } ` )
}
2021-03-29 09:17:00 +02:00
}
2023-11-21 16:03:26 +01:00
async pushSubActeur ( subActor , dataArray , dataPath , dataName ) {
let alreadyPresent = dataArray . find ( attached => attached . id == subActor . id ) ;
2021-02-11 02:48:27 +01:00
if ( ! alreadyPresent ) {
2023-11-21 16:03:26 +01:00
let newArray = [ ... dataArray , subActor ]
2021-02-11 02:48:27 +01:00
await this . update ( { [ dataPath ] : newArray } ) ;
2021-01-11 16:29:41 +01:00
} else {
2023-11-21 16:03:26 +01:00
ui . notifications . warn ( dataName + " est déja attaché à " + this . name ) ;
2021-01-11 16:29:41 +01:00
}
}
2023-11-21 16:03:26 +01:00
isAddSubActeurAllowed ( subActor ) {
if ( subActor ? . id == undefined ) {
ui . notifications . warn ( "Aucun acteur à ajouter" )
return false
}
2022-12-05 15:29:00 +01:00
if ( subActor ? . id == this . id ) {
2022-09-07 00:09:17 +02:00
ui . notifications . warn ( "Vous ne pouvez pas attacher un acteur à lui même" )
2023-11-21 16:03:26 +01:00
return false
2022-09-07 00:09:17 +02:00
}
else if ( ! subActor ? . isOwner ) {
ui . notifications . warn ( "Vous n'avez pas les droits sur l'acteur que vous attachez." )
2023-11-21 16:03:26 +01:00
return false
2022-09-07 00:09:17 +02:00
}
2023-11-21 16:03:26 +01:00
return true
2021-01-11 16:29:41 +01:00
}
2021-02-11 02:48:27 +01:00
2023-11-21 16:03:26 +01:00
async deleteSubActeur ( actorId ) {
[ 'vehicules' , 'suivants' , 'montures' ] . forEach ( async type => {
const subList = this . system . subacteurs [ type ] ;
if ( subList . find ( it => it . id == actorId ) ) {
let newList = subList . filter ( it => it . id != actorId )
await this . update ( { [ ` system.subacteurs. ${ type } ` ] : newList } , { 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 ) {
2023-03-14 02:38:21 +01:00
const pointsGuerisonInitial = pointsGuerison ;
2023-03-23 01:41:37 +01:00
const blessures = this . filterItems ( it => it . system . gravite > 0 , 'blessure' ) . sort ( Misc . descending ( it => it . system . gravite ) )
2023-03-14 02:38:21 +01:00
const ids = [ ]
const guerisonData = { list : [ ] , pointsConsommes : 0 }
for ( let blessure of blessures ) {
if ( pointsGuerison >= blessure . system . gravite ) {
pointsGuerison -= blessure . system . gravite ;
2023-03-30 00:19:12 +02:00
guerisonData . list . push ( ` 1 Blessure ${ blessure . system . label } ( ${ blessure . system . gravite } points) ` ) ;
2023-03-14 02:38:21 +01:00
ids . push ( blessure . id )
}
}
if ( ids . length > 0 ) {
await this . supprimerBlessures ( it => ids . includes ( it . id ) ) ;
}
if ( blessures . length == ids . length ) {
let pvManquants = this . system . sante . vie . max - this . system . sante . vie . value ;
let pvSoignees = Math . min ( pvManquants , Math . floor ( pointsGuerison / 2 ) ) ;
pointsGuerison -= pvSoignees * 2 ;
guerisonData . list . push ( pvSoignees + " Points de Vie soignés" ) ;
await this . santeIncDec ( 'vie' , + pvSoignees , false ) ;
2021-04-04 22:34:59 +02:00
}
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 ) {
2023-03-23 01:42:48 +01:00
await this . setBonusPotionSoin ( potionData . system . herbebonus ) ;
2021-04-04 22:34:59 +02:00
}
2021-10-09 22:04:34 +02:00
ChatMessage . create ( {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
2021-10-09 22:04:34 +02:00
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-soin.html ` , potionData )
} ) ;
2021-04-04 22:34:59 +02:00
}
2023-03-14 02:38:21 +01:00
async setBonusPotionSoin ( bonus ) {
2023-03-23 01:42:48 +01:00
await this . update ( { 'system.sante.bonusPotion' : bonus } ) ;
2023-03-14 02:38:21 +01: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 ) {
2023-03-23 01:42:48 +01:00
this . bonusRepos = potionData . system . herbebonus ;
2021-04-09 15:23:48 +02:00
}
2021-10-09 22:04:34 +02:00
ChatMessage . create ( {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
2021-10-09 22:04:34 +02:00
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 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 = {
2024-11-15 00:01:55 +01:00
alias : this . getAlias ( ) ,
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 ( {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
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 } ) {
2022-12-28 23:36:48 +01:00
const item = this . getItem ( 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 ( {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
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-04-16 23:07:09 +02:00
/* -------------------------------------------- */
async onPreUpdateItem ( item , change , options , id ) {
2022-10-08 14:25:31 +02:00
if ( item . isCompetencePersonnage ( ) && item . system . defaut _carac && item . system . xp ) {
2022-06-12 08:17:59 +02:00
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 ;
}
2023-01-05 00:55:04 +01:00
await item . onCreateItemTemporel ( this ) ;
2022-12-03 22:32:32 +01:00
await item . onCreateDecoupeComestible ( this ) ;
2021-02-11 02:48:27 +01:00
}
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 ;
2023-04-21 18:18:20 +02:00
case 'empoignade' :
await RdDEmpoignade . deleteLinkedEmpoignade ( this . id , item )
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 ) {
2024-10-23 23:42:38 +02:00
if ( Misc . isFirstConnectedGM ( ) ) {
2021-04-16 23:07:09 +02:00
let draconique = Draconique . all ( ) . find ( it => it . match ( item ) ) ;
if ( draconique ) {
2023-02-07 18:06:45 +01:00
await draconique . onActorCreateOwned ( this , item )
2021-04-16 23:07:09 +02:00
this . notifyGestionTeteSouffleQueue ( item , draconique . manualMessage ( ) ) ;
}
2023-02-10 02:01:43 +01:00
await this . setInfoSommeilInsomnie ( ) ;
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 ) {
2024-10-23 23:42:38 +02:00
if ( Misc . isFirstConnectedGM ( ) ) {
2021-04-16 23:07:09 +02:00
let draconique = Draconique . all ( ) . find ( it => it . match ( item ) ) ;
if ( draconique ) {
2023-02-07 18:06:45 +01:00
await draconique . onActorDeleteOwned ( this , item )
2021-04-16 23:07:09 +02:00
}
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 ) {
2024-10-23 23:42:38 +02:00
if ( Misc . isFirstConnectedGM ( ) ) {
2021-04-16 23:07:09 +02:00
let draconique = Draconique . all ( ) . find ( it => it . isCase ( item ) ) ;
if ( draconique ) {
2023-02-07 18:06:45 +01:00
await 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 ( {
2024-10-16 23:18:15 +02:00
whisper : ChatUtility . getOwners ( this ) ,
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
}
2023-06-20 23:20:44 +02:00
async nouvelleIncarnation ( ) {
let incarnation = this . toObject ( ) ;
2024-09-25 22:56:24 +02:00
incarnation . items = Array . from ( this . items . filter ( it => it . type == ITEM _TYPES . competence ) ,
2023-06-20 23:20:44 +02:00
it => {
it = it . toObject ( ) ;
it . id = undefined ;
it . system . niveau = it . system . base ;
it . system . niveau _archetype = Math . max ( it . system . niveau + ( it . system . xp > 0 ? 1 : 0 ) , it . system . niveau _archetype ) ;
it . system . xp = 0 ;
it . system . xp _sort = 0 ;
it . system . default _diffLibre = 0 ;
return it ;
} ) ;
incarnation . name = 'Réincarnation de ' + incarnation . name
incarnation . system = {
2024-05-02 14:08:02 +02:00
carac : foundry . utils . duplicate ( this . system . carac ) ,
2024-11-06 23:24:53 +01:00
heure : RdDTimestamp . defHeure ( await RdDDice . rollHeure ( { rollMode : "selfroll" , showDice : SHOW _DICE } ) ) . key ,
2023-06-20 23:20:44 +02:00
age : 18 ,
biographie : '' ,
notes : '' ,
experiencelog : [ ] ,
'compteurs.experience.value' : 3000 ,
'reve.seuil.value' : this . system . carac . reve . value ,
'reve.reve.value' : this . system . carac . reve . value ,
subacteurs : { suivants : [ ] , montures : [ ] , vehicules : [ ] } ,
}
incarnation = await RdDBaseActor . create ( incarnation ) ;
await incarnation . deleteEmbeddedDocuments ( 'ActiveEffect' , incarnation . getEmbeddedCollection ( "ActiveEffect" ) . map ( it => it . id ) ) ;
await incarnation . remiseANeuf ( ) ;
incarnation . sheet . render ( true ) ;
}
2021-03-15 00:05:56 +01:00
}
2021-02-11 02:48:27 +01:00