mirror of
https://github.com/thepaperpilot/The-Modding-Tree.git
synced 2025-01-31 23:51:37 +00:00
2.0.3
This commit is contained in:
parent
956f13370d
commit
a3d65b72a7
12 changed files with 89 additions and 33 deletions
|
@ -1,5 +1,13 @@
|
|||
# The Modding Tree changelog:
|
||||
|
||||
|
||||
### v2.0.3 - 10/16/20
|
||||
- Fixed hotkeys not displaying in info.
|
||||
- Fixed the game supressing all external hotkeys.
|
||||
- You can use more things as currencies for upgrade costs and challenge goals using currencyLocation.
|
||||
- Added maxTickLength, which can be used to prevent offline time or tab-switching from breaking time-limit based mechanics.
|
||||
- Made buyable respec buttons, and clickable "master" buttons their own components, and gave them a hide/show feature.
|
||||
|
||||
### v2.0.2 - 10/15/20
|
||||
- Branches are now dynamic (they can be functions).
|
||||
- Fixed a crash related to offline time.
|
||||
|
|
|
@ -33,11 +33,9 @@ Individual achievement can have these features:
|
|||
|
||||
- done(): A function returning a boolean to determine if the achievement should be awarded.
|
||||
|
||||
- goalTooltip: Appears when the achievement is hovered over and locked. This is to display the goal (or a hint).
|
||||
It can also be a function that returns updating text. Can use basic HTML.
|
||||
- tooltip: Default tooltip for the achievement, appears when it is hovered over. Should convey the goal and any reward for
|
||||
completing the achievement. It can also be a function that returns updating text. Can use basic HTML.
|
||||
|
||||
- doneTooltip: Appears when the achievement is hovered over and completed. This can display what the player achieved (the goal),
|
||||
and the rewards, if any. It can also be a function that returns updating text. Can use basic HTML.
|
||||
|
||||
- effect(): **optional**, A function that calculates and returns the current values of any bonuses from the achievement.
|
||||
Can return a value or an object containing multiple values.
|
||||
|
@ -52,4 +50,12 @@ Individual achievement can have these features:
|
|||
- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
|
||||
|
||||
- id: **Assigned automagically**. It's the "key" which the achievement was stored under, for convenient access.
|
||||
The achievement in the example's id is 11.
|
||||
The achievement in the example's id is 11.
|
||||
|
||||
|
||||
- goalTooltip: **optional, depracated** Appears when the achievement is hovered over and locked, overrides the basic tooltip.
|
||||
This is to display the goal (or a hint). It can also be a function that returns updating text. Can use basic HTML.
|
||||
|
||||
- doneTooltip: **optional, depracated** Appears when the achievement is hovered over and completed, overrides the basic tooltip.
|
||||
This can display what the player achieved (the goal), and the rewards, if any.
|
||||
It can also be a function that returns updating text. Can use basic HTML.
|
||||
|
|
|
@ -13,9 +13,10 @@ Buyables should be formatted like this:
|
|||
buyables: {
|
||||
rows: # of rows
|
||||
cols: # of columns
|
||||
respec() {}, **optional**, implement it to reset things and give back your currency.
|
||||
Having this function makes a respec button appear
|
||||
respecText: **optional**, text that appears on the respec button
|
||||
respec() {}, //**optional**, implement it to reset things and give back your currency.
|
||||
// Having this function makes a respec button appear
|
||||
respecText:// **optional**, text that appears on the respec button
|
||||
showRespecButton(){} //**optional**, a function determining whether or not to show the button. Defaults to true if absent.
|
||||
11: {
|
||||
display() {return "Blah"},
|
||||
etc
|
||||
|
|
|
@ -53,7 +53,9 @@ By default, challenges use basic Points for the goal. You can change that using
|
|||
- currencyDisplayName: **optional**, the name to display for the currency for the goal
|
||||
- currencyInternalName: **optional**, the internal name for that currency
|
||||
- currencyLayer: **optional**, the internal name of the layer that currency is stored in.
|
||||
If it's part of a layer, omit.
|
||||
If it's not in a layer, omit. If it's not stored directly in a layer, instead use the next feature.
|
||||
- currencyLocation: **optional**, if your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way.
|
||||
This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)
|
||||
|
||||
- completionLimit: **optional**, the amount of times you can complete this challenge. Default is 1 completion.
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ Clickables should be formatted like this:
|
|||
masterButtonPress() // **optional** If this is present, an additional button will appear above the clickables.
|
||||
// pressing it will call the function.
|
||||
masterButtonText: "Press me!" // **optional** text to display on the Master Button
|
||||
showMasterButton(){} //**optional**, a function determining whether or not to show the button. Defaults to true if absent.
|
||||
11: {
|
||||
display() {return "Blah"},
|
||||
etc
|
||||
|
|
|
@ -31,6 +31,11 @@ These are the existing components, but you can create more in v.js:
|
|||
If it's a single value (e.g. "20px"), that determines the height.
|
||||
If you have a pair of arguments, the first is width and the second is height.
|
||||
|
||||
- row: Display a list of components horizontally. The argument is an array of components in the tab layout format.
|
||||
|
||||
- column: Display a list of components vertically. The argument is an array of components in the tab layout format.
|
||||
This is useful to display columns within a row.
|
||||
|
||||
- main-display: The text that displays the main currency for the layer and its effects.
|
||||
|
||||
- prestige-button: The argument is a string that the prestige button should say before the amount of
|
||||
|
@ -50,7 +55,4 @@ These are the existing components, but you can create more in v.js:
|
|||
|
||||
- toggle: A toggle button that toggles a bool value. The data is a pair that identifies what bool to toggle, [layer, id]
|
||||
|
||||
- row: Display a list of components horizontally. The argument is an array of components in the tab layout format.
|
||||
|
||||
- column: Display a list of components vertically. The argument is an array of components in the tab layout format.
|
||||
This is useful to display columns within a row.
|
||||
- respec-button, master-button: The respec and master buttons for buyables and clickables, respectively.
|
|
@ -43,11 +43,13 @@ Individual upgrades can have these features:
|
|||
- onPurchase() - **optional**, this function will be called when the upgrade is purchased.
|
||||
Good for upgrades like "makes this layer act like it was unlocked first".
|
||||
|
||||
By default, upgrades use the main prestige currency for the layer. You can include these to change them:
|
||||
By default, upgrades use the main prestige currency for the layer. You can include these to change them (but it needs to be a Decimal):
|
||||
- currencyDisplayName: **optional**, the name to display for the currency for the upgrade
|
||||
- currencyInternalName: **optional**, the internal name for that currency
|
||||
- currencyLayer: **optional**, the internal name of the layer that currency is stored in.
|
||||
If it's not in a layer (like Points), omit.
|
||||
If it's not in a layer (like Points), omit. If it's not stored directly in a layer, instead use the next feature.
|
||||
- currencyLocation: **optional**, if your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way.
|
||||
This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)
|
||||
|
||||
- style: **Optional**, Applies CSS to this upgrade, in the form of an object where the keys are CSS attributes,
|
||||
and the values are the values for those attributes (both as strings)
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
<br><br>
|
||||
Time Played: {{ formatTime(player.timePlayed) }}<br><br>
|
||||
<h3>Hotkeys</h3><br>
|
||||
<span v-for="key in hotkeys" v-if="player[key.layer].unl"><br>{{key.description}}</span>
|
||||
<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>
|
||||
|
|
16
js/game.js
16
js/game.js
|
@ -37,7 +37,10 @@ function getPointGen() {
|
|||
return gain
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
function getResetGain(layer, useType = null) {
|
||||
let type = useType
|
||||
|
@ -256,11 +259,14 @@ function canCompleteChallenge(layer, x)
|
|||
{
|
||||
if (x != player[layer].activeChallenge) return
|
||||
|
||||
let challenge = layers[layer].challenges[x]
|
||||
let challenge = tmp[layer].challenges[x]
|
||||
|
||||
if (challenge.currencyInternalName){
|
||||
let name = challenge.currencyInternalName
|
||||
if (challenge.currencyLayer){
|
||||
if (challenge.currencyLocation){
|
||||
return !(challenge.currencyLocation[name].lt(challenge.goal))
|
||||
}
|
||||
else if (challenge.currencyLayer){
|
||||
let lr = challenge.currencyLayer
|
||||
return !(player[lr][name].lt(readData(challenge.goal)))
|
||||
}
|
||||
|
@ -306,6 +312,10 @@ function gameLoop(diff) {
|
|||
}
|
||||
if (player.devSpeed) diff *= player.devSpeed
|
||||
|
||||
let limit = maxTickLength()
|
||||
if(diff > limit)
|
||||
diff = limit
|
||||
|
||||
addTime(diff)
|
||||
player.points = player.points.add(tmp.pointGen.times(diff)).max(0)
|
||||
for (layer in layers){
|
||||
|
|
14
js/layers.js
14
js/layers.js
|
@ -107,7 +107,7 @@ addLayer("c", {
|
|||
cost: new Decimal(69),
|
||||
currencyDisplayName: "candies", // Use if using a nonstandard currency
|
||||
currencyInternalName: "points", // Use if using a nonstandard currency
|
||||
currencyLayer: "", // Leave empty if not in a layer "e.g. points"
|
||||
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
|
||||
|
@ -126,6 +126,10 @@ addLayer("c", {
|
|||
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
|
||||
},
|
||||
|
@ -133,6 +137,7 @@ addLayer("c", {
|
|||
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)
|
||||
|
@ -186,8 +191,8 @@ addLayer("c", {
|
|||
}, // Useful for if you gain secondary resources or have other interesting things happen to this layer when you reset it. You gain the currency after this function ends.
|
||||
|
||||
hotkeys: [
|
||||
{key: "c", description: "C: reset for lollipops or whatever", onPress(){if (player[this.layer].unlocked) doReset(this.layer)}},
|
||||
{key: "ctrl+c" + this.layer, description: "Ctrl+c: respec things", onPress(){if (player[this.layer].unlocked) respecBuyables(this.layer)}},
|
||||
{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
|
||||
|
||||
|
@ -485,8 +490,7 @@ addLayer("a", {
|
|||
13: {
|
||||
name: "EIEIO",
|
||||
done() {return player.f.points.gte(1)},
|
||||
goalTooltip: "Get a farm point.", // Shows when achievement is not completed
|
||||
doneTooltip: "Get a farm point.\n\nReward: The dinosaur is now your friend (you can max Farm Points).", // Showed when the achievement is completed
|
||||
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!")}
|
||||
},
|
||||
},
|
||||
|
|
18
js/utils.js
18
js/utils.js
|
@ -356,7 +356,7 @@ function respecBuyables(layer) {
|
|||
}
|
||||
|
||||
function canAffordUpgrade(layer, id) {
|
||||
let upg = layers[layer].upgrades[id]
|
||||
let upg = tmp[layer].upgrades[id]
|
||||
let cost = tmp[layer].upgrades[id].cost
|
||||
return canAffordPurchase(layer, upg, cost)
|
||||
}
|
||||
|
@ -414,9 +414,13 @@ function achievementEffect(layer, id){
|
|||
}
|
||||
|
||||
function canAffordPurchase(layer, thing, cost) {
|
||||
|
||||
if (thing.currencyInternalName){
|
||||
let name = thing.currencyInternalName
|
||||
if (thing.currencyLayer){
|
||||
if (thing.currencyLocation){
|
||||
return !(thing.currencyLocation[name].lt(cost))
|
||||
}
|
||||
else if (thing.currencyLayer){
|
||||
let lr = thing.currencyLayer
|
||||
return !(player[lr][name].lt(cost))
|
||||
}
|
||||
|
@ -433,12 +437,16 @@ function buyUpg(layer, id) {
|
|||
if (!player[layer].unlocked) return
|
||||
if (!layers[layer].upgrades[id].unlocked) return
|
||||
if (player[layer].upgrades.includes(id)) return
|
||||
let upg = layers[layer].upgrades[id]
|
||||
let upg = tmp[layer].upgrades[id]
|
||||
let cost = tmp[layer].upgrades[id].cost
|
||||
|
||||
if (upg.currencyInternalName){
|
||||
let name = upg.currencyInternalName
|
||||
if (upg.currencyLayer){
|
||||
if (upg.currencyLocation){
|
||||
if (upg.currencyLocation[name].lt(cost)) return
|
||||
upg.currencyLocation[name] = upg.currencyLocation[name].sub(cost)
|
||||
}
|
||||
else if (upg.currencyLayer){
|
||||
let lr = upg.currencyLayer
|
||||
if (player[lr][name].lt(cost)) return
|
||||
player[lr][name] = player[lr][name].sub(cost)
|
||||
|
@ -589,7 +597,7 @@ document.onkeydown = function(e) {
|
|||
let key = e.key
|
||||
if (ctrlDown) key = "ctrl+" + key
|
||||
if (onFocused) return
|
||||
if (ctrlDown && key != "-" && key != "_" && key != "+" && key != "=" && key != "r" && key != "R" && key != "F5") e.preventDefault()
|
||||
if (ctrlDown && hotkeys[key]) e.preventDefault()
|
||||
if(hotkeys[key]){
|
||||
if (player[hotkeys[key].layer].unlocked)
|
||||
hotkeys[key].onPress()
|
||||
|
|
20
js/v.js
20
js/v.js
|
@ -199,7 +199,7 @@ function loadVue() {
|
|||
props: ['layer', 'data'],
|
||||
template: `
|
||||
<div v-if="layers[layer].buyables" class="upgTable">
|
||||
<button v-if="tmp[layer].buyables.respec" 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><br>
|
||||
<respec-button v-if="tmp[layer].buyables.respec && !(layers[layer].buyables.showRespec !== undefined && tmp[layer].buyables.showRespec == false)" :layer = "layer" v-bind:style="[{'margin-bottom': '12px'}, tmp[layer].componentStyles['respec-button']]"></respec-button>
|
||||
<div v-for="row in tmp[layer].buyables.rows" class="upgRow">
|
||||
<div v-for="col in tmp[layer].buyables.cols"><div v-if="layers[layer].buyables[row*10+col]!== undefined && tmp[layer].buyables[row*10+col].unlocked" class="upgAlign" v-bind:style="{'margin-left': '7px', 'margin-right': '7px', 'height': (data ? data : 'inherit'),}">
|
||||
<buyable :layer = "layer" :data = "row*10+col" :size = "data" v-bind:style="tmp[layer].componentStyles.buyable"></buyable>
|
||||
|
@ -225,13 +225,19 @@ function loadVue() {
|
|||
`
|
||||
})
|
||||
|
||||
Vue.component('respec-button', {
|
||||
props: ['layer', 'data'],
|
||||
template: `
|
||||
<button v-if="layers[layer].buyables && tmp[layer].buyables.respec && !(layers[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><br>
|
||||
`
|
||||
})
|
||||
|
||||
// data = button size, in px
|
||||
Vue.component('clickables', {
|
||||
props: ['layer', 'data'],
|
||||
template: `
|
||||
<div v-if="layers[layer].clickables" class="upgTable">
|
||||
<button v-if="tmp[layer].clickables.masterButtonPress" v-on:click="layers[layer].clickables.masterButtonPress()" v-bind:class="{ longUpg: true, can: player[layer].unlocked, locked: !player[layer].unlocked }">{{tmp[layer].clickables.masterButtonText ? tmp[layer].clickables.masterButtonText : "Click me!"}}</button><br>
|
||||
<master-button v-if="tmp[layer].clickables.masterButtonPress && !(layers[layer].clickables.showMasterButton !== undefined && tmp[layer].clickables.showMasterButton == false)" :layer = "layer" v-bind:style="[{'margin-bottom': '12px'}, tmp[layer].componentStyles['master-button']]"></master-button>
|
||||
<div v-for="row in tmp[layer].clickables.rows" class="upgRow">
|
||||
<div v-for="col in tmp[layer].clickables.cols"><div v-if="layers[layer].clickables[row*10+col]!== undefined && tmp[layer].clickables[row*10+col].unlocked" class="upgAlign" v-bind:style="{'margin-left': '7px', 'margin-right': '7px', 'height': (data ? data : 'inherit'),}">
|
||||
<clickable :layer = "layer" :data = "row*10+col" :size = "data" v-bind:style="tmp[layer].componentStyles.clickable"></clickable>
|
||||
|
@ -257,6 +263,12 @@ function loadVue() {
|
|||
`
|
||||
})
|
||||
|
||||
Vue.component('master-button', {
|
||||
props: ['layer', 'data'],
|
||||
template: `
|
||||
<button v-if="tmp[layer].clickables && tmp[layer].clickables.masterButtonPress && !(layers[layer].clickables.showMasterButton !== undefined && tmp[layer].clickables.showMasterButton == false)" v-on:click="layers[layer].clickables.masterButtonPress()" v-bind:class="{ longUpg: true, can: player[layer].unlocked, locked: !player[layer].unlocked }">{{tmp[layer].clickables.masterButtonText ? tmp[layer].clickables.masterButtonText : "Click me!"}}</button><br>
|
||||
`
|
||||
})
|
||||
|
||||
// data = button size, in px
|
||||
Vue.component('microtabs', {
|
||||
|
@ -311,8 +323,8 @@ function loadVue() {
|
|||
template: `
|
||||
<div v-if="layers[layer].achievements && layers[layer].achievements[data]!== undefined && tmp[layer].achievements[data].unlocked" v-bind:class="{ [layer]: true, achievement: true, locked: !hasAchievement(layer, data), bought: hasAchievement(layer, data)}"
|
||||
v-bind:tooltip="
|
||||
hasAchievement(layer, data) ? (tmp[layer].achievements[data].doneTooltip ? tmp[layer].achievements[data].doneTooltip : 'You did it!')
|
||||
: (tmp[layer].achievements[data].goalTooltip ? tmp[layer].achievements[data].goalTooltip : 'LOCKED')
|
||||
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'))
|
||||
"
|
||||
|
||||
v-bind:style="[(!tmp[layer].achievements[data].unlocked) ? {'visibility': 'hidden'} : {}, tmp[layer].achievements[data].style,]">
|
||||
|
|
Loading…
Add table
Reference in a new issue