summaryrefslogtreecommitdiff
path: root/resources
diff options
context:
space:
mode:
Diffstat (limited to 'resources')
-rw-r--r--resources/css/menu.css4
-rw-r--r--resources/js/classes/Npc.js15
-rw-r--r--resources/js/db.js4
-rw-r--r--resources/js/game.js22
-rw-r--r--resources/js/helpers.js2
-rw-r--r--resources/js/memory.js5
-rw-r--r--resources/js/story.js38
-rw-r--r--resources/js/ui.js7
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'));