From 5214cdfbf26bc0bdee5d669a237fb8aefffb78d5 Mon Sep 17 00:00:00 2001 From: Daniel Weipert Date: Wed, 30 Aug 2023 21:35:28 +0200 Subject: story! --- resources/js/story.js | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 resources/js/story.js (limited to 'resources/js/story.js') 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} + */ + 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} + */ + 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(); + } + }, +}; -- cgit v1.2.3