Files
monkeygg2.github.io/games/progress-knight-quest/js/classes.js
T
2023-12-10 09:44:43 -06:00

357 lines
10 KiB
JavaScript

class Task {
constructor(baseData) {
this.baseData = baseData
this.name = baseData.name
this.level = 0
this.maxLevel = 0
this.xp = 0
this.xpBigInt = BigInt(0)
this.isHero = false
this.isFinished = false
this.xpMultipliers = []
}
toJSON() {
return {
baseData: this.baseData,
name: this.name,
level: this.level,
maxLevel: this.maxLevel,
xp: this.xp,
xpBigInt: bigIntToExponential(this.xpBigInt),
isHero: this.isHero,
isFinished: this.isFinished
}
}
getMaxXp() {
const maxXp = (this.isHero ? Math.pow(10, this.baseData.heroxp) : 1) * this.baseData.maxXp * (this.level + 1) * Math.pow(this.isHero ? 1.08 : 1.01, this.level)
if (isNaN(maxXp) || maxXp == Infinity || maxXp > 1e305) {
this.isFinished = true
}
return maxXp
}
getMaxBigIntXp() {
const maxXp = this.getMaxXp() == Infinity ? BigInt(1e305) : BigInt(Math.floor(this.getMaxXp()));
if (maxXp < 1e305)
return maxXp
return maxXp * 2n ** (BigInt(this.level) / 120n) * (2n ** (BigInt(this.baseData.heroxp) / 9n))
}
getXpLeft() {
return this.getMaxXp() - this.xp
}
getMaxLevelMultiplier() {
return gameData.active_challenge == "dance_with_the_devil" ? (10 / (this.maxLevel + 1)) : 1 + this.maxLevel / 10
}
getXpGain() {
return (this.isHero ? getHeroXpGainMultipliers(this) : 1) * applyMultipliers(10, this.xpMultipliers)
}
getXpGainBigInt() {
let xpGain = BigInt(Math.floor(this.isHero ? getHeroXpGainMultipliers(this) : 1))
this.xpMultipliers.forEach(multiplier => {
xpGain *= BigInt(Math.floor(multiplier()))
})
return xpGain
}
getXpGainFormatted() {
if (this.isFinished)
return bigIntToExponential(this.getXpGainBigInt())
return format(this.getXpGain())
}
getXpLeftFormatted() {
if (this.isFinished)
return bigIntToExponential(this.getMaxBigIntXp() - this.xpBigInt)
return format(this.getXpLeft())
}
increaseXp() {
if (this.isFinished) {
this.xpBigInt += applySpeedOnBigInt(this.getXpGainBigInt())
if (this.xpBigInt >= this.getMaxBigIntXp()) {
let excess = this.xpBigInt - this.getMaxBigIntXp()
let iterations = 0
while (excess >= 0n) {
iterations += 1
// This amount is way lower because calculations with a BigInt are really expensive.
// Probably want to look into more optimizations.
if (iterations > 300)
excess = -1n
this.level += 1
excess -= this.getMaxBigIntXp()
}
this.xpBigInt = this.getMaxBigIntXp() + excess
}
} else {
this.xp += applySpeed(this.getXpGain())
if (this.xp > 1e275 || isNaN(this.xp) || this.xp == Infinity || this.getXpGain() == Infinity
|| this.getMaxXp() == Infinity || this.getXpLeft() == Infinity) {
this.isFinished = true
return
}
if (this.xp >= this.getMaxXp()) {
let excess = this.xp - this.getMaxXp()
let iterations = 0
while (excess >= 0) {
iterations += 1
if (iterations > 2500)
excess = -1
this.level += 1
excess -= this.getMaxXp()
}
this.xp = this.getMaxXp() + excess
}
}
}
}
class Milestone {
constructor(baseData) {
this.baseData = baseData
this.name = baseData.name
this.tier = baseData.tier
this.expense = baseData.expense
this.description = baseData.description
}
getTier() { return this.tier }
}
class Job extends Task {
constructor(baseData) {
super(baseData)
this.incomeMultipliers = []
}
getLevelMultiplier() {
return 1 + Math.log10(this.level + 1)
}
getIncome() {
const income = (this.isHero ? heroIncomeMult
* (this.baseData.heroxp > 78 ? 1e6 : 1)
* (this.baseData.heroxp > 130 ? 1e5 : 1)
: 1) * applyMultipliers(this.baseData.income, this.incomeMultipliers) * getChallengeBonus("rich_and_the_poor")
return gameData.active_challenge == "rich_and_the_poor" ? Math.pow(income, 0.35) : income
}
}
class Skill extends Task {
constructor(baseData) {
super(baseData)
}
getEffect() {
var effect = 1 + this.baseData.effect * (this.isHero ? 1000 * this.level + 8000 : this.level)
return effect
}
getEffectDescription() {
return "x" + format(this.getEffect(), 2) + " " + this.baseData.description
}
}
class Item {
constructor(baseData) {
this.baseData = baseData
this.name = baseData.name
this.expenseMultipliers = []
this.isHero = false
}
getEffect() {
let effect = this.baseData.effect
if (this.isHero) {
if (itemCategories["Misc"].includes(this.name))
{
if (gameData.currentMisc.includes(this)) {
effect *= 10
if (this.name == "Universe Fragment" || this.name == "Multiverse Fragment")
effect *= 100000
}
}
if (itemCategories["Properties"].includes(this.name)) {
if (gameData.currentProperty == this)
effect = this.baseData.heroeffect
else
effect = 1
}
} else {
if (gameData.currentProperty != this && !gameData.currentMisc.includes(this)) return 1
}
return effect
}
getEffectDescription() {
let description = this.baseData.description
let effect = this.baseData.effect
if (this.isHero) {
if (itemCategories["Misc"].includes(this.name)) {
effect *= 10
if (this.name == "Universe Fragment" || this.name == "Multiverse Fragment")
effect *= 100000
}
if (itemCategories["Properties"].includes(this.name)) {
description = "Happiness"
effect = this.baseData.heroeffect
}
}
else {
if (itemCategories["Properties"].includes(this.name)) description = "Happiness"
}
return "x" + format(effect) + " " + description
}
getExpense(heroic) {
if (heroic === undefined)
heroic = this.isHero
return (heroic ? 4 * Math.pow(10, this.baseData.heromult) * heroIncomeMult : 1)
* applyMultipliers(this.baseData.expense, this.expenseMultipliers)
}
}
class Requirement {
constructor(querySelectors, requirements) {
this.querySelectors = querySelectors
this.elements = []
this.requirements = requirements
this.completed = false
}
queryElements() {
this.querySelectors.forEach(querySelector => {
this.elements.push(...document.querySelectorAll(querySelector))
})
}
isCompleted() {
if (this.completed) return true
for (const requirement of this.requirements) {
if (!this.getCondition(false, requirement)) {
return false
}
}
this.completed = true
return true
}
isCompletedActual(isHero = false) {
for (const requirement of this.requirements) {
if (!this.getCondition(isHero, requirement)) {
return false
}
}
return true
}
}
class TaskRequirement extends Requirement {
constructor(querySelectors, requirements) {
super(querySelectors, requirements)
this.type = "task"
}
getCondition(isHero, requirement) {
if (isHero && requirement.herequirement != null)
return gameData.taskData[requirement.task].level >= requirement.herequirement
else if (gameData.taskData[requirement.task].isHero && requirement.isHero)
return true
else
return gameData.taskData[requirement.task].level >= requirement.requirement
}
}
class CoinRequirement extends Requirement {
constructor(querySelectors, requirements) {
super(querySelectors, requirements)
this.type = "coins"
}
getCondition(isHero, requirement) {
return gameData.coins >= requirement.requirement
}
}
class AgeRequirement extends Requirement {
constructor(querySelectors, requirements) {
super(querySelectors, requirements)
this.type = "age"
}
getCondition(isHero, requirement) {
return daysToYears(gameData.days) >= requirement.requirement
}
}
class EvilRequirement extends Requirement {
constructor(querySelectors, requirements) {
super(querySelectors, requirements)
this.type = "evil"
}
getCondition(isHero, requirement) {
return gameData.evil >= requirement.requirement
}
}
class EssenceRequirement extends Requirement {
constructor(querySelectors, requirements) {
super(querySelectors, requirements)
this.type = "essence"
}
getCondition(isHero, requirement) {
return gameData.essence >= requirement.requirement
}
}
class DarkMatterRequirement extends Requirement {
constructor(querySelectors, requirements) {
super(querySelectors, requirements)
this.type = "darkMatter"
}
getCondition(isHero, requirement) {
return gameData.dark_matter >= requirement.requirement
}
}
class DarkOrbsRequirement extends Requirement {
constructor(querySelectors, requirements) {
super(querySelectors, requirements)
this.type = "darkOrb"
}
getCondition(isHero, requirement) {
return gameData.dark_orbs >= requirement.requirement
}
}