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.immediateProgress('start', 'introduction'); }, async introduction () { await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('omnichannel-ceo'), text: translate('spyder_intro00', true) }); await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('omnichannel-ceo'), text: translate('spyder_intro01', true) }); await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('tuxemart-keeper'), text: translate('spyder_intro_shopkeeper1', true) }); const possibleStarterMonsters = await Promise.all( [ 'budaye', 'dollfin', 'grintot', 'ignibus', 'memnomnom', ].map(async (monsterSlug) => { const monster = await fetchMonster(monsterSlug); monster.level = 5; return monster; }) ); 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('tuxemart-keeper'), text: translate('spyder_intro_shopkeeper4', true) }); // set rival monster Memory.state.rivalMonster = event.detail.monster.slug; // set initial values Memory.state.money = 250; // 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_myfirstmon1', 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) => { const monster = await fetchMonster(monsterSlug); monster.level = 5; return monster; }) ); 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.monsters.push(event.detail.monster); Game.setActivePlayerMonster(event.detail.monster); // go to starting area await Game.goToArea('paper-town'); UI.drawActiveMonster(); UI.drawActiveTechniques(); event.detail.popup.remove(); resolve(); })); }); await Story.immediateProgress('selectStarterMonster', 'battleRivalOne'); }, async battleRivalOne () { const rivalMonster = await fetchMonster(Memory.state.rivalMonster); rivalMonster.level = 5; Memory.state.opponent = new Trainer({ monsters: [ rivalMonster ] }); await Memory.state.opponent.initialize(); await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_billie'), text: translate('spyder_papertown_firstfight', true) }); await Story.battle(); if (Game.didWinStoryBattle) { await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_billie'), text: translate('spyder_papertown_firstfight_win', true) }); } else { await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_billie'), text: translate('spyder_papertown_firstfight_lose', true) }); } await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_billie'), text: translate('spyder_papertown_firstfight_after', true) }); Game.healParty(); }, // Helper /** * @param {string} slug */ 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(); }, /** * @param {string} fromSlug * @param {string} toSlug */ async immediateProgress (fromSlug, toSlug) { Memory.state.storyProgress[fromSlug] = true; Memory.saveToLocalStorage(); await Story.progress(toSlug); }, 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); }); // reset incremented trainer progress if (Memory.state.areaProgress[previousArea.slug]) { Memory.state.areaProgress[previousArea.slug].trainerProgress = previousArea.trainerProgress; } if (previousArea.slug === Memory.state.currentArea.slug) { Memory.state.currentArea.trainerProgress = previousArea.trainerProgress; UI.drawStatus(); } }, };