summaryrefslogtreecommitdiff
path: root/resources/js/game.js
diff options
context:
space:
mode:
authorDaniel Weipert <code@drogueronin.de>2023-08-23 20:29:07 +0200
committerDaniel Weipert <code@drogueronin.de>2023-08-23 20:29:07 +0200
commit7b1c251fcb085dc37de439ea1137373f1905d82e (patch)
tree32e3f2cd4367507726af6d0172e9621a37dff576 /resources/js/game.js
parent4dd1a344c6474087a3f8782dd54f5c7b4acc67ed (diff)
areas and capture and more
Diffstat (limited to 'resources/js/game.js')
-rw-r--r--resources/js/game.js153
1 files changed, 106 insertions, 47 deletions
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;