mirror of
https://github.com/Acamaeda/The-Modding-Tree.git
synced 2024-11-22 00:21:32 +00:00
Moved the original "game" to "demo" and made a basic one to build from
This commit is contained in:
parent
2316e3e635
commit
8dfb33455b
7 changed files with 787 additions and 516 deletions
|
@ -8,6 +8,7 @@
|
||||||
- Added the ability to display more things at the top of the tree tab below points.
|
- Added the ability to display more things at the top of the tree tab below points.
|
||||||
- Made the endgame condition customizable
|
- Made the endgame condition customizable
|
||||||
- Added "sell one" and "sell all" buttons for buyables.
|
- Added "sell one" and "sell all" buttons for buyables.
|
||||||
|
- Moved the old "game" to demo.js, and replaced it with a minimal game that won't cause issues when edited.
|
||||||
- Fixed issues with version number
|
- Fixed issues with version number
|
||||||
- Fixed number formatting issue making things like "10e9" appear.
|
- Fixed number formatting issue making things like "10e9" appear.
|
||||||
|
|
||||||
|
|
185
demo.html
Normal file
185
demo.html
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
|
||||||
|
<script type="text/javascript" src="js/break_eternity.js"></script>
|
||||||
|
<script type="text/javascript" src="js/layerSupport.js"></script>
|
||||||
|
<script type="text/javascript" src="js/demo/demoLayers.js"></script>
|
||||||
|
<script type="text/javascript" src="js/demo/demoMod.js"></script>
|
||||||
|
<script type="text/javascript" src="js/temp.js"></script>
|
||||||
|
<script type="text/javascript" src="js/game.js"></script>
|
||||||
|
<script type="text/javascript" src="js/utils.js"></script>
|
||||||
|
<script type="text/javascript" src="js/v.js"></script>
|
||||||
|
<script type="text/javascript" src="js/canvas.js"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body onload="load()">
|
||||||
|
<div id="app">
|
||||||
|
<div v-if="false" id="loadingSection" class="fullWidth">
|
||||||
|
<h1>Loading... (If this takes too long it means there was a serious error!)</h1>
|
||||||
|
</div>
|
||||||
|
<div class="vl" v-if="player.tab!='tree'&&player.tab!='gameEnded'"></div>
|
||||||
|
<div v-if="player.tab=='gameEnded'" class="fullWidth">
|
||||||
|
<br>
|
||||||
|
<h2>{{modInfo.name}} {{VERSION.withoutName}}</h2><br><br>
|
||||||
|
<h3>Congratulations! You have reached the end and beaten this game, but for now...</h3><br>
|
||||||
|
<h3>Please check the Discord to see there are new content updates!</h3><br><br>
|
||||||
|
<div v-if="!player.timePlayedReset">It took you {{formatTime(player.timePlayed)}} to beat the game.</div>
|
||||||
|
<div v-if="player.timePlayedReset">Make sure that you record the time in your stream or else your speedrun won't count!</div>
|
||||||
|
<br>
|
||||||
|
<button class="longUpg can" onclick="hardReset(true)">Play Again</button> <button class="longUpg can" onclick="keepGoing()">Keep Going</button>
|
||||||
|
<br><br><br>
|
||||||
|
<a class="link" href="https://discord.gg/F3xveHV" target="_blank">The Modding Tree Discord</a><br>
|
||||||
|
<a class="link" href="http://discord.gg/wwQfgPa" target="_blank">Main Prestige Tree Discord</a><br>
|
||||||
|
<br><br>
|
||||||
|
If you would like to speedrun this, press Play Again and record your attempt, then submit on the Discord Server in the channel #speedrun-submissions.
|
||||||
|
<br><br><br>
|
||||||
|
<h1>Oh, you are still reading this?</h1>
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
<div v-if="player.tab=='changelog'" class="col right">
|
||||||
|
<button class="back" onclick="showTab('tree')">←</button><br><br><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="player.tab=='info'" class="col right">
|
||||||
|
<button class="back" onclick="showTab('tree')">←</button><br>
|
||||||
|
<h2>{{modInfo.name}}</h2>
|
||||||
|
<br>
|
||||||
|
<h3>{{VERSION.withName}}</h3>
|
||||||
|
<br>
|
||||||
|
The Modding Tree {{TMT_VERSION.tmtNum}} by Acamaeda
|
||||||
|
<br>
|
||||||
|
The Prestige Tree made by Jacorb and Aarex
|
||||||
|
<br>
|
||||||
|
Original idea by papyrus (on discord)
|
||||||
|
<br><br>
|
||||||
|
<a v-bind:href="modInfo.changelogLink" target="_blank" class="link" >Changelog</a><br>
|
||||||
|
<span v-if="modInfo.discordLink"><a class="link" v-bind:href="modInfo.discordLink" target="_blank">{{modInfo.discordName}}</a><br></span>
|
||||||
|
<a class="link" href="https://discord.gg/F3xveHV" target="_blank" v-bind:style="modInfo.discordLink ? {'font-size': '16px'} : {}">The Modding Tree Discord</a><br>
|
||||||
|
<a class="link" href="http://discord.gg/wwQfgPa" target="_blank" v-bind:style="{'font-size': '16px'}">Main Prestige Tree server</a><br>
|
||||||
|
<br>
|
||||||
|
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 <a href="https://discord.gg/wwQfgPa" target="_blank">my discord</a>.
|
||||||
|
<br><br>
|
||||||
|
Time Played: {{ formatTime(player.timePlayed) }}<br><br>
|
||||||
|
<h3>Hotkeys</h3><br>
|
||||||
|
<span v-for="key in hotkeys" v-if="player[key.layer].unlocked"><br>{{key.description}}</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="player.tab=='options'" class="col right">
|
||||||
|
<button class="back" onclick="showTab('tree')">←</button><br>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><button class="opt" onclick="save()">Save</button></td>
|
||||||
|
<td><button class="opt" onclick="toggleOpt('autosave')">Autosave: {{ player.autosave?"ON":"OFF" }}</button></td>
|
||||||
|
<td><button class="opt" onclick="hardReset()">HARD RESET</button></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><button class="opt" onclick="exportSave()">Export to clipboard</button></td>
|
||||||
|
<td><button class="opt" onclick="importSave()">Import</button></td>
|
||||||
|
<td><button class="opt" onclick="toggleOpt('offlineProd')">Offline Prod: {{ player.offlineProd?"ON":"OFF" }}</button></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><button class="opt" onclick="switchTheme()">Theme: {{ getThemeName() }}</button></td>
|
||||||
|
<td><button class="opt" onclick="adjustMSDisp()">Show Milestones: {{ player.msDisplay.toUpperCase() }}</button></td>
|
||||||
|
<td><button class="opt" onclick="toggleOpt('hqTree')">High-Quality Tree: {{ player.hqTree?"ON":"OFF" }}</button></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><button class="opt" onclick="toggleOpt('hideChallenges')">Completed Challenges: {{ player.hideChallenges?"HIDDEN":"SHOWN" }}</button></td>
|
||||||
|
<!-- <td><button class="opt" onclick="toggleOpt('oldStyle')">Style: {{ player.oldStyle?"v1.0":"NEW" }}</button></td>-->
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div id="treeOverlay" class="treeOverlay" v-if="player.tab!='gameEnded'" onscroll="resizeCanvas()" v-bind:class="{ fullWidth: player.tab == 'tree', col: player.tab != 'tree', left: player.tab != 'tree'}">
|
||||||
|
<div id="version" class="overlayThing" style="margin-right: 13px">{{VERSION.withoutName}}</div>
|
||||||
|
<img id="optionWheel" class="overlayThing" v-if="player.tab!='options'" src="options_wheel.png" onclick="showTab('options')"></img>
|
||||||
|
<div id="info" v-if="player.tab!='info'" class="overlayThing" onclick="showTab('info')"><br>i</div>
|
||||||
|
<img id="discord" class="overlayThing" onclick="window.open((modInfo.discordLink ? modInfo.discordLink : 'https://discord.gg/F3xveHV'),'mywindow')" src="discord.png" target="_blank"></img>
|
||||||
|
<div class="overlayThing" style="padding-bottom:7px; width: 90%">
|
||||||
|
<span v-if="player.devSpeed && player.devSpeed != 1" class="overlayThing">
|
||||||
|
<br>Dev Speed: {{format(player.devSpeed)}}x<br>
|
||||||
|
</span>
|
||||||
|
<span v-if="player.offTime !== undefined" class="overlayThing">
|
||||||
|
<br>Offline Time: {{formatTime(player.offTime.remain)}}<br>
|
||||||
|
</span>
|
||||||
|
<span v-if="false && !player.keepGoing" class="overlayThing">
|
||||||
|
<br>Reach {{formatWhole(ENDGAME)}} to beat the game!<br>
|
||||||
|
</span>
|
||||||
|
<br>
|
||||||
|
<span v-if="player.points.lt('1e1000')" class="overlayThing">You have </span>
|
||||||
|
<h2 class="overlayThing" id="points">{{format(player.points)}}</h2>
|
||||||
|
<span v-if="player.points.lt('1e1e6')" class="overlayThing"> {{modInfo.pointsName}}</span>
|
||||||
|
<br>
|
||||||
|
<span v-if="canGenPoints()" class="overlayThing">({{format(getPointGen())}}/sec)</span>
|
||||||
|
<div v-for="thing in tmp.displayThings" class="overlayThing"><span v-if="thing" v-html="thing"></span></div>
|
||||||
|
</div>
|
||||||
|
<div class="sideLayers" >
|
||||||
|
<div v-for="node in OTHER_LAYERS['side']"><layer-node :layer='node.layer' :abb='layers[node.layer].symbol' :size="'small'"></layer-node></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="treeTab" style="z-index: 0" v-if="player.tab!='gameEnded'" onscroll="resizeCanvas()" v-bind:class="{ fullWidth: player.tab == 'tree', col: player.tab != 'tree', left: player.tab != 'tree'}">
|
||||||
|
<br><br><br><br>
|
||||||
|
<div id="fakeHead" style="visibility: hidden;">
|
||||||
|
<span v-if="player.devSpeed && player.devSpeed != 1" class="overlayThing">
|
||||||
|
<br>Dev Speed: {{format(player.devSpeed)}}x<br>
|
||||||
|
</span>
|
||||||
|
<span v-if="player.offTime !== undefined" class="overlayThing">
|
||||||
|
<br>Offline Time: {{formatTime(player.offTime.remain)}}<br>
|
||||||
|
</span>
|
||||||
|
<span v-if="false && !player.keepGoing" class="overlayThing">
|
||||||
|
<br>Reach {{formatWhole(ENDGAME)}} to beat the game!<br>
|
||||||
|
</span>
|
||||||
|
<br>
|
||||||
|
<span v-if="player.points.lt('1e1000')" class="overlayThing">You have </span>
|
||||||
|
<h2 class="overlayThing" id="points">{{format(player.points)}}</h2>
|
||||||
|
<span v-if="player.points.lt('1e1e6')" class="overlayThing"> {{modInfo.pointsName}}</span>
|
||||||
|
<br>
|
||||||
|
<span v-if="canGenPoints()" class="overlayThing">({{format(getPointGen())}}/sec)</span>
|
||||||
|
<div v-for="thing in tmp.displayThings" class="overlayThing"><span v-if="thing" v-html="thing"></span></div>
|
||||||
|
</div>
|
||||||
|
<span v-for="row in TREE_LAYERS"><table>
|
||||||
|
<td v-if="player.tab=='tree'&& someLayerUnlocked(row) && row != 0" class="left"><br><br><img class="remove" src="remove.png" onclick="resetRow(row)"></img></td>
|
||||||
|
<td v-for="node in row"><layer-node :layer='node.layer' :abb='layers[node.layer].symbol'></layer-node></td>
|
||||||
|
<table><button class="treeNode hidden"></button></td></table>
|
||||||
|
</span>
|
||||||
|
<canvas id="treeCanvas" class="canvas"></canvas>
|
||||||
|
</div>
|
||||||
|
<div v-for="layer in LAYERS" >
|
||||||
|
<div v-if="player.tab==layer" v-bind:class="'col right fast tab'" v-bind:style="[tmp[layer].style ? tmp[layer].style : {}, (layers[layer].tabFormat && !Array.isArray(tmp[layer].tabFormat)) ? tmp[layer].tabFormat[player.subtabs[layer].mainTabs].style : {}]">
|
||||||
|
<button class="back" onclick="showTab('tree')">←</button><br><br><br>
|
||||||
|
<div v-if="!layers[layer].tabFormat">
|
||||||
|
<main-display v-bind:style="tmp[layer].componentStyles['main-display']" :layer="layer"></main-display>
|
||||||
|
<div v-if="tmp[layer].type !== 'none'">
|
||||||
|
<prestige-button v-bind:style="tmp[layer].componentStyles['prestige-button']" :layer="layer"></prestige-button>
|
||||||
|
<span v-if="tmp[layer].type=='normal' && tmp[layer].resetGain.lt(100) && player[layer].points.lt(1e3)"><br>You have {{formatWhole(tmp[layer].baseAmt)}} {{tmp[layer].baseResource}}</span>
|
||||||
|
</div>
|
||||||
|
<br><br>
|
||||||
|
<span v-if="player[layer].best != undefined">Your best {{tmp[layer].resource}} is {{formatWhole(player[layer].best)}}<br></span>
|
||||||
|
<span v-if="player[layer].total != undefined">You have made a total of {{formatWhole(player[layer].total)}} {{tmp[layer].resource}}<br></span>
|
||||||
|
<milestones v-bind:style="tmp[layer].componentStyles.milestones" :layer="layer"></milestones>
|
||||||
|
<div v-if="Array.isArray(tmp[layer].midsection)">
|
||||||
|
<column :layer="layer" :data="tmp[layer].midsection"></column>
|
||||||
|
</div>
|
||||||
|
<clickables v-bind:style="tmp[layer].componentStyles['clickables']" :layer="layer"></clickables>
|
||||||
|
<buyables v-bind:style="tmp[layer].componentStyles.buyables" :layer="layer"></buyables>
|
||||||
|
<upgrades v-bind:style="tmp[layer].componentStyles['upgrades']" :layer="layer"></upgrades>
|
||||||
|
<challenges v-bind:style="tmp[layer].componentStyles['challenges']" :layer="layer"></challenges>
|
||||||
|
<br><br>
|
||||||
|
</div>
|
||||||
|
<div v-if="layers[layer].tabFormat">
|
||||||
|
<div v-if="Array.isArray(tmp[layer].tabFormat)">
|
||||||
|
<column :layer="layer" :data="tmp[layer].tabFormat"></column>
|
||||||
|
</div>
|
||||||
|
<div v-else v-bind:style="[{'margin-top': '-50px'}]">
|
||||||
|
<div class="upgTable" v-bind:style="{'padding-top': '25px', 'margin-bottom': '24px'}">
|
||||||
|
<tab-buttons v-bind:style="tmp[layer].componentStyles['tab-buttons']" :layer="layer" :data="tmp[layer].tabFormat" :name="'mainTabs'"></tab-buttons>
|
||||||
|
</div>
|
||||||
|
<column :layer="layer" :data="tmp[layer].tabFormat[player.subtabs[layer].mainTabs].content"></column>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
521
js/Demo/demoLayers.js
Normal file
521
js/Demo/demoLayers.js
Normal file
|
@ -0,0 +1,521 @@
|
||||||
|
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 {
|
||||||
|
unlocked: true,
|
||||||
|
points: new Decimal(0),
|
||||||
|
best: new Decimal(0),
|
||||||
|
total: new Decimal(0),
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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))
|
||||||
|
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 (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
|
||||||
|
return new Decimal(1)
|
||||||
|
},
|
||||||
|
row: 0, // Row the layer is in on the tree (0 is the first row)
|
||||||
|
effect() {
|
||||||
|
return { // Formulas for any boosts inherent to resources in the layer. Can return a single value instead of an object if there is just one effect
|
||||||
|
waffleBoost: (true == false ? 0 : Decimal.pow(player[this.layer].points, 0.2)),
|
||||||
|
icecreamCap: (player[this.layer].points * 10)
|
||||||
|
}},
|
||||||
|
effectDescription() { // Optional text to describe the effects
|
||||||
|
eff = this.effect();
|
||||||
|
eff.waffleBoost = eff.waffleBoost.times(buyableEffect(this.layer, 11).first)
|
||||||
|
return "which are boosting waffles by "+format(eff.waffleBoost)+" and increasing the Ice Cream cap by "+format(eff.icecreamCap)
|
||||||
|
},
|
||||||
|
milestones: {
|
||||||
|
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",
|
||||||
|
},
|
||||||
|
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)",
|
||||||
|
toggles: [
|
||||||
|
["c", "beep"], // Each toggle is defined by a layer and the data toggled for that layer
|
||||||
|
["f", "boop"]],
|
||||||
|
style() {
|
||||||
|
if(hasMilestone(this.layer, this.id)) return {
|
||||||
|
'background-color': '#1111DD'
|
||||||
|
}},
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
challenges: {
|
||||||
|
rows: 2,
|
||||||
|
cols: 12,
|
||||||
|
11: {
|
||||||
|
name: "Fun",
|
||||||
|
completionLimit: 3,
|
||||||
|
challengeDescription() {return "Makes the game 0% harder<br>"+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
|
||||||
|
rewardEffect() {
|
||||||
|
let ret = player[this.layer].points.add(1).tetrate(0.02)
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
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.
|
||||||
|
rewardDescription: "Says hi",
|
||||||
|
onComplete() {console.log("hiii")} // Called when you complete the challenge
|
||||||
|
},
|
||||||
|
},
|
||||||
|
upgrades: {
|
||||||
|
rows: 2,
|
||||||
|
cols: 3,
|
||||||
|
11: {
|
||||||
|
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),
|
||||||
|
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")
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
effectDisplay() { return format(this.effect())+"x" }, // Add formatting to the effect
|
||||||
|
},
|
||||||
|
13: {
|
||||||
|
description: "Unlock a <b>secret subtab</b> 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
|
||||||
|
currencyLocation: "", // The object in player data that the currency is contained in
|
||||||
|
unlocked() { return (hasUpgrade(this.layer, 12))},
|
||||||
|
onPurchase() { // This function triggers when the upgrade is purchased
|
||||||
|
player[this.layer].unlockOrder = 0
|
||||||
|
},
|
||||||
|
style() {
|
||||||
|
if (hasUpgrade(this.layer, this.id)) return {
|
||||||
|
'background-color': '#1111dd'
|
||||||
|
}
|
||||||
|
else if (!canAffordUpgrade(this.layer, this.id)) {
|
||||||
|
return {
|
||||||
|
'background-color': '#dd1111'
|
||||||
|
}
|
||||||
|
} // Otherwise use the default
|
||||||
|
},
|
||||||
|
},
|
||||||
|
22: {
|
||||||
|
title: "This upgrade doesn't exist",
|
||||||
|
description: "Or does it?.",
|
||||||
|
currencyLocation() {return player[this.layer].buyables}, // The object in player data that the currency is contained in
|
||||||
|
currencyDisplayName: "exhancers", // Use if using a nonstandard currency
|
||||||
|
currencyInternalName: 11, // Use if using a nonstandard currency
|
||||||
|
|
||||||
|
cost: new Decimal(3),
|
||||||
|
unlocked() { return player[this.layer].unlocked }, // The upgrade is only visible when this is true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
buyables: {
|
||||||
|
rows: 1,
|
||||||
|
cols: 12,
|
||||||
|
showRespec: true,
|
||||||
|
respec() { // Optional, reset things and give back your currency. Having this function makes a respec button appear
|
||||||
|
player[this.layer].points = player[this.layer].points.add(player[this.layer].spentOnBuyables) // A built-in thing to keep track of this but only keeps a single value
|
||||||
|
resetBuyables(this.layer)
|
||||||
|
doReset(this.layer, true) // Force a reset
|
||||||
|
},
|
||||||
|
respecText: "Respec Thingies", // Text on Respec button, optional
|
||||||
|
11: {
|
||||||
|
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))
|
||||||
|
return cost.floor()
|
||||||
|
},
|
||||||
|
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))
|
||||||
|
|
||||||
|
if (x.gte(0)) eff.second = x.pow(0.8)
|
||||||
|
else eff.second = x.times(-1).pow(0.8).times(-1)
|
||||||
|
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) + " lollipops\n\
|
||||||
|
Amount: " + player[this.layer].buyables[this.id] + "\n\
|
||||||
|
Adds + " + format(data.effect.first) + " things and multiplies stuff by " + format(data.effect.second)
|
||||||
|
},
|
||||||
|
unlocked() { return player[this.layer].unlocked },
|
||||||
|
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
|
||||||
|
style: {'height':'222px'},
|
||||||
|
sellOne() {
|
||||||
|
let amount = getBuyableAmount(this.layer, this.id)
|
||||||
|
if (amount.lte(0)) return // Only sell one if there is at least one
|
||||||
|
setBuyableAmount(this.layer, this.id, amount.sub(1))
|
||||||
|
player[this.layer].points = player[this.layer].points.add(this.cost())
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
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
|
||||||
|
},
|
||||||
|
layerShown() {return true}, // Condition for when layer appears on the tree
|
||||||
|
automate() {
|
||||||
|
}, // Do any automation inherent to this layer if appropriate
|
||||||
|
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.
|
||||||
|
|
||||||
|
hotkeys: [
|
||||||
|
{key: "c", description: "C: reset for lollipops or whatever", onPress(){if (canReset(this.layer)) doReset(this.layer)}},
|
||||||
|
{key: "ctrl+c", description: "Ctrl+c: respec things", onPress(){if (player[this.layer].unlocked) respecBuyables(this.layer)}},
|
||||||
|
],
|
||||||
|
increaseUnlockOrder: [], // Array of layer names to have their order increased when this one is first unlocked
|
||||||
|
|
||||||
|
microtabs: {
|
||||||
|
stuff: {
|
||||||
|
first: {
|
||||||
|
content: ["upgrades", ["display-text", function() {return "confirmed"}]]
|
||||||
|
},
|
||||||
|
second: {
|
||||||
|
content: [["upgrade", 11],
|
||||||
|
["row", [["upgrade", 11], "blank", "blank", ["upgrade", 11],]],
|
||||||
|
|
||||||
|
["display-text", function() {return "double confirmed"}]]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
otherStuff: {
|
||||||
|
// There could be another set of microtabs here
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
bars: {
|
||||||
|
longBoi: {
|
||||||
|
fillStyle: {'background-color' : "#FFFFFF"},
|
||||||
|
baseStyle: {'background-color' : "#696969"},
|
||||||
|
textStyle: {'color': '#04e050'},
|
||||||
|
|
||||||
|
borderStyle() {return {}},
|
||||||
|
direction: RIGHT,
|
||||||
|
width: 300,
|
||||||
|
height: 30,
|
||||||
|
progress() {
|
||||||
|
return (player.points.log(10).div(10)).toNumber()
|
||||||
|
},
|
||||||
|
display() {
|
||||||
|
return format(player.points) + " / 1e10 points"
|
||||||
|
},
|
||||||
|
unlocked: true,
|
||||||
|
|
||||||
|
},
|
||||||
|
tallBoi: {
|
||||||
|
fillStyle: {'background-color' : "#4BEC13"},
|
||||||
|
baseStyle: {'background-color' : "#000000"},
|
||||||
|
textStyle: {'text-shadow': '0px 0px 2px #000000'},
|
||||||
|
|
||||||
|
borderStyle() {return {'border-width': "7px"}},
|
||||||
|
direction: UP,
|
||||||
|
width: 50,
|
||||||
|
height: 200,
|
||||||
|
progress() {
|
||||||
|
return player.points.div(100)
|
||||||
|
},
|
||||||
|
display() {
|
||||||
|
return formatWhole((player.points.div(1)).min(100)) + "%"
|
||||||
|
},
|
||||||
|
unlocked: 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)
|
||||||
|
},
|
||||||
|
unlocked: true,
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Optional, lets you format the tab yourself by listing components. You can create your own components in v.js.
|
||||||
|
tabFormat: {
|
||||||
|
"main tab": {
|
||||||
|
buttonStyle() {return {'color': 'orange'}},
|
||||||
|
content:
|
||||||
|
["main-display",
|
||||||
|
"prestige-button",
|
||||||
|
["blank", "5px"], // Height
|
||||||
|
["raw-html", function() {return "<button onclick='console.log(`yeet`)'>'HI'</button>"}],
|
||||||
|
["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", "challenges"],
|
||||||
|
},
|
||||||
|
thingies: {
|
||||||
|
style() {return {'background-color': '#222222'}},
|
||||||
|
buttonStyle() {return {'border-color': 'orange'}},
|
||||||
|
content:[
|
||||||
|
["buyables", ""], "blank",
|
||||||
|
["row", [
|
||||||
|
["toggle", ["c", "beep"]], ["blank", ["30px", "10px"]], // Width, height
|
||||||
|
["display-text", function() {return "Beep"}], "blank", ["v-line", "200px"],
|
||||||
|
["column", [
|
||||||
|
["prestige-button", "", {'width': '150px', 'height': '80px'}],
|
||||||
|
["prestige-button", "", {'width': '100px', 'height': '150px'}],
|
||||||
|
]],
|
||||||
|
], {'width': '600px', 'height': '350px', 'background-color': 'green', 'border-style': 'solid'}],
|
||||||
|
"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 jail because \"bars\"! So funny! Ha ha!"],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
illuminati: {
|
||||||
|
unlocked() {return (hasUpgrade("c", 13))},
|
||||||
|
content:[
|
||||||
|
["raw-html", function() {return "<h1> C O N F I R M E D </h1>"}], "blank",
|
||||||
|
["microtabs", "stuff", {'width': '600px', 'height': '350px', 'background-color': 'brown', 'border-style': 'solid'}]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
style() {return {
|
||||||
|
//'background-color': '#3325CC'
|
||||||
|
}},
|
||||||
|
nodeStyle() {return { // Style on the layer node
|
||||||
|
'color': '#3325CC',
|
||||||
|
'text-decoration': 'underline'
|
||||||
|
}},
|
||||||
|
componentStyles: {
|
||||||
|
"challenge"() {return {'height': '200px'}},
|
||||||
|
"prestige-button"() {return {'color': '#AA66AA'}},
|
||||||
|
},
|
||||||
|
tooltip() { // Optional, tooltip displays when the layer is unlocked
|
||||||
|
let tooltip = formatWhole(player[this.layer].points) + " " + this.resource
|
||||||
|
if (player[this.layer].buyables[11].gt(0)) tooltip += "\n" + formatWhole(player[this.layer].buyables[11]) + " Exhancers"
|
||||||
|
return tooltip
|
||||||
|
},
|
||||||
|
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)
|
||||||
|
},
|
||||||
|
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)},
|
||||||
|
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 <u>weird dinosaur</u> 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 <u>weird dinosaur</u> and I'll give you <b>" + formatWhole(tmp[this.layer].resetGain) + "</b> 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:<br>" + 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
|
||||||
|
addLayer("a", {
|
||||||
|
startData() { return {
|
||||||
|
unlocked: true,
|
||||||
|
points: new Decimal(0),
|
||||||
|
}},
|
||||||
|
color: "yellow",
|
||||||
|
resource: "achievement power",
|
||||||
|
type: "none",
|
||||||
|
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",
|
||||||
|
row: 1,
|
||||||
|
layerShown: "ghost",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
66
js/Demo/demoMod.js
Normal file
66
js/Demo/demoMod.js
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
let modInfo = {
|
||||||
|
name: "The Modding Tree",
|
||||||
|
id: "modbase",
|
||||||
|
pointsName: "points",
|
||||||
|
discordName: "",
|
||||||
|
discordLink: "",
|
||||||
|
changelogLink: "https://github.com/Acamaeda/The-Modding-Tree/blob/master/changelog.md",
|
||||||
|
offlineLimit: 1, // In hours
|
||||||
|
initialStartPoints: new Decimal (10) // Used for hard resets and new players
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set your version in num and name
|
||||||
|
let VERSION = {
|
||||||
|
num: "2.1",
|
||||||
|
name: " We should have thought of this sooner!",
|
||||||
|
}
|
||||||
|
|
||||||
|
// If you add new functions anywhere inside of a layer, and those functions have an effect when called, add them here.
|
||||||
|
// (The ones here are examples, all official functions are already taken care of)
|
||||||
|
var doNotCallTheseFunctionsEveryTick = ["doReset", "buy", "onPurchase", "blowUpEverything"]
|
||||||
|
|
||||||
|
function getStartPoints(){
|
||||||
|
return new Decimal(modInfo.initialStartPoints)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determines if it should show points/sec
|
||||||
|
function canGenPoints(){
|
||||||
|
return hasUpgrade("c", 11)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate points/sec!
|
||||||
|
function getPointGen() {
|
||||||
|
if(!canGenPoints())
|
||||||
|
return new Decimal(0)
|
||||||
|
|
||||||
|
let gain = new Decimal(1)
|
||||||
|
if (hasUpgrade("c", 12)) gain = gain.times(upgradeEffect("c", 12))
|
||||||
|
return gain
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can add non-layer related variables that should to into "player" and be saved here, along with default values
|
||||||
|
function addedPlayerData() { return {
|
||||||
|
weather: "Yes",
|
||||||
|
happiness: new Decimal(72),
|
||||||
|
}}
|
||||||
|
|
||||||
|
// Display extra things at the top of the page
|
||||||
|
var displayThings = [
|
||||||
|
function() {if (player.points.eq(69)) return "Tee hee!"},
|
||||||
|
function() {if (player.f.points.gt(1)) return `You have ${player.f.points} farm points. (Which do nothing.)`},
|
||||||
|
function() {if (inChallenge("c", 11)) return "The game is currently <h1>0%</h1> harder."},
|
||||||
|
]
|
||||||
|
|
||||||
|
// Determines when the game "ends"
|
||||||
|
function isEndgame() {
|
||||||
|
return player.points.gte(new Decimal("e280000000"))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Less important things beyond this point!
|
||||||
|
|
||||||
|
// You can change this if you have things that can be messed up by long tick lengths
|
||||||
|
function maxTickLength() {
|
||||||
|
return(3600000) // Default is 1 hour which is just arbitrarily large
|
||||||
|
}
|
|
@ -107,7 +107,6 @@ function layerDataReset(layer, keep = []) {
|
||||||
if (player[layer][keep[thing]] !== undefined)
|
if (player[layer][keep[thing]] !== undefined)
|
||||||
storedData[keep[thing]] = player[layer][keep[thing]]
|
storedData[keep[thing]] = player[layer][keep[thing]]
|
||||||
}
|
}
|
||||||
console.log(storedData)
|
|
||||||
|
|
||||||
player[layer] = layers[layer].startData();
|
player[layer] = layers[layer].startData();
|
||||||
player[layer].upgrades = []
|
player[layer].upgrades = []
|
||||||
|
|
509
js/layers.js
509
js/layers.js
|
@ -1,523 +1,28 @@
|
||||||
addLayer("c", {
|
addLayer("p", {
|
||||||
layer: "c", // This is assigned automatically, both to the layer and all upgrades, etc. Shown here so you know about it
|
name: "prestige", // This is optional, only used in a few places, If absent it just uses the layer id.
|
||||||
name: "Candies", // This is optional, only used in a few places, If absent it just uses the layer id.
|
symbol: "P", // This appears on the layer's node. Default is the id with the first letter capitalized
|
||||||
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
|
position: 0, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order
|
||||||
startData() { return {
|
startData() { return {
|
||||||
unlocked: true,
|
unlocked: true,
|
||||||
points: new Decimal(0),
|
points: new Decimal(0),
|
||||||
best: new Decimal(0),
|
|
||||||
total: new Decimal(0),
|
|
||||||
buyables: {}, // You don't actually have to initialize this one
|
|
||||||
beep: false,
|
|
||||||
}},
|
}},
|
||||||
color: "#4BDC13",
|
color: "#4BDC13",
|
||||||
requires: new Decimal(10), // Can be a function that takes requirement increases into account
|
requires: new Decimal(10), // Can be a function that takes requirement increases into account
|
||||||
resource: "lollipops", // Name of prestige currency
|
resource: "prestige points", // Name of prestige currency
|
||||||
baseResource: "candies", // Name of resource prestige is based on
|
baseResource: "points", // Name of resource prestige is based on
|
||||||
baseAmount() {return player.points}, // Get the current amount of baseResource
|
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
|
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
|
exponent: 0.5, // Prestige currency exponent
|
||||||
base: 5, // Only needed for static layers, base of the formula (b^(x^exp))
|
|
||||||
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
|
gainMult() { // Calculate the multiplier for main currency from bonuses
|
||||||
mult = new Decimal(1)
|
mult = new Decimal(1)
|
||||||
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
|
return mult
|
||||||
},
|
},
|
||||||
gainExp() { // Calculate the exponent on main currency from bonuses
|
gainExp() { // Calculate the exponent on main currency from bonuses
|
||||||
return new Decimal(1)
|
return new Decimal(1)
|
||||||
},
|
},
|
||||||
row: 0, // Row the layer is in on the tree (0 is the first row)
|
row: 0, // Row the layer is in on the tree (0 is the first row)
|
||||||
effect() {
|
|
||||||
return { // Formulas for any boosts inherent to resources in the layer. Can return a single value instead of an object if there is just one effect
|
|
||||||
waffleBoost: (true == false ? 0 : Decimal.pow(player[this.layer].points, 0.2)),
|
|
||||||
icecreamCap: (player[this.layer].points * 10)
|
|
||||||
}},
|
|
||||||
effectDescription() { // Optional text to describe the effects
|
|
||||||
eff = this.effect();
|
|
||||||
eff.waffleBoost = eff.waffleBoost.times(buyableEffect(this.layer, 11).first)
|
|
||||||
return "which are boosting waffles by "+format(eff.waffleBoost)+" and increasing the Ice Cream cap by "+format(eff.icecreamCap)
|
|
||||||
},
|
|
||||||
milestones: {
|
|
||||||
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",
|
|
||||||
},
|
|
||||||
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)",
|
|
||||||
toggles: [
|
|
||||||
["c", "beep"], // Each toggle is defined by a layer and the data toggled for that layer
|
|
||||||
["f", "boop"]],
|
|
||||||
style() {
|
|
||||||
if(hasMilestone(this.layer, this.id)) return {
|
|
||||||
'background-color': '#1111DD'
|
|
||||||
}},
|
|
||||||
|
|
||||||
},
|
|
||||||
},
|
|
||||||
challenges: {
|
|
||||||
rows: 2,
|
|
||||||
cols: 12,
|
|
||||||
11: {
|
|
||||||
name: "Fun",
|
|
||||||
completionLimit: 3,
|
|
||||||
challengeDescription() {return "Makes the game 0% harder<br>"+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
|
|
||||||
rewardEffect() {
|
|
||||||
let ret = player[this.layer].points.add(1).tetrate(0.02)
|
|
||||||
return ret;
|
|
||||||
},
|
|
||||||
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.
|
|
||||||
rewardDescription: "Says hi",
|
|
||||||
onComplete() {console.log("hiii")} // Called when you complete the challenge
|
|
||||||
},
|
|
||||||
},
|
|
||||||
upgrades: {
|
|
||||||
rows: 2,
|
|
||||||
cols: 3,
|
|
||||||
11: {
|
|
||||||
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),
|
|
||||||
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")
|
|
||||||
return ret;
|
|
||||||
},
|
|
||||||
effectDisplay() { return format(this.effect())+"x" }, // Add formatting to the effect
|
|
||||||
},
|
|
||||||
13: {
|
|
||||||
description: "Unlock a <b>secret subtab</b> 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
|
|
||||||
currencyLocation: "", // The object in player data that the currency is contained in
|
|
||||||
unlocked() { return (hasUpgrade(this.layer, 12))},
|
|
||||||
onPurchase() { // This function triggers when the upgrade is purchased
|
|
||||||
player[this.layer].unlockOrder = 0
|
|
||||||
},
|
|
||||||
style() {
|
|
||||||
if (hasUpgrade(this.layer, this.id)) return {
|
|
||||||
'background-color': '#1111dd'
|
|
||||||
}
|
|
||||||
else if (!canAffordUpgrade(this.layer, this.id)) {
|
|
||||||
return {
|
|
||||||
'background-color': '#dd1111'
|
|
||||||
}
|
|
||||||
} // Otherwise use the default
|
|
||||||
},
|
|
||||||
},
|
|
||||||
22: {
|
|
||||||
title: "This upgrade doesn't exist",
|
|
||||||
description: "Or does it?.",
|
|
||||||
currencyLocation() {return player[this.layer].buyables}, // The object in player data that the currency is contained in
|
|
||||||
currencyDisplayName: "exhancers", // Use if using a nonstandard currency
|
|
||||||
currencyInternalName: 11, // Use if using a nonstandard currency
|
|
||||||
|
|
||||||
cost: new Decimal(3),
|
|
||||||
unlocked() { return player[this.layer].unlocked }, // The upgrade is only visible when this is true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
buyables: {
|
|
||||||
rows: 1,
|
|
||||||
cols: 12,
|
|
||||||
showRespec: true,
|
|
||||||
respec() { // Optional, reset things and give back your currency. Having this function makes a respec button appear
|
|
||||||
player[this.layer].points = player[this.layer].points.add(player[this.layer].spentOnBuyables) // A built-in thing to keep track of this but only keeps a single value
|
|
||||||
resetBuyables(this.layer)
|
|
||||||
doReset(this.layer, true) // Force a reset
|
|
||||||
},
|
|
||||||
respecText: "Respec Thingies", // Text on Respec button, optional
|
|
||||||
11: {
|
|
||||||
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))
|
|
||||||
return cost.floor()
|
|
||||||
},
|
|
||||||
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))
|
|
||||||
|
|
||||||
if (x.gte(0)) eff.second = x.pow(0.8)
|
|
||||||
else eff.second = x.times(-1).pow(0.8).times(-1)
|
|
||||||
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) + " lollipops\n\
|
|
||||||
Amount: " + player[this.layer].buyables[this.id] + "\n\
|
|
||||||
Adds + " + format(data.effect.first) + " things and multiplies stuff by " + format(data.effect.second)
|
|
||||||
},
|
|
||||||
unlocked() { return player[this.layer].unlocked },
|
|
||||||
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
|
|
||||||
style: {'height':'222px'},
|
|
||||||
sellOne() {
|
|
||||||
let amount = getBuyableAmount(this.layer, this.id)
|
|
||||||
if (amount.lte(0)) return // Only sell one if there is at least one
|
|
||||||
setBuyableAmount(this.layer, this.id, amount.sub(1))
|
|
||||||
player[this.layer].points = player[this.layer].points.add(this.cost())
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
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
|
|
||||||
},
|
|
||||||
layerShown() {return true}, // Condition for when layer appears on the tree
|
|
||||||
automate() {
|
|
||||||
}, // Do any automation inherent to this layer if appropriate
|
|
||||||
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.
|
|
||||||
|
|
||||||
hotkeys: [
|
hotkeys: [
|
||||||
{key: "c", description: "C: reset for lollipops or whatever", onPress(){if (canReset(this.layer)) doReset(this.layer)}},
|
{key: "p", description: "Reset for prestige points", onPress(){if (canReset(this.layer)) doReset(this.layer)}},
|
||||||
{key: "ctrl+c", description: "Ctrl+c: respec things", onPress(){if (player[this.layer].unlocked) respecBuyables(this.layer)}},
|
|
||||||
],
|
],
|
||||||
increaseUnlockOrder: [], // Array of layer names to have their order increased when this one is first unlocked
|
layerShown(){return true},
|
||||||
|
|
||||||
microtabs: {
|
|
||||||
stuff: {
|
|
||||||
first: {
|
|
||||||
content: ["upgrades", ["display-text", function() {return "confirmed"}]]
|
|
||||||
},
|
|
||||||
second: {
|
|
||||||
content: [["upgrade", 11],
|
|
||||||
["row", [["upgrade", 11], "blank", "blank", ["upgrade", 11],]],
|
|
||||||
|
|
||||||
["display-text", function() {return "double confirmed"}]]
|
|
||||||
},
|
|
||||||
},
|
|
||||||
otherStuff: {
|
|
||||||
// There could be another set of microtabs here
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
bars: {
|
|
||||||
longBoi: {
|
|
||||||
fillStyle: {'background-color' : "#FFFFFF"},
|
|
||||||
baseStyle: {'background-color' : "#696969"},
|
|
||||||
textStyle: {'color': '#04e050'},
|
|
||||||
|
|
||||||
borderStyle() {return {}},
|
|
||||||
direction: RIGHT,
|
|
||||||
width: 300,
|
|
||||||
height: 30,
|
|
||||||
progress() {
|
|
||||||
return (player.points.log(10).div(10)).toNumber()
|
|
||||||
},
|
|
||||||
display() {
|
|
||||||
return format(player.points) + " / 1e10 points"
|
|
||||||
},
|
|
||||||
unlocked: true,
|
|
||||||
|
|
||||||
},
|
|
||||||
tallBoi: {
|
|
||||||
fillStyle: {'background-color' : "#4BEC13"},
|
|
||||||
baseStyle: {'background-color' : "#000000"},
|
|
||||||
textStyle: {'text-shadow': '0px 0px 2px #000000'},
|
|
||||||
|
|
||||||
borderStyle() {return {'border-width': "7px"}},
|
|
||||||
direction: UP,
|
|
||||||
width: 50,
|
|
||||||
height: 200,
|
|
||||||
progress() {
|
|
||||||
return player.points.div(100)
|
|
||||||
},
|
|
||||||
display() {
|
|
||||||
return formatWhole((player.points.div(1)).min(100)) + "%"
|
|
||||||
},
|
|
||||||
unlocked: 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)
|
|
||||||
},
|
|
||||||
unlocked: true,
|
|
||||||
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// Optional, lets you format the tab yourself by listing components. You can create your own components in v.js.
|
|
||||||
tabFormat: {
|
|
||||||
"main tab": {
|
|
||||||
buttonStyle() {return {'color': 'orange'}},
|
|
||||||
content:
|
|
||||||
["main-display",
|
|
||||||
"prestige-button",
|
|
||||||
["blank", "5px"], // Height
|
|
||||||
["raw-html", function() {return "<button onclick='console.log(`yeet`)'>'HI'</button>"}],
|
|
||||||
["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", "challenges"],
|
|
||||||
},
|
|
||||||
thingies: {
|
|
||||||
style() {return {'background-color': '#222222'}},
|
|
||||||
buttonStyle() {return {'border-color': 'orange'}},
|
|
||||||
content:[
|
|
||||||
["buyables", ""], "blank",
|
|
||||||
["row", [
|
|
||||||
["toggle", ["c", "beep"]], ["blank", ["30px", "10px"]], // Width, height
|
|
||||||
["display-text", function() {return "Beep"}], "blank", ["v-line", "200px"],
|
|
||||||
["column", [
|
|
||||||
["prestige-button", "", {'width': '150px', 'height': '80px'}],
|
|
||||||
["prestige-button", "", {'width': '100px', 'height': '150px'}],
|
|
||||||
]],
|
|
||||||
], {'width': '600px', 'height': '350px', 'background-color': 'green', 'border-style': 'solid'}],
|
|
||||||
"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 jail because \"bars\"! So funny! Ha ha!"],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
illuminati: {
|
|
||||||
unlocked() {return (hasUpgrade("c", 13))},
|
|
||||||
content:[
|
|
||||||
["raw-html", function() {return "<h1> C O N F I R M E D </h1>"}], "blank",
|
|
||||||
["microtabs", "stuff", {'width': '600px', 'height': '350px', 'background-color': 'brown', 'border-style': 'solid'}]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
style() {return {
|
|
||||||
//'background-color': '#3325CC'
|
|
||||||
}},
|
|
||||||
nodeStyle() {return { // Style on the layer node
|
|
||||||
'color': '#3325CC',
|
|
||||||
'text-decoration': 'underline'
|
|
||||||
}},
|
|
||||||
componentStyles: {
|
|
||||||
"challenge"() {return {'height': '200px'}},
|
|
||||||
"prestige-button"() {return {'color': '#AA66AA'}},
|
|
||||||
},
|
|
||||||
tooltip() { // Optional, tooltip displays when the layer is unlocked
|
|
||||||
let tooltip = formatWhole(player[this.layer].points) + " " + this.resource
|
|
||||||
if (player[this.layer].buyables[11].gt(0)) tooltip += "\n" + formatWhole(player[this.layer].buyables[11]) + " Exhancers"
|
|
||||||
return tooltip
|
|
||||||
},
|
|
||||||
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)
|
|
||||||
},
|
|
||||||
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)},
|
|
||||||
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 <u>weird dinosaur</u> 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 <u>weird dinosaur</u> and I'll give you <b>" + formatWhole(tmp[this.layer].resetGain) + "</b> 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:<br>" + 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: true,
|
|
||||||
points: new Decimal(0),
|
|
||||||
}},
|
|
||||||
color: "yellow",
|
|
||||||
resource: "achievement power",
|
|
||||||
type: "none",
|
|
||||||
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",
|
|
||||||
]
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
// This layer is mostly minimal but it uses a custom prestige type and a clickable
|
|
||||||
addLayer("spook", {
|
|
||||||
startData() { return {
|
|
||||||
unlocked: true,
|
|
||||||
points: new Decimal(0),
|
|
||||||
}},
|
|
||||||
color: "yellow",
|
|
||||||
resource: "achievement power",
|
|
||||||
type: "none",
|
|
||||||
row: 1,
|
|
||||||
layerShown: "ghost",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
18
js/mod.js
18
js/mod.js
|
@ -1,6 +1,6 @@
|
||||||
let modInfo = {
|
let modInfo = {
|
||||||
name: "The Modding Tree",
|
name: "The Demo Tree",
|
||||||
id: "modbase",
|
id: "moddemo",
|
||||||
pointsName: "points",
|
pointsName: "points",
|
||||||
discordName: "",
|
discordName: "",
|
||||||
discordLink: "",
|
discordLink: "",
|
||||||
|
@ -11,13 +11,13 @@ let modInfo = {
|
||||||
|
|
||||||
// Set your version in num and name
|
// Set your version in num and name
|
||||||
let VERSION = {
|
let VERSION = {
|
||||||
num: "2.1",
|
num: "0.0",
|
||||||
name: " We should have thought of this sooner!",
|
name: "Literally nothing",
|
||||||
}
|
}
|
||||||
|
|
||||||
// If you add new functions anywhere inside of a layer, and those functions have an effect when called, add them here.
|
// If you add new functions anywhere inside of a layer, and those functions have an effect when called, add them here.
|
||||||
// (The ones here are examples, all official functions are already taken care of)
|
// (The ones here are examples, all official functions are already taken care of)
|
||||||
var doNotCallTheseFunctionsEveryTick = ["doReset", "buy", "onPurchase", "blowUpEverything"]
|
var doNotCallTheseFunctionsEveryTick = ["blowUpEverything"]
|
||||||
|
|
||||||
function getStartPoints(){
|
function getStartPoints(){
|
||||||
return new Decimal(modInfo.initialStartPoints)
|
return new Decimal(modInfo.initialStartPoints)
|
||||||
|
@ -25,7 +25,7 @@ function getStartPoints(){
|
||||||
|
|
||||||
// Determines if it should show points/sec
|
// Determines if it should show points/sec
|
||||||
function canGenPoints(){
|
function canGenPoints(){
|
||||||
return hasUpgrade("c", 11)
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate points/sec!
|
// Calculate points/sec!
|
||||||
|
@ -34,21 +34,15 @@ function getPointGen() {
|
||||||
return new Decimal(0)
|
return new Decimal(0)
|
||||||
|
|
||||||
let gain = new Decimal(1)
|
let gain = new Decimal(1)
|
||||||
if (hasUpgrade("c", 12)) gain = gain.times(upgradeEffect("c", 12))
|
|
||||||
return gain
|
return gain
|
||||||
}
|
}
|
||||||
|
|
||||||
// You can add non-layer related variables that should to into "player" and be saved here, along with default values
|
// You can add non-layer related variables that should to into "player" and be saved here, along with default values
|
||||||
function addedPlayerData() { return {
|
function addedPlayerData() { return {
|
||||||
weather: "Yes",
|
|
||||||
happiness: new Decimal(72),
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
// Display extra things at the top of the page
|
// Display extra things at the top of the page
|
||||||
var displayThings = [
|
var displayThings = [
|
||||||
function() {if (player.points.eq(69)) return "Tee hee!"},
|
|
||||||
function() {if (player.f.points.gt(1)) return `You have ${player.f.points} farm points. (Which do nothing.)`},
|
|
||||||
function() {if (inChallenge("c", 11)) return "The game is currently <h1>0%</h1> harder."},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
// Determines when the game "ends"
|
// Determines when the game "ends"
|
||||||
|
|
Loading…
Reference in a new issue