import { TeDeumUtility } from "../common/tedeum-utility.js"; import { TeDeumActor } from "../actors/tedeum-actor.js"; export class TeDeumCharacterCreator { /*--------------------------------------------*/ async init() { this.stages = {} this.currentStage = "origineSociale" this.sex = undefined this.origineSociale = undefined this.religion = undefined this.caracBonus = {} this.competenceBonus = {} this.competences = TeDeumUtility.getCompetencesForDropDown() for (let k in game.system.tedeum.config.caracteristiques) { this.caracBonus[k] = { value: 0 } } for (let stage in game.system.tedeum.config.etapesEducation) { this.stages[stage] = { selectedItem: null, items: [] } } const educations = await TeDeumUtility.loadCompendium("fvtt-te-deum.education") for (let edu of educations) { this.stages[edu.system.etape].items.push(edu) } this.processStage() } /*--------------------------------------------*/ increaseCompetence(compName) { if (compName === "" || compName == undefined || compName == "undefined") { return } compName = compName.toLowerCase() if (!this.competenceBonus[compName]) { this.competenceBonus[compName] = { value: 1 } } else { this.competenceBonus[compName].value += 1 } } /*--------------------------------------------*/ processReponses(question) { let fullResponses = [] for (let key in question.reponses) { let response = question.reponses[key] fullResponses.push({ id: key, label: `${response.reponse} (${TeDeumUtility.upperFirst( response.compName)} +1)` }) } return fullResponses } /*--------------------------------------------*/ processReponsesRadio(question) { let fullResponses = {} let selected = true for (let key in question.reponses) { let response = question.reponses[key] if (response.toSelect) { fullResponses[key] = { label: `${response.reponse}`, competences: response.compList, selected } } else { fullResponses[key] = { label: `${response.reponse} (${response.compName} +1)`, selected } } selected = false } return fullResponses } /*--------------------------------------------*/ async askStageName(context) { const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-stage-name.hbs", context) const choiceResult = await foundry.applications.api.DialogV2.wait({ window: { title: context.title }, classes: ["fvtt-te-deum"], content, buttons: [ { label: context.label, callback: (event, button, dialog) => { const output = Array.from(button.form.elements).reduce((obj, input) => { if (input.name) obj[input.name] = input.value return obj }, {}) return output }, }, ], actions: { }, rejectClose: false, // Click on Close button will not launch an error render: (event, dialog) => { } }) return choiceResult } /*--------------------------------------------*/ processCompetences(compList) { for (let compName in compList) { this.increaseCompetence(compName) } } /*--------------------------------------------*/ async askQuestionnaire(stage, context) { context.subtitle = "Questionnaire" for (let key in stage.system.questionnaire) { let question = stage.system.questionnaire[key] if (question.question === "") { break } context.question = question.question context.responses = this.processReponses(question) context.responsesRadio = this.processReponsesRadio(question) context.competences = {} context.responseKey = "reponse1" // By default const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-questions.hbs", context) const choiceResult = await foundry.applications.api.DialogV2.wait({ window: { title: context.title }, classes: ["fvtt-te-deum"], content, buttons: [ { label: context.label, callback: (event, button, dialog) => { const output = Array.from(button.form.elements).reduce((obj, input) => { if (input.name) obj[input.name] = input.value return obj }, {}) return output }, }, ], actions: { }, rejectClose: false, // Click on Close button will not launch an error render: (event, dialog) => { $(".questionnaire-radio").click(event => { let responseKey = $(event.target).data("response-key") context.responseKey = responseKey }) $(".questionnaire-select-competence").change(event => { // Get the responseKey data let responseKey = $(event.target).data("response-key") let compName = event.target.value console.log("Questionnaire Change", responseKey, compName) context.competences[responseKey] = compName.toLowerCase() }) } }) if (choiceResult == null) { this.currentStage = "cancelled" return } let selectedResponse = question.reponses[context.responseKey] let compName = context.competences[context.responseKey] || selectedResponse.compName this.increaseCompetence(compName) } } /*------------- -------------------------------*/ async askCompetences(stage, context) { context.subtitle = "Choix des Compétences" context.fixedCompetences = {} context.selectCompetences = {} for (let compKey in stage.system.competences) { let comp = stage.system.competences[compKey] if (comp.valid && comp.compName !== "") { if (comp.toSelect) { context.hasSelectCompetences = true context.selectCompetences[comp.compName] = TeDeumUtility.upperFirst(comp.compName) } else { context.fixedCompetences[comp.compName] = TeDeumUtility.upperFirst(comp.compName) } } } const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-competences.hbs", context) const choiceResult = await foundry.applications.api.DialogV2.wait({ window: { title: context.title }, classes: ["fvtt-te-deum"], content, buttons: [ { label: context.label, callback: (event, button, dialog) => { const output = Array.from(button.form.elements).reduce((obj, input) => { if (input.name) obj[input.name] = input.value return obj }, {}) return output }, }, ], actions: { }, rejectClose: false, // Click on Close button will not launch an error render: (event, dialog) => { } }) if (choiceResult == null) { this.currentStage = "cancelled" return } context.fixedCompetences[choiceResult.selectedCompetence] = choiceResult.selectedCompetence this.processCompetences(context.fixedCompetences) // Handle specific case when multiple skills can be selected (ie compagnon case) if ( stage.system.hasCompetencesOpt ) { context.fixedCompetences = [] context.hasSelectCompetences = true for (let i = 0; i < stage.system.competencesOptNumber; i++) { context.competences = {} context.selectCompetences = {} for (let compKey in stage.system.competencesOpt) { let comp = stage.system.competencesOpt[compKey] if (comp.compName !== "") { context.selectCompetences[comp.compName] = TeDeumUtility.upperFirst(comp.compName) } } const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-competences.hbs", context) const choiceResult = await foundry.applications.api.DialogV2.wait({ window: { title: context.title }, classes: ["fvtt-te-deum"], content, buttons: [ { label: context.label, callback: (event, button, dialog) => { const output = Array.from(button.form.elements).reduce((obj, input) => { if (input.name) obj[input.name] = input.value return obj }, {}) return output }, }, ], actions: { }, rejectClose: false, // Click on Close button will not launch an error render: (event, dialog) => { } }) if (choiceResult == null) { this.currentStage = "cancelled" return } context.fixedCompetences[choiceResult.selectedCompetence] = choiceResult.selectedCompetence this.processCompetences(context.fixedCompetences) } } } /*------------- -------------------------------*/ async askCarac(stage, context) { context.subtitle = "Choix des Caractéristiques" let selected = [] for (let i = 0; i < stage.system.nbChoixCarac; i++) { context.caracList = [] for (let caracKey in stage.system.caracteristiques) { let carac = stage.system.caracteristiques[caracKey] if (selected.includes(carac.caracId)) { continue } context.caracList.push(game.system.tedeum.config.caracteristiques[carac.caracId]) } const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-select-carac.hbs", context) const choiceResult = await foundry.applications.api.DialogV2.wait({ window: { title: context.title }, classes: ["fvtt-te-deum"], content, buttons: [ { label: context.label, callback: (event, button, dialog) => { const output = Array.from(button.form.elements).reduce((obj, input) => { if (input.name) obj[input.name] = input.value return obj }, {}) return output }, }, ], actions: { }, rejectClose: false, // Click on Close button will not launch an error render: (event, dialog) => { } }) if (choiceResult == null) { this.currentStage = "cancelled" return } this.caracBonus[choiceResult.carac].value += 1 selected.push(choiceResult.carac) } } /*--------------------------------------------*/ async renderOrigineSociale(stage) { let context = { title: "Création de personnage", subtitle: "Origine Sociale", sexeChoice: { "Homme": "Homme", "Femme": "Femme" }, religionChoice: { "catholique": "Catholique", "protestante": "Protestante" }, origineChoice: game.system.tedeum.config.origineSociale } const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-origine.hbs", context) const label = "Valider le choix de l'Origine Sociale" const choiceResult = await foundry.applications.api.DialogV2.wait({ window: { title: context.title }, classes: ["fvtt-te-deum"], content, buttons: [ { label: label, callback: (event, button, dialog) => { const output = Array.from(button.form.elements).reduce((obj, input) => { if (input.name) obj[input.name] = input.value return obj }, {}) return output }, }, ], actions: { }, rejectClose: false, // Click on Close button will not launch an error render: (event, dialog) => { } }) if (choiceResult == null) { this.currentStage = "cancelled" return } this.sexe = choiceResult.sexe this.religion = choiceResult.religion this.origineSociale = foundry.utils.duplicate(game.system.tedeum.config.origineSociale[choiceResult.origineSociale]) for (let key in this.origineSociale.caracteristiques) { this.caracBonus[key].value += this.origineSociale.caracteristiques[key] } this.currentStage = "pouponniere" } /*--------------------------------------------*/ async renderPouponniere(stage) { // Filter available pouponniere from origineSociale let pouponniereItems = stage.items.filter(item => item.system.accessible[this.origineSociale.id].isaccessible) let context = { title: "Création de personnage - La Pouponnière", subtitle: "Choix de la Pouponnière", label: "Valider le choix de la Pouponnière", choices: pouponniereItems, caracBonus: this.caracBonus, competenceBonus: this.competenceBonus } let choiceResult = await this.askStageName(context) if (choiceResult == null) { this.currentStage = "cancelled" return } this.pouponniere = foundry.utils.duplicate(stage.items.find(item => item.id === choiceResult.selectedItem)) context.title = `La Pouponnière - ${this.pouponniere.name}` TeDeumUtility.prepareEducationContent(this.pouponniere); context.label = "Valider l'augmentation de caracteristique" await this.askCarac(this.pouponniere, context) context.label = "Valider l'augmentation de compétences" await this.askCompetences(this.pouponniere, context) context.label = "Valider cette réponse" await this.askQuestionnaire(this.pouponniere, context) this.currentStage = "petitsgrimauds" } /*--------------------------------------------*/ async renderPetitsGrimauds(stage) { // Filter available pouponniere from origineSociale let grimaudsItems = stage.items.filter(item => item.system.accessible[this.origineSociale.id].isaccessible) let context = { title: "Les Petits Grimauds", label: "Valider le choix des Petits Grimauds", choices: grimaudsItems, caracBonus: this.caracBonus, competenceBonus: this.competenceBonus } let choiceResult = await this.askStageName(context) if (choiceResult == null) { this.currentStage = "cancelled" return } this.grimauds = foundry.utils.duplicate(stage.items.find(item => item.id === choiceResult.selectedItem)) context.title = `LesPetits Grimauds - ${this.grimauds.name}` TeDeumUtility.prepareEducationContent(this.grimauds); context.label = "Valider l'augmentation de caracteristique" await this.askCarac(this.grimauds, context) context.label = "Valider l'augmentation de compétences" await this.askCompetences(this.grimauds, context) context.label = "Valider cette réponse" await this.askQuestionnaire(this.grimauds, context) this.currentStage = "rosevie" } /*--------------------------------------------*/ async renderRosesDeLaVie(stage) { // Filter available pouponniere from origineSociale let rosesItems = stage.items.filter(item => item.system.accessible[this.origineSociale.id].isaccessible) let context = { title: "Création de personnage - Les Roses de la Vie", label: "Valider le choix des Roses de la Vie", choices: rosesItems, caracBonus: this.caracBonus, competenceBonus: this.competenceBonus } let choiceResult = await this.askStageName(context) if (choiceResult == null) { this.currentStage = "cancelled" return } this.roses = foundry.utils.duplicate(stage.items.find(item => item.id === choiceResult.selectedItem)) context.title = `Les Roses de la Vie - ${this.roses.name}` TeDeumUtility.prepareEducationContent(this.roses); context.label = "Valider l'augmentation de caracteristique" await this.askCarac(this.roses, context) context.label = "Valider l'augmentation de compétences" await this.askCompetences(this.roses, context) context.label = "Valider cette réponse" await this.askQuestionnaire(this.roses, context) this.currentStage = "ageviril" } /*--------------------------------------------*/ async renderAgeViril(stage) { let virilDebouche = this.roses.system.debouches let ageVirilItems = [] for (let key in virilDebouche) { let debouche = virilDebouche[key] if (debouche.debouche === "") { continue } let deboucheItem = stage.items.find(item => item.name.toLowerCase().includes(debouche.debouche.toLowerCase())) if (deboucheItem) { ageVirilItems.push(deboucheItem) } else { console.log(`Debouche ${debouche.debouche} not found !`) } } let context = { title: "Création de personnage - L'Age Viril", label: "Valider le choix de l'Age Viril", choices: ageVirilItems, caracBonus: this.caracBonus, competenceBonus: this.competenceBonus } let choiceResult = await this.askStageName(context) if (choiceResult == null) { this.currentStage = "cancelled" return } this.ageViril = foundry.utils.duplicate(stage.items.find(item => item.id === choiceResult.selectedItem)) context.title = `L'Age Viril - ${this.ageViril.name}` TeDeumUtility.prepareEducationContent(this.ageViril); context.label = "Valider l'augmentation de caracteristique" await this.askCarac(this.ageViril, context) context.label = "Valider l'augmentation de compétences" await this.askCompetences(this.ageViril, context) this.currentStage = "finished" } /*--------------------------------------------*/ async processStage() { while (this.currentStage !== "finished") { let stage = this.stages[this.currentStage] switch (this.currentStage) { case "origineSociale": await this.renderOrigineSociale(stage) break case "pouponniere": await this.renderPouponniere(stage) break case "petitsgrimauds": await this.renderPetitsGrimauds(stage) break case "rosevie": await this.renderRosesDeLaVie(stage) break case "ageviril": await this.renderAgeViril(stage) break case "cancelled": return break } } console.log("Carac Bonus", this.caracBonus) console.log("Competence Bonus", this.competenceBonus) let actor = await TeDeumActor.create({name: "Nouveau personnage", type: "pj"}) let updates = {} for (let key in this.caracBonus) { updates[`system.caracteristiques.${key}.value`] = Number(this.caracBonus[key].value)+1 } updates['system.genre'] = this.sexe updates['system.religion'] = TeDeumUtility.upperFirst(this.religion) updates['system.statutocial'] = this.origineSociale.label updates['system.equipmentfree'] = this.ageViril.system.trousseau actor.update( updates); // Process competences : increase know skills let updateComp = [] let toAdd = [] for (let compName in this.competenceBonus) { let comp = actor.items.find( i => i.type == "competence" && i.name.toLowerCase() === compName.toLowerCase()) if (comp) { updateComp.push({ _id: comp._id, "system.score": this.competenceBonus[compName].value }) } else { toAdd.push( compName) } } actor.updateEmbeddedDocuments("Item", updateComp) // Process adding skills let compendiumSkill = TeDeumUtility.getCompetences() let compToAdd = [ this.pouponniere, this.grimauds, this.roses, this.ageViril ] for (let compName of toAdd) { let comp = compendiumSkill.find( i => i.name.toLowerCase() === compName.toLowerCase()) comp.system.score = this.competenceBonus[compName].value compToAdd.push(comp) } await actor.createEmbeddedDocuments('Item', compToAdd) let newArgent = this.origineSociale.cagnotte * this.ageViril.system.cagnotteMultiplier newArgent /= this.ageViril.system.cagnotteDivider await actor.update({ [`system.fortune.${this.origineSociale.cagnotteUnit}`]: newArgent}) actor.render(true) const content = await renderTemplate("systems/fvtt-te-deum/templates/dialogs/character-creator-finished.hbs", context) const label = "Terminer" const choiceResult = await foundry.applications.api.DialogV2.wait({ window: { title: context.title }, classes: ["fvtt-te-deum"], content, buttons: [ { label: label, callback: (event, button, dialog) => { const output = Array.from(button.form.elements).reduce((obj, input) => { if (input.name) obj[input.name] = input.value return obj }, {}) return output }, }, ], actions: { }, rejectClose: false, // Click on Close button will not launch an error render: (event, dialog) => { } }) } }