summaryrefslogtreecommitdiff
path: root/resources
diff options
context:
space:
mode:
Diffstat (limited to 'resources')
-rw-r--r--resources/css/page.css4
-rw-r--r--resources/css/town.css3
-rw-r--r--resources/js/classes/Area.js8
-rw-r--r--resources/js/classes/State.js4
-rw-r--r--resources/js/db.js5
-rw-r--r--resources/js/game.js68
-rw-r--r--resources/js/main.js7
-rw-r--r--resources/js/ui.js65
8 files changed, 111 insertions, 53 deletions
diff --git a/resources/css/page.css b/resources/css/page.css
index 813b361..57c46a5 100644
--- a/resources/css/page.css
+++ b/resources/css/page.css
@@ -23,3 +23,7 @@ img {
width: 100vw;
height: 100vh;
}
+
+.hidden {
+ display: none;
+}
diff --git a/resources/css/town.css b/resources/css/town.css
new file mode 100644
index 0000000..4dd8195
--- /dev/null
+++ b/resources/css/town.css
@@ -0,0 +1,3 @@
+#scene__town {
+ background-color: #fff;
+}
diff --git a/resources/js/classes/Area.js b/resources/js/classes/Area.js
index 3451757..b2af3ea 100644
--- a/resources/js/classes/Area.js
+++ b/resources/js/classes/Area.js
@@ -27,11 +27,11 @@ class Area {
return DB.areas[this.slug].environment;
}
- get previousArea () {
- return DB.areas[this.slug].previousArea;
+ get events () {
+ return DB.areas[this.slug].events;
}
- get nextArea () {
- return DB.areas[this.slug].nextArea;
+ get connections () {
+ return DB.areas[this.slug].connections;
}
}
diff --git a/resources/js/classes/State.js b/resources/js/classes/State.js
index 9a72a8f..085d1c7 100644
--- a/resources/js/classes/State.js
+++ b/resources/js/classes/State.js
@@ -51,9 +51,9 @@ class State {
opponent = null;
/**
- * @type {Monster}
+ * @type {MonsterSlug}
*/
- rivalMonster = null;
+ rivalMonster = '';
/**
* @type {Technique}
diff --git a/resources/js/db.js b/resources/js/db.js
index ede65aa..f5cff6c 100644
--- a/resources/js/db.js
+++ b/resources/js/db.js
@@ -165,12 +165,15 @@ async function fetchTranslation (locale) {
* @returns {Promise<Area>}
*/
async function fetchArea (slug) {
+ if (Memory.state.areaProgress[slug]) {
+ return Memory.state.areaProgress[slug];
+ }
+
if (! DB.areas[slug]) {
DB.areas[slug] = await fetch(`/db/_generated/areas/${slug}.json`).then((response) => response.json());
}
const area = new Area(slug);
-
return area;
}
diff --git a/resources/js/game.js b/resources/js/game.js
index 5a31c39..7b40015 100644
--- a/resources/js/game.js
+++ b/resources/js/game.js
@@ -114,7 +114,7 @@ const Game = {
if (Memory.state.currentArea.encounters.length > 0) {
await Game.encounterWildMonster();
} else {
- await Game.progressToNextArea();
+ await Game.encounterTrainer();
}
} else {
await Game.encounterNextTrainerMonster();
@@ -662,12 +662,21 @@ const Game = {
async encounterTrainer () {
Game.clearCurrentTurn();
- const nextTrainer = Memory.state.currentArea.trainers[Memory.state.currentArea.trainerProgress];
+ let nextTrainerIdx = Memory.state.currentArea.trainerProgress;
+ while (nextTrainerIdx > Memory.state.currentArea.trainers.length - 1) {
+ nextTrainerIdx -= Memory.state.currentArea.trainers.length;
+ }
- const trainer = new Trainer(nextTrainer);
+ const nextTrainer = Memory.state.currentArea.trainers[nextTrainerIdx];
if (nextTrainer.name === 'Rival') {
- trainer.monsters.push(Memory.state.rivalMonster);
+ for (const idx in nextTrainer.monsters) {
+ if (nextTrainer.monsters[idx].slug === 'STARTER') {
+ nextTrainer.monsters[idx].slug = Memory.state.rivalMonster;
+ }
+ }
}
+
+ const trainer = new Trainer(nextTrainer);
await trainer.initialize()
Memory.state.opponent = trainer;
@@ -682,40 +691,39 @@ const Game = {
UI.drawOpponentMonster();
},
- async progressToNextArea () {
+ /**
+ * @param {string} areaSlug
+ */
+ async goToArea (areaSlug) {
Game.isLoadingArea = true;
Game.clearCurrentTurn();
- const currentArea = Memory.state.currentArea;
- const nextArea = await fetchArea(currentArea.nextArea);
+ if (Memory.state.currentArea) {
+ Memory.state.areaProgress[Memory.state.currentArea.slug] = Memory.state.currentArea;
+ }
- await Game.jumpToArea(nextArea);
+ Memory.state.currentArea = await fetchArea(areaSlug);
+ UI.drawArea();
- if (nextArea.encounters.length > 0) {
- await Game.encounterWildMonster();
+ if (Game.isTown(Memory.state.currentArea)) {
+ UI.elements.sceneBattle.classList.add('hidden');
+ UI.elements.sceneTown.classList.remove('hidden');
} else {
- await Game.encounterTrainer();
+ UI.elements.sceneTown.classList.add('hidden');
+ UI.elements.sceneBattle.classList.remove('hidden');
+ if (Memory.state.currentArea.encounters.length > 0) {
+ await Game.encounterWildMonster();
+ } else if (Memory.state.currentArea.trainers.length > 0) {
+ await Game.encounterTrainer();
+ }
}
UI.drawStatus();
+ UI.drawActiveBall();
Game.isLoadingArea = false;
},
- /**
- * @param {Area} area
- */
- async jumpToArea (area) {
- Game.clearCurrentTurn();
-
- if (Memory.state.currentArea) {
- Memory.state.areaProgress[Memory.state.currentArea.slug] = Memory.state.currentArea;
- }
- Memory.state.currentArea = area;
-
- UI.drawArea(area);
- },
-
/* Menu - Inventory */
@@ -806,7 +814,7 @@ const Game = {
* @returns {boolean}
*/
canCatchMonster () {
- return Game.isBattleType('monster') && Memory.state.activeBall;
+ return !Game.isTown(Memory.state.currentArea) && Game.isBattleType('monster') && Memory.state.activeBall;
},
async catchMonster () {
@@ -866,6 +874,13 @@ const Game = {
return Memory.state.opponent.type === type;
},
+ /**
+ * @param {Area} area
+ */
+ isTown (area) {
+ return area.encounters.length === 0 && area.trainers.length === 0;
+ },
+
getStageOfDaySimple () {
const hours = (new Date()).getHours();
if (hours >= 6 && hours < 18) {
@@ -878,7 +893,6 @@ const Game = {
// Game click bindings
UI.elements.nextTrainer.addEventListener('click', Game.encounterTrainer);
-UI.elements.nextArea.addEventListener('click', Game.progressToNextArea);
UI.elements.battleOpponent.addEventListener('click', Game.battleClick);
UI.elements.techniques.addEventListener('click', Game.techniqueClick);
UI.elements.menuCatch.addEventListener('click', Game.catchMonster);
diff --git a/resources/js/main.js b/resources/js/main.js
index 4fd9c62..24eafec 100644
--- a/resources/js/main.js
+++ b/resources/js/main.js
@@ -18,12 +18,9 @@
Game.setActivePlayerMonster(Memory.state.player.monsters[0]);
Memory.state.activeBall = Memory.state.player.inventory[0]; // tuxeball
- Memory.state.rivalMonster = await fetchMonster(possibleStarterMonsters[Math.round(Math.random() * (possibleStarterMonsters.length - 1))]);
+ Memory.state.rivalMonster = possibleStarterMonsters[Math.round(Math.random() * (possibleStarterMonsters.length - 1))];
- const area = await fetchArea('paper-town');
- await Game.jumpToArea(area);
- await Game.encounterTrainer();
- UI.drawStatus();
+ await Game.goToArea('paper-town');
UI.drawActiveMonster();
UI.drawActiveTechniques();
diff --git a/resources/js/ui.js b/resources/js/ui.js
index 92ca313..a40550b 100644
--- a/resources/js/ui.js
+++ b/resources/js/ui.js
@@ -34,6 +34,9 @@ const Template = {
const UI = {
elements: {
+ sceneBattle: document.querySelector('#scene__battle'),
+ sceneTown: document.querySelector('#scene__town'),
+
battle: document.querySelector('#battle'),
battleOpponent: document.querySelector('#battle__opponent'),
battleOpponentSprite: null,
@@ -46,7 +49,7 @@ const UI = {
status: document.querySelector('#status'),
nextTrainer: document.querySelector('#status [data-template-slot="nextTrainer"]'),
- nextArea: document.querySelector('#status [data-template-slot="nextArea"]'),
+ changeArea: document.querySelector('#status [data-template-slot="changeArea"]'),
menuParty: document.querySelector('#menu__party'),
menuInventory: document.querySelector('#menu__inventory'),
@@ -489,11 +492,8 @@ const UI = {
UI.elements.log.classList.toggle('log--is-hidden');
},
- /**
- * @param {Area} area
- */
- drawArea (area) {
- UI.elements.battle.style.backgroundImage = `url(/modules/tuxemon/mods/tuxemon/gfx/ui/combat/${area.environment.battle_graphics.background})`;
+ drawArea () {
+ UI.elements.battle.style.backgroundImage = `url(/modules/tuxemon/mods/tuxemon/gfx/ui/combat/${Memory.state.currentArea.environment.battle_graphics.background})`;
},
progressTurn () {
@@ -701,16 +701,52 @@ const UI = {
} else {
nextTrainerButton.disabled = true;
}
+ },
- const nextAreaButton = UI.elements.nextArea;
- if (
- currentArea.monsterProgress >= currentArea.requiredEncounters &&
- currentArea.trainerProgress === currentArea.trainers.length
- ) {
- nextAreaButton.disabled = false;
- } else {
- nextAreaButton.disabled = true;
+ openAreaSelection () {
+ const popup = UI.createPopup();
+ const template = document.createElement('div');
+ const currentArea = Memory.state.currentArea;
+
+ for (const connectionSlug in currentArea.connections) {
+ const connection = currentArea.connections[connectionSlug];
+ const connectionNode = document.createElement('div');
+
+ connectionNode.textContent = slugToName(connectionSlug);
+
+ let canGo = true;
+ for (const condition of connection.conditions) {
+ if (condition === 'encounters') {
+ canGo = canGo && currentArea.monsterProgress >= currentArea.requiredEncounters;
+ }
+
+ else if (condition === 'trainers') {
+ canGo = canGo && currentArea.trainerProgress >= currentArea.trainers.length;
+ }
+
+ else if (condition.startsWith('event.')) {
+ canGo = false;
+ }
+ }
+
+ if (!canGo) {
+ connectionNode.setAttribute('disabled', true);
+ }
+
+ connectionNode.addEventListener('click', () => {
+ if (canGo) {
+ Game.goToArea(connectionSlug);
+ popup.remove();
+ } else {
+ alert("Can\'t go there yet!");
+ }
+ });
+
+ template.appendChild(connectionNode);
}
+
+ popup.querySelector('.popup').appendChild(template);
+ UI.drawPopup(popup);
},
openPartyMenu () {
@@ -1305,6 +1341,7 @@ const UI = {
};
// UI element click bindings
+UI.elements.changeArea.addEventListener('click', UI.openAreaSelection);
UI.elements.menuParty.addEventListener('click', UI.openPartyMenu);
UI.elements.menuInventory.addEventListener('click', UI.openInventoryMenu);
UI.elements.menuLog.addEventListener('click', UI.toggleLog);