mirror of
https://github.com/thepaperpilot/The-Modding-Tree.git
synced 2025-03-14 10:01:47 +00:00
Merge remote-tracking branch 'upstream/master' into kronos
This commit is contained in:
commit
fd249f5b4a
20 changed files with 679 additions and 179 deletions
37
changelog.md
37
changelog.md
|
@ -1,9 +1,44 @@
|
|||
# The Modding Tree changelog:
|
||||
|
||||
# v2.5.3 - 5/8/21
|
||||
- Improved performance of tab formats and bars.
|
||||
- Respec confirmation settings are now kept on resets.
|
||||
- Improved compatibility with older browsers.
|
||||
- Fixed missing pixel on vertical bars.
|
||||
|
||||
# v2.5.2.1 - 5/7/21
|
||||
- Fixed microtabs making layers highlight incorrectly.
|
||||
|
||||
# v2.5.2 - 5/7/21
|
||||
- Added glowColor for subtabs.
|
||||
- Improved the display for extremely small numbers.
|
||||
- Fixed issues in the buyable docs.
|
||||
|
||||
# v2.5.1 - 5/7/21
|
||||
- Fixed dynamic things in tabFormat not updating.
|
||||
|
||||
## v2.5: Dreams Really Do Come True - 5/7/21
|
||||
- Optimizations, hopefully a significant amount.
|
||||
- Added OOM/s point gen display at high values (thanks to Ducdat!)
|
||||
- Only one tab will display if the window is not wide enough (also thanks to Ducdat!)
|
||||
- Holding down a buyable's button now buys it continuously.
|
||||
- New milestone setting will also show the most recently unlocked milestone. (Also renamed all settings to be clearer)
|
||||
- Added an onHold feature for clickables.
|
||||
- Layer nodes will be highlighted even if the player is on the same tab.
|
||||
- Added customizable node glowColor.
|
||||
- Added buyable purchaseLimit.
|
||||
- Amount is automatically supplied to buyable cost and effect functions.
|
||||
- Locked (not yet visible) milestones no longer take up space. Also fixed hidden milestones taking a tiny bit of space.
|
||||
- Re-centered respec buttons.
|
||||
- Force-displayed tooltips are not hidden by resets.
|
||||
- Added formatting support for very small numbers. Disabled in most places by default because rounding errors might cause issues. Access it with formatSmall, or enable it globally by adding "allowSmall: true" to modInfo.
|
||||
|
||||
|
||||
# v2.4.1 - 4/29/21
|
||||
- A number of minor fixes, many thanks to thepaperpilot.
|
||||
- The respec confirmation checkbox is now part of the respec-button component.
|
||||
- Added a few missing changes to the 2.4 changelog (the two at the bottom)
|
||||
(This also fixes the checkbox appearing when there is no respec button)
|
||||
- Added a few undocumented changes to the 2.4 changelog (the two at the bottom)
|
||||
|
||||
## v2.4: Rationalized Edition - 4/29/21
|
||||
- Completely reworked tooltips. Shift-click a node to force its tooltip to stay displayed. (And hopefully finally fixed flickering!)
|
||||
|
|
122
demo.html
Normal file
122
demo.html
Normal file
|
@ -0,0 +1,122 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
<link rel="stylesheet" type="text/css" href="popup.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 src="js/technical/break_eternity.js"></script>
|
||||
<script src="js/technical/layerSupport.js"></script>
|
||||
<script src="js/demo/demoTree.js"></script>
|
||||
<script src="js/demo/demoLayers.js"></script>
|
||||
<script src="js/demo/demoMod.js"></script>
|
||||
<script src="js/technical/temp.js"></script>
|
||||
<script src="js/technical/displays.js"></script>
|
||||
|
||||
<script src="js/game.js"></script>
|
||||
<script src="js/utils.js"></script>
|
||||
<script src="js/technical/systemComponents.js"></script>
|
||||
<script src="js/components.js"></script>
|
||||
<script src="js/technical/canvas.js"></script>
|
||||
<script src="js/utils/NumberFormating.js"></script>
|
||||
<script src="js/utils/options.js"></script>
|
||||
<script src="js/utils/save.js"></script>
|
||||
<script src="js/utils/themes.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="load()">
|
||||
<div id="app">
|
||||
<canvas id="treeCanvas" class="canvas" v-if="!(gameEnded && !player.keepGoing)"></canvas>
|
||||
|
||||
<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.navTab !== 'none' && tmp.other.splitScreen && player.tab!='none' && !(gameEnded && !player.keepGoing)"></div>
|
||||
<div v-if="(gameEnded && !player.keepGoing)" class="fullWidth">
|
||||
<br>
|
||||
<h2>{{modInfo.name}} {{VERSION.withoutName}}</h2><br><br>
|
||||
<h3 v-html="modInfo.winText"></h3><br>
|
||||
<h3>Please check the Discord to see if there are new content updates!</h3><br><br>
|
||||
<div v-if="!player.timePlayedReset">It took you {{formatTime(player.timePlayed)}} to beat the game.</div>
|
||||
<br>
|
||||
<button class="longUpg can" onclick="hardReset(true)">Play Again</button> <button
|
||||
class="longUpg can" onclick="keepGoing()">Keep Going</button>
|
||||
<br><br><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><br>
|
||||
</div>
|
||||
|
||||
<div id="treeOverlay" v-if="!(gameEnded && !player.keepGoing) && (player.tab === 'none' || tmp.other.splitScreen || !readData(layoutInfo.showTree))" class="treeOverlay" onscroll="resizeCanvas()"
|
||||
v-bind:class="{
|
||||
fullWidth: (player.tab == 'none' || player.navTab == 'none'),
|
||||
col: (player.tab !== 'none' && player.navTab !== 'none'),
|
||||
left: (player.tab !== 'none' && player.navTab !== 'none')}"
|
||||
:style="{'margin-top': !readData(layoutInfo.showTree) && player.tab == 'info-tab' ? '50px' : ''}">
|
||||
<div id="version" onclick="showTab('changelog-tab')" class="overlayThing" style="margin-right: 13px">
|
||||
{{VERSION.withoutName}}</div>
|
||||
<button
|
||||
v-if="player.navTab == 'none' && (tmp[player.tab].row == 'side' || tmp[player.tab].row == 'otherside')"
|
||||
class="other-back overlayThing" onclick="goBack()">←</button>
|
||||
<img id="optionWheel" class="overlayThing" v-if="player.tab!='options-tab'" src="options_wheel.png"
|
||||
onclick="showTab('options-tab')"></img>
|
||||
<div id="info" v-if="player.tab!='info-tab'" class="overlayThing" onclick="showTab('info-tab')"><br>i</div>
|
||||
<div id="discord" class="overlayThing">
|
||||
<img onclick="window.open((modInfo.discordLink ? modInfo.discordLink : 'https://discord.gg/F3xveHV'),'mywindow')"
|
||||
src="discord.png" target="_blank"></img>
|
||||
<ul id="discord-links">
|
||||
<li v-if="modInfo.discordLink"><a class="link" v-bind:href="modInfo.discordLink"
|
||||
target="_blank">{{modInfo.discordName}}</a><br></li>
|
||||
<li><a class="link" href="https://discord.gg/F3xveHV" target="_blank"
|
||||
v-bind:style="modInfo.discordLink ? {'font-size': '16px'} : {}">The Modding Tree
|
||||
Discord</a><br></li>
|
||||
<li><a class="link" href="http://discord.gg/wwQfgPa" target="_blank"
|
||||
v-bind:style="{'font-size': '16px'}">Main Prestige Tree server</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<overlay-head v-if="!(gameEnded && !player.keepGoing)"></overlay-head>
|
||||
<div class="sideLayers">
|
||||
<div v-for="(node, index) in OTHER_LAYERS['side']">
|
||||
<tree-node :layer='node' :abb='tmp[node].symbol' :size="'small'" :key="'side' + index"></tree-node>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="!(gameEnded && !player.keepGoing) && (player.tab === 'none' || tmp.other.splitScreen)" id="treeTab" style="z-index: 0" onscroll="resizeCanvas()"
|
||||
v-bind:class="{ fullWidth: (player.tab == 'none' || player.navTab == 'none'), col: (player.tab !== 'none' && player.navTab !== 'none'), left: (player.tab !== 'none' && player.navTab !== 'none')}">
|
||||
<br><br><br><br>
|
||||
<overlay-head id="fakeHead" style="visibility: hidden;">
|
||||
</overlay-head>
|
||||
|
||||
<layer-tab :layer="player.navTab == 'none' ? player.tab : player.navTab" :key="'left'"></layer-tab>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Popups -->
|
||||
<div class="popup-container">
|
||||
<transition-group name="fade">
|
||||
<div v-for="popup,index in activePopups" class="popup" v-bind:class="popup.type"
|
||||
v-bind:key="'p' + popup.id" v-on:click="() => {activePopups.splice(index, 1)}" v-bind:style="popup.color ? {'background-color': popup.color} : {}">
|
||||
<h3>{{popup.title}}</h3><br>
|
||||
<h2 v-html="popup.message"></h2>
|
||||
</div>
|
||||
</transition-group>
|
||||
</div>
|
||||
|
||||
<div v-if="player.navTab !== 'none' && player.tab !== 'none' && !(gameEnded && !player.keepGoing)" onscroll="resizeCanvas()" style="background-color:var(--background)" v-bind:class="{ fullWidth: player.navTab == 'none' || !tmp.other.splitScreen || !readData(layoutInfo.showTree), col: player.navTab != 'none', right: player.navTab != 'none', fast: true, tab: true}">
|
||||
<div v-for="layer in LAYERS">
|
||||
<div v-if="player.tab==layer">
|
||||
<layer-tab :layer="layer" :back="'none'" :spacing="'50px'" :key="'left'"></layer-tab>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
|
@ -15,12 +15,12 @@ Buyables should be formatted like this:
|
|||
```js
|
||||
buyables: {
|
||||
11: {
|
||||
cost(x) { return new Decimal(1).mul(x || getBuyableAmt(this.layer, this.id)) },
|
||||
cost(x) { return new Decimal(1).mul(x) },
|
||||
display() { return "Blah" },
|
||||
canAfford() { return player[this.layer].points.gte(this.cost()) },
|
||||
buy() {
|
||||
player[this.layer].points = player[this.layer].points.sub(this.cost())
|
||||
setBuyableAmount(this.layer, this.id, getBuyableAmt(this.layer, this.id).add(1))
|
||||
setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1))
|
||||
},
|
||||
etc
|
||||
},
|
||||
|
@ -32,9 +32,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 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. (x is a `Decimal`). Can return 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 purchase. (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.
|
||||
- effect(): **optional**. A function that calculates and returns the current values of bonuses of this buyable. Can have an optional argument "x" to calculate the effect of having x of the buyable..
|
||||
Can return a value or an object containing multiple values.
|
||||
|
||||
- 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.
|
||||
|
||||
|
@ -47,7 +49,9 @@ Features:
|
|||
- buyMax(): **optional**. A function that implements buying as many of the buyable as possible.
|
||||
|
||||
- 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).
|
||||
|
||||
|
||||
- purchaseLimit: **optional**. The limit on how many of the buyable can be bought. The default is no limit.
|
||||
|
||||
- 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 buyable was stored under, for convenient access. The buyable in the example's id is 11.
|
||||
|
@ -64,7 +68,7 @@ Including a `sellOne` or `sellAll` function will cause an additional button to a
|
|||
To add a respec button, or something similar, add the respecBuyables function to the main buyables object (not individual buyables).
|
||||
You can use these features along with it:
|
||||
|
||||
- respecBuyables(): **optional**. This is called when the button is pressed (after a toggleable confirmation message).
|
||||
- respec(): **optional**. This is called when the button is pressed (after a toggleable confirmation message).
|
||||
|
||||
- respecText: **optional**. Text to display on the respec Button.
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ Features:
|
|||
|
||||
- onClick(): A function that implements clicking one of the clickable.
|
||||
|
||||
- onHold(): **optional** A function that is called 20x/sec when the button is held for at least 0.25 seconds.
|
||||
|
||||
- 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.
|
||||
|
|
|
@ -155,6 +155,8 @@ You can make almost any value dynamic by using a function in its place, includin
|
|||
|
||||
- shouldNotify: **optional**. A function to return true if this layer should be highlighted in the tree. The layer will automatically be highlighted if you can buy an upgrade whether you have this or not.
|
||||
|
||||
- glowColor: **optional**. The color that this layer will be highlighted if it should notify. The default is red. You can use this if you want several different notification types!
|
||||
|
||||
- componentStyles: **optional**. An object that contains a set of functions returning CSS objects. Each of these will be applied to any components on the layer with the type of its id. Example:
|
||||
|
||||
```js
|
||||
|
|
|
@ -52,5 +52,8 @@ Normal subtabs and microtab subtabs both use the same features:
|
|||
|
||||
- shouldNotify()/prestigeNotify(): **optional**, if true, the tab button will be highlighted to notify the player that there is something there.
|
||||
|
||||
- glowColor: **optional**, specifies the color that the subtab glows. If this subtab is causing the main layer to node glow
|
||||
(and it would't otherwise) the node also glows this color. Is NOT overridden by embedding a layer.
|
||||
|
||||
- embedLayer: **SIGNIFICANT**, the id of another layer. If you have this, it will override "content", "style" and "shouldNotify",
|
||||
instead displaying the entire layer in the subtab.
|
20
index.html
20
index.html
|
@ -21,6 +21,7 @@
|
|||
<script type="text/javascript" src="js/tree.js"></script>
|
||||
<script type="text/javascript" src="js/mod.js"></script>
|
||||
<script type="text/javascript" src="js/technical/temp.js"></script>
|
||||
<script type="text/javascript" src="js/technical/displays.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/technical/systemComponents.js"></script>
|
||||
|
@ -67,7 +68,7 @@
|
|||
<div v-if="false" id="loadingSection" class="fullWidth">
|
||||
<h1>Loading...<br>(If this takes too long it means there was a serious error!)</h1>
|
||||
</div>
|
||||
<div class="vl" v-if="player.navTab!== 'none' &&player.tab!=='none'&&!(gameEnded && !player.keepGoing)"></div>
|
||||
<div class="vl" v-if="player.navTab !== 'none' && tmp.other.splitScreen && player.tab!='none' && !(gameEnded && !player.keepGoing)"></div>
|
||||
<div v-if="(gameEnded && !player.keepGoing)" class="fullWidth">
|
||||
<br>
|
||||
<h2>{{modInfo.name}} {{VERSION.withoutName}}</h2><br><br>
|
||||
|
@ -87,8 +88,15 @@
|
|||
<br><br>
|
||||
</div>
|
||||
|
||||
<div id="treeOverlay" v-if="!(gameEnded && !player.keepGoing)" class="treeOverlay" onscroll="resizeCanvas()"
|
||||
v-bind:class="{ fullWidth: (player.tab === 'none' || player.navTab === 'none'), col: (player.tab !== 'none' && player.navTab !== 'none'), left: (player.tab !== 'none' && player.navTab !== 'none')}">
|
||||
<div id="treeOverlay" v-if="!(gameEnded && !player.keepGoing) && (player.tab === 'none' || tmp.other.splitScreen || !readData(layoutInfo.showTree))" class="treeOverlay" onscroll="resizeCanvas()"
|
||||
v-bind:class="{
|
||||
fullWidth: (player.tab === 'none' || player.navTab === 'none'),
|
||||
col: (player.tab !== 'none' && player.navTab !== 'none'),
|
||||
left: (player.tab !== 'none' && player.navTab !== 'none')
|
||||
}"
|
||||
:style="{
|
||||
'margin-top': !readData(layoutInfo.showTree) && player.tab == 'info-tab' ? '50px' : ''
|
||||
}">
|
||||
<button v-if= "player.navTab === 'none' && (tmp[player.tab].row === 'side' || tmp[player.tab].row === 'otherside')" class="other-back overlayThing" onclick="goBack()">←</button>
|
||||
<overlay-head v-if="!(gameEnded && !player.keepGoing)"></overlay-head>
|
||||
<div class="sideLayers">
|
||||
|
@ -98,7 +106,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<perfect-scrollbar v-if="!(gameEnded && !player.keepGoing)" style="height: calc(100% - 70px)" id="treeTab" v-bind:style="{'z-index': (tmp.scrolled ? '1' : '5000')}" onscroll="resizeCanvas()"
|
||||
<perfect-scrollbar v-if="!(gameEnded && !player.keepGoing) && (player.tab === 'none' || tmp.other.splitScreen)" style="height: calc(100% - 70px); z-index: 0;" id="treeTab" onscroll="resizeCanvas()"
|
||||
v-bind:class="{ fullWidth: (player.tab === 'none' || player.navTab === 'none'), left: (player.tab !== 'none' && player.navTab !== 'none')}">
|
||||
<br>
|
||||
<overlay-head id="fakeHead" style="visibility: hidden;">
|
||||
|
@ -119,7 +127,7 @@
|
|||
</transition-group>
|
||||
</div>
|
||||
|
||||
<perfect-scrollbar v-if="player.navTab !== 'none' && player.tab !== 'none' && !(gameEnded && !player.keepGoing)" onscroll="resizeCanvas()" v-bind:class="{ fullWidth: player.navTab === 'none', right: player.navTab !== 'none', fast: true, tab: true}">
|
||||
<perfect-scrollbar v-if="player.navTab !== 'none' && player.tab !== 'none' && !(gameEnded && !player.keepGoing)" onscroll="resizeCanvas()" style="background-color:var(--background)" v-bind:class="{ fullWidth: player.navTab === 'none' || !tmp.other.splitScreen || !readData(layoutInfo.showTree), right: player.navTab !== 'none', fast: true, tab: true}">
|
||||
<div v-for="layer in LAYERS" >
|
||||
<div v-if="player.tab===layer" >
|
||||
<layer-tab :layer="layer" :back="'none'" :spacing="'50px'" :key="'left'"></layer-tab>
|
||||
|
@ -127,4 +135,4 @@
|
|||
</div>
|
||||
</perfect-scrollbar>
|
||||
</div>
|
||||
</body>
|
||||
</body>
|
||||
|
|
|
@ -158,12 +158,12 @@ addLayer("c", {
|
|||
respecMessage: "Are you sure? Respeccing these doesn't accomplish much.",
|
||||
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
|
||||
cost(x) { // 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
|
||||
effect(x) { // 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))
|
||||
|
@ -175,7 +175,7 @@ addLayer("c", {
|
|||
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\
|
||||
Amount: " + player[this.layer].buyables[this.id] + "/4\n\
|
||||
Adds + " + format(data.effect.first) + " things and multiplies stuff by " + format(data.effect.second)
|
||||
},
|
||||
unlocked() { return player[this.layer].unlocked },
|
||||
|
@ -189,6 +189,7 @@ addLayer("c", {
|
|||
},
|
||||
buyMax() {}, // You'll have to handle this yourself if you want
|
||||
style: {'height':'222px'},
|
||||
purchaseLimit: new Decimal(4),
|
||||
sellOne() {
|
||||
let amount = getBuyableAmount(this.layer, this.id)
|
||||
if (amount.lte(0)) return // Only sell one if there is at least one
|
||||
|
@ -220,6 +221,8 @@ addLayer("c", {
|
|||
content: ["upgrades", ["display-text", function() {return "confirmed"}]]
|
||||
},
|
||||
second: {
|
||||
embedLayer: "f",
|
||||
|
||||
content: [["upgrade", 11],
|
||||
["row", [["upgrade", 11], "blank", "blank", ["upgrade", 11],]],
|
||||
|
||||
|
@ -301,6 +304,8 @@ addLayer("c", {
|
|||
function() {return 'I have ' + format(player.points) + ' ' + player.c.thingy + ' points!'},
|
||||
{"color": "red", "font-size": "32px", "font-family": "Comic Sans MS"}],
|
||||
"h-line", "milestones", "blank", "upgrades", "challenges"],
|
||||
glowColor: "blue",
|
||||
|
||||
},
|
||||
thingies: {
|
||||
prestigeNotify: true,
|
||||
|
@ -354,13 +359,14 @@ addLayer("c", {
|
|||
'color': '#3325CC',
|
||||
'text-decoration': 'underline'
|
||||
}},
|
||||
glowColor: "orange", // If the node is highlighted, it will be this color (default is red)
|
||||
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 += "<br>" + formatWhole(player[this.layer].buyables[11]) + " Exhancers"
|
||||
if (player[this.layer].buyables[11].gt(0)) tooltip += "<br><i>" + formatWhole(player[this.layer].buyables[11]) + " Exhancers</i>"
|
||||
return tooltip
|
||||
},
|
||||
shouldNotify() { // Optional, layer will be highlighted on the tree if true.
|
||||
|
@ -405,7 +411,7 @@ addLayer("f", {
|
|||
// 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 points and lollipops! (At least " + formatWhole(tmp[this.layer].nextAt) + " points)"
|
||||
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 points and lollipops! (You'll get another one at " + formatWhole(tmp[layer].nextAtDisp) + " points)"
|
||||
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 points and lollipops! (You'll get another one at " + formatWhole(tmp[this.layer].nextAtDisp) + " points)"
|
||||
},
|
||||
getResetGain() {
|
||||
return getResetGain(this.layer, useType = "static")
|
||||
|
@ -450,9 +456,11 @@ addLayer("f", {
|
|||
default:
|
||||
player[this.layer].clickables[this.id] = "Start"
|
||||
break;
|
||||
|
||||
}
|
||||
},
|
||||
onHold(){
|
||||
console.log("Clickkkkk...")
|
||||
},
|
||||
style() {
|
||||
switch(getClickableState(this.layer, this.id)){
|
||||
case "Start":
|
||||
|
|
|
@ -11,8 +11,8 @@ let modInfo = {
|
|||
|
||||
// Set your version in num and name
|
||||
let VERSION = {
|
||||
num: "2.4.1",
|
||||
name: "Rationalized Edition",
|
||||
num: "2.5.3",
|
||||
name: "Dreams Really Do Come True",
|
||||
}
|
||||
|
||||
let changelog = `<h1>Changelog:</h1><br>
|
||||
|
|
|
@ -144,10 +144,11 @@ function loadVue() {
|
|||
Vue.component('challenge', {
|
||||
props: ['layer', 'data'],
|
||||
template: `
|
||||
<div v-if="tmp[layer].challenges && tmp[layer].challenges[data]!== undefined && tmp[layer].challenges[data].unlocked && !(player.hideChallenges && maxedChallenge(layer, [data]))" v-bind:class="{hChallenge: true, done: tmp[layer].challenges[data].defaultStyle === 'done', canComplete:tmp[layer].challenges[data].defaultStyle === 'canComplete', locked: tmp[layer].challenges[data].defaultStyle === 'locked'}" v-bind:style="tmp[layer].challenges[data].style">
|
||||
<div v-if="tmp[layer].challenges && tmp[layer].challenges[data]!== undefined && tmp[layer].challenges[data].unlocked && !(player.hideChallenges && maxedChallenge(layer, [data]))"
|
||||
v-bind:class="['hChallenge', challengeStyle(layer, data)]" v-bind:style="tmp[layer].challenges[data].style">
|
||||
<br><h3 v-html="tmp[layer].challenges[data].name"></h3><br><br>
|
||||
<button v-bind:class="{ longUpg: true, can: true, [layer]: true }" v-bind:style="{'background-color': tmp[layer].color}" v-on:click="startChallenge(layer, data)">{{tmp[layer].challenges[data].buttonText}}</button><br><br>
|
||||
<span v-if="tmp[layer].challenges[data].fullDisplay" v-html="tmp[layer].challenges[data].fullDisplay"></span>
|
||||
<button v-bind:class="{ longUpg: true, can: true, [layer]: true }" v-bind:style="{'background-color': tmp[layer].color}" v-on:click="startChallenge(layer, data)">{{challengeButtonText(layer, data)}}</button><br><br>
|
||||
<span v-if="layers[layer].challenges[data].fullDisplay" v-html="run(layers[layer].challenges[data].fullDisplay, layers[layer].challenges[data])"></span>
|
||||
<span v-else>
|
||||
<span v-html="tmp[layer].challenges[data].challengeDescription"></span><br>
|
||||
Goal: <span v-if="tmp[layer].challenges[data].goalDescription"
|
||||
|
@ -155,7 +156,7 @@ function loadVue() {
|
|||
v-else>{{ format(tmp[layer].challenges[data].goal) }}
|
||||
{{ tmp[layer].challenges[data].currencyDisplayName ? tmp[layer].challenges[data].currencyDisplayName : "points" }}</span><br>
|
||||
Reward: <span v-html="tmp[layer].challenges[data].rewardDescription"></span><br>
|
||||
<span v-if="tmp[layer].challenges[data].rewardDisplay!==undefined">Currently: <span v-html="(tmp[layer].challenges[data].rewardDisplay) ? (tmp[layer].challenges[data].rewardDisplay) : format(tmp[layer].challenges[data].rewardEffect)"></span></span>
|
||||
<span v-if="layers[layer].challenges[data].rewardDisplay!==undefined">Currently: <span v-html="(tmp[layer].challenges[data].rewardDisplay) ? (run(layers[layer].challenges[data].rewardDisplay, layers[layer].challenges[data])) : format(tmp[layer].challenges[data].rewardEffect)"></span></span>
|
||||
</span>
|
||||
</div>
|
||||
`
|
||||
|
@ -187,7 +188,7 @@ function loadVue() {
|
|||
v-on:click="buyUpg(layer, data)"
|
||||
v-bind:class="{ [layer]: true, upg: true, bought: hasUpgrade(layer, data), locked: (!(canAffordUpgrade(layer, data))&&!hasUpgrade(layer, data)), can: (canAffordUpgrade(layer, data)&&!hasUpgrade(layer, data))}"
|
||||
v-bind:style="[((!hasUpgrade(layer, data) && canAffordUpgrade(layer, data)) ? {'background-color': tmp[layer].color} : {}), tmp[layer].upgrades[data].style]">
|
||||
<span v-if="tmp[layer].upgrades[data].fullDisplay" v-html="tmp[layer].upgrades[data].fullDisplay"></span>
|
||||
<span v-if="layers[layer].upgrades[data].fullDisplay" v-html="run(layers[layer].upgrades[data].fullDisplay, layers[layer].upgrades[data])"></span>
|
||||
<span v-else>
|
||||
<span v-if="tmp[layer].upgrades[data].title">
|
||||
<!--suppress HtmlUnknownTag -->
|
||||
|
@ -238,12 +239,12 @@ function loadVue() {
|
|||
Vue.component("milestone", {
|
||||
props: ["layer", "data"],
|
||||
template: `
|
||||
<td v-if="tmp[layer].milestones && tmp[layer].milestones[data]!== undefined && milestoneShown(layer, data)"
|
||||
v-bind:style="[(!tmp[layer].milestones[data].unlocked) ? {'visibility': 'hidden'} : {}, tmp[layer].milestones[data].style]"
|
||||
<td v-if="tmp[layer].milestones && tmp[layer].milestones[data]!== undefined && milestoneShown(layer, data) && tmp[layer].milestones[data].unlocked"
|
||||
v-bind:style="[tmp[layer].milestones[data].style]"
|
||||
v-bind:class="{milestone: !hasMilestone(layer, data), milestoneDone: hasMilestone(layer, data)}">
|
||||
<h3 v-html="tmp[layer].milestones[data].title"></h3><br>
|
||||
<b v-html="tmp[layer].milestones[data].requirementDescription"></b><br>
|
||||
<span v-html="tmp[layer].milestones[data].effectDescription"></span><br>
|
||||
<span v-html="run(layers[layer].milestones[data].effectDescription, layers[layer].milestones[data])"></span><br>
|
||||
<span v-if="(tmp[layer].milestones[data].toggles)&&(hasMilestone(layer, data))"
|
||||
v-for="toggle in tmp[layer].milestones[data].toggles"><toggle :layer="layer" :data="toggle"
|
||||
v-bind:style="tmp[layer].componentStyles.toggle"/> </span>
|
||||
|
@ -267,7 +268,7 @@ function loadVue() {
|
|||
<button v-if="(tmp[layer].type !== 'none')"
|
||||
v-bind:class="{ [layer]: true, reset: true, locked: !tmp[layer].canReset, can: tmp[layer].canReset}"
|
||||
v-bind:style="[tmp[layer].canReset ? {'background-color': tmp[layer].color} : {}, tmp[layer].componentStyles['prestige-button']]"
|
||||
v-html="tmp[layer].prestigeButtonText" v-on:click="doReset(layer)">
|
||||
v-html="prestigeButtonText(layer)" v-on:click="doReset(layer)">
|
||||
</button>
|
||||
`
|
||||
|
||||
|
@ -287,7 +288,7 @@ function loadVue() {
|
|||
<span v-if="player[layer].points.lt('1e1000')">You have </span>
|
||||
<h2 v-bind:style="{'color': tmp[layer].color, 'text-shadow': '0px 0px 10px ' + tmp[layer].color}">
|
||||
{{ formatWhole(player[layer].points) }}</h2> {{ tmp[layer].resource }}<span
|
||||
v-if="tmp[layer].effectDescription">, <span v-html="tmp[layer].effectDescription"></span></span>
|
||||
v-if="layers[layer].effectDescription">, <span v-html="run(layers[layer].effectDescription, layers[layer])"></span></span>
|
||||
</div>
|
||||
`
|
||||
});
|
||||
|
@ -327,17 +328,33 @@ function loadVue() {
|
|||
props: ['layer', 'data', 'size'],
|
||||
template: `
|
||||
<div v-if="tmp[layer].buyables && tmp[layer].buyables[data]!== undefined && tmp[layer].buyables[data].unlocked" style="display: grid">
|
||||
<button v-bind:class="{ buyable: true, can: tmp[layer].buyables[data].canAfford, locked: !tmp[layer].buyables[data].canAfford}"
|
||||
v-bind:style="[tmp[layer].buyables[data].canAfford ? {'background-color': tmp[layer].buyables[data].color || tmp[layer].color} : {}, size ? {'height': size, 'width': size} : {}, tmp[layer].componentStyles.buyable, tmp[layer].buyables[data].style]"
|
||||
v-on:click="buyBuyable(layer, data)">
|
||||
<button v-bind:class="{ buyable: true, can: tmp[layer].buyables[data].canBuy, locked: !tmp[layer].buyables[data].canAfford, bought: player[layer].buyables[data].gte(tmp[layer].buyables[data].purchaseLimit)}"
|
||||
v-bind:style="[tmp[layer].buyables[data].canBuy ? {'background-color': tmp[layer].buyables[data].color || tmp[layer].color} : {}, size ? {'height': size, 'width': size} : {}, tmp[layer].componentStyles.buyable, tmp[layer].buyables[data].style]"
|
||||
v-on:click="buyBuyable(layer, data)" @mousedown="start" @mouseleave="stop" @mouseup="stop" @touchstart="start" @touchend="stop" @touchcancel="stop">
|
||||
<span v-if= "tmp[layer].buyables[data].title"><h2 v-html="tmp[layer].buyables[data].title"></h2><br></span>
|
||||
<span v-bind:style="{'white-space': 'pre-line'}" v-html="tmp[layer].buyables[data].display"></span>
|
||||
<span v-bind:style="{'white-space': 'pre-line'}" v-html="run(layers[layer].buyables[data].display, layers[layer].buyables[data])"></span>
|
||||
</button>
|
||||
<br v-if="(tmp[layer].buyables[data].sellOne !== undefined && !(tmp[layer].buyables[data].canSellOne !== undefined && tmp[layer].buyables[data].canSellOne == false)) || (tmp[layer].buyables[data].sellAll && !(tmp[layer].buyables[data].canSellAll !== undefined && tmp[layer].buyables[data].canSellAll == false))">
|
||||
<sell-one :layer="layer" :data="data" v-bind:style="tmp[layer].componentStyles['sell-one']" v-if="(tmp[layer].buyables[data].sellOne)&& !(tmp[layer].buyables[data].canSellOne !== undefined && tmp[layer].buyables[data].canSellOne == false)"></sell-one>
|
||||
<sell-all :layer="layer" :data="data" v-bind:style="tmp[layer].componentStyles['sell-all']" v-if="(tmp[layer].buyables[data].sellAll)&& !(tmp[layer].buyables[data].canSellAll !== undefined && tmp[layer].buyables[data].canSellAll == false)"></sell-all>
|
||||
</div>
|
||||
`
|
||||
`,
|
||||
data() { return { interval: false, time: 0,}},
|
||||
methods: {
|
||||
start() {
|
||||
if (!this.interval) {
|
||||
this.interval = setInterval((function() {
|
||||
if(this.time >= 5)
|
||||
buyBuyable(this.layer, this.data)
|
||||
this.time = this.time+1
|
||||
}).bind(this), 50)}
|
||||
},
|
||||
stop() {
|
||||
clearInterval(this.interval)
|
||||
this.interval = false
|
||||
this.time = 0
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
Vue.component("respec-button", {
|
||||
|
@ -345,7 +362,7 @@ function loadVue() {
|
|||
template: `
|
||||
<div>
|
||||
<div class="tooltipBox"><input type="checkbox" v-model="player[layer].noRespecConfirm" ><tooltip v-bind:text="'Disable respec confirmation'"></tooltip></div>
|
||||
<button v-if="tmp[layer].buyables && tmp[layer].buyables.respec && !(tmp[layer].buyables.showRespec !== undefined && tmp[layer].buyables.showRespec == false)" v-on:click="respecBuyables(layer)" v-bind:class="{ longUpg: true, can: player[layer].unlocked, locked: !player[layer].unlocked }">{{tmp[layer].buyables.respecText ? tmp[layer].buyables.respecText : "Respec"}}</button>
|
||||
<button v-if="tmp[layer].buyables && tmp[layer].buyables.respec && !(tmp[layer].buyables.showRespec !== undefined && tmp[layer].buyables.showRespec == false)" v-on:click="respecBuyables(layer)" v-bind:class="{ longUpg: true, can: player[layer].unlocked, locked: !player[layer].unlocked }" style="margin-right: 18px">{{tmp[layer].buyables.respecText ? tmp[layer].buyables.respecText : "Respec"}}</button>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
|
@ -446,20 +463,23 @@ function loadVue() {
|
|||
// data = id of the bar
|
||||
Vue.component("bar", {
|
||||
props: ["layer", "data"],
|
||||
computed: {
|
||||
style() {return constructBarStyle(this.layer, this.data)}
|
||||
},
|
||||
template: `
|
||||
<div v-if="tmp[layer].bars && tmp[layer].bars[data].unlocked !== false"
|
||||
v-bind:style="{'position': 'relative'}">
|
||||
<div
|
||||
v-bind:style="[tmp[layer].bars[data].style, tmp[layer].bars[data].dims, {'display': 'table', 'borderRadius': '10px', 'boxShadow': '0 0 10px 2px var(--shadowColor), inset 0 0 10px 4px var(--innerShadowColor)'}]">
|
||||
<div class="overlayTextContainer barBorder"
|
||||
v-bind:style="[tmp[layer].bars[data].borderStyle, tmp[layer].bars[data].dims]">
|
||||
v-bind:style="[tmp[layer].bars[data].borderStyle, style.dims]">
|
||||
<span class="overlayText" v-bind:style="[tmp[layer].bars[data].style, tmp[layer].bars[data].textStyle]"
|
||||
v-html="tmp[layer].bars[data].display"></span>
|
||||
v-html="run(layers[layer].bars[data].display, layers[layer].bars[data])"></span>
|
||||
</div>
|
||||
<div class="barBG barBorder"
|
||||
v-bind:style="[tmp[layer].bars[data].style, tmp[layer].bars[data].baseStyle, tmp[layer].bars[data].borderStyle, tmp[layer].bars[data].dims]">
|
||||
<div class="fill"
|
||||
v-bind:style="[tmp[layer].bars[data].style, tmp[layer].bars[data].fillStyle, tmp[layer].bars[data].fillDims]"></div>
|
||||
v-bind:style="[tmp[layer].bars[data].style, tmp[layer].bars[data].fillStyle, style.fillDims]"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -491,7 +511,7 @@ function loadVue() {
|
|||
props: ["layer", "data"],
|
||||
template: `
|
||||
<div v-if="tmp[layer].achievements && tmp[layer].achievements[data]!== undefined && tmp[layer].achievements[data].unlocked" v-bind:class="{ [layer]: true, achievement: true, tooltipBox:true, locked: !hasAchievement(layer, data), bought: hasAchievement(layer, data)}"
|
||||
v-bind:style="tmp[layer].achievements[data].computedStyle">
|
||||
v-bind:style="achievementStyle(layer, data)">
|
||||
<tooltip :text="
|
||||
(tmp[layer].achievements[data].tooltip == '') ? false : hasAchievement(layer, data) ? (tmp[layer].achievements[data].doneTooltip ? tmp[layer].achievements[data].doneTooltip : (tmp[layer].achievements[data].tooltip ? tmp[layer].achievements[data].tooltip : 'You did it!'))
|
||||
: (tmp[layer].achievements[data].goalTooltip ? tmp[layer].achievements[data].goalTooltip : (tmp[layer].achievements[data].tooltip ? tmp[layer].achievements[data].tooltip : 'LOCKED'))
|
||||
|
@ -614,9 +634,13 @@ function loadVue() {
|
|||
maxedChallenge,
|
||||
inChallenge,
|
||||
canAffordUpgrade,
|
||||
canBuyBuyable,
|
||||
canCompleteChallenge,
|
||||
subtabShouldNotify,
|
||||
subtabResetNotify,
|
||||
challengeStyle,
|
||||
challengeButtonText,
|
||||
constructBarStyle,
|
||||
VERSION,
|
||||
LAYERS,
|
||||
hotkeys,
|
||||
|
|
16
js/game.js
16
js/game.js
|
@ -5,8 +5,8 @@ let gameEnded = false;
|
|||
|
||||
// Don't change this
|
||||
const TMT_VERSION = {
|
||||
tmtNum: "2.4.1",
|
||||
tmtName: "Rationalized Edition"
|
||||
tmtNum: "2.5.3",
|
||||
tmtName: "Dreams Really Do Come True"
|
||||
}
|
||||
|
||||
function getResetGain(layer, useType = null) {
|
||||
|
@ -117,9 +117,13 @@ function shouldNotify(layer) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (tmp[layer].shouldNotify)
|
||||
return true
|
||||
|
||||
if (isPlainObject(tmp[layer].tabFormat)) {
|
||||
for (let subtab in tmp[layer].tabFormat) {
|
||||
if (subtabShouldNotify(layer, "mainTabs", subtab)) {
|
||||
tmp[layer].trueGlowColor = tmp[layer].tabFormat[subtab].glowColor
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -128,12 +132,13 @@ function shouldNotify(layer) {
|
|||
for (let family in tmp[layer].microtabs) {
|
||||
for (let subtab in tmp[layer].microtabs[family]) {
|
||||
if (subtabShouldNotify(layer, family, subtab)) {
|
||||
tmp[layer].trueGlowColor = tmp[layer].microtabs[family][subtab].glowColor
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tmp[layer].shouldNotify;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
@ -162,7 +167,7 @@ function rowReset(row, layer) {
|
|||
}
|
||||
|
||||
function layerDataReset(layer, keep = []) {
|
||||
let storedData = {unlocked: player[layer].unlocked}; // Always keep unlocked
|
||||
let storedData = {unlocked: player[layer].unlocked, forceTooltip: player[layer].forceTooltip, noRespecConfirm: player[layer].noRespecConfirm} // Always keep these
|
||||
|
||||
for (let thing in keep) {
|
||||
if (player[layer][keep[thing]] !== undefined) {
|
||||
|
@ -508,6 +513,9 @@ const interval = setInterval(function () {
|
|||
}
|
||||
tmp.scrolled = document.getElementById("treeTab")?.scrollTop > 30;
|
||||
updateTemp();
|
||||
updateOomps(diff);
|
||||
updateWidth()
|
||||
updateTabFormats()
|
||||
gameLoop(diff);
|
||||
fixNaNs();
|
||||
adjustPopupTime(0.05);
|
||||
|
|
194
js/technical/displays.js
Normal file
194
js/technical/displays.js
Normal file
|
@ -0,0 +1,194 @@
|
|||
function prestigeButtonText(layer) {
|
||||
if (layers[layer].prestigeButtonText !== undefined)
|
||||
return run(layers[layer].prestigeButtonText(), layers[layer])
|
||||
if (tmp[layer].type == "normal")
|
||||
return `${player[layer].points.lt(1e3) ? (tmp[layer].resetDescription !== undefined ? tmp[layer].resetDescription : "Reset for ") : ""}+<b>${formatWhole(tmp[layer].resetGain)}</b> ${tmp[layer].resource} ${tmp[layer].resetGain.lt(100) && player[layer].points.lt(1e3) ? `<br><br>Next at ${(tmp[layer].roundUpCost ? formatWhole(tmp[layer].nextAt) : format(tmp[layer].nextAt))} ${tmp[layer].baseResource}` : ""}`
|
||||
if (tmp[layer].type == "static")
|
||||
return `${tmp[layer].resetDescription !== undefined ? tmp[layer].resetDescription : "Reset for "}+<b>${formatWhole(tmp[layer].resetGain)}</b> ${tmp[layer].resource}<br><br>${player[layer].points.lt(30) ? (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}
|
||||
`
|
||||
if (tmp[layer].type == "none")
|
||||
return ""
|
||||
|
||||
return "You need prestige button text"
|
||||
}
|
||||
|
||||
function constructNodeStyle(layer){
|
||||
let style = []
|
||||
if ((tmp[layer].isLayer && layerunlocked(layer)) || (!tmp[layer].isLayer && tmp[layer].canClick))
|
||||
style.push({'background-color': tmp[layer].color})
|
||||
if (tmp[layer].image !== undefined)
|
||||
style.push({'background-image': 'url("' + tmp[layer].image + '")'})
|
||||
if(tmp[layer].notify && player[layer].unlocked)
|
||||
style.push({'box-shadow': 'var(--hqProperty2a), 0 0 20px ' + tmp[layer].trueGlowColor})
|
||||
style.push(tmp[layer].nodeStyle)
|
||||
return style
|
||||
}
|
||||
|
||||
|
||||
function challengeStyle(layer, id) {
|
||||
if (player[layer].activeChallenge == id && canCompleteChallenge(layer, id)) return "canComplete"
|
||||
else if (hasChallenge(layer, id)) return "done"
|
||||
return "locked"
|
||||
}
|
||||
|
||||
function challengeButtonText(layer, id) {
|
||||
return (player[layer].activeChallenge==(id)?(canCompleteChallenge(layer, id)?"Finish":"Exit Early"):(hasChallenge(layer, id)?"Completed":"Start"))
|
||||
|
||||
}
|
||||
|
||||
function achievementStyle(layer, id){
|
||||
ach = tmp[layer].achievements[id]
|
||||
let style = []
|
||||
if (ach.image){
|
||||
style.push({'background-image': 'url("' + ach.image + '")'})
|
||||
}
|
||||
if (!ach.unlocked) style.push({'visibility': 'hidden'})
|
||||
style.push(ach.style)
|
||||
return style
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function updateWidth() {
|
||||
var screenWidth = window.innerWidth
|
||||
var splitScreen = screenWidth >= 1024
|
||||
if (player.splitMode === "disabled") splitScreen = false
|
||||
if (player.splitMode === "enabled") splitScreen = true
|
||||
|
||||
|
||||
tmp.other.screenWidth = screenWidth
|
||||
tmp.other.splitScreen = splitScreen
|
||||
tmp.other.lastPoints = player.points
|
||||
}
|
||||
|
||||
function updateOomps(diff)
|
||||
{
|
||||
tmp.other.oompsMag = 0
|
||||
if (player.points.lte(new Decimal(1e100))) return
|
||||
|
||||
var pp = new Decimal(player.points);
|
||||
var lp = tmp.other.lastPoints || new Decimal(0);
|
||||
if (pp.gt(lp)) {
|
||||
if (pp.gte("10^^8")) {
|
||||
pp = pp.slog(1e10)
|
||||
lp = lp.slog(1e10)
|
||||
tmp.other.oomps = pp.sub(lp).div(diff)
|
||||
tmp.other.oompsMag = -1;
|
||||
} else {
|
||||
while (pp.div(lp).log(10).div(diff).gte("100") && tmp.other.oompsMag <= 5 && lp.gt(0)) {
|
||||
pp = pp.log(10)
|
||||
lp = lp.log(10)
|
||||
tmp.other.oomps = pp.sub(lp).div(diff)
|
||||
tmp.other.oompsMag++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function constructBarStyle(layer, id) {
|
||||
let bar = tmp[layer].bars[id]
|
||||
let style = {}
|
||||
if (bar.progress instanceof Decimal)
|
||||
bar.progress = bar.progress.toNumber()
|
||||
bar.progress = (1 -Math.min(Math.max(bar.progress, 0), 1)) * 100
|
||||
|
||||
style.dims = {'width': bar.width + "px", 'height': bar.height + "px"}
|
||||
let dir = bar.direction
|
||||
style.fillDims = {'width': (bar.width + 0.5) + "px", 'height': (bar.height + 0.5) + "px"}
|
||||
|
||||
switch(bar.direction) {
|
||||
case UP:
|
||||
style.fillDims['clip-path'] = 'inset(' + bar.progress + '% 0% 0% 0%)'
|
||||
style.fillDims.width = bar.width + 1 + 'px'
|
||||
break;
|
||||
case DOWN:
|
||||
style.fillDims['clip-path'] = 'inset(0% 0% ' + bar.progress + '% 0%)'
|
||||
style.fillDims.width = bar.width + 1 + 'px'
|
||||
|
||||
break;
|
||||
case RIGHT:
|
||||
style.fillDims['clip-path'] = 'inset(0% ' + bar.progress + '% 0% 0%)'
|
||||
break;
|
||||
case LEFT:
|
||||
style.fillDims['clip-path'] = 'inset(0% 0% 0% ' + bar.progress + '%)'
|
||||
break;
|
||||
case DEFAULT:
|
||||
style.fillDims['clip-path'] = 'inset(0% 50% 0% 0%)'
|
||||
}
|
||||
return style
|
||||
}
|
||||
|
||||
function constructTabFormat(layer, id, family){
|
||||
let tabTemp, tabLayer, tabFunc, location, key
|
||||
if (id === undefined){
|
||||
tabTemp = tmp[layer].tabFormat
|
||||
tabLayer = layers[layer].tabFormat
|
||||
tabFunc = funcs[layer].tabFormat
|
||||
location = tmp[layer]
|
||||
key = "tabFormat"
|
||||
}
|
||||
else if (family === undefined) {
|
||||
tabTemp = tmp[layer].tabFormat[id].content
|
||||
tabLayer = layers[layer].tabFormat[id].content
|
||||
tabFunc = funcs[layer].tabFormat[id].content
|
||||
location = tmp[layer].tabFormat[id]
|
||||
key = "content"
|
||||
|
||||
}
|
||||
else {
|
||||
tabTemp = tmp[layer].microtabs[family][id].content
|
||||
tabLayer = layers[layer].microtabs[family][id].content
|
||||
tabFunc = funcs[layer].microtabs[family][id].content
|
||||
location = tmp[layer].microtabs[family][id]
|
||||
key = "tabFormat"
|
||||
|
||||
}
|
||||
if (isFunction(tabLayer)) {
|
||||
|
||||
let bound = tabLayer.bind(layers[layer])
|
||||
Vue.set(tabTemp, key, bound())
|
||||
}
|
||||
updateTempData(tabLayer, tabTemp, tabFunc)
|
||||
return tabTemp
|
||||
}
|
||||
|
||||
function updateTabFormats() {
|
||||
updateTabFormat(player.tab)
|
||||
updateTabFormat(player.navTab)
|
||||
}
|
||||
|
||||
function updateTabFormat(layer) {
|
||||
if (layers[layer]?.tabFormat === undefined) return
|
||||
|
||||
let tab = player.subtabs[layer]?.mainTabs
|
||||
if (isFunction(layers[layer].tabFormat)) {
|
||||
Vue.set(temp[layer], 'tabFormat', layers[layer].tabFormat())
|
||||
}
|
||||
else if (Array.isArray(layers[layer].tabFormat)) {
|
||||
Vue.set(temp[layer], 'tabFormat', constructTabFormat(layer))
|
||||
}
|
||||
else if (isPlainObject(layers[layer].tabFormat)) {
|
||||
if (layers[layer].tabFormat[tab].embedLayer === undefined)
|
||||
Vue.set(temp[layer].tabFormat[tab], 'content', constructTabFormat(layer, tab))
|
||||
}
|
||||
|
||||
// Check for embedded layer
|
||||
if (isPlainObject(tmp[layer].tabFormat) && tmp[layer].tabFormat[tab].embedLayer !== undefined) {
|
||||
constructTabFormat(tmp[layer].tabFormat[tab].embedLayer)
|
||||
}
|
||||
|
||||
// Update microtabs
|
||||
for (family in layers[layer].microtabs) {
|
||||
tab = player.subtabs[layer][family]
|
||||
|
||||
if (tmp[layer].microtabs[family][tab]) {
|
||||
|
||||
if (tmp[layer].microtabs[family][tab].embedLayer)
|
||||
constructTabFormat(tmp[layer].microtabs[family][tab].embedLayer)
|
||||
else
|
||||
constructTabFormat(layer, tab, family)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -118,7 +118,9 @@ function setupLayer(layer){
|
|||
layers[layer].buyables[thing].layer = layer
|
||||
if (layers[layer].buyables[thing].unlocked === undefined)
|
||||
layers[layer].buyables[thing].unlocked = true
|
||||
}
|
||||
}
|
||||
layers[layer].buyables[thing].canBuy = function() {return canBuyBuyable(this.layer, this.id)}
|
||||
if (layers[layer].buyables[thing].purchaseLimit === undefined) layers[layer].buyables[thing].purchaseLimit = new Decimal(Infinity)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,6 +174,7 @@ function setupLayer(layer){
|
|||
if(layers[layer].displayRow === undefined) layers[layer].displayRow = layers[layer].row
|
||||
if(layers[layer].name === undefined) layers[layer].name = layer
|
||||
if(layers[layer].layerShown === undefined) layers[layer].layerShown = true
|
||||
if(layers[layer].glowColor === undefined) layers[layer].glowColor = "#ff0000"
|
||||
|
||||
let row = layers[layer].row
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ const systemComponents = {
|
|||
<div v-for="tab in Object.keys(data)">
|
||||
<button v-if="data[tab].unlocked === undefined || data[tab].unlocked"
|
||||
v-bind:class="{tabButton: true, notify: subtabShouldNotify(layer, name, tab), resetNotify: subtabResetNotify(layer, name, tab)}"
|
||||
v-bind:style="[{'border-color': tmp[layer].color}, tmp[layer].componentStyles['tab-button'], data[tab].buttonStyle]"
|
||||
v-on:click="function(){player.subtabs[layer][name] = tab; needCanvasUpdate = true;}">{{ tab }}
|
||||
v-bind:style="[{'border-color': tmp[layer].color}, (data[tab].glowColor && subtabShouldNotify(layer, name, tab) ? {'box-shadow': 'var(--hqProperty2a), 0 0 20px ' + data[tab].glowColor} : {}), tmp[layer].componentStyles['tab-button'], data[tab].buttonStyle]"
|
||||
v-on:click="function(){player.subtabs[layer][name] = tab; updateTabFormats(); needCanvasUpdate = true;}">{{ tab }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -41,7 +41,7 @@ const systemComponents = {
|
|||
resetNotify: tmp[layer].prestigeNotify,
|
||||
can: ((player[layer].unlocked || tmp[layer].isLayer) && tmp[layer].isLayer) || (!tmp[layer].isLayer && tmp[layer].canClick),
|
||||
}"
|
||||
v-bind:style="tmp[layer].computedNodeStyle">
|
||||
v-bind:style="constructNodeStyle(layer)">
|
||||
<span v-html="(abb !== '' && tmp[layer].image === undefined) ? abb : ' '"></span>
|
||||
<tooltip
|
||||
v-if="tmp[layer].tooltip != ''"
|
||||
|
@ -119,9 +119,12 @@ const systemComponents = {
|
|||
<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">({{tmp.other.oompsMag != 0 ? format(tmp.other.oomps) + " OOM" + (tmp.other.oompsMag < 0 ? "^OOM" : tmp.other.oompsMag > 1 ? "^" + tmp.other.oompsMag : "") + "s" : formatSmall(getPointGen())}}/sec)</span>
|
||||
<div v-for="thing in tmp.displayThings" class="overlayThing"><span v-if="thing" v-html="thing"></span></div>
|
||||
</div>
|
||||
`
|
||||
|
@ -176,8 +179,7 @@ const systemComponents = {
|
|||
<td><button class="opt" onclick="toggleOpt('offlineProd')">Offline Prod: {{ player.offlineProd?"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="adjustMSDisp()">Show Milestones: {{ player.msDisplay.toUpperCase() }}</button></td>
|
||||
<td><button class="opt" onclick="adjustMSDisp()">Show Milestones: {{ MS_DISPLAYS[MS_SETTINGS.indexOf(player.msDisplay)]}}</button></td>
|
||||
<td><button class="opt" onclick="toggleOpt('hqTree')">High-Quality Tree: {{ player.hqTree?"ON":"OFF" }}</button></td>
|
||||
</table>`
|
||||
},
|
||||
|
|
|
@ -8,7 +8,9 @@ let NaNalert = false;
|
|||
const activeFunctions = [
|
||||
"startData", "onPrestige", "doReset", "update", "automate",
|
||||
"buy", "buyMax", "respec", "onComplete", "onPurchase", "onPress", "onClick", "masterButtonPress",
|
||||
"sellOne", "sellAll", "pay",
|
||||
"sellOne", "sellAll", "pay", "actualCostFunction", "actualEffectFunction",
|
||||
"effectDescription", "display", "fullDisplay", "effectDisplay", "rewardDisplay",
|
||||
"tabFormat", "content",
|
||||
];
|
||||
|
||||
const noCall = doNotCallTheseFunctionsEveryTick;
|
||||
|
@ -34,10 +36,26 @@ function setupTemp() {
|
|||
tmp[layer].canReset = {}
|
||||
tmp[layer].notify = {}
|
||||
tmp[layer].prestigeNotify = {}
|
||||
tmp[layer].prestigeButtonText = {}
|
||||
tmp[layer].computedNodeStyle = []
|
||||
setupBarStyles(layer)
|
||||
setupBuyables(layer)
|
||||
tmp[layer].trueGlowColor = []
|
||||
}
|
||||
|
||||
tmp.other = {
|
||||
screenWidth: window.innerWidth,
|
||||
splitScreen: window.innerWidth >=1024,
|
||||
lastPoints: player.points || new Decimal(0),
|
||||
oomps: new Decimal(0),
|
||||
|
||||
held: {
|
||||
time: null,
|
||||
id: null,
|
||||
layer: null,
|
||||
type: null,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
temp = tmp
|
||||
}
|
||||
|
||||
|
@ -84,14 +102,9 @@ function updateTemp() {
|
|||
tmp[layer].nextAt = getNextAt(layer)
|
||||
tmp[layer].nextAtDisp = getNextAt(layer, true)
|
||||
tmp[layer].canReset = canReset(layer)
|
||||
tmp[layer].trueGlowColor = tmp[layer].glowColor
|
||||
tmp[layer].notify = shouldNotify(layer)
|
||||
tmp[layer].prestigeNotify = prestigeNotify(layer)
|
||||
tmp[layer].prestigeButtonText = prestigeButtonText(layer)
|
||||
constructBarStyles(layer)
|
||||
constructAchievementStyles(layer)
|
||||
constructNodeStyle(layer)
|
||||
updateChallengeDisplay(layer)
|
||||
|
||||
}
|
||||
|
||||
tmp.pointGen = getPointGen()
|
||||
|
@ -101,13 +114,13 @@ function updateTemp() {
|
|||
if (isFunction(text)) text = text()
|
||||
tmp.displayThings.push(text)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function updateTempData(layerData, tmpData, funcsData) {
|
||||
|
||||
for (let item in funcsData){
|
||||
if (Array.isArray(layerData[item])) {
|
||||
if (item === "tabFormat" || item === "content") return // These are only updated when needed
|
||||
updateTempData(layerData[item], tmpData[item], funcsData[item])
|
||||
}
|
||||
else if ((!!layerData[item]) && (layerData[item].constructor === Object) || (typeof layerData[item] === "object") && traversableClasses.includes(layerData[item].constructor.name)){
|
||||
|
@ -126,8 +139,6 @@ function updateTempData(layerData, tmpData, funcsData) {
|
|||
NaNalert = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vue.set(tmpData, item, value)
|
||||
}
|
||||
}
|
||||
|
@ -136,20 +147,8 @@ function updateTempData(layerData, tmpData, funcsData) {
|
|||
function updateChallengeTemp(layer)
|
||||
{
|
||||
updateTempData(layers[layer].challenges, tmp[layer].challenges, funcs[layer].challenges)
|
||||
updateChallengeDisplay(layer)
|
||||
}
|
||||
|
||||
function updateChallengeDisplay(layer) {
|
||||
for (let id in player[layer].challenges) {
|
||||
let style = "locked"
|
||||
if (player[layer].activeChallenge === id && canCompleteChallenge(layer, id)) style = "canComplete"
|
||||
else if (hasChallenge(layer, id)) style = "done"
|
||||
tmp[layer].challenges[id].defaultStyle = style
|
||||
|
||||
tmp[layer].challenges[id].buttonText = (player[layer].activeChallenge===(id)?(canCompleteChallenge(layer, id)?"Finish":"Exit Early"):(hasChallenge(layer, id)?"Completed":"Start"))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function updateBuyableTemp(layer)
|
||||
{
|
||||
|
@ -161,75 +160,20 @@ function updateClickableTemp(layer)
|
|||
updateTempData(layers[layer].clickables, tmp[layer].clickables, funcs[layer].clickables)
|
||||
}
|
||||
|
||||
function constructNodeStyle(layer){
|
||||
let style = []
|
||||
if ((tmp[layer].isLayer && layerunlocked(layer)) || (!tmp[layer].isLayer && tmp[layer].canClick))
|
||||
style.push({'background-color': tmp[layer].color})
|
||||
if (tmp[layer].image !== undefined)
|
||||
style.push({'background-image': 'url("' + tmp[layer].image + '")'})
|
||||
style.push(tmp[layer].nodeStyle)
|
||||
Vue.set(tmp[layer], 'computedNodeStyle', style)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function constructAchievementStyles(layer){
|
||||
for (let id in tmp[layer].achievements) {
|
||||
let ach = tmp[layer].achievements[id]
|
||||
if (isPlainObject(ach)) {
|
||||
let style = []
|
||||
if (ach.image){
|
||||
style.push({'background-image': 'url("' + ach.image + '")'})
|
||||
}
|
||||
if (!ach.unlocked) style.push({'visibility': 'hidden'})
|
||||
style.push(ach.style)
|
||||
Vue.set(ach, 'computedStyle', style)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function constructBarStyles(layer){
|
||||
if (layers[layer].bars === undefined)
|
||||
return
|
||||
for (let 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.progress = (1 -Math.min(Math.max(bar.progress, 0), 1)) * 100
|
||||
|
||||
bar.dims = {'width': bar.width + "px", 'height': bar.height + "px"}
|
||||
let dir = bar.direction
|
||||
bar.fillDims = {'width': (bar.width + 0.5) + "px", 'height': (bar.height + 0.5) + "px"}
|
||||
if (dir !== undefined)
|
||||
{
|
||||
bar.fillDims['clip-path'] = 'inset(0% 50% 0% 0%)'
|
||||
if(dir === UP){
|
||||
bar.fillDims['clip-path'] = 'inset(' + bar.progress + '% 0% 0% 0%)'
|
||||
}
|
||||
else if(dir === DOWN){
|
||||
bar.fillDims['clip-path'] = 'inset(0% 0% ' + bar.progress + '% 0%)'
|
||||
}
|
||||
else if(dir === RIGHT){
|
||||
bar.fillDims['clip-path'] = 'inset(0% ' + bar.progress + '% 0% 0%)'
|
||||
}
|
||||
else if(dir === LEFT){
|
||||
bar.fillDims['clip-path'] = 'inset(0% 0% 0% ' + bar.progress + '%)'
|
||||
}
|
||||
|
||||
function setupBuyables(layer) {
|
||||
for (id in layers[layer].buyables) {
|
||||
if (!isNaN(id)) {
|
||||
let b = layers[layer].buyables[id]
|
||||
b.actualCostFunction = b.cost
|
||||
b.cost = function(x) {
|
||||
x = (x === undefined ? player[this.layer].buyables[this.id] : x)
|
||||
return layers[this.layer].buyables[this.id].actualCostFunction(x)
|
||||
}
|
||||
b.actualEffectFunction = b.effect
|
||||
b.effect = function(x) {
|
||||
x = (x === undefined ? player[this.layer].buyables[this.id] : x)
|
||||
return layers[this.layer].buyables[this.id].actualEffectFunction(x)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function setupBarStyles(layer){
|
||||
if (layers[layer].bars === undefined)
|
||||
return
|
||||
for (let id in layers[layer].bars){
|
||||
let bar = tmp[layer].bars[id]
|
||||
bar.dims = {}
|
||||
bar.fillDims = {}
|
||||
}
|
||||
}
|
49
js/utils.js
49
js/utils.js
|
@ -18,6 +18,11 @@ function canAffordUpgrade(layer, id) {
|
|||
return canAffordPurchase(layer, upg, cost);
|
||||
}
|
||||
|
||||
function canBuyBuyable(layer, id) {
|
||||
let b = temp[layer].buyables[id]
|
||||
return (b.unlocked && b.canAfford && player[layer].buyables[id].lt(b.purchaseLimit))
|
||||
}
|
||||
|
||||
function hasUpgrade(layer, id) {
|
||||
return (player[layer].upgrades.includes(toNumber(id)) || player[layer].upgrades.includes(id.toString()));
|
||||
}
|
||||
|
@ -179,7 +184,7 @@ function buyBuyable(layer, id) {
|
|||
if (!tmp[layer].buyables[id].unlocked) {
|
||||
return;
|
||||
}
|
||||
if (!tmp[layer].buyables[id].canAfford) {
|
||||
if (!tmp[layer].buyables[id].canBuy) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -229,14 +234,14 @@ function showTab(name) {
|
|||
if (player.tab === name && isPlainObject(tmp[name].tabFormat)) {
|
||||
player.subtabs[name].mainTabs = Object.keys(layers[name].tabFormat)[0];
|
||||
}
|
||||
var toTreeTab = name == "none"
|
||||
player.tab = name
|
||||
if (player.navTab == "none" && (tmp[name].row !== "side") && (tmp[name].row !== "otherside")) player.lastSafeTab = name
|
||||
delete player.notify[name]
|
||||
updateTabFormats()
|
||||
needCanvasUpdate = true
|
||||
document.activeElement.blur()
|
||||
|
||||
player.tab = name;
|
||||
if (player.navTab === "none" && (tmp[name].row !== "side") && (tmp[name].row !== "otherside")) {
|
||||
player.lastSafeTab = name;
|
||||
}
|
||||
delete player.notify[name];
|
||||
needCanvasUpdate = true;
|
||||
document.activeElement.blur();
|
||||
}
|
||||
|
||||
function showNavTab(name) {
|
||||
|
@ -244,10 +249,11 @@ function showNavTab(name) {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
player.navTab = name;
|
||||
player.notify[name] = false;
|
||||
needCanvasUpdate = true;
|
||||
var toTreeTab = name == "tree"
|
||||
player.navTab = name
|
||||
player.notify[name] = false
|
||||
updateTabFormats()
|
||||
needCanvasUpdate = true
|
||||
}
|
||||
|
||||
|
||||
|
@ -338,6 +344,7 @@ function layerunlocked(layer) {
|
|||
function keepGoing() {
|
||||
player.keepGoing = true;
|
||||
needCanvasUpdate = true;
|
||||
goBack()
|
||||
}
|
||||
|
||||
function toNumber(x) {
|
||||
|
@ -360,6 +367,7 @@ function updateMilestones(layer) {
|
|||
if (tmp[layer].milestonePopups || tmp[layer].milestonePopups === undefined) {
|
||||
doPopup("milestone", tmp[layer].milestones[id].requirementDescription, "Milestone Gotten!", 3, tmp[layer].color);
|
||||
}
|
||||
player[layer].lastMilestone = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -423,7 +431,6 @@ document.onkeydown = function (e) {
|
|||
if (ctrlDown && hotkeys[key]) e.preventDefault()
|
||||
if (hotkeys[key]) {
|
||||
let k = hotkeys[key]
|
||||
console.log(tmp[k.layer].hotkeys)
|
||||
if (player[k.layer].unlocked && tmp[k.layer].hotkeys[k.id].unlocked)
|
||||
k.onPress()
|
||||
}
|
||||
|
@ -441,20 +448,6 @@ function focused(x) {
|
|||
onFocused = x;
|
||||
}
|
||||
|
||||
function prestigeButtonText(layer) {
|
||||
if (layers[layer].prestigeButtonText !== undefined) {
|
||||
return layers[layer].prestigeButtonText();
|
||||
} else if (tmp[layer].type === "normal") {
|
||||
return `${player[layer].points.lt(1e3) ? (tmp[layer].resetDescription !== undefined ? tmp[layer].resetDescription : "Reset for ") : ""}+<b>${formatWhole(tmp[layer].resetGain)}</b> ${tmp[layer].resource} ${tmp[layer].resetGain.lt(100) && player[layer].points.lt(1e3) ? `<br><br>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 "}+<b>${formatWhole(tmp[layer].resetGain)}</b> ${tmp[layer].resource}<br><br>${player[layer].points.lt(30) ? (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 "You need prestige button text";
|
||||
}
|
||||
}
|
||||
|
||||
function isFunction(obj) {
|
||||
return !!(obj && obj.constructor && obj.call && obj.apply);
|
||||
|
@ -522,7 +515,7 @@ function adjustPopupTime(diff) {
|
|||
}
|
||||
|
||||
function run(func, target, args = null) {
|
||||
if (func && func.constructor && func.call && func.apply) {
|
||||
if (ifFunction(func)) {
|
||||
let bound = func.bind(target);
|
||||
return bound(args);
|
||||
} else {
|
||||
|
|
107
js/utils/NumberFormating.js
Normal file
107
js/utils/NumberFormating.js
Normal file
|
@ -0,0 +1,107 @@
|
|||
|
||||
function exponentialFormat(num, precision, mantissa = true) {
|
||||
let e = num.log10().floor()
|
||||
let m = num.div(Decimal.pow(10, e))
|
||||
if (m.toStringWithDecimalPlaces(precision) == 10) {
|
||||
m = new Decimal(1)
|
||||
e = e.add(1)
|
||||
}
|
||||
e = (e.gte(1e9) ? format(e, 1) : (e.gte(10000) ? commaFormat(e, 0) : e.toStringWithDecimalPlaces(0)))
|
||||
if (mantissa)
|
||||
return m.toStringWithDecimalPlaces(precision) + "e" + e
|
||||
else return "e" + e
|
||||
}
|
||||
|
||||
function commaFormat(num, precision) {
|
||||
if (num === null || num === undefined) return "NaN"
|
||||
if (num.mag < 0.001) return (0).toFixed(precision)
|
||||
return num.toStringWithDecimalPlaces(precision).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")
|
||||
}
|
||||
|
||||
|
||||
function regularFormat(num, precision) {
|
||||
if (num === null || num === undefined) return "NaN"
|
||||
if (num.mag < 0.001) return (0).toFixed(precision)
|
||||
if (num.mag < 0.01) precision = 3
|
||||
return num.toStringWithDecimalPlaces(precision)
|
||||
}
|
||||
|
||||
function fixValue(x, y = 0) {
|
||||
return x || new Decimal(y)
|
||||
}
|
||||
|
||||
function sumValues(x) {
|
||||
x = Object.values(x)
|
||||
if (!x[0]) return new Decimal(0)
|
||||
return x.reduce((a, b) => Decimal.add(a, b))
|
||||
}
|
||||
|
||||
function format(decimal, precision = 2, small) {
|
||||
small = small || modInfo.allowSmall
|
||||
decimal = new Decimal(decimal)
|
||||
if (isNaN(decimal.sign) || isNaN(decimal.layer) || isNaN(decimal.mag)) {
|
||||
player.hasNaN = true;
|
||||
return "NaN"
|
||||
}
|
||||
if (decimal.sign < 0) return "-" + format(decimal.neg(), precision)
|
||||
if (decimal.mag == Number.POSITIVE_INFINITY) return "Infinity"
|
||||
if (decimal.gte("eeee1000")) {
|
||||
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("1e100000")) return exponentialFormat(decimal, 0, false)
|
||||
else if (decimal.gte("1e1000")) return exponentialFormat(decimal, 0)
|
||||
else if (decimal.gte(1e9)) return exponentialFormat(decimal, precision)
|
||||
else if (decimal.gte(1e3)) return commaFormat(decimal, 0)
|
||||
else if (decimal.gte(0.001) || !small) return regularFormat(decimal, precision)
|
||||
else if (decimal.eq(0)) return (0).toFixed(precision)
|
||||
|
||||
decimal = invertOOM(decimal)
|
||||
let val = ""
|
||||
if (decimal.lt("1e1000")){
|
||||
val = exponentialFormat(decimal, precision)
|
||||
return val.replace(/([^(?:e|F)]*)$/, '-$1')
|
||||
}
|
||||
else
|
||||
return format(decimal, precision) + "⁻¹"
|
||||
|
||||
}
|
||||
|
||||
function formatWhole(decimal) {
|
||||
decimal = new Decimal(decimal)
|
||||
if (decimal.gte(1e9)) return format(decimal, 2)
|
||||
if (decimal.lte(0.98) && !decimal.eq(0)) return format(decimal, 2)
|
||||
return format(decimal, 0)
|
||||
}
|
||||
|
||||
function formatTime(s) {
|
||||
if (s < 60) return format(s) + "s"
|
||||
else if (s < 3600) return formatWhole(Math.floor(s / 60)) + "m " + format(s % 60) + "s"
|
||||
else if (s < 86400) return formatWhole(Math.floor(s / 3600)) + "h " + formatWhole(Math.floor(s / 60) % 60) + "m " + format(s % 60) + "s"
|
||||
else if (s < 31536000) return formatWhole(Math.floor(s / 86400) % 365) + "d " + formatWhole(Math.floor(s / 3600) % 24) + "h " + formatWhole(Math.floor(s / 60) % 60) + "m " + format(s % 60) + "s"
|
||||
else return formatWhole(Math.floor(s / 31536000)) + "y " + formatWhole(Math.floor(s / 86400) % 365) + "d " + formatWhole(Math.floor(s / 3600) % 24) + "h " + formatWhole(Math.floor(s / 60) % 60) + "m " + format(s % 60) + "s"
|
||||
}
|
||||
|
||||
function toPlaces(x, precision, maxAccepted) {
|
||||
x = new Decimal(x)
|
||||
let result = x.toStringWithDecimalPlaces(precision)
|
||||
if (new Decimal(result).gte(maxAccepted)) {
|
||||
result = new Decimal(maxAccepted - Math.pow(0.1, precision)).toStringWithDecimalPlaces(precision)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Will also display very small numbers
|
||||
function formatSmall(x, precision=2) {
|
||||
return format(x, precision, true)
|
||||
}
|
||||
|
||||
function invertOOM(x){
|
||||
let e = x.log10().ceil()
|
||||
let m = x.div(Decimal.pow(10, e))
|
||||
e = e.neg()
|
||||
x = new Decimal(10).pow(e).times(m)
|
||||
|
||||
return x
|
||||
}
|
|
@ -43,12 +43,13 @@ function regularFormat(num, precision) {
|
|||
return (0).toFixed(precision);
|
||||
}
|
||||
if (num.mag < 0.01) {
|
||||
return num.toExponential(precision);
|
||||
precision = 3;
|
||||
}
|
||||
return num.toStringWithDecimalPlaces(precision);
|
||||
}
|
||||
|
||||
function format(decimal, precision=2,) {
|
||||
function format(decimal, precision=2, small) {
|
||||
small = small || modInfo.allowSmall;
|
||||
decimal = new Decimal(decimal);
|
||||
if (isNaN(decimal.sign)||isNaN(decimal.layer)||isNaN(decimal.mag)) {
|
||||
player.hasNaN = true;
|
||||
|
@ -75,9 +76,19 @@ function format(decimal, precision=2,) {
|
|||
return exponentialFormat(decimal, precision);
|
||||
} else if (decimal.gte(1e3)) {
|
||||
return commaFormat(decimal, 0);
|
||||
} else {
|
||||
} else if (decimal.gte(0.001) || !small) {
|
||||
return regularFormat(decimal, precision);
|
||||
} else if (decimal.eq(0)) {
|
||||
return (0).toFixed(precision);
|
||||
}
|
||||
|
||||
decimal = invertOOM(decimal);
|
||||
if (decimal.lt("1e1000")){
|
||||
const val = exponentialFormat(decimal, precision);
|
||||
return val.replace(/([^(?:e|F)]*)$/, '-$1');
|
||||
} else {
|
||||
return format(decimal, precision) + "⁻¹";
|
||||
}
|
||||
}
|
||||
|
||||
function formatWhole(decimal) {
|
||||
|
@ -108,3 +119,25 @@ function formatTime(s) {
|
|||
}
|
||||
}
|
||||
|
||||
function toPlaces(x, precision, maxAccepted) {
|
||||
x = new Decimal(x);
|
||||
let result = x.toStringWithDecimalPlaces(precision);
|
||||
if (new Decimal(result).gte(maxAccepted)) {
|
||||
result = new Decimal(maxAccepted - Math.pow(0.1, precision)).toStringWithDecimalPlaces(precision);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Will also display very small numbers
|
||||
function formatSmall(x, precision=2) {
|
||||
return format(x, precision, true);
|
||||
}
|
||||
|
||||
function invertOOM(x){
|
||||
let e = x.log10().ceil();
|
||||
let m = x.div(Decimal.pow(10, e));
|
||||
e = e.neg();
|
||||
x = new Decimal(10).pow(e).times(m);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
|
|
@ -28,9 +28,13 @@ function changeTreeQuality() {
|
|||
function toggleAuto(toggle) {
|
||||
player[toggle[0]][toggle[1]] = !player[toggle[0]][toggle[1]];
|
||||
}
|
||||
|
||||
const MS_DISPLAYS = ["ALL", "LAST, AUTO, INCOMPLETE", "AUTOMATION, INCOMPLETE", "INCOMPLETE", "NONE"];
|
||||
|
||||
const MS_SETTINGS = ["always", "last", "automation", "incomplete", "never"];
|
||||
|
||||
function adjustMSDisp() {
|
||||
let displays = ["always", "automation", "incomplete", "never"];
|
||||
player.msDisplay = displays[(displays.indexOf(player.msDisplay) + 1) % 4];
|
||||
player.msDisplay = MS_SETTINGS[(MS_SETTINGS.indexOf(player.msDisplay) + 1) % 5];
|
||||
}
|
||||
function milestoneShown(layer, id) {
|
||||
let complete = player[layer].milestones.includes(id);
|
||||
|
@ -39,6 +43,8 @@ function milestoneShown(layer, id) {
|
|||
switch (player.msDisplay) {
|
||||
case "always":
|
||||
return true;
|
||||
case "last":
|
||||
return (auto) || !complete || player[layer].lastMilestone === id;
|
||||
case "automation":
|
||||
return (auto) || !complete;
|
||||
case "incomplete":
|
||||
|
|
|
@ -94,6 +94,7 @@ function getStartLayerData(layer) {
|
|||
layerdata.spentOnBuyables = new Decimal(0);
|
||||
layerdata.upgrades = [];
|
||||
layerdata.milestones = [];
|
||||
layerdata.lastMilestone = null;
|
||||
layerdata.achievements = [];
|
||||
layerdata.challenges = getStartChallenges(layer);
|
||||
return layerdata;
|
||||
|
@ -219,6 +220,7 @@ function load() {
|
|||
setupTemp();
|
||||
updateTemp();
|
||||
updateTemp();
|
||||
updateTabFormats();
|
||||
loadVue();
|
||||
}
|
||||
function setupModInfo() {
|
||||
|
|
Loading…
Add table
Reference in a new issue