diff --git a/docs/layer-features.md b/docs/layer-features.md
index 98bdf9c..7d9bc66 100644
--- a/docs/layer-features.md
+++ b/docs/layer-features.md
@@ -89,8 +89,9 @@ Key:
- type: Determines which prestige formula you use.
"normal": The amount of currency you gain is independent of its current amount (like Prestige).
formula before bonuses is based on `baseResource^exponent`
- "static: The cost is dependent on your total after reset.
+ "static": The cost is dependent on your total after reset.
formula before bonuses is based on `base^(x^exponent)`
+ "custom": You can define everything, from the calculations to the text on the button, yourself. (See more at the bottom)
- exponent: Used as described above.
@@ -138,4 +139,24 @@ Key:
for any not-yet-unlocked layers in this list increases. This can be used to make them harder to unlock.
- should_notify: **optional**, a function to return true if this layer should be highlighted in the tree.
- The layer will automatically be highlighted if you can buy an upgrade whether you have this or not.
\ No newline at end of file
+ The layer will automatically be highlighted if you can buy an upgrade whether you have this or not.
+
+
+# Custom Prestige type only
+(No effect otherwise)
+
+- prestigeButtonText(): **Only for custom prestige type**, Function that returns the entirety of the text that should
+ be displayed on the prestige button.You can use HTML as well!
+
+- getResetGain(): **Only for custom prestige type**, Returns how many points you should get if you reset now. You can call
+ getResetGain(this.layer, useType = "static") or similar to calculate what your gain would be under another
+ prestige type (provided you have all of the required features in the layer.)
+
+- getNextAt(canMax=false): **Only for custom prestige type**, Returns how many of the base currency you need to get to
+ the next point. canMax is an optional variable used with Static-ish layers to differentiate between if
+ it's looking for the first point you can reset at, or the requirement for any gain at all.
+ (Supporting both is good). You can also call getNextAt(this.layer, canMax=false, useType = "static")
+ or similar to calculate what your next at would be under another prestige type (provided you have
+ all of the required features in the layer.)
+
+- canReset(): **Only for custom prestige type**, return true only if you have the resources required to do a prestige here.
\ No newline at end of file
diff --git a/docs/milestones.md b/docs/milestones.md
index 9af8fd2..4510939 100644
--- a/docs/milestones.md
+++ b/docs/milestones.md
@@ -29,6 +29,8 @@ Milestone features:
the value being toggled is stored in, and the second is the internal name of the variable to toggle.
(e.g. [["b", "auto"], ["g", "auto"])
+ **Tip:** Toggles are not de-set if the milestone becomes locked! In this case, you should also check if the player has the milestone.
+
- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
- id: **Assigned automagically**. It's the id for this milestone.
diff --git a/index.html b/index.html
index 1e25222..eee263d 100644
--- a/index.html
+++ b/index.html
@@ -52,6 +52,7 @@
v1.3: Tabbing out
Added subtabs! And also a Micro-tab component to let you make smaller subtab-esque areas anywhere.
+
Added a "custom" prestige formula type, and a number of features to support it.
Added points/sec display (can be disabled).
Added h-line, v-line and image-display components, plus components for individual upgrades, challenges, and milestones.
Added upgEffect, buyableEffect, and challEffect functions.
@@ -166,15 +167,9 @@
-
-
-
-
-
-
-
-
+
+
diff --git a/js/game.js b/js/game.js
index fa7468c..e53121d 100644
--- a/js/game.js
+++ b/js/game.js
@@ -48,38 +48,51 @@ function convertToDecimal() {
}
}
-function getResetGain(layer) {
+function getResetGain(layer, useType = null) {
+ let type = useType
+ if (!useType) type = layers[layer].type
+
if (tmp.gainExp[layer].eq(0)) return new Decimal(0)
- if (layers[layer].type=="static") {
+ if (type=="static") {
if ((!layers[layer].canBuyMax()) || tmp.layerAmt[layer].lt(tmp.layerReqs[layer])) return new Decimal(1)
let gain = tmp.layerAmt[layer].div(tmp.layerReqs[layer]).div(tmp.gainMults[layer]).max(1).log(layers[layer].base).times(tmp.gainExp[layer]).pow(Decimal.pow(layers[layer].exponent, -1))
return gain.floor().sub(player[layer].points).add(1).max(1);
- } else {
+ } else if (type=="normal"){
if (tmp.layerAmt[layer].lt(tmp.layerReqs[layer])) return new Decimal(0)
let gain = tmp.layerAmt[layer].div(tmp.layerReqs[layer]).pow(layers[layer].exponent).times(tmp.gainMults[layer]).pow(tmp.gainExp[layer])
if (gain.gte("e1e7")) gain = gain.sqrt().times("e5e6")
return gain.floor().max(0);
+ } else if (type=="custom"){
+ return layers[layer].getResetGain()
+ } else {
+ return new Decimal(0)
}
}
-function getNextAt(layer, disp=false) {
+function getNextAt(layer, canMax=false, useType = null) {
+ let type = useType
+ if (!useType) type = layers[layer].type
+
if (tmp.gainExp[layer].eq(0)) return new Decimal(1/0)
- if (layers[layer].type=="static")
+ if (type=="static")
{
- if (!layers[layer].canBuyMax()) disp = false
- let amt = player[layer].points.plus((disp&&tmp.layerAmt[layer].gte(tmp.nextAt[layer]))?tmp.resetGain[layer]:0)
+ if (!layers[layer].canBuyMax()) canMax = false
+ let amt = player[layer].points.plus((canMax&&tmp.layerAmt[layer].gte(tmp.nextAt[layer]))?tmp.resetGain[layer]:0)
let extraCost = Decimal.pow(layers[layer].base, amt.pow(layers[layer].exponent).div(tmp.gainExp[layer])).times(tmp.gainMults[layer])
let cost = extraCost.times(tmp.layerReqs[layer]).max(tmp.layerReqs[layer])
if (layers[layer].resCeil) cost = cost.ceil()
return cost;
- } else {
+ } else if (type=="normal"){
let next = tmp.resetGain[layer].add(1)
if (next.gte("e1e7")) next = next.div("e5e6").pow(2)
next = next.root(tmp.gainExp[layer]).div(tmp.gainMults[layer]).root(layers[layer].exponent).times(tmp.layerReqs[layer]).max(tmp.layerReqs[layer])
if (layers[layer].resCeil) next = next.ceil()
return next;
- }
-}
+ } else if (type=="custom"){
+ return layers[layer].getNextAt(canMax)
+ } else {
+ return new Decimal(0)
+ }}
// Return true if the layer should be highlighted. By default checks for upgrades only.
function shouldNotify(layer){
@@ -114,6 +127,16 @@ function fullLayerReset(layer) {
player[layer].upgrades = []
player[layer].milestones = []
player[layer].challs = []
+ if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)) {
+ if (player[layer].subtab == undefined) player[layer].subtab = {}
+ if (player[layer].subtab.mainTabs == undefined) player[layer].subtab.mainTabs = Object.keys(layers[layer].tabFormat)[0]
+ }
+
+ if (layers[layer].microtabs) {
+ if (player[layer].subtab == undefined) player[layer].subtab = {}
+ for (item in layers[layer].microtabs)
+ if (player[layer].subtab[item] == undefined) player[layer].subtab[item] = Object.keys(layers[layer].microtabs[item])[0]
+ }
resetBuyables(layer)
}
@@ -154,7 +177,10 @@ function doReset(layer, force=false) {
if (tmp.layerAmt[layer].lt(tmp.nextAt[layer])) return;
gain =(layers[layer].canBuyMax() ? gain : 1)
}
-
+ if (layers[layer].type=="custom") {
+ if (!tmp.canReset[layer]) return;
+ }
+
if (layers[layer].onPrestige)
layers[layer].onPrestige(gain)
diff --git a/js/layers.js b/js/layers.js
index e5bdc7c..0229c31 100644
--- a/js/layers.js
+++ b/js/layers.js
@@ -35,6 +35,7 @@ addLayer("c", {
}},
effectDescription() { // Optional text to describe the effects
eff = this.effect();
+ eff.waffleBoost = eff.waffleBoost.times(buyableEffect(this.layer, 11).first)
return "which are boosting waffles by "+format(eff.waffleBoost)+" and increasing the Ice Cream cap by "+format(eff.icecreamCap)
},
milestones: {
@@ -171,30 +172,60 @@ addLayer("c", {
],
incr_order: [], // Array of layer names to have their order increased when this one is first unlocked
+ microtabs: {
+ stuff: {
+ first: {
+ content: ["upgrades", ["display-text", function() {return "confirmed"}]]
+ },
+ second: {
+ content: [["upgrade", 11],
+ ["row", [["upgrade", 11], "blank", "blank", ["upgrade", 11],]],
+
+ ["display-text", function() {return "double confirmed"}]]
+ },
+ },
+ otherStuff: {
+ // There could be another set of microtabs here
+ }
+ },
+
// Optional, lets you format the tab yourself by listing components. You can create your own components in v.js.
tabFormat: {
- main:
- ["main-display",
- ["prestige-button", function() {return "Melt your points into "}],
- ["blank", "5px"], // Height
- ["raw-html", function() {return ""}],
- ["display-text",
- function() {return 'I have ' + format(player.points) + ' pointy points!'},
- {"color": "red", "font-size": "32px", "font-family": "Comic Sans MS"}],
- "h-line", "milestones", "blank", "upgrades", "challs"],
- thingies: [
- ["buyables", "150px"], "blank",
- ["row", [
- ["toggle", ["c", "beep"]], ["blank", ["30px", "10px"]], // Width, height
- ["display-text", function() {return "Beep"}], "blank", ["v-line", "200px"],
- ["column", [
- ["prestige-button", function() {return "Be redundant for "}, {'width': '150px', 'height': '30px'}],
- ["prestige-button", function() {return "Be redundant for "}, {'width': '150px', 'height': '30px'}],
- ]],
- ], {'width': '600px', 'height': '350px', 'background-color': 'green', 'border-style': 'solid'}],
- "blank",
- ["display-image", "discord.png"],
- ],
+ main: {
+ buttonStyle: {'color': 'orange'},
+ content:
+ ["main-display",
+ ["prestige-button", function() {return "Melt your points into "}],
+ ["blank", "5px"], // Height
+ ["raw-html", function() {return ""}],
+ ["display-text",
+ function() {return 'I have ' + format(player.points) + ' pointy points!'},
+ {"color": "red", "font-size": "32px", "font-family": "Comic Sans MS"}],
+ "h-line", "milestones", "blank", "upgrades", "challs"],
+ },
+ thingies: {
+ style: {'background-color': '#222222'},
+ buttonStyle: {'border-color': 'orange'},
+ content:[
+ ["buyables", "150px"], "blank",
+ ["row", [
+ ["toggle", ["c", "beep"]], ["blank", ["30px", "10px"]], // Width, height
+ ["display-text", function() {return "Beep"}], "blank", ["v-line", "200px"],
+ ["column", [
+ ["prestige-button", function() {return "Be redundant for "}, {'width': '150px', 'height': '30px'}],
+ ["prestige-button", function() {return "Be redundant for "}, {'width': '150px', 'height': '30px'}],
+ ]],
+ ], {'width': '600px', 'height': '350px', 'background-color': 'green', 'border-style': 'solid'}],
+ "blank",
+ ["display-image", "discord.png"],],
+ },
+ illuminati: {
+ content:[
+ ["raw-html", function() {return "
C O N F I R M E D
"}],
+ ["microtabs", "stuff", {'width': '600px', 'height': '350px', 'background-color': 'brown', 'border-style': 'solid'}]
+ ]
+ }
+
},
style() {return {
// 'background-color': '#3325CC'
@@ -205,6 +236,7 @@ addLayer("c", {
}
})
+// This layer is mostly minimal but it uses a custom prestige type
addLayer("f", {
startData() { return {
unl: false,
@@ -216,7 +248,7 @@ addLayer("f", {
resource: "farm points",
baseResource: "candies",
baseAmount() {return player.points},
- type: "static",
+ type: "custom", // A "Custom" type which is effectively static
exponent: 0.5,
base: 3,
resCeil: true,
@@ -229,7 +261,22 @@ addLayer("f", {
},
row: 1,
layerShown() {return true},
- branches: [["c", 1]] // Each pair corresponds to a line added to the tree when this node is unlocked. The letter is the other end of the line, and the number affects the color, 1 is default
+ branches: [["c", 1]], // Each pair corresponds to a line added to the tree when this node is unlocked. The letter is the other end of the line, and the number affects the color, 1 is default
+
+ // The following are only currently used for "custom" Prestige type:
+ prestigeButtonText() { //Is secretly HTML
+ if (!this.canBuyMax()) return "Hi! I'm a weird dinosaur and I'll give you a Farm Point in exchange for all of your candies and lollipops! (At least " + formatWhole(tmp.nextAt[layer]) + " candies)"
+ if (this.canBuyMax()) return "Hi! I'm a weird dinosaur and I'll give you " + formatWhole(tmp.resetGain[this.layer]) + " Farm Points in exchange for all of your candies and lollipops! (You'll get another one at " + format(tmp.nextAt[layer]) + " candies)"
+ },
+ getResetGain() {
+ return getResetGain(this.layer, useType = "static")
+ },
+ getNextAt(canMax=false) { //
+ return getNextAt(this.layer, canMax, useType = "static")
+ },
+ canReset() {
+ return tmp.layerAmt[this.layer].gte(tmp.nextAt[this.layer])
+ },
},
)
diff --git a/js/temp.js b/js/temp.js
index 708fe35..778f831 100644
--- a/js/temp.js
+++ b/js/temp.js
@@ -46,6 +46,8 @@ function updateTemp() {
if (!tmp.style) tmp.style = {}
if (!tmp.notify) tmp.notify = {}
if (!tmp.nextAtDisp) tmp.nextAtDisp = {}
+ if (!tmp.prestigeButtonText) tmp.prestigeButtonText = {}
+ if (!tmp.canReset) tmp.canReset = {}
for (layer in layers) {
if (layers[layer].color) tmp.layerColor[layer] = layers[layer].color()
@@ -59,6 +61,8 @@ function updateTemp() {
tmp.notify[layer] = shouldNotify(layer)
tmp.nextAtDisp[layer] = getNextAt(layer, true)
if (layers[layer].effectDescription) tmp.effectDescription[layer] = layers[layer].effectDescription()
+ if (layers[layer].canReset) tmp.canReset[layer] = layers[layer].canReset()
+ if (layers[layer].prestigeButtonText) tmp.prestigeButtonText[layer] = layers[layer].prestigeButtonText()
}
diff --git a/js/utils.js b/js/utils.js
index 4047317..d26502f 100644
--- a/js/utils.js
+++ b/js/utils.js
@@ -92,9 +92,15 @@ function getStartPlayer() {
playerdata[layer].upgrades = []
playerdata[layer].milestones = []
playerdata[layer].challs = []
- if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat))
- playerdata[layer].subtab = Object.keys(layers[layer].tabFormat)[0]
-
+ if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)) {
+ playerdata[layer].subtab = {}
+ playerdata[layer].subtab.mainTabs = Object.keys(layers[layer].tabFormat)[0]
+ }
+ if (layers[layer].microtabs) {
+ if (playerdata[layer].subtab == undefined) playerdata[layer].subtab = {}
+ for (item in layers[layer].microtabs)
+ playerdata[layer].subtab[item] = Object.keys(layers[layer].microtabs[item])[0]
+ }
}
return playerdata
}
@@ -133,8 +139,17 @@ function fixSave() {
}
}
- if (player[layer].subtab == undefined && layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat))
- player[layer].subtab = Object.keys(layers[layer].tabFormat)[0]
+ if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)) {
+ if (player[layer].subtab == undefined) player[layer].subtab = {}
+ if (player[layer].subtab.mainTabs == undefined) player[layer].subtab.mainTabs = Object.keys(layers[layer].tabFormat)[0]
+ }
+
+ if (layers[layer].microtabs) {
+ if (player[layer].subtab == undefined) player[layer].subtab = {}
+ for (item in layers[layer].microtabs)
+ if (player[layer].subtab[item] == undefined) player[layer].subtab[item] = Object.keys(layers[layer].microtabs[item])[0]
+ }
+
}
}
diff --git a/js/v.js b/js/v.js
index 4abea8d..79fbf7c 100644
--- a/js/v.js
+++ b/js/v.js
@@ -210,6 +210,7 @@ function loadVue() {
+
`
@@ -256,6 +257,38 @@ function loadVue() {
`
})
+ // data = button size, in px
+ Vue.component('microtabs', {
+ props: ['layer', 'data'],
+ computed: {
+ currentTab() {return player[layer].subtab[data]}
+ },
+ template: `
+
+
+
+
+
+
+ `
+ })
+
+
+ // NOT FOR USE IN STANDARD TAB FORMATTING
+ Vue.component('tab-buttons', {
+ props: ['layer', 'data', 'name'],
+ template: `
+