diff options
Diffstat (limited to 'resources/js/classes/Monster.js')
-rw-r--r-- | resources/js/classes/Monster.js | 223 |
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; + } + } +}; |