From 54e5ffaeb79f989463c144e58dfcd677b752c5a9 Mon Sep 17 00:00:00 2001 From: Daniel Weipert Date: Mon, 21 Aug 2023 22:44:21 +0200 Subject: log actions --- resources/js/classes/State.js | 17 +++++++-- resources/js/db.js | 2 +- resources/js/game.js | 89 +++++++++++++++++++++++++++++++++++++++++-- resources/js/helpers.js | 2 +- resources/js/memory.js | 4 +- resources/js/ui.js | 40 +++++++++++++++++-- 6 files changed, 140 insertions(+), 14 deletions(-) (limited to 'resources/js') diff --git a/resources/js/classes/State.js b/resources/js/classes/State.js index 6180c52..b7e9f5d 100644 --- a/resources/js/classes/State.js +++ b/resources/js/classes/State.js @@ -1,8 +1,17 @@ class State { - /** - * @type {string} - */ - language = 'en_US'; + Settings = { + /** + * @type {string} + */ + language: 'en_US', + + colors: { + player: '#00ff00', + player: '#ff0000', + }, + + logMaxLength: 1000, + }; /** * @type {Object.} diff --git a/resources/js/db.js b/resources/js/db.js index aaf5423..5850a01 100644 --- a/resources/js/db.js +++ b/resources/js/db.js @@ -84,7 +84,7 @@ async function initializeDB () { DB.elements[element] = await fetch(`/modules/tuxemon/mods/tuxemon/db/element/${element}.json`).then((response) => response.json()); } - await fetchTranslation(Memory.state.language); + await fetchTranslation(Memory.state.Settings.language); } /** diff --git a/resources/js/game.js b/resources/js/game.js index fad882b..d5e8669 100644 --- a/resources/js/game.js +++ b/resources/js/game.js @@ -14,6 +14,8 @@ const Game = { }, }, + logMessages: [], + isLoadingArea: false, isProgressingTurn: false, playerIsChoosingNextMonster: false, @@ -32,6 +34,8 @@ const Game = { await Game.applyStatusEffect(Memory.state.opponent.activeMonster); await Game.applyStatusEffect(Memory.state.player.activeMonster); + Game.logTurn('begin'); + // Phases for (const phaseKey of Object.keys(Game.phases)) { for (const event of Game.phases[phaseKey].player) { @@ -53,6 +57,8 @@ const Game = { Game.phases[phaseKey].opponent = []; } + Game.logTurn('end'); + UI.progressTurn(); Game.isProgressingTurn = false; }, @@ -186,6 +192,14 @@ const Game = { async tryUseTechnique (technique, user, target) { let canUse = true; + const log = (message, indentation) => { + Game.addPhaseEvent(Game.phases.preAction, user, () => { + Game.log(message, indentation); + }); + }; + + log(`${user.name} attempts to use ${technique.name}!`); + // recharge if (technique.isRecharging()) { if (Game.doBattleAnimation) { @@ -194,6 +208,8 @@ const Game = { UI.drawActionFeedback(feedbackNode); } + log('But has to recharge!', 1); + canUse = false; } @@ -204,6 +220,8 @@ const Game = { UI.drawActionFeedback(feedbackNode); } + log('But is nodding off!', 1); + canUse = false; } @@ -216,6 +234,8 @@ const Game = { technique.use(); Game.doBattleAnimation && UI.drawDamageMiss(UI.createDamageMiss()); + log('But missed!', 1); + return; } @@ -231,6 +251,10 @@ const Game = { async useTechnique (technique, user, target) { technique.use(); + Game.addPhaseEvent(Game.phases.action, user, () => { + Game.log(`${user.name} is using ${technique.name}!`); + }); + for (const techniqueEffectCode of technique.effects) { const techniqueEffect = new TechniqueEffect(techniqueEffectCode); techniqueEffect.setUser(user); @@ -250,6 +274,8 @@ const Game = { UI.drawDamage(damageNode); UI.drawTechniqueAnimation(technique); } + + Game.log(`Deals ${damage} to ${target.name}!`, 1); }); } @@ -271,7 +297,12 @@ const Game = { // healing else if (techniqueEffect.type === 'healing') { for (const recipient of techniqueEffect.recipients) { - recipient.hp += (user.level + 7) * technique.healingPower; + Game.addPhaseEvent(Game.phases.action, user, () => { + const heal = (user.level + 7) * technique.healingPower; + recipient.hp += heal; + + Game.log(`Heals ${heal}!`, 1); + }); } } @@ -293,7 +324,7 @@ const Game = { statusEffect.issuer = user; } - Game.addPhaseEvent(Game.phases.postAction, user, () => { + Game.addPhaseEvent(Game.phases.action, user, () => { // add status effect const potency = Math.random(); const success = technique.potency >= potency; @@ -304,6 +335,8 @@ const Game = { if (recipient.statusEffect) continue; recipient.statusEffect = statusEffect; + + Game.log(`${techniqueEffect.recipients.map((recipient) => recipient.name).join(', ')} ${techniqueEffect.recipients.length > 1 ? 'are' : 'is'} now ${statusEffect.name}!`, 1); } } }); @@ -327,6 +360,8 @@ const Game = { // if still 0 turns left after remove action if (monster.statusEffect.turnsLeft === 0) { + Game.log(`${monster.name} is not ${monster.statusEffect.name} anymore!`); + monster.statusEffect = null; } else { Game.applyStatusEffect(monster); @@ -336,6 +371,10 @@ const Game = { return; } + const logStatusIs = () => { + Game.log(`${monster.name} is ${monster.statusEffect.name}!`); + } + // poison / burn if (monster.statusEffect.slug === 'poison' || monster.statusEffect.slug === 'burn') { const statusEffectDamage = Math.floor(monster.stats.hp / 8); @@ -348,6 +387,8 @@ const Game = { UI.applyStatusEffectToDamage(damageNode, monster.statusEffect); UI.drawDamage(damageNode); } + + logStatusIs(); }); } @@ -369,6 +410,8 @@ const Game = { UI.applyStatusEffectToDamage(damageNode, monster.statusEffect); UI.drawDamage(damageNode); } + + logStatusIs(); }); } @@ -384,6 +427,8 @@ const Game = { UI.applyStatusEffectToDamage(feedbackNode, monster.statusEffect); UI.drawActionFeedback(feedbackNode); } + + logStatusIs(); }); } @@ -394,6 +439,8 @@ const Game = { Game.addPhaseEvent(Game.phases.preAction, monster, () => { technique.potency = technique.stats.potency * 0.5; technique.power = technique.stats.power * 0.5; + + logStatusIs(); }); monster.statusEffect.onRemove = () => { @@ -410,6 +457,8 @@ const Game = { Game.addPhaseEvent(Game.phases.preAction, monster, () => { technique.potency = technique.stats.potency * 0.5; technique.power = technique.stats.power * 0.5; + + logStatusIs(); }); monster.statusEffect.onRemove = () => { @@ -423,6 +472,10 @@ const Game = { else if (monster.statusEffect.slug === 'charging') { const nextStatusEffect = await fetchStatusEffect('chargedup'); + Game.addPhaseEvent(Game.phases.preAction, monster, () => { + logStatusIs(); + }); + monster.statusEffect.onRemove = () => { monster.statusEffect = nextStatusEffect; }; @@ -438,6 +491,8 @@ const Game = { Game.addPhaseEvent(Game.phases.preAction, monster, () => { monster.setStatModifier(statType, modifiedValue); + + logStatusIs(); }); } @@ -533,6 +588,33 @@ const Game = { })); }, + /** + * @param {string} message + * @param {number} indentation + * @param {string} style + */ + log (message, indentation = 0, style) { + Game.logMessages.push({ + message: message, + indentation: indentation, + style: style, + }); + UI.drawLog(); + }, + + /** + * @param {('begin' | 'end')} + */ + logTurn (state) { + Game.log( + '- '.repeat(8) + `Turn ${Memory.state.turn} · ${slugToName(state)}` + ' -'.repeat(8), + 0, + { + textAlign: 'center', + } + ); + }, + /* Progression */ @@ -718,8 +800,9 @@ const Game = { Memory.state.player.monsters.push(caughtMonster); + Game.log(`Caught ${caughtMonster.name}!`); + await Game.encounterWildMonster(); - await Game.progressTurn(); }, diff --git a/resources/js/helpers.js b/resources/js/helpers.js index 53a5c87..2395878 100644 --- a/resources/js/helpers.js +++ b/resources/js/helpers.js @@ -55,5 +55,5 @@ function randomString () { * @param {string} msgid */ function translate (msgid) { - return DB.translations[Memory.state.language][msgid]; + return DB.translations[Memory.state.Settings.language][msgid]; } diff --git a/resources/js/memory.js b/resources/js/memory.js index 1732472..550ea55 100644 --- a/resources/js/memory.js +++ b/resources/js/memory.js @@ -131,8 +131,8 @@ const Memory = { */ const loadedState = JSON.parse(atob(saveData)); - Memory.state.language = loadedState.language; - await fetchTranslation(Memory.state.language); + Memory.state.Settings.language = loadedState.language; + await fetchTranslation(Memory.state.Settings.language); Memory.state.turn = loadedState.turn; Memory.state.money = loadedState.money; diff --git a/resources/js/ui.js b/resources/js/ui.js index 06e55ed..bfd9204 100644 --- a/resources/js/ui.js +++ b/resources/js/ui.js @@ -42,6 +42,8 @@ const UI = { techniques: document.querySelector('#techniques'), + log: document.querySelector('#log'), + status: document.querySelector('#status'), nextTrainer: document.querySelector('#status [data-template-slot="nextTrainer"]'), nextArea: document.querySelector('#status [data-template-slot="nextArea"]'), @@ -49,6 +51,7 @@ const UI = { menuParty: document.querySelector('#menu__party'), menuInventory: document.querySelector('#menu__inventory'), menuCatch: document.querySelector('#menu__catch'), + menuLog: document.querySelector('#menu__log'), menuJournal: document.querySelector('#menu__journal'), menuSettings: document.querySelector('#menu__settings'), }, @@ -299,10 +302,12 @@ const UI = { if (Game.isBattleType('trainer')) { battleMonsterNode.classList.add('battle__monster--is-trainer'); + battleMonsterNode.querySelector('[data-template-slot="trainerName"]').textContent = Memory.state.opponent.name; if (Memory.state.opponent.sprite) { battleMonsterNode.classList.add('battle__monster--has-trainer-sprite'); battleMonsterNode.querySelector('[data-template-slot="trainerSprite"]').src = `/modules/tuxemon/mods/tuxemon/gfx/sprites/player/${Memory.state.opponent.sprite}`; + battleMonsterNode.querySelector('[data-template-slot="trainerSprite"]').title = Memory.state.opponent.name; } } @@ -456,6 +461,34 @@ const UI = { requestAnimationFrame(techniqueAnimationLoop); }, + drawLog () { + if (UI.elements.log.children.length > Memory.state.Settings.logMaxLength) { + UI.elements.log.innerHTML = ''; + } + + for (const message of Game.logMessages) { + const textNode = document.createElement('div'); + + textNode.innerHTML = '> '.repeat(message.indentation) + message.message; + + if (message.style) { + for (const property of Object.keys(message.style)) { + const value = message.style[property]; + textNode.style[property] = value; + } + } + + UI.elements.log.appendChild(textNode); + UI.elements.log.scrollTop = UI.elements.log.scrollHeight; + } + + Game.logMessages = []; + }, + + toggleLog () { + UI.elements.log.classList.toggle('log--is-hidden'); + }, + /** * @param {Area} area */ @@ -892,7 +925,7 @@ const UI = { languageOptionNode.value = languageCode; languageOptionNode.textContent = languageName; - if (languageCode === Memory.state.language) { + if (languageCode === Memory.state.Settings.language) { languageOptionNode.selected = true; } @@ -901,9 +934,9 @@ const UI = { languageSelectNode.addEventListener('change', async () => { const selected = [...languageSelectNode.children].find((node) => node.selected === true); - Memory.state.language = selected.value; + Memory.state.Settings.language = selected.value; - await fetchTranslation(Memory.state.language); + await fetchTranslation(Memory.state.Settings.language); UI.drawOpponentMonster(); UI.drawActiveMonster(); UI.drawActiveTechniques(); @@ -1227,5 +1260,6 @@ const UI = { // UI element click bindings UI.elements.menuParty.addEventListener('click', UI.openPartyMenu); UI.elements.menuInventory.addEventListener('click', UI.openInventoryMenu); +UI.elements.menuLog.addEventListener('click', UI.toggleLog); UI.elements.menuJournal.addEventListener('click', UI.openJournalMenu); UI.elements.menuSettings.addEventListener('click', UI.openSettingsMenu); -- cgit v1.2.3