From 7b1c251fcb085dc37de439ea1137373f1905d82e Mon Sep 17 00:00:00 2001 From: Daniel Weipert Date: Wed, 23 Aug 2023 20:29:07 +0200 Subject: areas and capture and more --- resources/js/game.js | 153 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 106 insertions(+), 47 deletions(-) (limited to 'resources/js/game.js') diff --git a/resources/js/game.js b/resources/js/game.js index 9370382..663e6b0 100644 --- a/resources/js/game.js +++ b/resources/js/game.js @@ -1,5 +1,6 @@ const Game = { phases: { + preTurnBegin: [], preTurn: [], battle: { preAction: { @@ -16,6 +17,7 @@ const Game = { }, }, postTurn: [], + postTurnEnd: [], }, logMessages: [], @@ -73,6 +75,11 @@ const Game = { Game.logTurn('end'); + for (const event of Game.phases.postTurnEnd) { + event(); + } + Game.phases.postTurnEnd = []; + UI.progressTurn(); Game.isProgressingTurn = false; }, @@ -133,29 +140,33 @@ const Game = { } Game.removeBattlePhaseEvents('action', 'opponent'); + Memory.state.player.activeMonster.statusEffect = await fetchStatusEffect('faint'); + // whole party defeated if (!Memory.state.player.monsters.some((monster) => monster.hp > 0)) { - if (Game.isBattleType('trainer')) { - if (Memory.state.currentArea.encounters.length > 0) { - await Game.encounterWildMonster(); - } else { - await Game.encounterTrainer(); - } - } + Game.isInBattle = false; + Memory.state.currentArea.monsterProgress = 0; - else if (Game.isBattleType('monster')) { - if (Memory.state.currentArea.monsterProgress < Memory.state.currentArea.requiredEncounters) { - Memory.state.currentArea.monsterProgress = 0; - UI.drawStatus(); - } - - await Game.encounterWildMonster(); - } + // go to last visited town + 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; } + + Memory.state.money -= totalHealingCenterPrice; + + Game.addPhaseEvent('postTurnEnd', () => { + Game.log(`Whited out!`); + Game.log(`Payed ${formatPrice(totalHealingCenterPrice)} for full recovery at ${Memory.state.currentArea.name}!`); + }); } // party members still left @@ -189,7 +200,7 @@ const Game = { }, /** - * @param {('preTurn' | 'postTurn')} phase + * @param {('preTurnBegin' | 'preTurn' | 'postTurn' | 'postTurnEnd')} phase * @param {Function} event */ addPhaseEvent (phase, event) { @@ -459,6 +470,14 @@ const Game = { }); } + // confused + else if (monster.statusEffect.slug === 'confused') { + Game.addBattlePhaseEvent('preAction', monster, () => { + // TODO + logStatusIs(); + }); + } + // stuck else if (monster.statusEffect.slug === 'stuck') { for (const technique of monster.activeTechniques) { @@ -533,25 +552,15 @@ const Game = { }); }, - /** - * @param {MouseEvent} event - */ - async battleClick (event) { - if (Game.isLoadingArea || Game.isProgressingTurn) { - return; - } - - Game.isInBattle = true; - UI.battleClickEvent = event; - - // player - await Game.tryUseTechnique(Memory.state.activeTechnique, Memory.state.player.activeMonster, Memory.state.opponent.activeMonster); - - // opponent + async opponentTryUseTechnique () { if (!Game.opponentActionTimeout) { let speedDifference = Memory.state.opponent.activeMonster.stats.speed - Memory.state.player.activeMonster.stats.speed; if (speedDifference > 0) speedDifference = speedDifference / 2; - else if (speedDifference < 0) speedDifference = speedDifference * 2; + else if (speedDifference < 0 && speedDifference > -100) speedDifference = speedDifference * 2; + let levelDifference = Memory.state.opponent.activeMonster.level - Memory.state.player.activeMonster.level; + if (levelDifference >= 5) levelDifference = levelDifference * 2; + else if (levelDifference < 0 && levelDifference > -10) levelDifference = 0; + else if (levelDifference <= -10) levelDifference = levelDifference / 10; const opponentActiveMonster = Memory.state.opponent.activeMonster; Game.opponentActionTimeout = setTimeout(async () => { @@ -576,13 +585,31 @@ const Game = { } Game.opponentActionTimeout = null; - }, Math.max(500, 2000 - (speedDifference * 10))); + }, Math.max(levelDifference < 10 ? 500 : 50, Math.min(2000 - (speedDifference * 10) - (levelDifference * 100), 3000))); console.log( 'Opponent Attack Timeout', Memory.state.opponent.activeMonster.stats.speed, Memory.state.player.activeMonster.stats.speed, - 2000 - (speedDifference * 10) + 2000 - (speedDifference * 10) - (levelDifference * 100) ); } + }, + + /** + * @param {MouseEvent} event + */ + async battleClick (event) { + if (Game.isLoadingArea || Game.isProgressingTurn) { + return; + } + + Game.isInBattle = true; + UI.battleClickEvent = event; + + // player + await Game.tryUseTechnique(Memory.state.activeTechnique, Memory.state.player.activeMonster, Memory.state.opponent.activeMonster); + + // opponent + await Game.opponentTryUseTechnique(); await Game.progressTurn(); }, @@ -669,7 +696,7 @@ const Game = { } const nextTrainer = Memory.state.currentArea.trainers[nextTrainerIdx]; - if (nextTrainer.name === 'Rival') { + if (nextTrainer.name.startsWith('Rival')) { for (const idx in nextTrainer.monsters) { if (nextTrainer.monsters[idx].slug === 'STARTER') { nextTrainer.monsters[idx].slug = Memory.state.rivalMonster; @@ -704,16 +731,12 @@ const Game = { } Memory.state.currentArea = await fetchArea(areaSlug); - UI.drawArea(); if (Game.isTown(Memory.state.currentArea)) { - UI.elements.sceneBattle.classList.add('hidden'); - UI.elements.sceneTown.classList.remove('hidden'); - - UI.drawTown(); + if (Object.values(Memory.state.currentArea.locations).some((location) => location.type === 'healingCenter')) { + Memory.state.lastVisitedTown = areaSlug; + } } else { - 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) { @@ -721,8 +744,7 @@ const Game = { } } - UI.drawStatus(); - UI.drawActiveBall(); + UI.drawArea(); Game.isLoadingArea = false; }, @@ -748,6 +770,10 @@ const Game = { conditionIsApplicable = eval(`${monster.hp} ${itemCondition.comparator} ${value}`); } + else if (itemCondition.what === 'status') { + conditionIsApplicable = monster.statusEffect && monster.statusEffect.slug === itemCondition.value.replace('status_', ''); + } + else if (itemCondition.what === 'wild_monster') { conditionIsApplicable = Game.isBattleType('monster'); } @@ -784,6 +810,13 @@ const Game = { UI.drawActiveMonster(); } + if (itemEffect.type === 'revive') { + monster.hp = itemEffect.amount; + monster.statusEffect = null; + item.quantity--; + UI.drawActiveMonster(); + } + else if (itemEffect.type === 'capture') { Memory.state.activeBall = item; UI.drawActiveBall(); @@ -825,15 +858,41 @@ const Game = { return; } - Game.clearCurrentTurn(); + const playerMonster = Memory.state.player.activeMonster; + const opposingMonster = Memory.state.opponent.activeMonster; + const activeBall = Memory.state.activeBall; - Memory.state.activeBall.quantity--; - if (Memory.state.activeBall.quantity === 0) { + // remove ball + activeBall.quantity--; + if (activeBall.quantity === 0) { Game.removeItemFromInventory(Memory.state.player.inventory, Memory.state.activeBall); Memory.state.activeBall = null; UI.drawActiveBall(); } + // attempt capture + Game.log('Attempting capture!'); + let success = true; + let attempts = 1; + const maxAttempts = 4; + while (success && attempts <= maxAttempts) { + success = checkCapture(playerMonster, opposingMonster, activeBall); + + if (!success) { + Game.log(`Escape attempt ${attempts}: succeeded!`); + Game.log(`${opposingMonster.name} broke free!`); + + Game.opponentTryUseTechnique(); + return; // can't catch + } + + Game.log(`Escape attempt ${attempts}: failed!`); + + attempts++; + } + + Game.clearCurrentTurn(); + const caughtMonster = new Monster(Memory.state.opponent.activeMonster.slug); caughtMonster.initialize(); caughtMonster.level = Memory.state.opponent.activeMonster.level; -- cgit v1.2.3