diff options
author | Daniel Weipert <code@drogueronin.de> | 2023-08-22 15:01:03 +0200 |
---|---|---|
committer | Daniel Weipert <code@drogueronin.de> | 2023-08-22 15:01:03 +0200 |
commit | c0354b250f84d578b609a7f25d71dee7fc24e9ca (patch) | |
tree | af586e0a4c44a2f2c8df956ca3b992be15daaba3 | |
parent | 54e5ffaeb79f989463c144e58dfcd677b752c5a9 (diff) |
currency, save/load
-rw-r--r-- | db/_generated/currencies.json | 1 | ||||
-rw-r--r-- | db/currencies/currencies.php | 42 | ||||
-rw-r--r-- | index.html | 8 | ||||
-rw-r--r-- | resources/js/classes/State.js | 2 | ||||
-rw-r--r-- | resources/js/classes/Trainer.js | 3 | ||||
-rw-r--r-- | resources/js/db.js | 6 | ||||
-rw-r--r-- | resources/js/formula.js | 14 | ||||
-rw-r--r-- | resources/js/game.js | 130 | ||||
-rw-r--r-- | resources/js/memory.js | 38 | ||||
-rw-r--r-- | resources/js/ui.js | 49 |
10 files changed, 239 insertions, 54 deletions
diff --git a/db/_generated/currencies.json b/db/_generated/currencies.json new file mode 100644 index 0000000..d3dc796 --- /dev/null +++ b/db/_generated/currencies.json @@ -0,0 +1 @@ +{"last_updated":"2023-08-21","map":{"AUD":{"rate":1.6995,"symbol":"$","name":"Australian Dollar","decimals":2},"BGN":{"rate":1.9558,"symbol":"\u043b\u0432","name":"Bulgarian Lev","decimals":2},"BRL":{"rate":5.414,"symbol":"R$","name":"Brazilian Real","decimals":2},"CAD":{"rate":1.4723,"symbol":"$","name":"Canadian Dollar","decimals":2},"CHF":{"rate":0.9588,"symbol":"CHF","name":"Swiss Franc","decimals":2},"CNY":{"rate":7.9456,"symbol":"\u00a5","name":"Chinese Yuan","decimals":2},"CZK":{"rate":24.02,"symbol":"K\u010d","name":"Czech Republic Koruna","decimals":2},"DKK":{"rate":7.4524,"symbol":"kr","name":"Danish Krone","decimals":2},"GBP":{"rate":0.85475,"symbol":"\u00a3","name":"British Pound Sterling","decimals":2},"HKD":{"rate":8.5488,"symbol":"$","name":"Hong Kong Dollar","decimals":2},"HUF":{"rate":381.73,"symbol":"Ft","name":"Hungarian Forint","decimals":2},"IDR":{"rate":16718,"symbol":"Rp","name":"Indonesian Rupiah","decimals":2},"ILS":{"rate":4.1395,"symbol":"\u20aa","name":"Israeli New Sheqel","decimals":2},"INR":{"rate":90.66,"symbol":"\u20b9","name":"Indian Rupee","decimals":2},"ISK":{"rate":143.7,"symbol":"kr","name":"Icelandic Kr\u00f3na","decimals":2},"JPY":{"rate":159.15,"symbol":"\u00a5","name":"Japanese Yen","decimals":0},"KRW":{"rate":1460.32,"symbol":"\u20a9","name":"South Korean Won","decimals":2},"MXN":{"rate":18.5927,"symbol":"$","name":"Mexican Peso","decimals":2},"MYR":{"rate":5.0706,"symbol":"RM","name":"Malaysian Ringgit","decimals":2},"NOK":{"rate":11.5205,"symbol":"kr","name":"Norwegian Krone","decimals":2},"NZD":{"rate":1.8407,"symbol":"$","name":"New Zealand Dollar","decimals":2},"PHP":{"rate":61.543,"symbol":"\u20b1","name":"Philippine Peso","decimals":2},"PLN":{"rate":4.4785,"symbol":"z\u0142","name":"Polish Zloty","decimals":2},"RON":{"rate":4.9406,"symbol":"lei","name":"Romanian Leu","decimals":2},"SEK":{"rate":11.9095,"symbol":"kr","name":"Swedish Krona","decimals":2},"SGD":{"rate":1.4791,"symbol":"S$","name":"Singapore Dollar","decimals":2},"THB":{"rate":38.314,"symbol":"\u0e3f","name":"Thai Baht","decimals":2},"TRY":{"rate":29.63,"symbol":"\u20ba","name":"Turkish Lira","decimals":2},"USD":{"rate":1.0908,"symbol":"$","name":"United States Dollar","decimals":2},"ZAR":{"rate":20.676,"symbol":"R","name":"South African Rand","decimals":2},"EUR":{"rate":1,"symbol":"\u20ac","name":"Euro","decimals":2}}}
\ No newline at end of file diff --git a/db/currencies/currencies.php b/db/currencies/currencies.php new file mode 100644 index 0000000..7c8b2ac --- /dev/null +++ b/db/currencies/currencies.php @@ -0,0 +1,42 @@ +<?php + +$currencySymbols = []; +$handle = fopen('https://raw.githubusercontent.com/bengourley/currency-symbol-map/master/map.js', 'r'); +while ($line = fgets($handle)) { + preg_match("/(\w+): '(.+)'/", $line, $match); + + if (isset($match[1])) { + $currencySymbols[$match[1]] = $match[2]; + } +} + +$currencyNames = json_decode(file_get_contents('https://openexchangerates.org/api/currencies.json'), true); + +$decimals = [ + 'JPY' => 0, +]; + +$currencies = []; +$apiResponse = json_decode(file_get_contents('https://api.frankfurter.app/latest?base=eur'), true); +$currencies['last_updated'] = $apiResponse['date']; +foreach ($apiResponse['rates'] as $code => $rate) { + $currencies['map'][$code] = [ + 'rate' => $rate, + 'symbol' => $currencySymbols[$code], + 'name' => $currencyNames[$code], + 'decimals' => $decimals[$code] ?? 2, + ]; +} + +// add EUR +$currencies['map']['EUR'] = [ + 'rate' => 1, + 'symbol' => $currencySymbols['EUR'], + 'name' => $currencyNames['EUR'], + 'decimals' => 2, +]; + +file_put_contents( + dirname(__DIR__) . '/_generated/currencies.json', + json_encode($currencies) +); @@ -285,6 +285,14 @@ Language <select data-template-slot="language"></select> </label> + + <br><br> + + <label> + Currency + <select data-template-slot="currency"></select> + <div>Last Updated: <span data-template-slot="currency.lastUpdated"></span></div> + </label> </div> </template> diff --git a/resources/js/classes/State.js b/resources/js/classes/State.js index b7e9f5d..9a72a8f 100644 --- a/resources/js/classes/State.js +++ b/resources/js/classes/State.js @@ -5,6 +5,8 @@ class State { */ language: 'en_US', + currency: 'EUR', + colors: { player: '#00ff00', player: '#ff0000', diff --git a/resources/js/classes/Trainer.js b/resources/js/classes/Trainer.js index d63e52d..4f083dc 100644 --- a/resources/js/classes/Trainer.js +++ b/resources/js/classes/Trainer.js @@ -31,7 +31,8 @@ class Trainer { */ constructor (trainerData) { this.#monsters = trainerData.monsters; - this.#inventory = trainerData.inventory || []; + this.#inventory = trainerData.inventory || this.inventory; + this.type = trainerData.type || this.type; this.name = trainerData.name; this.sprite = trainerData.sprite; } diff --git a/resources/js/db.js b/resources/js/db.js index 5850a01..ede65aa 100644 --- a/resources/js/db.js +++ b/resources/js/db.js @@ -68,9 +68,11 @@ const DB = { */ items: {}, + areas: {}, + translations: {}, - areas: {}, + currencies : {}, }; async function initializeDB () { @@ -85,6 +87,8 @@ async function initializeDB () { } await fetchTranslation(Memory.state.Settings.language); + + DB.currencies = await fetch('/db/_generated/currencies.json').then((response) => response.json()); } /** diff --git a/resources/js/formula.js b/resources/js/formula.js index 5a3433f..7223cb8 100644 --- a/resources/js/formula.js +++ b/resources/js/formula.js @@ -91,3 +91,17 @@ function calculateAwardedExperience (opposingMonster, participants) { return awardedExperienceDistribution; } + +/** + * @param {Monster} opposingMonster + * + * @returns {number[]} + */ +function calculateAwardedMoney (opposingMonster) { + let money = opposingMonster.level * opposingMonster.moneyModifier; + + const baseDecimalDiff = 2 - DB.currencies.map[Memory.state.Settings.currency].decimals; + money = money * Math.pow(10, baseDecimalDiff); + + return money; +} diff --git a/resources/js/game.js b/resources/js/game.js index d5e8669..5a31c39 100644 --- a/resources/js/game.js +++ b/resources/js/game.js @@ -1,17 +1,21 @@ const Game = { phases: { - preAction: { - opponent: [], - player: [], - }, - action: { - opponent: [], - player: [], - }, - postAction: { - opponent: [], - player: [], + preTurn: [], + battle: { + preAction: { + opponent: [], + player: [], + }, + action: { + opponent: [], + player: [], + }, + postAction: { + opponent: [], + player: [], + }, }, + postTurn: [], }, logMessages: [], @@ -37,26 +41,36 @@ const Game = { Game.logTurn('begin'); // Phases - for (const phaseKey of Object.keys(Game.phases)) { - for (const event of Game.phases[phaseKey].player) { + for (const event of Game.phases.preTurn) { + event(); + } + Game.phases.preTurn = []; + + for (const phaseKey of Object.keys(Game.phases.battle)) { + for (const event of Game.phases.battle[phaseKey].player) { event(); await Game.handleDefeatOpponent(); if (!Game.playerIsChoosingNextMonster) await Game.handleDefeatPlayer(); } - Game.phases[phaseKey].player = []; + Game.phases.battle[phaseKey].player = []; Game.doBattleAnimation = false; - for (const event of Game.phases[phaseKey].opponent) { + for (const event of Game.phases.battle[phaseKey].opponent) { event(); await Game.handleDefeatOpponent(); if (!Game.playerIsChoosingNextMonster) await Game.handleDefeatPlayer(); } Game.doBattleAnimation = true; - Game.phases[phaseKey].opponent = []; + Game.phases.battle[phaseKey].opponent = []; } + for (const event of Game.phases.postTurn) { + event(); + } + Game.phases.postTurn = []; + Game.logTurn('end'); UI.progressTurn(); @@ -67,13 +81,17 @@ const Game = { if (Memory.state.opponent.activeMonster.hp <= 0) { clearTimeout(Game.opponentActionTimeout); Game.opponentActionTimeout = null; - for (const phase of Object.keys(Game.phases)) { - Game.removePhaseEvents(phase, 'opponent'); + for (const phase of Object.keys(Game.phases.battle)) { + Game.removeBattlePhaseEvents(phase, 'opponent'); } - Game.removePhaseEvents('action', 'player'); + Game.removeBattlePhaseEvents('action', 'player'); // money - Memory.state.money += Memory.state.opponent.activeMonster.level * Memory.state.opponent.activeMonster.moneyModifier; + const money = calculateAwardedMoney(Memory.state.opponent.activeMonster); + Memory.state.money += money; + Game.addPhaseEvent('postTurn', () => { + Game.log(`Got ${money} money!`); + }); // exp Memory.state.player.activeMonster.exp += calculateAwardedExperience(Memory.state.opponent.activeMonster, [Memory.state.player.activeMonster])[0]; @@ -109,10 +127,10 @@ const Game = { if (Memory.state.player.activeMonster.hp <= 0) { clearTimeout(Game.opponentActionTimeout); Game.opponentActionTimeout = null; - for (const phase of Object.keys(Game.phases)) { - Game.removePhaseEvents(phase, 'player'); + for (const phase of Object.keys(Game.phases.battle)) { + Game.removeBattlePhaseEvents(phase, 'player'); } - Game.removePhaseEvents('action', 'opponent'); + Game.removeBattlePhaseEvents('action', 'opponent'); // whole party defeated if (!Memory.state.player.monsters.some((monster) => monster.hp > 0)) { @@ -149,15 +167,15 @@ const Game = { }, /** - * @param {Object} phase + * @param {('preAction' | 'action' | 'postAction')} phase * @param {Monster} monster * @param {Function} event */ - addPhaseEvent (phase, monster, event) { + addBattlePhaseEvent (phase, monster, event) { if (monster === Memory.state.player.activeMonster) { - phase.player.push(event); + Game.phases.battle[phase].player.push(event); } else { - phase.opponent.push(event); + Game.phases.battle[phase].opponent.push(event); } }, @@ -165,17 +183,25 @@ const Game = { * @param {('preAction' | 'action' | 'postAction')} phase * @param {('player' | 'opponent')} type */ - removePhaseEvents (phase, type) { - Game.phases[phase][type] = []; + removeBattlePhaseEvents (phase, type) { + Game.phases.battle[phase][type] = []; + }, + + /** + * @param {('preTurn' | 'postTurn')} phase + * @param {Function} event + */ + addPhaseEvent (phase, event) { + Game.phases[phase].push(event); }, clearAllPhaseEvents () { - Game.removePhaseEvents('preAction', 'player'); - Game.removePhaseEvents('preAction', 'opponent'); - Game.removePhaseEvents('action', 'player'); - Game.removePhaseEvents('action', 'opponent'); - Game.removePhaseEvents('postAction', 'player'); - Game.removePhaseEvents('postAction', 'opponent'); + Game.removeBattlePhaseEvents('preAction', 'player'); + Game.removeBattlePhaseEvents('preAction', 'opponent'); + Game.removeBattlePhaseEvents('action', 'player'); + Game.removeBattlePhaseEvents('action', 'opponent'); + Game.removeBattlePhaseEvents('postAction', 'player'); + Game.removeBattlePhaseEvents('postAction', 'opponent'); }, clearCurrentTurn () { @@ -193,7 +219,7 @@ const Game = { let canUse = true; const log = (message, indentation) => { - Game.addPhaseEvent(Game.phases.preAction, user, () => { + Game.addBattlePhaseEvent('preAction', user, () => { Game.log(message, indentation); }); }; @@ -251,7 +277,7 @@ const Game = { async useTechnique (technique, user, target) { technique.use(); - Game.addPhaseEvent(Game.phases.action, user, () => { + Game.addBattlePhaseEvent('action', user, () => { Game.log(`${user.name} is using ${technique.name}!`); }); @@ -262,7 +288,7 @@ const Game = { // damage if (['damage', 'splash', 'area'].includes(techniqueEffect.type)) { - Game.addPhaseEvent(Game.phases.action, user, () => { + Game.addBattlePhaseEvent('action', user, () => { const damage = simpleDamageCalculation(technique, user, target); target.hp -= damage; @@ -281,7 +307,7 @@ const Game = { // money else if (techniqueEffect.type === 'money') { - Game.addPhaseEvent(Game.phases.action, user, () => { + Game.addBattlePhaseEvent('action', user, () => { const money = Math.max(1, Math.floor(Math.random() * target.level)); Memory.state.money += money; @@ -297,7 +323,7 @@ const Game = { // healing else if (techniqueEffect.type === 'healing') { for (const recipient of techniqueEffect.recipients) { - Game.addPhaseEvent(Game.phases.action, user, () => { + Game.addBattlePhaseEvent('action', user, () => { const heal = (user.level + 7) * technique.healingPower; recipient.hp += heal; @@ -324,7 +350,7 @@ const Game = { statusEffect.issuer = user; } - Game.addPhaseEvent(Game.phases.action, user, () => { + Game.addBattlePhaseEvent('action', user, () => { // add status effect const potency = Math.random(); const success = technique.potency >= potency; @@ -355,7 +381,7 @@ const Game = { } if (monster.statusEffect.turnsLeft === 0) { - Game.addPhaseEvent(Game.phases.preAction, monster, () => { + Game.addBattlePhaseEvent('preAction', monster, () => { monster.statusEffect.onRemove && monster.statusEffect.onRemove(); // if still 0 turns left after remove action @@ -379,7 +405,7 @@ const Game = { if (monster.statusEffect.slug === 'poison' || monster.statusEffect.slug === 'burn') { const statusEffectDamage = Math.floor(monster.stats.hp / 8); - Game.addPhaseEvent(Game.phases.postAction, monster, () => { + Game.addBattlePhaseEvent('postAction', monster, () => { monster.hp -= statusEffectDamage; if (Game.doBattleAnimation) { @@ -396,7 +422,7 @@ const Game = { else if (monster.statusEffect.slug === 'lifeleech') { const statusEffectLeech = Math.floor(monster.stats.hp / 16); - Game.addPhaseEvent(Game.phases.postAction, monster, () => { + Game.addBattlePhaseEvent('postAction', monster, () => { // if issuer is defeated => don't if (monster.statusEffect.issuer.hp <= 0) { return; @@ -419,7 +445,7 @@ const Game = { else if (monster.statusEffect.slug === 'recover') { const statusEffectHeal = Math.floor(monster.stats.hp / 16); - Game.addPhaseEvent(Game.phases.postAction, monster, () => { + Game.addBattlePhaseEvent('postAction', monster, () => { monster.hp += statusEffectHeal; if (Game.doBattleAnimation) { @@ -436,7 +462,7 @@ const Game = { else if (monster.statusEffect.slug === 'stuck') { for (const technique of monster.activeTechniques) { if ([TechniqueRange.melee, TechniqueRange.touch].includes(technique.range)) { - Game.addPhaseEvent(Game.phases.preAction, monster, () => { + Game.addBattlePhaseEvent('preAction', monster, () => { technique.potency = technique.stats.potency * 0.5; technique.power = technique.stats.power * 0.5; @@ -454,7 +480,7 @@ const Game = { else if (monster.statusEffect.slug === 'grabbed') { for (const technique of monster.activeTechniques) { if ([TechniqueRange.ranged, TechniqueRange.reach].includes(technique.range)) { - Game.addPhaseEvent(Game.phases.preAction, monster, () => { + Game.addBattlePhaseEvent('preAction', monster, () => { technique.potency = technique.stats.potency * 0.5; technique.power = technique.stats.power * 0.5; @@ -472,7 +498,7 @@ const Game = { else if (monster.statusEffect.slug === 'charging') { const nextStatusEffect = await fetchStatusEffect('chargedup'); - Game.addPhaseEvent(Game.phases.preAction, monster, () => { + Game.addBattlePhaseEvent('preAction', monster, () => { logStatusIs(); }); @@ -489,7 +515,7 @@ const Game = { const statChange = monster.statusEffect.stats[statType]; const modifiedValue = Math.floor(eval(`${monster.stats[statType]} ${statChange.operation} ${statChange.value}`)); - Game.addPhaseEvent(Game.phases.preAction, monster, () => { + Game.addBattlePhaseEvent('preAction', monster, () => { monster.setStatModifier(statType, modifiedValue); logStatusIs(); @@ -501,7 +527,7 @@ const Game = { }; } - Game.addPhaseEvent(Game.phases.postAction, monster, () => { + Game.addBattlePhaseEvent('postAction', monster, () => { monster.statusEffect.turnsLeft--; }); }, @@ -682,6 +708,9 @@ const Game = { 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); @@ -741,6 +770,7 @@ const Game = { if (itemEffect.type === 'heal') { monster.hp += itemEffect.amount; item.quantity--; + UI.drawActiveMonster(); } else if (itemEffect.type === 'capture') { diff --git a/resources/js/memory.js b/resources/js/memory.js index 550ea55..47cde88 100644 --- a/resources/js/memory.js +++ b/resources/js/memory.js @@ -53,6 +53,19 @@ const Memory = { */ async load (saveData) { /** + * @param {Area} areaData + */ + const loadArea = async (areaData) => { + const area = await fetchArea(areaData.slug); + + area.monsterProgress = areaData.monsterProgress; + area.trainerProgress = areaData.trainerProgress; + area.isCompleted = areaData.isCompleted; + + return area; + }; + + /** * @param {Monster} monsterData */ const loadMonster = async (monsterData) => { @@ -116,6 +129,15 @@ const Memory = { }; /** + * @param {Trainer} trainerData + */ + const loadTrainer = async (trainerData) => { + const trainer = new Trainer(trainerData); + + return trainer; + }; + + /** * @param {Technique} techniqueData */ const loadTechnique = async (techniqueData) => { @@ -131,20 +153,34 @@ const Memory = { */ const loadedState = JSON.parse(atob(saveData)); - Memory.state.Settings.language = loadedState.language; + Memory.state.Settings.language = loadedState.Settings.language; await fetchTranslation(Memory.state.Settings.language); + Memory.state.Settings.currency = loadedState.Settings.currency; + Memory.state.Settings.logMaxLength = loadedState.Settings.logMaxLength; + + for (const areaSlug of Object.keys(loadedState.areaProgress)) { + const areaData = loadedState.areaProgress[areaSlug]; + Memory.state.areaProgress[areaSlug] = await loadArea(areaData); + } + Memory.state.currentArea = await loadArea(loadedState.currentArea); Memory.state.turn = loadedState.turn; Memory.state.money = loadedState.money; Memory.state.monsters = await Promise.all(loadedState.monsters.map(async (monsterData) => await loadMonster(monsterData))); + Memory.state.player = await loadTrainer(loadedState.player); Memory.state.player.monsters = await Promise.all(loadedState.player.monsters.map(async (monsterData) => await loadMonster(monsterData))); Memory.state.player.inventory = await Promise.all(loadedState.player.inventory.map(async (itemData) => await loadInventoryItem(itemData))); Memory.state.player.activeMonster = Memory.state.player.monsters[loadedState.player.activeMonsterIdx]; + Memory.state.opponent = await loadTrainer(loadedState.opponent); Memory.state.opponent.monsters = await Promise.all(loadedState.opponent.monsters.map(async (monsterData) => await loadMonster(monsterData))); Memory.state.opponent.inventory = await Promise.all(loadedState.opponent.inventory.map(async (itemData) => await loadInventoryItem(itemData))); 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); + UI.drawArea(Memory.state.currentArea); + UI.drawStatus(); UI.drawOpponentMonster(); UI.drawActiveMonster(); UI.drawActiveTechniques(); diff --git a/resources/js/ui.js b/resources/js/ui.js index bfd9204..92ca313 100644 --- a/resources/js/ui.js +++ b/resources/js/ui.js @@ -684,7 +684,10 @@ const UI = { drawStatus () { const currentArea = Memory.state.currentArea; - UI.elements.status.querySelector('[data-template-slot="money"]').textContent = `${Memory.state.money} €`; + UI.elements.status.querySelector('[data-template-slot="money"]').textContent = + `${Memory.state.money.toFixed(DB.currencies.map[Memory.state.Settings.currency].decimals)}` + + ' ' + + `${DB.currencies.map[Memory.state.Settings.currency].symbol}`; UI.elements.status.querySelector('[data-template-slot="monsterProgress"]').textContent = `${currentArea.monsterProgress} / ${currentArea.requiredEncounters}`; UI.elements.status.querySelector('[data-template-slot="trainerProgress"]').textContent = `${currentArea.trainerProgress} / ${currentArea.trainers.length}`; @@ -943,6 +946,50 @@ const UI = { }); + /* Currency */ + + const currencySelectNode = template.querySelector('[data-template-slot="currency"]'); + const currencyCodeMap = Object.keys(DB.currencies.map).sort((a, b) => { + const nameA = DB.currencies.map[a].name; + const nameB = DB.currencies.map[b].name; + + return nameA > nameB ? 1 : -1; + }); + + for (const currencyCode of currencyCodeMap) { + const currency = DB.currencies.map[currencyCode]; + const currencyOptionNode = document.createElement('option'); + + currencyOptionNode.value = currencyCode, + currencyOptionNode.textContent = `${currency.symbol} - ${currency.name}`; + + if (currencyCode === Memory.state.Settings.currency) { + currencyOptionNode.selected = true; + } + + currencySelectNode.appendChild(currencyOptionNode); + } + + currencySelectNode.addEventListener('change', async () => { + const selected = [...currencySelectNode.children].find((node) => node.selected === true); + const previousCurrencyCode = Memory.state.Settings.currency; + const newCurrencyCode = selected.value; + + Memory.state.Settings.currency = newCurrencyCode; + + // re-calculate money + const previousCurrency = DB.currencies.map[previousCurrencyCode]; + const newCurrency = DB.currencies.map[newCurrencyCode]; + const baseRateMoney = Memory.state.money / previousCurrency.rate; + const exchangedMoney = baseRateMoney * newCurrency.rate; + Memory.state.money = Number(exchangedMoney.toFixed(newCurrency.decimals)); + + UI.drawStatus(); + }); + + template.querySelector('[data-template-slot="currency.lastUpdated"]').textContent = DB.currencies.last_updated; + + popup.querySelector('.popup').appendChild(template); UI.drawPopup(popup); }, |