2021-04-01 21:18:36 +02:00
/* -------------------------------------------- */
import { VadentisCombat } from "./vadentis-combat.js" ;
/* -------------------------------------------- */
export class VadentisUtility extends Entity {
/* -------------------------------------------- */
static async preloadHandlebarsTemplates ( ) {
const templatePaths = [
'systems/foundryvtt-vadentis/templates/actor-sheet.html' ,
2021-04-01 22:35:03 +02:00
'systems/foundryvtt-vadentis/templates/item-sheet.html' ,
'systems/foundryvtt-vadentis/templates/editor-notes-gm.html'
2021-04-01 21:18:36 +02:00
]
return loadTemplates ( templatePaths ) ;
}
2021-04-08 13:58:51 +02:00
/* -------------------------------------------- */
static updateCombat ( combat , round , diff , id ) {
if ( game . user . isGM && combat . data . round != 0 && combat . turns && combat . data . active ) {
let turn = combat . turns . find ( t => t . tokenId == combat . current . tokenId ) ;
ChatMessage . create ( { content : ` Round ${ combat . data . round } : C'est au tour de ${ turn . actor . name } <br> ` } ) ;
canvas . tokens . get ( turn . token . _id ) . control ( ) ;
canvas . tokens . cycleTokens ( 1 , true ) ;
}
}
2021-04-03 22:48:02 +02:00
/* -------------------------------------------- */
static createOptionList ( min , max ) {
let options = ""
for ( let i = min ; i <= max ; i ++ ) {
2021-04-08 13:58:51 +02:00
options += ` <option value=" ${ i } "> ${ i } </option> \n ` ;
2021-04-03 22:48:02 +02:00
}
return options ;
}
/* -------------------------------------------- */
static createDirectOptionList ( min , max ) {
2021-04-06 08:03:44 +02:00
let options = { } ;
2021-04-03 22:48:02 +02:00
for ( let i = min ; i <= max ; i ++ ) {
2021-04-08 13:58:51 +02:00
options [ ` ${ i } ` ] = ` ${ i } ` ;
2021-04-03 22:48:02 +02:00
}
return options ;
2021-04-08 13:58:51 +02:00
}
/* -------------------------------------------- */
static createDirectReverseOptionList ( min , max ) {
let options = { } ;
for ( let i = max ; i >= min ; i -- ) {
options [ ` ${ i } ` ] = ` ${ i } ` ;
2021-04-03 22:48:02 +02:00
}
2021-04-08 13:58:51 +02:00
return options ;
}
2021-04-03 22:48:02 +02:00
/* -------------------------------------------- */
static getTarget ( ) {
if ( game . user . targets && game . user . targets . size == 1 ) {
for ( let target of game . user . targets ) {
return target ;
}
}
return undefined ;
}
2021-04-08 13:58:51 +02:00
/* -------------------------------------------- */
static processDamageString ( formula , actor ) {
let workFormula = formula . toLowerCase ( ) ;
if ( workFormula . includes ( 'bonus de force' ) ) {
workFormula = workFormula . replace ( 'bonus de force' , actor . getForceScore ( ) ) ;
}
return workFormula ;
}
/* -------------------------------------------- */
static async processRoll ( formula ) {
let myRoll = new Roll ( formula ) ;
myRoll . evaluate ( ) ;
if ( game . modules . get ( "dice-so-nice" ) && game . modules . get ( "dice-so-nice" ) . active ) {
await game . dice3d . showForRoll ( myRoll , game . user , true ) ;
}
return myRoll ;
}
2021-04-03 22:48:02 +02:00
/* -------------------------------------------- */
static async performAttack ( combatData ) {
let attacker = game . actors . get ( combatData . attackerActorId ) ;
let defender = game . actors . get ( combatData . targetActorId ) ;
if ( attacker && defender ) {
2021-04-13 14:01:22 +02:00
let defense = defender . getDefenseScore ( ) ;
2021-04-03 22:48:02 +02:00
let attaque = attacker . getAttaqueScore ( ) ;
2021-04-08 13:58:51 +02:00
2021-04-13 14:01:22 +02:00
let msgData = {
alias : this . name ,
title : ` ${ attacker . name } attaque ${ defender . name } `
}
let formulaTouche = "1d20+" + attaque ;
let formulaFull = attacker . buildTexteFormula ( attacker . data . data . combat . attaque ) ;
let myRoll = await this . processRoll ( formulaTouche ) ;
2021-04-08 13:58:51 +02:00
if ( myRoll . results [ 0 ] > 1 && myRoll . total >= defense ) { // Success !
let degats = ` normaux : ${ combatData . arme . data . damage } ` ;
let formula = combatData . arme . data . damage . toLowerCase ( ) ;
2021-04-13 14:01:22 +02:00
msgData . msg = ` ${ attacker . name } a réussi son attaque sur ${ defender . name } ( ${ formulaFull } => ${ myRoll . total } / ${ defense } ) !<br> Les dégâts sont ${ degats } . ` ;
2021-04-08 13:58:51 +02:00
if ( myRoll . results [ 0 ] == 20 ) {
degats = ` critiques : ${ combatData . arme . data . criticaldamage } ` ;
formula = combatData . arme . data . criticaldamage . toLowerCase ( ) ;
2021-04-13 14:01:22 +02:00
msgData . msg += ` <br>C'est une <strong>réussite critique</strong> ! ` ;
2021-04-08 13:58:51 +02:00
}
2021-04-13 14:01:22 +02:00
msgData . img = 'systems/foundryvtt-vadentis/images/icons/tchat_attaque_réussie.webp'
2021-04-08 13:58:51 +02:00
formula = this . processDamageString ( formula , attacker ) ;
let degatsRoll = await this . processRoll ( formula ) ;
2021-04-13 14:01:22 +02:00
msgData . msg += ` <br>Les dégats infligés sont de <strong> ${ degatsRoll . total } </strong> ( ${ formula } ). ` ;
2021-04-08 13:58:51 +02:00
defender . applyDamage ( degatsRoll . total ) ;
2021-04-03 22:48:02 +02:00
} else { //Echec
2021-04-13 14:01:22 +02:00
msgData . img = 'systems/foundryvtt-vadentis/images/icons/tchat_attaque_échouée.webp' ;
2021-04-08 13:58:51 +02:00
if ( myRoll . results [ 0 ] == 1 ) {
2021-04-13 14:01:22 +02:00
msgData . msg = ` ${ attacker . name } a fait un <strong>échec critique</strong> et a raté son attaque sur ${ defender . name } ( ${ myRoll . total } / ${ defense } ) ! ` ;
2021-04-08 13:58:51 +02:00
} else {
2021-04-13 14:01:22 +02:00
msgData . msg = ` ${ attacker . name } a raté son attaque sur ${ defender . name } ( ${ myRoll . total } / ${ defense } ) ! ` ;
2021-04-08 13:58:51 +02:00
}
2021-04-03 22:48:02 +02:00
}
2021-04-13 14:01:22 +02:00
ChatMessage . create ( {
//whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
content : await renderTemplate ( ` systems/foundryvtt-vadentis/templates/chat-generic-result.html ` , msgData )
} ) ;
2021-04-03 22:48:02 +02:00
} else {
ui . notifications . warn ( "Impossible de trouver l'attaquant et le défenseur." )
}
}
2021-04-01 22:35:03 +02:00
/* -------------------------------------------- */
static registerChatCallbacks ( ) {
}
2021-04-01 21:18:36 +02:00
/* -------------------------------------------- */
static fillRange ( start , end ) {
return Array ( end - start + 1 ) . fill ( ) . map ( ( item , index ) => start + index ) ;
}
/* -------------------------------------------- */
static onSocketMesssage ( msg ) {
if ( ! game . user . isGM ) return ; // Only GM
2021-04-03 22:48:02 +02:00
if ( msg . name == 'msg_attack' ) {
this . performAttack ( msg . data ) ;
2021-04-01 21:18:36 +02:00
}
}
/* -------------------------------------------- */
static async loadCompendiumNames ( compendium ) {
const pack = game . packs . get ( compendium ) ;
let competences ;
await pack . getIndex ( ) . then ( index => competences = index ) ;
return competences ;
}
/* -------------------------------------------- */
static async loadCompendium ( compendium , filter = item => true ) {
let compendiumItems = await SoSUtility . loadCompendiumNames ( compendium ) ;
const pack = game . packs . get ( compendium ) ;
let list = [ ] ;
for ( let compendiumItem of compendiumItems ) {
await pack . getEntity ( compendiumItem . _id ) . then ( it => {
const item = it . data ;
if ( filter ( item ) ) {
list . push ( item ) ;
}
} ) ;
} ;
return list ;
}
2021-04-02 16:47:38 +02:00
/* -------------------------------------------- */
static getDonnees ( ) {
return this . loadCompendiumNames ( 'foundryvtt-vadentis.donnees' ) ;
}
/* -------------------------------------------- */
static getEglises ( ) {
return this . loadCompendiumNames ( 'foundryvtt-vadentis.eglises' ) ;
}
2021-04-02 14:59:58 +02:00
/* -------------------------------------------- */
static async confirmDelete ( actorSheet , li ) {
let itemId = li . data ( "item-id" ) ;
let objet = actorSheet . actor . items . find ( item => item . _id == itemId ) ;
let msgTxt = "<p>Etes vous certain de souhaiter supprimer cet item ?" ;
let buttons = {
delete : {
icon : '<i class="fas fa-check"></i>' ,
label : "Oui, à supprimer" ,
callback : ( ) => {
actorSheet . actor . deleteOwnedItem ( itemId ) ;
li . slideUp ( 200 , ( ) => actorSheet . render ( false ) ) ;
}
} ,
cancel : {
icon : '<i class="fas fa-times"></i>' ,
label : "Annuler"
}
}
msgTxt += "</p>" ;
let d = new Dialog ( {
title : "Confirmer la suppression" ,
content : msgTxt ,
buttons : buttons ,
default : "cancel"
} ) ;
d . render ( true ) ;
}
2021-04-01 21:18:36 +02:00
}