2022-01-29 22:49:34 +01:00
import { SYSTEM _SOCKET _ID } 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 { TMRRencontres } from "./tmr-rencontres.js" ;
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-03-22 20:10:37 +01:00
import { Misc } from "./misc.js" ;
2021-05-08 20:08:56 +02:00
import { HtmlUtility } from "./html-utility.js" ;
import { ReglesOptionelles } from "./regles-optionelles.js" ;
2021-05-11 21:45:43 +02:00
import { RdDDice } from "./rdd-dice.js" ;
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
2021-02-11 02:48:27 +01:00
static async create ( html , actor , tmrData ) {
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 ( ) ;
this . loadSortsReserve ( ) ;
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 ( ) {
this . casesSpeciales = this . actor . data . items . filter ( item => Draconique . isCaseTMR ( item ) ) ;
}
2021-04-28 00:48:39 +02:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
loadSortsReserve ( ) {
2021-03-22 20:10:37 +01:00
this . sortsReserves = Misc . data ( this . actor ) . data . reve . reserve . list ;
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-06-25 17:49:19 +02:00
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
_createTokens ( ) {
2022-06-25 17:49:19 +02:00
if ( ! this . isDemiReveCache ( ) ) {
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 ( ) ;
this . loadSortsReserve ( ) ;
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 ( ) {
return this . sortsReserves . 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 ) {
return EffetsDraconiques . rencontre . token ( this . pixiTMR , rencontre , ( ) => rencontre . coord ) ;
}
2021-02-12 12:50:17 +01:00
_tokenCaseSpeciale ( casetmr ) {
2021-03-29 23:41:08 +02:00
const caseData = Misc . data ( casetmr ) ;
const draconique = Draconique . get ( caseData . data . specific ) ;
return draconique ? . token ( this . pixiTMR , caseData , ( ) => caseData . data . coord ) ;
2021-02-11 02:48:27 +01:00
}
_tokenSortEnReserve ( sortEnReserve ) {
return EffetsDraconiques . sortReserve . token ( this . pixiTMR , sortEnReserve . sort , ( ) => sortEnReserve . coord ) ;
}
2021-05-10 18:39:35 +02:00
2021-02-11 02:48:27 +01:00
_tokenDemiReve ( ) {
2021-03-29 23:41:08 +02:00
const actorData = Misc . data ( this . actor ) ;
return EffetsDraconiques . demiReve . token ( this . pixiTMR , actorData , ( ) => actorData . data . 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 ( ) {
return Misc . data ( this . actor ) . data . reve . tmrpos . coord ;
}
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 ) ;
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 ) {
2021-05-10 19:18:11 +02:00
html . find ( '.lancer-sort' ) . remove ( ) ;
html . find ( '.lire-signe-draconique' ) . remove ( ) ;
2021-02-11 02:48:27 +01:00
return ;
}
2021-05-10 19:18:11 +02:00
HtmlUtility . _showControlWhen ( $ ( ".appliquerFatigue" ) , ReglesOptionelles . isUsing ( "appliquer-fatigue" ) ) ;
HtmlUtility . _showControlWhen ( $ ( ".lire-signe-draconique" ) , this . actor . isResonanceSigneDraconique ( this . _getActorCoord ( ) ) ) ;
// Roll Sort
html . find ( '.lancer-sort' ) . click ( ( event ) => {
this . actor . rollUnSort ( this . _getActorCoord ( ) ) ;
} ) ;
html . find ( '.lire-signe-draconique' ) . click ( ( event ) => {
this . actor . rollLireSigneDraconique ( this . _getActorCoord ( ) ) ;
} ) ;
2021-04-28 00:48:39 +02:00
html . find ( '#dir-top' ) . click ( ( event ) => {
this . moveFromKey ( "top" ) ;
2021-05-10 18:39:35 +02:00
} ) ;
2021-04-28 00:48:39 +02:00
html . find ( '#dir-top-left' ) . click ( ( event ) => {
this . moveFromKey ( "top-left" ) ;
2021-05-10 18:39:35 +02:00
} ) ;
2021-04-28 00:48:39 +02:00
html . find ( '#dir-top-right' ) . click ( ( event ) => {
this . moveFromKey ( "top-right" ) ;
2021-05-10 18:39:35 +02:00
} ) ;
2021-04-28 00:48:39 +02:00
html . find ( '#dir-bottom-left' ) . click ( ( event ) => {
this . moveFromKey ( "bottom-left" ) ;
2021-05-10 18:39:35 +02:00
} ) ;
2021-04-28 00:48:39 +02:00
html . find ( '#dir-bottom-right' ) . click ( ( event ) => {
this . moveFromKey ( "bottom-right" ) ;
2021-05-10 18:39:35 +02:00
} ) ;
2021-04-28 00:48:39 +02:00
html . find ( '#dir-bottom' ) . click ( ( event ) => {
this . moveFromKey ( "bottom" ) ;
2021-05-10 18:39:35 +02:00
} ) ;
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 ( ) ) ;
2021-02-11 02:48:27 +01:00
await this . manageRencontre ( tmr , ( ) => {
this . postRencontre ( 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 ( ) {
const coord = this . _getActorCoord ( ) ;
const actorData = Misc . data ( this . actor ) ;
HtmlUtility . _showControlWhen ( $ ( ".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" ) ;
2021-03-22 20:10:37 +01:00
ptsreve . innerHTML = actorData . data . 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 ( ) ) {
2021-05-10 18:39:35 +02:00
tmrpos . innerHTML = '?? (' + TMRUtility . getTMRType ( coord ) + ')' ;
2021-04-28 00:48:39 +02:00
} else {
2021-05-10 18:39:35 +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" ) ;
2021-03-22 20:10:37 +01:00
refoulement . innerHTML = actorData . data . 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" ) ;
//console.log("Refresh : ", actorData.data.sante.fatigue.value);
fatigueItem . innerHTML = "<table class='table-fatigue'>" + RdDUtility . makeHTMLfatigueMatrix ( actorData . data . sante . fatigue . value , actorData . data . sante . endurance . max ) . html ( ) + "</table>" ;
}
2020-07-21 23:51:24 +02:00
}
2020-07-26 18:44:03 +02:00
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2021-02-11 02:48:27 +01:00
close ( ) {
2021-05-28 09:37:22 +02:00
if ( this . actor . tmrApp ) {
this . actor . tmrApp = undefined ; // Cleanup reference
if ( ! this . viewOnly ) {
2021-06-29 00:56:25 +02:00
this . actor . setStatusEffect ( "EFFECT.StatusDemiReve" , false ) ;
2021-05-28 09:37:22 +02:00
this . _tellToGM ( this . actor . name + " a quitté les terres médianes" ) ;
}
this . actor . santeIncDec ( "fatigue" , this . cumulFatigue ) . then ( super . close ( ) ) ; // moving 1 cell costs 1 fatigue
2021-02-11 02:48:27 +01:00
}
2020-07-26 18:44:03 +02:00
}
2020-11-14 03:16:03 +01:00
/* -------------------------------------------- */
2020-07-17 22:04:35 +02:00
async derober ( ) {
2020-11-14 03:16:03 +01:00
await this . actor . addTMRRencontre ( this . currentRencontre ) ;
2020-07-17 22:04:35 +02:00
console . log ( "-> derober" , 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 ( ) {
this . _tellToGM ( this . actor . name + " a refoulé : " + this . currentRencontre . name ) ;
2020-11-14 03:16:03 +01:00
await this . actor . deleteTMRRencontreAtPosition ( ) ; // Remove the stored rencontre if necessary
2021-01-29 15:13:59 +01:00
await this . actor . ajouterRefoulement ( this . currentRencontre . refoulement ? ? 1 ) ;
2021-02-11 02:48:27 +01:00
this . updateTokens ( ) ;
2020-07-14 22:19:29 +02:00
console . log ( "-> refouler" , this . currentRencontre )
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 ( ) {
this . _tellToGM ( this . actor . name + " a ignoré : " + this . currentRencontre . name ) ;
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 ( ) ;
}
/* -------------------------------------------- */
2021-12-12 17:36:22 +01:00
colorierZoneRencontre ( 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 ) {
let rect = this . _getCaseRectangleCoord ( coordTMR ) ;
2020-11-20 12:06:54 +01:00
var rectDraw = new PIXI . Graphics ( ) ;
rectDraw . beginFill ( 0xFFFF00 , 0.3 ) ;
// set the line style to have a width of 5 and set the color to red
rectDraw . lineStyle ( 5 , 0xFF0000 ) ;
// 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 14:30:00 +01:00
/* -------------------------------------------- */
2021-01-29 15:13:59 +01:00
// garder la trace de l'état en cours
setStateRencontre ( state ) {
this . rencontreState = state ;
2020-11-21 14:30:00 +01:00
}
2021-04-28 00:48:39 +02:00
/* -------------------------------------------- */
2021-01-29 15:13:59 +01:00
async choisirCasePortee ( coord , portee ) {
2022-06-25 17:49:19 +02:00
if ( this . actor . isTMRCache ( ) )
{
return ;
}
2021-01-29 15:13:59 +01:00
// Récupère la liste des cases à portées
let locList = TMRUtility . getTMRPortee ( coord , portee ) ;
this . colorierZoneRencontre ( locList ) ;
2020-12-30 15:18:58 +01:00
}
2020-11-21 08:27:28 +01:00
2021-04-28 00:48:39 +02:00
/* -------------------------------------------- */
2021-01-29 15:13:59 +01:00
async choisirCaseType ( type ) {
2021-02-11 02:48:27 +01:00
const locList = TMRUtility . filterTMR ( it => it . type == type ) . map ( it => it . coord ) ;
2021-01-29 15:13:59 +01:00
this . colorierZoneRencontre ( locList ) ;
2020-11-21 08:27:28 +01:00
}
2021-01-29 15:13:59 +01:00
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 ( ) {
if ( this . currentRencontre ? . isPersistant ) {
await this . refouler ( ) ;
2020-11-21 08:27:28 +01:00
}
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 ( ) {
2021-01-29 15:13:59 +01:00
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 ,
2021-05-27 19:40:45 +02: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 ) {
2021-03-29 18:08:18 +02:00
console . log ( "-> matriser" , rencData ) ;
2020-11-29 18:06:19 +01:00
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
2021-03-29 18:08:18 +02:00
let postProcess = await TMRRencontres . gererRencontre ( this , rencData ) ;
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
} ) ;
if ( postProcess ) {
/** Gère les rencontres avec du post-processing (passeur, messagers, tourbillons, ...) */
2021-03-29 18:08:18 +02:00
await postProcess ( this , rencData ) ;
2021-01-29 15:13:59 +01:00
}
else {
this . currentRencontre = undefined ;
}
2020-11-20 12:06:54 +01:00
2020-07-17 22:04:35 +02:00
this . updateValuesDisplay ( ) ;
2021-01-29 15:13:59 +01:00
if ( this . checkQuitterTMR ( ) ) {
return ;
}
2021-03-29 18:08:18 +02:00
else if ( rencData . rolled . isEchec && rencData . rencontre . isPersistant ) {
2021-01-29 15:13:59 +01:00
setTimeout ( ( ) => {
2021-03-29 18:08:18 +02:00
rencData . nbRounds ++ ;
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-03-29 18:08:18 +02:00
this . _tentativeMaitrise ( rencData ) ;
this . _deleteTmrMessages ( rencData . actor , rencData . nbRounds ) ;
2021-01-29 15:13:59 +01:00
} , 2000 ) ;
}
}
2021-04-28 00:48:39 +02:00
/* -------------------------------------------- */
2021-02-12 12:50:17 +01:00
_rollPresentCite ( rencontreData ) {
let rolled = RdDResolutionTable . computeChances ( rencontreData . reve , 0 ) ;
mergeObject ( rolled , { caracValue : rencontreData . reve , finalLevel : 0 , roll : rolled . score } ) ;
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
/* -------------------------------------------- */
2021-02-05 01:38:40 +01:00
async manageRencontre ( tmr , postRencontre ) {
2020-11-14 20:46:39 +01:00
if ( this . viewOnly ) {
return ;
}
2020-11-14 03:16:03 +01:00
this . currentRencontre = undefined ;
2021-02-12 12:50:17 +01:00
if ( this . _presentCite ( tmr , postRencontre ) ) {
return ;
}
2021-02-05 01:38:40 +01:00
let rencontre = await this . _jetDeRencontre ( tmr ) ;
2021-01-29 15:13:59 +01:00
2020-07-14 22:19:29 +02:00
if ( rencontre ) { // Manages it
2020-11-18 18:11:01 +01:00
if ( rencontre . rencontre ) rencontre = rencontre . rencontre ; // Manage stored rencontres
2020-12-30 18:12:01 +01:00
console . log ( "manageRencontre" , rencontre ) ;
2020-07-21 23:51:24 +02:00
this . currentRencontre = duplicate ( rencontre ) ;
2020-11-16 04:01:36 +01:00
2021-02-05 01:38:40 +01:00
let dialog = new RdDTMRRencontreDialog ( "" , this , this . currentRencontre , postRencontre ) ;
2020-11-12 23:35:29 +01:00
dialog . render ( true ) ;
2020-07-14 22:19:29 +02:00
}
2021-02-06 02:29:58 +01:00
else {
postRencontre ( ) ;
}
2020-07-14 22:19:29 +02:00
}
2020-11-14 03:16:03 +01:00
2021-04-28 00:48:39 +02:00
/* -------------------------------------------- */
2021-02-12 12:50:17 +01:00
_presentCite ( tmr , postRencontre ) {
const presentCite = this . casesSpeciales . find ( c => EffetsDraconiques . presentCites . isCase ( c , tmr . coord ) ) ;
if ( presentCite ) {
this . minimize ( ) ;
2021-12-23 01:31:27 +01:00
const caseData = Misc . data ( presentCite ) ;
EffetsDraconiques . presentCites . choisirUnPresent ( caseData , ( type => this . _utiliserPresentCite ( presentCite , type , tmr , postRencontre ) ) ) ;
2021-02-12 12:50:17 +01:00
}
return presentCite ;
}
2021-04-28 00:48:39 +02:00
/* -------------------------------------------- */
2021-02-12 12:50:17 +01:00
async _utiliserPresentCite ( presentCite , typeRencontre , tmr , postRencontre ) {
2021-02-12 13:05:09 +01:00
this . currentRencontre = TMRRencontres . getRencontre ( typeRencontre ) ;
await TMRRencontres . evaluerForceRencontre ( this . currentRencontre ) ;
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 ( ) ;
postRencontre ( ) ;
}
2020-12-30 15:18:58 +01:00
/* -------------------------------------------- */
2021-02-05 01:38:40 +01:00
async _jetDeRencontre ( tmr ) {
let rencontre = this . rencontresExistantes . find ( prev => prev . coord == tmr . coord ) ;
2021-01-29 15:13:59 +01:00
if ( rencontre ) {
return rencontre ;
}
2022-03-30 01:18:34 +02:00
let locTMR = ( this . isDemiReveCache ( )
? Misc . upperFirst ( tmr . type ) + " ??"
: tmr . label + " (" + tmr . coord + ")" ) ;
2021-05-28 10:25:34 +02:00
2021-11-21 22:41:53 +01:00
let myRoll = await RdDDice . rollTotal ( "1dt" ) ;
2021-02-11 02:48:27 +01:00
if ( TMRUtility . isForceRencontre ( ) || myRoll == 7 ) {
2021-05-28 10:25:34 +02:00
this . _tellToUser ( myRoll + ": Rencontre en " + locTMR ) ;
2021-02-06 21:53:25 +01:00
return await this . rencontreTMRRoll ( tmr , this . actor . isRencontreSpeciale ( ) ) ;
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
}
/* -------------------------------------------- */
async rencontreTMRRoll ( tmr , isMauvaise = false ) {
let rencontre = TMRUtility . utiliseForceRencontre ( ) ? ?
2021-02-11 02:48:27 +01:00
( isMauvaise
? await TMRRencontres . getMauvaiseRencontre ( )
: await TMRRencontres . getRencontreAleatoire ( tmr . type ) ) ;
2021-02-06 21:53:25 +01:00
rencontre . coord = tmr . coord ;
2021-02-12 01:44:27 +01:00
rencontre . date = game . system . rdd . calendrier . getDateFromIndex ( ) ;
2021-02-08 14:15:18 +01:00
rencontre . heure = game . system . rdd . calendrier . getCurrentHeure ( ) ;
2021-02-06 21:53:25 +01:00
return rencontre ;
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 ) {
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-04-23 01:02:03 +02:00
rollData . competence . data . 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-11 02:48:27 +01:00
this . toclose = rollData . rolled . isEchec ;
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 ) {
this . close ( ) ;
}
}
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 ) ) ) {
return undefined ;
}
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 )
} ) ;
2021-02-11 02:48:27 +01:00
return undefined ;
2021-02-05 01:38:40 +01:00
}
2021-02-11 02:48:27 +01:00
return - 7 ;
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 }
} ;
rollData . competence . data . defaut _carac = 'reve-actuel' ;
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 } ) ;
}
this . toclose = rollData . rolled . isEchec ;
2021-02-11 02:48:27 +01:00
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
const dialog = await RdDRoll . create ( this . actor , rollData ,
{
html : 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-maitrise-tmr.html' ,
2021-04-21 18:58:50 +02:00
options : { height : 420 } ,
2021-02-11 02:48:27 +01:00
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 ) {
2021-02-12 12:50:17 +01:00
2021-03-20 00:09:29 +01:00
let sortsEnCoord = TMRUtility . getSortsReserve ( this . sortsReserves , coord ) ;
if ( sortsEnCoord . 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>" ;
2021-03-20 00:09:29 +01:00
for ( let sortReserve of sortsEnCoord ) {
2021-02-12 01:44:27 +01:00
msg += "<li><a class='chat-card-button' id='sort-reserve' data-actor-id='" + this . actor . _id + "' data-tmr-coord='" + coord + "' data-sort-id='" + sortReserve . sort . _id + "'>" + sortReserve . 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
}
2021-03-20 00:09:29 +01:00
await this . processSortReserve ( sortsEnCoord [ 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 ) {
2021-03-20 00:09:29 +01:00
let sortEnCoord = TMRUtility . getSortsReserve ( this . sortsReserves , coord ) ;
let sortReserve = sortEnCoord . find ( sortReserve => sortReserve . sort . _id == sortId ) ;
2021-01-29 15:13:59 +01:00
if ( sortReserve ) {
this . processSortReserve ( sortReserve ) ;
2020-12-30 19:18:07 +01:00
} else {
2021-01-29 15:13:59 +01:00
ChatMessage . create ( {
2020-12-30 19:18:07 +01:00
content : "Une erreur est survenue : impossible de récupérer le sort en réserve demandé." ,
2021-01-29 15:13:59 +01:00
whisper : ChatMessage . getWhisperRecipients ( game . user . name )
} ) ;
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 ) {
2020-12-30 19:18:07 +01:00
await this . actor . deleteSortReserve ( sortReserve ) ;
2021-02-13 08:53:53 +01:00
//this.updateSortReserve();
2020-12-30 19:18:07 +01:00
console . log ( "declencheSortEnReserve" , sortReserve )
2021-03-20 00:09:29 +01:00
this . _tellToUserAndGM ( ` Vous avez déclenché le sort en réserve <strong> ${ sortReserve . sort . name } </strong>
2021-02-12 01:11:03 +01:00
avec $ { sortReserve . sort . data . ptreve _reel } points de Rêve
en $ { sortReserve . coord } ( $ { TMRUtility . getTMRLabel ( sortReserve . coord ) } )
` );
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 ;
}
2020-11-21 23:24:00 +01:00
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 )
|| ( this . isCaseHumide ( currentCoord ) && this . isCaseHumide ( targetCoord ) )
|| deplacementType == 'changeur' )
{
// déplacement possible
await this . actor . montreTMR ( ) ;
}
else
{
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 ;
}
}
switch ( deplacementType ) {
case 'normal' :
await this . _deplacerDemiReve ( targetCoord , deplacementType ) ;
break ;
case 'messager' :
await this . _messagerDemiReve ( targetCoord ) ;
break ;
case 'changeur' :
case 'passeur' :
await this . _deplacerDemiReve ( targetCoord , deplacementType ) ;
break ;
default :
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-06-25 17:49:19 +02:00
2021-12-12 17:36:22 +01:00
const isInArea = this . rencontreState == 'aucune'
? ( this . isTerreAttache ( targetCoord ) || this . isConnaissanceFleuve ( currentCoord , targetCoord ) || TMRUtility . distanceOddq ( fromOddq , toOddq ) <= 1 )
2021-02-12 01:44:27 +01:00
: this . currentRencontre ? . locList . find ( coord => coord == targetCoord ) ? ? false
if ( isInArea ) {
switch ( this . rencontreState ) {
case 'aucune' : return 'normal' ;
2022-06-25 17:49:19 +02:00
case 'passeur' : case 'changeur' : case 'messager' : return this . rencontreState ;
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
}
/* -------------------------------------------- */
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/...
await this . manageRencontre ( tmr , ( ) => this . postRencontre ( 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 ) ) {
await this . manageCaseHumide ( tmr ) ;
await this . conquerirCiteFermee ( tmr ) ;
2021-02-28 01:56:17 +01:00
await this . purifierPeriple ( tmr ) ;
2021-02-12 01:44:27 +01:00
await this . conquerirTMR ( tmr ) ;
2021-02-28 01:50:15 +01:00
await this . validerVisite ( tmr ) ;
2021-02-12 01:44:27 +01:00
await this . declencheSortEnReserve ( tmr . coord ) ;
await this . actor . checkSoufflePeage ( tmr ) ;
}
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]
y -= ( col % 2 == 0 ) ? tmrConstants . col1 _y : tmrConstants . col2 _y ;
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-06-25 17:49:19 +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-06-25 17:49:19 +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
}
}