Skip to content
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion scripts/daily-seed/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ export const EDIT_OPTIONS = /** @type {const} */ ([
"biome",
"luck",
"forced waves",
"trainer manipulation",
"challenges",
"mystery encounters",
"starting money",
"seed",
"edit",
Expand All @@ -49,6 +52,8 @@ export const BOSS_OPTIONS = /** @type {const} */ ([
"nature",
"ability",
"passive",
"segments",
"catchable",
"finish",
]);

Expand All @@ -58,7 +63,8 @@ export const STARTER_OPTIONS = /** @type {const} */ ([
"variant",
"moveset",
"nature",
"abilityIndex",
"ability",
"passive",
"finish",
]);

Expand Down
29 changes: 27 additions & 2 deletions scripts/daily-seed/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,17 @@ import { toTitleCase } from "../helpers/casing.js";
import { promptOverwrite, writeFileSafe } from "../helpers/file.js";
import { EDIT_OPTIONS } from "./constants.js";
import { promptBoss } from "./prompts/boss.js";
import { promptBiome, promptEdit, promptForcedWaves, promptLuck, promptMoney, promptSeed } from "./prompts/general.js";
import {
promptBiome,
promptChallenges,
promptEdit,
promptForcedWaves,
promptLuck,
promptMoney,
promptMysteryEncounters,
promptSeed,
promptTrainerManipulation,
} from "./prompts/general.js";
import { promptStarters } from "./prompts/starter.js";

/**
Expand All @@ -33,7 +43,8 @@ const rootDir = join(import.meta.dirname, "..", "..");
/**
* @import {BossConfig} from "./prompts/boss.js"
* @import {StarterConfig} from "./prompts/starter.js"
* @import {ForcedWaveConfig} from "./prompts/general.js"
* @import {ForcedWaveConfig, DailyTrainerManipulation, DailyEventChallenge} from "./prompts/general.js"
* @import {DailyEventMysteryEncounter} from "./prompts/general.js"
*/

/**
Expand All @@ -48,6 +59,9 @@ const rootDir = join(import.meta.dirname, "..", "..");
* biome?: number,
* luck?: number,
* forcedWaves?: ForcedWaveConfig[],
* trainerManipulations?: DailyTrainerManipulation[],
* challenges?: DailyEventChallenge[],
* mysteryEncounters?: DailyEventMysteryEncounter[],
* startingMoney?: number,
* seed: string
* }}
Expand All @@ -58,6 +72,8 @@ const customSeedConfig = {
biome: undefined,
luck: undefined,
forcedWaves: undefined,
trainerManipulations: undefined,
challenges: undefined,
startingMoney: undefined,
seed: "",
};
Expand Down Expand Up @@ -137,6 +153,15 @@ async function handleAnswer(answer) {
case "forced waves":
customSeedConfig.forcedWaves = await promptForcedWaves();
break;
case "trainer manipulation":
customSeedConfig.trainerManipulations = await promptTrainerManipulation();
break;
case "challenges":
customSeedConfig.challenges = await promptChallenges();
break;
case "mystery encounters":
customSeedConfig.mysteryEncounters = await promptMysteryEncounters();
break;
case "starting money":
customSeedConfig.startingMoney = await promptMoney();
break;
Expand Down
18 changes: 16 additions & 2 deletions scripts/daily-seed/prompts/boss.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { select } from "@inquirer/prompts";
import { confirm, select } from "@inquirer/prompts";
import chalk from "chalk";
import { toCamelCase, toTitleCase } from "../../helpers/casing.js";
import { BOSS_OPTIONS } from "../constants.js";
Expand All @@ -14,6 +14,7 @@ import {
promptFormIndex,
promptMoveset,
promptNature,
promptSegments,
promptSpeciesId,
promptVariant,
} from "./pokemon.js";
Expand All @@ -28,7 +29,9 @@ import {
* moveset?: number[],
* nature?: number,
* ability?: number,
* passive?: number
* passive?: number,
* segments?: number,
* catchable?: boolean,
* }} BossConfig - The config for a single boss pokemon.
*
*/
Expand All @@ -45,6 +48,8 @@ let bossConfig = {
nature: undefined,
ability: undefined,
passive: undefined,
segments: undefined,
catchable: undefined,
};

/**
Expand Down Expand Up @@ -99,6 +104,15 @@ async function promptBossOptions() {
case "passive":
bossConfig.passive = await promptAbility(true);
break;
case "segments":
bossConfig.segments = await promptSegments();
break;
case "catchable":
bossConfig.catchable = await confirm({
message: "Should the boss be catchable?",
default: false,
});
break;
case "finish":
return bossConfig;
}
Expand Down
155 changes: 155 additions & 0 deletions scripts/daily-seed/prompts/general.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { Ajv } from "ajv";
import chalk from "chalk";
import customDailyRunSchema from "../../../src/data/daily-seed/schema.json" with { type: "json" };
import { BIOMES } from "../../enums/biomes.js";
import { CHALLENGES } from "../../enums/challenges.js";
import { MYSTERY_ENCOUNTERS } from "../../enums/mystery-encounters.js";
import { toTitleCase, toUpperSnakeCase } from "../../helpers/casing.js";
import { BIOME_POOL_TIERS } from "../constants.js";
import { promptSpeciesId } from "./pokemon.js";
Expand All @@ -26,6 +28,27 @@ import { promptSpeciesId } from "./pokemon.js";
* }} ForcedWaveConfig
*/

/**
* @typedef {{
* waveIndex: number,
* isTrainer: boolean,
* }} DailyTrainerManipulation
*/

/**
* @typedef {{
* id: number,
* value: number,
* }} DailyEventChallenge
*/

/**
* @typedef {{
* waveIndex: number,
* type: number,
* }} DailyEventMysteryEncounter
*/

const ajv = new Ajv({
allErrors: true,
});
Expand Down Expand Up @@ -196,3 +219,135 @@ export async function promptForcedWaves() {
}
return forcedWaves;
}

/**
* Prompt the user to enter a list of trainer manipulations.
* @returns {Promise<DailyTrainerManipulation[] | undefined>} A Promise that resolves with the list of trainer manipulations.
*/
export async function promptTrainerManipulation() {
/** @type {DailyTrainerManipulation[]} */
const trainerManipulations = [];

async function addTrainerManipulation() {
const waveIndex = await number({
message: "Please enter the wave to manipulate.\nPressing ENTER will end the prompt early.",
min: 1,
max: 49,
validate: value => {
if (trainerManipulations.some(wave => wave.waveIndex === value)) {
return chalk.red.bold("Wave already manipulated!");
}
return true;
},
});
if (!waveIndex) {
return;
}

const isTrainer = await confirm({
message: "Should the wave be a trainer?",
default: false,
});

trainerManipulations.push({ waveIndex, isTrainer });

await addTrainerManipulation();
}

await addTrainerManipulation();
if (trainerManipulations.length === 0) {
return;
}
return trainerManipulations;
}

/**
* Prompt the user to enter a list of challenges.
* @returns {Promise<DailyEventChallenge[] | undefined>} A Promise that resolves with the list of challenges.
*/
export async function promptChallenges() {
/** @type {DailyEventChallenge[]} */
const challenges = [];
const challengeNames = Object.keys(CHALLENGES).map(toTitleCase);
challengeNames.unshift("Finish");

async function addChallenge() {
const challenge = await search({
message: "Please enter the challenge to add.\nPressing ENTER will end the prompt early.",
source: term => {
if (!term) {
return challengeNames;
}
return challengeNames.filter(id => id.toLowerCase().includes(term.toLowerCase()));
},
});
if (challenge === "Finish") {
return;
}

const value = await number({
message: `Please enter the value for ${challenge}. This is NOT validted atm.`,
min: 0,
required: true,
});

const challengeId = CHALLENGES[/** @type {keyof typeof CHALLENGES} */ (toUpperSnakeCase(challenge))];
challenges.push({ id: challengeId, value });
challengeNames.splice(challengeNames.indexOf(challenge), 1);
await addChallenge();
}
await addChallenge();

if (challenges.length === 0) {
return;
}
return challenges;
}

/**
* Prompt the user to enter a list of mystery encounters.
* @returns {Promise<DailyEventMysteryEncounter[] | undefined>} A Promise that resolves with the list of mystery encounters.
*/
export async function promptMysteryEncounters() {
/** @type {DailyEventMysteryEncounter[]} */
const mysteryEncounters = [];

async function addMysteryEncounter() {
const waveIndex = await number({
message: "Please enter the wave to force a mystery encounter.\nPressing ENTER will end the prompt early.",
min: 1,
max: 49,
validate: value => {
if (mysteryEncounters.some(wave => wave.waveIndex === value)) {
return chalk.red.bold("Wave already has a mystery encounter!");
}
return true;
},
});
if (!waveIndex) {
return;
}

const type = await search({
message: "Please select the mystery encounter to force.",
source: term => {
if (!term) {
return Object.keys(MYSTERY_ENCOUNTERS).map(toTitleCase);
}
return Object.keys(MYSTERY_ENCOUNTERS)
.map(toTitleCase)
.filter(id => id.toLowerCase().includes(term.toLowerCase()));
},
});

const typeId = MYSTERY_ENCOUNTERS[/** @type {keyof typeof MYSTERY_ENCOUNTERS} */ (toUpperSnakeCase(type))];
mysteryEncounters.push({ waveIndex, type: typeId });
await addMysteryEncounter();
}

await addMysteryEncounter();
if (mysteryEncounters.length === 0) {
return;
}
return mysteryEncounters;
}
17 changes: 6 additions & 11 deletions scripts/daily-seed/prompts/pokemon.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { toTitleCase, toUpperSnakeCase } from "../../helpers/casing.js";

/**
* Prompt the user to enter a speciesId.
* @see {@linkcode SPECIES_IDS} for a list of valid `SpeciesId`s.
* @returns {Promise<number>} A Promise that resolves with the chosen `SpeciesId`.
*/
export async function promptSpeciesId() {
Expand Down Expand Up @@ -131,8 +130,6 @@ export async function promptMoveset() {
* Prompt the user to enter an ability.
* @param {boolean} [passive=false] (Default `false`) Whether to prompt for a passive ability.
* @returns {Promise<number>} A Promise that resolves with the chosen ability.
* @remarks
* This is boss only for now, since the option for setting any ability is not yet implemented.
*/
export async function promptAbility(passive = false) {
const abilityName = await search({
Expand All @@ -150,16 +147,14 @@ export async function promptAbility(passive = false) {
}

/**
* Prompt the user to enter an ability index.
* @returns {Promise<number>} A Promise that resolves with the chosen ability index.
* @remarks This is starter only for now.
* Prompt the user to enter the number of segments for the boss fight.
* @returns {Promise<number>} A Promise that resolves with the chosen number of segments.
*/
// TODO: Validate the ability index & list the actual ability names based on main repo data
export async function promptAbilityIndex() {
export async function promptSegments() {
return await number({
message: `Please enter the starter's ability index.`,
min: 0,
max: 2,
message: "Please enter the number of segments for the boss fight.",
min: 1,
default: 5,
required: true,
});
}
12 changes: 8 additions & 4 deletions scripts/daily-seed/prompts/starter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { number, select } from "@inquirer/prompts";
import { toCamelCase, toTitleCase } from "../../helpers/casing.js";
import { STARTER_OPTIONS } from "../constants.js";
import {
promptAbilityIndex,
promptAbility,
promptFormIndex,
promptMoveset,
promptNature,
Expand All @@ -26,7 +26,8 @@ import {
* variant?: Variant,
* moveset?: number[],
* nature?: number,
* abilityIndex?: number,
* ability?: number,
* passive?: number
* }} StarterConfig
*/

Expand Down Expand Up @@ -99,8 +100,11 @@ async function promptStarterOptions(starterConfig) {
case "nature":
starterConfig.nature = await promptNature();
break;
case "abilityIndex":
starterConfig.abilityIndex = await promptAbilityIndex();
case "ability":
starterConfig.ability = await promptAbility();
break;
case "passive":
starterConfig.passive = await promptAbility(true);
break;
case "finish":
// Re-add all used options for next starter
Expand Down
Loading