mirror of
https://github.com/gregory-jagermeister/Fantasy-Content-Generator.git
synced 2026-07-22 07:30:31 +00:00
436 lines
No EOL
20 KiB
TypeScript
436 lines
No EOL
20 KiB
TypeScript
import { App, DropdownComponent, Modal, Setting } from "obsidian";
|
|
import { nameByRace } from "fantasy-name-generator";
|
|
import { familyNameList } from "lists/humanFamilyNames";
|
|
import { generateShipName } from "generators/ship";
|
|
import { generatorReligions } from "generators/religions";
|
|
import { generatorAirships } from "generators/airship";
|
|
import { generatorDrinks } from "generators/drink";
|
|
import { generatorGroups } from "generators/groups";
|
|
import { generatorAnimal_groups } from "generators/animalGroups";
|
|
import { generatorMetals } from "generators/metal";
|
|
import { generatorMagical_trees } from "generators/magicalTrees";
|
|
import { elfFamilyNames } from "lists/elvenFamilyNames";
|
|
import { dwarfFamilyNames } from "lists/dwarvenFamilyNames";
|
|
import * as FCG from "fantasy-content-generator";
|
|
import { generateCityName } from "generators/city";
|
|
import { generateLoot } from "generators/loot";
|
|
import FantasyPlugin from "main";
|
|
import { generateInn } from "generators/inn";
|
|
import { generatePathfinderName } from "generators/Pathfinder/pathfinderName";
|
|
import { ISettlementDomainObject } from "fantasy-content-generator/dist/interfaces";
|
|
import { generateMiscellaneousArtifacts } from "generators/artifact";
|
|
import { generateDungeonName } from "generators/dungeon";
|
|
import { generatePlotHook } from "generators/plothook";
|
|
import { innGeneratorSettings, lootTables } from "settings/Datatypes";
|
|
|
|
const races: string[] = ["none", "none", "dungeon", "inn", "settlement", "none", "airships", "drinks", "artifacts", "loot", "metals", "magicaltrees", "ship", "none", "animalgroups", "groups", "religion", "none", "aasimars", "catfolk", "fetchlings", "halfelf", "halforc", "hobgoblin", "ifrits", "kobalds", "oreads", "ratfolk", "sylphs", "tengu", "tians", "tiefling", "undines", "angel", "cavePerson", "darkelf", "demon", "dragon", "drow", "dwarf", "elf", "fairy", "gnome", "goblin", "halfdemon", "halfling", "highelf", "highfairy", "human", "ogre", "orc", "none", "plothook"];
|
|
const racesDisplayName: string[] = ["Select a Generator to Start", "--[Settlements and Buildings]--", "Dungeons & Labryinths", "Inn's & Taverns", "Settlement", "--[Objects and Vehicles]--", "Airships", "Drinks", "Artifacts", "Loot And Treasure", "Metals", "Magical Trees", "Ship", "--[Groups and Religions]--", "Animal Groups", "Groups", "Religion", "--[Races]--", "Aasimars", "Catfolk", "Fetchlings", "Half-Elf", "Half-Orc", "Hobgoblin", "Ifrits", "Kobalds", "Oreads", "Ratfolk", "Sylphs", "Tengu", "Tians", "Tiefling", "Undines", "Angel", "Cave Person", "Dark Elf", "Demon", "Dragon", "Drow", "Dwarf", "Elf", "Fairy", "Gnome", "Goblin", "Half Demon", "Halfling", "High Elf", "High Fairy", "Human", "Ogre", "Orc", "--[Story Tools]--", "Plot & Story Hooks"];
|
|
const pathfinderFilter = ["aasimars", "catfolk", "fetchlings","halfelf","halforc","hobgoblin","ifrits","kobalds","oreads","ratfolk","sylphs","tengu","tians","tiefling","undines"];
|
|
|
|
let genSettings = {
|
|
race: "angel",
|
|
gender: "male",
|
|
multiNames: false
|
|
}
|
|
|
|
export class GeneratorModal extends Modal {
|
|
result: string | Error;
|
|
onSubmit: (result: string | Error) => void;
|
|
plugin: FantasyPlugin;
|
|
constructor(app: App, onSubmit: (result: string | Error) => void, plugin: FantasyPlugin) {
|
|
super(app);
|
|
this.onSubmit = onSubmit;
|
|
this.plugin = plugin;
|
|
|
|
}
|
|
|
|
onOpen() {
|
|
const { contentEl } = this;
|
|
const amountToGen = 1;
|
|
contentEl.createEl("h1", { text: "Lets Generate!" });
|
|
contentEl.createEl("p", { text: "Welcome to the Fantasy Content Generator! Select the Generator for the name you would like to generate below and then fill out the form." });
|
|
contentEl.createEl("h2", { text: "Select the Generator." });
|
|
const select = new DropdownComponent(contentEl);
|
|
races.forEach((race,index) => {
|
|
select.addOption(race, racesDisplayName[index]);
|
|
})
|
|
|
|
const optionsDiv = contentEl.createDiv();
|
|
|
|
select.onChange((raceSelected) => {
|
|
switch (raceSelected) {
|
|
default:
|
|
this.generatorRaceSettings(optionsDiv, amountToGen, raceSelected);
|
|
break;
|
|
case "ship":
|
|
this.generatorCustomSettings(optionsDiv, amountToGen, generateShipName);
|
|
break;
|
|
case "dungeon":
|
|
this.generatorCustomSettings(optionsDiv, amountToGen, generateDungeonName, this.plugin.settings.dungeonSettings);
|
|
break;
|
|
case "plothook":
|
|
this.generatorCustomSettings(optionsDiv, amountToGen, generatePlotHook);
|
|
break;
|
|
case "religion":
|
|
this.generatorCustomSettings(optionsDiv, amountToGen, generatorReligions);
|
|
break;
|
|
case "inn":
|
|
this.generatorInnSettings(optionsDiv, amountToGen, generateInn);
|
|
break;
|
|
case "airships":
|
|
this.generatorCustomSettings(optionsDiv, amountToGen, generatorAirships);
|
|
break;
|
|
case "drinks":
|
|
this.generatorCustomSettings(optionsDiv, amountToGen, generatorDrinks, this.plugin.settings.drinkSettings);
|
|
break;
|
|
case "groups":
|
|
this.generatorCustomSettings(optionsDiv, amountToGen, generatorGroups, this.plugin.settings.groupSettings);
|
|
break;
|
|
case "animalgroups":
|
|
this.generatorCustomSettings(optionsDiv, amountToGen, generatorAnimal_groups);
|
|
break;
|
|
case "metals":
|
|
this.generatorCustomSettings(optionsDiv, amountToGen, generatorMetals);
|
|
break;
|
|
case "magicaltrees":
|
|
this.generatorCustomSettings(optionsDiv, amountToGen, generatorMagical_trees);
|
|
break;
|
|
case "settlement":
|
|
this.generatorFCGSettlementSettings(optionsDiv, amountToGen, FCG.Settlements.generate);
|
|
break;
|
|
case "loot":
|
|
this.generatorLootSettings(optionsDiv, amountToGen, generateLoot, this.plugin.settings.enableCurrency, this.plugin.settings.currencyFrequency, this.plugin.settings.currencyTypes);
|
|
break;
|
|
case "artifacts":
|
|
this.generatorCustomSettings(optionsDiv, amountToGen, generateMiscellaneousArtifacts);
|
|
break;
|
|
case "none":
|
|
optionsDiv.innerHTML = "";
|
|
break;
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
generatorRaceSettings(settingsdiv: HTMLElement, genAmount: number, raceSelected: string) {
|
|
genSettings = {
|
|
race: "angel",
|
|
gender: "male",
|
|
multiNames: false
|
|
}
|
|
genSettings.race = raceSelected;
|
|
settingsdiv.empty();
|
|
settingsdiv.createEl("h3", { text: "Customise The Generation" });
|
|
new Setting(settingsdiv)
|
|
.setName("Male or Female?")
|
|
.addDropdown((drop) => {
|
|
drop.addOption("male", "Male");
|
|
drop.addOption("female", "Female");
|
|
drop.onChange((value) => {
|
|
genSettings.gender = value;
|
|
})
|
|
});
|
|
new Setting(settingsdiv)
|
|
.setName("Family Name?")
|
|
.addToggle((toggle) => {
|
|
toggle.onChange((value) => {
|
|
genSettings.multiNames = value;
|
|
})
|
|
})
|
|
let fullCopy = '';
|
|
new Setting(settingsdiv)
|
|
.setName("Amount")
|
|
.setDesc("How Many Records to Generate")
|
|
.addText((text) => {
|
|
text.onChange((value) => genAmount = Number(value));
|
|
})
|
|
.addButton((btn) =>
|
|
btn.setButtonText("Generate")
|
|
.setCta()
|
|
.onClick(() => {
|
|
|
|
for (let index = 0; index < genAmount; index++) {
|
|
let firstName;
|
|
let familyName = '';
|
|
let fullName = '';
|
|
if (pathfinderFilter.includes(genSettings.race)) {
|
|
fullName = generatePathfinderName(genSettings.race, genSettings.gender, genSettings.multiNames);
|
|
|
|
} else {
|
|
type gender = 'male' | 'female' | undefined;
|
|
firstName = nameByRace(genSettings.race, { gender: genSettings.gender as gender });
|
|
if (genSettings.multiNames === true) {
|
|
familyName = genSettings.race.includes("human") || genSettings.race.includes("dwarf") || genSettings.race.includes("elf") ? " " + this.determineLastname(genSettings.race) : " " + nameByRace(genSettings.race, { gender: genSettings.gender as gender });
|
|
}
|
|
fullName = firstName + familyName;
|
|
}
|
|
|
|
new Setting(settingsdiv).addToggle((toggle) => {
|
|
toggle.onChange((value) => {
|
|
if (value === true) {
|
|
fullCopy += fullName + "\n";
|
|
} else {
|
|
const fullCIndex = fullCopy.indexOf(fullName);
|
|
fullCopy = fullCIndex === -1 ? fullCopy : fullCopy.slice(0, fullCIndex) + fullCopy.slice(fullCIndex + fullName.length);
|
|
}
|
|
})
|
|
.setValue(true);
|
|
}).setName(fullName);
|
|
|
|
}
|
|
|
|
}))
|
|
.addButton((btn) =>
|
|
btn
|
|
.setButtonText("Copy")
|
|
.setCta()
|
|
.onClick(() => {
|
|
if (fullCopy === '') {
|
|
this.result = new Error("Nothing Was Selected to Copy.");
|
|
} else {
|
|
this.result = fullCopy;
|
|
}
|
|
this.close();
|
|
this.onSubmit(this.result);
|
|
}));
|
|
|
|
}
|
|
|
|
generatorInnSettings(settingsdiv: HTMLElement, genAmount: number, generatorFunction: (settings: innGeneratorSettings) => {name:string,description:string,rumors:string[]}) {
|
|
settingsdiv.empty();
|
|
settingsdiv.createEl("h3", { text: "Customise The Generation" });
|
|
genAmount = 1;
|
|
let innList = '';
|
|
new Setting(settingsdiv)
|
|
.setName("Amount to Generate")
|
|
.addText((text) => {
|
|
text.onChange((value) => genAmount = Number(value));
|
|
})
|
|
.addButton((btn) =>
|
|
btn
|
|
.setButtonText("Generate")
|
|
.setCta()
|
|
.onClick(() => {
|
|
for (let index = 0; index < genAmount; index++) {
|
|
|
|
const innName = generatorFunction(this.plugin.settings.innSettings);
|
|
|
|
new Setting(settingsdiv).addToggle((toggle) => {
|
|
toggle.onChange((value) => {
|
|
const innString = innName.name + "\nDescription: " + innName.description + "\nRumors: " + innName.rumors;
|
|
if (value === true) {
|
|
innList += innString + "\n";
|
|
} else {
|
|
const fullCIndex = innList.indexOf(innString);
|
|
innList = fullCIndex === -1 ? innList : innList.slice(0, fullCIndex) + innList.slice(fullCIndex + innString.length);
|
|
}
|
|
})
|
|
.setValue(true);
|
|
}).setName(innName.name);
|
|
|
|
}
|
|
})).addButton((btn) =>
|
|
btn
|
|
.setButtonText("Copy")
|
|
.setCta()
|
|
.onClick(() => {
|
|
if (innList === '') {
|
|
this.result = new Error("Nothing Was Selected to Copy.");
|
|
} else {
|
|
this.result = innList;
|
|
}
|
|
this.close();
|
|
this.onSubmit(this.result);
|
|
}));
|
|
}
|
|
|
|
generatorLootSettings(settingsdiv: HTMLElement, genAmount: number, generatorFunction: (enableCurrency:boolean, currencyFrequency: number, currencyTypes: object[], lootTable: lootTables) => string, enableCurrency:boolean, currencyFrequency: number, currencyTypes: object[]) {
|
|
settingsdiv.empty();
|
|
settingsdiv.createEl("h3", { text: "Customise The Generation" });
|
|
genAmount = 1;
|
|
let list = '';
|
|
new Setting(settingsdiv)
|
|
.setName("Amount to Generate")
|
|
.addText((text) => {
|
|
text.onChange((value) => genAmount = Number(value));
|
|
})
|
|
.addButton((btn) =>
|
|
btn
|
|
.setButtonText("Generate")
|
|
.setCta()
|
|
.onClick(() => {
|
|
for (let index = 0; index < genAmount; index++) {
|
|
|
|
const shipName = generatorFunction(enableCurrency, currencyFrequency, currencyTypes, this.plugin.settings.lootSettings);
|
|
|
|
new Setting(settingsdiv).addToggle((toggle) => {
|
|
toggle.onChange((value) => {
|
|
if (value === true) {
|
|
list += shipName + "\n";
|
|
} else {
|
|
const fullCIndex = list.indexOf(shipName);
|
|
list = fullCIndex === -1 ? list : list.slice(0, fullCIndex) + list.slice(fullCIndex + shipName.length);
|
|
}
|
|
})
|
|
.setValue(true);
|
|
}).setName(shipName);
|
|
|
|
}
|
|
})).addButton((btn) =>
|
|
btn
|
|
.setButtonText("Copy")
|
|
.setCta()
|
|
.onClick(() => {
|
|
if (list === '') {
|
|
this.result = new Error("Nothing Was Selected to Copy.");
|
|
} else {
|
|
this.result = list;
|
|
}
|
|
this.close();
|
|
this.onSubmit(this.result);
|
|
}));
|
|
}
|
|
|
|
generatorFCGSettlementSettings(settingsdiv: HTMLElement, genAmount: number, generatorFunction: () => ISettlementDomainObject) {
|
|
settingsdiv.empty();
|
|
settingsdiv.createEl("h3", { text: "Customise The Generation" });
|
|
genAmount = 1;
|
|
let list = '';
|
|
new Setting(settingsdiv)
|
|
.setName("Amount to Generate")
|
|
.addText((text) => {
|
|
text.onChange((value) => genAmount = Number(value));
|
|
})
|
|
.addButton((btn) =>
|
|
btn
|
|
.setButtonText("Generate")
|
|
.setCta()
|
|
.onClick(() => {
|
|
for (let index = 0; index < genAmount; index++) {
|
|
|
|
const shipName = generatorFunction();
|
|
console.log(shipName);
|
|
|
|
const name = generateCityName(this.plugin.settings.citySettings);
|
|
const settlementString = "Name: " + name + "\nPopulation: " + shipName.population +"\nType: "+ this.formatString(shipName.type);
|
|
new Setting(settingsdiv).addToggle((toggle) => {
|
|
toggle.onChange((value) => {
|
|
if (value === true) {
|
|
list += settlementString + "\n\n";
|
|
} else {
|
|
const fullCIndex = list.indexOf(settlementString +"\n");
|
|
list = fullCIndex === -1 ? list : list.slice(0, fullCIndex) + list.slice(fullCIndex + settlementString.length);
|
|
}
|
|
})
|
|
.setValue(true);
|
|
}).setName(name);
|
|
|
|
}
|
|
})).addButton((btn) =>
|
|
btn
|
|
.setButtonText("Copy")
|
|
.setCta()
|
|
.onClick(() => {
|
|
if (list === '') {
|
|
this.result = new Error("Nothing Was Selected to Copy.");
|
|
} else {
|
|
this.result = this.formatStringList(list);
|
|
}
|
|
this.close();
|
|
this.onSubmit(this.result);
|
|
}));
|
|
}
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
generatorCustomSettings(settingsdiv: HTMLElement, genAmount: number, generatorFunction: (settings ?: any) => string, settings ?: any) {
|
|
settingsdiv.empty();
|
|
settingsdiv.createEl("h3", { text: "Customise The Generation" });
|
|
genAmount = 1;
|
|
let list = "";
|
|
new Setting(settingsdiv)
|
|
.setName("Amount to Generate")
|
|
.addText((text) => {
|
|
text.onChange((value) => genAmount = Number(value));
|
|
})
|
|
.addButton((btn) =>
|
|
btn
|
|
.setButtonText("Generate")
|
|
.setCta()
|
|
.onClick(() => {
|
|
for (let index = 0; index < genAmount; index++) {
|
|
let shipName = '';
|
|
if (settings !== undefined) {
|
|
shipName = generatorFunction(settings);
|
|
} else {
|
|
shipName = generatorFunction();
|
|
}
|
|
new Setting(settingsdiv).addToggle((toggle) => {
|
|
toggle.onChange((value) => {
|
|
if (value === true) {
|
|
list += shipName + "\n\n";
|
|
} else {
|
|
const fullCIndex = list.indexOf(shipName);
|
|
list = fullCIndex === -1 ? list : list.slice(0, fullCIndex) + list.slice(fullCIndex + shipName.length);
|
|
}
|
|
})
|
|
.setValue(true);
|
|
}).setName(shipName);
|
|
|
|
}
|
|
})).addButton((btn) =>
|
|
btn
|
|
.setButtonText("Copy")
|
|
.setCta()
|
|
.onClick(() => {
|
|
if (list === '') {
|
|
this.result = new Error("Nothing Was Selected to Copy.");
|
|
} else {
|
|
this.result = this.formatStringList(list);
|
|
|
|
}
|
|
this.close();
|
|
this.onSubmit(this.result);
|
|
}));
|
|
}
|
|
|
|
determineLastname(race: string) {
|
|
|
|
if (race.includes("human")) {
|
|
return this.randomItemFromArray(familyNameList);
|
|
}
|
|
|
|
if (race.includes("elf")) {
|
|
return this.randomItemFromArray(elfFamilyNames);
|
|
}
|
|
|
|
if (race.includes("dwarf")) {
|
|
return this.randomItemFromArray(dwarfFamilyNames);
|
|
}
|
|
|
|
return "The Unknown"
|
|
|
|
}
|
|
|
|
randomItemFromArray(array:string[]) {
|
|
const randomIndex = Math.floor(Math.random() * array.length);
|
|
return array[randomIndex];
|
|
}
|
|
|
|
formatStringList(input: string) {
|
|
return input.split('\n').filter(s => s.trim() !== '').join('\n\n');
|
|
}
|
|
|
|
formatString(str:string) {
|
|
return str.split("_").map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
}
|
|
|
|
onClose() {
|
|
const { contentEl } = this;
|
|
genSettings = {
|
|
race: "angel",
|
|
gender: "male",
|
|
multiNames: false
|
|
}
|
|
contentEl.empty();
|
|
}
|
|
} |