diff --git a/lang/en.json b/lang/en.json
index 0bcde30..c1ac4cd 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -27,6 +27,8 @@
"Mosh.CharacterGenerator.StatOption": "Stats & Saves",
"Mosh.CharacterGenerator.StatOptionPopupTitle": "Class Attribute and Saves option",
"Mosh.CharacterGenerator.StatOptionPopupText": "Choose where to apply the bonus of:",
+ "Mosh.CharacterGenerator.SkillOptionPopupTitle": "Choose your skills",
+ "Mosh.CharacterGenerator.SkillOptionChoice": "Option",
"Mosh.CharacterGenerator.Tables": "Tables",
"Mosh.CharacterGenerator.Table.Loadout": "Loadout Table",
"Mosh.CharacterGenerator.Table.Patch": "Patch Table",
@@ -124,6 +126,9 @@
"Mosh.SkillBonus": "Skill Bonus",
"Mosh.SkillName": "Skill Name",
"Mosh.SkillRank": "Skill Rank",
+ "Mosh.SkillRankTrained": "Trained",
+ "Mosh.SkillRankExpert": "Expert",
+ "Mosh.SkillRankMaster": "Master",
"Mosh.Skills": "Skills",
"Mosh.SkillsFixed": "Fixed Skills",
"Mosh.SkillsPrerequisite": "Prerequisite Skills",
diff --git a/module/windows/actor-generator.js b/module/windows/actor-generator.js
index d22a05f..58ad7a0 100644
--- a/module/windows/actor-generator.js
+++ b/module/windows/actor-generator.js
@@ -29,7 +29,10 @@ export class DLActorGenerator extends FormApplication {
//}
let data = this.object;
+ data.system.class = [];
data.system.class.value = "";
+ data.system.class.skills = [];
+ data.system.class.skills.uuid = [];
return data;
}
/* -------------------------------------------- */
@@ -161,6 +164,142 @@ export class DLActorGenerator extends FormApplication {
await this.rollLoadout(html);
}
+ async updateSkillHtmlUl(html, skillsUuid) {
+ //html.find(`ul[id="system.class.skils.text"]`).empty();
+ for (let i = 0; i < skillsUuid.length; i++) {
+ let skill = await fromUuid(skillsUuid[i]);
+ /**we need to keep only the Uuid of the item, not the complete string (for now) */
+ let li_html = `
${await TextEditor.enrichHTML(skill.name, { async: true })}`;
+ html.find(`ul[id="system.class.skils.text"]`).append(li_html);
+ }
+ let old_skills = html.find(`input[id="system.class.skills.uuid"]`).prop("value").split(",").filter(Boolean);
+ html.find(`input[id="system.class.skills.uuid"]`).prop("value", old_skills.concat(skillsUuid).join(","));
+ }
+
+ async popUpSkillOptions(skillPopupOptions) {
+
+ for (let i = 0; i < skillPopupOptions.master_full_set; i++) {
+ await this.showSkillDialog('systems/mosh/templates/dialogs/actor-generator/actor-generator-skill-option-full-master-dialog.html');
+
+ }
+ for (let i = 0; i < skillPopupOptions.expert_full_set; i++) {
+ await this.showSkillDialog('systems/mosh/templates/dialogs/actor-generator/actor-generator-skill-option-full-expert-dialog.html');
+
+ }
+ for (let i = 0; i < skillPopupOptions.trained; i++) {
+ await this.showSkillDialog('systems/mosh/templates/dialogs/actor-generator/actor-generator-skill-option-single-dialog.html', "trained");
+
+ }
+ for (let i = 0; i < skillPopupOptions.expert; i++) {
+ await this.showSkillDialog('systems/mosh/templates/dialogs/actor-generator/actor-generator-skill-option-single-dialog.html', "expert");
+
+ }
+ for (let i = 0; i < skillPopupOptions.master; i++) {
+ await this.showSkillDialog('systems/mosh/templates/dialogs/actor-generator/actor-generator-skill-option-single-dialog.html', "master");
+
+ }
+ //console.log(existingSkills);
+ //return skillsUuid;
+ }
+
+ async showSkillDialog(template, exclusive = false) {
+
+ let skillsUuid = this.skillsUuid;
+
+ let all_skills = await this.getAllSkills();
+ all_skills.forEach((element, index) => {
+ all_skills[index].disabled = (skillsUuid.includes(element.uuid) ? "disabled" : "");
+ });
+
+
+ let skillPopupData = {
+ title: game.i18n.localize("Mosh.CharacterGenerator.SkillOptionPopupTitle"),
+ existingSkills: skillsUuid,
+ skills: {
+ trained: all_skills.filter(i => i.system.rank == "Trained"),
+ expert: all_skills.filter(i => i.system.rank == "Expert"),
+ master: all_skills.filter(i => i.system.rank == "Master"),
+ }
+ };
+ if (exclusive) {
+ skillPopupData.description = game.i18n.localize("Mosh.CharacterGenerator.SkillOptionPopup" + exclusive + "Description");
+ switch (exclusive) {
+ case "master":
+ skillPopupData.skills = all_skills.filter(i => i.system.rank == "Master" && i.system.prerequisite_ids.filter(item => skillsUuid.includes(item)).length > 0);
+ break;
+ case "expert":
+ skillPopupData.skills = all_skills.filter(i => i.system.rank == "Expert" && i.system.prerequisite_ids.filter(item => skillsUuid.includes(item)).length > 0);
+ break;
+ case "trained":
+ skillPopupData.skills = all_skills.filter(i => i.system.rank == "Trained");
+ break;
+ }
+ }
+
+ let popUpContent = await renderTemplate(template, skillPopupData);
+
+ return new Promise((resolve) => {
+ let d = new Dialog({
+ title: game.i18n.localize("Mosh.CharacterGenerator.SkillOptionPopupTitle"),
+ content: popUpContent,
+ buttons: {
+ "1": {
+ icon: '',
+ label: "Save",
+ callback: (html) => {
+ let form = html.find('form')[0];
+ let formData = new FormData(form);
+ let new_skills = [];
+ formData.forEach((value, key) => {
+ if (value != "") {
+ new_skills.push(value);
+ this.skillsUuid.push(value);
+ }
+ });
+
+ this.updateSkillHtmlUl(this._element, new_skills);
+ resolve();
+ }
+ },
+ },
+ default: "1",
+ });
+ d.render(true);
+ });
+ }
+
+ async showOptionsDialog(option_1, option_2) {
+ let popupData = {
+ option_1: option_1,
+ option_2: option_2,
+ }
+ let popUpContent = await renderTemplate("systems/mosh/templates/dialogs/actor-generator/actor-generator-skill-option-choice-dialog.html", popupData);
+
+ return new Promise((resolve) => {
+ let d = new Dialog({
+ title: game.i18n.localize("Mosh.CharacterGenerator.SkillOptionPopupTitle"),
+ content: popUpContent,
+ width: 450,
+ buttons: {
+ "1": {
+ icon: '',
+ label: game.i18n.localize("Mosh.CharacterGenerator.SkillOptionChoice") + " 1",
+ callback: () => {
+ resolve(option_1);
+ }
+ },
+ "2": {
+ icon: '',
+ label: game.i18n.localize("Mosh.CharacterGenerator.SkillOptionChoice") + " 2",
+ callback: () => {
+ resolve(option_2);
+ }
+ },
+ },
+ });
+ d.render(true);
+ });
+ }
async updateClass(classUuid, randomCharacter = false) {
@@ -186,31 +325,39 @@ export class DLActorGenerator extends FormApplication {
this.patchTable = droppedObject.system.roll_tables.patch;
this.loadoutTable = droppedObject.system.roll_tables.loadout;
- // Skills
- //try{
- //let skills = JSON.parse(droppedObject.system.skills.replaceAll("","").replaceAll("
","").replaceAll("","").replaceAll("
","").replaceAll(" ",""));
+ /**
+ * Skills
+ * */
this._element.find(`ul[id="system.class.skils.text"]`).empty();
- const skillsUuid = droppedObject.system.base_adjustment.skills_granted;
- for (let i = 0; i < skillsUuid.length; i++) {
- let skill = await fromUuid(skillsUuid[i]);
- /**we need to keep only the Uuid of the item, not the complete string (for now) */
- let li_html = `
${await TextEditor.enrichHTML(skill.name, { async: true })}`;
- this._element.find(`ul[id="system.class.skils.text"]`).append(li_html);
- }
+ this.skillsUuid = droppedObject.system.base_adjustment.skills_granted.slice();
+ await this.updateSkillHtmlUl(this._element, this.skillsUuid);
let option_skills_1 = droppedObject.system.selected_adjustment.choose_skill_and;
+ await this.popUpSkillOptions(option_skills_1);
let option_skills_2 = droppedObject.system.selected_adjustment.choose_skill_or;
- //todo: add popups to choose skils from (following the skill tree and type)
+ const isEmptyOption1 = Object.values(option_skills_2.option_1).every(x => x === null || x === '' || x === 0);
+ const isEmptyOption2 = Object.values(option_skills_2.option_2).every(x => x === null || x === '' || x === 0);
+ let option_skills_2_choosed = {}
+ if (isEmptyOption1 == false && isEmptyOption2 == false) {
+ //we need to choose-> render popup with both options
+ option_skills_2_choosed = await this.showOptionsDialog(option_skills_2.option_1,option_skills_2.option_2);
+ } else if (isEmptyOption1 == false) {
+ //there is only option 1 (edge case) but we go with it.
+ option_skills_2_choosed = option_skills_2.option_1;
+ } else if (isEmptyOption2 == false) {
+ //there is only option 2 (edge case) but we go with it.
+ option_skills_2_choosed = option_skills_2.option_2;
+ }
+ await this.popUpSkillOptions(option_skills_2_choosed);
- this._element.find(`input[id="system.class.skills.uuid"]`).prop("value", skillsUuid);
- //}catch{
- // ui.notifications.error("Class has invalid skills configuration.");
- //}
- //Stats
+
+ /**
+ * Stats
+ */
///try{
//let statsandsaves = JSON.parse(droppedObject.system.statsandsaves.replaceAll("","").replaceAll("
","").replaceAll("","").replaceAll("
","").replaceAll(" ",""));
let fix_stats_and_saves = droppedObject.system.base_adjustment;
@@ -289,6 +436,18 @@ export class DLActorGenerator extends FormApplication {
//this._render();
}
+ async getAllSkills() {
+ /**TODO: Get only player skills ?¿ there is no way to tell pet skills apart */
+ let skills = game.items.filter(i => i.type == "skill");
+
+ for (const [compendium_key, compendium_value] of game.packs.entries()) {
+ let skillCompendium = await compendium_value.getDocuments({ type: "skill" });
+ if (skillCompendium.length > 0) {
+ skills = skills.concat(skillCompendium)
+ }
+ }
+ return skills;
+ }
async fill_class_options(html) {
diff --git a/templates/dialogs/actor-generator/actor-generator-skill-option-choice-dialog.html b/templates/dialogs/actor-generator/actor-generator-skill-option-choice-dialog.html
new file mode 100644
index 0000000..3125d16
--- /dev/null
+++ b/templates/dialogs/actor-generator/actor-generator-skill-option-choice-dialog.html
@@ -0,0 +1,70 @@
+
+
+
+
+
{{localize 'Mosh.CharacterGenerator.SkillOptionChoice'}} 1
+
+
+ {{#if option_1.master}}
+ -
+ {{localize 'Mosh.SkillRankMaster'}} : {{option_1.master}}
+
+ {{/if}}
+ {{#if option_1.expert}}
+ -
+ {{localize 'Mosh.SkillRankExpert'}} : {{option_1.expert}}
+
+ {{/if}}
+ {{#if option_1.trained}}
+ -
+ {{localize 'Mosh.SkillRankTrained'}} : {{option_1.trained}}
+
+ {{/if}}
+ {{#if option_1.master_full_set}}
+ -
+ {{localize 'Mosh.SkillRankMaster'}} & {{localize 'Mosh.SkillsPrerequisite'}} :
+ {{option_1.master_full_set}}
+
+ {{/if}}
+ {{#if option_1.expert_full_set}}
+ -
+ {{localize 'Mosh.SkillRankExpert'}} & {{localize 'Mosh.SkillsPrerequisite'}} :
+ {{option_1.expert_full_set}}
+
+ {{/if}}
+
+
+
+
{{localize 'Mosh.CharacterGenerator.SkillOptionChoice'}} 2
+
+ {{#if option_2.master}}
+ -
+ {{localize 'Mosh.SkillRankMaster'}} : {{option_2.master}}
+
+ {{/if}}
+ {{#if option_2.expert}}
+ -
+ {{localize 'Mosh.SkillRankExpert'}} : {{option_2.expert}}
+
+ {{/if}}
+ {{#if option_2.trained}}
+ -
+ {{localize 'Mosh.SkillRankTrained'}} : {{option_2.trained}}
+
+ {{/if}}
+ {{#if option_2.master_full_set}}
+ -
+ {{localize 'Mosh.SkillRankMaster'}} & {{localize 'Mosh.SkillsPrerequisite'}} :
+ {{option_2.master_full_set}}
+
+ {{/if}}
+ {{#if option_2.expert_full_set}}
+ -
+ {{localize 'Mosh.SkillRankExpert'}} & {{localize 'Mosh.SkillsPrerequisite'}} :
+ {{option_2.expert_full_set}}
+
+ {{/if}}
+
+
+
+
\ No newline at end of file
diff --git a/templates/dialogs/actor-generator/actor-generator-skill-option-full-expert-dialog.html b/templates/dialogs/actor-generator/actor-generator-skill-option-full-expert-dialog.html
new file mode 100644
index 0000000..c4af7a2
--- /dev/null
+++ b/templates/dialogs/actor-generator/actor-generator-skill-option-full-expert-dialog.html
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+ {{title}}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/templates/dialogs/actor-generator/actor-generator-skill-option-full-master-dialog.html b/templates/dialogs/actor-generator/actor-generator-skill-option-full-master-dialog.html
new file mode 100644
index 0000000..72c5c56
--- /dev/null
+++ b/templates/dialogs/actor-generator/actor-generator-skill-option-full-master-dialog.html
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+ {{title}}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/templates/dialogs/actor-generator/actor-generator-skill-option-single-dialog.html b/templates/dialogs/actor-generator/actor-generator-skill-option-single-dialog.html
new file mode 100644
index 0000000..fde5e83
--- /dev/null
+++ b/templates/dialogs/actor-generator/actor-generator-skill-option-single-dialog.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+ {{title}}
+
+
+
+
+
+
+
+
\ No newline at end of file