summaryrefslogtreecommitdiff
path: root/resources/js/story.js
diff options
context:
space:
mode:
Diffstat (limited to 'resources/js/story.js')
-rw-r--r--resources/js/story.js163
1 files changed, 163 insertions, 0 deletions
diff --git a/resources/js/story.js b/resources/js/story.js
new file mode 100644
index 0000000..c5f7add
--- /dev/null
+++ b/resources/js/story.js
@@ -0,0 +1,163 @@
+const Story = {
+ async start () {
+ const settingsPopup = UI.createPopup();
+ settingsPopup.querySelector('[data-template-slot="content"]').append(UI.createSettingsMenu());
+ UI.drawPopup(settingsPopup);
+
+ await new Promise((resolve) => {
+ settingsPopup.addEventListener('close', UI.wrapCallback(async () => {
+ resolve();
+ }));
+ });
+
+ await Story.progress('introduction');
+ },
+
+ async introduction () {
+ const possibleStarterMonsters = await Promise.all(
+ [
+ 'budaye',
+ 'dollfin',
+ 'grintot',
+ 'ignibus',
+ 'memnomnom',
+ ].map(async (monsterSlug) => await fetchMonster(monsterSlug))
+ );
+
+ const monsterSelection = UI.openStarterMonsterSelection(possibleStarterMonsters, { title: translate('story:introduction:monster_selection:title', true) });
+ await new Promise((resolve) => {
+ monsterSelection.addEventListener('starter:monster:selected', UI.wrapCallback(async (event) => {
+ if (!confirm(`Select ${event.detail.monster.name}?`)) {
+ return;
+ }
+
+ event.detail.popup.remove();
+
+ await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_dante'), text: translate('spyder_intro_shopkeeper4', true) });
+
+ // set rival monster
+ Memory.state.rivalMonster = event.detail.monster.slug;
+
+ // initialize state variables
+ Memory.state.money = 250;
+
+ Memory.state.opponent = new Trainer({ monsters: [] });
+ await Memory.state.opponent.initialize();
+
+ Memory.state.player = new Trainer({ monsters: [] });
+ await Memory.state.player.initialize();
+
+ // go to starting area
+ await Game.goToArea('paper-town');
+
+ resolve();
+ }));
+ });
+ },
+
+ async selectStarterMonster () {
+ await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_dante'), text: translate('spyder_papertown_myfirstmon_notmet', true) });
+ await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_dante'), text: translate('spyder_papertown_myfirstmon2', true) });
+
+ const possibleStarterMonsters = await Promise.all(
+ [
+ 'tweesher',
+ 'lambert',
+ 'nut',
+ 'agnite',
+ 'rockitten',
+ ].map(async (monsterSlug) => await fetchMonster(monsterSlug))
+ );
+
+ const monsterSelection = UI.openStarterMonsterSelection(possibleStarterMonsters, { title: translate('story:select_starter_monster:monster_selection:title', true) });
+ await new Promise((resolve) => {
+ monsterSelection.addEventListener('starter:monster:selected', UI.wrapCallback(async (event) => {
+ if (!confirm(`Select ${event.detail.monster.name}?`)) {
+ return;
+ }
+
+ Memory.state.player = new Trainer({
+ monsters: [
+ event.detail.monster,
+ ]
+ });
+ await Memory.state.player.initialize();
+
+ Game.setActivePlayerMonster(Memory.state.player.monsters[0]);
+
+ // go to starting area
+ await Game.goToArea('paper-town');
+
+ UI.drawActiveMonster();
+ UI.drawActiveTechniques();
+
+ event.detail.popup.remove();
+
+ resolve();
+ }));
+ });
+
+ await Story.progress('battleRivalOne');
+ },
+
+ async battleRivalOne () {
+ Memory.state.opponent = new Trainer({ monsters: [ await fetchMonster(Memory.state.rivalMonster) ] });
+ await Memory.state.opponent.initialize();
+
+ await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_rivalbillie'), text: translate('spyder_papertown_firstfight', true) });
+
+ await Story.battle();
+ },
+
+
+ // Helper
+
+ /**
+ * @param {string} slug
+ *
+ * @returns {Promise<any>}
+ */
+ async progress (slug) {
+ if (!Story[slug]) {
+ return;
+ }
+
+ Memory.state.currentStory = slug;
+ Memory.saveToLocalStorage();
+
+ await Story[slug]();
+
+ Memory.state.storyProgress[slug] = true;
+ Memory.state.currentStory = null;
+ Memory.saveToLocalStorage();
+ },
+
+ /**
+ * @returns {Promise<any>}
+ */
+ async battle () {
+ const previousArea = Object.assign({}, Memory.state.currentArea);
+
+ Game.isStoryBattle = true;
+ Memory.state.Game.isInBattle = true;
+ Memory.saveToLocalStorage();
+
+ UI.drawBattle();
+ UI.showBattle();
+
+ await new Promise((resolve) => {
+ const interval = setInterval(() => {
+ if (!Game.isStoryBattle) {
+ clearInterval(interval);
+ resolve();
+ }
+ }, 100);
+ });
+
+ if (previousArea.slug === Memory.state.currentArea.slug) {
+ Memory.state.currentArea.trainerProgress = previousArea.trainerProgress;
+
+ UI.drawStatus();
+ }
+ },
+};