2022-11-07 00:04:43 +01:00
import { SHOW _DICE } from "./constants.js" ;
2021-01-29 15:13:59 +01:00
import { RollDataAjustements } from "./rolldata-ajustements.js" ;
2020-07-06 09:03:21 +02:00
import { RdDUtility } from "./rdd-utility.js" ;
2021-12-12 17:36:22 +01:00
import { TMRUtility } from "./tmr-utility.js" ;
import { tmrConstants } from "./tmr-constants.js" ;
2020-11-12 16:35:51 +01:00
import { RdDResolutionTable } from "./rdd-resolution-table.js" ;
2020-11-29 18:21:34 +01:00
import { RdDTMRRencontreDialog } from "./rdd-tmr-rencontre-dialog.js" ;
2021-01-29 15:13:59 +01:00
import { ChatUtility } from "./chat-utility.js" ;
2021-02-06 21:53:25 +01:00
import { RdDRoll } from "./rdd-roll.js" ;
2021-02-06 23:58:15 +01:00
import { Poetique } from "./poetique.js" ;
2021-02-11 02:48:27 +01:00
import { EffetsDraconiques } from "./tmr/effets-draconiques.js" ;
import { PixiTMR } from "./tmr/pixi-tmr.js" ;
import { Draconique } from "./tmr/draconique.js" ;
2021-05-08 20:08:56 +02:00
import { HtmlUtility } from "./html-utility.js" ;
2022-11-06 21:39:03 +01:00
import { ReglesOptionelles } from "./settings/regles-optionelles.js" ;
2021-05-11 21:45:43 +02:00
import { RdDDice } from "./rdd-dice.js" ;
2022-11-06 21:39:03 +01:00
import { STATUSES } from "./settings/status-effects.js" ;
2023-01-18 01:37:22 +01:00
import { RdDRencontre } from "./item/rencontre.js" ;
2022-11-16 02:52:55 +01:00
import { RdDCalendrier } from "./rdd-calendrier.js" ;
2023-01-05 00:55:04 +01:00
import { RdDTimestamp } from "./rdd-timestamp.js" ;
2022-11-07 00:04:43 +01:00
2020-11-18 23:49:05 +01:00
/* -------------------------------------------- */
2021-12-12 17:36:22 +01:00
2020-07-05 21:45:25 +02:00
export class RdDTMRDialog extends Dialog {
2020-11-14 03:16:03 +01:00
2022-11-18 03:38:05 +01:00
static async create ( actor , tmrData ) {
let html = await renderTemplate ( 'systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html' , tmrData ) ;
2021-02-11 02:48:27 +01:00
if ( tmrData . mode != 'visu' ) {
// Notification au MJ
ChatMessage . create ( { content : actor . name + " est monté dans les TMR en mode : " + tmrData . mode , whisper : ChatMessage . getWhisperRecipients ( "GM" ) } ) ;
}
return new RdDTMRDialog ( html , actor , tmrData ) ;
}
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
constructor ( html , actor , tmrData ) {
2020-11-14 03:16:03 +01:00
const dialogConf = {
title : "Terres Médianes de Rêve" ,
2020-07-05 21:45:25 +02:00
content : html ,
2020-11-14 03:16:03 +01:00
buttons : {
closeButton : { label : "Fermer" , callback : html => this . close ( html ) }
} ,
default : "closeButton"
}
const dialogOptions = {
classes : [ "tmrdialog" ] ,
width : 920 , height : 980 ,
2021-05-04 12:22:19 +02:00
'z-index' : 40
2020-11-14 03:16:03 +01:00
}
2020-07-05 21:45:25 +02:00
super ( dialogConf , dialogOptions ) ;
2020-11-14 03:16:03 +01:00
this . tmrdata = duplicate ( tmrData ) ;
2020-07-14 22:19:29 +02:00
this . actor = actor ;
2020-11-17 18:08:19 +01:00
this . actor . tmrApp = this ; // reference this app in the actor structure
2021-02-11 02:48:27 +01:00
this . viewOnly = tmrData . mode == "visu"
2021-05-08 20:08:56 +02:00
this . fatigueParCase = this . viewOnly || ! ReglesOptionelles . isUsing ( "appliquer-fatigue" ) ? 0 : this . actor . getTMRFatigue ( ) ;
2021-02-06 01:34:49 +01:00
this . cumulFatigue = 0 ;
2021-02-11 02:48:27 +01:00
this . loadRencontres ( ) ;
2021-02-12 01:44:27 +01:00
this . loadCasesSpeciales ( ) ;
2020-11-17 18:08:19 +01:00
this . allTokens = [ ] ;
2020-11-20 13:46:43 +01:00
this . rencontreState = 'aucune' ;
2020-11-14 03:16:03 +01:00
this . pixiApp = new PIXI . Application ( { width : 720 , height : 860 } ) ;
2021-02-11 02:48:27 +01:00
2021-05-10 18:39:35 +02:00
this . pixiTMR = new PixiTMR ( this , this . pixiApp ) ;
2021-02-11 02:48:27 +01:00
this . callbacksOnAnimate = [ ] ;
2021-01-29 15:13:59 +01:00
if ( ! this . viewOnly ) {
2021-02-11 02:48:27 +01:00
this . _tellToGM ( this . actor . name + " monte dans les terres médianes (" + tmrData . mode + ")" ) ;
2020-11-29 18:06:19 +01:00
}
2021-04-28 00:48:39 +02:00
2021-02-11 02:48:27 +01:00
// load the texture we need
2021-05-10 18:39:35 +02:00
this . pixiTMR . load ( ( loader , resources ) => this . createPixiSprites ( ) ) ;
2021-02-11 02:48:27 +01:00
}
2022-03-30 01:18:34 +02:00
isDemiReveCache ( ) {
return ! game . user . isGM && this . actor . isTMRCache ( ) ;
}
2021-04-28 00:48:39 +02:00
/* -------------------------------------------- */
2021-02-12 01:44:27 +01:00
loadCasesSpeciales ( ) {
2022-06-12 12:14:55 +02:00
this . casesSpeciales = this . actor . items . filter ( item => Draconique . isCaseTMR ( item ) ) ;
2021-02-12 01:44:27 +01:00
}
2022-09-17 16:07:38 +02:00
get sortsReserve ( ) {
return this . actor . itemTypes [ 'sortreserve' ] ;
}
getSortsReserve ( coord ) {
return this . actor . itemTypes [ 'sortreserve' ] . filter ( // Reserve sur une case fleuve ou normale
TMRUtility . getTMR ( coord ) . type == 'fleuve'
? it => TMRUtility . getTMR ( it . system . coord ) . type == 'fleuve'
: it => it . system . coord == coord
2022-11-07 00:04:43 +01:00
) ;
2021-02-11 02:48:27 +01:00
}
2021-04-28 00:48:39 +02:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
loadRencontres ( ) {
2021-03-20 00:09:29 +01:00
this . rencontresExistantes = this . actor . getTMRRencontres ( ) ;
2020-07-14 22:19:29 +02:00
}
2021-01-29 15:13:59 +01:00
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
createPixiSprites ( ) {
2021-02-12 18:31:49 +01:00
EffetsDraconiques . carteTmr . createSprite ( this . pixiTMR ) ;
2021-02-11 02:48:27 +01:00
this . updateTokens ( ) ;
2022-06-25 17:49:19 +02:00
this . forceDemiRevePositionView ( ) ;
2020-07-25 10:29:28 +02:00
}
2022-09-17 16:07:38 +02:00
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
_createTokens ( ) {
2022-09-17 16:07:38 +02:00
if ( ! this . isDemiReveCache ( ) ) {
2022-06-25 17:49:19 +02:00
this . demiReve = this . _tokenDemiReve ( ) ;
this . _trackToken ( this . demiReve ) ;
}
2021-02-11 02:48:27 +01:00
let tokens = this . _getTokensCasesTmr ( )
. concat ( this . _getTokensRencontres ( ) )
. concat ( this . _getTokensSortsReserve ( ) ) ;
for ( let t of tokens ) {
this . _trackToken ( t ) ;
2020-07-26 18:44:03 +02:00
}
}
2020-11-14 03:16:03 +01:00
2021-05-28 10:25:34 +02:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
updateTokens ( ) {
this . _removeTokens ( t => true ) ;
this . loadRencontres ( ) ;
2021-02-12 01:44:27 +01:00
this . loadCasesSpeciales ( ) ;
2021-02-11 02:48:27 +01:00
this . _createTokens ( ) ;
}
2021-05-28 10:25:34 +02:00
/* -------------------------------------------- */
2021-02-28 01:56:17 +01:00
removeToken ( tmr , casetmr ) {
this . _removeTokens ( t => t . coordTMR ( ) == tmr . coord && t . caseSpeciale ? . _id == casetmr . _id ) ;
this . updateTokens ( )
}
2020-12-30 18:12:01 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
_getTokensCasesTmr ( ) {
return this . casesSpeciales . map ( c => this . _tokenCaseSpeciale ( c ) ) . filter ( token => token ) ;
}
_getTokensRencontres ( ) {
return this . rencontresExistantes . map ( it => this . _tokenRencontre ( it ) ) ;
}
_getTokensSortsReserve ( ) {
2022-09-17 16:07:38 +02:00
return this . actor . itemTypes [ 'sortreserve' ] . map ( it => this . _tokenSortEnReserve ( it ) ) ;
2020-12-30 18:12:01 +01:00
}
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
_tokenRencontre ( rencontre ) {
2022-11-07 00:04:43 +01:00
return EffetsDraconiques . rencontre . token ( this . pixiTMR , rencontre , ( ) => rencontre . system . coord ) ;
2021-02-11 02:48:27 +01:00
}
2021-02-12 12:50:17 +01:00
_tokenCaseSpeciale ( casetmr ) {
2022-06-12 12:14:55 +02:00
const caseData = casetmr ;
const draconique = Draconique . get ( caseData . system . specific ) ;
return draconique ? . token ( this . pixiTMR , caseData , ( ) => caseData . system . coord ) ;
2021-02-11 02:48:27 +01:00
}
2022-09-17 16:07:38 +02:00
_tokenSortEnReserve ( sortReserve ) {
return EffetsDraconiques . sortReserve . token ( this . pixiTMR , sortReserve , ( ) => sortReserve . system . coord ) ;
2021-02-11 02:48:27 +01:00
}
2021-05-10 18:39:35 +02:00
2021-02-11 02:48:27 +01:00
_tokenDemiReve ( ) {
2022-09-30 01:55:04 +02:00
return EffetsDraconiques . demiReve . token ( this . pixiTMR , this . actor , ( ) => this . actor . system . reve . tmrpos . coord ) ;
2021-02-11 02:48:27 +01:00
}
2022-06-25 17:49:19 +02:00
forceDemiRevePositionView ( ) {
2021-05-11 21:21:33 +02:00
this . notifierResonanceSigneDraconique ( this . _getActorCoord ( ) ) ;
2022-06-25 17:49:19 +02:00
this . _trackToken ( this . demiReve ) ;
2021-04-28 00:48:39 +02:00
}
2021-05-10 18:39:35 +02:00
_getActorCoord ( ) {
2022-06-12 12:14:55 +02:00
return this . actor . system . reve . tmrpos . coord ;
2021-05-10 18:39:35 +02:00
}
2021-04-28 00:48:39 +02:00
/* -------------------------------------------- */
2021-05-10 18:39:35 +02:00
async moveFromKey ( move ) {
2021-12-12 17:36:22 +01:00
let oddq = TMRUtility . coordTMRToOddq ( this . _getActorCoord ( ) ) ;
if ( move == 'top' ) oddq . row -= 1 ;
if ( move == 'bottom' ) oddq . row += 1 ;
if ( move . includes ( 'left' ) ) oddq . col -= 1 ;
if ( move . includes ( 'right' ) ) oddq . col += 1 ;
if ( oddq . col % 2 == 1 ) {
if ( move == 'top-left' ) oddq . row -= 1 ;
if ( move == 'top-right' ) oddq . row -= 1 ;
2021-04-28 00:48:39 +02:00
} else {
2021-12-12 17:36:22 +01:00
if ( move == 'bottom-left' ) oddq . row += 1 ;
if ( move == 'bottom-right' ) oddq . row += 1 ;
2021-04-28 00:48:39 +02:00
}
2021-12-12 17:36:22 +01:00
let targetCoord = TMRUtility . oddqToCoordTMR ( oddq ) ;
2021-04-28 00:48:39 +02:00
await this . _deplacerDemiReve ( targetCoord , 'normal' ) ;
this . checkQuitterTMR ( ) ;
2021-02-11 02:48:27 +01:00
}
/* -------------------------------------------- */
async activateListeners ( html ) {
super . activateListeners ( html ) ;
2022-12-09 02:00:31 +01:00
this . html = html ;
2021-02-11 02:48:27 +01:00
2021-02-28 01:56:17 +01:00
document . getElementById ( "tmrrow1" ) . insertCell ( 0 ) . append ( this . pixiApp . view ) ;
2021-02-11 02:48:27 +01:00
if ( this . viewOnly ) {
2022-12-09 02:00:31 +01:00
this . html . find ( '.lancer-sort' ) . remove ( ) ;
this . html . find ( '.lire-signe-draconique' ) . remove ( ) ;
2021-02-11 02:48:27 +01:00
return ;
}
2023-01-10 22:11:16 +01:00
HtmlUtility . showControlWhen ( this . html . find ( ".appliquerFatigue" ) , ReglesOptionelles . isUsing ( "appliquer-fatigue" ) ) ;
HtmlUtility . showControlWhen ( this . html . find ( ".lire-signe-draconique" ) , this . actor . isResonanceSigneDraconique ( this . _getActorCoord ( ) ) ) ;
2021-05-10 19:18:11 +02:00
// Roll Sort
2022-12-09 02:00:31 +01:00
this . html . find ( '.lancer-sort' ) . click ( ( event ) => {
2021-05-10 19:18:11 +02:00
this . actor . rollUnSort ( this . _getActorCoord ( ) ) ;
} ) ;
2022-12-09 02:00:31 +01:00
this . html . find ( '.lire-signe-draconique' ) . click ( ( event ) => {
2021-05-10 19:18:11 +02:00
this . actor . rollLireSigneDraconique ( this . _getActorCoord ( ) ) ;
} ) ;
2022-12-09 02:00:31 +01:00
this . html . find ( '#dir-top' ) . click ( ( event ) => this . moveFromKey ( "top" ) ) ;
this . html . find ( '#dir-top-left' ) . click ( ( event ) => this . moveFromKey ( "top-left" ) ) ;
this . html . find ( '#dir-top-right' ) . click ( ( event ) => this . moveFromKey ( "top-right" ) ) ;
this . html . find ( '#dir-bottom-left' ) . click ( ( event ) => this . moveFromKey ( "bottom-left" ) ) ;
this . html . find ( '#dir-bottom-right' ) . click ( ( event ) => this . moveFromKey ( "bottom-right" ) ) ;
this . html . find ( '#dir-bottom' ) . click ( ( event ) => this . moveFromKey ( "bottom" ) ) ;
2021-04-28 00:48:39 +02:00
2021-02-11 02:48:27 +01:00
// Gestion du cout de montée en points de rêve
2021-05-02 21:08:50 +02:00
let reveCout = ( ( this . tmrdata . isRapide && ! EffetsDraconiques . isDeplacementAccelere ( this . actor ) ) ? - 2 : - 1 ) - this . actor . countMonteeLaborieuse ( ) ;
2021-05-10 18:39:35 +02:00
if ( ReglesOptionelles . isUsing ( "appliquer-fatigue" ) ) {
2021-05-08 20:08:56 +02:00
this . cumulFatigue += this . fatigueParCase ;
}
2021-02-11 02:48:27 +01:00
await this . actor . reveActuelIncDec ( reveCout ) ;
// Le reste...
this . updateValuesDisplay ( ) ;
2021-05-10 18:39:35 +02:00
let tmr = TMRUtility . getTMR ( this . _getActorCoord ( ) ) ;
2022-09-22 00:33:50 +02:00
await this . manageRencontre ( tmr ) ;
2020-07-21 23:51:24 +02:00
}
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2021-05-11 21:21:33 +02:00
async updateValuesDisplay ( ) {
2022-09-21 16:47:34 +02:00
if ( ! this . rendered ) {
return ;
}
2021-05-11 21:21:33 +02:00
const coord = this . _getActorCoord ( ) ;
2023-01-10 22:11:16 +01:00
HtmlUtility . showControlWhen ( this . html . find ( ".lire-signe-draconique" ) , this . actor . isResonanceSigneDraconique ( coord ) ) ;
2021-05-10 19:18:11 +02:00
2021-02-11 02:48:27 +01:00
let ptsreve = document . getElementById ( "tmr-pointsreve-value" ) ;
2022-06-12 12:14:55 +02:00
ptsreve . innerHTML = this . actor . system . reve . reve . value ;
2021-02-11 02:48:27 +01:00
let tmrpos = document . getElementById ( "tmr-pos" ) ;
2022-03-30 01:18:34 +02:00
if ( this . isDemiReveCache ( ) ) {
2022-11-07 00:04:43 +01:00
tmrpos . innerHTML = ` ?? ( ${ TMRUtility . getTMRType ( coord ) } ) ` ;
2021-04-28 00:48:39 +02:00
} else {
2022-09-17 16:07:38 +02:00
tmrpos . innerHTML = ` ${ coord } ( ${ TMRUtility . getTMRLabel ( coord ) } ) ` ;
2021-04-28 00:48:39 +02:00
}
2021-02-11 02:48:27 +01:00
let etat = document . getElementById ( "tmr-etatgeneral-value" ) ;
etat . innerHTML = this . actor . getEtatGeneral ( ) ;
let refoulement = document . getElementById ( "tmr-refoulement-value" ) ;
2022-06-12 12:14:55 +02:00
refoulement . innerHTML = this . actor . system . reve . refoulement . value ;
2021-02-11 02:48:27 +01:00
2021-05-10 18:39:35 +02:00
if ( ReglesOptionelles . isUsing ( "appliquer-fatigue" ) ) {
2021-05-08 20:08:56 +02:00
let fatigueItem = document . getElementById ( "tmr-fatigue-table" ) ;
2022-06-12 12:14:55 +02:00
fatigueItem . innerHTML = "<table class='table-fatigue'>" + RdDUtility . makeHTMLfatigueMatrix ( this . actor . system . sante . fatigue . value , this . actor . system . sante . endurance . max ) . html ( ) + "</table>" ;
2021-05-08 20:08:56 +02:00
}
2020-07-21 23:51:24 +02:00
}
2020-07-26 18:44:03 +02:00
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2022-09-17 22:36:43 +02:00
async close ( ) {
2022-09-22 00:33:50 +02:00
this . descenteTMR = true ;
2022-09-17 22:36:43 +02:00
if ( this . actor . tmrApp ) {
2021-05-28 09:37:22 +02:00
this . actor . tmrApp = undefined ; // Cleanup reference
2022-09-17 22:36:43 +02:00
if ( ! this . viewOnly ) {
await this . actor . setEffect ( STATUSES . StatusDemiReve , false )
2021-05-28 09:37:22 +02:00
this . _tellToGM ( this . actor . name + " a quitté les terres médianes" ) ;
}
2022-09-17 22:36:43 +02:00
await this . actor . santeIncDec ( "fatigue" , this . cumulFatigue )
2021-02-11 02:48:27 +01:00
}
2022-12-09 02:00:31 +01:00
await super . close ( ) ;
2020-07-26 18:44:03 +02:00
}
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2022-11-07 00:04:43 +01:00
async onActionRencontre ( action , tmr ) {
switch ( action ) {
case 'derober' :
await this . derober ( ) ;
return ;
case 'refouler' :
await this . refouler ( ) ;
break ;
case 'maitriser' :
await this . maitriserRencontre ( ) ;
break ;
case 'ignorer' :
await this . ignorerRencontre ( ) ;
break ;
}
await this . postRencontre ( tmr ) ;
}
2020-07-17 22:04:35 +02:00
async derober ( ) {
console . log ( "-> derober" , this . currentRencontre ) ;
2022-11-07 00:04:43 +01:00
await this . actor . addTMRRencontre ( this . currentRencontre ) ;
2020-11-14 03:16:03 +01:00
this . _tellToGM ( this . actor . name + " s'est dérobé et quitte les TMR." ) ;
2020-07-21 23:51:24 +02:00
this . close ( ) ;
2020-07-14 22:19:29 +02:00
}
2021-04-28 00:48:39 +02:00
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2021-01-29 15:13:59 +01:00
async refouler ( ) {
2022-11-07 00:04:43 +01:00
console . log ( "-> refouler" , this . currentRencontre ) ;
await this . actor . ajouterRefoulement ( this . currentRencontre . system . refoulement , ` ${ this . currentRencontre . system . genre == 'f' ? 'une' : 'un' } ${ this . currentRencontre . name } ` ) ;
2020-11-14 03:16:03 +01:00
await this . actor . deleteTMRRencontreAtPosition ( ) ; // Remove the stored rencontre if necessary
2021-02-11 02:48:27 +01:00
this . updateTokens ( ) ;
2020-07-17 22:04:35 +02:00
this . updateValuesDisplay ( ) ;
2020-11-20 13:46:43 +01:00
this . nettoyerRencontre ( ) ;
2020-07-14 22:19:29 +02:00
}
2020-11-20 12:06:54 +01:00
/* -------------------------------------------- */
2021-01-29 15:13:59 +01:00
async ignorerRencontre ( ) {
2022-11-07 00:04:43 +01:00
console . log ( "-> ignorer" , this . currentRencontre ) ;
2022-10-31 15:20:33 +01:00
this . _tellToGM ( this . actor . name + " a ignoré: " + this . currentRencontre . name ) ;
2021-01-29 15:13:59 +01:00
await this . actor . deleteTMRRencontreAtPosition ( ) ; // Remove the stored rencontre if necessary
2021-02-11 02:48:27 +01:00
this . updateTokens ( ) ;
2021-01-29 15:13:59 +01:00
this . updateValuesDisplay ( ) ;
this . nettoyerRencontre ( ) ;
}
/* -------------------------------------------- */
2022-11-07 00:04:43 +01:00
// garder la trace de l'état en cours
setRencontreState ( state , listCoordTMR ) {
this . rencontreState = state ;
this . $marquerCasesTMR ( listCoordTMR ? ? [ ] ) ;
}
/* -------------------------------------------- */
$marquerCasesTMR ( listCoordTMR ) {
2020-11-20 12:06:54 +01:00
this . currentRencontre . graphics = [ ] ; // Keep track of rectangles to delete it
2021-12-12 17:36:22 +01:00
this . currentRencontre . locList = duplicate ( listCoordTMR ) ; // And track of allowed location
for ( let coordTMR of listCoordTMR ) {
2022-09-17 23:44:51 +02:00
const rect = this . _getCaseRectangleCoord ( coordTMR ) ;
const rectDraw = new PIXI . Graphics ( ) ;
2022-09-17 16:07:38 +02:00
rectDraw . beginFill ( 0xffff00 , 0.3 ) ;
2020-11-20 12:06:54 +01:00
// set the line style to have a width of 5 and set the color to red
2022-09-17 16:07:38 +02:00
rectDraw . lineStyle ( 5 , 0xff0000 ) ;
2020-11-20 12:06:54 +01:00
// draw a rectangle
rectDraw . drawRect ( rect . x , rect . y , rect . w , rect . h ) ;
this . pixiApp . stage . addChild ( rectDraw ) ;
this . currentRencontre . graphics . push ( rectDraw ) ; // garder les objets pour gestion post-click
}
}
2020-11-21 08:27:28 +01:00
/* -------------------------------------------- */
2020-11-21 23:24:00 +01:00
checkQuitterTMR ( ) {
2021-01-29 15:13:59 +01:00
if ( this . actor . isDead ( ) ) {
this . _tellToGM ( "Vous êtes mort : vous quittez les Terres médianes !" ) ;
2020-11-21 08:27:28 +01:00
this . close ( ) ;
2021-01-29 15:13:59 +01:00
return true ;
2020-11-21 08:27:28 +01:00
}
2021-02-06 01:34:49 +01:00
const resteAvantInconscience = this . actor . getFatigueMax ( ) - this . actor . getFatigueActuelle ( ) - this . cumulFatigue ;
2021-05-08 20:08:56 +02:00
if ( ReglesOptionelles . isUsing ( "appliquer-fatigue" ) && resteAvantInconscience <= 0 ) {
2020-11-29 18:06:19 +01:00
this . _tellToGM ( "Vous vous écroulez de fatigue : vous quittez les Terres médianes !" ) ;
2021-01-29 15:13:59 +01:00
this . quitterLesTMRInconscient ( ) ;
return true ;
2020-11-21 08:27:28 +01:00
}
2021-01-29 15:13:59 +01:00
if ( this . actor . getReveActuel ( ) == 0 ) {
this . _tellToGM ( "Vos Points de Rêve sont à 0 : vous quittez les Terres médianes !" ) ;
this . quitterLesTMRInconscient ( ) ;
return true ;
}
return false ;
}
2021-04-28 00:48:39 +02:00
/* -------------------------------------------- */
2021-01-29 15:13:59 +01:00
async quitterLesTMRInconscient ( ) {
2022-11-05 18:06:30 +01:00
await this . refouler ( ) ;
2021-01-29 15:13:59 +01:00
this . close ( ) ;
2020-11-20 12:06:54 +01:00
}
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
async maitriserRencontre ( ) {
2022-11-07 00:04:43 +01:00
console . log ( "-> maitriser" , this . currentRencontre ) ;
await this . actor . deleteTMRRencontreAtPosition ( ) ;
2021-02-11 02:48:27 +01:00
this . updateTokens ( ) ;
2020-11-14 03:16:03 +01:00
2021-01-29 15:13:59 +01:00
let rencontreData = {
actor : this . actor ,
alias : this . actor . name ,
reveDepart : this . actor . getReveActuel ( ) ,
competence : this . actor . getBestDraconic ( ) ,
rencontre : this . currentRencontre ,
nbRounds : 1 ,
2021-02-06 21:53:25 +01:00
canClose : false ,
2022-11-07 00:04:43 +01:00
selectedCarac : { label : "reve-actuel" } ,
2021-05-10 18:39:35 +02:00
tmr : TMRUtility . getTMR ( this . _getActorCoord ( ) )
2021-01-29 15:13:59 +01:00
}
await this . _tentativeMaitrise ( rencontreData ) ;
}
2020-11-14 03:16:03 +01:00
2021-02-11 02:48:27 +01:00
/* -------------------------------------------- */
2021-05-27 19:40:45 +02:00
async _tentativeMaitrise ( rencData ) {
2022-12-17 17:50:55 +01:00
this . rencontreState = 'normal' ;
2021-03-29 18:08:18 +02:00
rencData . reve = this . actor . getReveActuel ( ) ;
rencData . etat = this . actor . getEtatGeneral ( ) ;
2020-11-20 12:06:54 +01:00
2021-03-29 18:08:18 +02:00
RollDataAjustements . calcul ( rencData , this . actor ) ;
2021-01-29 15:13:59 +01:00
2021-03-29 18:08:18 +02:00
rencData . rolled = rencData . presentCite
? this . _rollPresentCite ( rencData )
: await RdDResolutionTable . roll ( rencData . reve , RollDataAjustements . sum ( rencData . ajustements ) ) ;
2021-02-12 12:50:17 +01:00
2022-11-07 00:04:43 +01:00
const result = rencData . rolled . isSuccess
? rencData . rencontre . system . succes
: rencData . rencontre . system . echec ;
await RdDRencontre . appliquer ( result . effets , this , rencData ) ;
rencData . poesie = { extrait : result . poesie , reference : result . reference } ;
rencData . message = this . formatMessageRencontre ( rencData , result . message ) ;
2021-01-29 15:13:59 +01:00
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name ) ,
2021-03-29 18:08:18 +02:00
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.html ` , rencData )
2021-01-29 15:13:59 +01:00
} ) ;
2020-07-17 22:04:35 +02:00
this . updateValuesDisplay ( ) ;
2021-01-29 15:13:59 +01:00
if ( this . checkQuitterTMR ( ) ) {
return ;
}
2022-11-07 00:04:43 +01:00
if ( this . rencontreState == 'persistant' ) {
this . _nouvelleTentativeMaitrise ( rencData ) ;
}
else if ( ! this . isRencontreDeplacement ( ) ) {
this . nettoyerRencontre ( ) ;
}
}
_nouvelleTentativeMaitrise ( rencData ) {
setTimeout ( ( ) => {
// TODO: remplacer par une boucle while(this.currentRencontre) ?
rencData . nbRounds ++ ;
if ( ReglesOptionelles . isUsing ( "appliquer-fatigue" ) ) {
this . cumulFatigue += this . fatigueParCase ;
}
this . _tentativeMaitrise ( rencData ) ;
this . _deleteTmrMessages ( rencData . actor , rencData . nbRounds ) ;
} , 2000 ) ;
}
formatMessageRencontre ( rencData , template ) {
let messageDuree = ''
if ( rencData . nbRounds > 1 ) {
if ( rencData . rolled . isSuccess ) {
messageDuree = ` Au total, vous avez passé ${ rencData . nbRounds } rounds à vous battre! ` ;
}
else {
2022-12-17 17:50:55 +01:00
messageDuree = ` Vous avez passé ${ rencData . nbRounds } rounds à lutter! ` ;
2022-11-07 00:04:43 +01:00
}
}
try {
const compiled = Handlebars . compile ( template ) ;
2022-12-17 17:50:55 +01:00
return compiled ( rencData ) + messageDuree ;
2022-11-07 00:04:43 +01:00
} catch ( error ) {
2022-12-17 17:50:55 +01:00
return template + messageDuree ;
2021-01-29 15:13:59 +01:00
}
}
2021-04-28 00:48:39 +02:00
/* -------------------------------------------- */
2022-11-07 00:04:43 +01:00
_rollPresentCite ( rencData ) {
let rolled = RdDResolutionTable . computeChances ( rencData . reve , 0 ) ;
mergeObject ( rolled , { caracValue : rencData . reve , finalLevel : 0 , roll : rolled . score } ) ;
2021-02-12 12:50:17 +01:00
RdDResolutionTable . succesRequis ( rolled ) ;
return rolled ;
}
2021-02-11 02:48:27 +01:00
/* -------------------------------------------- */
2021-01-29 15:13:59 +01:00
_deleteTmrMessages ( actor , nbRounds = - 1 ) {
2021-02-05 01:38:40 +01:00
setTimeout ( ( ) => {
if ( nbRounds < 0 ) {
ChatUtility . removeChatMessageContaining ( ` <h4 data-categorie="tmr" data-actor-id=" ${ actor . _id } " ` ) ;
2021-01-29 15:13:59 +01:00
}
2021-02-05 01:38:40 +01:00
else {
for ( let i = 1 ; i < nbRounds ; i ++ ) {
ChatUtility . removeChatMessageContaining ( ` <h4 data-categorie="tmr" data-actor-id=" ${ actor . _id } " data-rencontre-round=" ${ i } "> ` ) ;
}
}
} , 500 ) ;
2020-07-14 22:19:29 +02:00
}
2020-11-12 23:35:29 +01:00
2020-11-17 16:30:03 +01:00
/* -------------------------------------------- */
2020-11-14 03:16:03 +01:00
_tellToUser ( message ) {
2021-03-25 03:18:27 +01:00
ChatMessage . create ( { content : message , user : game . user . id , whisper : [ game . user . id ] } ) ;
2020-11-14 03:16:03 +01:00
}
2020-11-18 23:49:05 +01:00
/* -------------------------------------------- */
_tellToGM ( message ) {
2021-03-25 03:18:27 +01:00
ChatMessage . create ( { content : message , user : game . user . id , whisper : ChatMessage . getWhisperRecipients ( "GM" ) } ) ;
2020-11-18 23:49:05 +01:00
}
2021-01-29 15:13:59 +01:00
2021-03-20 00:09:29 +01:00
/* -------------------------------------------- */
_tellToUserAndGM ( message ) {
2021-03-25 03:18:27 +01:00
ChatMessage . create ( { content : message , user : game . user . id , whisper : [ game . user . id ] . concat ( ChatMessage . getWhisperRecipients ( "GM" ) ) } ) ;
2021-03-20 00:09:29 +01:00
}
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2022-09-22 00:33:50 +02:00
async manageRencontre ( tmr ) {
2020-11-14 20:46:39 +01:00
if ( this . viewOnly ) {
return ;
}
2022-09-22 00:33:50 +02:00
this . descenteTMR = false ;
2020-11-14 03:16:03 +01:00
this . currentRencontre = undefined ;
2022-09-22 00:33:50 +02:00
if ( this . _presentCite ( tmr ) ) {
2021-02-12 12:50:17 +01:00
return ;
}
2022-11-07 00:04:43 +01:00
this . currentRencontre = await this . _jetDeRencontre ( tmr ) ;
if ( this . currentRencontre ) {
2022-12-17 17:50:55 +01:00
if ( this . rencontresExistantes . find ( it => it . id == this . currentRencontre . id ) ) {
2022-11-07 00:04:43 +01:00
// rencontre en attente suite à dérobade
await this . maitriserRencontre ( ) ;
}
else {
let dialog = new RdDTMRRencontreDialog ( this , this . currentRencontre , tmr ) ;
dialog . render ( true ) ;
}
2020-07-14 22:19:29 +02:00
}
2021-02-06 02:29:58 +01:00
else {
2022-09-22 00:33:50 +02:00
this . postRencontre ( tmr ) ;
2021-02-06 02:29:58 +01:00
}
2020-07-14 22:19:29 +02:00
}
2020-11-14 03:16:03 +01:00
2021-04-28 00:48:39 +02:00
/* -------------------------------------------- */
2022-09-22 00:33:50 +02:00
_presentCite ( tmr ) {
2021-02-12 12:50:17 +01:00
const presentCite = this . casesSpeciales . find ( c => EffetsDraconiques . presentCites . isCase ( c , tmr . coord ) ) ;
if ( presentCite ) {
this . minimize ( ) ;
2022-06-12 12:14:55 +02:00
const caseData = presentCite ;
2022-11-07 00:04:43 +01:00
EffetsDraconiques . presentCites . choisirUnPresent ( caseData , ( present => this . _utiliserPresentCite ( presentCite , present , tmr ) ) ) ;
2021-02-12 12:50:17 +01:00
}
return presentCite ;
}
2021-04-28 00:48:39 +02:00
/* -------------------------------------------- */
2022-11-07 00:04:43 +01:00
async _utiliserPresentCite ( presentCite , present , tmr ) {
this . currentRencontre = present . clone ( {
'system.force' : await RdDDice . rollTotal ( present . system . formule ) ,
'system.coord' : tmr . coord
2022-12-17 17:50:55 +01:00
} , { save : false } ) ;
2022-11-07 00:04:43 +01:00
2021-02-12 13:05:09 +01:00
await EffetsDraconiques . presentCites . ouvrirLePresent ( this . actor , presentCite ) ;
this . removeToken ( tmr , presentCite ) ;
// simuler une rencontre
2021-02-12 12:50:17 +01:00
let rencontreData = {
actor : this . actor ,
alias : this . actor . name ,
reveDepart : this . actor . getReveActuel ( ) ,
competence : this . actor . getBestDraconic ( ) ,
2021-02-12 13:05:09 +01:00
rencontre : this . currentRencontre ,
tmr : tmr ,
presentCite : presentCite
2021-02-12 12:50:17 +01:00
} ;
2021-02-12 13:05:09 +01:00
await this . _tentativeMaitrise ( rencontreData ) ;
2021-02-12 12:50:17 +01:00
this . maximize ( ) ;
2022-09-22 00:33:50 +02:00
this . postRencontre ( tmr ) ;
2021-02-12 12:50:17 +01:00
}
2020-12-30 15:18:58 +01:00
/* -------------------------------------------- */
2021-02-05 01:38:40 +01:00
async _jetDeRencontre ( tmr ) {
2022-11-07 00:04:43 +01:00
let rencontre = this . lookupRencontreExistente ( tmr ) ;
2021-01-29 15:13:59 +01:00
if ( rencontre ) {
2022-11-28 16:00:49 +01:00
return game . system . rdd . rencontresTMR . calculRencontre ( rencontre , tmr ) ;
2021-01-29 15:13:59 +01:00
}
2022-03-30 01:18:34 +02:00
let locTMR = ( this . isDemiReveCache ( )
2022-11-07 00:04:43 +01:00
? TMRUtility . getTMRType ( tmr . coord ) + " ??"
2022-03-30 01:18:34 +02:00
: tmr . label + " (" + tmr . coord + ")" ) ;
2021-05-28 10:25:34 +02:00
2022-11-07 00:04:43 +01:00
let myRoll = await RdDDice . rollTotal ( "1dt" , { showDice : SHOW _DICE } ) ;
2022-11-10 00:59:25 +01:00
if ( myRoll == 7 ) {
2021-05-28 10:25:34 +02:00
this . _tellToUser ( myRoll + ": Rencontre en " + locTMR ) ;
2022-11-28 16:00:49 +01:00
return await game . system . rdd . rencontresTMR . getRencontreAleatoire ( tmr , this . actor . isMauvaiseRencontre ( ) )
2021-05-28 10:25:34 +02:00
} else {
this . _tellToUser ( myRoll + ": Pas de rencontre en " + locTMR ) ;
2021-01-29 15:13:59 +01:00
}
2021-02-06 21:53:25 +01:00
}
2022-11-07 00:04:43 +01:00
lookupRencontreExistente ( tmr ) {
return this . rencontresExistantes . find ( it => it . system . coord == tmr . coord )
? ? this . rencontresExistantes . find ( it => it . system . coord == "" ) ;
2020-11-29 18:06:19 +01:00
}
2020-12-30 18:12:01 +01:00
/* -------------------------------------------- */
2021-02-12 01:44:27 +01:00
async manageTmrInnaccessible ( tmr ) {
2022-09-17 23:45:59 +02:00
if ( ! tmr ) {
return await this . actor . reinsertionAleatoire ( 'Sortie de carte' ) ;
}
2021-02-12 01:44:27 +01:00
const caseTmrInnaccessible = this . casesSpeciales . find ( c => EffetsDraconiques . isInnaccessible ( c , tmr . coord ) ) ;
if ( caseTmrInnaccessible ) {
return await this . actor . reinsertionAleatoire ( caseTmrInnaccessible . name ) ;
2020-12-30 18:12:01 +01:00
}
2021-02-12 01:44:27 +01:00
return tmr ;
2020-12-30 18:12:01 +01:00
}
2020-11-12 16:35:51 +01:00
/* -------------------------------------------- */
2021-02-05 01:38:40 +01:00
async manageCaseHumide ( tmr ) {
if ( this . isCaseHumide ( tmr ) ) {
2021-02-06 21:53:25 +01:00
let rollData = {
actor : this . actor ,
competence : duplicate ( this . actor . getBestDraconic ( ) ) ,
tmr : tmr ,
canClose : false ,
diffLibre : - 7 ,
2021-02-11 02:48:27 +01:00
forceCarac : { 'reve-actuel' : { label : "Rêve Actuel" , value : this . actor . getReveActuel ( ) } } ,
maitrise : { verbe : 'maîtriser' , action : 'Maîtriser le fleuve' }
2020-11-12 16:35:51 +01:00
}
2021-02-12 12:50:17 +01:00
rollData . double = EffetsDraconiques . isDoubleResistanceFleuve ( this . actor ) ? true : undefined ,
2022-11-07 00:04:43 +01:00
rollData . competence . system . defaut _carac = 'reve-actuel' ;
2021-02-06 21:53:25 +01:00
await this . _rollMaitriseCaseHumide ( rollData ) ;
2020-07-17 22:04:35 +02:00
}
}
2021-02-05 01:38:40 +01:00
2021-02-11 02:48:27 +01:00
/* -------------------------------------------- */
async _rollMaitriseCaseHumide ( rollData ) {
await this . _maitriserTMR ( rollData , r => this . _resultatMaitriseCaseHumide ( r ) ) ;
}
async _resultatMaitriseCaseHumide ( rollData ) {
2021-02-28 01:54:19 +01:00
await this . souffleSiEchecTotal ( rollData ) ;
2021-02-12 01:11:03 +01:00
if ( rollData . rolled . isSuccess && rollData . double ) {
2021-02-11 02:48:27 +01:00
rollData . previous = { rolled : rollData . rolled , ajustements : rollData . ajustements } ;
2021-02-12 01:11:03 +01:00
rollData . double = undefined ;
2021-02-11 02:48:27 +01:00
await this . _rollMaitriseCaseHumide ( rollData ) ;
return ;
}
2021-05-11 21:45:43 +02:00
rollData . poesie = await Poetique . getExtrait ( ) ;
2021-02-11 02:48:27 +01:00
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name ) ,
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html ` , rollData )
} ) ;
if ( rollData . rolled . isEchec ) {
2022-09-22 00:33:50 +02:00
await this . close ( ) ;
2021-02-11 02:48:27 +01:00
}
}
2021-05-28 07:54:25 +02:00
/* -------------------------------------------- */
2021-02-28 01:54:19 +01:00
async souffleSiEchecTotal ( rollData ) {
if ( rollData . rolled . isETotal ) {
rollData . souffle = await this . actor . ajouterSouffle ( { chat : false } ) ;
}
}
2021-02-06 21:53:25 +01:00
/* -------------------------------------------- */
2021-02-05 01:38:40 +01:00
isCaseHumide ( tmr ) {
2021-02-11 02:48:27 +01:00
if ( ! ( TMRUtility . isCaseHumide ( tmr ) || this . isCaseHumideAdditionelle ( tmr ) ) ) {
2022-09-30 01:55:04 +02:00
return false ;
2021-02-11 02:48:27 +01:00
}
2021-02-05 01:38:40 +01:00
if ( this . isCaseMaitrisee ( tmr . coord ) ) {
ChatMessage . create ( {
content : tmr . label + ": cette case humide est déja maitrisée grâce à votre Tête <strong>Quête des Eaux</strong>" ,
whisper : ChatMessage . getWhisperRecipients ( game . user . name )
} ) ;
2022-09-30 01:55:04 +02:00
return false ;
2021-02-05 01:38:40 +01:00
}
2022-09-30 01:55:04 +02:00
return true ;
2021-02-05 01:38:40 +01:00
}
2021-02-06 21:53:25 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
isCaseHumideAdditionelle ( tmr ) {
if ( tmr . type == 'pont' && EffetsDraconiques . isPontImpraticable ( this . actor ) ) {
ChatMessage . create ( {
content : tmr . label + ": Vous êtes sous le coup d'une Impraticabilité des Ponts : ce pont doit être maîtrisé comme une case humide." ,
whisper : ChatMessage . getWhisperRecipients ( game . user . name )
} ) ;
return true ;
}
if ( this . isCaseInondee ( tmr . coord ) ) {
ChatMessage . create ( {
content : tmr . label + ": cette case est inondée, elle doit être maîtrisée comme une case humide." ,
whisper : ChatMessage . getWhisperRecipients ( game . user . name )
} ) ;
return true ;
}
return false ;
2021-02-06 21:53:25 +01:00
}
2021-02-12 01:11:03 +01:00
2021-02-11 02:48:27 +01:00
/* -------------------------------------------- */
async conquerirCiteFermee ( tmr ) {
2021-02-12 01:44:27 +01:00
if ( EffetsDraconiques . fermetureCites . find ( this . casesSpeciales , tmr . coord ) ) {
await this . _conquerir ( tmr , {
difficulte : - 9 ,
action : 'Conquérir la cité' ,
2021-02-28 01:50:15 +01:00
onConqueteReussie : r => EffetsDraconiques . fermetureCites . onVisiteSupprimer ( r . actor , tmr , ( casetmr ) => this . removeToken ( tmr , casetmr ) ) ,
onConqueteEchec : r => {
2021-02-28 01:54:19 +01:00
this . souffleSiEchecTotal ( rollData ) ;
2021-02-28 01:50:15 +01:00
this . close ( )
} ,
2021-02-12 01:44:27 +01:00
canClose : false
} ) ;
2021-02-11 02:48:27 +01:00
}
2021-02-12 01:44:27 +01:00
}
2021-02-28 01:56:17 +01:00
/* -------------------------------------------- */
async purifierPeriple ( tmr ) {
if ( EffetsDraconiques . periple . find ( this . casesSpeciales , tmr . coord ) ) {
await this . _conquerir ( tmr , {
difficulte : EffetsDraconiques . periple . getDifficulte ( tmr ) ,
action : 'Purifier ' + TMRUtility . getTMRDescr ( tmr . coord ) ,
onConqueteReussie : r => EffetsDraconiques . periple . onVisiteSupprimer ( r . actor , tmr , ( casetmr ) => this . removeToken ( tmr , casetmr ) ) ,
onConqueteEchec : r => {
this . souffleSiEchecTotal ( rollData ) ;
this . close ( )
} ,
canClose : false
} ) ;
}
2021-02-12 01:44:27 +01:00
}
/* -------------------------------------------- */
async conquerirTMR ( tmr ) {
if ( EffetsDraconiques . conquete . find ( this . casesSpeciales , tmr . coord ) ) {
await this . _conquerir ( tmr , {
difficulte : - 7 ,
action : 'Conquérir' ,
2021-02-28 01:50:15 +01:00
onConqueteReussie : r => EffetsDraconiques . conquete . onVisiteSupprimer ( r . actor , tmr , ( casetmr ) => this . removeToken ( tmr , casetmr ) ) ,
onConqueteEchec : r => this . close ( ) ,
2021-02-12 01:44:27 +01:00
canClose : false
} ) ;
2021-02-11 02:48:27 +01:00
}
}
2021-02-12 01:44:27 +01:00
/* -------------------------------------------- */
async _conquerir ( tmr , options ) {
let rollData = {
actor : this . actor ,
competence : duplicate ( this . actor . getBestDraconic ( ) ) ,
tmr : tmr ,
canClose : options . canClose ? ? false ,
diffLibre : options . difficulte ? ? - 7 ,
forceCarac : { 'reve-actuel' : { label : "Rêve Actuel" , value : this . actor . getReveActuel ( ) } } ,
maitrise : { verbe : 'conquérir' , action : options . action }
} ;
2022-06-12 12:14:55 +02:00
rollData . competence . system . defaut _carac = 'reve-actuel' ;
2021-02-12 01:44:27 +01:00
await this . _maitriserTMR ( rollData , r => this . _onResultatConquerir ( r , options ) ) ;
}
2021-04-28 00:48:39 +02:00
/* -------------------------------------------- */
2021-02-12 01:44:27 +01:00
async _onResultatConquerir ( rollData , options ) {
2021-02-06 21:53:25 +01:00
if ( rollData . rolled . isETotal ) {
rollData . souffle = await this . actor . ajouterSouffle ( { chat : false } ) ;
}
2021-05-11 21:45:43 +02:00
rollData . poesie = await Poetique . getExtrait ( ) ;
2021-02-06 21:53:25 +01:00
ChatMessage . create ( {
2021-02-06 23:58:15 +01:00
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name ) ,
2021-02-11 02:48:27 +01:00
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html ` , rollData )
2021-02-06 21:53:25 +01:00
} ) ;
if ( rollData . rolled . isEchec ) {
2021-02-12 01:44:27 +01:00
options . onConqueteEchec ( rollData , options . effetDraconique ) ;
2021-02-06 21:53:25 +01:00
}
2021-02-11 02:48:27 +01:00
else {
2021-02-12 01:44:27 +01:00
await options . onConqueteReussie ( rollData , options . effetDraconique ) ;
this . updateTokens ( ) ;
2021-02-11 02:48:27 +01:00
}
2021-02-06 21:53:25 +01:00
}
2020-12-30 19:18:07 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
async _maitriserTMR ( rollData , callbackMaitrise ) {
this . minimize ( ) ; // Hide
2022-06-26 01:09:57 +02:00
rollData . isTMRCache = rollData . actor . isTMRCache ( ) ;
2021-02-11 02:48:27 +01:00
const dialog = await RdDRoll . create ( this . actor , rollData ,
{
html : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-maitrise-tmr.html' ,
close : html => { this . maximize ( ) ; } // Re-display TMR
} ,
{
name : rollData . maitrise . verbe , label : rollData . maitrise . action ,
callbacks : [
this . actor . createCallbackExperience ( ) ,
{ action : callbackMaitrise }
]
}
) ;
dialog . render ( true ) ;
2020-12-30 19:18:07 +01:00
}
2020-11-14 03:16:03 +01:00
2021-04-25 10:08:40 +02:00
/* -------------------------------------------- */
2021-02-28 01:50:15 +01:00
async validerVisite ( tmr ) {
await EffetsDraconiques . pelerinage . onVisiteSupprimer ( this . actor , tmr , ( casetmr ) => this . removeToken ( tmr , casetmr ) ) ;
2021-02-28 01:56:17 +01:00
await EffetsDraconiques . urgenceDraconique . onVisiteSupprimer ( this . actor , tmr , ( casetmr ) => this . removeToken ( tmr , casetmr ) ) ;
2021-02-12 18:31:49 +01:00
}
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2021-02-12 01:44:27 +01:00
async declencheSortEnReserve ( coord ) {
2022-09-17 16:07:38 +02:00
let sorts = this . getSortsReserve ( coord ) ;
if ( sorts . length > 0 ) {
2021-02-28 01:56:17 +01:00
if ( EffetsDraconiques . isSortReserveImpossible ( this . actor ) ) {
2021-02-12 18:31:49 +01:00
ui . notifications . error ( "Une queue ou un souffle vous empèche de déclencher de sort!" ) ;
2021-02-12 01:44:27 +01:00
return ;
}
2021-02-28 01:56:17 +01:00
if ( ! EffetsDraconiques . isUrgenceDraconique ( this . actor ) &&
( EffetsDraconiques . isReserveEnSecurite ( this . actor ) || this . isReserveExtensible ( coord ) ) ) {
2021-01-29 15:13:59 +01:00
let msg = "Vous êtes sur une case avec un Sort en Réserve. Grâce à votre Tête <strong>Reserve en Sécurité</strong> ou <strong>Réserve Exensible</strong>, vous pouvez contrôler le déclenchement. Cliquez si vous souhaitez le déclencher : <ul>" ;
2022-09-17 16:07:38 +02:00
for ( let sort of sorts ) {
msg += ` <li><a class="chat-card-button declencher-sort-reserve" data-actor-id=" ${ this . actor . id } " data-tmr-coord=" ${ coord } " data-sort-id=' ${ sort . id } "> ${ sort . name } </a></li> ` ;
2020-12-30 19:18:07 +01:00
}
msg += "</ol>" ;
2021-01-29 15:13:59 +01:00
ChatMessage . create ( {
2020-12-30 19:18:07 +01:00
content : msg ,
2021-01-29 15:13:59 +01:00
whisper : ChatMessage . getWhisperRecipients ( game . user . name )
} ) ;
2021-02-28 01:56:17 +01:00
return ;
2020-12-30 19:18:07 +01:00
}
2022-09-17 16:07:38 +02:00
await this . processSortReserve ( sorts [ 0 ] ) ;
2020-12-30 19:18:07 +01:00
}
}
2021-02-11 02:48:27 +01:00
2020-12-30 19:18:07 +01:00
/* -------------------------------------------- */
2021-02-12 01:11:03 +01:00
lancerSortEnReserve ( coord , sortId ) {
2022-09-17 16:07:38 +02:00
let sorts = this . getSortsReserve ( coord ) ;
let sort = sorts . find ( it => it . id == sortId ) ;
if ( sort ) {
this . processSortReserve ( sort ) ;
2020-12-30 19:18:07 +01:00
} else {
2021-01-29 15:13:59 +01:00
ChatMessage . create ( {
2022-09-17 16:07:38 +02:00
content :
"Une erreur est survenue : impossible de récupérer le sort en réserve demandé." ,
whisper : ChatMessage . getWhisperRecipients ( game . user . name ) ,
2021-01-29 15:13:59 +01:00
} ) ;
2020-07-26 18:44:03 +02:00
}
}
2020-12-30 19:18:07 +01:00
/* -------------------------------------------- */
2021-01-29 15:13:59 +01:00
async processSortReserve ( sortReserve ) {
2022-09-17 16:07:38 +02:00
await this . actor . deleteEmbeddedDocuments ( 'Item' , [ sortReserve . id ] ) ;
console . log ( "declencheSortEnReserve" , sortReserve ) ;
2023-01-05 00:55:04 +01:00
const heureCible = RdDTimestamp . definition ( sortReserve . system . heurecible ) . label ;
2022-09-17 16:07:38 +02:00
this . _tellToUserAndGM ( ` Vous avez déclenché
$ { sortReserve . system . echectotal ? "<strong>l'échec total!</strong>" : "le sort" }
en réserve < strong > $ { sortReserve . name } < / s t r o n g >
avec $ { sortReserve . system . ptreve } points de Rêve
en $ { sortReserve . system . coord } ( $ { TMRUtility . getTMRLabel ( sortReserve . system . coord ) } ) .
2022-11-16 02:52:55 +01:00
L ' heure ciblée est $ { heureCible } ` );
2020-12-30 19:18:07 +01:00
this . close ( ) ;
}
2020-11-20 13:46:43 +01:00
/* -------------------------------------------- */
2021-01-29 15:13:59 +01:00
nettoyerRencontre ( ) {
if ( ! this . currentRencontre ) return ; // Sanity check
if ( this . currentRencontre . graphics ) {
2020-11-20 13:46:43 +01:00
for ( let drawRect of this . currentRencontre . graphics ) { // Suppression des dessins des zones possibles
2021-01-29 15:13:59 +01:00
this . pixiApp . stage . removeChild ( drawRect ) ;
2020-11-20 13:46:43 +01:00
}
}
this . currentRencontre = undefined ; // Nettoyage de la structure
this . rencontreState = 'aucune' ; // Et de l'état
}
2020-12-30 19:18:07 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
isCaseInondee ( coord ) {
2021-02-12 01:44:27 +01:00
return EffetsDraconiques . debordement . find ( this . casesSpeciales , coord ) ;
2021-02-11 02:48:27 +01:00
}
isCiteFermee ( coord ) {
2021-02-12 01:44:27 +01:00
return EffetsDraconiques . fermetureCites . find ( this . casesSpeciales , coord ) ;
2020-12-30 19:18:07 +01:00
}
2020-12-30 21:11:01 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
isTerreAttache ( coord ) {
2021-02-12 01:44:27 +01:00
return EffetsDraconiques . terreAttache . find ( this . casesSpeciales , coord ) ;
2021-02-11 02:48:27 +01:00
}
/* -------------------------------------------- */
isCaseMaitrisee ( coord ) {
2021-02-12 01:44:27 +01:00
return EffetsDraconiques . queteEaux . find ( this . casesSpeciales , coord ) ;
2021-02-11 02:48:27 +01:00
}
/* -------------------------------------------- */
isReserveExtensible ( coord ) {
2021-02-12 01:44:27 +01:00
return EffetsDraconiques . reserveExtensible . find ( this . casesSpeciales , coord ) ;
2021-02-11 02:48:27 +01:00
}
/* -------------------------------------------- */
isConnaissanceFleuve ( currentTMR , nextTMR ) {
return TMRUtility . getTMR ( currentTMR ) . type == 'fleuve' &&
TMRUtility . getTMR ( nextTMR ) . type == 'fleuve' &&
EffetsDraconiques . isConnaissanceFleuve ( this . actor ) ;
2020-12-30 21:11:01 +01:00
}
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2021-02-05 01:38:40 +01:00
async onClickTMR ( event ) {
2020-11-14 20:46:39 +01:00
if ( this . viewOnly ) {
return ;
}
2021-12-12 17:36:22 +01:00
let clickOddq = RdDTMRDialog . _computeEventOddq ( event . data . originalEvent ) ;
await this . _onClickTMRPos ( clickOddq ) ; // Vérifier l'état des compteurs reve/fatigue/vie
2021-02-05 01:38:40 +01:00
}
2021-04-25 10:08:40 +02:00
/* -------------------------------------------- */
2021-12-12 17:36:22 +01:00
async _onClickTMRPos ( clickOddq ) {
let currentOddq = TMRUtility . coordTMRToOddq ( this . _getActorCoord ( ) ) ;
let targetCoord = TMRUtility . oddqToCoordTMR ( clickOddq ) ;
let currentCoord = TMRUtility . oddqToCoordTMR ( currentOddq ) ;
2020-11-20 12:06:54 +01:00
// Validation de la case de destination (gestion du cas des rencontres qui peuvent téléporter)
2021-12-12 17:36:22 +01:00
let deplacementType = this . _calculDeplacement ( targetCoord , currentCoord , currentOddq , clickOddq ) ;
2021-05-10 18:39:35 +02:00
2022-06-25 17:49:19 +02:00
if ( this . isDemiReveCache ( ) ) {
if ( this . isTerreAttache ( targetCoord )
2022-11-07 00:04:43 +01:00
|| this . isConnaissanceFleuve ( currentCoord , targetCoord )
|| deplacementType == 'changeur' ) {
2022-06-25 17:49:19 +02:00
// déplacement possible
2022-09-30 01:55:04 +02:00
await this . actor . setTMRVisible ( true ) ;
this . demiReve = this . _tokenDemiReve ( ) ;
this . _trackToken ( this . demiReve ) ;
2022-06-25 17:49:19 +02:00
}
2022-11-07 00:04:43 +01:00
else {
2022-06-25 17:49:19 +02:00
ui . notifications . error ( ` Vous ne connaissez plus votre position dans les TMR.
Vous devez utiliser les boutons de direction pour vous déplacer .
Une fois que vous aurez retrouvé votre demi - rêve , demandez au gardien de vérifier et rendre les TMR visibles .
` );
return ;
}
}
2022-11-07 00:04:43 +01:00
switch ( deplacementType ) {
2022-06-25 17:49:19 +02:00
case 'normal' :
2022-11-07 00:04:43 +01:00
case 'changeur' :
case 'passeur' :
2022-06-25 17:49:19 +02:00
await this . _deplacerDemiReve ( targetCoord , deplacementType ) ;
break ;
case 'messager' :
await this . _messagerDemiReve ( targetCoord ) ;
break ;
default :
2022-11-07 00:04:43 +01:00
ui . notifications . error ( "Vous ne pouvez pas vous déplacer que sur des cases adjacentes à votre position ou valides dans le cas d'une rencontre" ) ;
console . log ( "STATUS :" , this . rencontreState , this . currentRencontre ) ;
2021-02-05 01:38:40 +01:00
}
2022-06-25 17:49:19 +02:00
2021-02-05 01:38:40 +01:00
this . checkQuitterTMR ( ) ;
}
2021-02-12 01:44:27 +01:00
/* -------------------------------------------- */
2021-12-12 17:36:22 +01:00
_calculDeplacement ( targetCoord , currentCoord , fromOddq , toOddq ) {
2022-11-07 00:04:43 +01:00
if ( this . isRencontreDeplacement ( ) ) {
if ( this . currentRencontre ? . locList ? . find ( coord => coord == targetCoord ) ) {
return this . rencontreState ;
}
}
else {
if ( this . isTerreAttache ( targetCoord ) || this . isConnaissanceFleuve ( currentCoord , targetCoord ) || TMRUtility . distanceOddq ( fromOddq , toOddq ) <= 1 ) {
return 'normal'
2021-02-12 01:44:27 +01:00
}
}
2022-06-25 17:49:19 +02:00
return 'erreur' ;
2021-02-12 01:44:27 +01:00
}
2022-11-07 00:04:43 +01:00
isRencontreDeplacement ( ) {
return [ 'passeur' , 'changeur' , 'messager' ] . includes ( this . rencontreState ) ;
}
2021-02-12 01:44:27 +01:00
/* -------------------------------------------- */
async _messagerDemiReve ( targetCoord ) {
/ *
TODO : si la case a un sort en réserve , lancer ce sort .
Si la case est le demi - rêve , ne pas lancer de sort .
Si un lancement de sort est en cours , trouver un moyen de réafficher cette fenêtre si on essaie de lancer un sort ( ou bloquer le lancer de sort )
* /
2021-05-11 21:21:33 +02:00
this . notifierResonanceSigneDraconique ( targetCoord ) ;
2021-02-12 01:44:27 +01:00
await this . actor . rollUnSort ( targetCoord ) ;
2021-02-05 01:38:40 +01:00
this . nettoyerRencontre ( ) ;
}
2021-04-28 00:48:39 +02:00
/* -------------------------------------------- */
2022-06-25 17:49:19 +02:00
externalRefresh ( ) {
2021-04-28 00:48:39 +02:00
this . createPixiSprites ( ) ;
this . updateValuesDisplay ( ) ;
this . updateTokens ( ) ;
console . log ( "TMR REFRESHED !!!" ) ;
}
/* -------------------------------------------- */
2021-02-05 01:38:40 +01:00
async _deplacerDemiReve ( targetCoord , deplacementType ) {
if ( this . currentRencontre != 'normal' ) {
this . nettoyerRencontre ( ) ;
}
let tmr = TMRUtility . getTMR ( targetCoord ) ;
2021-02-12 01:44:27 +01:00
// Gestion cases spéciales type Trou noir, etc
tmr = await this . manageTmrInnaccessible ( tmr ) ;
2021-02-05 01:38:40 +01:00
2021-02-12 01:44:27 +01:00
await this . actor . updateCoordTMR ( tmr . coord ) ;
2021-02-05 01:38:40 +01:00
2022-06-25 17:49:19 +02:00
this . forceDemiRevePositionView ( ) ;
2021-05-10 18:39:35 +02:00
if ( ReglesOptionelles . isUsing ( "appliquer-fatigue" ) ) {
2021-05-08 20:08:56 +02:00
this . cumulFatigue += this . fatigueParCase ;
}
2021-02-05 01:38:40 +01:00
this . updateValuesDisplay ( ) ;
2022-06-25 17:49:19 +02:00
this . actor . notifyRefreshTMR ( ) ;
2021-02-05 01:38:40 +01:00
if ( deplacementType == 'normal' ) { // Pas de rencontres après un saut de type passeur/changeur/...
2022-09-22 00:33:50 +02:00
await this . manageRencontre ( tmr ) ;
2020-07-14 22:19:29 +02:00
}
2021-02-06 21:53:25 +01:00
else {
2021-02-05 01:38:40 +01:00
await this . postRencontre ( tmr ) ;
}
}
2020-11-21 08:27:28 +01:00
2021-05-11 21:21:33 +02:00
async notifierResonanceSigneDraconique ( coord ) {
if ( this . actor . isResonanceSigneDraconique ( coord ) ) {
ChatMessage . create ( {
whisper : ChatUtility . getWhisperRecipientsAndGMs ( game . user . name ) ,
content : await renderTemplate ( ` systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-resonance.html ` , { alias : this . actor . name , typeTMR : TMRUtility . getTMRType ( coord ) } )
} ) ;
}
}
2021-04-25 10:08:40 +02:00
/* -------------------------------------------- */
2021-02-05 01:38:40 +01:00
async postRencontre ( tmr ) {
2021-02-12 01:44:27 +01:00
if ( ! ( this . viewOnly || this . currentRencontre ) ) {
2022-09-17 16:07:38 +02:00
// TODO: vérifier que la méthode s'arrête en cas de non-maîtrise
2022-09-22 00:33:50 +02:00
if ( ! this . descenteTMR ) await this . manageCaseHumide ( tmr ) ;
if ( ! this . descenteTMR ) await this . conquerirCiteFermee ( tmr ) ;
if ( ! this . descenteTMR ) await this . purifierPeriple ( tmr ) ;
if ( ! this . descenteTMR ) await this . conquerirTMR ( tmr ) ;
if ( ! this . descenteTMR ) await this . validerVisite ( tmr ) ;
if ( ! this . descenteTMR ) await this . declencheSortEnReserve ( tmr . coord ) ;
if ( ! this . descenteTMR ) await this . actor . checkSoufflePeage ( tmr ) ;
2021-02-12 01:44:27 +01:00
}
2020-07-05 22:35:18 +02:00
}
2021-02-28 01:50:15 +01:00
2021-01-23 23:56:43 +01:00
/* -------------------------------------------- */
2022-06-25 17:49:19 +02:00
async positionnerDemiReve ( coord ) {
2021-02-12 01:44:27 +01:00
await this . actor . updateCoordTMR ( coord ) ;
2022-06-25 17:49:19 +02:00
this . forceDemiRevePositionView ( ) ;
2021-02-12 01:44:27 +01:00
let tmr = TMRUtility . getTMR ( coord ) ;
2021-02-12 18:31:49 +01:00
await this . postRencontre ( tmr ) ;
2021-02-12 01:44:27 +01:00
return tmr ;
2020-11-17 18:08:19 +01:00
}
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2021-12-12 17:36:22 +01:00
static _computeEventOddq ( origEvent ) {
2020-11-14 03:16:03 +01:00
let canvasRect = origEvent . target . getBoundingClientRect ( ) ;
let x = origEvent . clientX - canvasRect . left ;
let y = origEvent . clientY - canvasRect . top ;
2021-12-12 17:36:22 +01:00
let col = Math . floor ( x / tmrConstants . cellw ) ; // [From 0 -> 12]
2022-09-17 16:07:38 +02:00
y -= col % 2 == 0 ? tmrConstants . col1 _y : tmrConstants . col2 _y ;
2021-12-12 17:36:22 +01:00
let row = Math . floor ( y / tmrConstants . cellh ) ; // [From 0 -> 14]
return { col : col , row : row } ;
2020-11-14 03:16:03 +01:00
}
2020-11-17 18:08:19 +01:00
/* -------------------------------------------- */
2020-11-20 12:06:54 +01:00
/** Retourne les coordonnées x, h, w, h du rectangle d'une case donnée */
2021-01-29 15:13:59 +01:00
_getCaseRectangleCoord ( coord ) {
2021-12-12 17:36:22 +01:00
return this . pixiTMR . getCaseRectangle ( TMRUtility . coordTMRToOddq ( coord ) ) ;
2020-11-20 12:06:54 +01:00
}
2022-09-17 16:07:38 +02:00
2020-11-17 18:08:19 +01:00
/* -------------------------------------------- */
2020-11-14 03:16:03 +01:00
_removeTokens ( filter ) {
const tokensToRemove = this . allTokens . filter ( filter ) ;
for ( let token of tokensToRemove ) {
this . pixiApp . stage . removeChild ( token . sprite ) ;
}
}
2022-09-17 16:07:38 +02:00
2020-11-17 18:08:19 +01:00
/* -------------------------------------------- */
2020-11-14 03:16:03 +01:00
_trackToken ( token ) {
2022-06-25 17:49:19 +02:00
if ( this . demiReve === token && this . isDemiReveCache ( ) ) {
return ;
}
this . pixiTMR . setPosition ( token . sprite , TMRUtility . coordTMRToOddq ( token . coordTMR ( ) ) ) ;
2021-02-11 02:48:27 +01:00
this . allTokens . push ( token ) ;
2020-07-05 21:45:25 +02:00
}
}