summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Weipert <code@drogueronin.de>2023-08-16 14:16:27 +0200
committerDaniel Weipert <code@drogueronin.de>2023-08-16 14:16:27 +0200
commitbcf6e73b067af23265d0a092148d026985f2694a (patch)
tree39036715e95c311a1b500b4b8501a80c6d1ddc9f
parentf2ef812f6e21582dd767814bca1b7b2e3a9aab15 (diff)
status effect duration + hit/miss
-rw-r--r--script.js178
1 files changed, 142 insertions, 36 deletions
diff --git a/script.js b/script.js
index db37ac5..4e5727d 100644
--- a/script.js
+++ b/script.js
@@ -129,6 +129,7 @@ class State {
activeTechnique = null;
turn = 0;
+ currentArea = null;
enemy = {
monster: null,
@@ -339,20 +340,22 @@ class Monster {
};
class Technique {
+ #accuracy = 0;
+ #potency = 0;
+ #power = 0;
+
combatEffects = [];
constructor (slug) {
this.slug = slug;
+
+ this.resetToBase();
}
get types () {
return DB.techniques[this.slug].types;
}
- get power () {
- return DB.techniques[this.slug].power;
- }
-
get range () {
return DB.techniques[this.slug].range;
}
@@ -368,6 +371,45 @@ class Technique {
get effects () {
return DB.techniques[this.slug].effects;
}
+
+ get accuracy () {
+ return this.#accuracy;
+ }
+ set accuracy (accuracy) {
+ this.#accuracy = accuracy;
+ }
+
+ get potency () {
+ return this.#potency;
+ }
+ set potency (potency) {
+ this.#potency = potency;
+ }
+
+ get power () {
+ return this.#power;
+ }
+ set power (power) {
+ this.#power = power;
+ }
+
+ get base () {
+ const accuracy = DB.techniques[this.slug].accuracy;
+ const potency = DB.techniques[this.slug].potency;
+ const power = DB.techniques[this.slug].power;
+
+ return {
+ accuracy,
+ potency,
+ power,
+ };
+ }
+
+ resetToBase () {
+ this.accuracy = this.base.accuracy;
+ this.potency = this.base.potency;
+ this.power = this.base.power;
+ }
}
class Item {}
@@ -387,16 +429,31 @@ class StatusEffect {
constructor (slug) {
this.slug = slug;
- this.turnsLeft = Math.ceil(Math.random() * 3) + 2;
if (['recover', 'lifeleech'].includes(this.slug)) {
this.turnsLeft = 1;
}
+ else if (['charging'].includes(this.slug)) {
+ this.turnsLeft = 2;
+ }
+ else if (this.category === 'positive') {
+ this.turnsLeft = Math.ceil(Math.random() * 6) + 4;
+ }
+ else if (this.category === 'negative') {
+ this.turnsLeft = Math.ceil(Math.random() * 3) + 2;
+ }
+ else {
+ this.turnsLeft = Math.ceil(Math.random() * 3) + 2;
+ }
}
get effects () {
return DB.statusEffects[this.slug].effects;
}
+ get category () {
+ return DB.statusEffects[this.slug].category;
+ }
+
get name () {
return slugToName(this.slug);
}
@@ -433,6 +490,10 @@ function simpleDamageMultiplier (techniqueTypes, targetTypes) {
return Math.max(0.25, Math.min(multiplier, 4));
}
function simpleDamageCalculation (technique, user, target) {
+ if (technique.power === 0) {
+ return 0;
+ }
+
let userBaseStrength = user.level + 7;
let userStrength = 1;
let targetResist = 1;
@@ -545,6 +606,7 @@ function slugToName (slug) {
await fetchMonster('glombroc'),
await fetchMonster('uneye'),
await fetchMonster('nostray'),
+ await fetchMonster('dragarbor'),
];
state.activeMonster = state.partyMonsters[0];
state.activeTechnique = await fetchTechnique(state.activeMonster.moveset[0].technique);
@@ -731,11 +793,6 @@ function slugToName (slug) {
const movesetList = UI.getTemplate(templateMovesetList);
for (const move of state.activeMonster.moveset) {
const technique = await fetchTechnique(move.technique);
-
- if (technique.power === 0) {
- continue;
- }
-
const movesetItem = UI.getTemplate(templateMovesetItem);
movesetItem.querySelector('.moveset__item__name').textContent = slugToName(technique.slug);
@@ -871,7 +928,11 @@ function slugToName (slug) {
continue;
}
- recipient.statusEffect = await fetchStatusEffect(effect.effect);
+ const potency = Math.random();
+ const success = technique.potency >= potency;
+ if (success) {
+ recipient.statusEffect = await fetchStatusEffect(effect.effect);
+ }
}
else if (effect.application === 'remove') {
if (recipient.statusEffect.slug === effect.effect) {
@@ -884,7 +945,7 @@ function slugToName (slug) {
technique.combatEffects = combatEffects;
},
- applyStatusEffect (affectedMonster, opposingMonster) {
+ async applyStatusEffect (affectedMonster, opposingMonster) {
if (!affectedMonster.statusEffect) {
return;
}
@@ -913,6 +974,14 @@ function slugToName (slug) {
UI.createDamage(clickEvent, statusEffectLeech);
}
+ else if (affectedMonster.statusEffect.slug === 'charging') {
+ turnEndPhaseEvents.push(async () => {
+ if (affectedMonster.statusEffect.turnsLeft === 0) {
+ affectedMonster.statusEffect = await fetchStatusEffect('chargedup');
+ }
+ });
+ }
+
else if (affectedMonster.statusEffect.effects.includes('statchange')) {
affectedMonster.resetStatusModifier();
@@ -925,12 +994,12 @@ function slugToName (slug) {
}
affectedMonster.statusEffect.turnsLeft--;
- if (affectedMonster.statusEffect.turnsLeft === 0) {
- postCleanUps.push(() => {
+ turnEndPhaseEvents.push(() => {
+ if (affectedMonster.statusEffect.turnsLeft === 0) {
affectedMonster.statusEffect = null;
affectedMonster.resetStatusModifier();
- });
- }
+ }
+ });
},
applyTechniqueEffect (technique, user, target) {
@@ -939,6 +1008,30 @@ function slugToName (slug) {
state.money += Math.floor(Math.random() * target.level);
}
}
+
+ // modify technique stats
+ if (user.statusEffect) {
+ if (user.statusEffect.slug === 'grabbed') {
+ if ([TechniqueRange.ranged, TechniqueRange.reach].includes(technique.range)) {
+ technique.potency = technique.base.potency * 0.5;
+ technique.power = technique.base.power * 0.5;
+ }
+ }
+
+ else if (user.statusEffect.slug === 'stuck') {
+ if ([TechniqueRange.melee, TechniqueRange.touch].includes(technique.range)) {
+ technique.potency = technique.base.potency * 0.5;
+ technique.power = technique.base.power * 0.5;
+ }
+ }
+
+ // remove effect
+ if (user.statusEffect.turnsLeft === 0) {
+ turnEndPhaseEvents.push(() => {
+ technique.resetToBase();
+ });
+ }
+ }
},
};
@@ -946,33 +1039,43 @@ function slugToName (slug) {
UI.setEnemyMonster();
let clickEvent;
- let postCleanUps = [];
+ let turnEndPhaseEvents = [];
document.querySelector('#battle__enemy').addEventListener('click', async (event) => {
clickEvent = event;
- await Game.useTechnique(state.activeTechnique, state.activeMonster, state.enemy.monster);
- Game.applyTechniqueEffect(state.activeTechnique, state.activeMonster, state.enemy.monster);
+ const accuracy = Math.random();
+ const hit = state.activeTechnique.accuracy >= accuracy;
+
+ if (hit) {
+ await Game.useTechnique(state.activeTechnique, state.activeMonster, state.enemy.monster);
+ }
+
+ await Game.applyStatusEffect(state.activeMonster, state.enemy.monster);
+ await Game.applyStatusEffect(state.enemy.monster, state.activeMonster);
- const damage = simpleDamageCalculation(state.activeTechnique, state.activeMonster, state.enemy.monster);
- UI.createDamage(event, damage);
+ if (hit) {
+ Game.applyTechniqueEffect(state.activeTechnique, state.activeMonster, state.enemy.monster);
- Game.applyStatusEffect(state.activeMonster, state.enemy.monster);
- Game.applyStatusEffect(state.enemy.monster, state.activeMonster);
+ const damage = simpleDamageCalculation(state.activeTechnique, state.activeMonster, state.enemy.monster);
+ UI.createDamage(event, damage);
- state.enemy.monster.hp -= damage;
- if (state.enemy.monster.hp <= 0) {
- const faintedMonster = state.enemy.monster;
+ state.enemy.monster.hp -= damage;
+ if (state.enemy.monster.hp <= 0) {
+ const faintedMonster = state.enemy.monster;
- await UI.createNewEnemyMonster();
+ await UI.createNewEnemyMonster();
- state.money += faintedMonster.level * faintedMonster.moneyModifier;
+ state.money += faintedMonster.level * faintedMonster.moneyModifier;
- state.activeMonster.exp += calculateAwardedExperience(state.activeMonster, faintedMonster);
- state.activeMonster.levelUp();
- if (state.activeMonster.canEvolve()) {
- await fetchMonster(state.activeMonster.evolutions[0].monster_slug);
- state.activeMonster.evolve();
+ state.activeMonster.exp += calculateAwardedExperience(state.activeMonster, faintedMonster);
+ state.activeMonster.levelUp();
+ if (state.activeMonster.canEvolve()) {
+ await fetchMonster(state.activeMonster.evolutions[0].monster_slug);
+ state.activeMonster.evolve();
+ }
}
+ } else {
+ UI.createDamage(event, 'MISS!');
}
UI.setActiveMonster();
@@ -982,10 +1085,13 @@ function slugToName (slug) {
money.textContent = state.money;
- for (const cleanUp of postCleanUps) {
- cleanUp();
+ for (const turnEndPhaseEvent of turnEndPhaseEvents) {
+ const returnValue = turnEndPhaseEvent();
+ if (returnValue instanceof Promise) {
+ await returnValue;
+ }
}
- postCleanUps = [];
+ turnEndPhaseEvents = [];
});
document.querySelector('#menu__party').addEventListener('click', UI.openPartyMenu);