summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--script.js192
1 files changed, 127 insertions, 65 deletions
diff --git a/script.js b/script.js
index d66f2bb..db37ac5 100644
--- a/script.js
+++ b/script.js
@@ -128,6 +128,8 @@ class State {
activeMonster = null;
activeTechnique = null;
+ turn = 0;
+
enemy = {
monster: null,
};
@@ -135,7 +137,6 @@ class State {
class Monster {
#level = 1;
- #status = null;
#hp = 0;
exp = 1;
@@ -264,33 +265,6 @@ class Monster {
this.hp = statusPostEvolve.hp - (statusPreEvolve.hp - hpPreEvolve);
}
- async useTechnique(technique, enemy) {
- const additionalEffects = technique.effects
- .filter((effect) => !['damage', 'splash', 'area'].includes(effect))
- .map((effect) => new TechniqueEffect(effect));
-
- for (const effect of additionalEffects) {
- let recipient;
-
- if (effect.recipient === 'user') {
- recipient = this;
- } else {
- recipient = enemy;
- }
-
- if (effect.type === 'status') {
- if (effect.application === 'give') {
- recipient.statusEffect = await fetchStatusEffect(effect.effect);
- }
- else if (effect.application === 'remove') {
- if (recipient.statusEffect.slug === effect.effect) {
- recipient.statusEffect = '';
- }
- }
- }
- }
- }
-
getTasteStatusModifier (statusName, baseStatus) {
let positive = 0;
let negative = 0;
@@ -329,10 +303,6 @@ class Monster {
}
get status () {
- if (this.#status) {
- return this.#status;
- }
-
const multiplier = this.level + 7;
let hp = (this.shape.hp * multiplier) + this.statusModifier.hp;
let melee = (this.shape.melee * multiplier) + this.statusModifier.melee;
@@ -348,7 +318,7 @@ class Monster {
dodge += this.getTasteStatusModifier('dodge', melee);
speed += this.getTasteStatusModifier('speed', melee);
- this.#status = {
+ return {
hp,
melee,
armour,
@@ -356,21 +326,21 @@ class Monster {
dodge,
speed,
};
-
- return this.#status;
}
- set status (status) {
- this.#status = status;
+ setStatusModifier (statusType, newAbsoluteValue) {
+ this.statusModifier[statusType] = newAbsoluteValue - this.status[statusType];
}
-
- resetStatus () {
- this.#status = null;
- this.status;
+ resetStatusModifier () {
+ for (const m in this.statusModifier) {
+ this.statusModifier[m] = 0;
+ }
}
};
class Technique {
+ combatEffects = [];
+
constructor (slug) {
this.slug = slug;
}
@@ -412,8 +382,15 @@ class TechniqueEffect {
}
class StatusEffect {
+ turnsLeft = 0;
+
constructor (slug) {
this.slug = slug;
+
+ this.turnsLeft = Math.ceil(Math.random() * 3) + 2;
+ if (['recover', 'lifeleech'].includes(this.slug)) {
+ this.turnsLeft = 1;
+ }
}
get effects () {
@@ -566,6 +543,8 @@ function slugToName (slug) {
await fetchMonster('prophetoise'),
await fetchMonster('drashimi'),
await fetchMonster('glombroc'),
+ await fetchMonster('uneye'),
+ await fetchMonster('nostray'),
];
state.activeMonster = state.partyMonsters[0];
state.activeTechnique = await fetchTechnique(state.activeMonster.moveset[0].technique);
@@ -698,14 +677,13 @@ function slugToName (slug) {
if (where === 'player') {
UI.setExp(monster, battleMonster.querySelector('.exp'));
- battleMonster.querySelector('.battle__monster-technique').innerHTML =
- slugToName(state.activeTechnique.slug) + '   '
- + state.activeTechnique.types.map((type) => UI.createElementTypeIcon(type)).join('');
battleMonster.querySelector('.battle__monster-technique').addEventListener('click', UI.openMovesetSelection);
battleMonster.classList.add('battle__monster--player');
battlePlayer.querySelector('.battle__monster') && battlePlayer.removeChild(battlePlayer.querySelector('.battle__monster'));
battlePlayer.appendChild(battleMonster);
+
+ UI.setActiveTechnique();
} else {
battleMonster.classList.add('battle__monster--enemy');
@@ -731,14 +709,20 @@ function slugToName (slug) {
UI.setBattleMonster(state.activeMonster, 'player');
},
- async setActiveTechnique () {
+ setActiveTechnique () {
+ battlePlayer.querySelector('.battle__monster-technique').innerHTML =
+ slugToName(state.activeTechnique.slug) + '   '
+ + state.activeTechnique.types.map((type) => UI.createElementTypeIcon(type)).join('');
+ },
+
+ async chooseActiveTechnique () {
let activeMoveIndex = 0;
while ((await fetchTechnique(state.activeMonster.moveset[activeMoveIndex].technique)).power === 0) {
activeMoveIndex++;
}
state.activeTechnique = await fetchTechnique(state.activeMonster.moveset[activeMoveIndex].technique);
- UI.setBattleMonster(state.activeMonster, 'player');
+ UI.setActiveTechnique();
},
async openMovesetSelection () {
@@ -765,7 +749,7 @@ function slugToName (slug) {
}
state.activeTechnique = technique;
- UI.setBattleMonster(state.activeMonster, 'player');
+ UI.setActiveTechnique();
popup.remove();
});
@@ -825,14 +809,14 @@ function slugToName (slug) {
partyMonster.dataset.slug = monster.slug;
partyMonster.querySelector('img').src = `/modules/tuxemon/mods/tuxemon/gfx/sprites/battle/${monster.slug}-front.png`;
- partyMonster.addEventListener('click', (event) => {
+ partyMonster.addEventListener('click', async (event) => {
let target = event.target;
while (target.parentNode.id !== 'party') {
target = target.parentNode;
}
state.activeMonster = state.partyMonsters[Array.prototype.indexOf.call(document.querySelector('#party').children, target)];
- UI.setActiveTechnique();
+ await UI.chooseActiveTechnique();
UI.setActiveMonster();
popup.remove();
@@ -859,29 +843,100 @@ function slugToName (slug) {
};
const Game = {
- applyEffect (monster) {
- if (!monster.statusEffect) {
+ async useTechnique(technique, user, target) {
+ let statusEffects = [];
+ let combatEffects = [];
+
+ for (const effect of technique.effects) {
+ if (effect.includes('status_')) {
+ statusEffects.push(new TechniqueEffect(effect));
+ }
+ else if (!['damage', 'splash', 'area'].includes(effect)) {
+ combatEffects.push(effect);
+ }
+ }
+
+ for (const effect of statusEffects) {
+ let recipient;
+
+ if (effect.recipient === 'user') {
+ recipient = user;
+ } else {
+ recipient = target;
+ }
+
+ if (effect.type === 'status') {
+ if (effect.application === 'give') {
+ if (recipient.statusEffect) {
+ continue;
+ }
+
+ recipient.statusEffect = await fetchStatusEffect(effect.effect);
+ }
+ else if (effect.application === 'remove') {
+ if (recipient.statusEffect.slug === effect.effect) {
+ recipient.statusEffect = '';
+ }
+ }
+ }
+ }
+
+ technique.combatEffects = combatEffects;
+ },
+
+ applyStatusEffect (affectedMonster, opposingMonster) {
+ if (!affectedMonster.statusEffect) {
+ return;
+ }
+
+ if (! (affectedMonster.statusEffect instanceof StatusEffect)) {
return;
}
- if (monster.statusEffect.slug === 'poison' || monster.statusEffect.slug === 'burn') {
- const statusEffectDamage = Math.floor(monster.status.hp / 8);
+ if (affectedMonster.statusEffect.slug === 'poison' || affectedMonster.statusEffect.slug === 'burn') {
+ const statusEffectDamage = Math.floor(affectedMonster.status.hp / 8);
+ affectedMonster.hp -= statusEffectDamage;
+
UI.createDamage(clickEvent, statusEffectDamage);
- monster.hp -= statusEffectDamage;
}
- if (monster.statusEffect.slug === 'recover') {
- const statusEffectHeal = Math.floor(monster.status.hp / 16);
- monster.hp += statusEffectHeal;
+ else if (affectedMonster.statusEffect.slug === 'recover') {
+ const statusEffectHeal = Math.floor(affectedMonster.status.hp / 16);
+ affectedMonster.hp += statusEffectHeal;
+ }
+
+ else if (affectedMonster.statusEffect.slug === 'lifeleech') {
+ const statusEffectLeech = Math.floor(affectedMonster.status.hp / 16);
+ affectedMonster.hp -= statusEffectLeech;
+ opposingMonster.hp += statusEffectLeech;
+
+ UI.createDamage(clickEvent, statusEffectLeech);
}
- if (monster.statusEffect.effects.includes('statchange')) {
- monster.resetStatus();
+ else if (affectedMonster.statusEffect.effects.includes('statchange')) {
+ affectedMonster.resetStatusModifier();
- for (const statusType in monster.statusEffect.status) {
- const statusChange = monster.statusEffect.status[statusType];
+ for (const statusType in affectedMonster.statusEffect.status) {
+ const statusChange = affectedMonster.statusEffect.status[statusType];
- monster.status[statusType] = Math.floor(eval(`${monster.status[statusType]} ${statusChange.operation} ${statusChange.value}`));
+ const modifiedValue = Math.floor(eval(`${affectedMonster.status[statusType]} ${statusChange.operation} ${statusChange.value}`));
+ affectedMonster.setStatusModifier(statusType, modifiedValue);
+ }
+ }
+
+ affectedMonster.statusEffect.turnsLeft--;
+ if (affectedMonster.statusEffect.turnsLeft === 0) {
+ postCleanUps.push(() => {
+ affectedMonster.statusEffect = null;
+ affectedMonster.resetStatusModifier();
+ });
+ }
+ },
+
+ applyTechniqueEffect (technique, user, target) {
+ for (const effect of technique.combatEffects) {
+ if (effect === 'money') {
+ state.money += Math.floor(Math.random() * target.level);
}
}
},
@@ -891,16 +946,18 @@ function slugToName (slug) {
UI.setEnemyMonster();
let clickEvent;
+ let postCleanUps = [];
document.querySelector('#battle__enemy').addEventListener('click', async (event) => {
clickEvent = event;
- Game.applyEffect(state.activeMonster);
- Game.applyEffect(state.enemy.monster);
+ await Game.useTechnique(state.activeTechnique, state.activeMonster, state.enemy.monster);
+ Game.applyTechniqueEffect(state.activeTechnique, state.activeMonster, state.enemy.monster);
const damage = simpleDamageCalculation(state.activeTechnique, state.activeMonster, state.enemy.monster);
UI.createDamage(event, damage);
- await state.activeMonster.useTechnique(state.activeTechnique, state.enemy.monster);
+ Game.applyStatusEffect(state.activeMonster, state.enemy.monster);
+ Game.applyStatusEffect(state.enemy.monster, state.activeMonster);
state.enemy.monster.hp -= damage;
if (state.enemy.monster.hp <= 0) {
@@ -924,6 +981,11 @@ function slugToName (slug) {
UI.setHp(state.enemy.monster, battleEnemy);
money.textContent = state.money;
+
+ for (const cleanUp of postCleanUps) {
+ cleanUp();
+ }
+ postCleanUps = [];
});
document.querySelector('#menu__party').addEventListener('click', UI.openPartyMenu);