From d4e38ba2f6a03ab3d82319cc7826ace95921c937 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Thu, 8 Oct 2020 23:13:15 -0400 Subject: [PATCH 01/33] Gagues are real --- changelog.md | 6 ++++++ js/layerSupport.js | 8 +++++++- js/layers.js | 23 +++++++++++++++++++++++ js/temp.js | 26 ++++++++++++++++++++++++++ js/utils.js | 7 ++++++- js/v.js | 12 ++++++++++++ 6 files changed, 80 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index e0891f3..3399259 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,12 @@ #The Modding Tree changelog: +##v1.3.5 +- Completely automated convertToDecimal, now you never have to worry about it again. +- Branches can be defined without a color id. But they can also use hex values for color ids! +- Created a tutorial for getting started with TMT and Github. +- Page title is now automatically taken from mod name. + ##v1.3.4: 10/8/20 - Added "midsection" feature to add things to a tab's layout while still keeping the standard layout. - Fix for being able to buy more buyables than you should. diff --git a/js/layerSupport.js b/js/layerSupport.js index c41ccd7..b5badc2 100644 --- a/js/layerSupport.js +++ b/js/layerSupport.js @@ -85,4 +85,10 @@ function readData(data, args=null){ return data(args); else return data; -} \ No newline at end of file +} + +// This isn't worth making a .ts file over +const UP = 1 +const DOWN = 2 +const LEFT = 3 +const RIGHT = 4 \ No newline at end of file diff --git a/js/layers.js b/js/layers.js index 52be58a..09ee265 100644 --- a/js/layers.js +++ b/js/layers.js @@ -206,6 +206,29 @@ addLayer("c", { } }, + gagues: { + longBoi: { + fillColor:() => "#4BEC13", + // fillStyle:(), + baseColor:() => "#333333", + // baseStyle:(), + // textStyle:(), + + borderStyle() {return {'border-color': '#321188'}}, + direction:() => RIGHT, + width:() => "250px", + height:() => "250px", + progress() { + return (player.points.log().div(10)) + }, + display() { + return format(player.points) + " / 1e10" + }, + unl:() => true, + + }, + }, + // Optional, lets you format the tab yourself by listing components. You can create your own components in v.js. tabFormat: { "main tab": { diff --git a/js/temp.js b/js/temp.js index 83596e0..efaebd6 100644 --- a/js/temp.js +++ b/js/temp.js @@ -30,6 +30,8 @@ function setupTemp(){ } function updateTemp() { + for (layer in layers) tmp[layer] = {} + if (tmp.genPoints == undefined) tmp.genPoints = false @@ -143,6 +145,13 @@ function updateTemp() { updateBuyableTemp(layer) } } + + for (layer in layers) { + if(layers[layer].gagues !== undefined){ + tmp[layer].gagues = {} + updateGagueTemp(layer) + } + } } @@ -309,4 +318,21 @@ function setupBuyableTemp(layer) { } } +} + + +// The start of not being backwards with tmp +function updateGagueTemp(layer) { + if (layers[layer] === undefined) return + let gagues = layers[layer].gagues + for (id in gagues) { + tmp[layer].gagues[id] = {} + for (item in gagues[id]) { + let thing = gagues[id][item] + if (isFunction(thing)) + tmp[layer].gagues[id] = thing() + else + tmp[layer].gagues[id] = thing + } + } } \ No newline at end of file diff --git a/js/utils.js b/js/utils.js index 73c460b..71e3a76 100644 --- a/js/utils.js +++ b/js/utils.js @@ -413,4 +413,9 @@ document.onkeydown = function(e) { var onFocused = false function focused(x) { onFocused = x -} \ No newline at end of file +} + +function isFunction(obj) { + return !!(obj && obj.constructor && obj.call && obj.apply); + }; + \ No newline at end of file diff --git a/js/v.js b/js/v.js index caf155f..15b3b24 100644 --- a/js/v.js +++ b/js/v.js @@ -245,6 +245,18 @@ function loadVue() { ` }) + // data = id of gague + Vue.component('gague', { + props: ['layer', 'data'], + template: ` +
+ ` + }) + + // NOT FOR USE IN STANDARD TAB FORMATTING Vue.component('tab-buttons', { From 6268caea20f53b81670fb936f747299372311c9b Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Fri, 9 Oct 2020 23:16:29 -0400 Subject: [PATCH 02/33] Automated temp and changed basically everything in the process --- changelog.md | 3 + docs/buyables.md | 4 +- docs/challenges.md | 2 +- docs/layer-features.md | 4 - docs/subtabs-and-microtabs.md | 2 +- docs/upgrades.md | 2 +- index.html | 31 ++- js/game.js | 68 +++--- js/layers.js | 29 ++- js/saves.js | 3 - js/temp.js | 377 ++++++---------------------------- js/utils.js | 19 +- js/v.js | 114 +++++----- 13 files changed, 206 insertions(+), 452 deletions(-) delete mode 100644 js/saves.js diff --git a/changelog.md b/changelog.md index 3399259..6751291 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,9 @@ #The Modding Tree changelog: + +effectDisplay in Challenges and Upgrades no longer takes an argument + ##v1.3.5 - Completely automated convertToDecimal, now you never have to worry about it again. - Branches can be defined without a color id. But they can also use hex values for color ids! diff --git a/docs/buyables.md b/docs/buyables.md index 69b2ccb..6986d34 100644 --- a/docs/buyables.md +++ b/docs/buyables.md @@ -29,9 +29,9 @@ Features: - title: **optional**, displayed at the top in a larger font It can also be a function that returns updating text. -- cost(x): cost for buying xth buyable, can be an object if there are multiple currencies +- cost(): cost for buying xth buyable, can be an object if there are multiple currencies -- effect(x): **optional**, A function that calculates and returns the current values of bonuses +- effect(): **optional**, A function that calculates and returns the current values of bonuses for having x of this buyable. Can return a value or an object containing multiple values. - display(): A function returning everything that should be displayed on the rebuyable after the title, likely diff --git a/docs/challenges.md b/docs/challenges.md index f8f1a23..0cb98c5 100644 --- a/docs/challenges.md +++ b/docs/challenges.md @@ -35,7 +35,7 @@ Individual Challenges can have these features: - effect(): **optional**, A function that calculates and returns the current values of any bonuses from the reward. Can return a value or an object containing multiple values. Can use basic HTML. -- effectDisplay(effects): **optional**, A function that returns a display of the current effects of the reward with +- effectDisplay(): **optional**, A function that returns a display of the current effects of the reward with formatting. Default behavior is to just display the a number appropriately formatted. - goal: A Decimal for the cost of the upgrade. By default, the goal is in basic Points. diff --git a/docs/layer-features.md b/docs/layer-features.md index c688179..7299b7b 100644 --- a/docs/layer-features.md +++ b/docs/layer-features.md @@ -138,10 +138,6 @@ Key: - automate(): **optional**, this function is called every game tick, after production. Use it to activate any autobuyers or auto-resets or similar on this layer, if appropriate. -- updateTemp(): **optional**, this function is called every game tick. use it to update anything in the "tmp" object. - You don't really need it. tmp is used as a way to store calculated values so it doesn't repeat - calculations. - - resetsNothing(): **optional**, returns true if this layer shouldn't trigger any resets when you prestige. - incr_order: **optional**, an array of layer ids. When this layer is unlocked for the first time, the "order" value diff --git a/docs/subtabs-and-microtabs.md b/docs/subtabs-and-microtabs.md index 091bda7..2302c3a 100644 --- a/docs/subtabs-and-microtabs.md +++ b/docs/subtabs-and-microtabs.md @@ -44,7 +44,7 @@ Normal subtabs and microtab subtabs both use the same features: - content: The tab layout code for the subtab, in [the tab layout format](custom-tab-layouts.md) -- style(: **Optional**, A function returning a CSS object, which affects the CSS when in that subtab. +- style(): **Optional**, A function returning a CSS object, which affects the CSS when in that subtab. - buttonStyle(): **Optional**, A function returning a CSS object, which affects the appearance of the button for that subtab. diff --git a/docs/upgrades.md b/docs/upgrades.md index b908a89..d43d871 100644 --- a/docs/upgrades.md +++ b/docs/upgrades.md @@ -34,7 +34,7 @@ Individual upgrades can have these features: - effect(): **optional**, A function that calculates and returns the current values of any bonuses from the upgrade. Can return a value or an object containing multiple values. -- effectDisplay(effects): **optional**, A function that returns a display of the current effects of the upgrade with +- effectDisplay(): **optional**, A function that returns a display of the current effects of the upgrade with formatting. Default behavior is to just display the a number appropriately formatted. Can use basic HTML. - cost: A Decimal for the cost of the upgrade. By default, upgrades cost the main prestige currency for the layer. diff --git a/index.html b/index.html index 0d98709..50a9cc9 100644 --- a/index.html +++ b/index.html @@ -15,7 +15,6 @@ - @@ -172,33 +171,33 @@
-
+



- - -
You have {{formatWhole(tmp.layerAmt[layer])}} {{layers[layer].baseResource}}
+ + +
You have {{formatWhole(tmp[layer].baseAmt)}} {{tmp[layer].baseResource}}


- Your best {{layers[layer].resource}} is {{formatWhole(player[layer].best)}}
- You have made a total of {{formatWhole(player[layer].total)}} {{layers[layer].resource}}
- + Your best {{tmp[layer].resource}} is {{formatWhole(player[layer].best)}}
+ You have made a total of {{formatWhole(player[layer].total)}} {{tmp[layer].resource}}
+
- +
- - - + + +

- +
-
+
- +
- +
diff --git a/js/game.js b/js/game.js index d6d1225..a0a5e9c 100644 --- a/js/game.js +++ b/js/game.js @@ -1,5 +1,4 @@ var player; -var tmp = {}; var needCanvasUpdate = true; var NaNalert = false; var gameEnded = false; @@ -39,14 +38,14 @@ 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 (tmp[layer].gainExp.eq(0)) return new Decimal(0) 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)) + if ((!layers[layer].canBuyMax()) || tmp[layer].baseAmount.lt(tmp[layer].requires)) return new Decimal(1) + let gain = tmp[layer].baseAmount.div(tmp[layer].requires).div(tmp[layer].gainMult).max(1).log(layers[layer].base).times(tmp[layer].gainExp).pow(Decimal.pow(layers[layer].exponent, -1)) return gain.floor().sub(player[layer].points).add(1).max(1); } 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 (tmp[layer].baseAmount.lt(tmp[layer].requires)) return new Decimal(0) + let gain = tmp[layer].baseAmount.div(tmp[layer].requires).pow(layers[layer].exponent).times(tmp[layer].gainMult).pow(tmp[layer].gainExp) if (gain.gte("e1e7")) gain = gain.sqrt().times("e5e6") return gain.floor().max(0); } else if (type=="custom"){ @@ -60,19 +59,19 @@ 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 (tmp[layer].gainExp.eq(0)) return new Decimal(1/0) if (type=="static") { 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]) + let amt = player[layer].points.plus((canMax&&tmp[layer].baseAmount.gte(tmp[layer].nextAt))?tmp[layer].resetGain:0) + let extraCost = Decimal.pow(layers[layer].base, amt.pow(layers[layer].exponent).div(tmp[layer].gainExp)).times(tmp[layer].gainMult) + let cost = extraCost.times(tmp[layer].requires).max(tmp[layer].requires) if (layers[layer].resCeil) cost = cost.ceil() return cost; } else if (type=="normal"){ - let next = tmp.resetGain[layer].add(1) + let next = tmp[layer].resetGain.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]) + next = next.root(tmp[layer].gainExp.div(tmp[layer].gainMult).root(layers[layer].exponent).times(tmp[layer].requires).max(tmp[layer].requires)) if (layers[layer].resCeil) next = next.ceil() return next; } else if (type=="custom"){ @@ -85,7 +84,7 @@ function getNextAt(layer, canMax=false, useType = null) { function shouldNotify(layer){ for (id in layers[layer].upgrades){ if (!isNaN(id)){ - if (canAffordUpg(layer, id) && !hasUpg(layer, id) && tmp.upgrades[layer][id].unl){ + if (canAffordUpg(layer, id) && !hasUpg(layer, id) && tmp[layer].upgrades[id].unl){ return true } } @@ -98,6 +97,16 @@ function shouldNotify(layer){ return false } +function canReset(layer) +{ + if(tmp[layer].type == "normal") + return tmp[layer].baseAmount.gte(tmp[layer].requires) + else if(tmp[layer].type== "static") + return tmp[layer].baseAmount.gte(tmp[layer].nextAt) + else + return layers[layer].canReset() +} + function rowReset(row, layer) { for (lr in ROW_LAYERS[row]){ if(layers[lr].doReset) { @@ -150,7 +159,7 @@ function addPoints(layer, gain) { } function generatePoints(layer, diff) { - addPoints(layer, tmp.resetGain[layer].times(diff)) + addPoints(layer, tmp[layer].resetGain.times(diff)) } var prevOnReset @@ -158,14 +167,14 @@ var prevOnReset function doReset(layer, force=false) { let row = layers[layer].row if (!force) { - if (tmp.layerAmt[layer].lt(tmp.layerReqs[layer])) return; - let gain = tmp.resetGain[layer] + if (tmp[layer].baseAmount.lt(tmp[layer].requires)) return; + let gain = tmp[layer].resetGain if (layers[layer].type=="static") { - if (tmp.layerAmt[layer].lt(tmp.nextAt[layer])) return; + if (tmp[layer].baseAmount.lt(tmp[layer].nextAt)) return; gain =(layers[layer].canBuyMax() ? gain : 1) } if (layers[layer].type=="custom") { - if (!tmp.canReset[layer]) return; + if (!tmp[layer].canReset) return; } if (layers[layer].onPrestige) @@ -185,10 +194,10 @@ function doReset(layer, force=false) { } } - tmp.layerAmt[layer] = new Decimal(0) // quick fix + tmp[layer].baseAmount = new Decimal(0) // quick fix } - if (layers[layer].resetsNothing && layers[layer].resetsNothing()) return + if (tmp[layer].resetsNothing) return for (layerResetting in layers) { @@ -201,7 +210,6 @@ function doReset(layer, force=false) { for (let x = row; x >= 0; x--) rowReset(x, layer) prevOnReset = undefined - setupTemp(); updateTemp() updateTemp() } @@ -216,7 +224,7 @@ function respecBuyables(layer) { function canAffordUpg(layer, id) { let upg = layers[layer].upgrades[id] - let cost = tmp.upgrades[layer][id].cost + let cost = tmp[layer].upgrades[id].cost return canAffordPurchase(layer, upg, cost) } @@ -233,15 +241,15 @@ function hasChall(layer, id){ } function upgEffect(layer, id){ - return (tmp.upgrades[layer][id].effect) + return (tmp[layer].upgrades[id].effect) } function challEffect(layer, id){ - return (tmp.challs[layer][id].effect) + return (tmp[layer].challs[id].effect) } function buyableEffect(layer, id){ - return (tmp.buyables[layer][id].effect) + return (tmp[layer].buyables[id].effect) } function canAffordPurchase(layer, thing, cost) { @@ -265,7 +273,7 @@ function buyUpg(layer, id) { if (!layers[layer].upgrades[id].unl()) return if (player[layer].upgrades.includes(id)) return let upg = layers[layer].upgrades[id] - let cost = tmp.upgrades[layer][id].cost + let cost = tmp[layer].upgrades[id].cost if (upg.currencyInternalName){ let name = upg.currencyInternalName @@ -290,8 +298,8 @@ function buyUpg(layer, id) { function buyMaxBuyable(layer, id) { if (!player[layer].unl) return - if (!tmp.buyables[layer][id].unl) return - if (!tmp.buyables[layer][id].canAfford) return + if (!tmp[layer].buyables[id].unl) return + if (!tmp[layer].buyables[id].canAfford) return if (!layers[layer].buyables[id].buyMax) return layers[layer].buyables[id].buyMax() @@ -300,8 +308,8 @@ function buyMaxBuyable(layer, id) { function buyBuyable(layer, id) { if (!player[layer].unl) return - if (!tmp.buyables[layer][id].unl) return - if (!tmp.buyables[layer][id].canAfford) return + if (!tmp[layer].buyables[id].unl) return + if (!tmp[layer].buyables[id].canAfford) return layers[layer].buyables[id].buy() updateBuyableTemp(layer) diff --git a/js/layers.js b/js/layers.js index c6cbe20..62db90a 100644 --- a/js/layers.js +++ b/js/layers.js @@ -97,7 +97,7 @@ addLayer("c", { if (ret.gte("1e20000000")) ret = ret.sqrt().times("1e10000000") return ret; }, - effectDisplay(fx) { return format(fx)+"x" }, // Add formatting to the effect + effectDisplay() { return format(this.effect())+"x" }, // Add formatting to the effect }, 13: { desc:() => "Unlock a secret subtab and make this layer act if you unlocked it first.", @@ -132,12 +132,12 @@ addLayer("c", { respecText:() => "Respec Thingies", // Text on Respec button, optional 11: { title:() => "Exhancers", // Optional, displayed at the top in a larger font - cost(x) { // cost for buying xth buyable, can be an object if there are multiple currencies + cost(x=player[this.layer].buyables[this.id]) { // cost for buying xth buyable, can be an object if there are multiple currencies if (x.gte(25)) x = x.pow(2).div(25) let cost = Decimal.pow(2, x.pow(1.5)) return cost.floor() }, - effect(x) { // Effects of owning x of the items, x is a decimal + effect(x=player[this.layer].buyables[this.id]) { // Effects of owning x of the items, x is a decimal let eff = {} if (x.gte(0)) eff.first = Decimal.pow(25, x.pow(1.1)) else eff.first = Decimal.pow(1/25, x.times(-1).pow(1.1)) @@ -147,16 +147,16 @@ addLayer("c", { return eff; }, display() { // Everything else displayed in the buyable button after the title - let data = tmp.buyables[this.layer][this.id] + let data = tmp[this.layer].buyables[this.id] return "Cost: " + format(data.cost) + " lollipops\n\ Amount: " + player[this.layer].buyables[this.id] + "\n\ Adds + " + format(data.effect.first) + " things and multiplies stuff by " + format(data.effect.second) }, unl() { return player[this.layer].unl }, canAfford() { - return player[this.layer].points.gte(tmp.buyables[this.layer][this.id].cost)}, + return player[this.layer].points.gte(tmp[this.layer].buyables[this.id].cost)}, buy() { - cost = tmp.buyables[this.layer][this.id].cost + cost = tmp[this.layer].buyables[this.id].cost player[this.layer].points = player[this.layer].points.sub(cost) player[this.layer].buyables[this.id] = player[this.layer].buyables[this.id].add(1) player[this.layer].spentOnBuyables = player[this.layer].spentOnBuyables.add(cost) // This is a built-in system that you can use for respeccing but it only works with a single Decimal value @@ -173,8 +173,6 @@ addLayer("c", { }, // Do any gameloop things (e.g. resource generation) inherent to this layer automate() { }, // Do any automation inherent to this layer if appropriate - updateTemp() { - }, // Do any necessary temp updating, not that important usually resetsNothing() {return false}, onPrestige(gain) { return @@ -232,7 +230,7 @@ addLayer("c", { buttonStyle() {return {'color': 'orange'}}, content: ["main-display", - ["prestige-button", function() {return "Melt your points into "}], + "prestige-button", ["blank", "5px"], // Height ["raw-html", function() {return ""}], ["display-text", @@ -249,8 +247,8 @@ addLayer("c", { ["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'}], + ["prestige-button", "", {'width': '150px', 'height': '80px'}], + ["prestige-button", "", {'width': '100px', 'height': '150px'}], ]], ], {'width': '600px', 'height': '350px', 'background-color': 'green', 'border-style': 'solid'}], "blank", @@ -284,7 +282,8 @@ addLayer("c", { shouldNotify() { // Optional, layer will be highlighted on the tree if true. // Layer will automatically highlight if an upgrade is purchasable. return (player.c.buyables[11] == 1) - } + }, + resetDesc: "Melt your points into ", }) // This layer is mostly minimal but it uses a custom prestige type @@ -325,8 +324,8 @@ addLayer("f", { // 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 " + formatWhole(tmp.nextAtDisp[layer]) + " candies)" + 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[this.layer].nextAt) + " candies)" + if (this.canBuyMax()) return "Hi! I'm a weird dinosaur and I'll give you " + formatWhole(tmp[this.layer].resetGain) + " Farm Points in exchange for all of your candies and lollipops! (You'll get another one at " + formatWhole(tmp[layer].nextAtDisp) + " candies)" }, getResetGain() { return getResetGain(this.layer, useType = "static") @@ -335,7 +334,7 @@ addLayer("f", { return getNextAt(this.layer, canMax, useType = "static") }, canReset() { - return tmp.layerAmt[this.layer].gte(tmp.nextAt[this.layer]) + return tmp[this.layer].baseAmount.gte(tmp[this.layer].nextAt) }, }, ) diff --git a/js/saves.js b/js/saves.js deleted file mode 100644 index 021a823..0000000 --- a/js/saves.js +++ /dev/null @@ -1,3 +0,0 @@ -const SAVES = { - PRE_SUPER_BOOSTERS: "eyJ0YWIiOiJvcHRpb25zIiwidGltZSI6MTU5ODE5ODI4NjQ4OCwiYXV0b3NhdmUiOnRydWUsInBvaW50cyI6IjMuMzYwMTkyNjc5ODczNDgzZTQxNDMiLCJwIjp7InVubCI6dHJ1ZSwicG9pbnRzIjoiMi4xMjI1NzI5ODA3NjQzMTQ2ZTI3NjMiLCJ1cGdyYWRlcyI6WzExLDEyLDIxLDIyLDEzLDIzXSwiYmVzdCI6IjUxMDIyNjAwNiJ9LCJiIjp7InVubCI6dHJ1ZSwicG9pbnRzIjoiMTgwIiwidXBncmFkZXMiOlsxMSwxMiwxMywyMiwyMSwyM10sImJlc3QiOiIxODAiLCJhdXRvIjp0cnVlfSwiZyI6eyJ1bmwiOnRydWUsInBvaW50cyI6IjEzOSIsInBvd2VyIjoiMi4zNDMxNTg3NTczMjc0ODVlMzM5IiwidXBncmFkZXMiOlsxMSwxMiwxMywxNCwxNSwyMiwyMSwyMywyNCwyNV0sImJlc3QiOiIxMzkiLCJhdXRvIjp0cnVlfSwiZSI6eyJ1bmwiOnRydWUsInBvaW50cyI6IjEuNzAxNTAzNTMzMDU4MTA3NmU4NiIsImJlc3QiOiIxLjcwMTUwMzUzMzA1ODEwNzZlODYiLCJlbmhhbmNlcnMiOiIzMyIsInVwZ3JhZGVzIjpbMTEsMTIsMTMsMTQsMTUsMjEsMjMsMjIsMjQsMjVdLCJvcmRlciI6MH0sInQiOnsidW5sIjp0cnVlLCJvcmRlciI6MCwicG9pbnRzIjoiMTYiLCJiZXN0IjoiMTYiLCJlbmVyZ3kiOiIxLjA4MDMzODY3NDA5Mjg3NmU5NCIsImV4dENhcHN1bGVzIjoiMjYiLCJ1cGdyYWRlcyI6WzExLDEyLDEzLDE0LDIxLDIyLDIzLDI0LDMxLDMyLDMzXX0sInMiOnsidW5sIjp0cnVlLCJvcmRlciI6MCwicG9pbnRzIjoiMTYiLCJiZXN0IjoiMTYiLCJzcGVudCI6IjY4IiwiYnVpbGRpbmdzIjp7IjEiOiIxNyIsIjIiOiIyNiIsIjMiOiIxMyIsIjQiOiI4IiwiNSI6IjQifSwidXBncmFkZXMiOlsxMSwxMiwxMywxNCwyMSwyMywyNCwzMSwyMiwzMiwzMywzNF19LCJzYiI6eyJ1bmwiOmZhbHNlLCJvcmRlciI6MCwicG9pbnRzIjoiMCIsImJlc3QiOiIwIiwidXBncmFkZXMiOltdfSwidmVyc2lvblR5cGUiOiJhbHBoYSIsInZlcnNpb24iOjEwfQ==", -} \ No newline at end of file diff --git a/js/temp.js b/js/temp.js index efaebd6..b7046b6 100644 --- a/js/temp.js +++ b/js/temp.js @@ -1,338 +1,79 @@ -function setupTemp(){ - if (!tmp.challActive) {tmp.challActive = {}} - if (!tmp.challs) tmp.challs = {} - for (layer in layers) { - if(layers[layer].challs !== undefined){ - tmp.challActive[layer] = {} - setupChallTemp(layer) - } - } +var tmp = {} - if (!tmp.upgrades) tmp.upgrades = {} - for (layer in layers) { - if(layers[layer].upgrades !== undefined){ - setupUpgradeTemp(layer) - } +// Tmp will not call these +var activeFunctions = [ + "startData", "onPrestige", "doReset", "update", "automate", + "buy", "buyMax", "respec", "onComplete", "onPurchase", "onPress" +] + +function setupTemp() { + tmp = {} + setupTempData(layers, tmp) + + for (layer in layers){ + tmp[layer].resetGain = {} + tmp[layer].nextAt = {} + tmp[layer].nextAtDisp = {} + tmp[layer].notify = {} + tmp[layer].canReset = {} + tmp[layer].prestigeButtonText = {} } - - if (!tmp.milestones) tmp.milestones = {} - for (layer in layers) { - if(layers[layer].milestones !== undefined){ - setupMilestoneTemp(layer) +} + +function setupTempData(layerData, tmpData) { + tmp.pointGen = {} + + + for (item in layerData){ + if (layerData[item] == null) { + tmpData[item] = null } - } - if (!tmp.buyables) tmp.buyables = {} - for (layer in layers) if (layers[layer].buyables) { - if(layers[layer].buyables !== undefined){ - setupBuyableTemp(layer) + else if (Array.isArray(layerData[item])) { + tmpData[item] = [] + setupTempData(layerData[item], tmpData[item]) } - } + else if ((!!layerData[item]) && (layerData[item].constructor === Object)) { + tmpData[item] = {} + setupTempData(layerData[item], tmpData[item]) + } + else if (isFunction(layerData[item]) && !activeFunctions.includes(item)){ + tmpData[item] = {} + } else { + tmpData[item] = layerData[item] + } + } } function updateTemp() { - for (layer in layers) tmp[layer] = {} + if (tmp === undefined) + setupTemp() - if (tmp.genPoints == undefined) tmp.genPoints = false + updateTempData(layers, tmp) + for (layer in layers){ + tmp[layer].resetGain = getResetGain(layer) + tmp[layer].nextAt = getNextAt(layer) + tmp[layer].nextAtDisp = getNextAt(layer, true) + tmp[layer].notify = shouldNotify(layer) + tmp[layer].canReset = canReset(layer) + tmp[layer].prestigeButtonText = prestigeButtonText(layer) - if (!tmp.layerReqs) tmp.layerReqs = {} - for (layer in layers) tmp.layerReqs[layer] = layers[layer].requires() - - if (!tmp.layerEffs) tmp.layerEffs = {} - for (layer in layers) if (layers[layer].effect) tmp.layerEffs[layer] = layers[layer].effect() - - if (!tmp.gainMults) tmp.gainMults = {} - if (!tmp.gainExp) tmp.gainExp = {} - if (!tmp.resetGain) tmp.resetGain = {} - if (!tmp.nextAt) tmp.nextAt = {} - if (!tmp.layerAmt) tmp.layerAmt = {} - if (!tmp.layerColor) tmp.layerColor = {} - if (!tmp.layerShown) tmp.layerShown = {} - if (!tmp.effectDescription) tmp.effectDescription = {} - if (!tmp.style) tmp.style = {} - if (!tmp.nodeStyle) tmp.nodeStyle = {} - if (!tmp.notify) tmp.notify = {} - if (!tmp.nextAtDisp) tmp.nextAtDisp = {} - if (!tmp.prestigeButtonText) tmp.prestigeButtonText = {} - if (!tmp.canReset) tmp.canReset = {} - if (!tmp.tooltips) tmp.tooltips = {} - if (!tmp.tooltipsLocked) tmp.tooltipsLocked = {} - - for (layer in layers) { - if (layers[layer].color) tmp.layerColor[layer] = layers[layer].color() - if (layers[layer].style) tmp.style[layer] = layers[layer].style() - tmp.layerShown[layer] = layers[layer].layerShown() - tmp.layerAmt[layer] = layers[layer].baseAmount() - tmp.gainMults[layer] = layers[layer].gainMult() - tmp.gainExp[layer] = layers[layer].gainExp() - tmp.resetGain[layer] = getResetGain(layer) - tmp.nextAt[layer] = getNextAt(layer) - 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() - if (layers[layer].tooltip) tmp.tooltips[layer] = layers[layer].tooltip() - if (layers[layer].tooltipLocked) tmp.tooltipsLocked[layer] = layers[layer].tooltipLocked() - if (layers[layer].nodeStyle) tmp.nodeStyle[layer] = layers[layer].nodeStyle() } tmp.pointGen = getPointGen() - - for (layer in layers){ - if (layers[layer].updateTemp) layers[layer].updateTemp() - } - - if (!tmp.componentStyles) tmp.componentStyles = {} - for (layer in layers) if (layers[layer].componentStyles) { - if(layers[layer].componentStyles !== undefined){ - tmp.componentStyles[layer] = {} - for (item in layers[layer].componentStyles) - tmp.componentStyles[layer][item] = layers[layer].componentStyles[item]() - } - } - - - if (!tmp.microtabs) tmp.microtabs = {} - for (layer in layers) { - if (!tmp.microtabs[layer]) tmp.microtabs[layer] = {} - if (layers[layer].microtabs) { - if(layers[layer].microtabs !== undefined){ - updateMicrotabTemp(layer) - } - } - if(layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)){ - let data2 = layers[layer].tabFormat - let set = "mainTabs" - if (!tmp.microtabs[layer][set]) tmp.microtabs[layer][set] = {} - for (tab in data2) { - if (!tmp.microtabs[layer][set][tab]) - tmp.microtabs[layer][set][tab] = {} - if(data2[tab].style) - tmp.microtabs[layer][set][tab].style = data2[tab].style() - if(data2[tab].buttonStyle) - tmp.microtabs[layer][set][tab].buttonStyle = data2[tab].buttonStyle() - } - } - } - - - if (!tmp.challActive) {tmp.challActive = {}} - if (!tmp.challs) tmp.challs = {} - for (layer in layers) { - if(layers[layer].challs !== undefined){ - tmp.challActive[layer] = {} - updateChallTemp(layer) - } - } - - if (!tmp.upgrades) tmp.upgrades = {} - for (layer in layers) { - if(layers[layer].upgrades !== undefined){ - updateUpgradeTemp(layer) - } - } - - if (!tmp.milestones) tmp.milestones = {} - for (layer in layers) { - if(layers[layer].milestones !== undefined){ - updateMilestoneTemp(layer) - } - } - if (!tmp.buyables) tmp.buyables = {} - for (layer in layers) if (layers[layer].buyables) { - if(layers[layer].buyables !== undefined){ - updateBuyableTemp(layer) - } - } - - for (layer in layers) { - if(layers[layer].gagues !== undefined){ - tmp[layer].gagues = {} - updateGagueTemp(layer) - } - } } +function updateTempData(layerData, tmpData) { - -function updateChallTemp(layer) { - if (player[layer] === undefined) return - if (!tmp.challs[layer]) tmp.challs[layer] = {} - - let data = tmp.challActive[layer] - let data2 = layers[layer].challs - let customActive = data2.active !== undefined - for (let row = 1; row <= data2.rows; row++) { - for (let col = 1; col <= data2.cols; col++) { - let id = row * 10 + col - tmp.challs[layer][id] = {} - - if (customActive ? data2.active(id) : player[layer].active == id) data[id] = 1 - else delete data[id] - - tmp.challs[layer][id].unl = data2[id].unl() - if(data2[id].name) tmp.challs[layer][id].name = data2[id].name() - if(data2[id].desc) tmp.challs[layer][id].desc = data2[id].desc() - if(data2[id].reward) tmp.challs[layer][id].reward = data2[id].reward() - if(data2[id].effect) tmp.challs[layer][id].effect = data2[id].effect() - if(data2[id].effectDisplay) tmp.challs[layer][id].effectDisplay = data2[id].effectDisplay(tmp.challs[layer][id].effect) - tmp.challs[layer][id].goal = data2[id].goal() - if(data2[id].style) tmp.challs[layer][id].style = data2[id].style() + for (item in layerData){ + if (Array.isArray(layerData[item])) { + updateTempData(layerData[item], tmpData[item]) } - } -} - -function updateUpgradeTemp(layer) { - if (layers[layer] === undefined) return - if (!tmp.upgrades[layer]) tmp.upgrades[layer] = {} - - let data2 = layers[layer].upgrades - for (let row = 1; row <= data2.rows; row++) { - for (let col = 1; col <= data2.cols; col++) { - let id = row * 10 + col - tmp.upgrades[layer][id] = {} - tmp.upgrades[layer][id].unl = data2[id].unl() - if(data2[id].effect) tmp.upgrades[layer][id].effect = data2[id].effect() - tmp.upgrades[layer][id].cost = data2[id].cost() - if(data2[id].effectDisplay) tmp.upgrades[layer][id].effectDisplay = data2[id].effectDisplay(tmp.upgrades[layer][id].effect) - if(data2[id].desc) tmp.upgrades[layer][id].desc = data2[id].desc() - if(data2[id].title) tmp.upgrades[layer][id].title = data2[id].title() - if(data2[id].style) tmp.upgrades[layer][id].style = data2[id].style() + else if ((!!layerData[item]) && (layerData[item].constructor === Object)) { + updateTempData(layerData[item], tmpData[item]) } - } -} - -function updateMilestoneTemp(layer) { - if (layers[layer] === undefined) return - if (!tmp.milestones[layer]) tmp.milestones[layer] = {} - - let data2 = layers[layer].milestones - for (id in data2) { - tmp.milestones[layer][id] = {} - if(data2[id].unl) tmp.milestones[layer][id].unl = data2[id].unl() - tmp.milestones[layer][id].done = data2[id].done() - if(data2[id].requirementDesc) tmp.milestones[layer][id].requirementDesc = data2[id].requirementDesc() - if(data2[id].effectDesc) tmp.milestones[layer][id].effectDesc = data2[id].effectDesc() - if(data2[id].style) tmp.milestones[layer][id].style = data2[id].style() - - } -} - -function updateBuyableTemp(layer) { - if (layers[layer] === undefined) return - if (!tmp.buyables[layer]) tmp.buyables[layer] = {} - let data2 = layers[layer].buyables - if(data2.respecText) tmp.buyables[layer].respecText = data2.respecText() - for (let row = 1; row <= data2.rows; row++) { - for (let col = 1; col <= data2.cols; col++) { - let id = row * 10 + col - let amt = player[layer].buyables[id] - tmp.buyables[layer][id] = {} - tmp.buyables[layer][id].unl = data2[id].unl() - if(data2[id].effect) tmp.buyables[layer][id].effect = data2[id].effect(amt) - tmp.buyables[layer][id].cost = data2[id].cost(amt) - tmp.buyables[layer][id].canAfford = data2[id].canAfford() - if(data2[id].title) tmp.buyables[layer][id].title = data2[id].title() - if(data2[id].display) tmp.buyables[layer][id].display = data2[id].display() - if(data2[id].style) tmp.buyables[layer][id].style = data2[id].style() - + else if (isFunction(layerData[item]) && !activeFunctions.includes(item)){ + tmpData[item] = layerData[item]() } - } -} - -function updateMicrotabTemp(layer) { - if (layers[layer] === undefined) return - let data2 = layers[layer].microtabs - for (set in data2) { - if (!tmp.microtabs[layer][set]) tmp.microtabs[layer][set] = {} - for (tab in data2[set]) { - if (!tmp.microtabs[layer][set][tab]) - tmp.microtabs[layer][set][tab] = {} - if(data2[set][tab].style) - tmp.microtabs[layer][set][tab].style = data2[set][tab].style() - if(data2[set][tab].buttonStyle) - tmp.microtabs[layer][set][tab].buttonStyle = data2[set][tab].buttonStyle() - - } - } -} - - -function setupChallTemp(layer) { - if (player[layer] === undefined) return - if (!tmp.challs[layer]) tmp.challs[layer] = {} - - let data = tmp.challActive[layer] - let data2 = layers[layer].challs - let customActive = data2.active !== undefined - for (let row = 1; row <= data2.rows; row++) { - for (let col = 1; col <= data2.cols; col++) { - let id = row * 10 + col - - tmp.challs[layer][id] = {} - if(data2[id].effect) tmp.challs[layer][id].effect = {} - if(data2[id].style) tmp.challs[layer][id].style = {} - } - } -} - -function setupUpgradeTemp(layer) { - if (layers[layer] === undefined) return - if (!tmp.upgrades[layer]) tmp.upgrades[layer] = {} - - let data2 = layers[layer].upgrades - for (let row = 1; row <= data2.rows; row++) { - for (let col = 1; col <= data2.cols; col++) { - let id = row * 10 + col - tmp.upgrades[layer][id] = {} - if(data2[id].effect) tmp.upgrades[layer][id].effect = {} - if(data2[id].style) tmp.upgrades[layer][id].style = {} - } - } -} - -function setupMilestoneTemp(layer) { - if (layers[layer] === undefined) return - if (!tmp.milestones[layer]) tmp.milestones[layer] = {} - - let data2 = layers[layer].milestones - for (id in data2) { - tmp.milestones[layer][id] = {} - if(data2[id].style) tmp.milestones[layer][id].style = {} - } -} - -function setupBuyableTemp(layer) { - if (layers[layer] === undefined) return - if (!tmp.buyables[layer]) tmp.buyables[layer] = {} - let data2 = layers[layer].buyables - for (let row = 1; row <= data2.rows; row++) { - for (let col = 1; col <= data2.cols; col++) { - let id = row * 10 + col - let amt = player[layer].buyables[id] - tmp.buyables[layer][id] = {} - if(data2[id].effect) tmp.buyables[layer][id].effect = {} - tmp.buyables[layer][id].cost = {} - if(data2[id].style) tmp.buyables[layer][id].style = {} - - } - } -} - - -// The start of not being backwards with tmp -function updateGagueTemp(layer) { - if (layers[layer] === undefined) return - let gagues = layers[layer].gagues - for (id in gagues) { - tmp[layer].gagues[id] = {} - for (item in gagues[id]) { - let thing = gagues[id][item] - if (isFunction(thing)) - tmp[layer].gagues[id] = thing() - else - tmp[layer].gagues[id] = thing - } - } + } } \ No newline at end of file diff --git a/js/utils.js b/js/utils.js index 764525c..eef5d86 100644 --- a/js/utils.js +++ b/js/utils.js @@ -333,7 +333,7 @@ function notifyLayer(name) { } function nodeShown(layer) { - if (tmp.layerShown[layer]) return true + if (tmp[layer].layerShown) return true switch(layer) { case "idk": return player.l.unl @@ -343,7 +343,7 @@ function nodeShown(layer) { } function layerUnl(layer) { - return LAYERS.includes(layer) && (player[layer].unl || (tmp.layerAmt[layer].gte(tmp.layerReqs[layer]) && layers[layer].layerShown())) + return LAYERS.includes(layer) && (player[layer].unl || (tmp[layer].baseAmount.gte(tmp[layer].requires) && layers[layer].layerShown())) } function keepGoing() { @@ -408,6 +408,21 @@ function focused(x) { onFocused = x } +function prestigeButtonText(layer) +{ + if(tmp[layer].type == "normal") + return `${ player[layer].points.lt(1e3) ? (tmp[layer].resetDesc !== undefined ? tmp[layer].resetDesc : "Reset for ") : ""}+${formatWhole(tmp[layer].resetGain)} ${tmp[layer].resource} ${tmp[layer].resetGain.lt(100) && player[layer].points.lt(1e3) ? `

Next at ${ (tmp[layer].resCeil ? formatWhole(tmp[layer].nextAt) : format(tmp[layer].nextAt))}` : ""} ${ tmp[layer].baseResource }` + else if(tmp[layer].type== "static") + return `${tmp[layer].resetDesc !== undefined ? tmp[layer].resetDesc : "Reset for "}+${formatWhole(tmp[layer].resetGain)} ${tmp[layer].resource}

${player[layer].points.lt(20) ? (tmp[layer].baseAmount.gte(tmp[layer].nextAt)&&(tmp[layer].canBuyMax !== undefined) && tmp[layer].canBuyMax?"Next":"Req") : ""}: ${formatWhole(tmp[layer].baseAmount)} / ${(tmp[layer].resCeil ? formatWhole(tmp[layer].nextAtDisp) : format(tmp[layer].nextAtDisp))} ${ tmp[layer].baseResource } + ` + else + return layers[layer].prestigeButtonText() +} + + + + + function isFunction(obj) { return !!(obj && obj.constructor && obj.call && obj.apply); }; diff --git a/js/v.js b/js/v.js index 923df0b..402a092 100644 --- a/js/v.js +++ b/js/v.js @@ -44,9 +44,9 @@ function loadVue() {
-
-
-
+
+
+
@@ -60,9 +60,9 @@ function loadVue() {
-
-
-
+
+
+
@@ -90,9 +90,9 @@ function loadVue() { props: ['layer'], template: `
-
-
- +
+
+
@@ -103,13 +103,13 @@ function loadVue() { Vue.component('chall', { props: ['layer', 'data'], template: ` -
-



-

-
- Goal: {{format(tmp.challs[layer][data].goal)}} {{layers[layer].challs[data].currencyDisplayName ? layers[layer].challs[data].currencyDisplayName : "points"}}
- Reward:
- Currently: +
+



+

+
+ Goal: {{format(tmp[layer].challs[data].goal)}} {{tmp[layer].challs[data].currencyDisplayName ? tmp[layer].challs[data].currencyDisplayName : "points"}}
+ Reward:
+ Currently:
` }) @@ -120,7 +120,7 @@ function loadVue() {
- +

@@ -132,12 +132,12 @@ function loadVue() { Vue.component('upgrade', { props: ['layer', 'data'], template: ` - ` }) @@ -147,8 +147,8 @@ function loadVue() { template: `
- - + +

@@ -160,17 +160,17 @@ function loadVue() { Vue.component('milestone', { props: ['layer', 'data'], template: ` - -


-
-   + +


+
+   ` }) Vue.component('toggle', { props: ['layer', 'data'], template: ` - + ` }) @@ -178,14 +178,10 @@ function loadVue() { Vue.component('prestige-button', { props: ['layer', 'data'], template: ` - - - - - + ` }) @@ -194,7 +190,7 @@ function loadVue() { Vue.component('main-display', { props: ['layer'], template: ` -
You have

{{formatWhole(player[layer].points)}}

{{layers[layer].resource}}, {{tmp.effectDescription[layer]}}

+
You have

{{formatWhole(player[layer].points)}}

{{tmp[layer].resource}}, {{tmp[layer].effectDescription}}

` }) @@ -203,10 +199,10 @@ function loadVue() { props: ['layer', 'data'], template: `
-
-
-
- +
+
+
+

@@ -219,12 +215,12 @@ function loadVue() { props: ['layer', 'data', 'size'], template: ` ` }) @@ -238,9 +234,9 @@ function loadVue() { template: `
- +
- +
` }) @@ -249,7 +245,7 @@ function loadVue() { Vue.component('gague', { props: ['layer', 'data'], template: ` -
@@ -264,7 +260,7 @@ function loadVue() { template: `
- +
` @@ -279,20 +275,20 @@ function loadVue() { showTab(layer) }" v-bind:tooltip=" - player[layer].unl ? (layers[layer].tooltip ? tmp.tooltips[layer] : formatWhole(player[layer].points) + ' ' + layers[layer].resource) - : (layers[layer].tooltipLocked ? tmp.tooltipsLocked[layer] : 'Reach ' + formatWhole(tmp.layerReqs[layer]) + ' ' + layers[layer].baseResource + ' to unlock (You have ' + formatWhole(tmp.layerAmt[layer]) + ' ' + layers[layer].baseResource + ')') + player[layer].unl ? (tmp[layer].tooltip ? tmp[layer].tooltip : formatWhole(player[layer].points) + ' ' + tmp[layer].resource) + : (tmp[layer].tooltipLocked ? tmp[layer].tooltipLocked : 'Reach ' + formatWhole(tmp[layer].requires) + ' ' + tmp[layer].baseResource + ' to unlock (You have ' + formatWhole(tmp[layer].baseAmount) + ' ' + tmp[layer].baseResource + ')') " v-bind:class="{ treeNode: true, [layer]: true, - hidden: !tmp.layerShown[layer], - locked: !player[layer].unl && !tmp.layerAmt[layer].gte(tmp.layerReqs[layer]), - notify: tmp.notify[layer], + hidden: !tmp[layer].layerShown, + locked: !player[layer].unl && !tmp[layer].baseAmount.gte(tmp[layer].requires), + notify: tmp[layer].notify, can: layerUnl(layer), }" v-bind:style="[layerUnl(layer) ? { - 'background-color': tmp.layerColor[layer], - } : {}, tmp.nodeStyle[layer]]"> + 'background-color': tmp[layer].color, + } : {}, tmp[layer].nodeStyle]"> {{abb}} ` From a7623e31803851ba55577b07b67948607322d299 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Fri, 9 Oct 2020 23:26:27 -0400 Subject: [PATCH 03/33] Updated documentation for the Tempocalypse --- docs/basic-layer-breakdown.md | 7 +++---- docs/buyables.md | 2 +- docs/challenges.md | 2 +- docs/layer-features.md | 26 +++++++++++++++----------- docs/milestones.md | 2 +- docs/subtabs-and-microtabs.md | 4 ++-- docs/upgrades.md | 4 ++-- 7 files changed, 25 insertions(+), 22 deletions(-) diff --git a/docs/basic-layer-breakdown.md b/docs/basic-layer-breakdown.md index 321ff7b..8846a90 100644 --- a/docs/basic-layer-breakdown.md +++ b/docs/basic-layer-breakdown.md @@ -1,8 +1,7 @@ # Basic layer breakdown This is a very minimal layer with minimal features. Most things will require additional features. -If you're curious about "() =>", it's a weird notation that lets you use either a value or function in the same slot, -and treats it like a function. You can use it to make actual functions, but it breaks things then. + ```js p: { @@ -12,14 +11,14 @@ and treats it like a function. You can use it to make actual functions, but it b // If you add non-standard Decimal variables, look at convertToDecimal }}, - color:() => "#FE0102", // The color for this layer, which affects many elements + color: "#FE0102", // The color for this layer, which affects many elements resource: "prestige points", // The name of this layer's main prestige resource row: 0, // The row this layer is on (0 is the first row) baseResource: "points", // The name of the resource your prestige gain is based on baseAmount() {return player.points}, // A function to return the current value of that resource - requires:() => new Decimal(200)}, // The amount of the base needed to gain 1 of the prestige currency. + requires: new Decimal(200)}, // The amount of the base needed to gain 1 of the prestige currency. // Also the amount required to unlock the layer. type: "normal", // Determines the formula used for calculating prestige currency. diff --git a/docs/buyables.md b/docs/buyables.md index 6986d34..95e84bd 100644 --- a/docs/buyables.md +++ b/docs/buyables.md @@ -45,7 +45,7 @@ Features: - buyMax(): **optional**, A function that implements buying as many of the buyable as possible. -- style(): **Optional**, A function returning a CSS object, which affects this buyable. +- style: **Optional**, A CSS object, which affects this buyable. - layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar diff --git a/docs/challenges.md b/docs/challenges.md index 0cb98c5..b684d98 100644 --- a/docs/challenges.md +++ b/docs/challenges.md @@ -54,7 +54,7 @@ By default, challenges use basic Points for the goal. You can change that using - currencyLayer: **optional**, the internal name of the layer that currency is stored in. If it's part of a layer, omit. -- style(): **Optional**, A function returning a CSS object, which affects this challenge. +- style: **Optional**, A CSS object, which affects this challenge. - layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar diff --git a/docs/layer-features.md b/docs/layer-features.md index 7299b7b..a0ab1db 100644 --- a/docs/layer-features.md +++ b/docs/layer-features.md @@ -3,6 +3,8 @@ This is a more comprehensive list of established features to add to layers. You can add more freely, if you want to have other functions or values associated with your layer. These have special functionality, though. +You can make almost any value dynamic by using a function in its place, including all display strings and styling/color features. + Key: - No label: This is required and the game will crash if it isn't included. - **sometimes required**: This is may be required, depending on other things in the layer. @@ -51,7 +53,7 @@ Key: ], ``` -- style(): **optional**, a function returning a CSS object containing any CSS that should affect this layer's whole tab. +- style: **optional**, a CSS object containing any CSS that should affect this layer's whole tab. - tabFormat: **optional**, use this if you want to add extra things to your tab or change the layout. [See here for more info.](custom-tab-layouts.md) @@ -110,6 +112,12 @@ Key: - onPrestige(gain): **optional**, A function that triggers when this layer prestiges, just before you gain the currency. Can be used to have secondary resource gain on prestige, or to recalculate things or whatnot. +- resetDesc: **optional**, use this to replace "Reset for " on the Prestige button with something else. + +- prestigeButtonText(): **Sometimes required**, Use this to make the entirety of the text a Prestige button contains. Only required for custom layers, + but usable by all types. + + # Tree/node features @@ -117,7 +125,7 @@ Key: in the list. Alternatively, an entry in the array can be a pair consisting of the layer id and a color value. The color value can either be a string with a hex color code, or a number from 1-3 (theme-affected colors) -- nodeStyle(): **optional**, a function returning a CSS object, styles this layer's node on the tree +- nodeStyle: **optional**, a CSS object, styles this layer's node on the tree - tooltip() / tooltipLocked(): **optional** Functions that return text, which is the tooltip for the node when the layer is unlocked or locked, respectively. By default the tooltips behave the same as in the original Prestige Tree. @@ -138,7 +146,7 @@ Key: - automate(): **optional**, this function is called every game tick, after production. Use it to activate any autobuyers or auto-resets or similar on this layer, if appropriate. -- resetsNothing(): **optional**, returns true if this layer shouldn't trigger any resets when you prestige. +- resetsNothing: **optional**, returns true if this layer shouldn't trigger any resets when you prestige. - incr_order: **optional**, an array of layer ids. When this layer is unlocked for the first time, the "order" value for any not-yet-unlocked layers in this list increases. This can be used to make them harder to unlock. @@ -157,21 +165,17 @@ Key: ``` -# Custom Prestige type only -(No effect otherwise) +# Custom Prestige type -- 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(): **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 +- getNextAt(canMax=false): **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 +- canReset(): **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 256e89e..6f70b04 100644 --- a/docs/milestones.md +++ b/docs/milestones.md @@ -31,7 +31,7 @@ Milestone features: **Tip:** Toggles are not de-set if the milestone becomes locked! In this case, you should also check if the player has the milestone. -- style(): **Optional**, A function returning a CSS object, which affects this milestone. +- style: **Optional**, A CSS object, which affects this milestone. - unl(): A function returning a boolean to determine if the milestone should be shown. If absent, it is always shown. diff --git a/docs/subtabs-and-microtabs.md b/docs/subtabs-and-microtabs.md index 2302c3a..711469a 100644 --- a/docs/subtabs-and-microtabs.md +++ b/docs/subtabs-and-microtabs.md @@ -44,9 +44,9 @@ Normal subtabs and microtab subtabs both use the same features: - content: The tab layout code for the subtab, in [the tab layout format](custom-tab-layouts.md) -- style(): **Optional**, A function returning a CSS object, which affects the CSS when in that subtab. +- style: **Optional**, A CSS object, which affects the CSS when in that subtab. -- buttonStyle(): **Optional**, A function returning a CSS object, which affects the appearance of the button for that subtab. +- buttonStyle: **Optional**, A CSS object, which affects the appearance of the button for that subtab. - unl(): **Optional**, a function to determine if the button for this subtab should be visible. By default, a subtab is always unlocked. (You can't use the "this" keyword in this function.) \ No newline at end of file diff --git a/docs/upgrades.md b/docs/upgrades.md index d43d871..0071246 100644 --- a/docs/upgrades.md +++ b/docs/upgrades.md @@ -5,7 +5,7 @@ Upgrades are stored in the following format: Useful functions for dealing with Upgrades and implementing their effects: - hasUpg(layer, id): determine if the player has the upgrade -- ugpEffect(layer, id): Returns the current effects of the upgrade, if any +- upgEffect(layer, id): Returns the current effects of the upgrade, if any Hint: Basic point gain is calculated in game.js's "getPointGain". @@ -50,7 +50,7 @@ By default, upgrades use the main prestige currency for the layer. You can inclu - currencyLayer: **optional**, the internal name of the layer that currency is stored in. If it's not in a layer (like Points), omit. -- style(): **Optional**, A function returning a CSS object, which affects this upgrade. +- style: **Optional**, A a CSS object, which affects this upgrade. - layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar From 8840d02a9b6aead4a0493e2c62570274494eb564 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Sat, 10 Oct 2020 21:32:41 -0400 Subject: [PATCH 04/33] You don't need the same number of upgrades in every row/col --- changelog.md | 4 ++-- js/layers.js | 8 +++++++- js/v.js | 8 ++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/changelog.md b/changelog.md index 6751291..b4b2f61 100644 --- a/changelog.md +++ b/changelog.md @@ -1,8 +1,8 @@ #The Modding Tree changelog: - - +Almost every value in layer data can be a function or a constant value! effectDisplay in Challenges and Upgrades no longer takes an argument +You don't have to have the same amount of upgrades in every row (and challs and buyables) ##v1.3.5 - Completely automated convertToDecimal, now you never have to worry about it again. diff --git a/js/layers.js b/js/layers.js index 62db90a..a428ff7 100644 --- a/js/layers.js +++ b/js/layers.js @@ -80,7 +80,7 @@ addLayer("c", { }, }, upgrades: { - rows: 1, + rows: 2, cols: 3, 11: { title:() => "Generator of Genericness", @@ -120,6 +120,12 @@ addLayer("c", { } // Otherwise use the default }, }, + 22: { + title:() => "This upgrade doesn't exist", + desc:() => "Or does it?.", + cost:() => new Decimal(1), + unl() { return player[this.layer].unl }, // The upgrade is only visible when this is true + }, }, buyables: { rows: 1, diff --git a/js/v.js b/js/v.js index 402a092..3d5342a 100644 --- a/js/v.js +++ b/js/v.js @@ -103,7 +103,7 @@ function loadVue() { Vue.component('chall', { props: ['layer', 'data'], template: ` -
+






@@ -132,7 +132,7 @@ function loadVue() { Vue.component('upgrade', { props: ['layer', 'data'], template: ` -
-
+
-
+

- ` + ` }) // data = id of buyable From 3cff3f1d5028c8c71b34ed4bff54b36456e138c6 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Sat, 10 Oct 2020 22:08:20 -0400 Subject: [PATCH 06/33] Enhancer spacing and style and stuff --- js/layers.js | 3 ++- js/v.js | 4 ++-- style.css | 2 -- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/js/layers.js b/js/layers.js index 937b6ed..0163a93 100644 --- a/js/layers.js +++ b/js/layers.js @@ -168,6 +168,7 @@ addLayer("c", { player[this.layer].spentOnBuyables = player[this.layer].spentOnBuyables.add(cost) // This is a built-in system that you can use for respeccing but it only works with a single Decimal value }, buyMax() {}, // You'll have to handle this yourself if you want + style: {'height':'222px'} }, }, doReset(resettingLayer){ // Triggers when this layer is being reset, along with the layer doing the resetting. Not triggered by lower layers resetting, but is by layers on the same row. @@ -248,7 +249,7 @@ addLayer("c", { style() {return {'background-color': '#222222'}}, buttonStyle() {return {'border-color': 'orange'}}, content:[ - ["buyables", "150px"], "blank", + ["buyables", ""], "blank", ["row", [ ["toggle", ["c", "beep"]], ["blank", ["30px", "10px"]], // Width, height ["display-text", function() {return "Beep"}], "blank", ["v-line", "200px"], diff --git a/js/v.js b/js/v.js index ffdda24..09e8191 100644 --- a/js/v.js +++ b/js/v.js @@ -201,7 +201,7 @@ function loadVue() {

-
+

@@ -217,7 +217,7 @@ function loadVue() {
@@ -96,15 +56,16 @@

{{VERSION.withName}}


- The Modding Tree by Acamaeda + The Modding Tree {{VERSION.tmtNum}} by Acamaeda
The Prestige Tree made by Jacorb and Aarex
Original idea by papyrus (on discord)


- The Modding Tree Discord
- Main Prestige Tree server
+ {{modInfo.discordName}}
+ The Modding Tree Discord
+ Main Prestige Tree server

Note by Jacorb: If anyone wishes to make a mod of this game, that is perfectly fine with me, just make sure to name it something different (ex: Prestige Tree NG+) and to let me know on my discord.

diff --git a/js/game.js b/js/game.js index a0a5e9c..fe88a30 100644 --- a/js/game.js +++ b/js/game.js @@ -3,9 +3,21 @@ var needCanvasUpdate = true; var NaNalert = false; var gameEnded = false; + +let modInfo = { + name: "The Modding Tree", + id: "modbase", + pointsName: "points", + discordName: "", + discordLink: "", + offlineLimit: 1 // In hours +} + let VERSION = { num: "1.3.5 maybe", - name: "Tabception... ception!" + name: "Tabception... ception!", + tmtNum: "1.3.5 maybe", + tmtName: "Tabception... ception!" } // Determines if it should show points/sec From 1ff8042fc7a3d544da7a38b3b9c6f388379afd80 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Sat, 10 Oct 2020 23:26:26 -0400 Subject: [PATCH 08/33] Index.html has lost its relevance! --- changelog.md | 2 ++ docs/layer-features.md | 5 +++++ index.html | 20 +++++++------------- js/layerSupport.js | 20 +++++++++++++++++++- js/layers.js | 3 ++- 5 files changed, 35 insertions(+), 15 deletions(-) diff --git a/changelog.md b/changelog.md index e253b22..2391801 100644 --- a/changelog.md +++ b/changelog.md @@ -1,9 +1,11 @@ #The Modding Tree changelog: +Tmp does not need to be manually updated. Almost every value in layer data can be a function or a constant value! effectDisplay in Challenges and Upgrades no longer takes an argument You don't have to have the same amount of upgrades in every row (and challs and buyables) Unl is optional for all Big Components (defaults to true). +Moved modInfo to game.js, added a spot for a Discord link, and a separate mod version from the TMT version ##v1.3.5 - Completely automated convertToDecimal, now you never have to worry about it again. diff --git a/docs/layer-features.md b/docs/layer-features.md index a0ab1db..8f3d658 100644 --- a/docs/layer-features.md +++ b/docs/layer-features.md @@ -121,6 +121,11 @@ Key: # Tree/node features +- symbol: **optional**, the text that appears on this layer's node. Default is the layer id with the first letter capitalized + +- position: **optional**, Determines the horizontal position of the layer in its row. By default, it uses the layer id, + and layers are sorted in alphabetical order. + - branches: **optional**, an array of layer ids. On a tree, a line will appear from this layer to all of the layers in the list. Alternatively, an entry in the array can be a pair consisting of the layer id and a color value. The color value can either be a string with a hex color code, or a number from 1-3 (theme-affected colors) diff --git a/index.html b/index.html index 9eb66a7..bb3597c 100644 --- a/index.html +++ b/index.html @@ -8,8 +8,8 @@ - + @@ -64,7 +64,7 @@


{{modInfo.discordName}}
- The Modding Tree Discord
+ The Modding Tree Discord
Main Prestige Tree server

Note by Jacorb: If anyone wishes to make a mod of this game, that is perfectly fine with me, just make sure to name it something different (ex: Prestige Tree NG+) and to let me know on my discord. @@ -118,17 +118,11 @@
({{format(getPointGen())}}/sec)



- - - -
- -
- - -


- -
+ + + +


+
diff --git a/js/layerSupport.js b/js/layerSupport.js index bfd5820..6cdd47f 100644 --- a/js/layerSupport.js +++ b/js/layerSupport.js @@ -23,10 +23,12 @@ function updateHotkeys() } var ROW_LAYERS = {} +var TREE_LAYERS = {} function updateLayers(){ LAYERS = Object.keys(layers); ROW_LAYERS = {} + TREE_LAYERS = {} for (layer in layers){ layers[layer].layer = layer if (layers[layer].upgrades){ @@ -72,12 +74,21 @@ function updateLayers(){ } if(!layers[layer].componentStyles) layers[layer].componentStyles = {} - + if(layers[layer].symbol === undefined) layers[layer].symbol = layer.charAt(0).toUpperCase() + layer.slice(1) row = layers[layer].row if(!ROW_LAYERS[row]) ROW_LAYERS[row] = {} + if(!TREE_LAYERS[row]) TREE_LAYERS[row] = [] ROW_LAYERS[row][layer]=layer; + let position = (layers[layer].position !== undefined ? layers[layer].position : layer) + TREE_LAYERS[row].push({layer: layer, position: position}) + + } + for (row in TREE_LAYERS) { + TREE_LAYERS[row].sort((a, b) => (a.position > b.position) ? 1 : -1) + } + updateHotkeys() } @@ -94,6 +105,13 @@ function readData(data, args=null){ return data; } +function someLayerUnlocked(row){ + for (layer in ROW_LAYERS[row]) + if (player[layer].unl) + return true + return false +} + // This isn't worth making a .ts file over const UP = 1 const DOWN = 2 diff --git a/js/layers.js b/js/layers.js index 0163a93..1f3080b 100644 --- a/js/layers.js +++ b/js/layers.js @@ -1,6 +1,8 @@ addLayer("c", { layer: "c", // This is assigned automatically, both to the layer and all upgrades, etc. Shown here so you know about it name: "Candies", // This is optional, only used in a few places, If absent it just uses the layer id. + symbol: "C", // 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 { unl: true, points: new Decimal(0), @@ -346,4 +348,3 @@ addLayer("f", { }, ) - From e9105e9865f4d501466045302aafed62e44ab260 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Sun, 11 Oct 2020 14:49:29 -0400 Subject: [PATCH 09/33] Test with Despacit Tree Delta, numerous fixes --- changelog.md | 5 +- docs/custom-tab-layouts.md | 5 +- index.html | 4 +- js/game.js | 3 +- js/gametest.js | 486 ++++++++++ js/temp.js | 8 +- js/test.js | 1872 ++++++++++++++++++++++++++++++++++++ js/v.js | 21 +- 8 files changed, 2378 insertions(+), 26 deletions(-) create mode 100644 js/gametest.js create mode 100644 js/test.js diff --git a/changelog.md b/changelog.md index 2391801..39aa6e9 100644 --- a/changelog.md +++ b/changelog.md @@ -1,11 +1,12 @@ #The Modding Tree changelog: +Moved modInfo to game.js, added a spot for a Discord link, and a separate mod version from the TMT version +Tree structure is based on layer data, no index.html needed. Tmp does not need to be manually updated. Almost every value in layer data can be a function or a constant value! -effectDisplay in Challenges and Upgrades no longer takes an argument You don't have to have the same amount of upgrades in every row (and challs and buyables) Unl is optional for all Big Components (defaults to true). -Moved modInfo to game.js, added a spot for a Discord link, and a separate mod version from the TMT version +effectDisplay in Challenges and Upgrades no longer takes an argument ##v1.3.5 - Completely automated convertToDecimal, now you never have to worry about it again. diff --git a/docs/custom-tab-layouts.md b/docs/custom-tab-layouts.md index 4f06b4f..f507911 100644 --- a/docs/custom-tab-layouts.md +++ b/docs/custom-tab-layouts.md @@ -22,10 +22,7 @@ which applies its style to the component. These are the existing components, but you can create more in v.js: -- display-text: Displays some text. The argument is the text to display. It can also be a function that returns updating text. - -- raw-html: Displays some HTML. The argument is the HTML as a string, or a function that returns updating HTML. - It doesn't work with many vue things. +- display-text: Displays some text (can use basic HTML). The argument is the text to display. It can also be a function that returns updating text. - blank: Adds empty space. The default dimensions are 8px x 17px. The argument changes the dimensions. If it's a single value (e.g. "20px"), that determines the height. diff --git a/index.html b/index.html index bb3597c..65f0174 100644 --- a/index.html +++ b/index.html @@ -6,9 +6,9 @@ - + - + diff --git a/js/game.js b/js/game.js index fe88a30..72f6ae4 100644 --- a/js/game.js +++ b/js/game.js @@ -27,7 +27,7 @@ function showPointGen(){ // Calculate points/sec! function getPointGen() { - if(!hasUpg("c", 11)) + if(!hasUpg("p", 11)) return new Decimal(0) let gain = new Decimal(1) @@ -264,6 +264,7 @@ function buyableEffect(layer, id){ return (tmp[layer].buyables[id].effect) } + function canAffordPurchase(layer, thing, cost) { if (thing.currencyInternalName){ let name = thing.currencyInternalName diff --git a/js/gametest.js b/js/gametest.js new file mode 100644 index 0000000..b556c8d --- /dev/null +++ b/js/gametest.js @@ -0,0 +1,486 @@ +var player; +var needCanvasUpdate = true; +var NaNalert = false; +var gameEnded = false; + + +let modInfo = { + name: "The Modding Tree", + id: "modbase", + pointsName: "points", + discordName: "", + discordLink: "", + offlineLimit: 1 // In hours +} + +let VERSION = { + num: "1.3.5 maybe", + name: "Tabception... ception!", + tmtNum: "1.3.5 maybe", + tmtName: "Tabception... ception!" +} + +// Determines if it should show points/sec +function showPointGen(){ + return (tmp.pointGen.neq(new Decimal(0))) +} + +// Calculate points/sec! +function getPointGen() { + if(!hasUpg("p", 11)) return new Decimal(0) + + let gain = new Decimal(1) + if (hasUpg("p", 12)) gain = gain.times(upgEffect("p", 12)) + if (hasUpg("p", 13)) gain = gain.times(upgEffect("p", 13)) + if (hasUpg("p", 22)) gain = gain.times(upgEffect("p", 22)) + if (player.b.unl) gain = gain.times(layers.b.effect()) + if (player.g.unl) gain = gain.times(layers.g.effect().powerBoost) + if (hasUpg("e", 11)) gain = gain.times(layers.e.upgrades[11].effect()) + if (player.e.unl && tmp.e.buyables) gain = gain.times(tmp.e.buyables[11].effect.second) + if (player.r.upgrades.includes(11)) gain = gain.times(layers.r.upgrades[11].effect()) + if (player.d.buyables[12].gt(0)) gain = gain.times(layers.d.buyables[12].effect(player.d.buyables[12]).first) + if (!player.s.active) if (player.pr.buyables[13].gt(0)) gain = gain.times(layers.pr.buyables[13].effect().first) + if (player.d.banking == 1) gain = gain.sqrt() + if (player.d.banking == 2) gain = gain.add(1).log10() + return gain +} + + + +// Function to determine if the player is in a challenge +function inChallenge(layer, id){ + let chall = player[layer].active + if (chall==toNumber(id)) return true + + if (layers[layer].challs[chall].countsAs) + return layers[layer].challs[id].countsAs.includes(id) +} + +function getResetGain(layer, useType = null) { + let type = useType + if (!useType) type = layers[layer].type + + if (tmp[layer].gainExp.eq(0)) return new Decimal(0) + if (type=="static") { + if ((!layers[layer].canBuyMax()) || tmp[layer].baseAmount.lt(tmp[layer].requires)) return new Decimal(1) + let gain = tmp[layer].baseAmount.div(tmp[layer].requires).div(tmp[layer].gainMult).max(1).log(layers[layer].base).times(tmp[layer].gainExp).pow(Decimal.pow(layers[layer].exponent, -1)) + return gain.floor().sub(player[layer].points).add(1).max(1); + } else if (type=="normal"){ + if (tmp[layer].baseAmount.lt(tmp[layer].requires)) return new Decimal(0) + let gain = tmp[layer].baseAmount.div(tmp[layer].requires).pow(layers[layer].exponent).times(tmp[layer].gainMult).pow(tmp[layer].gainExp) + 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, canMax=false, useType = null) { + let type = useType + if (!useType) type = layers[layer].type + + if (tmp[layer].gainExp.eq(0)) return new Decimal(1/0) + if (type=="static") + { + if (!layers[layer].canBuyMax()) canMax = false + let amt = player[layer].points.plus((canMax&&tmp[layer].baseAmount.gte(tmp[layer].nextAt))?tmp[layer].resetGain:0) + let extraCost = Decimal.pow(layers[layer].base, amt.pow(layers[layer].exponent).div(tmp[layer].gainExp)).times(tmp[layer].gainMult) + let cost = extraCost.times(tmp[layer].requires).max(tmp[layer].requires) + if (layers[layer].resCeil) cost = cost.ceil() + return cost; + } else if (type=="normal"){ + let next = tmp[layer].resetGain.add(1) + if (next.gte("e1e7")) next = next.div("e5e6").pow(2) + next = next.root(tmp[layer].gainExp.div(tmp[layer].gainMult).root(layers[layer].exponent).times(tmp[layer].requires).max(tmp[layer].requires)) + 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){ + for (id in layers[layer].upgrades){ + if (!isNaN(id)){ + if (canAffordUpg(layer, id) && !hasUpg(layer, id) && tmp[layer].upgrades[id].unl){ + return true + } + } + } + + if (layers[layer].shouldNotify){ + return layers[layer].shouldNotify() + } + else + return false +} + +function canReset(layer) +{ + if(tmp[layer].type == "normal") + return tmp[layer].baseAmount.gte(tmp[layer].requires) + else if(tmp[layer].type== "static") + return tmp[layer].baseAmount.gte(tmp[layer].nextAt) + else + return layers[layer].canReset() +} + +function rowReset(row, layer) { + for (lr in ROW_LAYERS[row]){ + if(layers[lr].doReset) { + player[lr].active = null // Exit challenges on any row reset on an equal or higher row + layers[lr].doReset(layer) + } + else + if(layers[layer].row > layers[lr].row) fullLayerReset(lr) + } +} + +function fullLayerReset(layer) { + player[layer] = layers[layer].startData(); + player[layer].upgrades = [] + player[layer].milestones = [] + player[layer].challs = [] + if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)) { + if (player.subtabs[layer] == undefined) player.subtabs[layer] = {} + if (player.subtabs[layer].mainTabs == undefined) player.subtabs[layer].mainTabs = Object.keys(layers[layer].tabFormat)[0] + } + + if (layers[layer].microtabs) { + if (player.subtabs[layer] == undefined) player.subtabs[layer] = {} + for (item in layers[layer].microtabs) + if (player.subtabs[layer][item] == undefined) player.subtabs[layer][item] = Object.keys(layers[layer].microtabs[item])[0] + } + resetBuyables(layer) +} + +function resetBuyables(layer){ + if (layers[layer].buyables) + player[layer].buyables = getStartBuyables(layer) + player[layer].spentOnBuyables = new Decimal(0) +} + +function getStartBuyables(layer){ + let data = {} + if (layers[layer].buyables) { + for (id in layers[layer].buyables) + if (!isNaN(id)) + data[id] = new Decimal(0) + } + return data +} + +function addPoints(layer, gain) { + player[layer].points = player[layer].points.add(gain).max(0) + if (player[layer].best) player[layer].best = player[layer].best.max(player[layer].points) + if (player[layer].total) player[layer].total = player[layer].total.add(gain) +} + +function generatePoints(layer, diff) { + addPoints(layer, tmp[layer].resetGain.times(diff)) +} + +var prevOnReset + +function doReset(layer, force=false) { + let row = layers[layer].row + if (!force) { + if (!tmp[layer].canReset) return + let gain = tmp[layer].resetGain + if (layers[layer].type=="static") { + gain =(layers[layer].canBuyMax() ? gain : 1) + } + if (layers[layer].onPrestige) + layers[layer].onPrestige(gain) + + addPoints(layer, gain) + updateMilestones(layer) + + if (!player[layer].unl) { + player[layer].unl = true; + needCanvasUpdate = true; + + if (layers[layer].incr_order){ + lrs = layers[layer].incr_order + for (lr in lrs) + if (!player[lrs[lr]].unl) player[lrs[lr]].order++ + } + } + + tmp[layer].baseAmount = new Decimal(0) // quick fix + } + + if (tmp[layer].resetsNothing) return + + + for (layerResetting in layers) { + if (row >= layers[layerResetting].row && (!force || layerResetting != layer)) completeChall(layerResetting) + } + + prevOnReset = {...player} //Deep Copy + player.points = (row == 0 ? new Decimal(0) : new Decimal(10)) + + for (let x = row; x >= 0; x--) rowReset(x, layer) + prevOnReset = undefined + + updateTemp() + updateTemp() +} + +function respecBuyables(layer) { + if (!layers[layer].buyables) return + if (!layers[layer].buyables.respec) return + if (!confirm("Are you sure you want to respec? This will force you to do a \"" + (layers[layer].name ? layers[layer].name : layer) + "\" reset as well!")) return + layers[layer].buyables.respec() + updateBuyableTemp(layer) +} + + + +function canAffordUpg(layer, id) { + if (!layers[layer].upgrades) return false + let upg = layers[layer].upgrades[id] + let cost = tmp[layer].upgrades[id].cost + return canAffordPurchase(layer, upg, cost) +} + +function hasUpg(layer, id){ + if (!layers[layer].upgrades) return false + + return (player[layer].upgrades.includes(toNumber(id)) || player[layer].upgrades.includes(id.toString())) +} + +function hasMilestone(layer, id) { + if (!layers[layer].milestones) return false + + return (player[layer].milestones.includes(toNumber(id)) || player[layer].milestones.includes(id.toString())) +} + +function hasChall(layer, id){ + if (!layers[layer].challs) return false + + return (player[layer].challs.includes(toNumber(id)) || player[layer].challs.includes(id.toString())) +} + +function upgEffect(layer, id){ + if (!layers[layer].upgrades) return {} + + return (tmp[layer].upgrades[id].effect) +} + +function challEffect(layer, id){ + if (!layers[layer].chall) return false + + return (tmp[layer].challs[id].effect) +} + +function buyableEffect(layer, id){ + if (!layers[layer].buyables) return false + + return (tmp[layer].buyables[id].effect) +} + +function canAffordPurchase(layer, thing, cost) { + if (thing.currencyInternalName){ + let name = thing.currencyInternalName + if (thing.currencyLayer){ + let lr = thing.currencyLayer + return !(player[lr][name].lt(cost)) + } + else { + return !(player[name].lt(cost)) + } + } + else { + return !(player[layer].points.lt(cost)) + } +} + +function buyUpg(layer, id) { + if (!player[layer].unl) return + if (!layers[layer].upgrades[id].unl()) return + if (player[layer].upgrades.includes(id)) return + let upg = layers[layer].upgrades[id] + let cost = tmp[layer].upgrades[id].cost + + if (upg.currencyInternalName){ + let name = upg.currencyInternalName + if (upg.currencyLayer){ + let lr = upg.currencyLayer + if (player[lr][name].lt(cost)) return + player[lr][name] = player[lr][name].sub(cost) + } + else { + if (player[name].lt(cost)) return + player[name] = player[name].sub(cost) + } + } + else { + if (player[layer].points.lt(cost)) return + player[layer].points = player[layer].points.sub(cost) + } + player[layer].upgrades.push(id); + if (upg.onPurchase != undefined) + upg.onPurchase() +} + +function buyMaxBuyable(layer, id) { + if (!player[layer].unl) return + if (!tmp[layer].buyables[id].unl) return + if (!tmp[layer].buyables[id].canAfford) return + if (!layers[layer].buyables[id].buyMax) return + + layers[layer].buyables[id].buyMax() + updateBuyableTemp(layer) +} + +function buyBuyable(layer, id) { + if (!player[layer].unl) return + if (!tmp[layer].buyables[id].unl) return + if (!tmp[layer].buyables[id].canAfford) return + + layers[layer].buyables[id].buy() + updateBuyableTemp(layer) +} + +function resetRow(row) { + if (prompt('Are you sure you want to reset this row? It is highly recommended that you wait until the end of your current run before doing this! Type "I WANT TO RESET THIS" to confirm')!="I WANT TO RESET THIS") return + let pre_layers = ROW_LAYERS[row-1] + let layers = ROW_LAYERS[row] + let post_layers = ROW_LAYERS[row+1] + rowReset(row+1, post_layers[0]) + doReset(pre_layers[0], true) + for (let layer in layers) { + player[layers[layer]].unl = false + if (player[layers[layer]].order) player[layers[layer]].order = 0 + } + player.points = new Decimal(10) + updateTemp(); + resizeCanvas(); +} + +function startChall(layer, x) { + let enter = false + if (!player[layer].unl) return + if (player[layer].active == x) { + completeChall(layer, x) + delete player[layer].active + } else { + enter = true + } + doReset(layer, true) + if(enter) player[layer].active = x + + updateChallTemp(layer) +} + +function canCompleteChall(layer, x) +{ + if (x != player[layer].active) return + + let chall = layers[layer].challs[x] + + if (chall.currencyInternalName){ + let name = chall.currencyInternalName + if (chall.currencyLayer){ + let lr = chall.currencyLayer + return !(player[lr][name].lt(readData(chall.goal))) + } + else { + return !(player[name].lt(chall.cost)) + } + } + else { + return !(player[layer].points.lt(chall.cost)) + } + +} + +function completeChall(layer, x) { + var x = player[layer].active + if (!x) return + if (! canCompleteChall(layer, x)) return + if (!player[layer].challs.includes(x)) { + needCanvasUpdate = true + player[layer].challs.push(x); + if (layers[layer].challs[x].onComplete) layers[layer].challs[x].onComplete() + } + delete player[layer].active + updateChallTemp(layer) +} + +VERSION.withoutName = "v" + VERSION.num + (VERSION.pre ? " Pre-Release " + VERSION.pre : VERSION.pre ? " Beta " + VERSION.beta : "") +VERSION.withName = VERSION.withoutName + (VERSION.name ? ": " + VERSION.name : "") + + +const ENDGAME = new Decimal("e280000000"); + +function gameLoop(diff) { + if (player.points.gte(ENDGAME) || gameEnded) gameEnded = 1 + + if (isNaN(diff)) diff = 0 + if (gameEnded && !player.keepGoing) { + diff = 0 + player.tab = "gameEnded" + } + if (player.devSpeed) diff *= player.devSpeed + + addTime(diff) + + for (layer in layers){ + if (layers[layer].update) layers[layer].update(diff); + } + + for (layer in layers){ + if (layers[layer].automate) layers[layer].automate(); + } + + for (layer in layers){ + if (layers[layer].milestones) updateMilestones(layer); + } + + if (player.hasNaN&&!NaNalert) { + clearInterval(interval); + player.autosave = false; + NaNalert = true; + + alert("We have detected a corruption in your save. Please visit https://discord.gg/wwQfgPa for help.") + } +} + +function hardReset() { + if (!confirm("Are you sure you want to do this? You will lose all your progress!")) return + player = getStartPlayer() + save(); + window.location.reload(); +} + +var ticking = false + +var interval = setInterval(function() { + if (player===undefined||tmp===undefined) return; + if (ticking) return; + if (gameEnded&&!player.keepGoing) return; + ticking = true + let now = Date.now() + let diff = (now - player.time) / 1e3 + if (player.offTime !== undefined) { + if (player.offTime.remain > modInfo.offlineLimit * 3600000) player.offlineTime.remain = modInfo.offlineLimit * 3600000 + if (player.offTime.remain > 0) { + let offlineDiff = Math.max(player.offTime.remain / 10, diff) + player.offTime.remain -= offlineDiff + diff += offlineDiff + } + if (!player.offlineProd || player.offTime.remain <= 0) delete player.offTime + } + if (player.devSpeed) diff *= player.devSpeed + player.time = now + if (needCanvasUpdate) resizeCanvas(); + updateTemp(); + gameLoop(diff) + ticking = false +}, 50) diff --git a/js/temp.js b/js/temp.js index b7c9299..8e50fe4 100644 --- a/js/temp.js +++ b/js/temp.js @@ -28,6 +28,8 @@ function setupTempData(layerData, tmpData) { if (layerData[item] == null) { tmpData[item] = null } + else if (layerData[item] instanceof Decimal) + tmpData[item] = layerData[item] else if (Array.isArray(layerData[item])) { tmpData[item] = [] setupTempData(layerData[item], tmpData[item]) @@ -37,7 +39,7 @@ function setupTempData(layerData, tmpData) { setupTempData(layerData[item], tmpData[item]) } else if (isFunction(layerData[item]) && !activeFunctions.includes(item)){ - tmpData[item] = {} + tmpData[item] = new Decimal(1) // The safest thing to put probably? } else { tmpData[item] = layerData[item] } @@ -64,7 +66,7 @@ function updateTemp() { } function updateTempData(layerData, tmpData) { - + for (item in layerData){ if (Array.isArray(layerData[item])) { updateTempData(layerData[item], tmpData[item]) @@ -73,7 +75,7 @@ function updateTempData(layerData, tmpData) { updateTempData(layerData[item], tmpData[item]) } else if (isFunction(layerData[item]) && !activeFunctions.includes(item)){ - tmpData[item] = layerData[item]() + Vue.set(tmpData, item, layerData[item]()) } } } diff --git a/js/test.js b/js/test.js new file mode 100644 index 0000000..e5cb029 --- /dev/null +++ b/js/test.js @@ -0,0 +1,1872 @@ +addLayer("p", { + + effect() {return {}}, + startData() { return { + unl: true, + points: new Decimal(0), + best: new Decimal(0), + total: new Decimal(0), + }}, + color:() => "#00bfbf", + background:() => undefined, + requires:() => new Decimal(10), // Can be a function that takes requirement increases into account + resource: "prestige points", // 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: 0.5, // Prestige currency exponent + base: 5, // Only needed for static layers, base of the formula (b^(x^exp)) + resCeil: false, // True if the cost needs to be rounded up (use when baseResource is static?) + canBuyMax() {}, // Only needed for static layers with buy max + gainMult() { // Calculate the multiplier for main currency from bonuses + mult = new Decimal(1) + if (player[this.layer].upgrades.includes(21)) mult = mult.times(2) + if (player[this.layer].upgrades.includes(23)) mult = mult.times(this.upgrades[23].effect()) + if (player.b.upgrades.includes(11)) mult = mult.times(layers.b.upgrades[11].effect()) + if (player.g.upgrades.includes(11)) mult = mult.times(layers.g.upgrades[11].effect()) + if (player.e.upgrades.includes(11)) mult = mult.times(layers.e.upgrades[11].effect()) + if (player.e.unl) mult = mult.times(layers.e.buyables[11].effect.second) + if (player.d.unl) mult = mult.times(layers.d.buyables[11].effect(player.d.buyables[11]).first) + if (!player.s.active) if (player.pr.buyables[13].gt(0)) mult = mult.times(layers.pr.buyables[13].effect().first) + if (player.s.challs.includes(21)) mult = mult.times(layers.s.challs[21].effect()) + return mult.max(1) + }, + gainExp() { // Calculate the exponent on main currency from bonuses + let exp = new Decimal(1) + if (player.d.unl && player.d.banking == 1) exp = exp.div(2) + if (player.s.active == 11) exp = exp.div(10) + return exp + }, + row: 0, // Row the layer is in on the tree (0 is the first row) + upgrades: { + rows: 2, + cols: 3, + 11: { + desc:() => "Gain 1 Point every second.", + cost:() => new Decimal(1), + unl() { return player[this.layer].unl }, // The upgrade is only visible when this is true + }, + 12: { + desc:() => "Point generation is faster based on your unspent prestige points.", + cost:() => new Decimal(1), + unl() { return player[this.layer].upgrades.includes(11) }, + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + if (player.d.banking == 1) return new Decimal(1) + let ret = player[this.layer].points.add(2).pow(0.5) + if (player.s.unl) ret = ret.pow(layers.s.effect()) + if (ret.gte("1e20000000")) ret = ret.sqrt().times("1e10000000") + return ret; + }, + effectDisplay() { return format(tmp[this.layer].upgrades[this.id].effect)+"x" }, // Add formatting to the effect + }, + 13: { + desc:() => "Points boost point gain.", + cost:() => new Decimal(5), + unl() { return player[this.layer].upgrades.includes(12) }, + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player.points.add(1).log10().add(1) + return ret; + }, + effectDisplay() { return format(tmp[this.layer].upgrades[this.id].effect)+"x" }, // Add formatting to the effect + }, + 21: { + desc:() => "Double prestige point gain.", + cost:() => new Decimal(10), + unl() { return player[this.layer].upgrades.includes(13) }, + }, + 22: { + desc:() => "Point generation is faster based on your prestige upgrades.", + cost:() => new Decimal(25), + unl() { return player[this.layer].upgrades.includes(21) }, + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = Decimal.pow(1.4, player[this.layer].upgrades.length) + return ret + }, + effectDisplay() { return format(tmp[this.layer].upgrades[this.id].effect)+"x" }, // Add formatting to the effect + }, + 23: { + desc:() => "Prestige Point gain is boosted by normal Points.", + cost:() => new Decimal(250), + unl() { return player[this.layer].upgrades.includes(22) }, + effect() { + let ret = player.points.add(1).log10().cbrt().add(1) + return ret; + }, + effectDisplay() { return format(tmp[this.layer].upgrades[this.id].effect)+"x" }, // Add formatting to the effect + }, + }, + doReset(resettingLayer){ // Triggers when this layer is being reset, along with the layer doing the resetting. Not triggered by lower layers resetting, but is by layers on the same row. + if(resettingLayer == "b") { + if (player.b.milestones.includes("0")) { + let upgrades = player[this.layer].upgrades + fullLayerReset(this.layer) + player[this.layer].upgrades = upgrades + return; + } + } + if(resettingLayer == "g") { + if (player.g.milestones.includes("0")) { + let upgrades = player[this.layer].upgrades + fullLayerReset(this.layer) + player[this.layer].upgrades = upgrades + return; + } + } + if(resettingLayer == "e") { + if (player.e.milestones.includes("0")) { + let upgrades = player[this.layer].upgrades + fullLayerReset(this.layer) + player[this.layer].upgrades = upgrades + return; + } + } + if(resettingLayer == "r") { + if (player.r.milestones.includes("0")) { + let upgrades = player[this.layer].upgrades + fullLayerReset(this.layer) + player[this.layer].upgrades = upgrades + return; + } + } + if(resettingLayer == "d") { + if (player.d.milestones.includes("0")) { + let upgrades = player[this.layer].upgrades + fullLayerReset(this.layer) + player[this.layer].upgrades = upgrades + return; + } + } + if(layers[resettingLayer].row > this.row) fullLayerReset(this.layer) // This is actually the default behavior + }, + layerShown() {return true}, // Condition for when layer appears on the tree + update(diff) { + if (player[this.layer].upgrades.includes(11)) player.points = player.points.add(tmp.pointGen.times(diff)).max(0) + }, // Do any gameloop things (e.g. resource generation) inherent to this layer + hotkeys: [ + {key: "p", desc: "P: Reset points for prestige points.", onPress(){if (player[this.layer].unl) doReset(this.layer)}}, + ], + // Optional, lets you format the tab yourself by listing components. You can create your own components in v.js. + tabFormat: ["main-display", + ["prestige-button", function() {return "Convert your points into "}], + ["blank", "5px"], // Height + ["display-text", + function() {return 'You have ' + format(player.points) + ' points.'}, + {"font-size": "14px"}], + "upgrades"], +}) + + +addLayer("b", { + startData() { return { + unl: false, + auto: false, + points: new Decimal(0), + best: new Decimal(0), + total: new Decimal(0), + milestones: [] + }}, + color:() => "#415a9e", + background:() => 'https://cdn.glitch.com/7460ed4d-c31b-459d-8407-710f48e787a3%2Fefdb5b70-5e55-4f23-9524-953a8eea4545.image.png?v=1601771864943', + requires() { + let req = new Decimal(5000) + if (player.g.unl && !player.b.unl) req = req.mul(500) + return req + }, // Can be a function that takes requirement increases into account + resource: "boosters", // Name of prestige currency + baseResource: "points", // Name of resource prestige is based on + baseAmount() {return player.points}, // Get the current amount of baseResource + type: "custom", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have + exponent: 1, // Prestige currency exponent + base: 5, // Only needed for static layers, base of the formula (b^(x^exp)) + resCeil: false, // True if the cost needs to be rounded up (use when baseResource is static?) + canBuyMax() { + return player[this.layer].milestones.includes("1") + }, // Only needed for static layers with buy max + gainMult() { // Calculate the multiplier for main currency from bonuses + mult = new Decimal(1) + if (player[this.layer].upgrades.includes(21)) mult = mult.div(layers[this.layer].upgrades[21].effect()) + if (!player.s.active) if (player.pr.buyables[11].gt(0)) mult = mult.div(layers.pr.buyables[11].effect().first) + if (player.s.challs.includes(12)) mult = mult.div(layers.s.challs[12].effect()) + return mult + }, + gainExp() { // Calculate the exponent on main currency from bonuses + exp = new Decimal(1) + if (player.d.unl && player.d.banking == 3) exp = exp.div(2) + return exp + }, + row: 1, // Row the layer is in on the tree (0 is the first row) + effect() { + let base = new Decimal(2) + if (player[this.layer].upgrades.includes(12)) base = base.add(layers[this.layer].upgrades[12].effect()) + if (player[this.layer].upgrades.includes(13)) base = base.add(layers[this.layer].upgrades[13].effect()) + if (player.e.unl && tmp.buyables) base = base.add(tmp.e.buyables[11].effect.first) + if (!player.s.active) if (player.pr.buyables[12].gt(0)) base = base.add(layers.pr.buyables[12].effect().first) + if (player.g.upgrades.includes(23)) base = base.mul(2) + if (player.s.active == 11) base = base.pow(0.1) + if (player.d.unl && player.d.banking == 3) base = new Decimal(2) + let exp = new Decimal(1) + if (player.d.banking == 1) exp = exp.div(2) + let free = new Decimal(0) + if (!player.s.active) if (player.pr.buyables[14].gt(0)) free = free.add(layers.pr.buyables[14].effect().first) + return Decimal.pow(base, player[this.layer].points.add(free)).pow(exp) + }, + effectDescription:() => "multiplying point gain by "+format(layers[this.layer].effect())+"x", + milestones: { + 0: { + requirementDesc:() => "4 boosters", + effectDesc:() => "You don't lose prestige upgrades on booster resets", + done() { + return player[this.layer].best.gte(4) || player.e.milestones.includes("0") || player.r.milestones.includes("0") || player.d.milestones.includes("0"); + } + }, + 1: { + requirementDesc:() => "8 boosters", + effectDesc:() => "You can max-buy boosters.", + done() { + return player[this.layer].best.gte(8); + } + } + }, + doReset(resettingLayer){ // Triggers when this layer is being reset, along with the layer doing the resetting. Not triggered by lower layers resetting, but is by layers on the same row. + let unlocked = true + let autoed = player[this.layer].auto + if(resettingLayer == "r") { + if (player.r.milestones.includes("2")) { + let milestones = player[this.layer].milestones + let upgrades = player[this.layer].upgrades + fullLayerReset(this.layer) + player[this.layer].milestones = milestones + player[this.layer].upgrades = upgrades + player[this.layer].unl = unlocked + player[this.layer].auto = autoed + return; + } + if (player.r.milestones.includes("1")) { + let milestones = player[this.layer].milestones + fullLayerReset(this.layer) + player[this.layer].milestones = milestones + player[this.layer].unl = unlocked + player[this.layer].auto = autoed + return; + } + } + if(resettingLayer == "d") { + if (player.d.milestones.includes("2")) { + let milestones = player[this.layer].milestones + let upgrades = player[this.layer].upgrades + fullLayerReset(this.layer) + player[this.layer].milestones = milestones + player[this.layer].upgrades = upgrades + player[this.layer].unl = unlocked + player[this.layer].auto = autoed + return; + } + if (player.d.milestones.includes("1")) { + let milestones = player[this.layer].milestones + fullLayerReset(this.layer) + player[this.layer].milestones = milestones + player[this.layer].unl = unlocked + player[this.layer].auto = autoed + return; + } + } + if(resettingLayer == "e") { + if (player.e.milestones.includes("2")) { + let milestones = player[this.layer].milestones + let upgrades = player[this.layer].upgrades + fullLayerReset(this.layer) + player[this.layer].milestones = milestones + player[this.layer].upgrades = upgrades + player[this.layer].unl = unlocked + player[this.layer].auto = autoed + return; + } + if (player.e.milestones.includes("1")) { + let milestones = player[this.layer].milestones + fullLayerReset(this.layer) + player[this.layer].milestones = milestones + player[this.layer].unl = unlocked + player[this.layer].auto = autoed + return; + } + } + if(layers[resettingLayer].row > this.row) { + fullLayerReset(this.layer) // This is actually the default behavior + player[this.layer].unl = unlocked + } + }, + layerShown() {return player.p.unl}, // Condition for when layer appears on the tree + resetsNothing() {return player.e.milestones.includes("3") || player.r.milestones.includes("3") || player.d.milestones.includes("3")}, + upgrades: { + rows: 2, + cols: 3, + 11: { + desc:() => "Boosters multiply prestige points.", + cost:() => new Decimal(3), + unl() { return player[this.layer].unl }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player[this.layer].points.add(2).log10().add(1).pow(2) + return ret; + }, + effectDisplay() { return format(tmp[this.layer].upgrades[this.id].effect)+"x" }, // Add formatting to the effect + }, + 12: { + desc:() => "Generators add to the base of Boosters.", + cost:() => new Decimal(8), + unl() { return player[this.layer].upgrades.includes(11) && player.g.unl }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player.g.points.add(1).log10().div(3) + return ret; + }, + effectDisplay() { return "+"+format(tmp[this.layer].upgrades[this.id].effect) }, // Add formatting to the effect + }, + 13: { + desc:() => "Prestige Points add to the base of Boosters.", + cost:() => new Decimal(16), + unl() { return player[this.layer].upgrades.includes(12) }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player.p.points.add(1).log10().root(7).div(3) + return ret; + }, + effectDisplay() { return "+"+format(tmp[this.layer].upgrades[this.id].effect) }, // Add formatting to the effect + }, + 21: { + desc:() => "Points divide the Booster cost.", + cost:() => new Decimal(20), + unl() { return player[this.layer].upgrades.includes(13) }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = (player.points.add(1)).root(15) + return ret; + }, + effectDisplay() { return "/"+format(tmp[this.layer].upgrades[this.id].effect) }, // Add formatting to the effect + }, + 22: { + desc:() => "Square the Generator Power effect.", + cost:() => new Decimal(21), + unl() { return player[this.layer].upgrades.includes(21) }, // The upgrade is only visible when this is true + }, + 23: { + desc:() => "Boosters multiply Generator Power gain.", + cost:() => new Decimal(24), + unl() { return player[this.layer].upgrades.includes(22) }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player.b.points.add(1).log10().add(1).pow(5) + return ret; + }, + effectDisplay(fx) { return format(tmp[this.layer].upgrades[this.id].effect)+"x" }, // Add formatting to the effect + }, + }, + hotkeys: [ + {key: "b", desc: "B: Reset points for boosters.", onPress(){if (player[this.layer].unl) doReset(this.layer)}}, + ], + incr_order: [], // Array of layer names to have their order increased when this one is first unlocked + prestigeButtonText() { //Is secretly HTML + return `Convert your points into +${formatWhole(tmp[layer].resetGain)} ${layers[layer].resource}

${(tmp[layer].baseAmount.gte(tmp[layer].nextAt)&&layers[layer].canBuyMax && layers[layer].canBuyMax())?"Next":"Req"}: ${formatWhole(tmp[layer].baseAmount)} / ${(layers[layer].resCeil ? formatWhole(tmp[layer].nextAtDisp) : format(tmp[layer].nextAtDisp))} ${ layers[layer].baseResource }` + }, + getResetGain() { + if ((!layers[layer].canBuyMax()) || tmp[layer].baseAmount.lt(tmp[layer].requires)) return new Decimal(1) + let gain = tmp[layer].baseAmount.div(tmp[layer].requires).div(tmp[layer].gainMult).max(1).log(layers[layer].base).times(tmp[layer].gainExp).pow(Decimal.pow(layers[layer].exponent, -1)) + if (gain.gte(12)) { + gain = gain.times(12).sqrt() + } + if (gain.gte(1225)) gain = gain.times(Decimal.pow(1225, 9)).pow(0.1) + return gain.floor().sub(player[layer].points).add(1).max(1); + }, + getNextAt() { + let amt = player[layer].points + if (amt.gte(1225)) amt = amt.pow(10).div(Decimal.pow(1225, 9)) + if (amt.gte(12)) { + amt = amt.pow(2).div(12) + } + let extraCost = Decimal.pow(layers[layer].base, amt.pow(layers[layer].exponent).div(tmp[layer].gainExp)).times(tmp[layer].gainMult) + let cost = extraCost.times(tmp[layer].requires).max(tmp[layer].requires) + if (layers[layer].resCeil) cost = cost.ceil() + return cost; + }, + canReset() { + return tmp[this.layer].baseAmount.gte(tmp[this.layer].nextAt) + }, + automate() { + if (player.e.milestones.includes("4") || player.r.milestones.includes("4") || player.d.milestones.includes("4") && player[this.layer].auto) doReset(this.layer, false) + }, // Do any automation inherent to this layer if appropriate + // Optional, lets you format the tab yourself by listing components. You can create your own components in v.js. + tabFormat: ["main-display", + ["prestige-button", function() {return "Convert your points into "}, {}], + ["blank", "5px"], // Height + ["display-text", + function() {return 'You have ' + format(player.points) + ' points.'}, + {"font-size": "14px"}], + "upgrades", "blank", "milestones"], + branches: [["p", 1]] + /*style() {return { + 'background-color': '#3325CC' + }},*/ +}) + + +addLayer("g", { + startData() { return { + unl: false, + auto: false, + points: new Decimal(0), + best: new Decimal(0), + total: new Decimal(0), + power: new Decimal(0), + milestones: [] + }}, + color:() => "#409c6e", + background:() => 'https://cdn.glitch.com/7460ed4d-c31b-459d-8407-710f48e787a3%2Fefdb5b70-5e55-4f23-9524-953a8eea4545.image.png?v=1601771864943', + requires() { + let req = new Decimal(5000) + if (player.b.unl && !player.g.unl) req = req.mul(500) + return req + }, // Can be a function that takes requirement increases into account + resource: "generators", // Name of prestige currency + baseResource: "points", // Name of resource prestige is based on + baseAmount() {return player.points}, // Get the current amount of baseResource + type: "custom", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have + exponent: 1, // Prestige currency exponent + base: 5, // Only needed for static layers, base of the formula (b^(x^exp)) + resCeil: false, // True if the cost needs to be rounded up (use when baseResource is static?) + canBuyMax() { + return player[this.layer].milestones.includes("1") + }, // Only needed for static layers with buy max + gainMult() { // Calculate the multiplier for main currency from bonuses + mult = new Decimal(1) + if (player[this.layer].upgrades.includes(21)) mult = mult.div(layers[this.layer].upgrades[21].effect()) + if (!player.s.active) if (player.pr.buyables[11].gt(0)) mult = mult.div(layers.pr.buyables[11].effect().first) + if (player.s.challs.includes(12)) mult = mult.div(layers.s.challs[12].effect()) + return mult + }, + gainExp() { // Calculate the exponent on main currency from bonuses + exp = new Decimal(1) + if (player.d.unl && player.d.banking == 3) exp = exp.div(2) + return exp + }, + row: 1, // Row the layer is in on the tree (0 is the first row) + effect() { + let base = new Decimal(2) + if (player[this.layer].upgrades.includes(12)) base = base.add(layers[this.layer].upgrades[12].effect()) + if (player[this.layer].upgrades.includes(13)) base = base.add(layers[this.layer].upgrades[13].effect()) + if (player.r.upgrades.includes(14)) base = base.add(layers.r.upgrades[14].effect()) + if (player.e.unl && tmp.buyables) base = base.add(tmp.e.buyables[11].effect.first) + if (!player.s.active) if (player.pr.buyables[12].gt(0)) base = base.add(layers.pr.buyables[12].effect().first) + if (player.s.active == 11) base = base.pow(0.1) + if (player.d.unl && player.d.banking == 3) base = new Decimal(2) + + let genMult = new Decimal(1) + if (player[this.layer].upgrades.includes(14)) genMult = genMult.add(layers[this.layer].upgrades[14].effect()) + if (player[this.layer].upgrades.includes(22)) genMult = genMult.add(layers[this.layer].upgrades[22].effect()) + if (player.b.upgrades.includes(23)) genMult = genMult.add(layers.b.upgrades[23].effect(player.e.buyables[11])) + if (player.r.unl) genMult = genMult.times(layers.r.effect().powerBoost) + if (player.d.unl) genMult = genMult.times(layers.d.buyables[13].effect(player.d.buyables[13]).first) + + let powerPow = new Decimal(1) + if (player.b.upgrades.includes(21)) powerPow = powerPow.add(1) + if (player.d.banking == 1) powerPow = powerPow.div(2) + + let freeGens = new Decimal(0) + if (player.r.unl && tmp.buyables) freeGens = freeGens.add(tmp.r.buyables[13].effect.first) + if (!player.s.active) if (player.pr.buyables[14].gt(0)) freeGens = freeGens.add(layers.pr.buyables[14].effect().first) + return { + genProd: Decimal.pow(base, player[this.layer].points.add(freeGens)).sub(1).mul(genMult), + powerBoost: player.g.power.add(1).pow(1/3).pow(powerPow) + } + }, + effectDescription() {return "producing "+format(layers[this.layer].effect().genProd)+" generator power each second"}, + milestones: { + 0: { + requirementDesc:() => "4 generators", + effectDesc:() => "You don't lose prestige upgrades on generator resets", + done() { + return player[this.layer].best.gte(4) || player.e.milestones.includes("0") || player.r.milestones.includes("0") || player.d.milestones.includes("0"); + } + }, + 1: { + requirementDesc:() => "8 generators", + effectDesc:() => "You can buy max generators.", + done() { + return player[this.layer].best.gte(8); + } + }, + 2: { + requirementDesc:() => "14 generators", + effectDesc:() => "You get 100% of Prestige Points gained on Prestige each second.", + done() { + return player[this.layer].best.gte(14); + } + } + }, + doReset(resettingLayer){ // Triggers when this layer is being reset, along with the layer doing the resetting. Not triggered by lower layers resetting, but is by layers on the same row. + if(layers[resettingLayer].row > this.row-1) player.g.power = new Decimal(0) + let unlocked = true + let autoed = player[this.layer].auto + if(resettingLayer == "d") { + if (player.d.milestones.includes("2")) { + let milestones = player[this.layer].milestones + let upgrades = player[this.layer].upgrades + fullLayerReset(this.layer) + player[this.layer].milestones = milestones + player[this.layer].upgrades = upgrades + player[this.layer].unl = unlocked + player[this.layer].auto = autoed + return; + } + if (player.d.milestones.includes("1")) { + let milestones = player[this.layer].milestones + fullLayerReset(this.layer) + player[this.layer].milestones = milestones + player[this.layer].unl = unlocked + player[this.layer].auto = autoed + return; + } + } + if(resettingLayer == "r") { + if (player.r.milestones.includes("2")) { + let milestones = player[this.layer].milestones + let upgrades = player[this.layer].upgrades + fullLayerReset(this.layer) + player[this.layer].milestones = milestones + player[this.layer].upgrades = upgrades + player[this.layer].unl = unlocked + player[this.layer].auto = autoed + return; + } + if (player.r.milestones.includes("1")) { + let milestones = player[this.layer].milestones + fullLayerReset(this.layer) + player[this.layer].milestones = milestones + player[this.layer].unl = unlocked + player[this.layer].auto = autoed + return; + } + } + if(resettingLayer == "e") { + if (player.e.milestones.includes("2")) { + let milestones = player[this.layer].milestones + let upgrades = player[this.layer].upgrades + fullLayerReset(this.layer) + player[this.layer].milestones = milestones + player[this.layer].upgrades = upgrades + player[this.layer].unl = unlocked + player[this.layer].auto = autoed + return; + } + if (player.e.milestones.includes("1")) { + let milestones = player[this.layer].milestones + fullLayerReset(this.layer) + player[this.layer].milestones = milestones + player[this.layer].unl = unlocked + player[this.layer].auto = autoed + return; + } + } + if(layers[resettingLayer].row > this.row) { + fullLayerReset(this.layer) // This is actually the default behavior + player[this.layer].unl = unlocked + } + }, + convertToDecimal() { + player.g.power = new Decimal(player.g.power) + // Convert any layer-specific Decimal values (besides points, total, and best) from String to Decimal (used when loading save) + }, + layerShown() {return player.p.unl}, // Condition for when layer appears on the tree + automate() { + if (player.e.milestones.includes("4") || player.r.milestones.includes("4") || player.d.milestones.includes("4") && player[this.layer].auto) doReset(this.layer, false) + }, // Do any automation inherent to this layer if appropriate + updateTemp() { + }, // Do any necessary temp updating, not that important usually + update(diff) { + if (player.g.unl) player.g.power = player.g.power.add(layers[this.layer].effect().genProd.mul(diff)) + if (player[this.layer].milestones.includes("2")) generatePoints("p", diff) + }, + resetsNothing() {return player.e.milestones.includes("3") || player.r.milestones.includes("3") || player.d.milestones.includes("3")}, + onPrestige(gain) { + return + }, // Useful for if you gain secondary resources or have other interesting things happen to this layer when you reset it. You gain the currency after this function ends. + upgrades: { + rows: 2, + cols: 4, + 11: { + desc:() => "Generators multiply prestige points.", + cost:() => new Decimal(3), + unl() { return player[this.layer].unl }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player[this.layer].points.add(2).log10().add(1).pow(2) + return ret; + }, + effectDisplay(fx) { return format(tmp[this.layer].upgrades[this.id].effect)+"x" }, // Add formatting to the effect + }, + 12: { + desc:() => " Boosters add to the base of Generators.", + cost:() => new Decimal(8), + unl() { return player[this.layer].upgrades.includes(11) && player.b.unl }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player.b.points.add(1).log10().div(3) + return ret; + }, + effectDisplay(fx) { return "+"+format(tmp[this.layer].upgrades[this.id].effect) }, // Add formatting to the effect + }, + 13: { + desc:() => "Prestige Points add to the base of Generators.", + cost:() => new Decimal(16), + unl() { return player[this.layer].upgrades.includes(12) }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player.p.points.add(1).log10().root(7).div(3) + return ret; + }, + effectDisplay(fx) { return "+"+format(tmp[this.layer].upgrades[this.id].effect) }, // Add formatting to the effect + }, + 14: { + desc:() => "Generator Power boosts itself.", + cost:() => new Decimal(19), + unl() { return player[this.layer].upgrades.includes(13) }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player[this.layer].power.add(1).log10().add(1).pow(1.15) + return ret; + }, + effectDisplay(fx) { return format(tmp[this.layer].upgrades[this.id].effect)+"x" }, // Add formatting to the effect + }, + 21: { + desc:() => "Prestige Points divide the Generator cost.", + cost:() => new Decimal(24), + unl() { return player[this.layer].upgrades.includes(14) }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = (player.p.points.add(1)).root(13) + return ret; + }, + effectDisplay(fx) { return "/"+format(tmp[this.layer].upgrades[this.id].effect) }, // Add formatting to the effect + }, + 22: { + desc:() => "Points multiply Generator Power gain.", + cost:() => new Decimal(25), + unl() { return player[this.layer].upgrades.includes(21) }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player.points.add(1).log10().add(1).pow(2) + return ret; + }, + effectDisplay(fx) { return format(tmp[this.layer].upgrades[this.id].effect)+"x" }, // Add formatting to the effect + }, + 23: { + desc:() => "Double the Booster base.", + cost:() => new Decimal(26), + unl() { return player[this.layer].upgrades.includes(22) }, // The upgrade is only visible when this is true + }, + 24: { + desc:() => "???", + cost:() => new Decimal(1/0), + unl() { return false }, // The upgrade is only visible when this is true + }, + }, + hotkeys: [ + {key: "g", desc: "G: Reset points for generators.", onPress(){if (player[this.layer].unl) doReset(this.layer)}}, + ], + incr_order: [], // Array of layer names to have their order increased when this one is first unlocked + prestigeButtonText() { //Is secretly HTML + return `Convert your points into +${formatWhole(tmp[layer].resetGain)} ${layers[layer].resource}

${(tmp[layer].baseAmount.gte(tmp[layer].nextAt)&&layers[layer].canBuyMax && layers[layer].canBuyMax())?"Next":"Req"}: ${formatWhole(tmp[layer].baseAmount)} / ${(layers[layer].resCeil ? formatWhole(tmp[layer].nextAtDisp) : format(tmp[layer].nextAtDisp))} ${ layers[layer].baseResource }` + }, + getResetGain() { + if ((!layers[layer].canBuyMax()) || tmp[layer].baseAmount.lt(tmp[layer].requires)) return new Decimal(1) + let gain = tmp[layer].baseAmount.div(tmp[layer].requires).div(tmp[layer].gainMult).max(1).log(layers[layer].base).times(tmp[layer].gainExp).pow(Decimal.pow(layers[layer].exponent, -1)) + if (gain.gte(12)) { + gain = gain.times(12).sqrt() + } + if (gain.gte(1225)) gain = gain.times(Decimal.pow(1225, 9)).pow(0.1) + return gain.floor().sub(player[layer].points).add(1).max(1); + }, + getNextAt() { + let amt = player[layer].points + if (amt.gte(1225)) amt = amt.pow(10).div(Decimal.pow(1225, 9)) + if (amt.gte(12)) { + amt = amt.pow(2).div(12) + } + let extraCost = Decimal.pow(layers[layer].base, amt.pow(layers[layer].exponent).div(tmp[layer].gainExp)).times(tmp[layer].gainMult) + let cost = extraCost.times(tmp[layer].requires).max(tmp[layer].requires) + if (layers[layer].resCeil) cost = cost.ceil() + return cost; + }, + canReset() { + return tmp[this.layer].baseAmount.gte(tmp[this.layer].nextAt) + }, + + // Optional, lets you format the tab yourself by listing components. You can create your own components in v.js. + tabFormat: ["main-display", + ["prestige-button", function() {return "Convert your points into "}, {}], + ["display-text", + function() {return 'You have ' + format(player.points) + ' points.'}, + {"font-size": "14px"}], + ["blank", "5px"], // Height + ["display-text", + function() {return 'You have ' + format(player.g.power) + ' generator power, translating to a '+format(layers.g.effect().powerBoost)+'x multiplier to points.'}, + {"font-size": "14px"}], + "upgrades", "blank", "milestones"], + branches: [["p", 1]] + /*style() {return { + 'background-color': '#3325CC' + }},*/ +}) + +addLayer("e", { + startData() { return { + unl: false, + points: new Decimal(0), + best: new Decimal(0), + total: new Decimal(0), + milestones: [], + order: 0 + }}, + color:() => "#9643a3", + background:() => 'https://cdn.glitch.com/7460ed4d-c31b-459d-8407-710f48e787a3%2Fefdb5b70-5e55-4f23-9524-953a8eea4545.image.png?v=1601771864943', + requires() { + let req = new Decimal(1e60) + if (!player[this.layer].upgrades.includes(14)) if (player[this.layer].order > 0) req = req.pow(player[this.layer].order+1) + return req + }, // Can be a function that takes requirement increases into account + resource: "enhance points", // 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: 0.04, // Prestige currency exponent + base: 5, // Only needed for static layers, base of the formula (b^(x^exp)) + resCeil: false, // True if the cost needs to be rounded up (use when baseResource is static?) + canBuyMax() {}, // Only needed for static layers with buy max + gainMult() { // Calculate the multiplier for main currency from bonuses + mult = new Decimal(1) + if (player[this.layer].upgrades.includes(12)) mult = mult.mul(layers[this.layer].upgrades[12].effect()) + return mult + }, + 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) + milestones: { + 0: { + requirementDesc:() => "1 enhance point", + effectDesc:() => "You don't lose prestige upgrades on previous resets and this resets", + done() { + return player[this.layer].best.gte(1); + } + }, + 1: { + requirementDesc:() => "3 enhance points", + effectDesc:() => "You keep all booster and generator milestones on reset.", + done() { + return player[this.layer].best.gte(3); + } + }, + 2: { + requirementDesc:() => "10 enhance points", + effectDesc:() => "You keep booster and generator upgrades on reset.", + done() { + return player[this.layer].best.gte(10); + } + }, + 3: { + requirementDesc:() => "15 enhance points", + effectDesc:() => "Boosters and generators do not reset everything.", + done() { + return player[this.layer].best.gte(15); + } + }, + 4: { + requirementDesc:() => "50 enhance points", + effectDesc:() => "Automate boosters and generators.", + done() { + return player[this.layer].best.gte(50); + }, + toggles: [ + ["b", "auto"], + ["g", "auto"] + ] + } + }, + buyables: { + rows: 1, + cols: 1, + 11: { + title:() => "Enhancers", // Optional, displayed at the top in a larger font + cost() { // cost for buying xth buyable, can be an object if there are multiple currencies + let x = player[this.layer].buyables[this.id] + if (x.gte(25)) x = x.pow(2).div(25) + if (player[this.layer].upgrades.includes(13)) x = x.div(layers[this.layer].upgrades[13].effect()) + let cost = Decimal.pow(2, x.pow(1.5)) + return cost.floor() + }, + effect() { // Effects of owning x of the items, x is a decimal + let x = player[this.layer].buyables[this.id] + + let eff = {} + eff.first = Decimal.pow(1.5, x.sqrt()) + + eff.second = x.add(1).pow(3) + return eff; + }, + display() { // Everything else displayed in the buyable button after the title + let data = tmp[this.layer].buyables[this.id] + return "Cost: " + format(data.cost) + " enhance points\n\ + Amount: " + player[this.layer].buyables[this.id] + "\n\ + Adds + " + format(data.effect.first) + " to the booster and generator base and multiply points and prestige points by " + format(data.effect.second) + }, + unl() { return player[this.layer].unl }, + canAfford() { + return player[this.layer].points.gte(tmp[this.layer].buyables[this.id].cost)}, + buy() { + cost = tmp[this.layer].buyables[this.id].cost + player[this.layer].points = player[this.layer].points.sub(cost) + player[this.layer].buyables[this.id] = player[this.layer].buyables[this.id].add(1) + player[this.layer].spentOnBuyables = player[this.layer].spentOnBuyables.add(cost) // This is a built-in system that you can use for respeccing but it only works with a single Decimal value + }, + buyMax() {}, // You'll have to handle this yourself if you want + }, + }, + doReset(resettingLayer){ // Triggers when this layer is being reset, along with the layer doing the resetting. Not triggered by lower layers resetting, but is by layers on the same row. + }, + layerShown() {return player.b.unl && player.g.unl}, // Condition for when layer appears on the tree + automate() { + }, // Do any automation inherent to this layer if appropriate + updateTemp() { + }, // Do any necessary temp updating, not that important usually + resetsNothing() {return false}, + onPrestige(gain) { + return + }, // Useful for if you gain secondary resources or have other interesting things happen to this layer when you reset it. You gain the currency after this function ends. + upgrades: { + rows: 1, + cols: 4, + 11: { + desc:() => "Enhance points boost point and prestige point gain.", + cost:() => new Decimal(100), + unl() { return player[this.layer].unl }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player[this.layer].points.add(2).root(1.5) + return ret; + }, + effectDisplay(fx) { return format(tmp[this.layer].upgrades[this.id].effect)+"x" }, // Add formatting to the effect + }, + 12: { + desc:() => "Generator Power boosts enhance point gain.", + cost:() => new Decimal(500), + unl() { return player[this.layer].upgrades.includes(11) }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player.g.power.add(1).log10().add(1).root(8) + return ret; + }, + effectDisplay(fx) { return format(tmp[this.layer].upgrades[this.id].effect)+"x" }, // Add formatting to the effect + }, + 13: { + desc:() => "Boosters reduce the enhancer cost formula power.", + cost:() => new Decimal(1000), + unl() { return player[this.layer].upgrades.includes(12) }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player.b.points.add(1).log10().add(1).root(3) + return ret; + }, + effectDisplay(fx) { return "/"+format(tmp[this.layer].upgrades[this.id].effect) }, // Add formatting to the effect + }, + 14: { + desc:() => "This layer behaves like it was bought first..", + cost:() => new Decimal(1000), + unl() { return player[this.layer].order > 0 && player[this.layer].upgrades.includes(13) }, // The upgrade is only visible when this is true + }, + }, + hotkeys: [ + {key: "e", desc: "E: Reset points for enhance points.", onPress(){if (player[this.layer].unl) doReset(this.layer)}}, + ], + tooltipLocked() { // Optional, tooltip displays when the layer is locked + return ("(Passive layer) This layer requires " + this.requires() + " points. You only have " + formatWhole(player.points)) + }, + incr_order: ["r", "d"], + + // Optional, lets you format the tab yourself by listing components. You can create your own components in v.js. + tabFormat: ["main-display", + ["prestige-button", function() {return "Convert your points into "}, {}], + ["display-text", + function() {return 'You have ' + format(player.points) + ' points.'}, + {"font-size": "14px"}], + ["blank", "5px"], // Height + "buyables", "blank", "blank", + "upgrades", "blank", "milestones"], + branches: [["b", 1], ["g", 1]] + /*style() {return { + 'background-color': '#3325CC' + }},*/ +}) + +addLayer("r", { + startData() { return { + unl: false, + points: new Decimal(0), + best: new Decimal(0), + total: new Decimal(0), + milestones: [], + power: new Decimal(1), + order: 0 + }}, + color:() => "#94bc42", + background:() => 'https://cdn.glitch.com/7460ed4d-c31b-459d-8407-710f48e787a3%2Fefdb5b70-5e55-4f23-9524-953a8eea4545.image.png?v=1601771864943', + requires() { + let req = new Decimal(1e20) + if (!player[this.layer].upgrades.includes(15)) if (player[this.layer].order > 0) req = req.pow(player[this.layer].order+1) + return req + }, // Can be a function that takes requirement increases into account + resource: "replicators", // Name of prestige currency + baseResource: "generator power", // Name of resource prestige is based on + baseAmount() {return player.g.power}, // Get the current amount of baseResource + type: "custom", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have + exponent: 1, // Prestige currency exponent + base: 25, // Only needed for static layers, base of the formula (b^(x^exp)) + resCeil: false, // True if the cost needs to be rounded up (use when baseResource is static?) + canBuyMax() {return player[this.layer].milestones.includes("4")}, // Only needed for static layers with buy max + gainMult() { // Calculate the multiplier for main currency from bonuses + mult = new Decimal(1) + return mult + }, + 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) + effect() { + let base = new Decimal(1) + if (player.r.unl && tmp.buyables) base = base.mul(tmp.r.buyables[11].effect.first) + if (player[this.layer].upgrades.includes(12)) base = base.mul(layers[this.layer].upgrades[12].effect()) + if (player[this.layer].upgrades.includes(13)) base = base.mul(layers[this.layer].upgrades[13].effect()) + + let genMult = new Decimal(1) + if (player.r.unl && tmp.buyables) genMult = genMult.mul(tmp.r.buyables[12].effect.first) + + return { + genProd: player[this.layer].points.add(1).log10().add(1).pow(base).sub(1), + powerBoost: player.r.power.add(1).log2().add(1).pow(genMult) + } + }, + effectDescription() {return "making replicanti multiply by "+format(layers[this.layer].effect().genProd.add(1))+" each second"}, + milestones: { + 0: { + requirementDesc:() => "1 replicator", + effectDesc:() => "You don't lose prestige upgrades on previous resets and this resets", + done() { + return player[this.layer].best.gte(1); + } + }, + 1: { + requirementDesc:() => "2 replicators", + effectDesc:() => "You keep all booster and generator milestones on reset.", + done() { + return player[this.layer].best.gte(2); + } + }, + 2: { + requirementDesc:() => "4 replicators", + effectDesc:() => "You keep booster and generator upgrades on reset.", + done() { + return player[this.layer].best.gte(4); + } + }, + 3: { + requirementDesc:() => "5 replicators", + effectDesc:() => "Boosters and generators do not reset everything.", + done() { + return player[this.layer].best.gte(5); + } + }, + 4: { + requirementDesc:() => "8 replicators", + effectDesc:() => "Automate boosters and generators, and you can buy max replicators.", + done() { + return player[this.layer].best.gte(8); + }, + toggles: [ + ["b", "auto"], + ["g", "auto"] + ] + } + }, + buyables: { + rows: 1, + cols: 3, + 11: { + title:() => "Replication Up", // Optional, displayed at the top in a larger font + cost() { // cost for buying xth buyable, can be an object if there are multiple currencies + let x = player[this.layer].buyables[this.id] + if (x.gte(25)) x = x.pow(2).div(25) + if (player[this.layer].buyables[this.id].gte(150)) x = x.pow(1.5).div(12.2474487139) + let cost = Decimal.pow(500, x.add(1).pow(1.5)) + return cost.floor() + }, + effect() { // Effects of owning x of the items, x is a decimal + let x = player[this.layer].buyables[this.id] + let eff = {} + eff.first = Decimal.pow(1.4, x.sqrt()) + return eff; + }, + display() { // Everything else displayed in the buyable button after the title + let data = tmp[this.layer].buyables[this.id] + return "Cost: " + format(data.cost) + " replicanti\n\ + Amount: " + player[this.layer].buyables[this.id] + "\n\ + Multiplies replicator power by " + format(data.effect.first) + "x" + }, + unl() { return player[this.layer].unl }, + canAfford() { + return player[this.layer].power.gte(tmp[this.layer].buyables[this.id].cost)}, + buy() { + cost = tmp[this.layer].buyables[this.id].cost + player[this.layer].power = player[this.layer].power.sub(cost) + player[this.layer].buyables[this.id] = player[this.layer].buyables[this.id].add(1) + player[this.layer].spentOnBuyables = player[this.layer].spentOnBuyables.add(cost) // This is a built-in system that you can use for respeccing but it only works with a single Decimal value + }, + buyMax() {}, // You'll have to handle this yourself if you want + }, + 12: { + title:() => "Effect Up", // Optional, displayed at the top in a larger font + cost() { // cost for buying xth buyable, can be an object if there are multiple currencies + let x = player[this.layer].buyables[this.id] + if (x.gte(25)) x = x.pow(2).div(25) + if (player[this.layer].buyables[this.id].gte(150)) x = x.pow(1.5).div(12.2474487139) + let cost = Decimal.pow(1000, x.add(1).pow(1.5)) + return cost.floor() + }, + effect() { // Effects of owning x of the items, x is a decimal + let x = player[this.layer].buyables[this.id] + let eff = {} + eff.first = x.add(1).log10().add(1).pow(0.25) + return eff; + }, + display() { // Everything else displayed in the buyable button after the title + let data = tmp[this.layer].buyables[this.id] + return "Cost: " + format(data.cost) + " replicanti\n\ + Amount: " + player[this.layer].buyables[this.id] + "\n\ + Multiplies replicanti power by " + format(data.effect.first) + "x" + }, + unl() { return player[this.layer].unl }, + canAfford() { + return player[this.layer].power.gte(tmp[this.layer].buyables[this.id].cost)}, + buy() { + cost = tmp[this.layer].buyables[this.id].cost + player[this.layer].power = player[this.layer].power.sub(cost) + player[this.layer].buyables[this.id] = player[this.layer].buyables[this.id].add(1) + player[this.layer].spentOnBuyables = player[this.layer].spentOnBuyables.add(cost) // This is a built-in system that you can use for respeccing but it only works with a single Decimal value + }, + buyMax() {}, // You'll have to handle this yourself if you want + }, + 13: { + title:() => "Generator", // Optional, displayed at the top in a larger font + cost() { // cost for buying xth buyable, can be an object if there are multiple currencies + let x = player[this.layer].buyables[this.id] + if (x.gte(5)) x = x.pow(3).div(25) + if (player[this.layer].buyables[this.id].gte(25)) x = x.pow(4).div(244140625) + if (player[this.layer].buyables[this.id].gte(50)) x = x.pow(5).div(3.90625e13) + let cost = Decimal.pow("1.80e308", x.add(1).pow(0.125)) + return cost.floor() + }, + effect() { // Effects of owning x of the items, x is a decimal + let x = player[this.layer].buyables[this.id] + let eff = {} + eff.first = x + return eff; + }, + display() { // Everything else displayed in the buyable button after the title + let data = tmp[this.layer].buyables[this.id] + return "Cost: " + format(data.cost) + " replicanti\n\ + Amount: " + player[this.layer].buyables[this.id] + "\n\ + Get " + format(data.effect.first) + " free generators, and increase the replicanti limit by "+format(tmp[this.layer].buyables[this.id].cost.div("1.80e308"))+"x" + }, + unl() { return player[this.layer].unl }, + canAfford() { + return player[this.layer].power.gte(tmp[this.layer].buyables[this.id].cost)}, + buy() { + cost = tmp[this.layer].buyables[this.id].cost + player[this.layer].power = player[this.layer].power.sub(cost) + player[this.layer].buyables[this.id] = player[this.layer].buyables[this.id].add(1) + player[this.layer].spentOnBuyables = player[this.layer].spentOnBuyables.add(cost) // This is a built-in system that you can use for respeccing but it only works with a single Decimal value + }, + buyMax() {}, // You'll have to handle this yourself if you want + }, + }, + upgrades: { + rows: 1, + cols: 5, + 11: { + desc:() => "Replicanti boosts point gain.", + cost:() => new Decimal(3), + unl() { return player[this.layer].unl }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player[this.layer].power.add(1).log2().add(1).log2().add(1).pow(3) + return ret; + }, + effectDisplay(fx) { return format(tmp[this.layer].upgrades[this.id].effect)+"x" }, // Add formatting to the effect + }, + 12: { + desc:() => "Generator Power boosts replicanti gain.", + cost:() => new Decimal(7), + unl() { return player[this.layer].upgrades.includes(11) }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player.g.power.add(1).log2().add(1).log2().add(1).log2().add(1) + return ret; + }, + effectDisplay(fx) { return format(tmp[this.layer].upgrades[this.id].effect)+"x" }, // Add formatting to the effect + }, + 13: { + desc:() => "Replicanti boosts itself.", + cost:() => new Decimal(14), + unl() { return player[this.layer].upgrades.includes(12) }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player[this.layer].power.add(1).log2().add(1).log2().add(1).log2().add(1).log2().add(1) + return ret; + }, + effectDisplay(fx) { return format(tmp[this.layer].upgrades[this.id].effect)+"x" }, // Add formatting to the effect + }, + 14: { + desc:() => "Replicators boost the generator base.", + cost:() => new Decimal(17), + unl() { return player[this.layer].upgrades.includes(13) }, // The upgrade is only visible when this is true + effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values + let ret = player[this.layer].points.add(1).log2().add(1).log2().add(1).cbrt() + return ret; + }, + effectDisplay(fx) { return "+"+format(tmp[this.layer].upgrades[this.id].effect) }, // Add formatting to the effect + }, + 15: { + desc:() => "This layer behaves like it was bought first.", + cost:() => new Decimal(20), + unl() { return player[this.layer].order > 0 && player[this.layer].upgrades.includes(14) }, // The upgrade is only visible when this is true + }, + }, + doReset(resettingLayer){ // Triggers when this layer is being reset, along with the layer doing the resetting. Not triggered by lower layers resetting, but is by layers on the same row. + if(layers[resettingLayer].row > this.row-1) player.r.power = new Decimal(1) + }, + convertToDecimal() { + player.r.power = new Decimal(player.r.power).max(1) + }, + layerShown() {return player.g.unl}, // Condition for when layer appears on the tree + automate() { + }, // Do any automation inherent to this layer if appropriate + updateTemp() { + }, // Do any necessary temp updating, not that important usually + resetsNothing() {return false}, + onPrestige(gain) { + return + }, // Useful for if you gain secondary resources or have other interesting things happen to this layer when you reset it. You gain the currency after this function ends. + update(diff) { + player.r.power = player.r.power.mul(layers[this.layer].effect().genProd.mul(diff).add(1)).max(1).min(tmp["r"].buyables[13].cost) + }, + hotkeys: [ + {key: "r", desc: "R: Reset generator power for replicators.", onPress(){if (player[this.layer].unl) doReset(this.layer)}}, + ], + prestigeButtonText() { //Is secretly HTML + return `Convert your generator power into +${formatWhole(tmp[layer].resetGain)} ${layers[layer].resource}

${(tmp[layer].baseAmount.gte(tmp[layer].nextAt)&&layers[layer].canBuyMax && layers[layer].canBuyMax())?"Next":"Req"}: ${formatWhole(tmp[layer].baseAmount)} / ${(layers[layer].resCeil ? formatWhole(tmp[layer].nextAtDisp) : format(tmp[layer].nextAtDisp))} ${ layers[layer].baseResource }` + }, + getResetGain() { + if ((!layers[layer].canBuyMax()) || tmp[layer].baseAmount.lt(tmp[layer].requires)) return new Decimal(1) + let gain = tmp[layer].baseAmount.div(tmp[layer].requires).div(tmp[layer].gainMult).max(1).log(layers[layer].base).times(tmp[layer].gainExp).pow(Decimal.pow(layers[layer].exponent, -1)) + if (gain.gte(12)) { + gain = gain.times(12).sqrt() + } + if (gain.gte(1225)) gain = gain.times(Decimal.pow(1225, 9)).pow(0.1) + return gain.floor().sub(player[layer].points).add(1).max(1); + }, + getNextAt() { + let amt = player[layer].points + if (amt.gte(1225)) amt = amt.pow(10).div(Decimal.pow(1225, 9)) + if (amt.gte(12)) { + amt = amt.pow(2).div(12) + } + let extraCost = Decimal.pow(layers[layer].base, amt.pow(layers[layer].exponent).div(tmp[layer].gainExp)).times(tmp[layer].gainMult) + let cost = extraCost.times(tmp[layer].requires).max(tmp[layer].requires) + if (layers[layer].resCeil) cost = cost.ceil() + return cost; + }, + canReset() { + return tmp[this.layer].baseAmount.gte(tmp[this.layer].nextAt) + }, + tooltipLocked() { // Optional, tooltip displays when the layer is locked + return ("(Active layer) This layer requires " + this.requires() + " generator power. You only have " + formatWhole(player.g.power)) + }, + incr_order: ["e", "d"], + + // Optional, lets you format the tab yourself by listing components. You can create your own components in v.js. + tabFormat: ["main-display", + ["prestige-button", function() {return "Convert your generator power into "}, {}], + ["display-text", + function() {return 'You have ' + format(player.r.power) + ' replicanti (Limit at '+format(tmp["r"].buyables[13].cost)+'), multiplying generator power gain by '+format(tmp.r.effect.powerBoost)+'.'}, + {"font-size": "14px"}], + "upgrades", "buyables", ["blank", "25px"], "milestones"], + branches: [["g", 1]] + /*style() {return { + 'background-color': '#3325CC' + }},*/ +}) + +addLayer("d", { + startData() { return { + unl: false, + points: new Decimal(0), + best: new Decimal(0), + total: new Decimal(0), + milestones: [], + power: new Decimal(1), + order: 0, + banking: 0 + }}, + color:() => "#328ba8", + background:() => 'https://cdn.glitch.com/7460ed4d-c31b-459d-8407-710f48e787a3%2Fefdb5b70-5e55-4f23-9524-953a8eea4545.image.png?v=1601771864943', + requires() { + let req = new Decimal(1e32) + if (!player[this.layer].upgrades.includes(11)) if (player[this.layer].order > 0) req = req.pow(player[this.layer].order+1) + return req + }, // Can be a function that takes requirement increases into account + resource: "tachyon particles", // Name of prestige currency + baseResource: "prestige points", // Name of resource prestige is based on + baseAmount() {return player.p.points}, // Get the current amount of baseResource + type: "custom", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have + exponent: 0.750, // Prestige currency exponent + base: 500, // Only needed for static layers, base of the formula (b^(x^exp)) + resCeil: false, // True if the cost needs to be rounded up (use when baseResource is static?) + canBuyMax() {return true}, // Only needed for static layers with buy max + effect() { + let base = new Decimal(1.1) + return Decimal.pow(base, player[this.layer].points.pow(0.9)) + }, + effectDescription:() => "multiplying dilated currency gain by "+format(layers[this.layer].effect())+"x", + gainMult() { // Calculate the multiplier for main currency from bonuses + mult = new Decimal(1) + return mult + }, + 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) + milestones: { + 0: { + requirementDesc:() => "1 tachyon particle", + effectDesc:() => "You don't lose prestige upgrades on previous resets and this resets", + done() { + return player[this.layer].best.gte(1); + } + }, + 1: { + requirementDesc:() => "2 tachyon particles", + effectDesc:() => "You keep all booster and generator milestones on reset.", + done() { + return player[this.layer].best.gte(2); + } + }, + 2: { + requirementDesc:() => "4 tachyon particles", + effectDesc:() => "You keep booster and generator upgrades on reset.", + done() { + return player[this.layer].best.gte(4); + } + }, + 3: { + requirementDesc:() => "5 tachyon particles", + effectDesc:() => "Boosters and generators do not reset everything.", + done() { + return player[this.layer].best.gte(5); + } + }, + 4: { + requirementDesc:() => "8 tachyon particles", + effectDesc:() => "Automate boosters and generators.", + done() { + return player[this.layer].best.gte(8); + }, + toggles: [ + ["b", "auto"], + ["g", "auto"] + ] + } + }, + dilationMult() { + let mult = layers[this.layer].effect() + if (player.d.unl) mult = mult.times(layers.d.buyables[21].effect(player.d.buyables[21]).first) + return mult + }, + buyables: { + rows: 2, + cols: 3, + 11: { + title:() => "Dilated Prestige Points", // Optional, displayed at the top in a larger font + cost() { // cost for buying xth buyable, can be an object if there are multiple currencies + return new Decimal(0) + }, + effect() { // Effects of owning x of the items, x is a decimal + let x = player[this.layer].buyables[this.id] + let eff = {} + eff.first = x.add(1).root(2) + return eff; + }, + display() { // Everything else displayed in the buyable button after the title + let data = tmp[this.layer].buyables[this.id] + return data.canAfford + ? "You have " + format(player[this.layer].buyables[this.id], 0) + " dilated prestige points, which are boosting prestige point multiplier by " + format(data.effect.first) + "x.\n\n\ + Dilation is currently " + (player[this.layer].banking == 1 ? "enabled.\n\ + Click here to disable dilation and gain " + format(player.p.points.mul(layers[this.layer].dilationMult()).sub(player.d.buyables[11]).max(0), 0) + " dilated prestige points." : "disabled.\n\ + Click here to enable dilation, which will force a dilation reset and square root all of your point generation speed, prestige point gain, generator effects, booster effects, and disable the second Prestige Upgrade.") + : "You need to obtain at least 2 tachyon particles before you can use this function." + }, + unl() { return player[this.layer].unl }, + canAfford() { + return true}, + buy() { + if (player.d.banking == 1) player.d.buyables[11] = player.d.buyables[11].max(player.p.points.mul(layers[this.layer].dilationMult())) + player.d.banking = player.d.banking == 1 ? 0 : 1 + doReset(this.layer, true) + }, + buyMax() {}, // You'll have to handle this yourself if you want + }, + 12: { + title:() => "Dilated Points", // Optional, displayed at the top in a larger font + cost() { // cost for buying xth buyable, can be an object if there are multiple currencies + return new Decimal(0) + }, + effect() { // Effects of owning x of the items, x is a decimal + let x = player[this.layer].buyables[this.id] + let eff = {} + eff.first = x.add(1) + return eff; + }, + display() { // Everything else displayed in the buyable button after the title + let data = tmp[this.layer].buyables[this.id] + return data.canAfford + ? "You have " + format(player[this.layer].buyables[this.id], 0) + " dilated points, which are boosting point multiplier by " + format(data.effect.first) + "x.\n\n\ + Dilation is currently " + (player[this.layer].banking == 2 ? "enabled.\n\ + Click here to disable dilation and gain " + format(player.points.mul(layers[this.layer].dilationMult()).sub(player.d.buyables[12]).max(0), 0) + " dilated prestige points." : "disabled.\n\ + Click here to enable dilation, which will force a dilation reset and apply logarithm to your point generation.") + : "You need to obtain at least 3 tachyon particles before you can use this function." + }, + unl() { return player[this.layer].unl }, + canAfford() { + return player[this.layer].points.gte(3)}, + buy() { + if (player.d.banking == 2) player.d.buyables[12] = player.d.buyables[12].max(player.points.mul(layers[this.layer].dilationMult())) + player.d.banking = player.d.banking == 2 ? 0 : 2 + doReset(this.layer, true) + }, + buyMax() {}, // You'll have to handle this yourself if you want + }, + 13: { + title:() => "Dilated Generator Power", // Optional, displayed at the top in a larger font + cost() { // cost for buying xth buyable, can be an object if there are multiple currencies + return new Decimal(0) + }, + effect() { // Effects of owning x of the items, x is a decimal + let x = player[this.layer].buyables[this.id] + let eff = {} + eff.first = x.add(1).root(5) + return eff; + }, + display() { // Everything else displayed in the buyable button after the title + let data = tmp[this.layer].buyables[this.id] + return data.canAfford + ? "You have " + format(player[this.layer].buyables[this.id], 0) + " dilated generator power, which are boosting generator power gain by " + format(data.effect.first) + "x.\n\n\ + Dilation is currently " + (player[this.layer].banking == 3 ? "enabled.\n\ + Click here to disable dilation and gain " + format(player.g.power.mul(layers[this.layer].dilationMult()).sub(player.d.buyables[13]).max(0), 0) + " dilated generator power." : "disabled.\n\ + Click here to enable dilation, which will force a dilation reset, lock the generator and booster bases at 2, and double booster and generator cost multiplier.") + : "You need to obtain at least 7 tachyon particles before you can use this function." + }, + unl() { return player[this.layer].unl }, + canAfford() { + return player[this.layer].points.gte(7)}, + buy() { + if (player.d.banking == 3) player.d.buyables[13] = player.d.buyables[13].max(player.g.power.mul(layers[this.layer].dilationMult())) + player.d.banking = player.d.banking == 3 ? 0 : 3 + doReset(this.layer, true) + }, + buyMax() {}, // You'll have to handle this yourself if you want + }, + 21: { + title:() => "Dilation Boost", // Optional, displayed at the top in a larger font + cost() { // cost for buying xth buyable, can be an object if there are multiple currencies + let x = player[this.layer].buyables[this.id] + let cost = Decimal.pow("5000", x.add(1)) + return { + 1: cost.floor(), + 2: cost.sqrt().div(50).floor(), + 3: cost.pow(2).floor() + } + }, + effect() { // Effects of owning x of the items, x is a decimal + let x = player[this.layer].buyables[this.id] + let eff = {} + eff.first = Decimal.pow(4, x) + return eff; + }, + display() { // Everything else displayed in the buyable button after the title + let data = tmp[this.layer].buyables[this.id] + return "Cost: " + format(data.cost[1]) + " dilated prestige points, " + format(data.cost[2]) + " dilated points, " + format(data.cost[3]) + " dilated generator power\n\ + Amount: " + player[this.layer].buyables[this.id] + "\n\ + Multiply all dilation currency gain by " + format(data.effect.first) + "x" + }, + unl() { return player[this.layer].unl }, + canAfford() { + return (player[this.layer].buyables[11].gte(tmp[this.layer].buyables[this.id].cost[1]) && player[this.layer].buyables[12].gte(tmp[this.layer].buyables[this.id].cost[2]) && player[this.layer].buyables[13].gte(tmp[this.layer].buyables[this.id].cost[3])) + }, + buy() { + cost = tmp[this.layer].buyables[this.id].cost + player[this.layer].buyables[11] = player[this.layer].buyables[11].sub(cost[1]) + player[this.layer].buyables[12] = player[this.layer].buyables[12].sub(cost[2]) + player[this.layer].buyables[13] = player[this.layer].buyables[13].sub(cost[3]) + player[this.layer].buyables[this.id] = player[this.layer].buyables[this.id].add(1) + }, + buyMax() {}, // You'll have to handle this yourself if you want + }, + 22: { + title:() => "shh", // Optional, displayed at the top in a larger font + cost() { // cost for buying xth buyable, can be an object if there are multiple currencies + let x = player[this.layer].buyables[this.id] + + let cost = Decimal.pow("5000", x.add(1)) + return cost.floor() + }, + effect() { // Effects of owning x of the items, x is a decimal + let x = player[this.layer].buyables[this.id] + let eff = {} + eff.first = x + return eff; + }, + display() { // Everything else displayed in the buyable button after the title + let data = tmp[this.layer].buyables[this.id] + return "Why are you here" + }, + unl() { return false }, + canAfford() { + return player[this.layer].buyables[11].gte(tmp[this.layer].buyables[this.id].cost)}, + buy() { + cost = tmp[this.layer].buyables[this.id].cost + player[this.layer].buyables[11] = player[this.layer].buyables[11].sub(cost) + player[this.layer].buyables[this.id] = player[this.layer].buyables[this.id].add(1) + }, + buyMax() {}, // You'll have to handle this yourself if you want + }, + 23: { + title:() => "shh", // Optional, displayed at the top in a larger font + cost() { // cost for buying xth buyable, can be an object if there are multiple currencies + let x = player[this.layer].buyables[this.id] + + let cost = Decimal.pow("5000", x.add(1)) + return cost.floor() + }, + effect() { // Effects of owning x of the items, x is a decimal + let x = player[this.layer].buyables[this.id] + let eff = {} + eff.first = x + return eff; + }, + display() { // Everything else displayed in the buyable button after the title + let data = tmp[this.layer].buyables[this.id] + return "Why are you here" + }, + unl() { return false }, + canAfford() { + return player[this.layer].buyables[11].gte(tmp[this.layer].buyables[this.id].cost)}, + buy() { + cost = tmp[this.layer].buyables[this.id].cost + player[this.layer].buyables[11] = player[this.layer].buyables[11].sub(cost) + player[this.layer].buyables[this.id] = player[this.layer].buyables[this.id].add(1) + }, + buyMax() {}, // You'll have to handle this yourself if you want + }, + }, + upgrades: { + rows: 1, + cols: 1, + 11: { + desc:() => "This layer no longer uses order.", + cost:() => new Decimal(15), + unl() { return player[this.layer].order > 0 }, // The upgrade is only visible when this is true + }, + }, + doReset(resettingLayer){ // Triggers when this layer is being reset, along with the layer doing the resetting. Not triggered by lower layers resetting, but is by layers on the same row. + if(layers[resettingLayer].row > this.row-1) player.r.power = new Decimal(1) + }, + layerShown() {return player.b.unl}, // Condition for when layer appears on the tree + automate() { + }, // Do any automation inherent to this layer if appropriate + updateTemp() { + }, // Do any necessary temp updating, not that important usually + resetsNothing() {return false}, + onPrestige(gain) { + return + }, // Useful for if you gain secondary resources or have other interesting things happen to this layer when you reset it. You gain the currency after this function ends. + update(diff) { + }, + hotkeys: [ + {key: "d", desc: "D: Reset prestige points for tachyon particles.", onPress(){if (player[this.layer].unl) doReset(this.layer)}}, + ], + prestigeButtonText() { //Is secretly HTML + return `Convert your prestige points into +${formatWhole(tmp[layer].resetGain)} ${layers[layer].resource}

${(tmp[layer].baseAmount.gte(tmp[layer].nextAt)&&layers[layer].canBuyMax && layers[layer].canBuyMax())?"Next":"Req"}: ${formatWhole(tmp[layer].baseAmount)} / ${(layers[layer].resCeil ? formatWhole(tmp[layer].nextAtDisp) : format(tmp[layer].nextAtDisp))} ${ layers[layer].baseResource }` + }, + getResetGain() { + if ((!layers[layer].canBuyMax()) || tmp[layer].baseAmount.lt(tmp[layer].requires)) return new Decimal(1) + let gain = tmp[layer].baseAmount.div(tmp[layer].requires).div(tmp[layer].gainMult).max(1).log(layers[layer].base).times(tmp[layer].gainExp).pow(Decimal.pow(layers[layer].exponent, -1)) + if (gain.gte(12)) { + gain = gain.times(12).sqrt() + } + if (gain.gte(1225)) gain = gain.times(Decimal.pow(1225, 9)).pow(0.1) + return gain.floor().sub(player[layer].points).add(1).max(1); + }, + getNextAt() { + let amt = player[layer].points + if (amt.gte(1225)) amt = amt.pow(10).div(Decimal.pow(1225, 9)) + if (amt.gte(12)) { + amt = amt.pow(2).div(12) + } + let extraCost = Decimal.pow(layers[layer].base, amt.pow(layers[layer].exponent).div(tmp[layer].gainExp)).times(tmp[layer].gainMult) + let cost = extraCost.times(tmp[layer].requires).max(tmp[layer].requires) + if (layers[layer].resCeil) cost = cost.ceil() + return cost; + }, + canReset() { + return tmp[this.layer].baseAmount.gte(tmp[this.layer].nextAt) + }, + tooltipLocked() { // Optional, tooltip displays when the layer is locked + return ("(Idle layer) This layer requires " + this.requires() + " prestige points. You only have " + formatWhole(player.p.points)) + }, + incr_order: ["r", "e"], + + // Optional, lets you format the tab yourself by listing components. You can create your own components in v.js. + tabFormat: ["main-display", + ["prestige-button", function() {return "Convert your prestige points into "}, {}], + "upgrades", "buyables", ["blank", "25px"], "milestones"], + branches: [["b", 1]] + /*style() {return { + 'background-color': '#3325CC' + }},*/ +}) + +addLayer("pr", { + startData() { return { + unl: false, + points: new Decimal(0), + best: new Decimal(0), + total: new Decimal(0), + milestones: [], + power: new Decimal(1), + order: 0 + }}, + color:() => "#e8d684", + background:() => 'https://cdn.glitch.com/7460ed4d-c31b-459d-8407-710f48e787a3%2Fefdb5b70-5e55-4f23-9524-953a8eea4545.image.png?v=1601771864943', + requires() { + let req = new Decimal(68) + return req + }, // Can be a function that takes requirement increases into account + resource: "ascension power", // Name of prestige currency + baseResource: "boosters", // Name of resource prestige is based on + baseAmount() {return player.b.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: 0.850, // Prestige currency exponent + base: 1.03, // Only needed for static layers, base of the formula (b^(x^exp)) + resCeil: true, // True if the cost needs to be rounded up (use when baseResource is static?) + canBuyMax() {return true}, // Only needed for static layers with buy max + gainMult() { // Calculate the multiplier for main currency from bonuses + mult = new Decimal(1) + return mult + }, + 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) + effect() { + let base = new Decimal(1.03) + return Decimal.pow(base, player[this.layer].points.sub(8).max(0).sqrt()) + }, + effectDescription:() => "increasing the perk power by "+format(layers[this.layer].effect().sub(1).mul(100))+"%", + maxActivePerks() { + let number = 1; + if (player.s.challs.includes(11)) number += 1 + return number + }, + activePerks() { + let number = 0; + for (var i in player[this.layer].buyables) { + if (player[this.layer].buyables[i].gt(0)) number += 1 + } + return number + }, + perkPower() { + let power = layers[this.layer].effect() + return power + }, + buyables: { + rows: 1, + cols: 4, + 11: { + title:() => "Cost Perk", // Optional, displayed at the top in a larger font + cost(x) { // cost for buying xth buyable, can be an object if there are multiple currencies + let multiplier = new Decimal(30) + return multiplier + }, + effect(x) { // Effects of owning x of the items, x is a decimal + let eff = {} + eff.first = new Decimal(1e7) + eff.first = eff.first.pow(layers[this.layer].perkPower()) + return eff; + }, + display() { // Everything else displayed in the buyable button after the title + let data = tmp[this.layer].buyables[this.id] + let activeThing = (player[this.layer].buyables[this.id].gt(1) ? "Active for "+format(player[this.layer].buyables[this.id], 0)+" seconds" : "Not Active") + + "\n\ + Divide booster and generator costs by /" + format(data.effect.first) + return activeThing + }, + unl() { return player[this.layer].unl }, + canAfford() { + return (layers[this.layer].activePerks() < layers[this.layer].maxActivePerks()) }, + buy() { + if (player[this.layer].buyables[this.id].gt(0)) return; + player[this.layer].buyables[this.id] = layers[this.layer].buyables[this.id].cost() + }, + }, + 12: { + title:() => "Base Perk", // Optional, displayed at the top in a larger font + cost(x) { // cost for buying xth buyable, can be an object if there are multiple currencies + let multiplier = new Decimal(30) + return multiplier + }, + effect(x) { // Effects of owning x of the items, x is a decimal + let eff = {} + eff.first = new Decimal(2) + eff.first = eff.first.pow(layers[this.layer].perkPower()) + return eff; + }, + display() { // Everything else displayed in the buyable button after the title + let data = tmp[this.layer].buyables[this.id] + let activeThing = (player[this.layer].buyables[this.id].gt(1) ? "Active for "+format(player[this.layer].buyables[this.id], 0)+" seconds" : "Not Active") + + "\n\ + Add +" + format(data.effect.first) + " to the generator and booster bases" + return activeThing + }, + unl() { return player[this.layer].unl }, + canAfford() { + return (layers[this.layer].activePerks() < layers[this.layer].maxActivePerks()) }, + buy() { + if (player[this.layer].buyables[this.id].gt(0)) return; + player[this.layer].buyables[this.id] = layers[this.layer].buyables[this.id].cost() + }, + }, + 13: { + title:() => "Multiplier Perk", // Optional, displayed at the top in a larger font + cost(x) { // cost for buying xth buyable, can be an object if there are multiple currencies + let multiplier = new Decimal(30) + return multiplier + }, + effect(x) { // Effects of owning x of the items, x is a decimal + let eff = {} + eff.first = new Decimal(1e15) + eff.first = eff.first.pow(layers[this.layer].perkPower()) + return eff; + }, + display() { // Everything else displayed in the buyable button after the title + let data = tmp[this.layer].buyables[this.id] + let activeThing = (player[this.layer].buyables[this.id].gt(1) ? "Active for "+format(player[this.layer].buyables[this.id], 0)+" seconds" : "Not Active") + + "\n\ + Multiply prestige point and prestige point gain by x" + format(data.effect.first, 1) + return activeThing + }, + unl() { return player[this.layer].unl }, + canAfford() { + return (layers[this.layer].activePerks() < layers[this.layer].maxActivePerks()) }, + buy() { + if (player[this.layer].buyables[this.id].gt(0)) return; + player[this.layer].buyables[this.id] = layers[this.layer].buyables[this.id].cost() + }, + }, + 14: { + title:() => "Bonus Perk", // Optional, displayed at the top in a larger font + cost(x) { // cost for buying xth buyable, can be an object if there are multiple currencies + let multiplier = new Decimal(30) + return multiplier + }, + effect(x) { // Effects of owning x of the items, x is a decimal + let eff = {} + eff.first = new Decimal(5) + eff.first = eff.first.pow(layers[this.layer].perkPower()) + return eff; + }, + display() { // Everything else displayed in the buyable button after the title + let data = tmp[this.layer].buyables[this.id] + let activeThing = (player[this.layer].buyables[this.id].gt(1) ? "Active for "+format(player[this.layer].buyables[this.id], 0)+" seconds" : "Not Active") + + "\n\ + Add +" + format(data.effect.first, 1) + " free boosters and generators" + return activeThing + }, + unl() { return player.s.challs.includes(12) }, + canAfford() { + return (layers[this.layer].activePerks() < layers[this.layer].maxActivePerks()) }, + buy() { + if (player[this.layer].buyables[this.id].gt(0)) return; + player[this.layer].buyables[this.id] = layers[this.layer].buyables[this.id].cost() + }, + }, + }, + layerShown() {return player.d.unl && player.e.unl && player.r.unl}, // Condition for when layer appears on the tree + automate() { + }, // Do any automation inherent to this layer if appropriate + updateTemp() { + }, // Do any necessary temp updating, not that important usually + resetsNothing() {return true}, + onPrestige(gain) { + return + }, // Useful for if you gain secondary resources or have other interesting things happen to this layer when you reset it. You gain the currency after this function ends. + update(diff) { + for (var i in player[this.layer].buyables) { + player[this.layer].buyables[i] = player[this.layer].buyables[i].sub(diff).max(0) + } + }, + hotkeys: [ + {key: "P", desc: "Shift+P: Reset boosters for ascension power.", onPress(){if (player[this.layer].unl) doReset(this.layer)}}, + ], + incr_order: ["s"], + + // Optional, lets you format the tab yourself by listing components. You can create your own components in v.js. + tabFormat: ["main-display", + ["prestige-button", function() {return "Convert your points into "}, {}], + ["display-text", + function() {return '(Perk Power: '+format((layers.pr.perkPower()?layers.pr.perkPower():new Decimal(1)).mul(100))+'%)'}, + {"font-size": "16px", "color": "orange"}], + "buyables", ["blank", "25px"], "milestones"], + branches: [["b", 1]] + /*style() {return { + 'background-color': '#3325CC' + }},*/ +}) + +addLayer("s", { + startData() { return { + unl: false, + points: new Decimal(0), + best: new Decimal(0), + total: new Decimal(0), + milestones: [], + order: 0 + }}, + color:() => "#fab4d9", + background:() => 'https://cdn.glitch.com/7460ed4d-c31b-459d-8407-710f48e787a3%2Fefdb5b70-5e55-4f23-9524-953a8eea4545.image.png?v=1601771864943', + requires() { + let req = new Decimal(67) + return req + }, // Can be a function that takes requirement increases into account + resource: "stadium power", // Name of prestige currency + baseResource: "generators", // Name of resource prestige is based on + baseAmount() {return player.g.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: 0.850, // Prestige currency exponent + base: 1.03, // Only needed for static layers, base of the formula (b^(x^exp)) + resCeil: true, // True if the cost needs to be rounded up (use when baseResource is static?) + canBuyMax() {return true}, // Only needed for static layers with buy max + gainMult() { // Calculate the multiplier for main currency from bonuses + mult = new Decimal(1) + return mult + }, + gainExp() { // Calculate the exponent on main currency from bonuses + return new Decimal(1) + }, + effect() { + let base = new Decimal(1.02) + return Decimal.pow(base, player[this.layer].points.sub(8).max(0).add(1.25).log10()) + }, + effectDescription:() => "increasing the second prestige upgrade power by "+format(layers[this.layer].effect().sub(1).mul(100))+"%", + row: 2, // Row the layer is in on the tree (0 is the first row) + doReset(resettingLayer){ // Triggers when this layer is being reset, along with the layer doing the resetting. Not triggered by lower layers resetting, but is by layers on the same row. + if(layers[resettingLayer].row > this.row-1) player.r.power = new Decimal(1) + }, + layerShown() {return player.d.unl && player.e.unl && player.r.unl}, // Condition for when layer appears on the tree + automate() { + }, // Do any automation inherent to this layer if appropriate + updateTemp() { + }, // Do any necessary temp updating, not that important usually + challengeUnlocks: ["1.80e308", "1e340", "1e370", "1e800"], + getChallengeUnlock() { + let number = 0 + for (var i in layers[this.layer].challs) { + if (layers[this.layer].challs[i].unl) if (layers[this.layer].challs[i].unl()) number += 1 + } + return number + }, + challs: { + rows: 2, + cols: 2, + 11: { + name:() => "Spaceon", + desc:() => "Prestige point gain is raised to the 10th root.", + unl() { return player.points.gt(layers[this.layer].challengeUnlocks[0]) || player[this.layer].challs.includes(11) || player[this.layer].active == 11 }, + goal:() => new Decimal("10000"), + currencyDisplayName: "prestige points", // Use if using a nonstandard currency + currencyInternalName: "points", // Use if using a nonstandard currency + currencyLayer: "p", // Leave empty if not in a layer + reward:() => "You can have two perks active at once.", + }, + 12: { + name:() => "Infinity", + desc:() => "Booster and generators are 90% weaker.", + unl() { return player.points.gt(layers[this.layer].challengeUnlocks[1]) || player[this.layer].challs.includes(12) || player[this.layer].active == 12 }, + goal:() => new Decimal("1e137"), + currencyDisplayName: "prestige points", // Use if using a nonstandard currency + currencyInternalName: "points", // Use if using a nonstandard currency + currencyLayer: "p", // Leave empty if not in a layer + reward:() => "Unlock a new perk, and generator and booster cost is divided by stadium and ascension power.", + effect() { + let ret = player[this.layer].points.add(player.pr.points).mul(100).pow(3).add(1) + return ret; + }, + effectDisplay(x) { return "/"+format(x) }, + }, + 21: { + name:() => "Eternity", + desc:() => "Time speed is reduced based on your points. (Hold P for more prestige gain)", + unl() { return player.points.gt(layers[this.layer].challengeUnlocks[2]) || player[this.layer].challs.includes(21) || player[this.layer].active == 21 }, + goal:() => new Decimal("1e147"), + currencyDisplayName: "prestige points", // Use if using a nonstandard currency + currencyInternalName: "points", // Use if using a nonstandard currency + currencyLayer: "p", // Leave empty if not in a layer + reward:() => "Generators and boosters multiply prestige point gain.", + effect() { + let ret = player.g.points.add(player.b.points).mul(1e5).pow(2).add(1) + return ret; + }, + effectDisplay(x) { return format(x)+"x" }, + }, + 22: { + name:() => "???", + desc:() => "Time speed is reduced based on your points.", + unl() { return player.points.gt(layers[this.layer].challengeUnlocks[3]) || player[this.layer].challs.includes(22) || player[this.layer].active == 22 }, + goal:() => new Decimal("1e50"), + currencyDisplayName: "prestige points", // Use if using a nonstandard currency + currencyInternalName: "points", // Use if using a nonstandard currency + currencyLayer: "p", // Leave empty if not in a layer + reward:() => "Generators and boosters multiply prestige point gain.", + effect() { + let ret = player.g.points.add(player.b.points).mul(1e5).pow(2).add(1) + return ret; + }, + effectDisplay(x) { return format(x)+"x" }, + }, + }, + resetsNothing() {return true}, + onPrestige(gain) { + return + }, // Useful for if you gain secondary resources or have other interesting things happen to this layer when you reset it. You gain the currency after this function ends. + update(diff) { + }, + onReset() { + if (player[this.layer].active) doReset("d", true) + }, + hotkeys: [ + {key: "s", desc: "S: Reset generators for stadium power.", onPress(){if (player[this.layer].unl) doReset(this.layer)}}, + ], + + // Optional, lets you format the tab yourself by listing components. You can create your own components in v.js. + tabFormat: ["main-display", + ["prestige-button", function() {return "Convert your points into "}, {}], + ["display-text", + function() {return 'Next stadium challenge at '+format(layers["s"].challengeUnlocks[layers["s"].getChallengeUnlock()])+" points."}, + {"font-size": "14px"}], "blank", "blank", + ["display-text", + function() {return '(Note: Perks do not work in stadium challenges)'}, + {"font-size": "10px"}], + "challs"], + branches: [["g", 1]] + /*style() {return { + 'background-color': '#3325CC' + }},*/ +}) \ No newline at end of file diff --git a/js/v.js b/js/v.js index 09e8191..3870889 100644 --- a/js/v.js +++ b/js/v.js @@ -5,17 +5,10 @@ function loadVue() { Vue.component('display-text', { props: ['layer', 'data'], template: ` - + ` }) - // data = a function returning html content, with some limited functionality - Vue.component('raw-html', { - props: ['layer', 'data'], - template: ` - - ` - }) // Blank space, data = optional height in px or pair with width and height in px Vue.component('blank', { @@ -33,7 +26,7 @@ function loadVue() { Vue.component('display-image', { props: ['layer', 'data'], template: ` - + ` }) @@ -45,8 +38,8 @@ function loadVue() {
-
-
+
+
@@ -60,9 +53,9 @@ function loadVue() {
-
-
-
+
+
+
From 61788c6bddcd4e4754ee705a40671e3e2ca4fbe9 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Sun, 11 Oct 2020 15:09:30 -0400 Subject: [PATCH 10/33] Updated buyable documentation and added buyablesOwned --- changelog.md | 3 ++- docs/buyables.md | 6 ++++-- js/game.js | 8 ++++++++ js/v.js | 4 ++-- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/changelog.md b/changelog.md index 39aa6e9..a0434f5 100644 --- a/changelog.md +++ b/changelog.md @@ -6,7 +6,8 @@ Tmp does not need to be manually updated. Almost every value in layer data can be a function or a constant value! You don't have to have the same amount of upgrades in every row (and challs and buyables) Unl is optional for all Big Components (defaults to true). -effectDisplay in Challenges and Upgrades no longer takes an argument +effectDisplay in Challenges and Upgrades no longer takes an argument, as well as buyable effect. +Buyable cost can take an argument for amount of buyables, but if one is not supplied it should do the cost of the next buyable. ##v1.3.5 - Completely automated convertToDecimal, now you never have to worry about it again. diff --git a/docs/buyables.md b/docs/buyables.md index 95e84bd..0f7d137 100644 --- a/docs/buyables.md +++ b/docs/buyables.md @@ -5,6 +5,7 @@ the player can reset the purchases to get their currency back. However, if you're creative, you can use them for basically anything. "canAfford()" is effectively "canClick()" and "buy()" is effectively "onClick()". +The amount of a buyable owned is a Decimal, and can be accessed with buyablesOwned(layer, id). You can use buyableEffect(layer, id) to get the current effects of a buyable. Buyables should be formatted like this: @@ -29,10 +30,11 @@ Features: - title: **optional**, displayed at the top in a larger font It can also be a function that returns updating text. -- cost(): cost for buying xth buyable, can be an object if there are multiple currencies +- cost(): cost for buying the next buyable. Can have an optional argument "x" to calculate the cost of the x+1th object, + but needs to use "current amount" as a default value for x. Can return an object if there are multiple currencies. - effect(): **optional**, A function that calculates and returns the current values of bonuses - for having x of this buyable. Can return a value or an object containing multiple values. + of this buyable. Can return a value or an object containing multiple values. - display(): A function returning everything that should be displayed on the rebuyable after the title, likely including the description, amount bought, cost, and current effect. Can use basic HTML. diff --git a/js/game.js b/js/game.js index 72f6ae4..0edaabb 100644 --- a/js/game.js +++ b/js/game.js @@ -252,6 +252,14 @@ function hasChall(layer, id){ return (player[layer].challs.includes(toNumber(id)) || player[layer].challs.includes(id.toString())) } +function buyablesOwned(layer, id){ + return (player[layer].buyables[id]) +} + +function clickableState(layer, id){ + return (player[layer].clickables[id]) +} + function upgEffect(layer, id){ return (tmp[layer].upgrades[id].effect) } diff --git a/js/v.js b/js/v.js index 3870889..a3e2d8a 100644 --- a/js/v.js +++ b/js/v.js @@ -140,9 +140,9 @@ function loadVue() { template: `
- +
-
+

From dee1f932987eff0b3596fdf1de41660a685f78a2 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Sun, 11 Oct 2020 16:16:36 -0400 Subject: [PATCH 11/33] Added Clickables --- docs/!general-info.md | 4 +- docs/buyables.md | 7 +- docs/clickables.md | 51 ++++++++++++++ docs/custom-tab-layouts.md | 4 +- index.html | 5 +- js/game.js | 122 ++++------------------------------ js/gametest.js | 8 +++ js/layerSupport.js | 12 ++++ js/layers.js | 63 +++++++++++++++++- js/temp.js | 7 +- js/utils.js | 132 +++++++++++++++++++++++++++++++++++++ js/v.js | 33 ++++++++++ 12 files changed, 326 insertions(+), 122 deletions(-) create mode 100644 docs/clickables.md diff --git a/docs/!general-info.md b/docs/!general-info.md index 7e7a9f2..ed7fe30 100644 --- a/docs/!general-info.md +++ b/docs/!general-info.md @@ -25,7 +25,9 @@ plain number, and perform operations on them by calling functions. e.g, instead - [Milestones](milestones.md): How to create milestones for a layer. - [Challenges](challenges.md): How to create challenges for a layer. - [Buyables](buyables.md): Create rebuyable upgrades for your layer (with the option to make them respec-able). - Can be used to make Enhancers or Space Buildings, but they're flexible enough to do anything. + Can be used to make Enhancers or Space Buildings. +- [Clickables](clickables.md): A more generalized variant of buyables, for any kind of thing that is sometimes clickable. + Between these and Buyables, you can do just about anything. - [Custom Tab Layouts](custom-tab-layouts.md): An optional way to give your tabs a different layout. You can even create entirely new components to use. - [Subtabs and Microtabs](subtabs-and-microtabs.md): Create subtabs for your tabs, as well as "microtab" components that you can put inside the tabs. diff --git a/docs/buyables.md b/docs/buyables.md index 0f7d137..098bb01 100644 --- a/docs/buyables.md +++ b/docs/buyables.md @@ -3,9 +3,8 @@ Buyables are usually things that can be bought multiple times with scaling costs. If you set a respec function, the player can reset the purchases to get their currency back. -However, if you're creative, you can use them for basically anything. "canAfford()" is effectively "canClick()" and "buy()" is effectively "onClick()". - -The amount of a buyable owned is a Decimal, and can be accessed with buyablesOwned(layer, id). +The amount of a buyable owned is a Decimal. +You can get or set the amount of a buyable with getBuyableAmt(layer, id) and setBuyableAmt(layer, id, amt). You can use buyableEffect(layer, id) to get the current effects of a buyable. Buyables should be formatted like this: @@ -36,7 +35,7 @@ Features: - effect(): **optional**, A function that calculates and returns the current values of bonuses of this buyable. Can return a value or an object containing multiple values. -- display(): A function returning everything that should be displayed on the rebuyable after the title, likely +- display(): A function returning everything that should be displayed on the buyable after the title, likely including the description, amount bought, cost, and current effect. Can use basic HTML. - unl(): A function returning a bool to determine if the buyable is visible or not. diff --git a/docs/clickables.md b/docs/clickables.md new file mode 100644 index 0000000..0730ab2 --- /dev/null +++ b/docs/clickables.md @@ -0,0 +1,51 @@ +# Clickables + +Clickables are any kind of thing that you can click for an effect. They're a more generalized version of Buyables. + +There are several differences between the two. One is that a buyable's saved data is its amount as a Decimal, while +Clickables store a "state" which can be a number or string, but not Decimal, array, or object). +Buyables have a number of extra features which you can see on their page. +Clickables also have a smaller default size. + +You can get and set a clickable's state with getClickableState(layer, id) and setClickableState(layer, id, state). +You can use clickableEffect(layer, id) to get the current effects of a clickable. + +Clickables should be formatted like this: + +```js + clickables: { + rows: # of rows + cols: # of columns + masterButtonPress() // **optional** If this is present, an additional button will appear above the clickables. + // pressing it will call the function. + masterButtonText: "Press me!" // **optional** text to display on the Master Button + 11: { + desc:() => "Blah", + etc + } + etc + } +``` + +Features: + +- title: **optional**, displayed at the top in a larger font + It can also be a function that returns updating text. + +- effect(): **optional**, A function that calculates and returns the current values of bonuses + of this clickable. Can return a value or an object containing multiple values. + +- display(): A function returning everything that should be displayed on the clickable after the title, likely + changing based on its state. Can use basic HTML. + +- unl(): A function returning a bool to determine if the clickable is visible or not. + +- canClick(): A function returning a bool to determine if you can click the clickable. + +- onClick(): A function that implements clicking one of the clickable. + +- style: **Optional**, A CSS object, which affects this clickable. + +- 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 clickable. \ No newline at end of file diff --git a/docs/custom-tab-layouts.md b/docs/custom-tab-layouts.md index f507911..d89e734 100644 --- a/docs/custom-tab-layouts.md +++ b/docs/custom-tab-layouts.md @@ -35,8 +35,8 @@ These are the existing components, but you can create more in v.js: - upgrades, milestones, challs: Display the upgrades, milestones, and challenges for a layer, as appropriate. -- buyables: Display all of the buyables for this layer, as appropriate. The argument optional, and is the size of the - boxes in pixels. +- buyables, clickables: Display all of the buyables/clickables for this layer, as appropriate. The argument optional, + and is the size of the boxes in pixels. - microtabs: Display a set of subtabs for an area. The argument is the name of the set of microtabs in the "microtabs" feature. diff --git a/index.html b/index.html index 65f0174..6175dad 100644 --- a/index.html +++ b/index.html @@ -6,9 +6,9 @@ - + - + @@ -139,6 +139,7 @@
+ diff --git a/js/game.js b/js/game.js index 0edaabb..a1e2439 100644 --- a/js/game.js +++ b/js/game.js @@ -27,7 +27,7 @@ function showPointGen(){ // Calculate points/sec! function getPointGen() { - if(!hasUpg("p", 11)) + if(!hasUpg("c", 11)) return new Decimal(0) let gain = new Decimal(1) @@ -164,6 +164,16 @@ function getStartBuyables(layer){ return data } +function getStartClickables(layer){ + let data = {} + if (layers[layer].buyables) { + for (id in layers[layer].buyables) + if (!isNaN(id)) + data[id] = "" + } + return data +} + function addPoints(layer, gain) { player[layer].points = player[layer].points.add(gain).max(0) if (player[layer].best) player[layer].best = player[layer].best.max(player[layer].points) @@ -226,116 +236,6 @@ function doReset(layer, force=false) { updateTemp() } -function respecBuyables(layer) { - if (!layers[layer].buyables) return - if (!layers[layer].buyables.respec) return - if (!confirm("Are you sure you want to respec? This will force you to do a \"" + (layers[layer].name ? layers[layer].name : layer) + "\" reset as well!")) return - layers[layer].buyables.respec() - updateBuyableTemp(layer) -} - -function canAffordUpg(layer, id) { - let upg = layers[layer].upgrades[id] - let cost = tmp[layer].upgrades[id].cost - return canAffordPurchase(layer, upg, cost) -} - -function hasUpg(layer, id){ - return (player[layer].upgrades.includes(toNumber(id)) || player[layer].upgrades.includes(id.toString())) -} - -function hasMilestone(layer, id){ - return (player[layer].milestones.includes(toNumber(id)) || player[layer].milestones.includes(id.toString())) -} - -function hasChall(layer, id){ - return (player[layer].challs.includes(toNumber(id)) || player[layer].challs.includes(id.toString())) -} - -function buyablesOwned(layer, id){ - return (player[layer].buyables[id]) -} - -function clickableState(layer, id){ - return (player[layer].clickables[id]) -} - -function upgEffect(layer, id){ - return (tmp[layer].upgrades[id].effect) -} - -function challEffect(layer, id){ - return (tmp[layer].challs[id].effect) -} - -function buyableEffect(layer, id){ - return (tmp[layer].buyables[id].effect) -} - - -function canAffordPurchase(layer, thing, cost) { - if (thing.currencyInternalName){ - let name = thing.currencyInternalName - if (thing.currencyLayer){ - let lr = thing.currencyLayer - return !(player[lr][name].lt(cost)) - } - else { - return !(player[name].lt(cost)) - } - } - else { - return !(player[layer].points.lt(cost)) - } -} - -function buyUpg(layer, id) { - if (!player[layer].unl) return - if (!layers[layer].upgrades[id].unl()) return - if (player[layer].upgrades.includes(id)) return - let upg = layers[layer].upgrades[id] - let cost = tmp[layer].upgrades[id].cost - - if (upg.currencyInternalName){ - let name = upg.currencyInternalName - if (upg.currencyLayer){ - let lr = upg.currencyLayer - if (player[lr][name].lt(cost)) return - player[lr][name] = player[lr][name].sub(cost) - } - else { - if (player[name].lt(cost)) return - player[name] = player[name].sub(cost) - } - } - else { - if (player[layer].points.lt(cost)) return - player[layer].points = player[layer].points.sub(cost) - } - player[layer].upgrades.push(id); - if (upg.onPurchase != undefined) - upg.onPurchase() -} - -function buyMaxBuyable(layer, id) { - if (!player[layer].unl) return - if (!tmp[layer].buyables[id].unl) return - if (!tmp[layer].buyables[id].canAfford) return - if (!layers[layer].buyables[id].buyMax) return - - layers[layer].buyables[id].buyMax() - updateBuyableTemp(layer) -} - -function buyBuyable(layer, id) { - if (!player[layer].unl) return - if (!tmp[layer].buyables[id].unl) return - if (!tmp[layer].buyables[id].canAfford) return - - layers[layer].buyables[id].buy() - updateBuyableTemp(layer) -} - function resetRow(row) { if (prompt('Are you sure you want to reset this row? It is highly recommended that you wait until the end of your current run before doing this! Type "I WANT TO RESET THIS" to confirm')!="I WANT TO RESET THIS") return let pre_layers = ROW_LAYERS[row-1] diff --git a/js/gametest.js b/js/gametest.js index b556c8d..34f394e 100644 --- a/js/gametest.js +++ b/js/gametest.js @@ -266,6 +266,14 @@ function hasChall(layer, id){ return (player[layer].challs.includes(toNumber(id)) || player[layer].challs.includes(id.toString())) } +function buyablesOwned(layer, id){ + return (player[layer].buyables[id]) +} + +function clickableState(layer, id){ + return (player[layer].clickables[id]) +} + function upgEffect(layer, id){ if (!layers[layer].upgrades) return {} diff --git a/js/layerSupport.js b/js/layerSupport.js index 6cdd47f..ff463bc 100644 --- a/js/layerSupport.js +++ b/js/layerSupport.js @@ -73,6 +73,18 @@ function updateLayers(){ } } + if (layers[layer].clickables){ + layers[layer].clickables.layer = layer + for (thing in layers[layer].clickables){ + if (!isNaN(thing)){ + layers[layer].clickables[thing].id = thing + layers[layer].clickables[thing].layer = layer + if (layers[layer].clickables[thing].unl === undefined) + layers[layer].clickables[thing].unl = true + } + } + } + if(!layers[layer].componentStyles) layers[layer].componentStyles = {} if(layers[layer].symbol === undefined) layers[layer].symbol = layer.charAt(0).toUpperCase() + layer.slice(1) diff --git a/js/layers.js b/js/layers.js index 1f3080b..448b44f 100644 --- a/js/layers.js +++ b/js/layers.js @@ -295,12 +295,13 @@ addLayer("c", { resetDesc: "Melt your points into ", }) -// This layer is mostly minimal but it uses a custom prestige type +// This layer is mostly minimal but it uses a custom prestige type and a clickable addLayer("f", { startData() { return { unl: false, points: new Decimal(0), boop: false, + clickables: {[11]: "Start"} // Optional default Clickable state }}, color:() => "#FE0102", requires() {return new Decimal(10)}, @@ -345,6 +346,66 @@ addLayer("f", { canReset() { return tmp[this.layer].baseAmount.gte(tmp[this.layer].nextAt) }, + + // This is also non minimal, a Clickable! + clickables: { + rows: 1, + cols: 1, + masterButtonPress() { // Optional, reset things and give back your currency. Having this function makes a respec button appear + if (getClickableState(this.layer, 11) == "Borkened...") + player[this.layer].clickables[11] = "Start" + }, + masterButtonText() {return (getClickableState(this.layer, 11) == "Borkened...") ? "Fix the clickable!" : "Does nothing"}, // Text on Respec button, optional + 11: { + title:() => "Clicky clicky!", // Optional, displayed at the top in a larger font + display() { // Everything else displayed in the buyable button after the title + let data = getClickableState(this.layer, this.id) + return "Current state:
" + data + }, + unl() { return player[this.layer].unl }, + canClick() { + return getClickableState(this.layer, this.id) !== "Borkened..."}, + onClick() { + switch(getClickableState(this.layer, this.id)){ + case "Start": + player[this.layer].clickables[this.id] = "A new state!" + break; + case "A new state!": + player[this.layer].clickables[this.id] = "Keep going!" + break; + case "Keep going!": + player[this.layer].clickables[this.id] = "Maybe that's a bit too far..." + break; + case "Maybe that's a bit too far...": + player[this.layer].clickables[this.id] = "Borkened..." + break; + default: + player[this.layer].clickables[this.id] = "Start" + break; + + } + }, + style() { + switch(getClickableState(this.layer, this.id)){ + case "Start": + return {'background-color': 'green'} + break; + case "A new state!": + return {'background-color': 'yellow'} + break; + case "Keep going!": + return {'background-color': 'orange'} + break; + case "Maybe that's a bit too far...": + return {'background-color': 'red'} + break; + default: + return {} + break; + }}, + }, + }, + }, ) diff --git a/js/temp.js b/js/temp.js index 8e50fe4..a2d0c13 100644 --- a/js/temp.js +++ b/js/temp.js @@ -3,7 +3,7 @@ var tmp = {} // Tmp will not call these var activeFunctions = [ "startData", "onPrestige", "doReset", "update", "automate", - "buy", "buyMax", "respec", "onComplete", "onPurchase", "onPress" + "buy", "buyMax", "respec", "onComplete", "onPurchase", "onPress", "onClick", "masterButtonPress" ] function setupTemp() { @@ -88,4 +88,9 @@ function updateChallTemp(layer) function updateBuyableTemp(layer) { updateTempData(layers[layer].buyables, tmp[layer].buyables) +} + +function updateClickableTemp(layer) +{ + updateTempData(layers[layer].clickables, tmp[layer].clickables) } \ No newline at end of file diff --git a/js/utils.js b/js/utils.js index eef5d86..3ddc27a 100644 --- a/js/utils.js +++ b/js/utils.js @@ -89,6 +89,7 @@ function getStartPlayer() { for (layer in layers){ playerdata[layer] = layers[layer].startData() playerdata[layer].buyables = getStartBuyables(layer) + if(playerdata[layer].clickables == undefined) playerdata[layer].clickables = getStartClickables(layer) playerdata[layer].spentOnBuyables = new Decimal(0) playerdata[layer].upgrades = [] playerdata[layer].milestones = [] @@ -310,6 +311,137 @@ function milestoneShown(layer, id) { return false; } + + +// ************ Big Feature related ************ + +function respecBuyables(layer) { + if (!layers[layer].buyables) return + if (!layers[layer].buyables.respec) return + if (!confirm("Are you sure you want to respec? This will force you to do a \"" + (layers[layer].name ? layers[layer].name : layer) + "\" reset as well!")) return + layers[layer].buyables.respec() + updateBuyableTemp(layer) +} + +function canAffordUpg(layer, id) { + let upg = layers[layer].upgrades[id] + let cost = tmp[layer].upgrades[id].cost + return canAffordPurchase(layer, upg, cost) +} + +function hasUpg(layer, id){ + return (player[layer].upgrades.includes(toNumber(id)) || player[layer].upgrades.includes(id.toString())) +} + +function hasMilestone(layer, id){ + return (player[layer].milestones.includes(toNumber(id)) || player[layer].milestones.includes(id.toString())) +} + +function hasChall(layer, id){ + return (player[layer].challs.includes(toNumber(id)) || player[layer].challs.includes(id.toString())) +} + +function getBuyableAmt(layer, id){ + return (player[layer].buyables[id]) +} + +function setBuyableAmt(layer, id, amt){ + player[layer].buyables[id] = amt +} + +function getClickableState(layer, id){ + return (player[layer].clickables[id]) +} + +function setClickableState(layer, id, state){ + player[layer].clickables[id] = state +} + +function upgEffect(layer, id){ + return (tmp[layer].upgrades[id].effect) +} + +function challEffect(layer, id){ + return (tmp[layer].challs[id].effect) +} + +function buyableEffect(layer, id){ + return (tmp[layer].buyables[id].effect) +} + + +function canAffordPurchase(layer, thing, cost) { + if (thing.currencyInternalName){ + let name = thing.currencyInternalName + if (thing.currencyLayer){ + let lr = thing.currencyLayer + return !(player[lr][name].lt(cost)) + } + else { + return !(player[name].lt(cost)) + } + } + else { + return !(player[layer].points.lt(cost)) + } +} + +function buyUpg(layer, id) { + if (!player[layer].unl) return + if (!layers[layer].upgrades[id].unl()) return + if (player[layer].upgrades.includes(id)) return + let upg = layers[layer].upgrades[id] + let cost = tmp[layer].upgrades[id].cost + + if (upg.currencyInternalName){ + let name = upg.currencyInternalName + if (upg.currencyLayer){ + let lr = upg.currencyLayer + if (player[lr][name].lt(cost)) return + player[lr][name] = player[lr][name].sub(cost) + } + else { + if (player[name].lt(cost)) return + player[name] = player[name].sub(cost) + } + } + else { + if (player[layer].points.lt(cost)) return + player[layer].points = player[layer].points.sub(cost) + } + player[layer].upgrades.push(id); + if (upg.onPurchase != undefined) + upg.onPurchase() +} + +function buyMaxBuyable(layer, id) { + if (!player[layer].unl) return + if (!tmp[layer].buyables[id].unl) return + if (!tmp[layer].buyables[id].canAfford) return + if (!layers[layer].buyables[id].buyMax) return + + layers[layer].buyables[id].buyMax() + updateBuyableTemp(layer) +} + +function buyBuyable(layer, id) { + if (!player[layer].unl) return + if (!tmp[layer].buyables[id].unl) return + if (!tmp[layer].buyables[id].canAfford) return + + layers[layer].buyables[id].buy() + updateBuyableTemp(layer) +} + +function clickClickable(layer, id) { + if (!player[layer].unl) return + if (!tmp[layer].clickables[id].unl) return + if (!tmp[layer].clickables[id].canClick) return + + layers[layer].clickables[id].onClick() + updateClickableTemp(layer) +} + // ************ Misc ************ var onTreeTab = true diff --git a/js/v.js b/js/v.js index a3e2d8a..9b88198 100644 --- a/js/v.js +++ b/js/v.js @@ -218,6 +218,39 @@ function loadVue() { ` }) + + // data = button size, in px + Vue.component('clickables', { + props: ['layer', 'data'], + template: ` +
+
+
+
+ +
+
+
+
+ ` + }) + + // data = id of clickable + Vue.component('clickable', { + props: ['layer', 'data', 'size'], + template: ` + + ` + }) + + // data = button size, in px Vue.component('microtabs', { props: ['layer', 'data'], From 9b035a22801c84c39aee221546604406e0484440 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Sun, 11 Oct 2020 16:42:32 -0400 Subject: [PATCH 12/33] Added multiple challenge completions --- changelog.md | 4 ++++ docs/challenges.md | 3 +++ js/game.js | 28 ++++++---------------------- js/layerSupport.js | 3 +++ js/layers.js | 5 +++-- js/utils.js | 41 ++++++++++++++++++++++++++++++++++++++--- js/v.js | 4 ++-- 7 files changed, 59 insertions(+), 29 deletions(-) diff --git a/changelog.md b/changelog.md index a0434f5..f14dd85 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,8 @@ #The Modding Tree changelog: +Added clickables, a more generalized variant of buyables! +Support for multiple completions of challenges. +Added getter/setter functions for buyable amount and such Moved modInfo to game.js, added a spot for a Discord link, and a separate mod version from the TMT version Tree structure is based on layer data, no index.html needed. Tmp does not need to be manually updated. @@ -8,6 +11,7 @@ You don't have to have the same amount of upgrades in every row (and challs and Unl is optional for all Big Components (defaults to true). effectDisplay in Challenges and Upgrades no longer takes an argument, as well as buyable effect. Buyable cost can take an argument for amount of buyables, but if one is not supplied it should do the cost of the next buyable. +All displays will update correctly. ##v1.3.5 - Completely automated convertToDecimal, now you never have to worry about it again. diff --git a/docs/challenges.md b/docs/challenges.md index b684d98..ad715a6 100644 --- a/docs/challenges.md +++ b/docs/challenges.md @@ -4,6 +4,7 @@ Useful functions for dealing with Challenges and implementing their effects: - inChall(layer, id): determine if the player is in a given challenge (or another challenge on the same layer that counts as this one) - hasChall(layer, id): determine if the player has completed the challenge +- challCompletions(layer, id): determine if the player has completed the challenge - challEffect(layer, id): Returns the current effects of the challenge, if any @@ -54,6 +55,8 @@ By default, challenges use basic Points for the goal. You can change that using - currencyLayer: **optional**, the internal name of the layer that currency is stored in. If it's part of a layer, omit. +- completionLimit: **optional**, the amount of times you can complete this challenge. Default is 1 completion. + - style: **Optional**, A CSS object, which affects this challenge. - layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar diff --git a/js/game.js b/js/game.js index a1e2439..8c6ae9e 100644 --- a/js/game.js +++ b/js/game.js @@ -154,25 +154,6 @@ function resetBuyables(layer){ player[layer].spentOnBuyables = new Decimal(0) } -function getStartBuyables(layer){ - let data = {} - if (layers[layer].buyables) { - for (id in layers[layer].buyables) - if (!isNaN(id)) - data[id] = new Decimal(0) - } - return data -} - -function getStartClickables(layer){ - let data = {} - if (layers[layer].buyables) { - for (id in layers[layer].buyables) - if (!isNaN(id)) - data[id] = "" - } - return data -} function addPoints(layer, gain) { player[layer].points = player[layer].points.add(gain).max(0) @@ -292,10 +273,13 @@ function canCompleteChall(layer, x) function completeChall(layer, x) { var x = player[layer].active if (!x) return - if (! canCompleteChall(layer, x)) return - if (!player[layer].challs.includes(x)) { + if (! canCompleteChall(layer, x)){ + delete player[layer].active + return + } + if (player[layer].challs[x] < tmp[layer].challs[x].completionLimit) { needCanvasUpdate = true - player[layer].challs.push(x); + player[layer].challs[x] += 1 if (layers[layer].challs[x].onComplete) layers[layer].challs[x].onComplete() } delete player[layer].active diff --git a/js/layerSupport.js b/js/layerSupport.js index ff463bc..4f250d0 100644 --- a/js/layerSupport.js +++ b/js/layerSupport.js @@ -58,6 +58,9 @@ function updateLayers(){ layers[layer].challs[thing].layer = layer if (layers[layer].challs[thing].unl === undefined) layers[layer].challs[thing].unl = true + if (layers[layer].challs[thing].completionLimit === undefined) + layers[layer].challs[thing].completionLimit = 1 + } } } diff --git a/js/layers.js b/js/layers.js index 448b44f..cb714c2 100644 --- a/js/layers.js +++ b/js/layers.js @@ -64,8 +64,9 @@ addLayer("c", { rows: 2, cols: 12, 11: { - name:() => "Fun", - desc:() => "Makes the game 0% harder", + name:() => "Fun", + completionLimit: 3, + desc() {return "Makes the game 0% harder
"+challCompletions(this.layer, this.id) + "/" + this.completionLimit + " completions"}, unl() { return player[this.layer].best.gt(0) }, goal:() => new Decimal("20"), currencyDisplayName: "lollipops", // Use if using a nonstandard currency diff --git a/js/utils.js b/js/utils.js index 3ddc27a..7e5fc6f 100644 --- a/js/utils.js +++ b/js/utils.js @@ -93,7 +93,7 @@ function getStartPlayer() { playerdata[layer].spentOnBuyables = new Decimal(0) playerdata[layer].upgrades = [] playerdata[layer].milestones = [] - playerdata[layer].challs = [] + playerdata[layer].challs = getStartChalls(layer) if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)) { playerdata.subtabs[layer] = {} playerdata.subtabs[layer].mainTabs = Object.keys(layers[layer].tabFormat)[0] @@ -107,6 +107,37 @@ function getStartPlayer() { return playerdata } + +function getStartBuyables(layer){ + let data = {} + if (layers[layer].buyables) { + for (id in layers[layer].buyables) + if (!isNaN(id)) + data[id] = new Decimal(0) + } + return data +} + +function getStartClickables(layer){ + let data = {} + if (layers[layer].clickables) { + for (id in layers[layer].clickables) + if (!isNaN(id)) + data[id] = "" + } + return data +} + +function getStartChalls(layer){ + let data = {} + if (layers[layer].challs) { + for (id in layers[layer].challs) + if (!isNaN(id)) + data[id] = 0 + } + return data +} + function fixSave() { defaultData = getStartPlayer() fixData(defaultData, player) @@ -137,7 +168,7 @@ function fixData(defaultData, newData) { newData[item] = new Decimal(newData[item]) } else if ((!!defaultData[item]) && (defaultData[item].constructor === Object)) { - if (newData[item] === undefined) + if (newData[item] === undefined || (defaultData[item].constructor !== Object)) newData[item] = defaultData[item] else fixData(defaultData[item], newData[item]) @@ -338,7 +369,11 @@ function hasMilestone(layer, id){ } function hasChall(layer, id){ - return (player[layer].challs.includes(toNumber(id)) || player[layer].challs.includes(id.toString())) + return (player[layer].challs[id]) +} + +function challCompletions(layer, id){ + return (player[layer].challs[id]) } function getBuyableAmt(layer, id){ diff --git a/js/v.js b/js/v.js index 9b88198..22390d6 100644 --- a/js/v.js +++ b/js/v.js @@ -96,9 +96,9 @@ function loadVue() { Vue.component('chall', { props: ['layer', 'data'], template: ` -
+



-

+


Goal: {{format(tmp[layer].challs[data].goal)}} {{tmp[layer].challs[data].currencyDisplayName ? tmp[layer].challs[data].currencyDisplayName : "points"}}
Reward:
From 18898f519eb0baa60f0d7c563628d52e7037a873 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Sun, 11 Oct 2020 18:11:42 -0400 Subject: [PATCH 13/33] Made changelog no longer in index.html, URL can be set in modInfo --- changelog.md | 3 ++- index.html | 10 +--------- js/game.js | 1 + 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/changelog.md b/changelog.md index f14dd85..94775a3 100644 --- a/changelog.md +++ b/changelog.md @@ -3,7 +3,7 @@ Added clickables, a more generalized variant of buyables! Support for multiple completions of challenges. Added getter/setter functions for buyable amount and such -Moved modInfo to game.js, added a spot for a Discord link, and a separate mod version from the TMT version +Moved modInfo to game.js, added a spot for a Discord link, changelog link, and a separate mod version from the TMT version Tree structure is based on layer data, no index.html needed. Tmp does not need to be manually updated. Almost every value in layer data can be a function or a constant value! @@ -12,6 +12,7 @@ Unl is optional for all Big Components (defaults to true). effectDisplay in Challenges and Upgrades no longer takes an argument, as well as buyable effect. Buyable cost can take an argument for amount of buyables, but if one is not supplied it should do the cost of the next buyable. All displays will update correctly. +Changelog is no longer in index.html at all. ##v1.3.5 - Completely automated convertToDecimal, now you never have to worry about it again. diff --git a/index.html b/index.html index 6175dad..1243f00 100644 --- a/index.html +++ b/index.html @@ -40,14 +40,6 @@



-

v1.3.5

-
    -
  • The system now handles convertToDecimal for everything automatically!
  • -
  • Created a tutorial for getting started with TMT and Github.
  • -
  • Branches can be defined without a color id. But they can also use hex values for color ids!
  • -
  • Page title is now automatically taken from mod name.
  • -

- Full history
@@ -62,7 +54,7 @@
Original idea by papyrus (on discord)

-
+ Changelog
{{modInfo.discordName}}
The Modding Tree Discord
Main Prestige Tree server
diff --git a/js/game.js b/js/game.js index 8c6ae9e..b58aa90 100644 --- a/js/game.js +++ b/js/game.js @@ -10,6 +10,7 @@ let modInfo = { pointsName: "points", discordName: "", discordLink: "", + changelogLink: "https://github.com/Acamaeda/The-Modding-Tree/blob/master/changelog.md", offlineLimit: 1 // In hours } From e9d0f17d418fa9669e9988a49875655c0524d114 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Sun, 11 Oct 2020 18:38:54 -0400 Subject: [PATCH 14/33] Made point generation make sense --- changelog.md | 5 +++++ index.html | 2 +- js/game.js | 19 +++++-------------- js/layers.js | 3 --- js/utils.js | 9 +++++++++ 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/changelog.md b/changelog.md index 94775a3..c650942 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,6 @@ #The Modding Tree changelog: +##v2.0 Added clickables, a more generalized variant of buyables! Support for multiple completions of challenges. Added getter/setter functions for buyable amount and such @@ -13,14 +14,18 @@ effectDisplay in Challenges and Upgrades no longer takes an argument, as well as Buyable cost can take an argument for amount of buyables, but if one is not supplied it should do the cost of the next buyable. All displays will update correctly. Changelog is no longer in index.html at all. +Generation of Points now happens in the main game loop (not in a layer update function), enabled by canGenPoints in game.js + ##v1.3.5 + - Completely automated convertToDecimal, now you never have to worry about it again. - Branches can be defined without a color id. But they can also use hex values for color ids! - Created a tutorial for getting started with TMT and Github. - Page title is now automatically taken from mod name. ##v1.3.4: 10/8/20 + - Added "midsection" feature to add things to a tab's layout while still keeping the standard layout. - Fix for being able to buy more buyables than you should. diff --git a/index.html b/index.html index 1243f00..da90b19 100644 --- a/index.html +++ b/index.html @@ -108,7 +108,7 @@

{{format(player.points)}}

{{modInfo.pointsName}}
- ({{format(getPointGen())}}/sec) + ({{format(getPointGen())}}/sec)



diff --git a/js/game.js b/js/game.js index b58aa90..ac45790 100644 --- a/js/game.js +++ b/js/game.js @@ -22,13 +22,13 @@ let VERSION = { } // Determines if it should show points/sec -function showPointGen(){ - return (tmp.pointGen.neq(new Decimal(0))) -} +function canGenPoints(){ + return hasUpg("c", 11) +} // Calculate points/sec! function getPointGen() { - if(!hasUpg("c", 11)) + if(!canGenPoints()) return new Decimal(0) let gain = new Decimal(1) @@ -38,15 +38,6 @@ function getPointGen() { -// Function to determine if the player is in a challenge -function inChallenge(layer, id){ - let chall = player[layer].active - if (chall==toNumber(id)) return true - - if (layers[layer].challs[chall].countsAs) - return layers[layer].challs[id].countsAs.includes(id) -} - function getResetGain(layer, useType = null) { let type = useType if (!useType) type = layers[layer].type @@ -304,7 +295,7 @@ function gameLoop(diff) { if (player.devSpeed) diff *= player.devSpeed addTime(diff) - + player.points = player.points.add(tmp.pointGen.times(diff)).max(0) for (layer in layers){ if (layers[layer].update) layers[layer].update(diff); } diff --git a/js/layers.js b/js/layers.js index cb714c2..f41816b 100644 --- a/js/layers.js +++ b/js/layers.js @@ -178,9 +178,6 @@ addLayer("c", { if(layers[resettingLayer].row > this.row) fullLayerReset(this.layer) // This is actually the default behavior }, layerShown() {return true}, // Condition for when layer appears on the tree - update(diff) { - if (player[this.layer].upgrades.includes(11)) player.points = player.points.add(tmp.pointGen.times(diff)).max(0) - }, // Do any gameloop things (e.g. resource generation) inherent to this layer automate() { }, // Do any automation inherent to this layer if appropriate resetsNothing() {return false}, diff --git a/js/utils.js b/js/utils.js index 7e5fc6f..3834f38 100644 --- a/js/utils.js +++ b/js/utils.js @@ -477,6 +477,15 @@ function clickClickable(layer, id) { updateClickableTemp(layer) } +// Function to determine if the player is in a challenge +function inChallenge(layer, id){ + let chall = player[layer].active + if (chall==toNumber(id)) return true + + if (layers[layer].challs[chall].countsAs) + return layers[layer].challs[id].countsAs.includes(id) +} + // ************ Misc ************ var onTreeTab = true From 40bbf036685b04c3068f5752e2a74e5e17654a7d Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Mon, 12 Oct 2020 18:28:12 -0400 Subject: [PATCH 15/33] Added Bars component --- index.html | 6 ++-- js/game.js | 8 +++-- js/layerSupport.js | 21 ++++++++--- js/layers.js | 88 +++++++++++++++++++++++++++++++++++++--------- js/temp.js | 47 ++++++++++++++++++++++++- js/utils.js | 2 +- js/v.js | 46 +++++++++++++++--------- style.css | 40 +++++++++++++++++++-- 8 files changed, 211 insertions(+), 47 deletions(-) diff --git a/index.html b/index.html index da90b19..0566a11 100644 --- a/index.html +++ b/index.html @@ -117,8 +117,8 @@ -
-
+
+



@@ -141,7 +141,7 @@
-
+
diff --git a/js/game.js b/js/game.js index ac45790..7be1dfa 100644 --- a/js/game.js +++ b/js/game.js @@ -63,19 +63,21 @@ function getNextAt(layer, canMax=false, useType = null) { let type = useType if (!useType) type = layers[layer].type - if (tmp[layer].gainExp.eq(0)) return new Decimal(1/0) + if (tmp[layer].gainMult.lte(0)) return new Decimal(Infinity) + if (tmp[layer].gainExp.lte(0)) return new Decimal(Infinity) + if (type=="static") { if (!layers[layer].canBuyMax()) canMax = false let amt = player[layer].points.plus((canMax&&tmp[layer].baseAmount.gte(tmp[layer].nextAt))?tmp[layer].resetGain:0) - let extraCost = Decimal.pow(layers[layer].base, amt.pow(layers[layer].exponent).div(tmp[layer].gainExp)).times(tmp[layer].gainMult) + let extraCost = Decimal.pow(layers[layer].base, amt.pow(tmp[layer].exponent).div(tmp[layer].gainExp)).times(tmp[layer].gainMult) let cost = extraCost.times(tmp[layer].requires).max(tmp[layer].requires) if (layers[layer].resCeil) cost = cost.ceil() return cost; } else if (type=="normal"){ let next = tmp[layer].resetGain.add(1) if (next.gte("e1e7")) next = next.div("e5e6").pow(2) - next = next.root(tmp[layer].gainExp.div(tmp[layer].gainMult).root(layers[layer].exponent).times(tmp[layer].requires).max(tmp[layer].requires)) + next=next.root(tmp[layer].gainExp.div(tmp[layer].gainMult)).root(tmp[layer].exponent).times(tmp[layer].requires).max(tmp[layer].requires) if (layers[layer].resCeil) next = next.ceil() return next; } else if (type=="custom"){ diff --git a/js/layerSupport.js b/js/layerSupport.js index 4f250d0..1b2c936 100644 --- a/js/layerSupport.js +++ b/js/layerSupport.js @@ -88,6 +88,18 @@ function updateLayers(){ } } + if (layers[layer].bars){ + layers[layer].bars.layer = layer + for (thing in layers[layer].bars){ + if (!isNaN(thing)){ + layers[layer].bars[thing].id = thing + layers[layer].bars[thing].layer = layer + if (layers[layer].bars[thing].unl === undefined) + layers[layer].bars[thing].unl = true + } + } + } + if(!layers[layer].componentStyles) layers[layer].componentStyles = {} if(layers[layer].symbol === undefined) layers[layer].symbol = layer.charAt(0).toUpperCase() + layer.slice(1) @@ -127,8 +139,9 @@ function someLayerUnlocked(row){ return false } + // This isn't worth making a .ts file over -const UP = 1 -const DOWN = 2 -const LEFT = 3 -const RIGHT = 4 \ No newline at end of file +const UP = 0 +const DOWN = 1 +const LEFT = 2 +const RIGHT = 3 diff --git a/js/layers.js b/js/layers.js index f41816b..e500f2a 100644 --- a/js/layers.js +++ b/js/layers.js @@ -208,23 +208,54 @@ addLayer("c", { } }, - gagues: { + bars: { longBoi: { - fillColor:() => "#4BEC13", - // fillStyle:(), - baseColor:() => "#333333", - // baseStyle:(), - // textStyle:(), + fillStyle: {'background-color' : "#FFFFFF"}, + baseStyle: {'background-color' : "#696969"}, + textStyle: {'color': '#04e050'}, - borderStyle() {return {'border-color': '#321188'}}, - direction:() => RIGHT, - width:() => "250px", - height:() => "250px", + borderStyle() {return {}}, + direction: RIGHT, + width: 300, + height: 30, progress() { - return (player.points.log().div(10)) + return (player.points.log(10).div(10)).toNumber() }, display() { - return format(player.points) + " / 1e10" + return format(player.points) + " / 1e10 points" + }, + unl:() => true, + + }, + tallBoi: { + fillStyle: {'background-color' : "#4BEC13"}, + baseStyle: {'background-color' : "#000000"}, + textStyle: {'text-shadow': '0px 0px 2px #000000'}, + + borderStyle() {return {}}, + direction: UP, + width: 50, + height: 200, + progress() { + return player.points.div(100) + }, + display() { + return formatWhole((player.points.div(1)).min(100)) + "%" + }, + unl:() => true, + + }, + flatBoi: { + fillStyle: {'background-color' : "#FE0102"}, + baseStyle: {'background-color' : "#222222"}, + textStyle: {'text-shadow': '0px 0px 2px #000000'}, + + borderStyle() {return {}}, + direction: UP, + width: 100, + height: 30, + progress() { + return player.c.points.div(50) }, unl:() => true, @@ -248,7 +279,7 @@ addLayer("c", { thingies: { style() {return {'background-color': '#222222'}}, buttonStyle() {return {'border-color': 'orange'}}, - content:[ + content:[ ["buyables", ""], "blank", ["row", [ ["toggle", ["c", "beep"]], ["blank", ["30px", "10px"]], // Width, height @@ -261,17 +292,33 @@ addLayer("c", { "blank", ["display-image", "discord.png"],], }, + jail: { + content: [ + ["bar", "longBoi"], "blank", + ["row", [ + ["column", [ + ["display-text", "Sugar level:", {'color': 'teal'}], "blank", ["bar", "tallBoi"]], + {'background-color': '#555555', 'padding': '15px'}], + "blank", + ["column", [ + ["display-text", "idk"], + ["blank", ['0', '50px']], ["bar", "flatBoi"] + ]], + ]], + "blank", ["display-text", "It's because bars! So funny! Ha ha!"], + ], + }, illuminati: { unl() {return (hasUpg("c", 13))}, content:[ - ["raw-html", function() {return "

C O N F I R M E D

"}], + ["raw-html", function() {return "

C O N F I R M E D

"}], "blank", ["microtabs", "stuff", {'width': '600px', 'height': '350px', 'background-color': 'brown', 'border-style': 'solid'}] ] } }, style() {return { - 'background-color': '#3325CC' + //'background-color': '#3325CC' }}, nodeStyle() {return { // Style on the layer node 'color': '#3325CC', @@ -344,7 +391,16 @@ addLayer("f", { canReset() { return tmp[this.layer].baseAmount.gte(tmp[this.layer].nextAt) }, - + upgrades: { + rows: 1, + cols: 1, + 11: { + title:() => "Generator", + cost:() => new Decimal(1), + desc:() => "Gain 1 point per second", + } + + }, // This is also non minimal, a Clickable! clickables: { rows: 1, diff --git a/js/temp.js b/js/temp.js index a2d0c13..7592ab2 100644 --- a/js/temp.js +++ b/js/temp.js @@ -17,6 +17,7 @@ function setupTemp() { tmp[layer].notify = {} tmp[layer].canReset = {} tmp[layer].prestigeButtonText = {} + setupBarStyles(layer) } } @@ -59,7 +60,7 @@ function updateTemp() { tmp[layer].notify = shouldNotify(layer) tmp[layer].canReset = canReset(layer) tmp[layer].prestigeButtonText = prestigeButtonText(layer) - + constructBarStyles(layer) } tmp.pointGen = getPointGen() @@ -93,4 +94,48 @@ function updateBuyableTemp(layer) function updateClickableTemp(layer) { updateTempData(layers[layer].clickables, tmp[layer].clickables) +} + + +var DIR_MARGINS = ["margin-bottom", "margin-top", "margin-right", "margin-left"] + +function constructBarStyles(layer){ + if (layers[layer].bars === undefined) + return + for (id in layers[layer].bars){ + if (id !== "layer") { + let bar = tmp[layer].bars[id] + if (bar.progress instanceof Decimal) + bar.progress = bar.progress.toNumber() + bar.dims = {'width': bar.width + "px", 'height': bar.height + "px"} + let dir = bar.direction + bar.fillDims = {'width': bar.width + "px", 'height': bar.height + "px"} + if (dir !== undefined) + { + bar.fillDims[DIR_MARGINS[dir]] = "0px" + if (dir == UP || dir == DOWN) + { + bar.fillDims.height = bar.height * Math.min(bar.progress, 1) + "px" + if (dir == UP) bar.fillDims['margin-top'] = bar.height * (1 - Math.min(bar.progress, 1)) + "px" + } + else + { + bar.fillDims.width = bar.width * Math.min(bar.progress, 1) + "px" + if (dir == LEFT) bar.fillDims['margin-left'] = bar.width * (1 - Math.min(bar.progress, 1)) + "px" + } + } + } + + } +} + +function setupBarStyles(layer){ + if (layers[layer].bars === undefined) + return + for (id in layers[layer].bars){ + let bar = tmp[layer].bars[id] + bar.dims = {} + let dir = bar.direction + bar.fillDims = {} + } } \ No newline at end of file diff --git a/js/utils.js b/js/utils.js index 3834f38..d467b04 100644 --- a/js/utils.js +++ b/js/utils.js @@ -423,7 +423,7 @@ function canAffordPurchase(layer, thing, cost) { function buyUpg(layer, id) { if (!player[layer].unl) return - if (!layers[layer].upgrades[id].unl()) return + if (!layers[layer].upgrades[id].unl) return if (player[layer].upgrades.includes(id)) return let upg = layers[layer].upgrades[id] let cost = tmp[layer].upgrades[id].cost diff --git a/js/v.js b/js/v.js index 22390d6..69c21a4 100644 --- a/js/v.js +++ b/js/v.js @@ -5,19 +5,26 @@ function loadVue() { Vue.component('display-text', { props: ['layer', 'data'], template: ` - + ` }) +// data = a function returning the content (actually HTML) + Vue.component('raw-html', { + props: ['layer', 'data'], + template: ` + + ` + }) // Blank space, data = optional height in px or pair with width and height in px Vue.component('blank', { props: ['layer', 'data'], template: ` -
-
-
-

+
+
+
+

` }) @@ -26,7 +33,7 @@ function loadVue() { Vue.component('display-image', { props: ['layer', 'data'], template: ` - + ` }) @@ -34,7 +41,7 @@ function loadVue() { Vue.component('row', { props: ['layer', 'data'], template: ` -
+
@@ -50,7 +57,7 @@ function loadVue() { Vue.component('column', { props: ['layer', 'data'], template: ` -
+
@@ -67,7 +74,7 @@ function loadVue() { Vue.component('h-line', { props: ['layer', 'data'], template:` -
+
` }) @@ -75,7 +82,7 @@ function loadVue() { Vue.component('v-line', { props: ['layer', 'data'], template: ` -
+
` }) @@ -153,7 +160,7 @@ function loadVue() { Vue.component('milestone', { props: ['layer', 'data'], template: ` -
@@ -267,18 +274,23 @@ function loadVue() { ` }) - // data = id of gague - Vue.component('gague', { + + // data = id of the bar + Vue.component('bar', { props: ['layer', 'data'], template: ` -
-
+
+ +
+
+ +
` }) - + // NOT FOR USE IN STANDARD TAB FORMATTING Vue.component('tab-buttons', { diff --git a/style.css b/style.css index 00c32d4..6dc272b 100644 --- a/style.css +++ b/style.css @@ -122,9 +122,37 @@ h1, h2, h3, b, input { text-shadow: 0px 0px 7px var(--color); } +.barBorder { + border: 2px solid; + border-radius: 10%; + border-color: var(--color); + overflow: hidden; + -webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC); +} + +.overlayTextContainer { + z-index: 3; + border-radius: 10%; + vertical-align: middle; + display: flex; + justify-content: center; + align-items: left; + position: absolute; +} + +.fill { + background-color: var(--color); + border-radius: 5%; + position: absolute; + overflow: hidden; +} + +.overlayText { + z-index: 6; +} + .tabButton { background-color: transparent; - border: none; color: var(--color); font-size: 20px; cursor: pointer; @@ -359,6 +387,14 @@ a { transition-duration: 0s } +.instant { + transition-duration: 0s !important +} + +.fast { + transition:color none +} + .col.right { top: 0; right: 0; @@ -486,4 +522,4 @@ ul { display: flex; flex-direction: column; justify-content: center; -} \ No newline at end of file +} From 9956aa77e5ac78166ed05fb1d65e90b65a244dde Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Mon, 12 Oct 2020 19:18:20 -0400 Subject: [PATCH 16/33] Fixed NextAt --- js/game.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/game.js b/js/game.js index 7be1dfa..df2dc70 100644 --- a/js/game.js +++ b/js/game.js @@ -77,7 +77,7 @@ function getNextAt(layer, canMax=false, useType = null) { } else if (type=="normal"){ let next = tmp[layer].resetGain.add(1) if (next.gte("e1e7")) next = next.div("e5e6").pow(2) - next=next.root(tmp[layer].gainExp.div(tmp[layer].gainMult)).root(tmp[layer].exponent).times(tmp[layer].requires).max(tmp[layer].requires) + next = next.root(tmp[layer].gainExp).div(tmp[layer].gainMult).root(tmp[layer].exponent).times(tmp[layer].requires).max(tmp[layer].requires) if (layers[layer].resCeil) next = next.ceil() return next; } else if (type=="custom"){ From 02da021fb1d220532a95f9e159e743c88b33ea4b Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Mon, 12 Oct 2020 20:48:06 -0400 Subject: [PATCH 17/33] Started to update docs --- changelog.md | 18 +++++++++++++++++- docs/basic-layer-breakdown.md | 2 +- docs/challenges.md | 2 +- docs/getting-started.md | 7 ++++--- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/changelog.md b/changelog.md index c650942..56e8577 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,7 @@ #The Modding Tree changelog: ##v2.0 +Added Progress bars, which are highly customizable and can be horizontal or vertical. Added clickables, a more generalized variant of buyables! Support for multiple completions of challenges. Added getter/setter functions for buyable amount and such @@ -93,4 +94,19 @@ parameters. - Lots of minor good things. #v1.0: -- First release. \ No newline at end of file +- First release. + + +Make it clear that anything can be a function + +buyables.md: cost is a Decimal + +Define "CSS Object" clearly in the first instance in each file + +Explain automagical assignments better + + + +Change all "chall", "unl", "desc", "res_ceil", "incr_order", + +Challenges: "chall", "desc", reward -> rewardDescription, effect -> reward, effectDisplay -> rewardDisplay, \ No newline at end of file diff --git a/docs/basic-layer-breakdown.md b/docs/basic-layer-breakdown.md index 8846a90..0e330d1 100644 --- a/docs/basic-layer-breakdown.md +++ b/docs/basic-layer-breakdown.md @@ -18,7 +18,7 @@ This is a very minimal layer with minimal features. Most things will require add baseResource: "points", // The name of the resource your prestige gain is based on baseAmount() {return player.points}, // A function to return the current value of that resource - requires: new Decimal(200)}, // The amount of the base needed to gain 1 of the prestige currency. + requires: new Decimal(200), // The amount of the base needed to gain 1 of the prestige currency. // Also the amount required to unlock the layer. type: "normal", // Determines the formula used for calculating prestige currency. diff --git a/docs/challenges.md b/docs/challenges.md index ad715a6..b92a2b1 100644 --- a/docs/challenges.md +++ b/docs/challenges.md @@ -39,7 +39,7 @@ Individual Challenges can have these features: - effectDisplay(): **optional**, A function that returns a display of the current effects of the reward with formatting. Default behavior is to just display the a number appropriately formatted. -- goal: A Decimal for the cost of the upgrade. By default, the goal is in basic Points. +- goal: A Decimal for the amount of currency required to beat the challenge. By default, the goal is in basic Points. The goal can also be a function if its value changes. - unl(): A function returning a bool to determine if the challenge is visible or not. diff --git a/docs/getting-started.md b/docs/getting-started.md index 93eeacb..464e353 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -43,10 +43,11 @@ The benefits of using Github: 2. To edit your project, click "open in VSCode" in Github Desktop. -3. Open index.html, and look at the top part where it says "modInfo". On the lines below that, change - the mod's name to whatever you want, and change the id as well. (The id is important, it determines where the game looks for your saves. It should be different from other mods, and shouldn't be changed once set.) +3. Open game.js in VSCode, and look at the top part where it says "modInfo". On the lines below that, change + the mod's name to whatever you want, and change the id as well. (It can be any string value, and it's used to determine + where the savefile is. Make it something that's probably unique, and don't change it again later.) -4. Reload index.html. The title on the tab, as well as on the info page, will now be the new ones! +4. Save game.js, and then reload index.html. The title on the tab, as well as on the info page, will now be the new ones! 5. Go back to Github Desktop. It's time to save your changes into the git system by making a "commit". From fde714d73f3a11ffbe358cd7d82342bbc66e5e19 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Mon, 12 Oct 2020 23:08:19 -0400 Subject: [PATCH 18/33] Renamed many things to be more readable and updated docs --- {js => Old Code}/gametest.js | 60 ++++++++++++------------ {js => Old Code}/test.js | 0 changelog.md | 19 ++++++-- docs/!general-info.md | 2 + docs/basic-layer-breakdown.md | 2 +- docs/buyables.md | 17 ++++--- docs/challenges.md | 24 +++++----- docs/clickables.md | 10 ++-- docs/custom-tab-layouts.md | 7 ++- docs/layer-features.md | 20 +++++--- docs/milestones.md | 9 ++-- docs/subtabs-and-microtabs.md | 6 ++- docs/upgrades.md | 14 +++--- index.html | 6 +-- js/game.js | 60 ++++++++++++------------ js/layerSupport.js | 38 +++++++-------- js/layers.js | 88 ++++++++++++++++------------------- js/temp.js | 4 +- js/utils.js | 72 ++++++++++++++-------------- js/v.js | 70 ++++++++++++++-------------- style.css | 6 +-- 21 files changed, 281 insertions(+), 253 deletions(-) rename {js => Old Code}/gametest.js (90%) rename {js => Old Code}/test.js (100%) diff --git a/js/gametest.js b/Old Code/gametest.js similarity index 90% rename from js/gametest.js rename to Old Code/gametest.js index 34f394e..b1256df 100644 --- a/js/gametest.js +++ b/Old Code/gametest.js @@ -49,11 +49,11 @@ function getPointGen() { // Function to determine if the player is in a challenge function inChallenge(layer, id){ - let chall = player[layer].active - if (chall==toNumber(id)) return true + let challenge = player[layer].active + if (challenge==toNumber(id)) return true - if (layers[layer].challs[chall].countsAs) - return layers[layer].challs[id].countsAs.includes(id) + if (layers[layer].challenges[challenge].countsAs) + return layers[layer].challenges[id].countsAs.includes(id) } function getResetGain(layer, useType = null) { @@ -144,7 +144,7 @@ function fullLayerReset(layer) { player[layer] = layers[layer].startData(); player[layer].upgrades = [] player[layer].milestones = [] - player[layer].challs = [] + player[layer].challenges = [] if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)) { if (player.subtabs[layer] == undefined) player.subtabs[layer] = {} if (player.subtabs[layer].mainTabs == undefined) player.subtabs[layer].mainTabs = Object.keys(layers[layer].tabFormat)[0] @@ -218,7 +218,7 @@ function doReset(layer, force=false) { for (layerResetting in layers) { - if (row >= layers[layerResetting].row && (!force || layerResetting != layer)) completeChall(layerResetting) + if (row >= layers[layerResetting].row && (!force || layerResetting != layer)) completeChallenge(layerResetting) } prevOnReset = {...player} //Deep Copy @@ -260,10 +260,10 @@ function hasMilestone(layer, id) { return (player[layer].milestones.includes(toNumber(id)) || player[layer].milestones.includes(id.toString())) } -function hasChall(layer, id){ - if (!layers[layer].challs) return false +function hasChallenge(layer, id){ + if (!layers[layer].challenges) return false - return (player[layer].challs.includes(toNumber(id)) || player[layer].challs.includes(id.toString())) + return (player[layer].challenges.includes(toNumber(id)) || player[layer].challenges.includes(id.toString())) } function buyablesOwned(layer, id){ @@ -280,10 +280,10 @@ function upgEffect(layer, id){ return (tmp[layer].upgrades[id].effect) } -function challEffect(layer, id){ - if (!layers[layer].chall) return false +function challengeEffect(layer, id){ + if (!layers[layer].challenge) return false - return (tmp[layer].challs[id].effect) + return (tmp[layer].challenges[id].effect) } function buyableEffect(layer, id){ @@ -371,11 +371,11 @@ function resetRow(row) { resizeCanvas(); } -function startChall(layer, x) { +function startChallenge(layer, x) { let enter = false if (!player[layer].unl) return if (player[layer].active == x) { - completeChall(layer, x) + completeChallenge(layer, x) delete player[layer].active } else { enter = true @@ -383,42 +383,42 @@ function startChall(layer, x) { doReset(layer, true) if(enter) player[layer].active = x - updateChallTemp(layer) + updateChallengeTemp(layer) } -function canCompleteChall(layer, x) +function canCompleteChallenge(layer, x) { if (x != player[layer].active) return - let chall = layers[layer].challs[x] + let challenge = layers[layer].challenges[x] - if (chall.currencyInternalName){ - let name = chall.currencyInternalName - if (chall.currencyLayer){ - let lr = chall.currencyLayer - return !(player[lr][name].lt(readData(chall.goal))) + if (challenge.currencyInternalName){ + let name = challenge.currencyInternalName + if (challenge.currencyLayer){ + let lr = challenge.currencyLayer + return !(player[lr][name].lt(readData(challenge.goal))) } else { - return !(player[name].lt(chall.cost)) + return !(player[name].lt(challenge.cost)) } } else { - return !(player[layer].points.lt(chall.cost)) + return !(player[layer].points.lt(challenge.cost)) } } -function completeChall(layer, x) { +function completeChallenge(layer, x) { var x = player[layer].active if (!x) return - if (! canCompleteChall(layer, x)) return - if (!player[layer].challs.includes(x)) { + if (! canCompleteChallenge(layer, x)) return + if (!player[layer].challenges.includes(x)) { needCanvasUpdate = true - player[layer].challs.push(x); - if (layers[layer].challs[x].onComplete) layers[layer].challs[x].onComplete() + player[layer].challenges.push(x); + if (layers[layer].challenges[x].onComplete) layers[layer].challenges[x].onComplete() } delete player[layer].active - updateChallTemp(layer) + updateChallengeTemp(layer) } VERSION.withoutName = "v" + VERSION.num + (VERSION.pre ? " Pre-Release " + VERSION.pre : VERSION.pre ? " Beta " + VERSION.beta : "") diff --git a/js/test.js b/Old Code/test.js similarity index 100% rename from js/test.js rename to Old Code/test.js diff --git a/changelog.md b/changelog.md index 56e8577..55909f8 100644 --- a/changelog.md +++ b/changelog.md @@ -16,7 +16,8 @@ Buyable cost can take an argument for amount of buyables, but if one is not supp All displays will update correctly. Changelog is no longer in index.html at all. Generation of Points now happens in the main game loop (not in a layer update function), enabled by canGenPoints in game.js - +Renamed many things to increase readability (see something or other for a list) +Improved documentation based on feedback ##v1.3.5 @@ -106,7 +107,19 @@ Define "CSS Object" clearly in the first instance in each file Explain automagical assignments better +"incr_order", -Change all "chall", "unl", "desc", "res_ceil", "incr_order", -Challenges: "chall", "desc", reward -> rewardDescription, effect -> reward, effectDisplay -> rewardDisplay, \ No newline at end of file +All instances of: + chall -> challenge + unl -> unlocked + upg -> upgrade + amt -> amount + desc -> description + resCeil -> roundUpCost + +Challenges: + desc -> challengeDescription + reward -> rewardDescription + effect -> rewardEffect + effectDisplay -> rewardDisplay \ No newline at end of file diff --git a/docs/!general-info.md b/docs/!general-info.md index ed7fe30..0b9507c 100644 --- a/docs/!general-info.md +++ b/docs/!general-info.md @@ -28,6 +28,8 @@ plain number, and perform operations on them by calling functions. e.g, instead Can be used to make Enhancers or Space Buildings. - [Clickables](clickables.md): A more generalized variant of buyables, for any kind of thing that is sometimes clickable. Between these and Buyables, you can do just about anything. +- [Bars](bars.md): Display some information as a progress bar, gague, or similar. They are highly customizable, + and can be horizontal and vertical as well. - [Custom Tab Layouts](custom-tab-layouts.md): An optional way to give your tabs a different layout. You can even create entirely new components to use. - [Subtabs and Microtabs](subtabs-and-microtabs.md): Create subtabs for your tabs, as well as "microtab" components that you can put inside the tabs. diff --git a/docs/basic-layer-breakdown.md b/docs/basic-layer-breakdown.md index 0e330d1..43d7696 100644 --- a/docs/basic-layer-breakdown.md +++ b/docs/basic-layer-breakdown.md @@ -6,7 +6,7 @@ This is a very minimal layer with minimal features. Most things will require add ```js p: { startData() { return { // startData is a function that returns default data for a layer. - unl: false, // You can add more variables here to add them to your layer. + unlocked: false, // You can add more variables here to add them to your layer. points: new Decimal(0), // "points" is the internal name for the main resource of the layer. // If you add non-standard Decimal variables, look at convertToDecimal }}, diff --git a/docs/buyables.md b/docs/buyables.md index 098bb01..b3976db 100644 --- a/docs/buyables.md +++ b/docs/buyables.md @@ -17,7 +17,7 @@ Buyables should be formatted like this: Having this function makes a respec button appear respecText: **optional**, text that appears on the respec button 11: { - desc:() => "Blah", + display:() => "Blah", etc } etc @@ -30,7 +30,8 @@ Features: It can also be a function that returns updating text. - cost(): cost for buying the next buyable. Can have an optional argument "x" to calculate the cost of the x+1th object, - but needs to use "current amount" as a default value for x. Can return an object if there are multiple currencies. + but needs to use "current amount" as a default value for x. (x is a Decimal). + Can return an object if there are multiple currencies. - effect(): **optional**, A function that calculates and returns the current values of bonuses of this buyable. Can return a value or an object containing multiple values. @@ -38,16 +39,18 @@ Features: - display(): A function returning everything that should be displayed on the buyable after the title, likely including the description, amount bought, cost, and current effect. Can use basic HTML. -- unl(): A function returning a bool to determine if the buyable is visible or not. +- unlocked(): **optional**, A function returning a bool to determine if the buyable is visible or not. Default is unlocked. - canAfford(): A function returning a bool to determine if you can buy one of the buyables. -- buy(): A function that implements buying one of the buyable. +- buy(): A function that implements buying one of the buyable, including spending the currency. - buyMax(): **optional**, A function that implements buying as many of the buyable as possible. -- style: **Optional**, A CSS object, which affects this buyable. - +- style: **Optional**, Applies CSS to this buyable, in the form of an object where the keys are CSS attributes, + and the values are the values for those attributes (both as strings) + - 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 buyable. \ No newline at end of file +- id: **Assigned automagically**. It's the "key" which the buyable was stored under, for convenient access. + The buyable in the example's id is 11. \ No newline at end of file diff --git a/docs/challenges.md b/docs/challenges.md index b92a2b1..bb48509 100644 --- a/docs/challenges.md +++ b/docs/challenges.md @@ -2,16 +2,16 @@ Useful functions for dealing with Challenges and implementing their effects: -- inChall(layer, id): determine if the player is in a given challenge (or another challenge on the same layer that counts as this one) -- hasChall(layer, id): determine if the player has completed the challenge -- challCompletions(layer, id): determine if the player has completed the challenge +- inChallenge(layer, id): determine if the player is in a given challenge (or another challenge on the same layer that counts as this one) +- hasChallenge(layer, id): determine if the player has completed the challenge +- challengeCompletions(layer, id): determine how many times the player completed the challenge - challEffect(layer, id): Returns the current effects of the challenge, if any Challenges are stored in the following format: ```js - challs: { + challenges: { rows: # of rows cols: # of columns 11: { @@ -27,22 +27,22 @@ Individual Challenges can have these features: - name: Name of the challenge, can be a string or a function. Can use basic HTML. -- desc: A description of what makes the challenge a challenge. *You will need to implement these elsewhere* +- challengeDescription: A description of what makes the challenge a challenge. *You will need to implement these elsewhere* It can also be a function that returns updating text. Can use basic HTML. -- reward: A description of the reward's effect. *You will also have to implement the effect where it is applied.* +- rewardDescription: A description of the reward's effect. *You will also have to implement the effect where it is applied.* It can also be a function that returns updating text. Can use basic HTML. -- effect(): **optional**, A function that calculates and returns the current values of any bonuses from the reward. +- rewardEffect(): **optional**, A function that calculates and returns the current values of any bonuses from the reward. Can return a value or an object containing multiple values. Can use basic HTML. -- effectDisplay(): **optional**, A function that returns a display of the current effects of the reward with +- rewardDisplay(): **optional**, A function that returns a display of the current effects of the reward with formatting. Default behavior is to just display the a number appropriately formatted. - goal: A Decimal for the amount of currency required to beat the challenge. By default, the goal is in basic Points. The goal can also be a function if its value changes. -- unl(): A function returning a bool to determine if the challenge is visible or not. +- unlocked(): **optional**, A function returning a bool to determine if the challenge is visible or not. Default is unlocked. - onComplete() - **optional**, this function will be called when the challenge is completed when previously incomplete. @@ -57,8 +57,10 @@ By default, challenges use basic Points for the goal. You can change that using - completionLimit: **optional**, the amount of times you can complete this challenge. Default is 1 completion. -- style: **Optional**, A CSS object, which affects this challenge. +- style: **Optional**, Applies CSS to this challenge, in the form of an object where the keys are CSS attributes, + and the values are the values for those attributes (both as strings) - 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 challenge. \ No newline at end of file +- id: **Assigned automagically**. It's the "key" which the challenge was stored under, for convenient access. + The challenge in the example's id is 11. \ No newline at end of file diff --git a/docs/clickables.md b/docs/clickables.md index 0730ab2..9874f19 100644 --- a/docs/clickables.md +++ b/docs/clickables.md @@ -38,14 +38,16 @@ Features: - display(): A function returning everything that should be displayed on the clickable after the title, likely changing based on its state. Can use basic HTML. -- unl(): A function returning a bool to determine if the clickable is visible or not. +- unlocked(): **optional**, A function returning a bool to determine if the clickable is visible or not. Default is unlocked. - canClick(): A function returning a bool to determine if you can click the clickable. - onClick(): A function that implements clicking one of the clickable. -- style: **Optional**, A CSS object, which affects this clickable. +- style: **Optional**, Applies CSS to this clickable, in the form of an object where the keys are CSS attributes, + and the values are the values for those attributes (both as strings) -- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar +- 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 clickable. \ No newline at end of file +- id: **Assigned automagically**. It's the "key" which the clickable was stored under, for convenient access. + The clickable in the example's id is 11. \ No newline at end of file diff --git a/docs/custom-tab-layouts.md b/docs/custom-tab-layouts.md index d89e734..7106f37 100644 --- a/docs/custom-tab-layouts.md +++ b/docs/custom-tab-layouts.md @@ -17,8 +17,9 @@ Custom tab layouts can be used to do basically anything in a tab window, especia "milestones", "blank", "blank", "upgrades"] ``` -It is a list of components, which can be either just a name, or an array with arguments. If it's an array, the first item is the name of the component, the second is the data passed into it, and the third (optional) is a CSS object, -which applies its style to the component. +It is a list of components, which can be either just a name, or an array with arguments. If it's an array, +the first item is the name of the component, the second is the data passed into it, and the third (optional) +applies a CSS style to it with a "CSS object", where the keys are CSS attributes. These are the existing components, but you can create more in v.js: @@ -43,6 +44,8 @@ These are the existing components, but you can create more in v.js: - upgrade, milestone, chall, buyable: An individual upgrade, challenge, etc. The argument is the id. This can be used if you want to have upgrades split up across multiple subtabs, for example. +- bar: Display a bar. The argument is the id of the bar to display. + - toggle: A toggle button that toggles a bool value. The data is a pair that identifies what bool to toggle, [layer, id] - row: Display a list of components horizontally. The argument is an array of components in the tab layout format. diff --git a/docs/layer-features.md b/docs/layer-features.md index 8f3d658..e57b557 100644 --- a/docs/layer-features.md +++ b/docs/layer-features.md @@ -21,7 +21,7 @@ Key: Any nonstandard Decimal variables need to be added to convertToDecimal as well. Standard values: Required: - unl: a bool determining if this layer is unlocked or not + unlocked: a bool determining if this layer is unlocked or not points: a Decimal, the main currency for the layer Optional: total: A Decimal, tracks total amount of main prestige currency @@ -49,11 +49,12 @@ Key: hotkeys: [ {key: "p", // What the hotkey button is. Use uppercase if it's combined with shift, or "ctrl+x" if ctrl is. desc: "p: reset your points for prestige points", // The description of the hotkey used in the How To Play - onPress(){if (player.p.unl) doReset("p")}}, // This function is called when the hotkey is pressed. + onPress(){if (player.p.unlocked) doReset("p")}}, // This function is called when the hotkey is pressed. ], ``` -- style: **optional**, a CSS object containing any CSS that should affect this layer's whole tab. +- style: **optional**, a "CSS object" where the keys are CSS attributes ,containing any CSS that should affect this + layer's entire tab. - tabFormat: **optional**, use this if you want to add extra things to your tab or change the layout. [See here for more info.](custom-tab-layouts.md) @@ -73,12 +74,17 @@ Key: they recieve a bonus. [Explanations are in a separate file.](challenges.md) -- buyables: Effectively upgrades that can be bought multiple times, and are optionally respeccable. +- buyables: Effectively upgrades that can be bought multiple times, and are optionally respeccable. Many uses. [Explanations are in a separate file.](buyables.md) +- clickables: Extremely versatile and generalized buttons which can only be clicked sometimes. + [Explanations are in a separate file.](clickables.md) + - microtabs: An area that functions like a set of subtabs, with buttons at the top changing the content within. (Advanced) [Explanations are in a separate file.](subtabs-and-microtabs.md) +- bars: Display some information as a progress bar, gague, or similar. They are highly customizable, and can be vertical as well. + [Explanations are in a separate file.](bars.md) # Prestige formula features @@ -101,7 +107,7 @@ Key: - base: **sometimes required**, required for "static" layers, used as described above. -- resCeil: **optional**, a bool, which is true if the resource cost needs to be rounded up. +- roundUpCost: **optional**, a bool, which is true if the resource cost needs to be rounded up. (use if the base resource is a "static" currency.) - canBuyMax(): **sometimes required**, required for static layers, function used to determine if buying max is permitted. @@ -130,7 +136,7 @@ Key: in the list. Alternatively, an entry in the array can be a pair consisting of the layer id and a color value. The color value can either be a string with a hex color code, or a number from 1-3 (theme-affected colors) -- nodeStyle: **optional**, a CSS object, styles this layer's node on the tree +- nodeStyle: **optional**, a CSS object, where the keys are CSS attributes, which styles this layer's node on the tree - tooltip() / tooltipLocked(): **optional** Functions that return text, which is the tooltip for the node when the layer is unlocked or locked, respectively. By default the tooltips behave the same as in the original Prestige Tree. @@ -164,7 +170,7 @@ Key: ```js componentStyles: { - "chall"() {return {'height': '200px'}}, + "challenges"() {return {'height': '200px'}}, "prestige-button"() {return {'color': '#AA66AA'}}, }, ``` diff --git a/docs/milestones.md b/docs/milestones.md index 6f70b04..a8c521c 100644 --- a/docs/milestones.md +++ b/docs/milestones.md @@ -31,10 +31,13 @@ Milestone features: **Tip:** Toggles are not de-set if the milestone becomes locked! In this case, you should also check if the player has the milestone. -- style: **Optional**, A CSS object, which affects this milestone. +- style: **Optional**, Applies CSS to this milestone, in the form of an object where the keys are CSS attributes, + and the values are the values for those attributes (both as strings) -- unl(): A function returning a boolean to determine if the milestone should be shown. If absent, it is always shown. +- unlocked(): **Optional** A function returning a boolean to determine if the milestone should be shown. + If absent, it is always shown. - 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. +- id: **Assigned automagically**. It's the "key" which the milestone was stored under, for convenient access. + The milestone in the example's id is 0. \ No newline at end of file diff --git a/docs/subtabs-and-microtabs.md b/docs/subtabs-and-microtabs.md index 711469a..42d2e7e 100644 --- a/docs/subtabs-and-microtabs.md +++ b/docs/subtabs-and-microtabs.md @@ -44,9 +44,11 @@ Normal subtabs and microtab subtabs both use the same features: - content: The tab layout code for the subtab, in [the tab layout format](custom-tab-layouts.md) -- style: **Optional**, A CSS object, which affects the CSS when in that subtab. +- style: **Optional**, Applies CSS to the whole subtab when switched to, in the form of an "CSS Object", + where the keys are CSS attributes, and the values are the values for those attributes (both as strings) - buttonStyle: **Optional**, A CSS object, which affects the appearance of the button for that subtab. -- unl(): **Optional**, a function to determine if the button for this subtab should be visible. By default, a subtab is always unlocked. +- unlocked(): **Optional**, a function to determine if the button for this subtab should be visible. + By default, a subtab is always unlocked. (You can't use the "this" keyword in this function.) \ No newline at end of file diff --git a/docs/upgrades.md b/docs/upgrades.md index 0071246..3b78ec8 100644 --- a/docs/upgrades.md +++ b/docs/upgrades.md @@ -4,8 +4,8 @@ Upgrades are stored in the following format: Useful functions for dealing with Upgrades and implementing their effects: -- hasUpg(layer, id): determine if the player has the upgrade -- upgEffect(layer, id): Returns the current effects of the upgrade, if any +- hasUpgrade(layer, id): determine if the player has the upgrade +- upgradeEffect(layer, id): Returns the current effects of the upgrade, if any Hint: Basic point gain is calculated in game.js's "getPointGain". @@ -28,7 +28,7 @@ Individual upgrades can have these features: - title: **optional**, displayed at the top in a larger font It can also be a function that returns updating text. Can use basic HTML. -- desc: A description of the upgrade's effect. *You will also have to implement the effect where it is applied.* +- description: A description of the upgrade's effect. *You will also have to implement the effect where it is applied.* It can also be a function that returns updating text. Can use basic HTML. - effect(): **optional**, A function that calculates and returns the current values of any bonuses from the upgrade. @@ -39,7 +39,7 @@ Individual upgrades can have these features: - cost: A Decimal for the cost of the upgrade. By default, upgrades cost the main prestige currency for the layer. -- unl(): A function returning a bool to determine if the upgrade is visible or not. +- unlocked(): **optional**, A function returning a bool to determine if the upgrade is visible or not. Default is unlocked. - onPurchase() - **optional**, this function will be called when the upgrade is purchased. Good for upgrades like "makes this layer act like it was unlocked first". @@ -50,8 +50,10 @@ By default, upgrades use the main prestige currency for the layer. You can inclu - currencyLayer: **optional**, the internal name of the layer that currency is stored in. If it's not in a layer (like Points), omit. -- style: **Optional**, A a CSS object, which affects this upgrade. +- style: **Optional**, Applies CSS to this upgrade, in the form of an object where the keys are CSS attributes, + and the values are the values for those attributes (both as strings) - 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 upgrade. \ No newline at end of file +- id: **Assigned automagically**. It's the "key" which the upgrade was stored under, for convenient access. + The upgrade in the example's id is 11. \ No newline at end of file diff --git a/index.html b/index.html index 0566a11..26e1535 100644 --- a/index.html +++ b/index.html @@ -63,7 +63,7 @@

Time Played: {{ formatTime(player.timePlayed) }}

Hotkeys


-
{{key.desc}}
+
{{key.description}}

@@ -84,7 +84,7 @@
- +


+



 
@@ -134,7 +134,7 @@ - +

diff --git a/js/game.js b/js/game.js index df2dc70..4c953a4 100644 --- a/js/game.js +++ b/js/game.js @@ -23,7 +23,7 @@ let VERSION = { // Determines if it should show points/sec function canGenPoints(){ - return hasUpg("c", 11) + return hasUpgrade("c", 11) } // Calculate points/sec! @@ -32,7 +32,7 @@ function getPointGen() { return new Decimal(0) let gain = new Decimal(1) - if (hasUpg("c", 12)) gain = gain.times(upgEffect("c", 12)) + if (hasUpgrade("c", 12)) gain = gain.times(upgradeEffect("c", 12)) return gain } @@ -72,13 +72,13 @@ function getNextAt(layer, canMax=false, useType = null) { let amt = player[layer].points.plus((canMax&&tmp[layer].baseAmount.gte(tmp[layer].nextAt))?tmp[layer].resetGain:0) let extraCost = Decimal.pow(layers[layer].base, amt.pow(tmp[layer].exponent).div(tmp[layer].gainExp)).times(tmp[layer].gainMult) let cost = extraCost.times(tmp[layer].requires).max(tmp[layer].requires) - if (layers[layer].resCeil) cost = cost.ceil() + if (layers[layer].roundUpCost) cost = cost.ceil() return cost; } else if (type=="normal"){ let next = tmp[layer].resetGain.add(1) if (next.gte("e1e7")) next = next.div("e5e6").pow(2) next = next.root(tmp[layer].gainExp).div(tmp[layer].gainMult).root(tmp[layer].exponent).times(tmp[layer].requires).max(tmp[layer].requires) - if (layers[layer].resCeil) next = next.ceil() + if (layers[layer].roundUpCost) next = next.ceil() return next; } else if (type=="custom"){ return layers[layer].getNextAt(canMax) @@ -90,7 +90,7 @@ function getNextAt(layer, canMax=false, useType = null) { function shouldNotify(layer){ for (id in layers[layer].upgrades){ if (!isNaN(id)){ - if (canAffordUpg(layer, id) && !hasUpg(layer, id) && tmp[layer].upgrades[id].unl){ + if (canAffordUpgrade(layer, id) && !hasUpgrade(layer, id) && tmp[layer].upgrades[id].unlocked){ return true } } @@ -128,7 +128,7 @@ function fullLayerReset(layer) { player[layer] = layers[layer].startData(); player[layer].upgrades = [] player[layer].milestones = [] - player[layer].challs = [] + player[layer].challenges = [] if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)) { if (player.subtabs[layer] == undefined) player.subtabs[layer] = {} if (player.subtabs[layer].mainTabs == undefined) player.subtabs[layer].mainTabs = Object.keys(layers[layer].tabFormat)[0] @@ -180,14 +180,14 @@ function doReset(layer, force=false) { addPoints(layer, gain) updateMilestones(layer) - if (!player[layer].unl) { - player[layer].unl = true; + if (!player[layer].unlocked) { + player[layer].unlocked = true; needCanvasUpdate = true; if (layers[layer].incr_order){ lrs = layers[layer].incr_order for (lr in lrs) - if (!player[lrs[lr]].unl) player[lrs[lr]].order++ + if (!player[lrs[lr]].unlocked) player[lrs[lr]].order++ } } @@ -198,7 +198,7 @@ function doReset(layer, force=false) { for (layerResetting in layers) { - if (row >= layers[layerResetting].row && (!force || layerResetting != layer)) completeChall(layerResetting) + if (row >= layers[layerResetting].row && (!force || layerResetting != layer)) completeChallenge(layerResetting) } prevOnReset = {...player} //Deep Copy @@ -219,7 +219,7 @@ function resetRow(row) { rowReset(row+1, post_layers[0]) doReset(pre_layers[0], true) for (let layer in layers) { - player[layers[layer]].unl = false + player[layers[layer]].unlocked = false if (player[layers[layer]].order) player[layers[layer]].order = 0 } player.points = new Decimal(10) @@ -227,11 +227,11 @@ function resetRow(row) { resizeCanvas(); } -function startChall(layer, x) { +function startChallenge(layer, x) { let enter = false - if (!player[layer].unl) return + if (!player[layer].unlocked) return if (player[layer].active == x) { - completeChall(layer, x) + completeChallenge(layer, x) delete player[layer].active } else { enter = true @@ -239,45 +239,45 @@ function startChall(layer, x) { doReset(layer, true) if(enter) player[layer].active = x - updateChallTemp(layer) + updateChallengeTemp(layer) } -function canCompleteChall(layer, x) +function canCompleteChallenge(layer, x) { if (x != player[layer].active) return - let chall = layers[layer].challs[x] + let challenge = layers[layer].challenges[x] - if (chall.currencyInternalName){ - let name = chall.currencyInternalName - if (chall.currencyLayer){ - let lr = chall.currencyLayer - return !(player[lr][name].lt(readData(chall.goal))) + if (challenge.currencyInternalName){ + let name = challenge.currencyInternalName + if (challenge.currencyLayer){ + let lr = challenge.currencyLayer + return !(player[lr][name].lt(readData(challenge.goal))) } else { - return !(player[name].lt(chall.cost)) + return !(player[name].lt(challenge.cost)) } } else { - return !(player[layer].points.lt(chall.cost)) + return !(player[layer].points.lt(challenge.cost)) } } -function completeChall(layer, x) { +function completeChallenge(layer, x) { var x = player[layer].active if (!x) return - if (! canCompleteChall(layer, x)){ + if (! canCompleteChallenge(layer, x)){ delete player[layer].active return } - if (player[layer].challs[x] < tmp[layer].challs[x].completionLimit) { + if (player[layer].challenges[x] < tmp[layer].challenges[x].completionLimit) { needCanvasUpdate = true - player[layer].challs[x] += 1 - if (layers[layer].challs[x].onComplete) layers[layer].challs[x].onComplete() + player[layer].challenges[x] += 1 + if (layers[layer].challenges[x].onComplete) layers[layer].challenges[x].onComplete() } delete player[layer].active - updateChallTemp(layer) + updateChallengeTemp(layer) } VERSION.withoutName = "v" + VERSION.num + (VERSION.pre ? " Pre-Release " + VERSION.pre : VERSION.pre ? " Beta " + VERSION.beta : "") diff --git a/js/layerSupport.js b/js/layerSupport.js index 1b2c936..7647d93 100644 --- a/js/layerSupport.js +++ b/js/layerSupport.js @@ -36,8 +36,8 @@ function updateLayers(){ if (!isNaN(thing)){ layers[layer].upgrades[thing].id = thing layers[layer].upgrades[thing].layer = layer - if (layers[layer].upgrades[thing].unl === undefined) - layers[layer].upgrades[thing].unl = true + if (layers[layer].upgrades[thing].unlocked === undefined) + layers[layer].upgrades[thing].unlocked = true } } } @@ -46,20 +46,20 @@ function updateLayers(){ if (!isNaN(thing)){ layers[layer].milestones[thing].id = thing layers[layer].milestones[thing].layer = layer - if (layers[layer].milestones[thing].unl === undefined) - layers[layer].milestones[thing].unl = true + if (layers[layer].milestones[thing].unlocked === undefined) + layers[layer].milestones[thing].unlocked = true } } } - if (layers[layer].challs){ - for (thing in layers[layer].challs){ + if (layers[layer].challenges){ + for (thing in layers[layer].challenges){ if (!isNaN(thing)){ - layers[layer].challs[thing].id = thing - layers[layer].challs[thing].layer = layer - if (layers[layer].challs[thing].unl === undefined) - layers[layer].challs[thing].unl = true - if (layers[layer].challs[thing].completionLimit === undefined) - layers[layer].challs[thing].completionLimit = 1 + layers[layer].challenges[thing].id = thing + layers[layer].challenges[thing].layer = layer + if (layers[layer].challenges[thing].unlocked === undefined) + layers[layer].challenges[thing].unlocked = true + if (layers[layer].challenges[thing].completionLimit === undefined) + layers[layer].challenges[thing].completionLimit = 1 } } @@ -70,8 +70,8 @@ function updateLayers(){ if (!isNaN(thing)){ layers[layer].buyables[thing].id = thing layers[layer].buyables[thing].layer = layer - if (layers[layer].buyables[thing].unl === undefined) - layers[layer].buyables[thing].unl = true + if (layers[layer].buyables[thing].unlocked === undefined) + layers[layer].buyables[thing].unlocked = true } } } @@ -82,8 +82,8 @@ function updateLayers(){ if (!isNaN(thing)){ layers[layer].clickables[thing].id = thing layers[layer].clickables[thing].layer = layer - if (layers[layer].clickables[thing].unl === undefined) - layers[layer].clickables[thing].unl = true + if (layers[layer].clickables[thing].unlocked === undefined) + layers[layer].clickables[thing].unlocked = true } } } @@ -94,8 +94,8 @@ function updateLayers(){ if (!isNaN(thing)){ layers[layer].bars[thing].id = thing layers[layer].bars[thing].layer = layer - if (layers[layer].bars[thing].unl === undefined) - layers[layer].bars[thing].unl = true + if (layers[layer].bars[thing].unlocked === undefined) + layers[layer].bars[thing].unlocked = true } } } @@ -134,7 +134,7 @@ function readData(data, args=null){ function someLayerUnlocked(row){ for (layer in ROW_LAYERS[row]) - if (player[layer].unl) + if (player[layer].unlocked) return true return false } diff --git a/js/layers.js b/js/layers.js index e500f2a..766b58a 100644 --- a/js/layers.js +++ b/js/layers.js @@ -4,7 +4,7 @@ addLayer("c", { symbol: "C", // 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 { - unl: true, + unlocked: true, points: new Decimal(0), best: new Decimal(0), total: new Decimal(0), @@ -19,12 +19,12 @@ addLayer("c", { type: "normal", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have exponent: 0.5, // Prestige currency exponent base: 5, // Only needed for static layers, base of the formula (b^(x^exp)) - resCeil: false, // True if the cost needs to be rounded up (use when baseResource is static?) + roundUpCost: false, // True if the cost needs to be rounded up (use when baseResource is static?) canBuyMax() {}, // Only needed for static layers with buy max gainMult() { // Calculate the multiplier for main currency from bonuses mult = new Decimal(1) - if (hasUpg(this.layer, 166)) mult = mult.times(2) // These upgrades don't exist - if (hasUpg(this.layer, 120)) mult = mult.times(upgEffect(this.layer, 120)) + if (hasUpgrade(this.layer, 166)) mult = mult.times(2) // These upgrades don't exist + if (hasUpgrade(this.layer, 120)) mult = mult.times(upgradeEffect(this.layer, 120)) return mult }, gainExp() { // Calculate the exponent on main currency from bonuses @@ -42,14 +42,14 @@ addLayer("c", { return "which are boosting waffles by "+format(eff.waffleBoost)+" and increasing the Ice Cream cap by "+format(eff.icecreamCap) }, milestones: { - 0: {requirementDesc:() => "3 Lollipops", + 0: {requirementDescription:() => "3 Lollipops", done() {return player[this.layer].best.gte(3)}, // Used to determine when to give the milestone - effectDesc:() => "Unlock the next milestone", + effectDescription:() => "Unlock the next milestone", }, - 1: {requirementDesc:() => "4 Lollipops", - unl() {return hasMilestone(this.layer, 0)}, + 1: {requirementDescription:() => "4 Lollipops", + unlocked() {return hasMilestone(this.layer, 0)}, done() {return player[this.layer].best.gte(4)}, - effectDesc:() => "You can toggle beep and boop (which do nothing)", + effectDescription:() => "You can toggle beep and boop (which do nothing)", toggles: [ ["c", "beep"], // Each toggle is defined by a layer and the data toggled for that layer ["f", "boop"]], @@ -60,25 +60,25 @@ addLayer("c", { }, }, - challs: { + challenges: { rows: 2, cols: 12, 11: { name:() => "Fun", completionLimit: 3, - desc() {return "Makes the game 0% harder
"+challCompletions(this.layer, this.id) + "/" + this.completionLimit + " completions"}, - unl() { return player[this.layer].best.gt(0) }, + challengeDescription() {return "Makes the game 0% harder
"+challengeCompletions(this.layer, this.id) + "/" + this.completionLimit + " completions"}, + unlocked() { return player[this.layer].best.gt(0) }, goal:() => new Decimal("20"), currencyDisplayName: "lollipops", // Use if using a nonstandard currency currencyInternalName: "points", // Use if using a nonstandard currency currencyLayer: this.layer, // Leave empty if not in a layer - effect() { + rewardEffect() { let ret = player[this.layer].points.add(1).tetrate(0.02) return ret; }, - effectDisplay(x) { return format(x)+"x" }, + rewardDisplay() { return format(this.rewardEffect())+"x" }, countsAs: [12, 21], // Use this for if a challenge includes the effects of other challenges. Being in this challenge "counts as" being in these. - reward:() => "Says hi", + rewardDescription: "Says hi", onComplete() {console.log("hiii")} // Called when you complete the challenge }, }, @@ -87,14 +87,14 @@ addLayer("c", { cols: 3, 11: { title:() => "Generator of Genericness", - desc:() => "Gain 1 Point every second.", + description:() => "Gain 1 Point every second.", cost:() => new Decimal(1), - unl() { return player[this.layer].unl }, // The upgrade is only visible when this is true + unlocked() { return player[this.layer].unlocked }, // The upgrade is only visible when this is true }, 12: { - desc:() => "Candy generation is faster based on your unspent Lollipops.", + description:() => "Candy generation is faster based on your unspent Lollipops.", cost:() => new Decimal(1), - unl() { return (hasUpg(this.layer, 11))}, + unlocked() { return (hasUpgrade(this.layer, 11))}, effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values let ret = player[this.layer].points.add(1).pow(player[this.layer].upgrades.includes(24)?1.1:(player[this.layer].upgrades.includes(14)?0.75:0.5)) if (ret.gte("1e20000000")) ret = ret.sqrt().times("1e10000000") @@ -103,20 +103,20 @@ addLayer("c", { effectDisplay() { return format(this.effect())+"x" }, // Add formatting to the effect }, 13: { - desc:() => "Unlock a secret subtab and make this layer act if you unlocked it first.", + description:() => "Unlock a secret subtab and make this layer act if you unlocked it first.", cost:() => new Decimal(69), currencyDisplayName: "candies", // Use if using a nonstandard currency currencyInternalName: "points", // Use if using a nonstandard currency currencyLayer: "", // Leave empty if not in a layer "e.g. points" - unl() { return (hasUpg(this.layer, 12))}, + unlocked() { return (hasUpgrade(this.layer, 12))}, onPurchase() { // This function triggers when the upgrade is purchased player[this.layer].order = 0 }, style() { - if (hasUpg(this.layer, this.id)) return { + if (hasUpgrade(this.layer, this.id)) return { 'background-color': '#1111dd' } - else if (!canAffordUpg(this.layer, this.id)) { + else if (!canAffordUpgrade(this.layer, this.id)) { return { 'background-color': '#dd1111' } @@ -125,9 +125,9 @@ addLayer("c", { }, 22: { title:() => "This upgrade doesn't exist", - desc:() => "Or does it?.", - cost:() => new Decimal(1), - unl() { return player[this.layer].unl }, // The upgrade is only visible when this is true + description:() => "Or does it?.", + cost:() => new Decimal(3), + unlocked() { return player[this.layer].unlocked }, // The upgrade is only visible when this is true }, }, buyables: { @@ -161,7 +161,7 @@ addLayer("c", { Amount: " + player[this.layer].buyables[this.id] + "\n\ Adds + " + format(data.effect.first) + " things and multiplies stuff by " + format(data.effect.second) }, - unl() { return player[this.layer].unl }, + unlocked() { return player[this.layer].unlocked }, canAfford() { return player[this.layer].points.gte(tmp[this.layer].buyables[this.id].cost)}, buy() { @@ -186,8 +186,8 @@ addLayer("c", { }, // Useful for if you gain secondary resources or have other interesting things happen to this layer when you reset it. You gain the currency after this function ends. hotkeys: [ - {key: "c", desc: "C: reset for lollipops or whatever", onPress(){if (player[this.layer].unl) doReset(this.layer)}}, - {key: "ctrl+c" + this.layer, desc: "Ctrl+c: respec things", onPress(){if (player[this.layer].unl) respecBuyables(this.layer)}}, + {key: "c", description: "C: reset for lollipops or whatever", onPress(){if (player[this.layer].unlocked) doReset(this.layer)}}, + {key: "ctrl+c" + this.layer, description: "Ctrl+c: respec things", onPress(){if (player[this.layer].unlocked) respecBuyables(this.layer)}}, ], incr_order: [], // Array of layer names to have their order increased when this one is first unlocked @@ -224,7 +224,7 @@ addLayer("c", { display() { return format(player.points) + " / 1e10 points" }, - unl:() => true, + unlocked:() => true, }, tallBoi: { @@ -242,7 +242,7 @@ addLayer("c", { display() { return formatWhole((player.points.div(1)).min(100)) + "%" }, - unl:() => true, + unlocked:() => true, }, flatBoi: { @@ -257,7 +257,7 @@ addLayer("c", { progress() { return player.c.points.div(50) }, - unl:() => true, + unlocked:() => true, }, }, @@ -274,7 +274,7 @@ addLayer("c", { ["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"], + "h-line", "milestones", "blank", "upgrades", "challenges"], }, thingies: { style() {return {'background-color': '#222222'}}, @@ -309,7 +309,7 @@ addLayer("c", { ], }, illuminati: { - unl() {return (hasUpg("c", 13))}, + unlocked() {return (hasUpgrade("c", 13))}, content:[ ["raw-html", function() {return "

C O N F I R M E D

"}], "blank", ["microtabs", "stuff", {'width': '600px', 'height': '350px', 'background-color': 'brown', 'border-style': 'solid'}] @@ -325,7 +325,7 @@ addLayer("c", { 'text-decoration': 'underline' }}, componentStyles: { - "chall"() {return {'height': '200px'}}, + "challenge"() {return {'height': '200px'}}, "prestige-button"() {return {'color': '#AA66AA'}}, }, tooltip() { // Optional, tooltip displays when the layer is unlocked @@ -337,13 +337,13 @@ addLayer("c", { // Layer will automatically highlight if an upgrade is purchasable. return (player.c.buyables[11] == 1) }, - resetDesc: "Melt your points into ", + resetDescription: "Melt your points into ", }) // This layer is mostly minimal but it uses a custom prestige type and a clickable addLayer("f", { startData() { return { - unl: false, + unlocked: false, points: new Decimal(0), boop: false, clickables: {[11]: "Start"} // Optional default Clickable state @@ -356,7 +356,7 @@ addLayer("f", { type: "custom", // A "Custom" type which is effectively static exponent: 0.5, base: 3, - resCeil: true, + roundUpCost: true, canBuyMax:() => true, gainMult() { return new Decimal(1) @@ -391,16 +391,6 @@ addLayer("f", { canReset() { return tmp[this.layer].baseAmount.gte(tmp[this.layer].nextAt) }, - upgrades: { - rows: 1, - cols: 1, - 11: { - title:() => "Generator", - cost:() => new Decimal(1), - desc:() => "Gain 1 point per second", - } - - }, // This is also non minimal, a Clickable! clickables: { rows: 1, @@ -416,7 +406,7 @@ addLayer("f", { let data = getClickableState(this.layer, this.id) return "Current state:
" + data }, - unl() { return player[this.layer].unl }, + unlocked() { return player[this.layer].unlocked }, canClick() { return getClickableState(this.layer, this.id) !== "Borkened..."}, onClick() { diff --git a/js/temp.js b/js/temp.js index 7592ab2..ebbb0e0 100644 --- a/js/temp.js +++ b/js/temp.js @@ -81,9 +81,9 @@ function updateTempData(layerData, tmpData) { } } -function updateChallTemp(layer) +function updateChallengeTemp(layer) { - updateTempData(layers[layer].challs, tmp[layer].challs) + updateTempData(layers[layer].challenges, tmp[layer].challenges) } function updateBuyableTemp(layer) diff --git a/js/utils.js b/js/utils.js index d467b04..81fdc50 100644 --- a/js/utils.js +++ b/js/utils.js @@ -78,7 +78,7 @@ function startPlayerBase() { timePlayed: 0, keepGoing: false, hasNaN: false, - hideChalls: false, + hideChallenges: false, points: new Decimal(10), subtabs: {}, } @@ -93,7 +93,7 @@ function getStartPlayer() { playerdata[layer].spentOnBuyables = new Decimal(0) playerdata[layer].upgrades = [] playerdata[layer].milestones = [] - playerdata[layer].challs = getStartChalls(layer) + playerdata[layer].challenges = getStartChallenges(layer) if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)) { playerdata.subtabs[layer] = {} playerdata.subtabs[layer].mainTabs = Object.keys(layers[layer].tabFormat)[0] @@ -128,10 +128,10 @@ function getStartClickables(layer){ return data } -function getStartChalls(layer){ +function getStartChallenges(layer){ let data = {} - if (layers[layer].challs) { - for (id in layers[layer].challs) + if (layers[layer].challenges) { + for (id in layers[layer].challenges) if (!isNaN(id)) data[id] = 0 } @@ -354,13 +354,13 @@ function respecBuyables(layer) { updateBuyableTemp(layer) } -function canAffordUpg(layer, id) { +function canAffordUpgrade(layer, id) { let upg = layers[layer].upgrades[id] let cost = tmp[layer].upgrades[id].cost return canAffordPurchase(layer, upg, cost) } -function hasUpg(layer, id){ +function hasUpgrade(layer, id){ return (player[layer].upgrades.includes(toNumber(id)) || player[layer].upgrades.includes(id.toString())) } @@ -368,19 +368,19 @@ function hasMilestone(layer, id){ return (player[layer].milestones.includes(toNumber(id)) || player[layer].milestones.includes(id.toString())) } -function hasChall(layer, id){ - return (player[layer].challs[id]) +function hasChallenge(layer, id){ + return (player[layer].challenges[id]) } -function challCompletions(layer, id){ - return (player[layer].challs[id]) +function challengeCompletions(layer, id){ + return (player[layer].challenges[id]) } -function getBuyableAmt(layer, id){ +function getBuyableAmount(layer, id){ return (player[layer].buyables[id]) } -function setBuyableAmt(layer, id, amt){ +function setBuyableAmount(layer, id, amt){ player[layer].buyables[id] = amt } @@ -392,12 +392,12 @@ function setClickableState(layer, id, state){ player[layer].clickables[id] = state } -function upgEffect(layer, id){ +function upgradeEffect(layer, id){ return (tmp[layer].upgrades[id].effect) } -function challEffect(layer, id){ - return (tmp[layer].challs[id].effect) +function challengeEffect(layer, id){ + return (tmp[layer].challenges[id].effect) } function buyableEffect(layer, id){ @@ -422,8 +422,8 @@ function canAffordPurchase(layer, thing, cost) { } function buyUpg(layer, id) { - if (!player[layer].unl) return - if (!layers[layer].upgrades[id].unl) return + if (!player[layer].unlocked) return + if (!layers[layer].upgrades[id].unlocked) return if (player[layer].upgrades.includes(id)) return let upg = layers[layer].upgrades[id] let cost = tmp[layer].upgrades[id].cost @@ -450,8 +450,8 @@ function buyUpg(layer, id) { } function buyMaxBuyable(layer, id) { - if (!player[layer].unl) return - if (!tmp[layer].buyables[id].unl) return + if (!player[layer].unlocked) return + if (!tmp[layer].buyables[id].unlocked) return if (!tmp[layer].buyables[id].canAfford) return if (!layers[layer].buyables[id].buyMax) return @@ -460,8 +460,8 @@ function buyMaxBuyable(layer, id) { } function buyBuyable(layer, id) { - if (!player[layer].unl) return - if (!tmp[layer].buyables[id].unl) return + if (!player[layer].unlocked) return + if (!tmp[layer].buyables[id].unlocked) return if (!tmp[layer].buyables[id].canAfford) return layers[layer].buyables[id].buy() @@ -469,8 +469,8 @@ function buyBuyable(layer, id) { } function clickClickable(layer, id) { - if (!player[layer].unl) return - if (!tmp[layer].clickables[id].unl) return + if (!player[layer].unlocked) return + if (!tmp[layer].clickables[id].unlocked) return if (!tmp[layer].clickables[id].canClick) return layers[layer].clickables[id].onClick() @@ -479,18 +479,18 @@ function clickClickable(layer, id) { // Function to determine if the player is in a challenge function inChallenge(layer, id){ - let chall = player[layer].active - if (chall==toNumber(id)) return true + let challenge = player[layer].active + if (challenge==toNumber(id)) return true - if (layers[layer].challs[chall].countsAs) - return layers[layer].challs[id].countsAs.includes(id) + if (layers[layer].challenges[challenge].countsAs) + return layers[layer].challenges[id].countsAs.includes(id) } // ************ Misc ************ var onTreeTab = true function showTab(name) { - if (LAYERS.includes(name) && !layerUnl(name)) return + if (LAYERS.includes(name) && !layerunlocked(name)) return var toTreeTab = name == "tree" player.tab = name @@ -504,7 +504,7 @@ function showTab(name) { } function notifyLayer(name) { - if (player.tab == name || !layerUnl(name)) return + if (player.tab == name || !layerunlocked(name)) return player.notify[name] = 1 } @@ -512,14 +512,14 @@ function nodeShown(layer) { if (tmp[layer].layerShown) return true switch(layer) { case "idk": - return player.l.unl + return player.l.unlocked break; } return false } -function layerUnl(layer) { - return LAYERS.includes(layer) && (player[layer].unl || (tmp[layer].baseAmount.gte(tmp[layer].requires) && layers[layer].layerShown())) +function layerunlocked(layer) { + return LAYERS.includes(layer) && (player[layer].unlocked || (tmp[layer].baseAmount.gte(tmp[layer].requires) && layers[layer].layerShown())) } function keepGoing() { @@ -574,7 +574,7 @@ document.onkeydown = function(e) { if (onFocused) return if (ctrlDown && key != "-" && key != "_" && key != "+" && key != "=" && key != "r" && key != "R" && key != "F5") e.preventDefault() if(hotkeys[key]){ - if (player[hotkeys[key].layer].unl) + if (player[hotkeys[key].layer].unlocked) hotkeys[key].onPress() } } @@ -587,9 +587,9 @@ function focused(x) { function prestigeButtonText(layer) { if(tmp[layer].type == "normal") - return `${ player[layer].points.lt(1e3) ? (tmp[layer].resetDesc !== undefined ? tmp[layer].resetDesc : "Reset for ") : ""}+${formatWhole(tmp[layer].resetGain)} ${tmp[layer].resource} ${tmp[layer].resetGain.lt(100) && player[layer].points.lt(1e3) ? `

Next at ${ (tmp[layer].resCeil ? formatWhole(tmp[layer].nextAt) : format(tmp[layer].nextAt))}` : ""} ${ tmp[layer].baseResource }` + return `${ player[layer].points.lt(1e3) ? (tmp[layer].resetDescription !== undefined ? tmp[layer].resetDescription : "Reset for ") : ""}+${formatWhole(tmp[layer].resetGain)} ${tmp[layer].resource} ${tmp[layer].resetGain.lt(100) && player[layer].points.lt(1e3) ? `

Next at ${ (tmp[layer].roundUpCost ? formatWhole(tmp[layer].nextAt) : format(tmp[layer].nextAt))}` : ""} ${ tmp[layer].baseResource }` else if(tmp[layer].type== "static") - return `${tmp[layer].resetDesc !== undefined ? tmp[layer].resetDesc : "Reset for "}+${formatWhole(tmp[layer].resetGain)} ${tmp[layer].resource}

${player[layer].points.lt(20) ? (tmp[layer].baseAmount.gte(tmp[layer].nextAt)&&(tmp[layer].canBuyMax !== undefined) && tmp[layer].canBuyMax?"Next":"Req") : ""}: ${formatWhole(tmp[layer].baseAmount)} / ${(tmp[layer].resCeil ? formatWhole(tmp[layer].nextAtDisp) : format(tmp[layer].nextAtDisp))} ${ tmp[layer].baseResource } + return `${tmp[layer].resetDescription !== undefined ? tmp[layer].resetDescription : "Reset for "}+${formatWhole(tmp[layer].resetGain)} ${tmp[layer].resource}

${player[layer].points.lt(20) ? (tmp[layer].baseAmount.gte(tmp[layer].nextAt)&&(tmp[layer].canBuyMax !== undefined) && tmp[layer].canBuyMax?"Next":"Req") : ""}: ${formatWhole(tmp[layer].baseAmount)} / ${(tmp[layer].roundUpCost ? formatWhole(tmp[layer].nextAtDisp) : format(tmp[layer].nextAtDisp))} ${ tmp[layer].baseResource } ` else return layers[layer].prestigeButtonText() diff --git a/js/v.js b/js/v.js index 69c21a4..72f55ae 100644 --- a/js/v.js +++ b/js/v.js @@ -86,13 +86,13 @@ function loadVue() { ` }) - Vue.component('challs', { + Vue.component('challenges', { props: ['layer'], template: ` -
-
-
- +
+
+
+
@@ -100,16 +100,16 @@ function loadVue() { }) // data = id - Vue.component('chall', { + Vue.component('challenge', { props: ['layer', 'data'], template: ` -
-



-

-
- Goal: {{format(tmp[layer].challs[data].goal)}} {{tmp[layer].challs[data].currencyDisplayName ? tmp[layer].challs[data].currencyDisplayName : "points"}}
- Reward:
- Currently: +
+



+

+
+ Goal: {{format(tmp[layer].challenges[data].goal)}} {{tmp[layer].challenges[data].currencyDisplayName ? tmp[layer].challenges[data].currencyDisplayName : "points"}}
+ Reward:
+ Currently:
` }) @@ -119,7 +119,7 @@ function loadVue() { template: `
-
+
@@ -132,10 +132,10 @@ function loadVue() { Vue.component('upgrade', { props: ['layer', 'data'], template: ` - @@ -147,7 +147,7 @@ function loadVue() { template: `
-
@@ -160,9 +160,9 @@ function loadVue() { Vue.component('milestone', { props: ['layer', 'data'], template: ` - -


-
+ +


+
  ` }) @@ -199,9 +199,9 @@ function loadVue() { props: ['layer', 'data'], template: `
-
+
-
+

@@ -215,7 +215,7 @@ function loadVue() { props: ['layer', 'data', 'size'], template: `
+
-
+

@@ -247,7 +247,7 @@ function loadVue() { props: ['layer', 'data', 'size'], template: ` +
` @@ -313,18 +313,18 @@ function loadVue() { showTab(layer) }" v-bind:tooltip=" - player[layer].unl ? (tmp[layer].tooltip ? tmp[layer].tooltip : formatWhole(player[layer].points) + ' ' + tmp[layer].resource) + player[layer].unlocked ? (tmp[layer].tooltip ? tmp[layer].tooltip : formatWhole(player[layer].points) + ' ' + tmp[layer].resource) : (tmp[layer].tooltipLocked ? tmp[layer].tooltipLocked : 'Reach ' + formatWhole(tmp[layer].requires) + ' ' + tmp[layer].baseResource + ' to unlock (You have ' + formatWhole(tmp[layer].baseAmount) + ' ' + tmp[layer].baseResource + ')') " v-bind:class="{ treeNode: true, [layer]: true, hidden: !tmp[layer].layerShown, - locked: !player[layer].unl && !tmp[layer].baseAmount.gte(tmp[layer].requires), + locked: !player[layer].unlocked && !tmp[layer].baseAmount.gte(tmp[layer].requires), notify: tmp[layer].notify, - can: layerUnl(layer), + can: layerunlocked(layer), }" - v-bind:style="[layerUnl(layer) ? { + v-bind:style="[layerunlocked(layer) ? { 'background-color': tmp[layer].color, } : {}, tmp[layer].nodeStyle]"> {{abb}} @@ -344,10 +344,10 @@ function loadVue() { formatTime, focused, getThemeName, - layerUnl, + layerunlocked, doReset, buyUpg, - startChall, + startChallenge, milestoneShown, keepGoing, VERSION, diff --git a/style.css b/style.css index 6dc272b..0ae3521 100644 --- a/style.css +++ b/style.css @@ -428,7 +428,7 @@ ul { list-style-type: none; } -.hChall { +.hChallenge { background-color: #bf8f8f; border: 4px solid; border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125); @@ -439,11 +439,11 @@ ul { border-radius: 33.33%; } -.hChall.done { +.hChallenge.done { background-color: #77bf5f; } -.hChall.canComplete { +.hChallenge.canComplete { background-color: #ffbf00; } From 95e1fc2ff058af794dceaed3ce53328359d3ea21 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Mon, 12 Oct 2020 23:28:02 -0400 Subject: [PATCH 19/33] Added documentation for bars, fixes in other docs --- docs/bars.md | 39 +++++++++++++++++++++++++++++++++++ docs/basic-layer-breakdown.md | 1 - docs/buyables.md | 2 +- docs/challenges.md | 2 +- docs/clickables.md | 2 +- docs/milestones.md | 2 +- docs/upgrades.md | 2 +- js/layerSupport.js | 11 +++++----- js/layers.js | 2 +- js/temp.js | 6 ++++-- 10 files changed, 54 insertions(+), 15 deletions(-) create mode 100644 docs/bars.md diff --git a/docs/bars.md b/docs/bars.md new file mode 100644 index 0000000..6cbb85a --- /dev/null +++ b/docs/bars.md @@ -0,0 +1,39 @@ +# Buyables + +Bars let you display information in a more direct way. It can be a progress bar, health bar, capacity gague, or anything else. + +Bars are defined like other Big Features: + +```js + bars: { + bigBar: { + display() {return "Blah"}, + etc + } + etc + } +``` + +Features: + +- direction: UP, DOWN, LEFT, or RIGHT (not Strings). Determines the direction that the bar is filled as it progresses. + RIGHT means from left to right. + +- width, height: The size in pixels of the bar, but as Numbers (no "px" at the end) + +- progress(): A function that returns the portion of the bar that is filled, from "empty" at 0 to "full" at 1. + (Nothing bad happens if the value goes out of these bounds, and it can be a number or Decimal). + +- display(): **optional**, A function that returns text to be displayed on top of the bar, can use HTML. + +- unlocked(): **optional**, A function returning a bool to determine if the buyable is visible or not. Default is unlocked. + +- baseStyle, fillStyle, borderStyle, textStyle: **Optional**, Apply CSS to the unfilled portion, filled portion, border, and + display text on the bar, in the form of an object where the keys are CSS attributes, and the values are the + values for those attributes (both as strings). + + +- 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 "key" which the bar was stored under, for convenient access. + The bar in the example's id is "bigBar". \ No newline at end of file diff --git a/docs/basic-layer-breakdown.md b/docs/basic-layer-breakdown.md index 43d7696..a9cf954 100644 --- a/docs/basic-layer-breakdown.md +++ b/docs/basic-layer-breakdown.md @@ -8,7 +8,6 @@ This is a very minimal layer with minimal features. Most things will require add startData() { return { // startData is a function that returns default data for a layer. unlocked: false, // You can add more variables here to add them to your layer. points: new Decimal(0), // "points" is the internal name for the main resource of the layer. - // If you add non-standard Decimal variables, look at convertToDecimal }}, color: "#FE0102", // The color for this layer, which affects many elements diff --git a/docs/buyables.md b/docs/buyables.md index b3976db..2422a37 100644 --- a/docs/buyables.md +++ b/docs/buyables.md @@ -17,7 +17,7 @@ Buyables should be formatted like this: Having this function makes a respec button appear respecText: **optional**, text that appears on the respec button 11: { - display:() => "Blah", + display() {return "Blah"}, etc } etc diff --git a/docs/challenges.md b/docs/challenges.md index bb48509..7023ce6 100644 --- a/docs/challenges.md +++ b/docs/challenges.md @@ -15,7 +15,7 @@ Challenges are stored in the following format: rows: # of rows cols: # of columns 11: { - name:() => "Ouch", + name: "Ouch", etc } etc diff --git a/docs/clickables.md b/docs/clickables.md index 9874f19..d2590ed 100644 --- a/docs/clickables.md +++ b/docs/clickables.md @@ -20,7 +20,7 @@ Clickables should be formatted like this: // pressing it will call the function. masterButtonText: "Press me!" // **optional** text to display on the Master Button 11: { - desc:() => "Blah", + display() {return "Blah"}, etc } etc diff --git a/docs/milestones.md b/docs/milestones.md index a8c521c..615abab 100644 --- a/docs/milestones.md +++ b/docs/milestones.md @@ -5,7 +5,7 @@ Milestones should be formatted like this: ```js milestones: { 0: { - requirementDesc:() => "123 waffles", + requirementDesc: "123 waffles", } etc } diff --git a/docs/upgrades.md b/docs/upgrades.md index 3b78ec8..0784210 100644 --- a/docs/upgrades.md +++ b/docs/upgrades.md @@ -15,7 +15,7 @@ Hint: Basic point gain is calculated in game.js's "getPointGain". rows: # of rows cols: # of columns 11: { - desc:() => "Blah", + desc: "Blah", more features } etc diff --git a/js/layerSupport.js b/js/layerSupport.js index 7647d93..26bd62e 100644 --- a/js/layerSupport.js +++ b/js/layerSupport.js @@ -91,12 +91,11 @@ function updateLayers(){ if (layers[layer].bars){ layers[layer].bars.layer = layer for (thing in layers[layer].bars){ - if (!isNaN(thing)){ - layers[layer].bars[thing].id = thing - layers[layer].bars[thing].layer = layer - if (layers[layer].bars[thing].unlocked === undefined) - layers[layer].bars[thing].unlocked = true - } + layers[layer].bars[thing].id = thing + layers[layer].bars[thing].layer = layer + if (layers[layer].bars[thing].unlocked === undefined) + layers[layer].bars[thing].unlocked = true + } } diff --git a/js/layers.js b/js/layers.js index 766b58a..77b97f0 100644 --- a/js/layers.js +++ b/js/layers.js @@ -305,7 +305,7 @@ addLayer("c", { ["blank", ['0', '50px']], ["bar", "flatBoi"] ]], ]], - "blank", ["display-text", "It's because bars! So funny! Ha ha!"], + "blank", ["display-text", "It's jail because \"bars\"! So funny! Ha ha!"], ], }, illuminati: { diff --git a/js/temp.js b/js/temp.js index ebbb0e0..b15a124 100644 --- a/js/temp.js +++ b/js/temp.js @@ -107,6 +107,8 @@ function constructBarStyles(layer){ let bar = tmp[layer].bars[id] if (bar.progress instanceof Decimal) bar.progress = bar.progress.toNumber() + bar.progress = Math.min(Math.max(bar.progress, 0), 1) + bar.dims = {'width': bar.width + "px", 'height': bar.height + "px"} let dir = bar.direction bar.fillDims = {'width': bar.width + "px", 'height': bar.height + "px"} @@ -115,12 +117,12 @@ function constructBarStyles(layer){ bar.fillDims[DIR_MARGINS[dir]] = "0px" if (dir == UP || dir == DOWN) { - bar.fillDims.height = bar.height * Math.min(bar.progress, 1) + "px" + bar.fillDims.height = bar.height * bar.progress + "px" if (dir == UP) bar.fillDims['margin-top'] = bar.height * (1 - Math.min(bar.progress, 1)) + "px" } else { - bar.fillDims.width = bar.width * Math.min(bar.progress, 1) + "px" + bar.fillDims.width = bar.width * bar.progress + "px" if (dir == LEFT) bar.fillDims['margin-left'] = bar.width * (1 - Math.min(bar.progress, 1)) + "px" } } From 99d269b2d0b5ab3d8dff7c18b557337e8028419a Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Tue, 13 Oct 2020 18:56:17 -0400 Subject: [PATCH 20/33] Changed fullLayerReset to resetLayerData with ways to keep things --- changelog.md | 4 ++-- docs/!general-info.md | 10 ++++++++-- docs/custom-tab-layouts.md | 2 ++ docs/layer-features.md | 11 ++++++++--- js/game.js | 35 +++++++++++++++++++---------------- js/layers.js | 2 +- js/utils.js | 2 +- 7 files changed, 41 insertions(+), 25 deletions(-) diff --git a/changelog.md b/changelog.md index 55909f8..efadcd1 100644 --- a/changelog.md +++ b/changelog.md @@ -1,8 +1,8 @@ #The Modding Tree changelog: ##v2.0 -Added Progress bars, which are highly customizable and can be horizontal or vertical. -Added clickables, a more generalized variant of buyables! +Added progress bars, which are highly customizable and can be horizontal or vertical! +Added clickables, a more generalized variant of buyables. Support for multiple completions of challenges. Added getter/setter functions for buyable amount and such Moved modInfo to game.js, added a spot for a Discord link, changelog link, and a separate mod version from the TMT version diff --git a/docs/!general-info.md b/docs/!general-info.md index 0b9507c..f5a7287 100644 --- a/docs/!general-info.md +++ b/docs/!general-info.md @@ -2,10 +2,12 @@ The main way to add content is through creating layers. You can either add a layer directly in the layers object in layersSupportjs, or declare it in another file and then do "`addLayer(layername, layerdata)`" (good for breaking things up into smaller files). The existing layers are just examples and can be freely deleted. -You can use those as references and a base for your own layers. +You can also use them as references and a base for your own layers. -**You will also need to add layer nodes to the tree in the HTML, look for where it says "Modify the tree in the table below!"** While you're there, you can also edit the modInfo at the top to change the name for your mod and some other settings. A unique modId will prevent your mod's saves from conflicting with other mods. +The first thing you need to do is to edit the modInfo at the top of game.js to set your modID (a string). A +unique modId will prevent your mod's saves from conflicting with other mods. + Most of the time, you won't need to dive deep into the code to create things, but you still can if you really want to. @@ -15,6 +17,10 @@ The Modding Tree uses break_eternity.js to store large values. This means that m and must be treated differently. For example, you have to use `new Decimal(x)` to create a Decimal value instead of a plain number, and perform operations on them by calling functions. e.g, instead of `x = x + y`, use `x = x.add(y)`. +Almost all values can be either a constant value, or a dynamic value. Dynamic values are defined by putting a function +that returns what the value should be at any given time. + +All display text can be basic HTML instead (But you can't use most Vue features there). ## Table of Contents: diff --git a/docs/custom-tab-layouts.md b/docs/custom-tab-layouts.md index 7106f37..b387dbb 100644 --- a/docs/custom-tab-layouts.md +++ b/docs/custom-tab-layouts.md @@ -25,6 +25,8 @@ These are the existing components, but you can create more in v.js: - display-text: Displays some text (can use basic HTML). The argument is the text to display. It can also be a function that returns updating text. +- raw-html: Displays some basic HTML, can also be a function. + - blank: Adds empty space. The default dimensions are 8px x 17px. The argument changes the dimensions. If it's a single value (e.g. "20px"), that determines the height. If you have a pair of arguments, the first is width and the second is height. diff --git a/docs/layer-features.md b/docs/layer-features.md index e57b557..1f098f4 100644 --- a/docs/layer-features.md +++ b/docs/layer-features.md @@ -145,9 +145,14 @@ Key: # Other features - doReset(resettingLayer): **optional**, is triggered when a layer on a row greater than or equal to this one does a reset. - If you use it, you can choose what to keep via milestones and such. - Without it, the default is to reset everything on the row, but only - if it was triggered by a layer in a higher row. + The default behavior is to reset everything on the row, but only if it was triggered by a layer in a higher row. + + If you want to keep things, determine what to keep based on the resettingLayer, milestones, and such, then call + resetLayerData(layer, keep), where layer is this layer, and keep is an array of the names of things to keep. + It can include things like "points", "best", "total" (for this layer's prestige currency), "upgrades", + any unique variables like "generatorPower", etc. + If you want to only keep specific upgrades or something like that, save them in a separate variable, then + call resetLayerData, and then set player[layer].upgrades to the saved upgrades. - update(diff): **optional**, this function is called every game tick. Use it for any passive resource production or time-based things. diff is the time since the last tick. diff --git a/js/game.js b/js/game.js index 4c953a4..b307809 100644 --- a/js/game.js +++ b/js/game.js @@ -14,11 +14,12 @@ let modInfo = { offlineLimit: 1 // In hours } +// Set your version in num and name, but leave the tmt values so people know what version it is let VERSION = { - num: "1.3.5 maybe", - name: "Tabception... ception!", - tmtNum: "1.3.5 maybe", - tmtName: "Tabception... ception!" + num: "2.0", + name: "Finally making some progress!", + tmtNum: "2.0", + tmtName: "Finally making some progress!" } // Determines if it should show points/sec @@ -120,26 +121,28 @@ function rowReset(row, layer) { layers[lr].doReset(layer) } else - if(layers[layer].row > layers[lr].row) fullLayerReset(lr) + if(layers[layer].row > layers[lr].row) layerDataReset(lr) } } -function fullLayerReset(layer) { +function layerDataReset(layer, keep = []) { + let storedData = {} + + for (thing in keep) { + if (player[layer][keep[thing]] !== undefined) + storedData[keep[thing]] = player[layer][keep[thing]] + } + console.log(storedData) + player[layer] = layers[layer].startData(); player[layer].upgrades = [] player[layer].milestones = [] player[layer].challenges = [] - if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)) { - if (player.subtabs[layer] == undefined) player.subtabs[layer] = {} - if (player.subtabs[layer].mainTabs == undefined) player.subtabs[layer].mainTabs = Object.keys(layers[layer].tabFormat)[0] - } - - if (layers[layer].microtabs) { - if (player.subtabs[layer] == undefined) player.subtabs[layer] = {} - for (item in layers[layer].microtabs) - if (player.subtabs[layer][item] == undefined) player.subtabs[layer][item] = Object.keys(layers[layer].microtabs[item])[0] - } resetBuyables(layer) + + for (thing in storedData) { + player[layer][thing] =storedData[thing] + } } function resetBuyables(layer){ diff --git a/js/layers.js b/js/layers.js index 77b97f0..5df326c 100644 --- a/js/layers.js +++ b/js/layers.js @@ -175,7 +175,7 @@ addLayer("c", { }, }, doReset(resettingLayer){ // Triggers when this layer is being reset, along with the layer doing the resetting. Not triggered by lower layers resetting, but is by layers on the same row. - if(layers[resettingLayer].row > this.row) fullLayerReset(this.layer) // This is actually the default behavior + if(layers[resettingLayer].row > this.row) layerDataReset(this.layer, ["upgrades", "challenges"]) // This is actually the default behavior }, layerShown() {return true}, // Condition for when layer appears on the tree automate() { diff --git a/js/utils.js b/js/utils.js index 81fdc50..201f9dd 100644 --- a/js/utils.js +++ b/js/utils.js @@ -587,7 +587,7 @@ function focused(x) { function prestigeButtonText(layer) { if(tmp[layer].type == "normal") - return `${ player[layer].points.lt(1e3) ? (tmp[layer].resetDescription !== undefined ? tmp[layer].resetDescription : "Reset for ") : ""}+${formatWhole(tmp[layer].resetGain)} ${tmp[layer].resource} ${tmp[layer].resetGain.lt(100) && player[layer].points.lt(1e3) ? `

Next at ${ (tmp[layer].roundUpCost ? formatWhole(tmp[layer].nextAt) : format(tmp[layer].nextAt))}` : ""} ${ tmp[layer].baseResource }` + return `${ player[layer].points.lt(1e3) ? (tmp[layer].resetDescription !== undefined ? tmp[layer].resetDescription : "Reset for ") : ""}+${formatWhole(tmp[layer].resetGain)} ${tmp[layer].resource} ${tmp[layer].resetGain.lt(100) && player[layer].points.lt(1e3) ? `

Next at ${ (tmp[layer].roundUpCost ? formatWhole(tmp[layer].nextAt) : format(tmp[layer].nextAt))} ${ tmp[layer].baseResource }` : ""}` else if(tmp[layer].type== "static") return `${tmp[layer].resetDescription !== undefined ? tmp[layer].resetDescription : "Reset for "}+${formatWhole(tmp[layer].resetGain)} ${tmp[layer].resource}

${player[layer].points.lt(20) ? (tmp[layer].baseAmount.gte(tmp[layer].nextAt)&&(tmp[layer].canBuyMax !== undefined) && tmp[layer].canBuyMax?"Next":"Req") : ""}: ${formatWhole(tmp[layer].baseAmount)} / ${(tmp[layer].roundUpCost ? formatWhole(tmp[layer].nextAtDisp) : format(tmp[layer].nextAtDisp))} ${ tmp[layer].baseResource } ` From 9590b09c134612c763c3ab0c271573a373f87f38 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Wed, 14 Oct 2020 18:10:12 -0400 Subject: [PATCH 21/33] Update changelog.md --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index efadcd1..8addaa7 100644 --- a/changelog.md +++ b/changelog.md @@ -18,6 +18,7 @@ Changelog is no longer in index.html at all. Generation of Points now happens in the main game loop (not in a layer update function), enabled by canGenPoints in game.js Renamed many things to increase readability (see something or other for a list) Improved documentation based on feedback +Changed fullLayerReset to resetLayerData with ways to keep things ##v1.3.5 From 082fd913f712f345b54959102b670c4aebf6e78c Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Wed, 14 Oct 2020 19:06:45 -0400 Subject: [PATCH 22/33] The points display and other gui elements stay at the top of the screen when the tree scrolls. --- changelog.md | 1 + index.html | 63 +++++++++++++++++++++++++++++++++++----------------- style.css | 10 +++++++++ 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/changelog.md b/changelog.md index 8addaa7..7cd20a9 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,7 @@ Added progress bars, which are highly customizable and can be horizontal or vertical! Added clickables, a more generalized variant of buyables. Support for multiple completions of challenges. +The points display and other gui elements stay at the top of the screen when the tree scrolls. Added getter/setter functions for buyable amount and such Moved modInfo to game.js, added a spot for a Discord link, changelog link, and a separate mod version from the TMT version Tree structure is based on layer data, no index.html needed. diff --git a/index.html b/index.html index 26e1535..6784a7b 100644 --- a/index.html +++ b/index.html @@ -89,27 +89,50 @@
-
-
{{VERSION.withoutName}}
- -

i
- - -
Dev Speed: {{format(player.devSpeed)}}x
-
- -
Offline Time: {{formatTime(player.offTime.remain)}}
-
- -
Reach {{formatWhole(ENDGAME)}} to beat the game!
-
-
- You have -

{{format(player.points)}}

- {{modInfo.pointsName}} -
- ({{format(getPointGen())}}/sec) +
+
{{VERSION.withoutName}}
+ +

i
+ +
+ +
Dev Speed: {{format(player.devSpeed)}}x
+
+ +
Offline Time: {{formatTime(player.offTime.remain)}}
+
+ +
Reach {{formatWhole(ENDGAME)}} to beat the game!
+
+
+ You have +

{{format(player.points)}}

+ {{modInfo.pointsName}} +
+ ({{format(getPointGen())}}/sec) +
+
+ + +




+ diff --git a/style.css b/style.css index 0ae3521..7b8fa65 100644 --- a/style.css +++ b/style.css @@ -523,3 +523,13 @@ ul { flex-direction: column; justify-content: center; } + +.treeOverlay { + z-index: 200000; + pointer-events:none; +} + +.overlayThing { + pointer-events:auto; + background-color: var(--background); +} \ No newline at end of file From d784a6c2e4ae748da045c02016ebdc04a95cf5c2 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Wed, 14 Oct 2020 19:34:15 -0400 Subject: [PATCH 23/33] Added side layers. --- index.html | 3 + js/layerSupport.js | 10 +- js/layers.js | 329 ++++++++++++++++++++++++++++++++------------- js/v.js | 5 +- style.css | 21 +++ 5 files changed, 270 insertions(+), 98 deletions(-) diff --git a/index.html b/index.html index 6784a7b..ea3c92b 100644 --- a/index.html +++ b/index.html @@ -111,6 +111,9 @@
({{format(getPointGen())}}/sec) +
+
+
diff --git a/js/layerSupport.js b/js/layerSupport.js index 26bd62e..f5d4383 100644 --- a/js/layerSupport.js +++ b/js/layerSupport.js @@ -24,6 +24,7 @@ function updateHotkeys() var ROW_LAYERS = {} var TREE_LAYERS = {} +var OTHER_LAYERS = {} function updateLayers(){ LAYERS = Object.keys(layers); @@ -104,11 +105,14 @@ function updateLayers(){ row = layers[layer].row if(!ROW_LAYERS[row]) ROW_LAYERS[row] = {} - if(!TREE_LAYERS[row]) TREE_LAYERS[row] = [] + if(!TREE_LAYERS[row] && !isNaN(row)) TREE_LAYERS[row] = [] + if(!OTHER_LAYERS[row] && isNaN(row)) OTHER_LAYERS[row] = [] + ROW_LAYERS[row][layer]=layer; let position = (layers[layer].position !== undefined ? layers[layer].position : layer) - TREE_LAYERS[row].push({layer: layer, position: position}) - + + if (!isNaN(row)) TREE_LAYERS[row].push({layer: layer, position: position}) + else OTHER_LAYERS[row].push({layer: layer, position: position}) } for (row in TREE_LAYERS) { diff --git a/js/layers.js b/js/layers.js index 5df326c..caa9276 100644 --- a/js/layers.js +++ b/js/layers.js @@ -342,112 +342,255 @@ addLayer("c", { // This layer is mostly minimal but it uses a custom prestige type and a clickable addLayer("f", { + startData() { return { + unlocked: false, + points: new Decimal(0), + boop: false, + clickables: {[11]: "Start"} // Optional default Clickable state + }}, + color:() => "#FE0102", + requires() {return new Decimal(10)}, + resource: "farm points", + baseResource: "candies", + baseAmount() {return player.points}, + type: "custom", // A "Custom" type which is effectively static + exponent: 0.5, + base: 3, + roundUpCost: true, + canBuyMax:() => true, + gainMult() { + return new Decimal(1) + }, + gainExp() { + return new Decimal(1) + }, + row: 1, + layerShown() {return true}, + branches: ["c"], // When this layer appears, a branch will appear from this layer to any layers here. Each entry can be a pair consisting of a layer id and a color. + + tooltipLocked() { // Optional, tooltip displays when the layer is locked + return ("This weird farmer dinosaur will only see you if you have at least " + this.requires() + " candies. You only have " + formatWhole(player.points)) + }, + + midsection: [ + "blank", ['display-image', 'https://images.beano.com/store/24ab3094eb95e5373bca1ccd6f330d4406db8d1f517fc4170b32e146f80d?auto=compress%2Cformat&dpr=1&w=390'], + ["display-text", "Bork bork!"] + ], + + // 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[this.layer].nextAt) + " candies)" + if (this.canBuyMax()) return "Hi! I'm a weird dinosaur and I'll give you " + formatWhole(tmp[this.layer].resetGain) + " Farm Points in exchange for all of your candies and lollipops! (You'll get another one at " + formatWhole(tmp[layer].nextAtDisp) + " candies)" + }, + getResetGain() { + return getResetGain(this.layer, useType = "static") + }, + getNextAt(canMax=false) { // + return getNextAt(this.layer, canMax, useType = "static") + }, + canReset() { + return tmp[this.layer].baseAmount.gte(tmp[this.layer].nextAt) + }, + // This is also non minimal, a Clickable! + clickables: { + rows: 1, + cols: 1, + masterButtonPress() { // Optional, reset things and give back your currency. Having this function makes a respec button appear + if (getClickableState(this.layer, 11) == "Borkened...") + player[this.layer].clickables[11] = "Start" + }, + masterButtonText() {return (getClickableState(this.layer, 11) == "Borkened...") ? "Fix the clickable!" : "Does nothing"}, // Text on Respec button, optional + 11: { + title:() => "Clicky clicky!", // Optional, displayed at the top in a larger font + display() { // Everything else displayed in the buyable button after the title + let data = getClickableState(this.layer, this.id) + return "Current state:
" + data + }, + unlocked() { return player[this.layer].unlocked }, + canClick() { + return getClickableState(this.layer, this.id) !== "Borkened..."}, + onClick() { + switch(getClickableState(this.layer, this.id)){ + case "Start": + player[this.layer].clickables[this.id] = "A new state!" + break; + case "A new state!": + player[this.layer].clickables[this.id] = "Keep going!" + break; + case "Keep going!": + player[this.layer].clickables[this.id] = "Maybe that's a bit too far..." + break; + case "Maybe that's a bit too far...": + player[this.layer].clickables[this.id] = "Borkened..." + break; + default: + player[this.layer].clickables[this.id] = "Start" + break; + + } + }, + style() { + switch(getClickableState(this.layer, this.id)){ + case "Start": + return {'background-color': 'green'} + break; + case "A new state!": + return {'background-color': 'yellow'} + break; + case "Keep going!": + return {'background-color': 'orange'} + break; + case "Maybe that's a bit too far...": + return {'background-color': 'red'} + break; + default: + return {} + break; + }}, + }, + }, + +}, +) + + +// This layer is mostly minimal but it uses a custom prestige type and a clickable +addLayer("f", { + startData() { return { + unlocked: false, + points: new Decimal(0), + boop: false, + clickables: {[11]: "Start"} // Optional default Clickable state + }}, + color:() => "#FE0102", + requires() {return new Decimal(10)}, + resource: "farm points", + baseResource: "candies", + baseAmount() {return player.points}, + type: "custom", // A "Custom" type which is effectively static + exponent: 0.5, + base: 3, + roundUpCost: true, + canBuyMax:() => true, + gainMult() { + return new Decimal(1) + }, + gainExp() { + return new Decimal(1) + }, + row: 1, + layerShown() {return true}, + branches: ["c"], // When this layer appears, a branch will appear from this layer to any layers here. Each entry can be a pair consisting of a layer id and a color. + + tooltipLocked() { // Optional, tooltip displays when the layer is locked + return ("This weird farmer dinosaur will only see you if you have at least " + this.requires() + " candies. You only have " + formatWhole(player.points)) + }, + + midsection: [ + "blank", ['display-image', 'https://images.beano.com/store/24ab3094eb95e5373bca1ccd6f330d4406db8d1f517fc4170b32e146f80d?auto=compress%2Cformat&dpr=1&w=390'], + ["display-text", "Bork bork!"] + ], + + // 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[this.layer].nextAt) + " candies)" + if (this.canBuyMax()) return "Hi! I'm a weird dinosaur and I'll give you " + formatWhole(tmp[this.layer].resetGain) + " Farm Points in exchange for all of your candies and lollipops! (You'll get another one at " + formatWhole(tmp[layer].nextAtDisp) + " candies)" + }, + getResetGain() { + return getResetGain(this.layer, useType = "static") + }, + getNextAt(canMax=false) { // + return getNextAt(this.layer, canMax, useType = "static") + }, + canReset() { + return tmp[this.layer].baseAmount.gte(tmp[this.layer].nextAt) + }, + // This is also non minimal, a Clickable! + clickables: { + rows: 1, + cols: 1, + masterButtonPress() { // Optional, reset things and give back your currency. Having this function makes a respec button appear + if (getClickableState(this.layer, 11) == "Borkened...") + player[this.layer].clickables[11] = "Start" + }, + masterButtonText() {return (getClickableState(this.layer, 11) == "Borkened...") ? "Fix the clickable!" : "Does nothing"}, // Text on Respec button, optional + 11: { + title:() => "Clicky clicky!", // Optional, displayed at the top in a larger font + display() { // Everything else displayed in the buyable button after the title + let data = getClickableState(this.layer, this.id) + return "Current state:
" + data + }, + unlocked() { return player[this.layer].unlocked }, + canClick() { + return getClickableState(this.layer, this.id) !== "Borkened..."}, + onClick() { + switch(getClickableState(this.layer, this.id)){ + case "Start": + player[this.layer].clickables[this.id] = "A new state!" + break; + case "A new state!": + player[this.layer].clickables[this.id] = "Keep going!" + break; + case "Keep going!": + player[this.layer].clickables[this.id] = "Maybe that's a bit too far..." + break; + case "Maybe that's a bit too far...": + player[this.layer].clickables[this.id] = "Borkened..." + break; + default: + player[this.layer].clickables[this.id] = "Start" + break; + + } + }, + style() { + switch(getClickableState(this.layer, this.id)){ + case "Start": + return {'background-color': 'green'} + break; + case "A new state!": + return {'background-color': 'yellow'} + break; + case "Keep going!": + return {'background-color': 'orange'} + break; + case "Maybe that's a bit too far...": + return {'background-color': 'red'} + break; + default: + return {} + break; + }}, + }, + }, + +}, +) + + +// This layer is mostly minimal but it uses a custom prestige type and a clickable +addLayer("a", { startData() { return { - unlocked: false, + unlocked: true, points: new Decimal(0), - boop: false, - clickables: {[11]: "Start"} // Optional default Clickable state }}, - color:() => "#FE0102", - requires() {return new Decimal(10)}, - resource: "farm points", + color: "yellow", + requires: new Decimal (1), + resource: "idk", baseResource: "candies", baseAmount() {return player.points}, - type: "custom", // A "Custom" type which is effectively static + type: "normal", // A "Custom" type which is effectively static exponent: 0.5, - base: 3, - roundUpCost: true, - canBuyMax:() => true, gainMult() { return new Decimal(1) }, gainExp() { return new Decimal(1) }, - row: 1, + row: "side", layerShown() {return true}, - branches: ["c"], // When this layer appears, a branch will appear from this layer to any layers here. Each entry can be a pair consisting of a layer id and a color. - - tooltipLocked() { // Optional, tooltip displays when the layer is locked - return ("This weird farmer dinosaur will only see you if you have at least " + this.requires() + " candies. You only have " + formatWhole(player.points)) - }, - - midsection: [ - "blank", ['display-image', 'https://images.beano.com/store/24ab3094eb95e5373bca1ccd6f330d4406db8d1f517fc4170b32e146f80d?auto=compress%2Cformat&dpr=1&w=390'], - ["display-text", "Bork bork!"] - ], - - // 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[this.layer].nextAt) + " candies)" - if (this.canBuyMax()) return "Hi! I'm a weird dinosaur and I'll give you " + formatWhole(tmp[this.layer].resetGain) + " Farm Points in exchange for all of your candies and lollipops! (You'll get another one at " + formatWhole(tmp[layer].nextAtDisp) + " candies)" - }, - getResetGain() { - return getResetGain(this.layer, useType = "static") - }, - getNextAt(canMax=false) { // - return getNextAt(this.layer, canMax, useType = "static") - }, - canReset() { - return tmp[this.layer].baseAmount.gte(tmp[this.layer].nextAt) - }, - // This is also non minimal, a Clickable! - clickables: { - rows: 1, - cols: 1, - masterButtonPress() { // Optional, reset things and give back your currency. Having this function makes a respec button appear - if (getClickableState(this.layer, 11) == "Borkened...") - player[this.layer].clickables[11] = "Start" - }, - masterButtonText() {return (getClickableState(this.layer, 11) == "Borkened...") ? "Fix the clickable!" : "Does nothing"}, // Text on Respec button, optional - 11: { - title:() => "Clicky clicky!", // Optional, displayed at the top in a larger font - display() { // Everything else displayed in the buyable button after the title - let data = getClickableState(this.layer, this.id) - return "Current state:
" + data - }, - unlocked() { return player[this.layer].unlocked }, - canClick() { - return getClickableState(this.layer, this.id) !== "Borkened..."}, - onClick() { - switch(getClickableState(this.layer, this.id)){ - case "Start": - player[this.layer].clickables[this.id] = "A new state!" - break; - case "A new state!": - player[this.layer].clickables[this.id] = "Keep going!" - break; - case "Keep going!": - player[this.layer].clickables[this.id] = "Maybe that's a bit too far..." - break; - case "Maybe that's a bit too far...": - player[this.layer].clickables[this.id] = "Borkened..." - break; - default: - player[this.layer].clickables[this.id] = "Start" - break; - - } - }, - style() { - switch(getClickableState(this.layer, this.id)){ - case "Start": - return {'background-color': 'green'} - break; - case "A new state!": - return {'background-color': 'yellow'} - break; - case "Keep going!": - return {'background-color': 'orange'} - break; - case "Maybe that's a bit too far...": - return {'background-color': 'red'} - break; - default: - return {} - break; - }}, - }, + tooltipUnlocked() { // Optional, tooltip displays when the layer is locked + return ("YEETS") }, }, diff --git a/js/v.js b/js/v.js index 72f55ae..f7d51af 100644 --- a/js/v.js +++ b/js/v.js @@ -305,7 +305,7 @@ function loadVue() { }) Vue.component('layer-node', { - props: ['layer', 'abb'], + props: ['layer', 'abb', 'size'], template: `

+


Goal: {{format(tmp[layer].challenges[data].goal)}} {{tmp[layer].challenges[data].currencyDisplayName ? tmp[layer].challenges[data].currencyDisplayName : "points"}}
Reward:
From 923f096aa0502d96079aa3fd57eed2bd5e07ffda Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Wed, 14 Oct 2020 21:43:16 -0400 Subject: [PATCH 25/33] Achievements --- docs/!general-info.md | 1 + docs/achievements.md | 55 ++++++++++++++++++++++++++++++++++++++ docs/custom-tab-layouts.md | 4 +-- docs/layer-features.md | 4 +++ docs/milestones.md | 4 +-- docs/upgrades.md | 3 +-- js/game.js | 6 +++-- js/layerSupport.js | 10 +++++++ js/layers.js | 34 ++++++++++++++++++++--- js/utils.js | 17 ++++++++++++ js/v.js | 30 +++++++++++++++++++++ style.css | 19 +++++++++++-- 12 files changed, 173 insertions(+), 14 deletions(-) create mode 100644 docs/achievements.md diff --git a/docs/!general-info.md b/docs/!general-info.md index f5a7287..ceb90dd 100644 --- a/docs/!general-info.md +++ b/docs/!general-info.md @@ -39,4 +39,5 @@ All display text can be basic HTML instead (But you can't use most Vue features - [Custom Tab Layouts](custom-tab-layouts.md): An optional way to give your tabs a different layout. You can even create entirely new components to use. - [Subtabs and Microtabs](subtabs-and-microtabs.md): Create subtabs for your tabs, as well as "microtab" components that you can put inside the tabs. +- [Achievements](milestones.md): How to create achievements for a layer (or for the whole game). - [Updating TMT](updating-tmt.md): Using Github Desktop to update your mod's version of TMT. diff --git a/docs/achievements.md b/docs/achievements.md new file mode 100644 index 0000000..b03d2c5 --- /dev/null +++ b/docs/achievements.md @@ -0,0 +1,55 @@ +#Achievements + +Achievements are awarded to the player when they meet a certain goal, and give some benefit. +Currently, they are pretty basic, but additional features will be added later to help. + +You can make global achievements by putting them in a side layer (make its row "side" instead of a number) + +Useful functions for dealing with achievements and implementing their effects: + +- hasAchievement(layer, id): determine if the player has the Achievement +- achievementEffect(layer, id): Returns the current effects of the achievement, if any + + +Achievements should be formatted like this: + +```js + achievements: { + rows: # of rows + cols: # of columns + 11: { + name: "Blah", + more features + } + etc + } +``` + +Each achievement should have an id where the first digit is the row and the second digit is the column. +Individual achievement can have these features: + +- name: **optional**, displayed at the top of the achievement. The only visible text. + It can also be a function that returns updating text. Can use basic HTML. + +- done(): A function returning a boolean to determine if the achievement should be awarded. + +- goalTooltip: Appears when the achievement is hovered over and locked. This is to display the goal (or a hint). + It can also be a function that returns updating text. Can use basic HTML. + +- doneTooltip: Appears when the achievement is hovered over and completed. This can display what the player achieved (the goal), + and the rewards, if any. It can also be a function that returns updating text. Can use basic HTML. + +- effect(): **optional**, A function that calculates and returns the current values of any bonuses from the achievement. + Can return a value or an object containing multiple values. + +- unlocked(): **optional**, A function returning a bool to determine if the achievement is visible or not. Default is unlocked. + +- onComplete() - **optional**, this function will be called when the achievement is completed. + +- style: **Optional**, Applies CSS to this achievement, in the form of an object where the keys are CSS attributes, + and the values are the values for those attributes (both as strings) + +- 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 "key" which the achievement was stored under, for convenient access. + The achievement in the example's id is 11. \ No newline at end of file diff --git a/docs/custom-tab-layouts.md b/docs/custom-tab-layouts.md index b387dbb..c97016a 100644 --- a/docs/custom-tab-layouts.md +++ b/docs/custom-tab-layouts.md @@ -36,14 +36,14 @@ These are the existing components, but you can create more in v.js: - prestige-button: The argument is a string that the prestige button should say before the amount of currency you will gain. It can also be a function that returns updating text. -- upgrades, milestones, challs: Display the upgrades, milestones, and challenges for a layer, as appropriate. +- upgrades, milestones, challs, achievements: Display the upgrades, milestones, and challenges for a layer, as appropriate. - buyables, clickables: Display all of the buyables/clickables for this layer, as appropriate. The argument optional, and is the size of the boxes in pixels. - microtabs: Display a set of subtabs for an area. The argument is the name of the set of microtabs in the "microtabs" feature. -- upgrade, milestone, chall, buyable: An individual upgrade, challenge, etc. The argument is the id. +- upgrade, milestone, chall, buyable, clickable, achievement: An individual upgrade, challenge, etc. The argument is the id. This can be used if you want to have upgrades split up across multiple subtabs, for example. - bar: Display a bar. The argument is the id of the bar to display. diff --git a/docs/layer-features.md b/docs/layer-features.md index ef8368c..646d1d5 100644 --- a/docs/layer-features.md +++ b/docs/layer-features.md @@ -90,6 +90,10 @@ Key: - bars: Display some information as a progress bar, gague, or similar. They are highly customizable, and can be vertical as well. [Explanations are in a separate file.](bars.md) +- achievements: Kind of like milestones, but with a different display style and some other differences. Extra features are on the way at a later date! + [Explanations are in a separate file.](achievements.md) + + # Prestige formula features - baseResource: The name of the resource that determines how much of the main currency you gain on reset. diff --git a/docs/milestones.md b/docs/milestones.md index 615abab..ff36b7e 100644 --- a/docs/milestones.md +++ b/docs/milestones.md @@ -1,6 +1,6 @@ #Milestones -Milestones should be formatted like this: +Milestones are awarded to the player when they meet a certain goal, and give some benefit. Milestones should be formatted like this: ```js milestones: { @@ -21,7 +21,7 @@ Milestone features: - effectDesc: A string describing the reward for having the milestone. *You will have to implement the reward elsewhere.* It can also be a function that returns updating text. Can use basic HTML. -- done(): A function returning a boolean to determine if the milestone has been fulfilled. +- done(): A function returning a boolean to determine if the milestone should be awarded. - toggles: *optional*, Creates toggle buttons that appear on the milestone when it is unlocked. The toggles can toggle a given boolean value in a layer. diff --git a/docs/upgrades.md b/docs/upgrades.md index 0784210..ce47011 100644 --- a/docs/upgrades.md +++ b/docs/upgrades.md @@ -1,7 +1,5 @@ # Upgrades -Upgrades are stored in the following format: - Useful functions for dealing with Upgrades and implementing their effects: - hasUpgrade(layer, id): determine if the player has the upgrade @@ -9,6 +7,7 @@ Useful functions for dealing with Upgrades and implementing their effects: Hint: Basic point gain is calculated in game.js's "getPointGain". +Upgrades are stored in the following format: ```js upgrades: { diff --git a/js/game.js b/js/game.js index 1762c09..0b799f9 100644 --- a/js/game.js +++ b/js/game.js @@ -17,9 +17,9 @@ let modInfo = { // Set your version in num and name, but leave the tmt values so people know what version it is let VERSION = { num: "2.0", - name: "Finally making some progress!", + name: "Pinnacle of Achievement Mountain", tmtNum: "2.0", - tmtName: "Finally making some progress!" + tmtName: "Pinnacle of Achievement Mountain" } // Determines if it should show points/sec @@ -182,6 +182,7 @@ function doReset(layer, force=false) { addPoints(layer, gain) updateMilestones(layer) + updateAchievements(layer) if (!player[layer].unlocked) { player[layer].unlocked = true; @@ -312,6 +313,7 @@ function gameLoop(diff) { for (layer in layers){ if (layers[layer].milestones) updateMilestones(layer); + if (layers[layer].achievements) updateAchievements(layer) } if (player.hasNaN&&!NaNalert) { diff --git a/js/layerSupport.js b/js/layerSupport.js index f5d4383..8aa1cc2 100644 --- a/js/layerSupport.js +++ b/js/layerSupport.js @@ -52,6 +52,16 @@ function updateLayers(){ } } } + if (layers[layer].achievements){ + for (thing in layers[layer].achievements){ + if (!isNaN(thing)){ + layers[layer].achievements[thing].id = thing + layers[layer].achievements[thing].layer = layer + if (layers[layer].achievements[thing].unlocked === undefined) + layers[layer].achievements[thing].unlocked = true + } + } + } if (layers[layer].challenges){ for (thing in layers[layer].challenges){ if (!isNaN(thing)){ diff --git a/js/layers.js b/js/layers.js index 6401378..b760785 100644 --- a/js/layers.js +++ b/js/layers.js @@ -576,8 +576,8 @@ addLayer("a", { }}, color: "yellow", requires: new Decimal (1), - resource: "idk", - baseResource: "candies", + resource: "achievement power", + baseResource: "achievements", baseAmount() {return player.points}, type: "normal", // A "Custom" type which is effectively static exponent: 0.5, @@ -589,9 +589,35 @@ addLayer("a", { }, row: "side", layerShown() {return true}, - tooltipUnlocked() { // Optional, tooltip displays when the layer is locked - return ("YEETS") + tooltip() { // Optional, tooltip displays when the layer is locked + return ("Achievements") }, + achievements: { + rows: 2, + cols: 3, + 11: { + name: "Get me!", + done() {return true}, // This one is a freebie + goalTooltip: "How did this happen?", // Shows when achievement is not completed + doneTooltip: "You did it!", // Showed when the achievement is completed + }, + 12: { + name: "Impossible!", + done() {return false}, + goalTooltip: "Mwahahaha!", // Shows when achievement is not completed + doneTooltip: "HOW????", // Showed when the achievement is completed + }, + 13: { + name: "EIEIO", + done() {return player.f.points.gte(1)}, + goalTooltip: "Get a farm point.", // Shows when achievement is not completed + doneTooltip: "Get a farm point.\n\nReward: The dinosaur is now your friend.", // Showed when the achievement is completed + onComplete() {console.log("Bork bork bork!")} + }, + }, + tabFormat: [ + "main-display", "blank", "blank", "achievements", + ] }, ) diff --git a/js/utils.js b/js/utils.js index c53f421..aff4914 100644 --- a/js/utils.js +++ b/js/utils.js @@ -93,6 +93,7 @@ function getStartPlayer() { playerdata[layer].spentOnBuyables = new Decimal(0) playerdata[layer].upgrades = [] playerdata[layer].milestones = [] + playerdata[layer].achievements = [] playerdata[layer].challenges = getStartChallenges(layer) if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)) { playerdata.subtabs[layer] = {} @@ -368,6 +369,10 @@ function hasMilestone(layer, id){ return (player[layer].milestones.includes(toNumber(id)) || player[layer].milestones.includes(id.toString())) } +function hasAchievement(layer, id){ + return (player[layer].achievements.includes(toNumber(id)) || player[layer].achievements.includes(id.toString())) +} + function hasChallenge(layer, id){ return (player[layer].challenges[id]) } @@ -404,6 +409,9 @@ function buyableEffect(layer, id){ return (tmp[layer].buyables[id].effect) } +function achievementEffect(layer, id){ + return (tmp[layer].achievements[id].effect) +} function canAffordPurchase(layer, thing, cost) { if (thing.currencyInternalName){ @@ -540,6 +548,15 @@ function updateMilestones(layer){ } } +function updateAchievements(layer){ + for (id in layers[layer].achievements){ + if (!isNaN(id) && !(player[layer].achievements.includes(id)) && layers[layer].achievements[id].done()) { + player[layer].achievements.push(id) + if (layers[layer].achievements[id].onComplete) layers[layer].achievements[id].onComplete() + } + } +} + function addTime(diff, layer) { let data = player let time = data.timePlayed diff --git a/js/v.js b/js/v.js index 7c8cdb1..2fa7637 100644 --- a/js/v.js +++ b/js/v.js @@ -291,6 +291,36 @@ function loadVue() { }) + Vue.component('achievements', { + props: ['layer'], + template: ` +
+
+
+ +
+
+
+
+ ` + }) + + // data = id + Vue.component('achievement', { + props: ['layer', 'data'], + template: ` +
+


+
+ ` + }) + // NOT FOR USE IN STANDARD TAB FORMATTING Vue.component('tab-buttons', { diff --git a/style.css b/style.css index 113a76a..6bf9e42 100644 --- a/style.css +++ b/style.css @@ -200,6 +200,20 @@ h1, h2, h3, b, input { font-size: 10px; } +.achievement { + height: 90px; + width: 90px; + border-radius: 25%; + border: 2px solid; + border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125); + font-size: 10px; + color: white; + text-shadow: 0px 0px 2px #000000; +} +.achievement:hover { + box-shadow: 0px 0px 10px var(--points); +} + .buyable { height: 200px; width: 200px; @@ -541,6 +555,7 @@ ul { .treeOverlay { z-index: 200000; pointer-events:none; + overflow:hidden; } .overlayThing { @@ -551,6 +566,6 @@ ul { .sideLayers { pointer-events:auto; position: absolute; - right: 35px; - top: 55px; + right: 55px; + top: 65px; } \ No newline at end of file From 79639ce03d1827f724561567a5298dfb8ffef5e7 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Wed, 14 Oct 2020 21:52:48 -0400 Subject: [PATCH 26/33] A few small improvements. --- docs/layer-features.md | 2 +- js/layers.js | 167 +++++++---------------------------------- 2 files changed, 27 insertions(+), 142 deletions(-) diff --git a/docs/layer-features.md b/docs/layer-features.md index 646d1d5..0752c75 100644 --- a/docs/layer-features.md +++ b/docs/layer-features.md @@ -141,7 +141,7 @@ Key: and layers are sorted in alphabetical order. - branches: **optional**, an array of layer ids. On a tree, a line will appear from this layer to all of the layers - in the list. Alternatively, an entry in the array can be a pair consisting of the layer id and a color + in the list. Alternatively, an entry in the array can be a 2-element array consisting of the layer id and a color value. The color value can either be a string with a hex color code, or a number from 1-3 (theme-affected colors) - nodeStyle: **optional**, a CSS object, where the keys are CSS attributes, which styles this layer's node on the tree diff --git a/js/layers.js b/js/layers.js index b760785..c7d43b4 100644 --- a/js/layers.js +++ b/js/layers.js @@ -11,8 +11,8 @@ addLayer("c", { buyables: {}, // You don't actually have to initialize this one beep: false, }}, - color:() => "#4BDC13", - requires:() => new Decimal(10), // Can be a function that takes requirement increases into account + color: "#4BDC13", + requires: new Decimal(10), // Can be a function that takes requirement increases into account resource: "lollipops", // Name of prestige currency baseResource: "candies", // Name of resource prestige is based on baseAmount() {return player.points}, // Get the current amount of baseResource @@ -42,14 +42,14 @@ addLayer("c", { return "which are boosting waffles by "+format(eff.waffleBoost)+" and increasing the Ice Cream cap by "+format(eff.icecreamCap) }, milestones: { - 0: {requirementDescription:() => "3 Lollipops", + 0: {requirementDescription: "3 Lollipops", done() {return player[this.layer].best.gte(3)}, // Used to determine when to give the milestone - effectDescription:() => "Unlock the next milestone", + effectDescription: "Unlock the next milestone", }, - 1: {requirementDescription:() => "4 Lollipops", + 1: {requirementDescription: "4 Lollipops", unlocked() {return hasMilestone(this.layer, 0)}, done() {return player[this.layer].best.gte(4)}, - effectDescription:() => "You can toggle beep and boop (which do nothing)", + effectDescription: "You can toggle beep and boop (which do nothing)", toggles: [ ["c", "beep"], // Each toggle is defined by a layer and the data toggled for that layer ["f", "boop"]], @@ -64,11 +64,11 @@ addLayer("c", { rows: 2, cols: 12, 11: { - name:() => "Fun", + name: "Fun", completionLimit: 3, challengeDescription() {return "Makes the game 0% harder
"+challengeCompletions(this.layer, this.id) + "/" + this.completionLimit + " completions"}, unlocked() { return player[this.layer].best.gt(0) }, - goal:() => new Decimal("20"), + goal: new Decimal("20"), currencyDisplayName: "lollipops", // Use if using a nonstandard currency currencyInternalName: "points", // Use if using a nonstandard currency currencyLayer: this.layer, // Leave empty if not in a layer @@ -86,14 +86,14 @@ addLayer("c", { rows: 2, cols: 3, 11: { - title:() => "Generator of Genericness", - description:() => "Gain 1 Point every second.", - cost:() => new Decimal(1), + title: "Generator of Genericness", + description: "Gain 1 Point every second.", + cost: new Decimal(1), unlocked() { return player[this.layer].unlocked }, // The upgrade is only visible when this is true }, 12: { - description:() => "Candy generation is faster based on your unspent Lollipops.", - cost:() => new Decimal(1), + description: "Candy generation is faster based on your unspent Lollipops.", + cost: new Decimal(1), unlocked() { return (hasUpgrade(this.layer, 11))}, effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values let ret = player[this.layer].points.add(1).pow(player[this.layer].upgrades.includes(24)?1.1:(player[this.layer].upgrades.includes(14)?0.75:0.5)) @@ -103,8 +103,8 @@ addLayer("c", { effectDisplay() { return format(this.effect())+"x" }, // Add formatting to the effect }, 13: { - description:() => "Unlock a secret subtab and make this layer act if you unlocked it first.", - cost:() => new Decimal(69), + description: "Unlock a secret subtab and make this layer act if you unlocked it first.", + cost: new Decimal(69), currencyDisplayName: "candies", // Use if using a nonstandard currency currencyInternalName: "points", // Use if using a nonstandard currency currencyLayer: "", // Leave empty if not in a layer "e.g. points" @@ -124,9 +124,9 @@ addLayer("c", { }, }, 22: { - title:() => "This upgrade doesn't exist", - description:() => "Or does it?.", - cost:() => new Decimal(3), + title: "This upgrade doesn't exist", + description: "Or does it?.", + cost: new Decimal(3), unlocked() { return player[this.layer].unlocked }, // The upgrade is only visible when this is true }, }, @@ -138,9 +138,9 @@ addLayer("c", { resetBuyables(this.layer) doReset(this.layer, true) // Force a reset }, - respecText:() => "Respec Thingies", // Text on Respec button, optional + respecText: "Respec Thingies", // Text on Respec button, optional 11: { - title:() => "Exhancers", // Optional, displayed at the top in a larger font + title: "Exhancers", // Optional, displayed at the top in a larger font cost(x=player[this.layer].buyables[this.id]) { // cost for buying xth buyable, can be an object if there are multiple currencies if (x.gte(25)) x = x.pow(2).div(25) let cost = Decimal.pow(2, x.pow(1.5)) @@ -224,7 +224,7 @@ addLayer("c", { display() { return format(player.points) + " / 1e10 points" }, - unlocked:() => true, + unlocked: true, }, tallBoi: { @@ -242,7 +242,7 @@ addLayer("c", { display() { return formatWhole((player.points.div(1)).min(100)) + "%" }, - unlocked:() => true, + unlocked: true, }, flatBoi: { @@ -257,7 +257,7 @@ addLayer("c", { progress() { return player.c.points.div(50) }, - unlocked:() => true, + unlocked: true, }, }, @@ -348,7 +348,7 @@ addLayer("f", { boop: false, clickables: {[11]: "Start"} // Optional default Clickable state }}, - color:() => "#FE0102", + color: "#FE0102", requires() {return new Decimal(10)}, resource: "farm points", baseResource: "candies", @@ -357,7 +357,7 @@ addLayer("f", { exponent: 0.5, base: 3, roundUpCost: true, - canBuyMax:() => true, + canBuyMax() {return hasAchievement('a', 13)}, gainMult() { return new Decimal(1) }, @@ -401,7 +401,7 @@ addLayer("f", { }, masterButtonText() {return (getClickableState(this.layer, 11) == "Borkened...") ? "Fix the clickable!" : "Does nothing"}, // Text on Respec button, optional 11: { - title:() => "Clicky clicky!", // Optional, displayed at the top in a larger font + title: "Clicky clicky!", // Optional, displayed at the top in a larger font display() { // Everything else displayed in the buyable button after the title let data = getClickableState(this.layer, this.id) return "Current state:
" + data @@ -453,121 +453,6 @@ addLayer("f", { }, ) - -// This layer is mostly minimal but it uses a custom prestige type and a clickable -addLayer("f", { - startData() { return { - unlocked: false, - points: new Decimal(0), - boop: false, - clickables: {[11]: "Start"} // Optional default Clickable state - }}, - color:() => "#FE0102", - requires() {return new Decimal(10)}, - resource: "farm points", - baseResource: "candies", - baseAmount() {return player.points}, - type: "custom", // A "Custom" type which is effectively static - exponent: 0.5, - base: 3, - roundUpCost: true, - canBuyMax:() => true, - gainMult() { - return new Decimal(1) - }, - gainExp() { - return new Decimal(1) - }, - row: 1, - layerShown() {return true}, - branches: ["c"], // When this layer appears, a branch will appear from this layer to any layers here. Each entry can be a pair consisting of a layer id and a color. - - tooltipLocked() { // Optional, tooltip displays when the layer is locked - return ("This weird farmer dinosaur will only see you if you have at least " + this.requires() + " candies. You only have " + formatWhole(player.points)) - }, - - midsection: [ - "blank", ['display-image', 'https://images.beano.com/store/24ab3094eb95e5373bca1ccd6f330d4406db8d1f517fc4170b32e146f80d?auto=compress%2Cformat&dpr=1&w=390'], - ["display-text", "Bork bork!"] - ], - - // 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[this.layer].nextAt) + " candies)" - if (this.canBuyMax()) return "Hi! I'm a weird dinosaur and I'll give you " + formatWhole(tmp[this.layer].resetGain) + " Farm Points in exchange for all of your candies and lollipops! (You'll get another one at " + formatWhole(tmp[layer].nextAtDisp) + " candies)" - }, - getResetGain() { - return getResetGain(this.layer, useType = "static") - }, - getNextAt(canMax=false) { // - return getNextAt(this.layer, canMax, useType = "static") - }, - canReset() { - return tmp[this.layer].baseAmount.gte(tmp[this.layer].nextAt) - }, - // This is also non minimal, a Clickable! - clickables: { - rows: 1, - cols: 1, - masterButtonPress() { // Optional, reset things and give back your currency. Having this function makes a respec button appear - if (getClickableState(this.layer, 11) == "Borkened...") - player[this.layer].clickables[11] = "Start" - }, - masterButtonText() {return (getClickableState(this.layer, 11) == "Borkened...") ? "Fix the clickable!" : "Does nothing"}, // Text on Respec button, optional - 11: { - title:() => "Clicky clicky!", // Optional, displayed at the top in a larger font - display() { // Everything else displayed in the buyable button after the title - let data = getClickableState(this.layer, this.id) - return "Current state:
" + data - }, - unlocked() { return player[this.layer].unlocked }, - canClick() { - return getClickableState(this.layer, this.id) !== "Borkened..."}, - onClick() { - switch(getClickableState(this.layer, this.id)){ - case "Start": - player[this.layer].clickables[this.id] = "A new state!" - break; - case "A new state!": - player[this.layer].clickables[this.id] = "Keep going!" - break; - case "Keep going!": - player[this.layer].clickables[this.id] = "Maybe that's a bit too far..." - break; - case "Maybe that's a bit too far...": - player[this.layer].clickables[this.id] = "Borkened..." - break; - default: - player[this.layer].clickables[this.id] = "Start" - break; - - } - }, - style() { - switch(getClickableState(this.layer, this.id)){ - case "Start": - return {'background-color': 'green'} - break; - case "A new state!": - return {'background-color': 'yellow'} - break; - case "Keep going!": - return {'background-color': 'orange'} - break; - case "Maybe that's a bit too far...": - return {'background-color': 'red'} - break; - default: - return {} - break; - }}, - }, - }, - -}, -) - - // This layer is mostly minimal but it uses a custom prestige type and a clickable addLayer("a", { startData() { return { From a6786b2268567d99ec341abd091a6e08bb91f5fc Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Wed, 14 Oct 2020 22:13:29 -0400 Subject: [PATCH 27/33] Updated changelog and moved format changes --- 2.0-format-changes.md | 26 ++++++++++++++++ changelog.md | 70 ++++++++++++++----------------------------- 2 files changed, 49 insertions(+), 47 deletions(-) create mode 100644 2.0-format-changes.md diff --git a/2.0-format-changes.md b/2.0-format-changes.md new file mode 100644 index 0000000..78081f6 --- /dev/null +++ b/2.0-format-changes.md @@ -0,0 +1,26 @@ +# 2.0 format changes + +- Temp format is changed from temp.something[layer] to temp[layer]. something, for consistency +- Challenges are now saved as an object with the amount of completions in each spot. (This will break saves.) +- effectDisplay in Challenges and Upgrades no longer takes an argument, and neither does effect for Buyables +- Buyable cost can take an argument for amount of buyables, but it needs to function if no argument is supplied (it should do the cost for the next purchase). +- Generation of Points now happens in the main game loop (not in a layer update function), enabled by canGenPoints in game.js. +- Changed fullLayerReset to resetLayerData, which takes an array of names of values to keep + +In addition, many names were changed, mostly expanding abbreviations: + +All instances of: + chall -> challenge + unl -> unlocked + upg -> upgrade (besides CSS) + amt -> amount + desc -> description + resCeil -> roundUpCost + +Challenges: + desc -> challengeDescription + reward -> rewardDescription + effect -> rewardEffect + effectDisplay -> rewardDisplay + active -> challengeActive + diff --git a/changelog.md b/changelog.md index 7cd20a9..50af070 100644 --- a/changelog.md +++ b/changelog.md @@ -1,25 +1,28 @@ #The Modding Tree changelog: ##v2.0 -Added progress bars, which are highly customizable and can be horizontal or vertical! -Added clickables, a more generalized variant of buyables. -Support for multiple completions of challenges. -The points display and other gui elements stay at the top of the screen when the tree scrolls. -Added getter/setter functions for buyable amount and such -Moved modInfo to game.js, added a spot for a Discord link, changelog link, and a separate mod version from the TMT version -Tree structure is based on layer data, no index.html needed. -Tmp does not need to be manually updated. -Almost every value in layer data can be a function or a constant value! -You don't have to have the same amount of upgrades in every row (and challs and buyables) -Unl is optional for all Big Components (defaults to true). -effectDisplay in Challenges and Upgrades no longer takes an argument, as well as buyable effect. -Buyable cost can take an argument for amount of buyables, but if one is not supplied it should do the cost of the next buyable. -All displays will update correctly. -Changelog is no longer in index.html at all. -Generation of Points now happens in the main game loop (not in a layer update function), enabled by canGenPoints in game.js -Renamed many things to increase readability (see something or other for a list) -Improved documentation based on feedback -Changed fullLayerReset to resetLayerData with ways to keep things +- Added progress bars, which are highly customizable and can be horizontal or vertical! +- Added "side layers", displayed smaller and off to the side, and don't get reset by default. + They can be used for global achievements and statistics. Speaking of which... +- Added achievements! +- Added clickables, a more generalized variant of buyables. +- Almost every value in layer data can be either a function or a constant value! +- Added support for multiple completions of challenges. +- The points display and other gui elements stay at the top of the screen when the tree scrolls. +- Added getter/setter functions for the amounts and effects of most Big Features +- Moved modInfo to game.js, added a spot in modInfo for a Discord link, changelog link. + Also added a separate mod version from the TMT version in VERSION. +- Tree structure is based on layer data, no index.html editing is needed. +- Tmp does not need to be manually updated. +- You don't have to have the same amount of upgrades in every row (and challs and buyables) +- "unlocked" is optional for all Big Components (defaults to true). +- All displays will update correctly. +- Changelog is no longer in index.html at all. +- Generation of Points now happens in the main game loop +- Changed the reset functions to make keeping things easier +- Renamed many things to increase readability (see something or other for a list) +- Improved documentation based on feedback + [For a full list of changes to the format and functionality of existing things, click here.](2.0-format-changes.md) ##v1.3.5 @@ -97,31 +100,4 @@ parameters. - Lots of minor good things. #v1.0: -- First release. - - -Make it clear that anything can be a function - -buyables.md: cost is a Decimal - -Define "CSS Object" clearly in the first instance in each file - -Explain automagical assignments better - - -"incr_order", - - -All instances of: - chall -> challenge - unl -> unlocked - upg -> upgrade - amt -> amount - desc -> description - resCeil -> roundUpCost - -Challenges: - desc -> challengeDescription - reward -> rewardDescription - effect -> rewardEffect - effectDisplay -> rewardDisplay \ No newline at end of file +- First release. \ No newline at end of file From fd61aaf7b3f9d8268eb24d949c53c94780394439 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Wed, 14 Oct 2020 22:15:13 -0400 Subject: [PATCH 28/33] Fixed changelog formatting --- changelog.md | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/changelog.md b/changelog.md index 50af070..e32a390 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,6 @@ -#The Modding Tree changelog: +#T he Modding Tree changelog: -##v2.0 +# v2.0 10/14/20 - Added progress bars, which are highly customizable and can be horizontal or vertical! - Added "side layers", displayed smaller and off to the side, and don't get reset by default. They can be used for global achievements and statistics. Speaking of which... @@ -24,22 +24,24 @@ - Improved documentation based on feedback [For a full list of changes to the format and functionality of existing things, click here.](2.0-format-changes.md) -##v1.3.5 + + +## v1.3.5 - Completely automated convertToDecimal, now you never have to worry about it again. - Branches can be defined without a color id. But they can also use hex values for color ids! - Created a tutorial for getting started with TMT and Github. - Page title is now automatically taken from mod name. -##v1.3.4: 10/8/20 +## v1.3.4: 10/8/20 - Added "midsection" feature to add things to a tab's layout while still keeping the standard layout. - Fix for being able to buy more buyables than you should. -##v1.3.3: - 10/7/20 +## v1.3.3: - 10/7/20 - Fix for the "order of operations" issue in temp. -##v1.3.1: - 10/7/20 +## v1.3.1: - 10/7/20 - Added custom CSS and tooltips for Layer Nodes. - Added custom CSS for upgrades, buyables, milestones, and challenges, both individually and layer-wide. @@ -48,7 +50,7 @@ - Fixed importing saves, and issue with upgrades not appearing, and probably more. - Optional "name" layer feature, used in confirmation messages. -##v1.3: Tabception... ception! - 10/7/20 +## v1.3: Tabception... ception! - 10/7/20 - 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. @@ -62,20 +64,20 @@ -##v1.2.4 - 10/4/20 +## v1.2.4 - 10/4/20 - Layers are now highlighted if you can buy an upgrade, and a new feature, shouldNotify, lets you make it highlight other ways. - Fixed bugs with hasUpg, hasChall, hasMilestone, and inChallenge. - Changed the sample code to use the above functions for convenience. -##v1.2.3 - 10/3/20 +## v1.2.3 - 10/3/20 - Added a row component, which displays a list of objects in a row. - Added a column component, which displays a list of objects in a column (useful within a row). - Changed blanks to have a customizable width and height. -#v1.2: This Changes Everything! - 10/3/20 +# v1.2: This Changes Everything! - 10/3/20 - Many layer features can now be static values or functions. (This made some formats change, which will break old things) @@ -88,16 +90,17 @@ which will break old things) -##v1.1.1 +## v1.1.1 - You can define hotkeys directly from layer config. -#v1.1: Enhanced Edition +# v1.1: Enhanced Edition - Added "Buyables", which can function like Space Buildings or Enhancers. - Custom CSS can now be used on any component! Make the third argument an object with CSS parameters. - Lots of minor good things. -#v1.0: + +# v1.0: - First release. \ No newline at end of file From b95ef2fe441f2d4352be8bac605ca567304630c9 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Wed, 14 Oct 2020 23:09:30 -0400 Subject: [PATCH 29/33] Added "none" prestige type --- changelog.md | 26 ++++++++++++++------------ docs/layer-features.md | 15 ++++++++------- index.html | 6 ++++-- js/game.js | 7 ++++++- js/layers.js | 16 +++------------- js/utils.js | 2 ++ js/v.js | 2 +- 7 files changed, 38 insertions(+), 36 deletions(-) diff --git a/changelog.md b/changelog.md index e32a390..20a3f2d 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,6 @@ -#T he Modding Tree changelog: +# The Modding Tree changelog: -# v2.0 10/14/20 +## v2.0 10/14/20 - Added progress bars, which are highly customizable and can be horizontal or vertical! - Added "side layers", displayed smaller and off to the side, and don't get reset by default. They can be used for global achievements and statistics. Speaking of which... @@ -8,6 +8,7 @@ - Added clickables, a more generalized variant of buyables. - Almost every value in layer data can be either a function or a constant value! - Added support for multiple completions of challenges. +- Added "none" prestige type, which removes the need for any other prestige-related features. - The points display and other gui elements stay at the top of the screen when the tree scrolls. - Added getter/setter functions for the amounts and effects of most Big Features - Moved modInfo to game.js, added a spot in modInfo for a Discord link, changelog link. @@ -22,26 +23,27 @@ - Changed the reset functions to make keeping things easier - Renamed many things to increase readability (see something or other for a list) - Improved documentation based on feedback + [For a full list of changes to the format and functionality of existing things, click here.](2.0-format-changes.md) -## v1.3.5 +### v1.3.5 - Completely automated convertToDecimal, now you never have to worry about it again. - Branches can be defined without a color id. But they can also use hex values for color ids! - Created a tutorial for getting started with TMT and Github. - Page title is now automatically taken from mod name. -## v1.3.4: 10/8/20 +### v1.3.4: 10/8/20 - Added "midsection" feature to add things to a tab's layout while still keeping the standard layout. - Fix for being able to buy more buyables than you should. -## v1.3.3: - 10/7/20 +### v1.3.3: - 10/7/20 - Fix for the "order of operations" issue in temp. -## v1.3.1: - 10/7/20 +### v1.3.1: - 10/7/20 - Added custom CSS and tooltips for Layer Nodes. - Added custom CSS for upgrades, buyables, milestones, and challenges, both individually and layer-wide. @@ -64,20 +66,20 @@ -## v1.2.4 - 10/4/20 +### v1.2.4 - 10/4/20 - Layers are now highlighted if you can buy an upgrade, and a new feature, shouldNotify, lets you make it highlight other ways. - Fixed bugs with hasUpg, hasChall, hasMilestone, and inChallenge. - Changed the sample code to use the above functions for convenience. -## v1.2.3 - 10/3/20 +### v1.2.3 - 10/3/20 - Added a row component, which displays a list of objects in a row. - Added a column component, which displays a list of objects in a column (useful within a row). - Changed blanks to have a customizable width and height. -# v1.2: This Changes Everything! - 10/3/20 +## v1.2: This Changes Everything! - 10/3/20 - Many layer features can now be static values or functions. (This made some formats change, which will break old things) @@ -90,11 +92,11 @@ which will break old things) -## v1.1.1 +### v1.1.1 - You can define hotkeys directly from layer config. -# v1.1: Enhanced Edition +## v1.1: Enhanced Edition - Added "Buyables", which can function like Space Buildings or Enhancers. - Custom CSS can now be used on any component! Make the third argument an object with CSS @@ -102,5 +104,5 @@ parameters. - Lots of minor good things. -# v1.0: +## v1.0: - First release. \ No newline at end of file diff --git a/docs/layer-features.md b/docs/layer-features.md index 0752c75..2d782ff 100644 --- a/docs/layer-features.md +++ b/docs/layer-features.md @@ -96,6 +96,14 @@ Key: # Prestige formula features +- 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. + 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) + "none": This layer does not prestige, and therefore does not need any of the other features in this section. + - baseResource: The name of the resource that determines how much of the main currency you gain on reset. - baseAmount(): A function that gets the current value of the base resource. @@ -104,13 +112,6 @@ Key: Also the amount required to unlock the layer. You can instead make this a function, to make it harder if another layer was unlocked first (based on "order"). -- 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. - 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. - base: **sometimes required**, required for "static" layers, used as described above. diff --git a/index.html b/index.html index ea3c92b..3192a59 100644 --- a/index.html +++ b/index.html @@ -148,8 +148,10 @@


- -
You have {{formatWhole(tmp[layer].baseAmt)}} {{tmp[layer].baseResource}}
+
+ +
You have {{formatWhole(tmp[layer].baseAmt)}} {{tmp[layer].baseResource}}
+


Your best {{tmp[layer].resource}} is {{formatWhole(player[layer].best)}}
You have made a total of {{formatWhole(player[layer].total)}} {{tmp[layer].resource}}
diff --git a/js/game.js b/js/game.js index 0b799f9..f148a49 100644 --- a/js/game.js +++ b/js/game.js @@ -42,7 +42,8 @@ function getPointGen() { function getResetGain(layer, useType = null) { let type = useType if (!useType) type = layers[layer].type - + if(tmp[layer].type == "none") + return new Decimal (0) if (tmp[layer].gainExp.eq(0)) return new Decimal(0) if (type=="static") { if ((!layers[layer].canBuyMax()) || tmp[layer].baseAmount.lt(tmp[layer].requires)) return new Decimal(1) @@ -63,6 +64,8 @@ function getResetGain(layer, useType = null) { function getNextAt(layer, canMax=false, useType = null) { let type = useType if (!useType) type = layers[layer].type + if(tmp[layer].type == "none") + return new Decimal (Infinity) if (tmp[layer].gainMult.lte(0)) return new Decimal(Infinity) if (tmp[layer].gainExp.lte(0)) return new Decimal(Infinity) @@ -110,6 +113,8 @@ function canReset(layer) return tmp[layer].baseAmount.gte(tmp[layer].requires) else if(tmp[layer].type== "static") return tmp[layer].baseAmount.gte(tmp[layer].nextAt) + if(tmp[layer].type == "none") + return false else return layers[layer].canReset() } diff --git a/js/layers.js b/js/layers.js index c7d43b4..a634b37 100644 --- a/js/layers.js +++ b/js/layers.js @@ -460,18 +460,8 @@ addLayer("a", { points: new Decimal(0), }}, color: "yellow", - requires: new Decimal (1), resource: "achievement power", - baseResource: "achievements", - baseAmount() {return player.points}, - type: "normal", // A "Custom" type which is effectively static - exponent: 0.5, - gainMult() { - return new Decimal(1) - }, - gainExp() { - return new Decimal(1) - }, + type: "none", row: "side", layerShown() {return true}, tooltip() { // Optional, tooltip displays when the layer is locked @@ -500,8 +490,8 @@ addLayer("a", { onComplete() {console.log("Bork bork bork!")} }, }, - tabFormat: [ - "main-display", "blank", "blank", "achievements", + midsection: [ + "achievements", ] }, ) diff --git a/js/utils.js b/js/utils.js index aff4914..3dd4083 100644 --- a/js/utils.js +++ b/js/utils.js @@ -608,6 +608,8 @@ function prestigeButtonText(layer) else if(tmp[layer].type== "static") return `${tmp[layer].resetDescription !== undefined ? tmp[layer].resetDescription : "Reset for "}+${formatWhole(tmp[layer].resetGain)} ${tmp[layer].resource}

${player[layer].points.lt(20) ? (tmp[layer].baseAmount.gte(tmp[layer].nextAt)&&(tmp[layer].canBuyMax !== undefined) && tmp[layer].canBuyMax?"Next":"Req") : ""}: ${formatWhole(tmp[layer].baseAmount)} / ${(tmp[layer].roundUpCost ? formatWhole(tmp[layer].nextAtDisp) : format(tmp[layer].nextAtDisp))} ${ tmp[layer].baseResource } ` + else if(tmp[layer].type == "none") + return "" else return layers[layer].prestigeButtonText() } diff --git a/js/v.js b/js/v.js index 2fa7637..2e70842 100644 --- a/js/v.js +++ b/js/v.js @@ -178,7 +178,7 @@ function loadVue() { Vue.component('prestige-button', { props: ['layer', 'data'], template: ` - From af78b0d99b9d076849446cc2b3097eaae2d3698c Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Wed, 14 Oct 2020 23:24:34 -0400 Subject: [PATCH 30/33] Updated treenode borders --- js/layers.js | 2 +- style.css | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/js/layers.js b/js/layers.js index a634b37..5c4244e 100644 --- a/js/layers.js +++ b/js/layers.js @@ -486,7 +486,7 @@ addLayer("a", { name: "EIEIO", done() {return player.f.points.gte(1)}, goalTooltip: "Get a farm point.", // Shows when achievement is not completed - doneTooltip: "Get a farm point.\n\nReward: The dinosaur is now your friend.", // Showed when the achievement is completed + doneTooltip: "Get a farm point.\n\nReward: The dinosaur is now your friend (you can max Farm Points).", // Showed when the achievement is completed onComplete() {console.log("Bork bork bork!")} }, }, diff --git a/style.css b/style.css index 6bf9e42..f427315 100644 --- a/style.css +++ b/style.css @@ -65,7 +65,7 @@ h1, h2, h3, b, input { height: 100px; width: 100px; border: var(--hqProperty1); - border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125); + border-color: rgba(0, 0, 0, 0.125); border-radius: 50%; box-shadow: var(--hqProperty2a), var(--hqProperty2b); font-size: 40px; @@ -78,7 +78,7 @@ h1, h2, h3, b, input { height: 60px; width: 60px; border: var(--hqProperty1); - border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125); + border-color: rgba(0, 0, 0, 0.125); border-radius: 50%; box-shadow: var(--hqProperty2a), var(--hqProperty2b); font-size: 30px; @@ -104,7 +104,7 @@ h1, h2, h3, b, input { .treeNode.notify { transform: scale(1.1, 1.1); - border-color: rgba(255, 0, 0, 0.125) rgba(255, 0, 0, 0.25) rgba(255, 0, 0, 0.25) rgba(255, 0, 0, 0.125); + border-color: rgba(0, 0, 0, 0.125); box-shadow: var(--hqProperty2a), 0px 0px 20px #ff0000; z-index: 3 } @@ -174,7 +174,7 @@ h1, h2, h3, b, input { margin: 5px 5px 5px 5px; border-radius: 25%; border: 2px solid; - border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125); + border-color: rgba(0, 0, 0, 0.125); } @@ -188,7 +188,7 @@ h1, h2, h3, b, input { width: 180px; border-radius: 25%; border: 4px solid; - border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125); + border-color: rgba(0, 0, 0, 0.125); } .upg { @@ -196,7 +196,7 @@ h1, h2, h3, b, input { width: 120px; border-radius: 25%; border: 2px solid; - border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125); + border-color: rgba(0, 0, 0, 0.125); font-size: 10px; } @@ -205,7 +205,7 @@ h1, h2, h3, b, input { width: 90px; border-radius: 25%; border: 2px solid; - border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125); + border-color: rgba(0, 0, 0, 0.125); font-size: 10px; color: white; text-shadow: 0px 0px 2px #000000; @@ -219,7 +219,7 @@ h1, h2, h3, b, input { width: 200px; border-radius: 25%; border: 2px solid; - border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125); + border-color: rgba(0, 0, 0, 0.125); font-size: 10px; } @@ -228,7 +228,7 @@ h1, h2, h3, b, input { width: 200px; border-radius: 25%; border: 2px solid; - border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125); + border-color: rgba(0, 0, 0, 0.125); } .longUpg { @@ -237,7 +237,7 @@ h1, h2, h3, b, input { background: var(--points); border-radius: 50%; border: 2px solid; - border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125); + border-color: rgba(0, 0, 0, 0.125); font-size: 10px; } @@ -246,7 +246,7 @@ h1, h2, h3, b, input { width: 40px; border-radius: 25%; border: 2px solid; - border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125); + border-color: rgba(0, 0, 0, 0.125); } #points { @@ -373,7 +373,7 @@ a { background-color: #bf8f8f; border: 4px solid; border-radius: 4px; - border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125); + border-color: rgba(0, 0, 0, 0.125); color: rgba(0, 0, 0, 0.5); } @@ -383,7 +383,7 @@ a { background-color: #77bf5f; border: 4px solid; border-radius: 4px; - border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125); + border-color: rgba(0, 0, 0, 0.125); color: rgba(0, 0, 0, 0.5); } @@ -459,7 +459,7 @@ ul { .hChallenge { background-color: #bf8f8f; border: 4px solid; - border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125); + border-color: rgba(0, 0, 0, 0.125); color: rgba(0, 0, 0, 0.5); width: 300px; height: 300px; From 30673fd80d7dff915491a667ee5b1dcbd14d6e36 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Wed, 14 Oct 2020 23:31:05 -0400 Subject: [PATCH 31/33] Renamed Order --- 2.0-format-changes.md | 2 ++ docs/layer-features.md | 6 +++--- js/game.js | 8 ++++---- js/layerSupport.js | 1 + js/layers.js | 4 ++-- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/2.0-format-changes.md b/2.0-format-changes.md index 78081f6..fbead8f 100644 --- a/2.0-format-changes.md +++ b/2.0-format-changes.md @@ -16,6 +16,8 @@ All instances of: amt -> amount desc -> description resCeil -> roundUpCost + order -> unlockOrderS + incr_order -> increaseUnlockOrder Challenges: desc -> challengeDescription diff --git a/docs/layer-features.md b/docs/layer-features.md index 2d782ff..bd6c363 100644 --- a/docs/layer-features.md +++ b/docs/layer-features.md @@ -26,7 +26,7 @@ Key: Optional: total: A Decimal, tracks total amount of main prestige currency best: A Decimal, tracks highest amount of main prestige currency - order: used to keep track of relevant layers unlocked before this one. + unlockOrder: used to keep track of relevant layers unlocked before this one. - color: A color associated with this layer, used in many places. (A string in hex format with a #) @@ -110,7 +110,7 @@ Key: - requires: A Decimal, the amount of the base needed to gain 1 of the prestige currency. Also the amount required to unlock the layer. - You can instead make this a function, to make it harder if another layer was unlocked first (based on "order"). + You can instead make this a function, to make it harder if another layer was unlocked first (based on unlockOrder). - exponent: Used as described above. @@ -174,7 +174,7 @@ Key: - resetsNothing: **optional**, returns true if this layer shouldn't trigger any resets when you prestige. -- incr_order: **optional**, an array of layer ids. When this layer is unlocked for the first time, the "order" value +- increaseUnlockOrder: **optional**, an array of layer ids. When this layer is unlocked for the first time, the unlockOrder value 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. diff --git a/js/game.js b/js/game.js index f148a49..f07f13b 100644 --- a/js/game.js +++ b/js/game.js @@ -193,10 +193,10 @@ function doReset(layer, force=false) { player[layer].unlocked = true; needCanvasUpdate = true; - if (layers[layer].incr_order){ - lrs = layers[layer].incr_order + if (layers[layer].increaseUnlockOrder){ + lrs = layers[layer].increaseUnlockOrder for (lr in lrs) - if (!player[lrs[lr]].unlocked) player[lrs[lr]].order++ + if (!player[lrs[lr]].unlocked) player[lrs[lr]].unlockOrder++ } } @@ -230,7 +230,7 @@ function resetRow(row) { doReset(pre_layers[0], true) for (let layer in layers) { player[layers[layer]].unlocked = false - if (player[layers[layer]].order) player[layers[layer]].order = 0 + if (player[layers[layer]].unlockOrder) player[layers[layer]].unlockOrder = 0 } player.points = new Decimal(10) updateTemp(); diff --git a/js/layerSupport.js b/js/layerSupport.js index 8aa1cc2..ef27d29 100644 --- a/js/layerSupport.js +++ b/js/layerSupport.js @@ -112,6 +112,7 @@ function updateLayers(){ if(!layers[layer].componentStyles) layers[layer].componentStyles = {} if(layers[layer].symbol === undefined) layers[layer].symbol = layer.charAt(0).toUpperCase() + layer.slice(1) + if(layers[layer].unlockOrder === undefined) layers[layer].unlockOrder = 0 row = layers[layer].row if(!ROW_LAYERS[row]) ROW_LAYERS[row] = {} diff --git a/js/layers.js b/js/layers.js index 5c4244e..0a80efd 100644 --- a/js/layers.js +++ b/js/layers.js @@ -110,7 +110,7 @@ addLayer("c", { currencyLayer: "", // Leave empty if not in a layer "e.g. points" unlocked() { return (hasUpgrade(this.layer, 12))}, onPurchase() { // This function triggers when the upgrade is purchased - player[this.layer].order = 0 + player[this.layer].unlockOrder = 0 }, style() { if (hasUpgrade(this.layer, this.id)) return { @@ -189,7 +189,7 @@ addLayer("c", { {key: "c", description: "C: reset for lollipops or whatever", onPress(){if (player[this.layer].unlocked) doReset(this.layer)}}, {key: "ctrl+c" + this.layer, description: "Ctrl+c: respec things", onPress(){if (player[this.layer].unlocked) respecBuyables(this.layer)}}, ], - incr_order: [], // Array of layer names to have their order increased when this one is first unlocked + increaseUnlockOrder: [], // Array of layer names to have their order increased when this one is first unlocked microtabs: { stuff: { From 8e4bf3f953a97865bfd9b4cf5a84db609e08d1ed Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Wed, 14 Oct 2020 23:32:42 -0400 Subject: [PATCH 32/33] Update 2.0-format-changes.md --- 2.0-format-changes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2.0-format-changes.md b/2.0-format-changes.md index fbead8f..3475732 100644 --- a/2.0-format-changes.md +++ b/2.0-format-changes.md @@ -16,7 +16,7 @@ All instances of: amt -> amount desc -> description resCeil -> roundUpCost - order -> unlockOrderS + order -> unlockOrder incr_order -> increaseUnlockOrder Challenges: From 8889bac5c9bfead06c4541227e20cbf6033b6d40 Mon Sep 17 00:00:00 2001 From: Acamaeda Date: Thu, 15 Oct 2020 13:29:25 -0400 Subject: [PATCH 33/33] Final touchups --- docs/achievements.md | 2 +- docs/getting-started.md | 4 ++-- docs/layer-features.md | 12 ++++++------ docs/milestones.md | 2 +- js/utils.js | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/achievements.md b/docs/achievements.md index b03d2c5..e7f856f 100644 --- a/docs/achievements.md +++ b/docs/achievements.md @@ -1,4 +1,4 @@ -#Achievements +# Achievements Achievements are awarded to the player when they meet a certain goal, and give some benefit. Currently, they are pretty basic, but additional features will be added later to help. diff --git a/docs/getting-started.md b/docs/getting-started.md index 464e353..2855de2 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -17,7 +17,7 @@ The benefits of using Github: - It lets you collaborate with other people, if you want to. -# Getting set up with Github and The Modding Tree: +## Getting set up with Github and The Modding Tree: 1. Install [Github Desktop](https://desktop.github.com/) and [Visual Studio Code](https://code.visualstudio.com/). @@ -36,7 +36,7 @@ The benefits of using Github: 6. Select that you're using it for your own purposes, and click continue. It will download the files and handle everything. -# Using your repository +## Using your repository 1. Click on "show in finder" to the right, and then open index.html. This will let you view and test your project! diff --git a/docs/layer-features.md b/docs/layer-features.md index bd6c363..3ae4cbe 100644 --- a/docs/layer-features.md +++ b/docs/layer-features.md @@ -10,7 +10,7 @@ Key: - **sometimes required**: This is may be required, depending on other things in the layer. - **optional**: You can leave this out if you don't intend to use that feature for the layer. -# Layer Definition features +## Layer Definition features - layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar to access the save value. It makes copying code to new layers easier. It is also assigned to all upgrades and buyables and such. @@ -66,7 +66,7 @@ Key: standard tab layout. (cannot do subtabs) -# Big features (all optional) +## Big features (all optional) - upgrades: A grid of one-time purchases which can have unique upgrade conditions, currency costs, and bonuses. [Explanations are in a separate file.](upgrades.md) @@ -94,7 +94,7 @@ Key: [Explanations are in a separate file.](achievements.md) -# Prestige formula features +## Prestige formula features - type: Determines which prestige formula you use. "normal": The amount of currency you gain is independent of its current amount (like Prestige). @@ -134,7 +134,7 @@ Key: -# Tree/node features +## Tree/node features - symbol: **optional**, the text that appears on this layer's node. Default is the layer id with the first letter capitalized @@ -151,7 +151,7 @@ Key: is unlocked or locked, respectively. By default the tooltips behave the same as in the original Prestige Tree. -# Other features +## Other features - doReset(resettingLayer): **optional**, is triggered when a layer on a row greater than or equal to this one does a reset. The default behavior is to reset everything on the row, but only if it was triggered by a layer in a higher row. @@ -191,7 +191,7 @@ Key: ``` -# Custom Prestige type +## Custom Prestige type - getResetGain(): **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 diff --git a/docs/milestones.md b/docs/milestones.md index ff36b7e..a690095 100644 --- a/docs/milestones.md +++ b/docs/milestones.md @@ -1,4 +1,4 @@ -#Milestones +# Milestones Milestones are awarded to the player when they meet a certain goal, and give some benefit. Milestones should be formatted like this: diff --git a/js/utils.js b/js/utils.js index 3dd4083..98d1b94 100644 --- a/js/utils.js +++ b/js/utils.js @@ -34,7 +34,7 @@ function format(decimal, precision=2) { var slog = decimal.slog() if (slog.gte(1e6)) return "F" + format(slog.floor()) else return Decimal.pow(10, slog.sub(slog.floor())).toStringWithDecimalPlaces(3) + "F" + commaFormat(slog.floor(), 0) - } else if (decimal.gte("1e1000")) return (Math.floor(decimal.mantissa + 0.01) + ("e"+formatWhole(decimal.log10()))) + } else if (decimal.gte("1e1000")) return (Math.floor(decimal.mantissa + 0.01) + ("e"+formatWhole(decimal.log10().floor()))) else if (decimal.gte(1e9)) return exponentialFormat(decimal, precision) else if (decimal.gte(1e3)) return commaFormat(decimal, 0) else return commaFormat(decimal, precision)