diff --git a/js/Demo/demoLayers.js b/js/Demo/demoLayers.js
index 1bbb5f5..bdcb271 100644
--- a/js/Demo/demoLayers.js
+++ b/js/Demo/demoLayers.js
@@ -1,3 +1,157 @@
+
+var testTree = [["f", "c"],
+["g", "spook", "h"]]
+
+// 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() {return hasAchievement('a', 13)},
+
+ 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;
+ }},
+ },
+ },
+
+},
+)
+
+// A side layer with achievements, with no prestige
+addLayer("a", {
+ startData() { return {
+ unlocked: true,
+ points: new Decimal(0),
+ }},
+ color: "yellow",
+ resource: "achievement power",
+ row: "side",
+ layerShown() {return true},
+ 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)},
+ tooltip: "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!")}
+ },
+ },
+ midsection: [
+ "achievements",
+ ]
+ },
+)
+
+
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.
@@ -194,7 +348,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) layerDataReset(this.layer, ["upgrades", "challenges"]) // This is actually the default behavior
+ if(layers[resettingLayer].row > this.row) layerDataReset(this.layer) // This is actually the default behavior
},
layerShown() {return true}, // Condition for when layer appears on the tree
automate() {
@@ -238,7 +392,7 @@ addLayer("c", {
width: 300,
height: 30,
progress() {
- return (player.points.log(10).div(10)).toNumber()
+ return (player.points.add(1).log(10).div(10)).toNumber()
},
display() {
return format(player.points) + " / 1e10 points"
@@ -287,7 +441,7 @@ addLayer("c", {
buttonStyle() {return {'color': 'orange'}},
shouldNotify: true,
content:
- ["main-display",
+ [["tree", testTree], "main-display",
"prestige-button", "resource-display",
["blank", "5px"], // Height
["raw-html", function() {return ""}],
@@ -361,165 +515,30 @@ addLayer("c", {
resetDescription: "Melt your points into ",
})
-// 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() {return hasAchievement('a', 13)},
-
- 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;
- }},
- },
- },
-
-},
-)
-
-// A side layer with achievements, with no prestige
-addLayer("a", {
- startData() { return {
- unlocked: true,
- points: new Decimal(0),
- }},
- color: "yellow",
- resource: "achievement power",
- row: "side",
- layerShown() {return true},
- 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)},
- tooltip: "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!")}
- },
- },
- midsection: [
- "achievements",
- ]
- },
-)
-
-
// A "ghost" layer which offsets f in the tree
-addLayer("spook", {
- startData() { return {
- unlocked: true,
- points: new Decimal(0),
- }},
- type: "none",
+addNode("spook", {
row: 1,
layerShown: "ghost",
},
)
+
+// A "ghost" layer which offsets f in the tree
+addNode("g", {
+ row: "h",
+ branches: ["c"],
+ layerShown: true,
+
+},
+)
+
+
+// A "ghost" layer which offsets f in the tree
+addNode("h", {
+ row: "g",
+ branches: ["g"],
+ layerShown: true,
+
+},
+)
+
diff --git a/js/canvas.js b/js/canvas.js
index 323858f..e0f3444 100644
--- a/js/canvas.js
+++ b/js/canvas.js
@@ -17,9 +17,9 @@ function resizeCanvas() {
if (!retrieveCanvasData()) return
canvas.width = 0;
canvas.height = 0;
- canvas.width = document.getElementById("treeTab").scrollWidth;
- canvas.height = document.getElementById("treeTab").scrollHeight;
- drawTree();
+ canvas.width = window.innerWidth;
+ canvas.height = window.innerHeight;
+ drawTree();
}
var colors = {
diff --git a/js/game.js b/js/game.js
index 861c3c9..4414b2e 100644
--- a/js/game.js
+++ b/js/game.js
@@ -91,6 +91,7 @@ function canReset(layer)
function rowReset(row, layer) {
for (lr in ROW_LAYERS[row]){
if(layers[lr].doReset) {
+
player[lr].activeChallenge = null // Exit challenges on any row reset on an equal or higher row
layers[lr].doReset(layer)
}
@@ -287,28 +288,28 @@ function gameLoop(diff) {
for (x = 0; x <= maxRow; x++){
for (item in TREE_LAYERS[x]) {
- let layer = TREE_LAYERS[x][item].layer
+ let layer = TREE_LAYERS[x][item]
if (layers[layer].update) layers[layer].update(diff);
}
}
for (row in OTHER_LAYERS){
for (item in OTHER_LAYERS[row]) {
- let layer = OTHER_LAYERS[row][item].layer
+ let layer = OTHER_LAYERS[row][item]
if (layers[layer].update) layers[layer].update(diff);
}
}
for (x = maxRow; x >= 0; x--){
for (item in TREE_LAYERS[x]) {
- let layer = TREE_LAYERS[x][item].layer
+ let layer = TREE_LAYERS[x][item]
if (layers[layer].automate) layers[layer].automate();
}
}
for (row in OTHER_LAYERS){
for (item in OTHER_LAYERS[row]) {
- let layer = OTHER_LAYERS[row][item].layer
+ let layer = OTHER_LAYERS[row][item]
if (layers[layer].automate) layers[layer].automate();
}
}
diff --git a/js/layerSupport.js b/js/layerSupport.js
index 2711b3e..ec77831 100644
--- a/js/layerSupport.js
+++ b/js/layerSupport.js
@@ -149,17 +149,33 @@ function updateLayers(){
}
for (row in OTHER_LAYERS) {
OTHER_LAYERS[row].sort((a, b) => (a.position > b.position) ? 1 : -1)
+ for (layer in OTHER_LAYERS[row])
+ OTHER_LAYERS[row][layer] = OTHER_LAYERS[row][layer].layer
}
for (row in TREE_LAYERS) {
TREE_LAYERS[row].sort((a, b) => (a.position > b.position) ? 1 : -1)
+ for (layer in TREE_LAYERS[row])
+ TREE_LAYERS[row][layer] = TREE_LAYERS[row][layer].layer
}
+ let treeLayers2 = []
+ for (x = 0; x < maxRow + 1; x++) {
+ if (TREE_LAYERS[x]) treeLayers2.push(TREE_LAYERS[x])
+ }
+ TREE_LAYERS = treeLayers2
updateHotkeys()
}
function addLayer(layerName, layerData){ // Call this to add layers from a different file!
layers[layerName] = layerData
+ layers[layerName].isLayer = true
}
+function addNode(layerName, layerData){ // Does the same thing
+ layers[layerName] = layerData
+ layers[layerName].isLayer = false
+}
+
+
// If data is a function, return the result of calling it. Otherwise, return the data.
function readData(data, args=null){
if (!!(data && data.constructor && data.call && data.apply))
diff --git a/js/utils.js b/js/utils.js
index b9f17fc..58f7bd4 100644
--- a/js/utils.js
+++ b/js/utils.js
@@ -111,7 +111,9 @@ function getStartPlayer() {
playerdata.infoboxes = {}
for (layer in layers){
- playerdata[layer] = layers[layer].startData()
+ playerdata[layer] = {}
+ if (layers[layer].startData)
+ 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)
@@ -591,12 +593,7 @@ function showTab(name) {
var toTreeTab = name == "none"
player.tab = name
-
- if (toTreeTab != onTreeTab) {
- document.getElementById("treeTab").className = toTreeTab ? "fullWidth" : "col left"
- onTreeTab = toTreeTab
- resizeCanvas()
- }
+
delete player.notify[name]
}
@@ -616,6 +613,7 @@ function nodeShown(layer) {
}
function layerunlocked(layer) {
+ if (tmp[layer] && tmp[layer].type == "none") return (player[layer].unlocked)
return LAYERS.includes(layer) && (player[layer].unlocked || (tmp[layer].baseAmount.gte(tmp[layer].requires) && tmp[layer].layerShown))
}
diff --git a/js/v.js b/js/v.js
index 74ffc92..917a258 100644
--- a/js/v.js
+++ b/js/v.js
@@ -315,7 +315,7 @@ function loadVue() {
-
+
`
})
@@ -367,6 +367,20 @@ function loadVue() {
`
})
+ // Data is an array with the structure of the tree
+ Vue.component('tree', {
+ props: ['layer', 'data'],
+ template: `
+
+
+
+
+
+
+
+
+ `
+ })
// These are for buyables, data is the id of the corresponding buyable
Vue.component('sell-one', {
@@ -394,6 +408,36 @@ function loadVue() {
`
})
+ Vue.component('button-node', {
+ props: ['layer', 'abb', 'size'],
+ template: `
+
+ `
+ })
+
Vue.component('layer-node', {
props: ['layer', 'abb', 'size'],
template: `
@@ -422,7 +466,7 @@ function loadVue() {
{{abb}}
`
- },
+ })
Vue.component('layer-tab', {
props: ['layer', 'back'],
@@ -461,7 +505,7 @@ function loadVue() {
- )
+
app = new Vue({