Integrals!

Big number hardcap and achievements
This commit is contained in:
Nif 2024-03-15 15:48:00 +00:00
parent 707d9f3e73
commit dc4539ec52
14 changed files with 341 additions and 36 deletions

3
.idea/.gitignore generated vendored Normal file
View file

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

9
.idea/just_another_tree.iml generated Normal file
View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/misc.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/just_another_tree.iml" filepath="$PROJECT_DIR$/.idea/just_another_tree.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

178
js/data/achievements.js Normal file
View file

@ -0,0 +1,178 @@
addLayer("ach", {
name: "achievements", // This is optional, only used in a few places, If absent it just uses the layer id.
symbol: "&star;", // This appears on the layer's node. Default is the id with the first letter capitalized
position: 0, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order
startData() { return {
unlocked: true,
has45: false,
has55: false
}},
color: "#9d750d",
effect() {
return Decimal.div(player[this.layer].achievements.length, 20).add(1)
},
achievements: {
11: {
name: "All that progress is gone!",
done() { return player.p.points.gte(1) },
tooltip: "Reset for 1 PP."
},
12: {
name: "So that's what the mechanic is...",
done() { return getAlphaLevel().gte(2) },
tooltip: "Reach Alpha level 2."
},
13: {
name: "This is quite fun!",
done() { return getBetaLevel().gte(1) },
tooltip: "Reach Beta level 1."
},
14: {
name: "Oh so many bars.",
done() { return getGammaLevel().gte(1) },
tooltip: "Reach Gamma level 1."
},
15: {
name: "GREEN!!!",
done() { return options.theme === "verdant" },
tooltip: "Switch to the Verdant theme."
},
21: {
name: "Nomial gains.",
done() { return getPointGen().gte(1) },
tooltip: "Get 1 point per second."
},
22: {
name: "That's an exponent!",
done() { return getEpsilonLevel().gte(1) },
tooltip: "Reach Epsilon level 1."
},
23: {
name: "What's a \"Rank\"?",
done() { return getAlphaRank().gte(1) },
tooltip: "Reach Alpha rank 1."
},
24: {
name: "No more bars?",
done() { return getZetaLevel().gte(1) },
tooltip: "Reach Zeta level 1."
},
25: {
name: "Lots of points",
done() { return player.points.gte(200) },
tooltip: "Reach 200 points."
},
31: {
name: "Even more progress.",
done() { return getBuyableAmount('p', 11).gte(1) },
tooltip: "Get 1x <b>More progress</b> buyable."
},
32: {
name: "So this just boosts Gamma further?",
done() { return getBuyableAmount('p', 12).gte(1) },
tooltip: "Get 1x <b>Rebased</b> buyable."
},
33: {
name: "Softcap?? >:(",
done() { return getPointGen().gte(getKappaEffect().mul(1000)) },
tooltip: "Reach the first softcap."
},
33: {
name: "Decrementy",
done() { return getBuyableAmount('p', 13).gte(1) },
tooltip: "Get 1x <b>Shorter bars</b> buyable."
},
34: {
name: "Super!",
done() { return player.sp.points.gte(1) },
tooltip: "Reset for 1 SPP."
},
35: {
name: "Where were you??",
done() { return getPointGen().gt(0) && player.points.div(100).gte(getPointGen()) },
tooltip: "Have your points reach 100x your points per second."
},
41: {
name: "Progressed further.",
done() { return getThetaLevel().gte(1) },
tooltip: "Reach Theta level 1."
},
42: {
name: "Literally just another exponent.",
done() { return getIotaLevel().gte(1) },
tooltip: "Reach Iota level 1."
},
43: {
name: "YES! GOODBYE SOFTCAP!",
done() { return getKappaLevel().gte(1) },
tooltip: "Reach Kappa level 1."
},
44: {
name: "Very big multiplier",
done() { return getLambdaLevel().gte(1) },
tooltip: "Reach Lambda level 1."
},
45: {
name: "Don't even need PP anymore",
done() { return player[this.layer].has45 },
tooltip: "Reset for SPP with 0 PP."
},
51: {
name: "An exponent to progress points?",
done() { return getBuyableAmount('sp', 11).gte(1) },
tooltip: "Get 1x <b>Much more progress</b> buyable."
},
52: {
name: "And another exponent to points ¬_¬",
done() { return getBuyableAmount('sp', 12).gte(1) },
tooltip: "Get 1x <b>Super point booster</b> buyable."
},
53: {
name: "A new prestige layer!",
done() { return player.p.points.gte(5000) },
tooltip: "Reach 5000 PP."
},
54: {
name: "Ok so that speeds things up",
done() { return hasMilestone('f', 2) },
tooltip: "Earn Filestone 3."
},
55: {
name: "Well that was useful",
done() { return player[this.layer].has55 },
tooltip: "Respec directory upgrades when you have none."
},
61: {
name: "Ooh upgrades",
done() { return player.f.upgrades.map(x => x - 20).filter(x => x >= 0 && x < 9).length == 3 },
tooltip: "Get all row 2 directory upgrades."
},
62: {
name: "Lots of boosts!!",
done() { return player.f.upgrades.map(x => x - 30).filter(x => x >= 0 && x < 9).length == 3 },
tooltip: "Get all row 3 directory upgrades."
},
63: {
name: "Wait that's all of them?",
done() { return player.f.upgrades.map(x => x - 40).filter(x => x >= 0 && x < 9).length == 4 },
tooltip: "Get all row 4 directory upgrades."
},
64: {
name: "Well that exploded",
done() { return player.i.points.gt(0) },
tooltip: "Reset for 1 integral.<br>Current endgame."
},
},
tabFormat: [
"blank",
["raw-html", function () { return "Achievements: " + player[this.layer].achievements.length + "/" + (Object.keys(tmp[this.layer].achievements).length - 2) }],
["raw-html", function () { return "Effect: x" + tmp[this.layer].effect + " to point gen." }],
"blank",
"achievements"
],
tooltip() {
return player[this.layer].achievements.length + " achievement" + (player[this.layer].achievements.length == 1 ? "" : "s")
},
row: "side", // Row the layer is in on the tree (0 is the first row)
layerShown(){return true}
})

View file

@ -1,7 +1,7 @@
addLayer("f", {
name: "files", // This is optional, only used in a few places, If absent it just uses the layer id.
symbol: "&#x1f5ce;", // This appears on the layer's node. Default is the id with the first letter capitalized
position: 0, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order
position: 1, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order
startData() { return {
unlocked: false,
points: new Decimal(0),
@ -18,9 +18,9 @@ addLayer("f", {
baseResource: "progress points", // Name of resource prestige is based on
baseAmount() {return player.p.points}, // Get the current amount of baseResource
type: "static", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have
exponent: 1.1, // Prestige currency exponent
exponent: 1.3, // Prestige currency exponent
base() {
let base = 1.2
let base = 2
if (hasUpgrade(this.layer, 41)) base **= 0.95
return base
},
@ -114,7 +114,7 @@ addLayer("f", {
branches: [11]
},
23: {
description: "Gain 5% of your PP gain every second.",
description: "Gain 10% of your PP gain every second.",
cost: 4,
unlocked() { return hasUpgrade(this.layer, 11) },
branches: [11]
@ -158,7 +158,7 @@ addLayer("f", {
branches: [32, 33]
},
44: {
description: "Gain another 5% of your PP gain every second.",
description: "Gain another 15% of your PP gain every second.",
cost: 8,
unlocked() { return hasUpgrade(this.layer, 23) && hasUpgrade(this.layer, 33) },
branches: [[23, 2], 33]
@ -169,6 +169,9 @@ addLayer("f", {
display() { return "Reset directory" },
onClick() {
if (confirm("Are you sure you want to respec?")) {
if (player[this.layer].upgrades == 0) {
player.ach.has55 = true
}
for (let i of player[this.layer].upgrades) {
player[this.layer].points = player[this.layer].points.add(tmp[this.layer].upgrades[i].cost)
}

28
js/data/integrals.js Normal file
View file

@ -0,0 +1,28 @@
addLayer("i", {
name: "integrals", // This is optional, only used in a few places, If absent it just uses the layer id.
symbol: "&int;", // This appears on the layer's node. Default is the id with the first letter capitalized
position: 0, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order
startData() { return {
unlocked: false,
points: new Decimal(0)
}},
color: "#a62222",
requires: Decimal.pow(2, 128), // Can be a function that takes requirement increases into account
resource: "integrals", // Name of prestige currency
baseResource: "points", // Name of resource prestige is based on
baseAmount() {return player.points}, // Get the current amount of baseResource
type: "normal", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have
exponent: 1, // Prestige currency exponent
gainMult() { // Calculate the multiplier for main currency from bonuses
return new Decimal(1)
},
gainExp() { // Calculate the exponent on main currency from bonuses
return new Decimal(1)
},
row: 2, // Row the layer is in on the tree (0 is the first row)
hotkeys: [
{key: "i", description: "I: reset for integrals", onPress(){if (canReset(this.layer)) doReset(this.layer)}},
],
layerShown(){ return player.points.gte("1e25") || player[this.layer].unlocked },
branches: ['sp', 'f']
})

View file

@ -36,8 +36,7 @@ function getGammaCost(points = player.p.points) {
return cumulativeExponential(1.5, getGammaLevel(points).floor()).mul(15).pow(buyableEffect('p', 13))
}
function getGammaEffect(points = player.p.points) {
return Decimal.add(points, 1).add(hasUpgrade('f', 31) ? getTotalLevel() : 0).log(Decimal.pow(50, buyableEffect('p', 12)))
.add(1).pow(getGammaLevel(points).mul(getGammaRankEffect(points).add(1/10)))
return Decimal.add(points, 1).add(hasUpgrade('f', 31) ? getTotalLevel() : 0).log(Decimal.pow(50, buyableEffect('p', 12))).add(1).pow(getGammaLevel(points).mul(getGammaRankEffect(points).add(1/10)))
}
function getDeltaLevel(points = player.p.points) {
if (Decimal.eq(points, 0)) return new Decimal(0)
@ -74,8 +73,7 @@ function getZetaEffect(points = player.p.points) {
}
function getTotalLevel(points = player.p.points) {
return getAlphaLevel(points).add(getBetaLevel(points)).add(getGammaLevel(points)).add(getDeltaLevel(points))
.add(getEpsilonLevel(points)).add(getZetaLevel(points))
return getAlphaLevel(points).add(getBetaLevel(points)).add(getGammaLevel(points)).add(getDeltaLevel(points)).add(getEpsilonLevel(points)).add(getZetaLevel(points))
}
function getEtaLevel(points = player.sp.points) {
@ -90,35 +88,45 @@ function getEtaEffect(points = player.sp.points) {
}
function getThetaLevel(points = player.sp.points) {
if (Decimal.eq(points, 0)) return new Decimal(0)
return inverseCumulativeExponential(1.5, Decimal.div(points, 3)).floor()
return inverseCumulativeExponential(1.3, Decimal.div(points, 3)).floor()
}
function getThetaCost(points = player.sp.points) {
return cumulativeExponential(1.5, getThetaLevel(points)).mul(3)
return cumulativeExponential(1.3, getThetaLevel(points)).mul(3)
}
function getThetaEffect(points = player.sp.points) {
return getThetaLevel(points).pow(1/4).add(1)
}
function getIotaLevel(points = player.sp.points) {
if (Decimal.eq(points, 0)) return new Decimal(0)
return inverseCumulativeExponential(1.7, Decimal.div(points, 5)).floor()
return inverseCumulativeExponential(1.5, Decimal.div(points, 5)).floor()
}
function getIotaCost(points = player.sp.points) {
return cumulativeExponential(1.7, getIotaLevel(points)).mul(5)
return cumulativeExponential(1.5, getIotaLevel(points)).mul(5)
}
function getIotaEffect(points = player.sp.points) {
return getIotaLevel(points).pow(1/3).add(1)
}
function getKappaLevel(points = player.sp.points) {
if (Decimal.eq(points, 0)) return new Decimal(0)
return inverseCumulativeExponential(2, Decimal.div(points, 8)).floor()
return inverseCumulativeExponential(1.7, Decimal.div(points, 8)).floor()
}
function getKappaCost(points = player.sp.points) {
return cumulativeExponential(2, getKappaLevel(points)).mul(8)
return cumulativeExponential(1.7, getKappaLevel(points)).mul(8)
}
function getKappaEffect(points = player.sp.points) {
return getKappaLevel(points).pow(2/3).add(1)
return getKappaLevel(points).sqrt().add(1)
}
function getLambdaLevel(points = player.sp.points) {
if (Decimal.eq(points, 0)) return new Decimal(0)
return inverseCumulativeExponential(2, Decimal.div(points, 13)).floor()
}
function getLambdaCost(points = player.sp.points) {
return cumulativeExponential(2, getLambdaLevel(points)).mul(13)
}
function getLambdaEffect(points = player.sp.points) {
return getLambdaLevel(points).add(1).pow(3/2)
}
function getTotalSuperLevel(points = player.sp.points) {
return getEtaLevel(points).add(getThetaLevel(points)).add(getIotaLevel(points)).add(getKappaLevel(points))
return getEtaLevel(points).add(getThetaLevel(points)).add(getIotaLevel(points)).add(getKappaLevel(points)).add(getLambdaLevel(points))
}

View file

@ -26,7 +26,7 @@ addLayer("p", {
return mult
},
gainExp() { // Calculate the exponent on main currency from bonuses
return new Decimal(1)
return buyableEffect('sp', 11)
},
row: 0, // Row the layer is in on the tree (0 is the first row)
hotkeys: [
@ -34,8 +34,8 @@ addLayer("p", {
],
passiveGeneration() {
let gain = 0
if (hasUpgrade('f', 44)) gain += 0.05
if (hasUpgrade('f', 23)) gain += 0.05
if (hasUpgrade('f', 23)) gain += 0.1
if (hasUpgrade('f', 44)) gain += 0.15
return gain
},
automate() {
@ -194,7 +194,7 @@ addLayer("p", {
cost() { return Decimal.pow(getBuyableAmount(this.layer, this.id), 1.2).mul(5).add(50) },
display() {
return "Increase progress point gain.<br><br>Amount: " + getBuyableAmount(this.layer, this.id)
+ ".<br>Effect: " + this.effect(getBuyableAmount(this.layer, this.id)) + "x.<br>Cost: "
+ ".<br>Effect: x" + this.effect(getBuyableAmount(this.layer, this.id)) + ".<br>Cost: "
+ this.cost(getBuyableAmount(this.layer, this.id)) + " total levels."
},
canAfford() { return Decimal.gte(getTotalLevel(), this.cost()) },
@ -260,8 +260,8 @@ addLayer("p", {
"main-display",
["row", ["prestige-button", ["clickable", 11]]],
"resource-display",
["raw-html", () => "You have " + getTotalLevel() + " levels."],
["raw-html", () => "You have " + getTotalRank() + " ranks."],
["raw-html", () => "You have " + getTotalLevel() + " level" + (getTotalLevel().eq(1) ? "" : "s") + "."],
["raw-html", () => "You have " + getTotalRank() + " rank" + (getTotalRank().eq(1) ? "" : "s") + "."],
"blank",
"blank",
["bar", "alphaRank"],
@ -278,8 +278,8 @@ addLayer("p", {
"main-display",
["row", ["prestige-button", ["clickable", 11]]],
"resource-display",
["raw-html", () => "You have " + getTotalLevel() + " levels."],
["raw-html", () => "You have " + getTotalRank() + " ranks."],
["raw-html", () => "You have " + getTotalLevel() + " level" + (getTotalLevel().eq(1) ? "" : "s") + "."],
["raw-html", () => "You have " + getTotalRank() + " rank" + (getTotalRank().eq(1) ? "" : "s") + "."],
"blank",
"blank",
"buyables"

View file

@ -1,7 +1,7 @@
addLayer("sp", {
name: "super progress", // This is optional, only used in a few places, If absent it just uses the layer id.
symbol: "&permil;", // This appears on the layer's node. Default is the id with the first letter capitalized
position: 1, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order
position: 0, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order
startData() { return {
unlocked: false,
points: new Decimal(0)
@ -23,6 +23,9 @@ addLayer("sp", {
hotkeys: [
{key: "s", description: "S: Reset for super progress points", onPress(){if (canReset(this.layer)) doReset(this.layer)}},
],
onPrestige(gain) {
if (player.p.points.eq(0)) { player.ach.has45 = true }
},
bars: {
eta: {
direction: RIGHT,
@ -66,11 +69,49 @@ addLayer("sp", {
progress() { return player[this.layer].points.div(getKappaCost()) },
display() {
return "Kappa - Level " + getKappaLevel() + " (" + player[this.layer].points + "/" + getKappaCost()
+ ")<br>Effect: x" + getKappaEffect() + " to point gen."
+ ")<br>Effect: x" + getKappaEffect() + " to softcap."
},
fillStyle: {backgroundColor: "#107f76"},
unlocked() { return getIotaLevel().gt(0) }
},
lambda: {
direction: RIGHT,
width: 300,
height: 50,
progress() { return player[this.layer].points.div(getLambdaCost()) },
display() {
return "Lambda - Level " + getLambdaLevel() + " (" + player[this.layer].points + "/" + getLambdaCost()
+ ")<br>Effect: x" + getLambdaEffect() + " to point gen."
},
fillStyle: {backgroundColor: "#107f76"},
unlocked() { return getKappaLevel().gt(0) }
},
},
buyables: {
11: {
title: "Much more progress",
effect() { return Decimal.div(getBuyableAmount(this.layer, this.id), 20).add(1) },
cost() { return Decimal.pow(getBuyableAmount(this.layer, this.id), 1.2).mul(3).add(20) },
display() {
return "Increase PP gain.<br><br>Amount: " + getBuyableAmount(this.layer, this.id)
+ ".<br>Effect: ^" + this.effect(getBuyableAmount(this.layer, this.id)) + ".<br>Cost: "
+ this.cost(getBuyableAmount(this.layer, this.id)) + " total super levels."
},
canAfford() { return Decimal.gte(getTotalSuperLevel(), this.cost()) },
buy() { addBuyables(this.layer, this.id, 1) }
},
12: {
title: "Super point booster",
effect() { return Decimal.pow(getBuyableAmount(this.layer, this.id), 1.3).add(1) },
cost() { return Decimal.pow(getBuyableAmount(this.layer, this.id), 1.2).mul(5).add(25) },
display() {
return "Increase point gen.<br><br>Amount: " + getBuyableAmount(this.layer, this.id)
+ ".<br>Effect: ^" + this.effect(getBuyableAmount(this.layer, this.id)) + ".<br>Cost: "
+ this.cost(getBuyableAmount(this.layer, this.id)) + " total super levels."
},
canAfford() { return Decimal.gte(getTotalSuperLevel(), this.cost()) },
buy() { addBuyables(this.layer, this.id, 1) }
},
},
clickables: {
11: {
@ -86,16 +127,28 @@ addLayer("sp", {
"main-display",
["row", ["prestige-button", ["clickable", 11]]],
"resource-display",
["raw-html", () =>
"You have " + getTotalSuperLevel() + " super level" + (getTotalSuperLevel().eq(1) ? "" : "s") + "."
],
["raw-html", () => "You have " + getTotalSuperLevel() + " super level" + (getTotalSuperLevel().eq(1) ? "" : "s") + "."],
"blank",
"blank",
["bar", "eta"],
["bar", "theta"],
["bar", "iota"],
["bar", "kappa"],
["bar", "lambda"],
]
},
"super buyables": {
content: [
"main-display",
["row", ["prestige-button", ["clickable", 11]]],
"resource-display",
["raw-html", () => "You have " + getTotalSuperLevel() + " super level" + (getTotalSuperLevel().eq(1) ? "" : "s") + "."],
"blank",
"blank",
"buyables",
],
unlocked() { return getTotalSuperLevel().gte(18) }
},
},
layerShown(){ return player.points.gte(10000) || player[this.layer].unlocked },
branches: ['p'],

View file

@ -3,7 +3,7 @@ let modInfo = {
id: "nif/pbic",
author: "Nif",
pointsName: "points",
modFiles: ["ranks.js", "levels.js", "progress.js", "super progress.js", "files.js", "tree.js"],
modFiles: ["data/ranks.js", "data/levels.js", "data/progress.js", "data/super progress.js", "data/files.js", "data/integrals.js", "data/achievements.js", "data/tree.js"],
discordName: "",
discordLink: "",
@ -21,7 +21,7 @@ let changelog = `<h1>Changelog:</h1><br><br>
<h3>v1.0</h3><br>
- I've given up trying to log all of the changes I'm making.`
let winText = `Download 100% complete.<br><br>You won! Congratulations!<br>Beyond this point may be unbalanced / incomplete, proceed with caution!`
let winText = `Download 100% complete.<br><br>You won! Congratulations!<br>More content coming soon...`
// If you add new functions anywhere inside of a layer, and those functions have an effect when called, add them here.
// (The ones here are examples, all official functions are already taken care of)
@ -47,18 +47,21 @@ function getPointGen() {
gain = gain.mul(getGammaEffect())
gain = gain.mul(getDeltaEffect())
gain = gain.mul(getZetaEffect())
gain = gain.mul(getKappaEffect())
gain = gain.mul(getLambdaEffect())
gain = gain.mul(tmp.ach.effect)
if (hasMilestone('f', 0)) gain = gain.mul(getTotalLevel().add(1).log(5).add(1))
if (hasMilestone('f', 1)) gain = gain.mul(3)
// exponentiative
if (gain.gte(1)) {
gain = gain.pow(getEpsilonEffect())
gain = gain.pow(getIotaEffect())
gain = gain.pow(buyableEffect('sp', 12))
if (hasMilestone('f', 3)) gain = gain.pow(2)
if (hasUpgrade('f', 11)) gain = gain.pow(upgradeEffect('f', 11))
}
// softcaps
gain = softcap(gain, 1000, d => d.add(1).log(1.01))
gain = softcap(gain, getKappaEffect().mul(1000), d => d.add(1).log(Math.E).add(1).pow(2).sub(1).div(2))
gain = softcap(gain, Decimal.pow(2, 128), _ => new Decimal(0), player.points)
return gain
}
@ -69,12 +72,12 @@ function addedPlayerData() { return {
// Display extra things at the top of the page
var displayThings = [
"All exponentiative upgrades only take affect above 1.",
() => getPointGen().gte(1000) ? "Your points per second are being logarithmically softcapped over 1000/s" : ""
() => getPointGen().gte(getKappaEffect().mul(1000)) ? "Your points per second are being logarithmically softcapped over " + getKappaEffect().mul(1000) + "/s" : ""
]
// Determines when the game "ends"
function isEndgame() {
return player.f.total.gte(40)
return player.i.points.gt(0)
}