summaryrefslogtreecommitdiff
path: root/resources/js/classes
diff options
context:
space:
mode:
authorDaniel Weipert <code@drogueronin.de>2023-08-17 02:53:14 +0200
committerDaniel Weipert <code@drogueronin.de>2023-08-17 17:42:15 +0200
commitcc685bfe02b42b592987117fa008a4461785f53c (patch)
tree625c1c9573b178e574bb70cac042c35da4036cf1 /resources/js/classes
parent717fde1c48c7221da986ac02d2b806b2fee6f2d5 (diff)
refactorrefactor
Diffstat (limited to 'resources/js/classes')
-rw-r--r--resources/js/classes/Item.js1
-rw-r--r--resources/js/classes/Monster.js223
-rw-r--r--resources/js/classes/State.js38
-rw-r--r--resources/js/classes/StatusEffect.js55
-rw-r--r--resources/js/classes/Technique.js77
5 files changed, 394 insertions, 0 deletions
diff --git a/resources/js/classes/Item.js b/resources/js/classes/Item.js
new file mode 100644
index 0000000..e274a20
--- /dev/null
+++ b/resources/js/classes/Item.js
@@ -0,0 +1 @@
+class Item {}
diff --git a/resources/js/classes/Monster.js b/resources/js/classes/Monster.js
new file mode 100644
index 0000000..9023f32
--- /dev/null
+++ b/resources/js/classes/Monster.js
@@ -0,0 +1,223 @@
+class Monster {
+ #level = 2;
+ #hp = 0;
+
+ exp = 1;
+
+ tasteWarm = TasteWarm.tasteless;
+ tasteCold = TasteCold.tasteless;
+
+ gender = '';
+
+ heldItem = null;
+
+ /**
+ * @type {StatusEffect}
+ */
+ statusEffect = null;
+
+ statModifiers = {
+ hp: 0,
+ melee: 0,
+ armour: 0,
+ ranged: 0,
+ dodge: 0,
+ speed: 0,
+ };
+
+ experienceModifier = 1;
+ moneyModifier = 1;
+
+ /**
+ * @type {Technique[]}
+ */
+ activeTechniques = [];
+
+ constructor (slug) {
+ this.slug = slug;
+
+ const tasteWarm = Object.keys(TasteWarm).slice(1);
+ this.tasteWarm = tasteWarm[Math.floor(Math.random() * tasteWarm.length)];
+ const tasteCold = Object.keys(TasteCold).slice(1);
+ this.tasteCold = tasteCold[Math.floor(Math.random() * tasteCold.length)];
+
+ this.hp = this.stats.hp;
+
+ const possibleGenders = DB.monsters[this.slug].possible_genders;
+ this.gender = possibleGenders[Math.floor(Math.random() * possibleGenders.length)];
+
+ }
+
+ async initialize () {
+ for (const move of this.getLearnableTechniques()) {
+ this.activeTechniques.push(await fetchTechnique(move.technique));
+ }
+ }
+
+ get shape () {
+ for (const shapeData of DB.shapes) {
+ if (shapeData.slug === DB.monsters[this.slug].shape) {
+ return shapeData;
+ }
+ }
+ }
+
+ get types () {
+ return DB.monsters[this.slug].types;
+ }
+
+ get moveset () {
+ return DB.monsters[this.slug].moveset;
+ }
+
+ get evolutions () {
+ return DB.monsters[this.slug].evolutions;
+ }
+
+ get level () {
+ return this.#level;
+ }
+
+ set level (level) {
+ const statsPreLevelUp = this.stats;
+ const hpPreLevelUp = this.hp;
+
+ this.#level = level;
+
+ const statsPostLevelUp = this.stats;
+
+ this.hp = statsPostLevelUp.hp - (statsPreLevelUp.hp - hpPreLevelUp);
+
+ if (this.exp < this.getExperienceRequired(-1)) {
+ this.exp = this.getExperienceRequired(-1);
+ }
+ }
+
+ get hp () {
+ return this.#hp;
+ }
+
+ set hp (hp) {
+ this.#hp = Math.max(0, Math.min(hp, this.stats.hp));
+ }
+
+ get name () {
+ return slugToName(this.slug);
+ }
+
+ getLearnableTechniques () {
+ return this.moveset.filter((move) => this.level >= move.level_learned);
+ }
+
+ canLevelUp () {
+ return this.exp >= this.getExperienceRequired();
+ }
+
+ levelUp () {
+ while (this.canLevelUp()) {
+ this.level++;
+ }
+ }
+
+ getExperienceRequired (levelOffset = 0) {
+ return Math.max(
+ Math.pow(this.level + levelOffset, 3),
+ 1
+ );
+ }
+
+ getPossibleEvolutions () {
+ // return this.evolutions.filter((evolution) => this.level >= evolution.at_level && (!evolution.item || this.heldItem === evolution.item));
+ return this.evolutions.filter((evolution) => evolution.path === 'standard' && this.level >= evolution.at_level);
+ }
+
+ canEvolve () {
+ return this.getPossibleEvolutions().length > 0;
+ }
+
+ evolve () {
+ const evolution = this.getPossibleEvolutions()[0];
+
+ const statsPreEvolve = this.stats;
+ const hpPreEvolve = this.hp;
+
+ this.slug = evolution.monster_slug;
+
+ const statsPostEvolve = this.stats;
+
+ this.hp = statsPostEvolve.hp - (statsPreEvolve.hp - hpPreEvolve);
+ }
+
+ getTasteStatModifier (statType, baseStat) {
+ let positive = 0;
+ let negative = 0;
+
+ let isPositive = false;
+ let isNegative = false;
+ if (statType === StatType.melee) {
+ isPositive = this.tasteWarm === TasteWarm.salty;
+ isNegative = this.tasteCold === TasteCold.sweet;
+ }
+ else if (statType === StatType.armour) {
+ isPositive = this.tasteWarm === TasteWarm.hearty;
+ isNegative = this.tasteCold === TasteCold.soft;
+ }
+ else if (statType === StatType.ranged) {
+ isPositive = this.tasteWarm === TasteWarm.zesty;
+ isNegative = this.tasteCold === TasteCold.flakey;
+ }
+ else if (statType === StatType.dodge) {
+ isPositive = this.tasteWarm === TasteWarm.refined;
+ isNegative = this.tasteCold === TasteCold.dry;
+ }
+ else if (statType === StatType.speed) {
+ isPositive = this.tasteWarm === TasteWarm.peppy;
+ isNegative = this.tasteCold === TasteCold.mild;
+ }
+
+ if (isPositive) {
+ positive = baseStat * 10 / 100;
+ }
+ if (isNegative) {
+ negative = baseStat * 10 / 100;
+ }
+
+ return Math.floor(positive) - Math.floor(negative);
+ }
+
+ get stats () {
+ const multiplier = this.level + 7;
+ let hp = (this.shape.hp * multiplier) + this.statModifiers.hp;
+ let melee = (this.shape.melee * multiplier) + this.statModifiers.melee;
+ let armour = (this.shape.armour * multiplier) + this.statModifiers.armour;
+ let ranged = (this.shape.ranged * multiplier) + this.statModifiers.ranged;
+ let dodge = (this.shape.dodge * multiplier) + this.statModifiers.dodge;
+ let speed = (this.shape.speed * multiplier) + this.statModifiers.speed;
+
+ // Tastes
+ melee += this.getTasteStatModifier(StatType.melee, melee);
+ armour += this.getTasteStatModifier(StatType.armour, armour);
+ ranged += this.getTasteStatModifier(StatType.ranged, ranged);
+ dodge += this.getTasteStatModifier(StatType.dodge, dodge);
+ speed += this.getTasteStatModifier(StatType.speed, speed);
+
+ return {
+ hp: hp,
+ [StatType.melee]: melee,
+ [StatType.armour]: armour,
+ [StatType.ranged]: ranged,
+ [StatType.dodge]: dodge,
+ [StatType.speed]: speed,
+ };
+ }
+
+ setStatModifier (statType, newAbsoluteValue) {
+ this.statModifiers[statType] = newAbsoluteValue - this.stats[statType];
+ }
+
+ resetStatModifiers () {
+ for (const m in this.statModifiers) {
+ this.statModifiers[m] = 0;
+ }
+ }
+};
diff --git a/resources/js/classes/State.js b/resources/js/classes/State.js
new file mode 100644
index 0000000..2384a85
--- /dev/null
+++ b/resources/js/classes/State.js
@@ -0,0 +1,38 @@
+class State {
+ /**
+ * @type {number}
+ */
+ money = 0;
+
+ /**
+ * @type {Monster[]}
+ */
+ monsters = [];
+
+ /**
+ * @type {Item[]}
+ */
+ inventory = [];
+
+ /**
+ * @type {Monster[]}
+ */
+ partyMonsters = [];
+
+ /**
+ * @type {Monster}
+ */
+ activeMonster = null;
+
+ /**
+ * @type {Technique}
+ */
+ activeTechnique = null;
+
+ enemy = {
+ /**
+ * @type {Monster}
+ */
+ monster: null,
+ };
+};
diff --git a/resources/js/classes/StatusEffect.js b/resources/js/classes/StatusEffect.js
new file mode 100644
index 0000000..ac6ae54
--- /dev/null
+++ b/resources/js/classes/StatusEffect.js
@@ -0,0 +1,55 @@
+class StatusEffect {
+ turnsLeft = 0;
+ onRemove = null;
+
+ /**
+ * @type {Monster}
+ */
+ issuer = null;
+
+ constructor (slug) {
+ this.slug = slug;
+
+ 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;
+ }
+ }
+
+ /**
+ * @returns {string[]}
+ */
+ get effects () {
+ return DB.statusEffects[this.slug].effects;
+ }
+
+ get category () {
+ return DB.statusEffects[this.slug].category;
+ }
+
+ get name () {
+ return slugToName(this.slug);
+ }
+
+ get stats () {
+ const stats = {};
+
+ const statsChangeKeys = Object.keys(DB.statusEffects[this.slug]).filter((key) => key.startsWith('stat'));
+ for (const statChangeKey of statsChangeKeys) {
+ stats[statChangeKey.replace('stat', '')] = DB.statusEffects[this.slug][statChangeKey];
+ }
+
+ return stats;
+ }
+}
diff --git a/resources/js/classes/Technique.js b/resources/js/classes/Technique.js
new file mode 100644
index 0000000..a24e094
--- /dev/null
+++ b/resources/js/classes/Technique.js
@@ -0,0 +1,77 @@
+class Technique {
+ #accuracy = 0;
+ #potency = 0;
+ #power = 0;
+
+ constructor (slug) {
+ this.slug = slug;
+
+ this.resetStats();
+ }
+
+ get name () {
+ return slugToName(this.slug);
+ }
+
+ get types () {
+ return DB.techniques[this.slug].types;
+ }
+
+ get range () {
+ return DB.techniques[this.slug].range;
+ }
+
+ get animation () {
+ return DB.techniques[this.slug].animation;
+ }
+
+ get sfx () {
+ return DB.techniques[this.slug].sfx;
+ }
+
+ /**
+ * @returns {string[]}
+ */
+ 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 stats () {
+ 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,
+ };
+ }
+
+ resetStats () {
+ this.accuracy = this.stats.accuracy;
+ this.potency = this.stats.potency;
+ this.power = this.stats.power;
+ }
+}