@ -6,6 +6,370 @@ import { Grammar } from "../grammar.js";
import { Misc } from "../misc.js" ;
import { ENTITE _INCARNE , ENTITE _NONINCARNE } from "../constants.js" ;
const WHITESPACES = "\\s+"
const NUMERIC = "[\\+\\-]?\\d+"
const NUMERIC _VALUE = "(?<value>" + NUMERIC + ")"
const XREGEXP _NAME = "(?<name>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)"
const XREGEXP _COMP _CREATURE = WHITESPACES + "(?<carac>\\d+)"
+ WHITESPACES + NUMERIC _VALUE
+ "(" + WHITESPACES + "(?<init>\\d+)?\\s+?(?<dommages>[\\+\\-]?\\d+)?" + ")?"
// Skill parser depending on the type of actor
const compParser = {
personnage : "(\\D+)*" + WHITESPACES + NUMERIC _VALUE ,
creature : XREGEXP _COMP _CREATURE ,
entite : XREGEXP _COMP _CREATURE
}
const XREGEXP _SORT _VOIE = "[OHNT\\/]+"
const XREGEXP _SORT _CASE = "\\((?<case>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)\\)" ;
const XREGEXP _SORT = "(" + XREGEXP _SORT _VOIE
+ WHITESPACES + XREGEXP _NAME
+ WHITESPACES + XREGEXP _SORT _CASE
+ WHITESPACES + "R(?<diff>([\\-\\d]+|(\\w|\\s)+))"
+ WHITESPACES + "r(?<reve>(\\d+(\\+)?|\\s\\w+))"
+ "(" + WHITESPACES + "\\+(?<bonus>\\d+)\\s?%" + WHITESPACES + "en" + WHITESPACES + "(?<bonuscase>[A-M]\\d{1,2})" + ")?"
+ ")"
// Main class for parsing a stat block
export class RdDStatBlockParser {
static openInputDialog ( ) {
let dialog = new Dialog ( {
title : "Import de stats de PNJ/Créatures" ,
content : `
< div >
< p > Coller le texte de la stat ici < / p >
< textarea id = "statBlock" style = "width: 100%; height: 200px;" > < / t e x t a r e a >
< / d i v >
` ,
buttons : {
ok : {
label : "OK" ,
callback : async ( html ) => {
let statBlock = html . find ( "#statBlock" ) [ 0 ] . value ;
await RdDStatBlockParser . parseStatBlock ( statBlock ) ;
dialog . close ( ) ;
}
} ,
cancel : {
label : "Cancel"
}
}
} ) ;
dialog . render ( true ) ;
}
static fixWeirdPDF ( statString ) {
// Split the statString into lines
let lines = statString . split ( "\n" ) ;
let newLines = [ ] ;
let index = 0 ;
let nextType = "string" ;
// Loop through each line
for ( let i = 0 ; i < lines . length ; i ++ ) {
// remove trailing spaces
lines [ i ] = lines [ i ] . trim ( ) ;
// Is it text ?
if ( lines [ i ] . match ( /^[a-zA-Zéêè\s]+/ ) ) {
if ( nextType == "string" ) {
newLines [ index ] = lines [ i ] ;
nextType = "number" ;
} else {
console . log ( "Wrong sequence string detected..." , lines [ i ] , nextType ) ;
}
}
// Is it a number ?
if ( lines [ i ] . match ( /^[\d\s]+/ ) ) {
if ( nextType == "number" ) {
newLines [ index ] = newLines [ index ] + lines [ i ] ;
nextType = "string" ;
index ++ ;
} else {
console . log ( "Wrong sequence number detected..." , lines [ i ] , nextType ) ;
}
}
}
}
static getHeureKey ( heure ) {
for ( let h of game . system . rdd . config . heuresRdD ) {
if ( h . label . toLowerCase ( ) == heure . toLowerCase ( ) ) {
return h . value ;
}
}
return "vaisseau" ;
}
static async parseStatBlock ( statString , type = "npc" ) {
//statString = statBlock03;
if ( ! statString ) {
return ;
}
// Special function to fix strange/weird copy/paste from PDF readers
// Unused up to now : this.fixWeirdPDF(statString);
// Replace all endline by space in the statString
statString = statString . replace ( /\n/g , " " ) ;
// Remove all multiple spaces
statString = statString . replace ( /\s{2,}/g , " " ) ;
// Remove all leading and trailing spaces
statString = statString . trim ( ) ;
// TODO: check for entite
let actorType = RdDStatBlockParser . parseActorType ( statString ) ;
// Now start carac
let actorData = foundry . utils . deepClone ( game . model . Actor [ actorType ] ) ;
for ( let key in actorData . carac ) {
let caracDef = actorData . carac [ key ] ;
// Parse the stat string for each caracteristic
let carac = XRegExp . exec ( statString , XRegExp ( caracDef . label + "\\s+(?<value>\\d+)" , 'giu' ) ) ;
if ( carac ? . value ) {
actorData . carac [ key ] . value = Number ( carac . value ) ;
}
}
// If creature we need to setup additionnal fields
switch ( actorType ) {
case "creature" :
RdDStatBlockParser . parseCreature ( statString , actorData )
break
case "entite" :
RdDStatBlockParser . parseEntite ( statString , actorData )
break
}
let items = [ ] ;
// Get skills from compendium
const competences = await SystemCompendiums . getCompetences ( actorType ) ;
//console.log("Competences : ", competences);
for ( let comp of competences ) {
let compMatch = XRegExp . exec ( statString , XRegExp ( comp . name + compParser [ actorType ] , 'giu' ) ) ;
if ( compMatch ) {
comp = comp . toObject ( )
comp . system . niveau = Number ( compMatch . value ) ;
if ( actorType == "creature" || actorType == "entite" ) {
comp . system . carac _value = Number ( compMatch . carac ) ;
if ( compMatch . dommages != undefined ) {
comp . system . dommages = Number ( compMatch . dommages ) ;
comp . system . iscombat = true ;
}
}
items . push ( comp )
}
else if ( actorType == "personnage" ) {
comp = comp . toObject ( )
items . push ( comp )
}
}
// Now process weapons
const weapons = await SystemCompendiums . getWorldOrCompendiumItems ( "arme" , "equipement" )
//console.log("Equipement : ", equipment);
// TODO: les noms d'armes peuvent avoir un suffixe (à une main, lancée) qui détermine la compétence correspondante
// TODO: une arme peut être spécifique ("fourche"), ajouter une compétence dans ces cas là?
for ( let weapon of weapons ) {
let weapMatch = XRegExp . exec ( statString , XRegExp ( weapon . name + "\\s+(?<value>\\+\\d+)" , 'giu' ) ) ;
if ( weapMatch ) {
weapon = weapon . toObject ( )
weapon . system . equipe = 'true'
items . push ( weapon )
// now process the skill
if ( weapon . system ? . competence != "" ) {
let wComp = items . find ( i => Grammar . equalsInsensitive ( i . name , weapon . system . competence ) )
if ( wComp ) {
wComp . system . niveau = Number ( weapMatch . value ) ;
}
}
if ( weapon . system ? . tir != "" ) {
let wComp = items . find ( i => Grammar . equalsInsensitive ( i . name , weapon . system . tir ) )
if ( wComp ) {
wComp . system . niveau = Number ( weapMatch . value ) ;
}
}
if ( weapon . system ? . lancer != "" ) {
let wComp = items . find ( i => Grammar . equalsInsensitive ( i . name , weapon . system . lancer ) )
if ( wComp ) {
wComp . system . niveau = Number ( weapMatch . value ) ;
}
}
}
}
// Now process armors
const armors = await SystemCompendiums . getWorldOrCompendiumItems ( "armure" , "equipement" )
for ( let armor of armors ) {
let matchArmor = XRegExp . exec ( statString , XRegExp ( armor . name , 'giu' ) ) ;
if ( matchArmor ) {
armor = armor . toObject ( )
armor . system . equipe = true
items . push ( armor ) ;
}
}
// Attemp to detect spell
let hautRevant = false
let sorts = await SystemCompendiums . getWorldOrCompendiumItems ( "sort" , "sorts-oniros" )
sorts = sorts . concat ( await SystemCompendiums . getWorldOrCompendiumItems ( "sort" , "sorts-hypnos" ) )
sorts = sorts . concat ( await SystemCompendiums . getWorldOrCompendiumItems ( "sort" , "sorts-narcos" ) )
sorts = sorts . concat ( await SystemCompendiums . getWorldOrCompendiumItems ( "sort" , "sorts-thanatos" ) )
XRegExp . forEach ( statString , XRegExp ( XREGEXP _SORT , 'giu' ) ,
function ( matchSort , i ) {
let sort = sorts . find ( s => Grammar . equalsInsensitive ( s . name , matchSort . name ) )
if ( sort ) {
hautRevant = true
sort = sort . toObject ( ) ;
if ( matchSort . bonus && matchSort . bonuscase ) {
sort . system . bonuscase = ` ${ matchSort . bonuscase } : ${ matchSort . bonus } `
}
items . push ( sort ) ;
}
} ) ;
if ( hautRevant ) {
let tetes = await SystemCompendiums . getWorldOrCompendiumItems ( "tete" , "tetes-de-dragon-pour-tous-personnages" )
let donHR = tetes . find ( t => Grammar . equalsInsensitive ( t . name , "Don de Haut-Rêve" ) )
if ( donHR ) {
items . push ( donHR . toObject ( ) ) ;
}
}
if ( actorType == "personnage" ) {
let feminin = XRegExp . exec ( statString , XRegExp ( "né(?<value>e?) à" , 'giu' ) ) ;
actorData . sexe = ( feminin ? . value == 'e' ) ? 'féminin' : 'masculin'
// Get hour name : heure du XXXXX
let heure = XRegExp . exec ( statString , XRegExp ( "heure (du|de la|des|de l\')\\s*(?<value>[A-Za-zÀ-ÖØ-öø-ÿ\\s]+)," , 'giu' ) ) ;
actorData . heure = this . getHeureKey ( heure ? . value || "Vaisseau" ) ;
// Get age
let age = XRegExp . exec ( statString , XRegExp ( "(?<value>\\d+) ans" , 'giu' ) ) ;
if ( age ? . value ) {
actorData . age = Number ( age . value ) ;
}
// Get height
let taille = XRegExp . exec ( statString , XRegExp ( "(?<value>\\d+m\\d+)" , 'giu' ) ) ;
if ( taille ? . value ) {
actorData . taille = taille . value ;
}
// Get weight
let poids = XRegExp . exec ( statString , XRegExp ( "(?<value>\\d+) kg" , 'giu' ) ) ;
if ( poids ? . value ) {
actorData . poids = poids . value ;
}
// Get cheveux
let cheveux = XRegExp . exec ( statString , XRegExp ( "kg,\\s+(?<value>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+),\\s+yeux" , 'giu' ) ) ;
if ( cheveux ? . value ) {
actorData . cheveux = cheveux . value ;
}
// Get yeux
let yeux = XRegExp . exec ( statString , XRegExp ( "yeux\\s+(?<value>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+), Beau" , 'giu' ) ) ;
if ( yeux ? . value ) {
actorData . yeux = yeux . value ;
}
// Get beauty
let beaute = XRegExp . exec ( statString , XRegExp ( "beauté\\s+(?<value>\\d+)" , 'giu' ) ) ;
if ( beaute ? . value ) {
actorData . beaute = Number ( beaute . value ) ;
}
}
// Name is all string before ', né'
let name = RdDStatBlockParser . extractName ( actorType , statString ) ;
let newActor = RdDBaseActorReve . create ( { name : name || "Importé" , type : actorType , system : actorData , items : items } ) ;
// DUmp....
console . log ( actorData ) ;
}
static parseCreature ( statString , actorData ) {
let plusDom = XRegExp . exec ( statString , XRegExp ( "\\+dom\\s+(?<value>[\\+\\-]?\\d+)" , 'giu' ) ) ;
if ( plusDom ? . values ) {
actorData . attributs . plusdom . value = Number ( plusDom . value ) ;
}
let protection = XRegExp . exec ( statString , XRegExp ( "protection\\s+(?<value>[\\-]?\\d+)" , 'giu' ) ) ;
if ( protection ? . value ) {
actorData . attributs . protection . value = Number ( protection . value ) ;
}
let endurance = XRegExp . exec ( statString , XRegExp ( "endurance\\s+(?<value>\\d+)" , 'giu' ) ) ;
if ( endurance ? . value ) {
actorData . sante . endurance . value = Number ( endurance . value ) ;
actorData . sante . endurance . max = Number ( endurance . value ) ;
}
let vie = XRegExp . exec ( statString , XRegExp ( "vie\\s+(?<value>\\d+)" , 'giu' ) ) ;
if ( vie . value ) {
actorData . sante . vie . value = Number ( vie . value ) ;
actorData . sante . vie . max = Number ( vie . value ) ;
}
let vitesse = XRegExp . exec ( statString , XRegExp ( "vitesse\\s+(?<value>[\\d\\/]+)" , 'giu' ) ) ;
if ( vitesse ? . value ) {
actorData . attributs . vitesse . value = vitesse . value ;
}
}
static parseEntite ( statString , actorData ) {
let plusDom = XRegExp . exec ( statString , XRegExp ( "\\+dom\\s+(?<value>[\\+\\-]?\\d+)" , 'giu' ) ) ;
if ( plusDom ? . values ) {
actorData . attributs . plusdom . value = Number ( plusDom . value ) ;
}
actorData . definition . categorieentite = 'cauchemar'
actorData . definition . typeentite = ENTITE _NONINCARNE
let endurance = XRegExp . exec ( statString , XRegExp ( "endurance\\s+(?<value>\\d+)" , 'giu' ) ) ;
if ( endurance ? . value ) {
actorData . sante . endurance . value = Number ( endurance . value ) ;
actorData . sante . endurance . max = Number ( endurance . value ) ;
actorData . definition . typeentite = ENTITE _INCARNE
}
let vitesse = XRegExp . exec ( statString , XRegExp ( "vitesse\\s+(?<value>[\\d\\/]+)" , 'giu' ) ) ;
if ( vitesse ? . value ) {
actorData . attributs . vitesse . value = vitesse . value ;
}
}
static parseActorType ( statString ) {
let niveau = XRegExp . exec ( statString , XRegExp ( "Niveau\\s+(?<value>[\\+\\-]?\\d+)" , 'giu' ) )
let perception = XRegExp . exec ( statString , XRegExp ( "perception\\s+(?<value>\\d+)" , 'giu' ) )
if ( perception ? . value ) {
return "creature"
}
if ( niveau ? . value ) {
return "entite"
}
return "personnage"
}
static extractName ( actorType , statString ) {
switch ( actorType ) {
case "personnage" : return RdDStatBlockParser . extractNamePersonnage ( statString ) ;
case "creature" : return RdDStatBlockParser . extractNameCreature ( statString ) ;
}
return RdDStatBlockParser . extractNameCreature ( statString ) ;
}
static extractNamePersonnage ( statString ) {
let name = XRegExp . exec ( statString , XRegExp ( "(?<value>[\\p{Letter}\\s\\d]+)," , 'giu' ) ) ;
if ( ! name ? . value ) {
name = XRegExp . exec ( statString , XRegExp ( "(?<value>.+)\\s+taille" , 'giu' ) ) ;
}
return Misc . upperFirst ( name ? . value || "Importé" ) ;
}
static extractNameCreature ( statString ) {
const name = XRegExp . exec ( statString , XRegExp ( "(?<value>.+)\\s+taille" , 'giu' ) ) ;
return Misc . upperFirst ( name ? . value || "Importé" ) ;
}
}
/************************************************************************************/
// Some internal test strings
let statBlock01 = ` + $ 16(/, baron de Sylvedire, né à l’ heure du
@ -197,337 +561,4 @@ Discrétion
Vigilance
13
+ 3
`
// Skill parser depending on the type of actor
const compParser = {
personnage : "(\\D+)*\\s+(?<value>[\\+\\-]?\\d+)" ,
creature : "\\s+(?<carac>\\d+)\\s+(?<value>[\\+\\-]?\\d+)\\s?(?<init>\\d+)?\\s+?(?<dommages>\\+\\d+)?"
} ;
// Main class for parsing a stat block
export class RdDStatBlockParser {
static openInputDialog ( ) {
let dialog = new Dialog ( {
title : "Import de stats de PNJ/Créatures" ,
content : `
< div >
< p > Coller le texte de la stat ici < / p >
< textarea id = "statBlock" style = "width: 100%; height: 200px;" > < / t e x t a r e a >
< / d i v >
` ,
buttons : {
ok : {
label : "OK" ,
callback : async ( html ) => {
let statBlock = html . find ( "#statBlock" ) [ 0 ] . value ;
await RdDStatBlockParser . parseStatBlock ( statBlock ) ;
dialog . close ( ) ;
}
} ,
cancel : {
label : "Cancel"
}
}
} ) ;
dialog . render ( true ) ;
}
static fixWeirdPDF ( statString ) {
// Split the statString into lines
let lines = statString . split ( "\n" ) ;
let newLines = [ ] ;
let index = 0 ;
let nextType = "string" ;
// Loop through each line
for ( let i = 0 ; i < lines . length ; i ++ ) {
// remove trailing spaces
lines [ i ] = lines [ i ] . trim ( ) ;
// Is it text ?
if ( lines [ i ] . match ( /^[a-zA-Zéêè\s]+/ ) ) {
if ( nextType == "string" ) {
newLines [ index ] = lines [ i ] ;
nextType = "number" ;
} else {
console . log ( "Wrong sequence string detected..." , lines [ i ] , nextType ) ;
}
}
// Is it a number ?
if ( lines [ i ] . match ( /^[\d\s]+/ ) ) {
if ( nextType == "number" ) {
newLines [ index ] = newLines [ index ] + lines [ i ] ;
nextType = "string" ;
index ++ ;
} else {
console . log ( "Wrong sequence number detected..." , lines [ i ] , nextType ) ;
}
}
}
}
static getHeureKey ( heure ) {
for ( let h of game . system . rdd . config . heuresRdD ) {
if ( h . label . toLowerCase ( ) == heure . toLowerCase ( ) ) {
return h . value ;
}
}
return "vaisseau" ;
}
static async parseStatBlock ( statString , type = "npc" ) {
//statString = statBlock03;
if ( ! statString ) {
return ;
}
// Special function to fix strange/weird copy/paste from PDF readers
// Unused up to now : this.fixWeirdPDF(statString);
// Replace all endline by space in the statString
statString = statString . replace ( /\n/g , " " ) ;
// Remove all multiple spaces
statString = statString . replace ( /\s{2,}/g , " " ) ;
// Remove all leading and trailing spaces
statString = statString . trim ( ) ;
// TODO: check for entite
let actorType = RdDStatBlockParser . parseActorType ( statString ) ;
// Now start carac
let actorData = foundry . utils . deepClone ( game . model . Actor [ actorType ] ) ;
for ( let key in actorData . carac ) {
let caracDef = actorData . carac [ key ] ;
// Parse the stat string for each caracteristic
let carac = XRegExp . exec ( statString , XRegExp ( caracDef . label + "\\s+(?<value>\\d+)" , 'giu' ) ) ;
if ( carac ? . value ) {
actorData . carac [ key ] . value = Number ( carac . value ) ;
}
}
// If creature we need to setup additionnal fields
switch ( actorType ) {
case "creature" :
RdDStatBlockParser . parseCreature ( statString , actorData )
break
case "entite" :
RdDStatBlockParser . parseEntite ( statString , actorData )
break
}
let items = [ ] ;
// Get skills from compendium
const competences = await SystemCompendiums . getCompetences ( actorType ) ;
//console.log("Competences : ", competences);
let allComp = competences . map ( i => i . toObject ( ) )
for ( let comp of allComp ) {
const compName = comp . name ;
let skill = XRegExp . exec ( Grammar . toLowerCaseNoAccent ( statString ) , XRegExp ( Grammar . toLowerCaseNoAccent ( compName ) + compParser [ actorType ] , 'giu' ) ) ;
if ( skill ) {
comp . system . niveau = Number ( skill . value ) ;
if ( actorType == "creature" ) {
comp . system . carac _value = Number ( skill . carac ) ;
if ( skill . init ) {
comp . system . dommages = Number ( skill . dommages ) ;
comp . system . iscombat = true ;
}
}
}
if ( actorType == "personnage" || skill != undefined ) {
items . push ( comp )
}
}
// Now process weapons
const weapons = await SystemCompendiums . getWorldOrCompendiumItems ( "arme" , "equipement" )
//console.log("Equipement : ", equipment);
// TODO: les noms d'armes peuvent avoir un suffixe (à une main, lancée) qui détermine la compétence correspondante
// TODO: une arme peut être spécifique ("fourche"), ajouter une compétence dans ces cas là?
for ( let w of weapons ) {
let weapon = XRegExp . exec ( statString , XRegExp ( w . name + "\\s+(?<value>\\+\\d+)" , 'giu' ) ) ;
if ( weapon ) {
w . system . equipe = 'true'
items . push ( w . toObject ( ) ) ;
// now process the skill
if ( w . system ? . competence != "" ) {
let wComp = items . find ( i => Grammar . equalsInsensitive ( i . name , w . system . competence ) )
if ( wComp ) {
wComp . system . niveau = Number ( weapon . value ) ;
}
}
if ( w . system ? . tir != "" ) {
let wComp = items . find ( i => Grammar . equalsInsensitive ( i . name , w . system . tir ) )
if ( wComp ) {
wComp . system . niveau = Number ( weapon . value ) ;
}
}
if ( w . system ? . lancer != "" ) {
let wComp = items . find ( i => Grammar . equalsInsensitive ( i . name , w . system . lancer ) )
if ( wComp ) {
wComp . system . niveau = Number ( weapon . value ) ;
}
}
}
}
// Now process armors
const armors = await SystemCompendiums . getWorldOrCompendiumItems ( "armure" , "equipement" )
for ( let a of armors ) {
let armor = XRegExp . exec ( statString , XRegExp ( a . name , 'giu' ) ) ;
if ( armor ) {
a . system . equipe = true
items . push ( a . toObject ( ) ) ;
}
}
// Attemp to detect spell
let hautRevant = false
let sorts = await SystemCompendiums . getWorldOrCompendiumItems ( "sort" , "sorts-oniros" )
sorts = sorts . concat ( await SystemCompendiums . getWorldOrCompendiumItems ( "sort" , "sorts-hypnos" ) )
sorts = sorts . concat ( await SystemCompendiums . getWorldOrCompendiumItems ( "sort" , "sorts-narcos" ) )
sorts = sorts . concat ( await SystemCompendiums . getWorldOrCompendiumItems ( "sort" , "sorts-thanatos" ) )
XRegExp . forEach ( statString , XRegExp ( "[OHNT]\\s+(?<name>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)\\s+\\((?<case>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)\\)\\s+R(?<diff>[\\-\\d]+)\\s+r(?<reve>\\d+)" , 'giu' ) ,
function ( match , i ) {
let sortCompendium = sorts . find ( s => Grammar . equalsInsensitive ( s . name , match . name ) )
if ( sortCompendium ) {
hautRevant = true
let sort = sortCompendium . toObject ( ) ;
items . push ( sort ) ;
}
} ) ;
if ( hautRevant ) {
let tetes = await SystemCompendiums . getWorldOrCompendiumItems ( "tete" , "tetes-de-dragon-pour-tous-personnages" )
let donHR = tetes . find ( t => Grammar . equalsInsensitive ( t . name , "Don de Haut-Rêve" ) )
if ( donHR ) {
items . push ( donHR . toObject ( ) ) ;
}
}
let feminin = XRegExp . exec ( statString , XRegExp ( "né(?<value>e?) à" , 'giu' ) ) ;
actorData . sexe = ( feminin ? . value == 'e' ) ? 'féminin' : 'masculin'
// Get hour name : heure du XXXXX
let heure = XRegExp . exec ( statString , XRegExp ( "heure (du|de la|des|de l\')\\s*(?<value>[A-Za-zÀ-ÖØ-öø-ÿ\\s]+)," , 'giu' ) ) ;
actorData . heure = this . getHeureKey ( heure ? . value || "Vaisseau" ) ;
// Get age
let age = XRegExp . exec ( statString , XRegExp ( "(?<value>\\d+) ans" , 'giu' ) ) ;
if ( age ? . value ) {
actorData . age = Number ( age . value ) ;
}
// Get height
let taille = XRegExp . exec ( statString , XRegExp ( "(?<value>\\d+m\\d+)" , 'giu' ) ) ;
if ( taille ? . value ) {
actorData . taille = taille . value ;
}
// Get weight
let poids = XRegExp . exec ( statString , XRegExp ( "(?<value>\\d+) kg" , 'giu' ) ) ;
if ( poids ? . value ) {
actorData . poids = poids . value ;
}
// Get cheveux
let cheveux = XRegExp . exec ( statString , XRegExp ( "kg,\\s+(?<value>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+),\\s+yeux" , 'giu' ) ) ;
if ( cheveux ? . value ) {
actorData . cheveux = cheveux . value ;
}
// Get yeux
let yeux = XRegExp . exec ( statString , XRegExp ( "yeux\\s+(?<value>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+), Beau" , 'giu' ) ) ;
if ( yeux ? . value ) {
actorData . yeux = yeux . value ;
}
// Get beauty
let beaute = XRegExp . exec ( statString , XRegExp ( "beauté\\s+(?<value>\\d+)" , 'giu' ) ) ;
if ( beaute ? . value ) {
actorData . beaute = Number ( beaute . value ) ;
}
// Name is all string before ', né'
let name = RdDStatBlockParser . extractName ( actorType , statString ) ;
let newActor = RdDBaseActorReve . create ( { name : name || "Importé" , type : actorType , system : actorData , items : items } ) ;
// DUmp....
console . log ( actorData ) ;
}
static parseCreature ( statString , actorData ) {
let plusDom = XRegExp . exec ( statString , XRegExp ( "\\+dom\\s+(?<value>[\\+\\-]?\\d+)" , 'giu' ) ) ;
if ( plusDom ? . values ) {
actorData . attributs . plusdom . value = Number ( plusDom . value ) ;
}
let protection = XRegExp . exec ( statString , XRegExp ( "protection\\s+(?<value>[\\-]?\\d+)" , 'giu' ) ) ;
if ( protection ? . value ) {
actorData . attributs . protection . value = Number ( protection . value ) ;
}
let endurance = XRegExp . exec ( statString , XRegExp ( "endurance\\s+(?<value>\\d+)" , 'giu' ) ) ;
if ( endurance ? . value ) {
actorData . sante . endurance . value = Number ( endurance . value ) ;
actorData . sante . endurance . max = Number ( endurance . value ) ;
}
let vie = XRegExp . exec ( statString , XRegExp ( "vie\\s+(?<value>\\d+)" , 'giu' ) ) ;
if ( vie . value ) {
actorData . sante . vie . value = Number ( vie . value ) ;
actorData . sante . vie . max = Number ( vie . value ) ;
}
let vitesse = XRegExp . exec ( statString , XRegExp ( "vitesse\\s+(?<value>[\\d\\/]+)" , 'giu' ) ) ;
if ( vitesse ? . value ) {
actorData . attributs . vitesse . value = vitesse . value ;
}
}
static parseEntite ( statString , actorData ) {
let plusDom = XRegExp . exec ( statString , XRegExp ( "\\+dom\\s+(?<value>[\\+\\-]?\\d+)" , 'giu' ) ) ;
if ( plusDom ? . values ) {
actorData . attributs . plusdom . value = Number ( plusDom . value ) ;
}
actorData . definition . categorieentite = 'cauchemar'
actorData . definition . typeentite = ENTITE _NONINCARNE
let endurance = XRegExp . exec ( statString , XRegExp ( "endurance\\s+(?<value>\\d+)" , 'giu' ) ) ;
if ( endurance ? . value ) {
actorData . sante . endurance . value = Number ( endurance . value ) ;
actorData . sante . endurance . max = Number ( endurance . value ) ;
actorData . definition . typeentite = ENTITE _INCARNE
}
let vitesse = XRegExp . exec ( statString , XRegExp ( "vitesse\\s+(?<value>[\\d\\/]+)" , 'giu' ) ) ;
if ( vitesse ? . value ) {
actorData . attributs . vitesse . value = vitesse . value ;
}
}
static parseActorType ( statString ) {
let niveau = XRegExp . exec ( statString , XRegExp ( "Niveau\\s+(?<value>[\\+\\-]?\\d+)" , 'giu' ) )
let perception = XRegExp . exec ( statString , XRegExp ( "perception\\s+(?<value>\\d+)" , 'giu' ) )
if ( perception ? . value ) {
return "creature"
}
if ( niveau ? . value ) {
return "entite"
}
return "personnage"
}
static extractName ( actorType , statString ) {
switch ( actorType ) {
case "personnage" : return RdDStatBlockParser . extractNamePersonnage ( statString ) ;
case "creature" : return RdDStatBlockParser . extractNameCreature ( statString ) ;
}
return RdDStatBlockParser . extractNameCreature ( statString ) ;
}
static extractNamePersonnage ( statString ) {
let name = XRegExp . exec ( statString , XRegExp ( "(?<value>[\\p{Letter}\\s\\d]+)," , 'giu' ) ) ;
if ( ! name ? . value ) {
name = XRegExp . exec ( statString , XRegExp ( "(?<value>.+)\\s+taille" , 'giu' ) ) ;
}
return Misc . upperFirst ( name ? . value || "Importé" ) ;
}
static extractNameCreature ( statString ) {
const name = XRegExp . exec ( statString , XRegExp ( "(?<value>.+)\\s+taille" , 'giu' ) ) ;
return Misc . upperFirst ( name ? . value || "Importé" ) ;
}
}
`