src/tutorial.ts
Rama beta · réplica de lectura del repositorio original.
import { globalScene } from "#app/global-scene";
import { settings } from "#app/global-settings-manager";
import { activeOverrides } from "#app/overrides";
import { UiMode } from "#enums/ui-mode";
import { AwaitableUiHandler } from "#ui/awaitable-ui-handler";
import type { UiHandler } from "#ui/ui-handler";
import i18next from "i18next";
export enum Tutorial {
INTRO = "INTRO",
ACCESS_MENU = "ACCESS_MENU",
MENU = "MENU",
STARTER_SELECT = "STARTER_SELECT",
POKEDEX = "POKEDEX",
POKERUS = "POKERUS",
STAT_CHANGE = "STAT_CHANGE",
SELECT_ITEM = "SELECT_ITEM",
EGG_GACHA = "EGG_GACHA",
}
/**
* Show a tutorial text with a speaker box.
* @param key - The i18next key for the tutorial text
* @param callback - Callback for when the tutorial dialogue is dismissed
*/
function showTutorialDialogue(key: string, callback: () => void): void {
globalScene.ui.showDialogue(i18next.t(key), i18next.t("tutorial:name"), null, callback);
}
const tutorialHandlers = {
[Tutorial.INTRO]: () => {
return new Promise<void>(resolve => {
globalScene.ui.showText(i18next.t("tutorial:intro"), null, () => resolve(), null, true);
});
},
[Tutorial.ACCESS_MENU]: () => {
return new Promise<void>(resolve => {
if (settings.general.enableTouchControls) {
return resolve();
}
globalScene
.showFieldOverlay(1000)
.then(() =>
showTutorialDialogue("tutorial:accessMenu", () => globalScene.hideFieldOverlay(1000).then(() => resolve())),
);
});
},
[Tutorial.MENU]: () => {
return new Promise<void>(resolve => {
globalScene.gameData.saveTutorialFlag(Tutorial.ACCESS_MENU, true);
showTutorialDialogue("tutorial:menu", () => globalScene.ui.showText("", null, () => resolve()));
});
},
[Tutorial.STARTER_SELECT]: () => {
return new Promise<void>(resolve => {
showTutorialDialogue("tutorial:starterSelect", () => globalScene.ui.showText("", null, () => resolve()));
});
},
[Tutorial.POKERUS]: () => {
return new Promise<void>(resolve => {
showTutorialDialogue("tutorial:pokerus", () => globalScene.ui.showText("", null, () => resolve()));
});
},
[Tutorial.STAT_CHANGE]: () => {
return new Promise<void>(resolve => {
globalScene
.showFieldOverlay(1000)
.then(() =>
showTutorialDialogue("tutorial:statChange", () =>
globalScene.ui.showText("", null, () => globalScene.hideFieldOverlay(1000).then(() => resolve())),
),
);
});
},
[Tutorial.SELECT_ITEM]: () => {
return new Promise<void>(resolve => {
globalScene.ui.setModeWithoutClear(UiMode.MESSAGE).then(() => {
showTutorialDialogue("tutorial:selectItem", () =>
globalScene.ui.showText("", null, () =>
globalScene.ui.setModeWithoutClear(UiMode.MODIFIER_SELECT).then(() => resolve()),
),
);
});
});
},
[Tutorial.EGG_GACHA]: () => {
return new Promise<void>(resolve => {
showTutorialDialogue("tutorial:eggGacha", () => globalScene.ui.showText("", null, () => resolve()));
});
},
};
/**
* Run through the specified tutorial if it hasn't been seen before and mark it as seen once done. \
* This will show a tutorial overlay if defined in the current {@linkcode AwaitableUiHandler}. \
* The main menu will also get disabled while the tutorial is running
* @param tutorial - The {@linkcode Tutorial} to play
* @returns a promise with result `true` if the tutorial was run and finished, `false` otherwise
*/
export async function handleTutorial(tutorial: Tutorial): Promise<boolean> {
if (!activeOverrides.BYPASS_TUTORIAL_SKIP_OVERRIDE) {
if (!settings.general.enableTutorials) {
return false;
}
if (globalScene.gameData.getTutorialFlags()[tutorial]) {
return false;
}
}
const handler = globalScene.ui.getHandler();
const isMenuDisabled = globalScene.disableMenu;
// starting tutorial, disable menu
globalScene.disableMenu = true;
if (handler instanceof AwaitableUiHandler) {
handler.tutorialActive = true;
}
await showTutorialOverlay(handler);
await tutorialHandlers[tutorial]();
await hideTutorialOverlay(handler);
// tutorial finished and overlay gone, re-enable menu, save tutorial as seen
globalScene.disableMenu = isMenuDisabled;
globalScene.gameData.saveTutorialFlag(tutorial, true);
if (handler instanceof AwaitableUiHandler) {
handler.tutorialActive = false;
}
return true;
}
/**
* Show the tutorial overlay if there is one
* @param handler the current UiHandler
* @returns `true` once the overlay has finished appearing, or if there is no overlay
*/
async function showTutorialOverlay(handler: UiHandler) {
if (handler instanceof AwaitableUiHandler && handler.tutorialOverlay) {
globalScene.tweens.add({
targets: handler.tutorialOverlay,
alpha: 0.6,
duration: 750,
ease: "Sine.easeOut",
onComplete: () => {
return true;
},
});
} else {
return true;
}
}
/**
* Hide the tutorial overlay if there is one
* @param handler the current UiHandler
* @returns `true` once the overlay has finished disappearing, or if there is no overlay
*/
async function hideTutorialOverlay(handler: UiHandler) {
if (handler instanceof AwaitableUiHandler && handler.tutorialOverlay) {
globalScene.tweens.add({
targets: handler.tutorialOverlay,
alpha: 0,
duration: 500,
ease: "Sine.easeOut",
onComplete: () => {
return true;
},
});
} else {
return true;
}
}