diff options
| author | Daniel Weipert <code@drogueronin.de> | 2023-08-31 20:23:06 +0200 | 
|---|---|---|
| committer | Daniel Weipert <code@drogueronin.de> | 2023-08-31 20:23:06 +0200 | 
| commit | c657c77d0cf49afba627b93848e1915e2ce7d3ff (patch) | |
| tree | 5d96a65df277f52558cd5ff84f2fefbf4480a926 /resources | |
| parent | 7f6ab8779bd143b1b5f3465e3681abcbc113d19d (diff) | |
story and npcs
Diffstat (limited to 'resources')
| -rw-r--r-- | resources/css/menu.css | 4 | ||||
| -rw-r--r-- | resources/js/classes/Npc.js | 15 | ||||
| -rw-r--r-- | resources/js/db.js | 4 | ||||
| -rw-r--r-- | resources/js/game.js | 22 | ||||
| -rw-r--r-- | resources/js/helpers.js | 2 | ||||
| -rw-r--r-- | resources/js/memory.js | 5 | ||||
| -rw-r--r-- | resources/js/story.js | 38 | ||||
| -rw-r--r-- | resources/js/ui.js | 7 | 
8 files changed, 71 insertions, 26 deletions
diff --git a/resources/css/menu.css b/resources/css/menu.css index 56e2525..70fc0b8 100644 --- a/resources/css/menu.css +++ b/resources/css/menu.css @@ -386,6 +386,7 @@    border: 2px solid yellow !important;  } +.setting-highlight--map svg [data-interactable],  .setting-highlight--map svg [data-location],  .setting-highlight--map svg [data-area],  .setting-highlight--map svg [data-encounter] { @@ -425,7 +426,8 @@  .story__popup {    padding: 1rem; -  max-width: 300px; +  max-width: 100vw; +  width: 360px;    display: grid;    grid-gap: 1rem; diff --git a/resources/js/classes/Npc.js b/resources/js/classes/Npc.js new file mode 100644 index 0000000..6121bce --- /dev/null +++ b/resources/js/classes/Npc.js @@ -0,0 +1,15 @@ +class Npc { +  name = ''; +  spriteName = ''; + +  constructor (slug) { +    this.slug = slug; + +    this.name = translate(slug) || slugToName(slug.replace('spyder_', '')); +    this.spriteName = DB.npcs[slug]?.template[0].sprite_name; +  } + +  get sprite () { +    return `/modules/tuxemon/mods/tuxemon/gfx/sprites/player/${this.spriteName}.png`; +  } +} diff --git a/resources/js/db.js b/resources/js/db.js index 3c8be05..35ed7bd 100644 --- a/resources/js/db.js +++ b/resources/js/db.js @@ -171,10 +171,10 @@ async function fetchItem (slug) {   */  async function fetchNpc (slug) {    if (! DB.npcs[slug]) { -    DB.npcs[slug] = await fetchDBData(`/modules/tuxemon/mods/tuxemon/db/npc/${slug}.json`).then((response) => response.json()); +    DB.npcs[slug] = await fetchDBData(`/db/_generated/npc/${slug}.json`).then((response) => response.json());    } -  return DB.npcs[slug]; +  return new Npc(slug);  }  /** diff --git a/resources/js/game.js b/resources/js/game.js index fb25ea4..2c6ecc0 100644 --- a/resources/js/game.js +++ b/resources/js/game.js @@ -26,6 +26,7 @@ const Game = {    isProgressingTurn: false,    playerIsChoosingNextMonster: false,    isStoryBattle: false, +  didWinStoryBattle: true,    doBattleAnimation: true,    opponentActionTimeout: null,    didTechniqueHit: false, @@ -127,6 +128,7 @@ const Game = {              UI.showMap();            } +          Game.didWinStoryBattle = true;            Game.isStoryBattle = false;          } else {            await Game.encounterNextTrainerMonster(); @@ -151,6 +153,7 @@ const Game = {        // whole party defeated        if (!Memory.state.player.monsters.some((monster) => monster.hp > 0)) {          Memory.state.Game.isInBattle = false; +        Game.didWinStoryBattle = false;          Game.isStoryBattle = false;          if (Memory.state.currentArea.monsterProgress < Memory.state.currentArea.requiredEncounters) { @@ -161,16 +164,10 @@ const Game = {          await Game.goToArea(Memory.state.lastVisitedTown);          // heal all monsters full -        let totalHealingCenterPrice = 0; -        for (const monster of Memory.state.player.monsters) { -          monster.hp = monster.stats.hp; -          monster.statusEffect = null; - -          // pay healing center -          const healingCenterPrice = Object.values(Memory.state.currentArea.locations).find((location) => location.type === 'healingCenter').price; -          totalHealingCenterPrice += healingCenterPrice; -        } +        Game.healParty(); +        const healingCenterPrice = Object.values(Memory.state.currentArea.locations).find((location) => location.type === 'healingCenter').price; +        const totalHealingCenterPrice = healingCenterPrice * Memory.state.player.monsters.length;          Memory.state.money -= totalHealingCenterPrice;          Game.addPhaseEvent('postTurnEnd', () => { @@ -1006,6 +1003,13 @@ const Game = {      monster.evolve(monster.evolutions[0]);    }, +  healParty () { +    for (const monster of Memory.state.player.monsters) { +      monster.hp = monster.stats.hp; +      monster.statusEffect = null; +    } +  }, +    /**     * @param {string} type     * diff --git a/resources/js/helpers.js b/resources/js/helpers.js index bceaf5e..aa149b1 100644 --- a/resources/js/helpers.js +++ b/resources/js/helpers.js @@ -19,7 +19,7 @@ function slugToName (slug) {   * @returns {string}   */  function nl2br (text) { -  return text.replace(new RegExp(/\\n/g), '<br>'); +  return text.replace(new RegExp(/\\n/g), '<br><br>');  }  /** diff --git a/resources/js/memory.js b/resources/js/memory.js index f8d8a82..47608da 100644 --- a/resources/js/memory.js +++ b/resources/js/memory.js @@ -251,12 +251,11 @@ const Memory = {          UI.drawArea();          UI.drawStatus();        }, - - -      async () => Story.progress(Memory.state.currentStory),      ];      await UI.showLoading(loadActions); + +    await Story.progress(Memory.state.currentStory)    },    /** diff --git a/resources/js/story.js b/resources/js/story.js index bdec2e1..1901829 100644 --- a/resources/js/story.js +++ b/resources/js/story.js @@ -10,10 +10,14 @@ const Story = {        }));      }); -    await Story.progress('introduction'); +    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', @@ -37,7 +41,7 @@ const Story = {          event.detail.popup.remove(); -        await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_dante'), text: translate('spyder_intro_shopkeeper4', true) }); +        await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('tuxemart-keeper'), text: translate('spyder_intro_shopkeeper4', true) });          // set rival monster          Memory.state.rivalMonster = event.detail.monster.slug; @@ -55,6 +59,7 @@ const Story = {    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( @@ -93,7 +98,7 @@ const Story = {        }));      }); -    await Story.progress('battleRivalOne'); +    await Story.immediateProgress('selectStarterMonster', 'battleRivalOne');    },    async battleRivalOne () { @@ -102,9 +107,18 @@ const Story = {      Memory.state.opponent = new Trainer({ monsters: [ rivalMonster ] });      await Memory.state.opponent.initialize(); -    await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_rivalbillie'), text: translate('spyder_papertown_firstfight', true) }); +    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();    }, @@ -112,8 +126,6 @@ const Story = {    /**     * @param {string} slug -   * -   * @returns {Promise<any>}     */    async progress (slug) {      if (!Story[slug]) { @@ -131,8 +143,16 @@ const Story = {    },    /** -   * @returns {Promise<any>} +   * @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); @@ -152,6 +172,10 @@ const Story = {        }, 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; diff --git a/resources/js/ui.js b/resources/js/ui.js index 6884e14..e5afb53 100644 --- a/resources/js/ui.js +++ b/resources/js/ui.js @@ -556,7 +556,8 @@ const UI = {    },    drawBattle () { -    UI.elements.battle.style.backgroundImage = `url(/modules/tuxemon/mods/tuxemon/gfx/ui/combat/${Memory.state.currentArea.environment.battle_graphics.background})`; +    UI.elements.battle.style.backgroundImage = `url(${Memory.state.currentArea.environment.battle_graphics.background})`; +    UI.elements.battle.style.backgroundPosition = `${Memory.state.currentArea.environment.battle_graphics.background_position || 'top'}`;      UI.showBattle();      UI.drawOpponentMonster(); @@ -1945,8 +1946,8 @@ const UI = {    applyStoryPopupContent (popup, { speaker, text }) {      const template = UI.createTemplate(Template.storyPopup); -    template.querySelector('[data-template-slot="speaker.sprite"]').src = `/modules/tuxemon/mods/tuxemon/gfx/sprites/player/${speaker.template[0].sprite_name}.png`; -    template.querySelector('[data-template-slot="speaker.name"]').textContent = slugToName(speaker.slug.replace('spyder_', '')); +    template.querySelector('[data-template-slot="speaker.sprite"]').src = speaker.sprite; +    template.querySelector('[data-template-slot="speaker.name"]').textContent = speaker.name;      template.querySelector('[data-template-slot="text"]').innerHTML = nl2br(text);      template.querySelector('[data-template-slot="next"]').addEventListener('click', UI.wrapCallback(() => {        popup.dispatchEvent(new Event('next'));  | 
