summaryrefslogtreecommitdiff
path: root/resources
diff options
context:
space:
mode:
authorDaniel Weipert <code@drogueronin.de>2023-08-26 20:46:22 +0200
committerDaniel Weipert <code@drogueronin.de>2023-08-26 20:46:22 +0200
commit36a5d5862c3744f899fe6a5712f81171af144795 (patch)
treeba3c4782ca2da1bdd6b9271371b3bab87f2816a8 /resources
parentb7db43abcaf8c9d9ccb4bcaff07c5416cb21ff62 (diff)
evolution items and shop interface
Diffstat (limited to 'resources')
-rw-r--r--resources/css/town.css2
-rw-r--r--resources/js/classes/State.js4
-rw-r--r--resources/js/definitions.js1
-rw-r--r--resources/js/game.js59
-rw-r--r--resources/js/main.js2
-rw-r--r--resources/js/memory.js7
-rw-r--r--resources/js/ui.js60
7 files changed, 103 insertions, 32 deletions
diff --git a/resources/css/town.css b/resources/css/town.css
index 832c3d8..75a95d0 100644
--- a/resources/css/town.css
+++ b/resources/css/town.css
@@ -12,7 +12,9 @@
.shop {
padding: 1rem;
+}
+.shop__items {
display: grid;
grid-gap: 1rem;
}
diff --git a/resources/js/classes/State.js b/resources/js/classes/State.js
index 417c685..e4820d3 100644
--- a/resources/js/classes/State.js
+++ b/resources/js/classes/State.js
@@ -70,7 +70,7 @@ class State {
activeTechnique = null;
/**
- * @type {InventoryItem}
+ * @type {ItemSlug}
*/
- activeBall = null;
+ activeBall = '';
};
diff --git a/resources/js/definitions.js b/resources/js/definitions.js
index d399a3c..f39025d 100644
--- a/resources/js/definitions.js
+++ b/resources/js/definitions.js
@@ -1,6 +1,7 @@
/**
* @typedef {string} MonsterSlug
* @typedef {string} TechniqueSlug
+ * @typedef {string} ItemSlug
* @typedef {string} AreaSlug
*/
diff --git a/resources/js/game.js b/resources/js/game.js
index b628553..c64d744 100644
--- a/resources/js/game.js
+++ b/resources/js/game.js
@@ -146,7 +146,10 @@ const Game = {
// whole party defeated
if (!Memory.state.player.monsters.some((monster) => monster.hp > 0)) {
Memory.state.Game.isInBattle = false;
- Memory.state.currentArea.monsterProgress = 0;
+
+ if (Memory.state.currentArea.monsterProgress < Memory.state.currentArea.requiredEncounters) {
+ Memory.state.currentArea.monsterProgress = 0;
+ }
// go to last visited town
await Game.goToArea(Memory.state.lastVisitedTown);
@@ -769,6 +772,7 @@ const Game = {
for (const itemConditionCode of item.conditions) {
const itemCondition = new ItemCondition(itemConditionCode);
let conditionIsApplicable = true;
+ console.log(monster.evolutions);
if (itemCondition.what === 'current_hp') {
const value = parseInt(itemCondition.value) * monster.stats.hp;
@@ -787,6 +791,15 @@ const Game = {
conditionIsApplicable = Memory.state.opponent.activeMonster.category === 'threat';
}
+ else if (itemCondition.what === 'level') {
+ const value = parseInt(itemCondition.value);
+ conditionIsApplicable = eval(`${monster.level} ${itemCondition.comparator} ${value}`);
+ }
+
+ else if (itemCondition.what === 'has_path') {
+ conditionIsApplicable = monster.evolutions.some((evolution) => evolution.path === 'item' && evolution.item === item.slug)
+ }
+
else {
conditionIsApplicable = false;
}
@@ -806,48 +819,68 @@ const Game = {
* @param {Monster}
*/
async useItem (item, monster) {
+ let useLowersQuantity = false;
+
for (const itemEffectCode of item.effects) {
const itemEffect = new ItemEffect(itemEffectCode);
if (itemEffect.type === 'heal') {
monster.hp += itemEffect.amount;
- item.quantity--;
+ useLowersQuantity = true;
UI.drawActiveMonster();
}
if (itemEffect.type === 'revive') {
monster.hp = itemEffect.amount;
monster.statusEffect = null;
- item.quantity--;
+ useLowersQuantity = true;
UI.drawActiveMonster();
}
else if (itemEffect.type === 'capture') {
- Memory.state.activeBall = item;
+ Memory.state.activeBall = item.slug;
UI.drawActiveBall();
}
else if (itemEffect.type === 'evolve') {
- const evolution = Memory.state.player.activeMonster.getPossibleEvolutions('item')[0];
+ const evolution = monster.evolutions.find((evolution) => evolution.path === 'item' && evolution.item === item.slug);
if (evolution) {
await fetchMonster(evolution.monster_slug);
- Memory.state.player.activeMonster.evolve(evolution);
+ monster.evolve(evolution);
UI.drawActiveMonster();
- item.quantity--;
+ useLowersQuantity = true;
}
}
}
+ // decrease quantity
+ if (useLowersQuantity) {
+ item.quantity--;
+
+ // remove from inventory
+ if (item.quantity === 0) {
+ Game.removeItemFromInventory(Memory.state.player.inventory, item.slug);
+ }
+ }
+
Memory.saveToLocalStorage();
},
/**
- * @param {Array} inventory
- * @param {InventoryItem} item
+ * @param {InventoryItem[]} inventory
+ * @param {ItemSlug} itemSlug
+ */
+ getItemFromInventory (inventory, itemSlug) {
+ return inventory.find((inventoryItem) => inventoryItem.slug === itemSlug);
+ },
+
+ /**
+ * @param {InventoryItem[]} inventory
+ * @param {ItemSlug} itemSlug
*/
- removeItemFromInventory (inventory, item) {
- inventory.splice(inventory.indexOf(item), 1);
+ removeItemFromInventory (inventory, itemSlug) {
+ inventory.splice(inventory.findIndex((inventoryItem) => inventoryItem.slug === itemSlug), 1);
},
@@ -867,13 +900,13 @@ const Game = {
const playerMonster = Memory.state.player.activeMonster;
const opposingMonster = Memory.state.opponent.activeMonster;
- const activeBall = Memory.state.activeBall;
+ const activeBall = Game.getItemFromInventory(Memory.state.player.inventory, Memory.state.activeBall);
// remove ball
activeBall.quantity--;
if (activeBall.quantity === 0) {
Game.removeItemFromInventory(Memory.state.player.inventory, Memory.state.activeBall);
- Memory.state.activeBall = null;
+ Memory.state.activeBall = '';
UI.drawActiveBall();
}
diff --git a/resources/js/main.js b/resources/js/main.js
index 662dff6..ff570ad 100644
--- a/resources/js/main.js
+++ b/resources/js/main.js
@@ -36,7 +36,7 @@ UI.createEventListener(async function () {
await Memory.state.player.initialize();
Game.setActivePlayerMonster(Memory.state.player.monsters[0]);
- Memory.state.activeBall = Memory.state.player.inventory[0]; // tuxeball
+ Memory.state.activeBall = 'tuxeball';
// set rival monster
possibleStarterMonsters.splice(possibleStarterMonsters.indexOf(event.detail.monster), 1);
diff --git a/resources/js/memory.js b/resources/js/memory.js
index 35da905..6450136 100644
--- a/resources/js/memory.js
+++ b/resources/js/memory.js
@@ -212,7 +212,12 @@ const Memory = {
Memory.state.opponent.activeMonster = Memory.state.opponent.monsters[loadedState.opponent.activeMonsterIdx];
Memory.state.rivalMonster = loadedState.rivalMonster;
Memory.state.activeTechnique = await loadTechnique(loadedState.activeTechnique);
- Memory.state.activeBall = await loadInventoryItem(loadedState.activeBall);
+
+ if (Memory.state.activeBall instanceof String) { // backwards compat: TODO: remove check later
+ Memory.state.activeBall = loadedState.activeBall;
+ } else {
+ Memory.state.activeBall = loadedState.activeBall && loadedState.activeBall.slug;
+ }
// draw game
if (!Game.isTown(Memory.state.currentArea)) {
diff --git a/resources/js/ui.js b/resources/js/ui.js
index 006e6fc..dd287df 100644
--- a/resources/js/ui.js
+++ b/resources/js/ui.js
@@ -691,6 +691,8 @@ const UI = {
/* Map */
+ shopSelectionMode: 'buy',
+
/**
* @returns {HTMLElement}
*/
@@ -785,26 +787,49 @@ const UI = {
itemNode.querySelector('[data-template-slot="price"]').innerHTML = formatPrice(price);
itemNode.addEventListener('click', () => {
- if (Memory.state.money < price) {
- alert(`Not enough ${DB.currencies.map[Memory.state.Settings.currency].symbol}.`);
- return;
- }
+ if (UI.shopSelectionMode === 'buy') {
- Memory.state.money -= price;
+ if (Memory.state.money < price) {
+ alert(`Not enough ${DB.currencies.map[Memory.state.Settings.currency].symbol}.`);
+ return;
+ }
- const itemInInventory = Memory.state.player.inventory.find((inventoryItem) => inventoryItem.slug === item.slug);
- if (itemInInventory) {
- itemInInventory.quantity++;
- } else {
- Memory.state.player.inventory.push(new InventoryItem(item, 1));
+ Memory.state.money -= price;
+
+ const itemInInventory = Memory.state.player.inventory.find((inventoryItem) => inventoryItem.slug === item.slug);
+ if (itemInInventory) {
+ itemInInventory.quantity++;
+ } else {
+ Memory.state.player.inventory.push(new InventoryItem(item, 1));
+ }
+
+ UI.drawStatus();
}
- UI.drawStatus();
+ else if (UI.shopSelectionMode === 'info') {
+ UI.openItemInfo(item);
+ }
});
- template.appendChild(itemNode);
+ template.querySelector('[data-template-slot="items"]').appendChild(itemNode);
}
+ const selectionModesNode = template.querySelector('[data-template-slot="modes"]');
+ const selectionModeNodes = selectionModesNode.querySelectorAll('[data-selection-mode]');
+ selectionModeNodes.forEach((node) => {
+ if (node.dataset.selectionMode === UI.shopSelectionMode) {
+ node.setAttribute('selected', true);
+ }
+
+ node.addEventListener('click', () => {
+ selectionModesNode.querySelector(`[data-selection-mode="${UI.shopSelectionMode}"]`).removeAttribute('selected');
+
+ UI.shopSelectionMode = node.dataset.selectionMode;
+
+ node.setAttribute('selected', true);
+ });
+ });
+
popup.querySelector('.popup').appendChild(template);
UI.drawPopup(popup);
},
@@ -1089,7 +1114,7 @@ const UI = {
}
if (Memory.state.activeBall) {
- UI.elements.menuCatch.querySelector('img').src = `/modules/tuxemon/mods/tuxemon/gfx/items/${Memory.state.activeBall.slug}.png`;
+ UI.elements.menuCatch.querySelector('img').src = `/modules/tuxemon/mods/tuxemon/gfx/items/${Memory.state.activeBall}.png`;
} else {
UI.elements.menuCatch.querySelector('img').src = `/modules/tuxemon/mods/tuxemon/gfx/items/tuxeball.png`;
}
@@ -1546,7 +1571,12 @@ const UI = {
else if (item.category === 'capture') {
Game.useItem(item);
}
+
+ else if (item.category === 'booster') {
+ UI.openItemMonsterSelection(item);
+ }
}
+
else if (UI.inventorySelectionMode === 'info') {
UI.openItemInfo(item);
}
@@ -1586,7 +1616,6 @@ const UI = {
await Game.useItem(item, monster);
if (item.quantity === 0) {
- Game.removeItemFromInventory(Memory.state.player.inventory, item);
template.dispatchEvent(new Event('item:isExhausted'));
}
@@ -1639,7 +1668,7 @@ const UI = {
const popup = UI.createPopup();
const template = document.createElement('div');
- template.textContent = item.conditions + ' -- ' + item.effects + ' -- ' + item.description;
+ template.textContent = item.description;
popup.querySelector('.popup').appendChild(template);
@@ -1653,6 +1682,7 @@ const UI = {
const popup = UI.createPopup();
const dialog = UI.createTemplate(Template.dialogSave);
+ Memory.saveToLocalStorage();
const saveData = Memory.saveToString();
dialog.querySelector('[data-template-slot="saveData"]').value = saveData;