summaryrefslogtreecommitdiff
path: root/resources/js/classes/Monster.js
diff options
context:
space:
mode:
Diffstat (limited to 'resources/js/classes/Monster.js')
-rw-r--r--resources/js/classes/Monster.js223
1 files changed, 223 insertions, 0 deletions
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;
+ }
+ }
+};