mirror of
https://github.com/Acamaeda/The-Modding-Tree.git
synced 2024-11-21 16:13:55 +00:00
Added "buyables" which can fill the roles of Enhancers or Space Buildings or more! Also enables custom CSS on all components!
This commit is contained in:
parent
37286ac520
commit
2933537307
7 changed files with 223 additions and 25 deletions
14
index.html
14
index.html
|
@ -42,18 +42,20 @@
|
|||
</div>
|
||||
<div v-if="player.tab=='changelog'" class="col right">
|
||||
<button class="back" onclick="showTab('tree')">←</button><br>
|
||||
<h3>v0.0.1: Technically something</h3>
|
||||
<h3>v1.1: Enhanced Edition</h3>
|
||||
<ul>
|
||||
<li>There is a game, but not the right game.</li>
|
||||
<li>Added "Buyables", which can function like Space Buildings or Enhancers.</li>
|
||||
<li>Custom CSS can now be used on any component! Make the third argument an object with the CSS parameters.</li>
|
||||
<li>Lots of minor good things.</li>
|
||||
</ul><br>
|
||||
|
||||
<div class="link" onclick="showTab('Old Stuff')">Alpha / Beta</div><br>
|
||||
</div>
|
||||
<div v-if="player.tab=='changelog_beta'" class="col right">
|
||||
<button class="back" onclick="showTab('changelog')">←</button><br>
|
||||
<h3>v0.0 Literally nothing</h3>
|
||||
<h3>v1.0 Something</h3>
|
||||
<ul>
|
||||
<li>Added nothing</li>
|
||||
<li>The first numbered version.</li>
|
||||
</ul><br>
|
||||
|
||||
</div>
|
||||
|
@ -140,7 +142,7 @@
|
|||
<span v-if="player[layer].best != undefined">Your best {{layers[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)}} {{layers[layer].resource}}<br></span>
|
||||
<milestones :layer="layer"></milestones>
|
||||
<br><br>
|
||||
<buyables :layer="layer"></buyables>
|
||||
<upgrades :layer="layer"></upgrades>
|
||||
<challs :layer="layer"></challs>
|
||||
<br><br>
|
||||
|
@ -148,7 +150,7 @@
|
|||
<div v-if="layers[layer].tabFormat">
|
||||
<div v-for="data in layers[layer].tabFormat">
|
||||
<div v-if="!Array.isArray(data)" v-bind:is="data" :layer= "layer"></div>
|
||||
<div v-else-if="data.length==3" v-bind:is="data[0]" :layer= "layer" :data= "data[1]" :data2="data[2]"></div>
|
||||
<div v-else-if="data.length==3" v-bind:style="(data[2] ? data[2] : {})" v-bind:is="data[0]" :layer= "layer" :data= "data[1]"></div>
|
||||
<div v-else-if="data.length==2" v-bind:is="data[0]" :layer= "layer" :data= "data[1]"></div>
|
||||
</divs>
|
||||
</div>
|
||||
|
|
83
js/game.js
83
js/game.js
|
@ -4,6 +4,11 @@ var needCanvasUpdate = true;
|
|||
var NaNalert = false;
|
||||
var gameEnded = false;
|
||||
|
||||
let VERSION = {
|
||||
num: 1.1,
|
||||
name: "Enhanced Edition"
|
||||
}
|
||||
|
||||
function startPlayerBase() {
|
||||
return {
|
||||
tab: "tree",
|
||||
|
@ -26,6 +31,9 @@ function getStartPlayer() {
|
|||
playerdata = startPlayerBase()
|
||||
for (layer in layers){
|
||||
playerdata[layer] = layers[layer].startData()
|
||||
playerdata[layer].buyables = getStartBuyables(layer)
|
||||
playerdata[layer].spentOnBuyables = new Decimal(0)
|
||||
|
||||
}
|
||||
return playerdata
|
||||
}
|
||||
|
@ -63,6 +71,18 @@ function fixSave() {
|
|||
player[layer][datum] = defaultData[datum]
|
||||
}
|
||||
}
|
||||
|
||||
if (player[layer].spentOnBuyables == undefined)
|
||||
player[layer].spentOnBuyables = new Decimal(0)
|
||||
|
||||
if (layers[layer].buyables) {
|
||||
if (player[layer].buyables == undefined) player[layer].buyables = {}
|
||||
|
||||
for (id in layers[layer].buyables){
|
||||
if (player[layer].buyables[id] == undefined && !isNaN(id))
|
||||
player[layer].buyables[id] = new Decimal(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,6 +158,14 @@ function convertToDecimal() {
|
|||
player[layer].points = new Decimal(player[layer].points)
|
||||
if (player[layer].best != undefined) player[layer].best = new Decimal(player[layer].best)
|
||||
if (player[layer].total !== undefined) player[layer].total = new Decimal(player[layer].total)
|
||||
player[layer].spentOnBuyables = new Decimal(player[layer].spentOnBuyables)
|
||||
|
||||
if (player[layer].buyables != undefined) {
|
||||
for (id in player[layer].buyables)
|
||||
player[layer].buyables[id] = new Decimal(player[layer].buyables[id])
|
||||
}
|
||||
player[layer].best = new Decimal(player[layer].best)
|
||||
|
||||
if (layers[layer].convertToDecimal) layers[layer].convertToDecimal();
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +205,7 @@ function sumValues(x) {
|
|||
return x.reduce((a, b) => Decimal.add(a, b))
|
||||
}
|
||||
|
||||
function format(decimal, precision=3) {
|
||||
function format(decimal, precision=2) {
|
||||
decimal = new Decimal(decimal)
|
||||
if (isNaN(decimal.sign)||isNaN(decimal.layer)||isNaN(decimal.mag)) {
|
||||
player.hasNaN = true;
|
||||
|
@ -281,6 +309,23 @@ function rowReset(row, layer) {
|
|||
|
||||
function fullLayerReset(layer) {
|
||||
player[layer] = layers[layer].startData();
|
||||
resetBuyables(layer)
|
||||
}
|
||||
|
||||
function resetBuyables(layer){
|
||||
if (layers[layer].buyables)
|
||||
player[layer].buyables = getStartBuyables(layer)
|
||||
player[layer].spentOnBuyables = new Decimal(0)
|
||||
}
|
||||
|
||||
function getStartBuyables(layer){
|
||||
let data = {}
|
||||
if (layers[layer].buyables) {
|
||||
for (id in layers[layer].buyables)
|
||||
if (!isNaN(id))
|
||||
data[id] = new Decimal(0)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
function addPoints(layer, gain) {
|
||||
|
@ -340,21 +385,32 @@ function doReset(layer, force=false) {
|
|||
updateTemp()
|
||||
}
|
||||
|
||||
function respecBuyables(layer) {
|
||||
if (!layers[layer].buyables) return
|
||||
if (!layers[layer].buyables.respec) return
|
||||
if (!confirm("Are you sure you want to respec? This will force you to do a \"" + layer + "\" reset as well!")) return
|
||||
layers[layer].buyables.respec()
|
||||
}
|
||||
|
||||
function canAffordUpg(layer, id) {
|
||||
upg = layers[layer].upgrades[id]
|
||||
cost = upg.cost
|
||||
return canAffordPurchase(layer, upg, cost)
|
||||
}
|
||||
|
||||
if (upg.currencyInternalName){
|
||||
let name = upg.currencyInternalName
|
||||
if (upg.currencyLayer){
|
||||
let lr = upg.currencyLayer
|
||||
return !(player[lr][name].lt(upg.cost))
|
||||
function canAffordPurchase(layer, thing, cost) {
|
||||
if (thing.currencyInternalName){
|
||||
let name = thing.currencyInternalName
|
||||
if (thing.currencyLayer){
|
||||
let lr = thing.currencyLayer
|
||||
return !(player[lr][name].lt(cost))
|
||||
}
|
||||
else {
|
||||
return !(player[name].lt(upg.cost))
|
||||
return !(player[name].lt(cost))
|
||||
}
|
||||
}
|
||||
else {
|
||||
return !(player[layer].points.lt(upg.cost))
|
||||
return !(player[layer].points.lt(cost))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,6 +441,13 @@ function buyUpg(layer, id) {
|
|||
upg.onPurchase()
|
||||
}
|
||||
|
||||
function buyBuyable(layer, id) {
|
||||
if (!player[layer].unl) return
|
||||
if (!layers[layer].buyables[id].unl()) return
|
||||
if (!layers[layer].buyables[id].canAfford()) return
|
||||
|
||||
layers[layer].buyables[id].buy()
|
||||
}
|
||||
|
||||
function resetRow(row) {
|
||||
if (prompt('Are you sure you want to reset this row? It is highly recommended that you wait until the end of your current run before doing this! Type "I WANT TO RESET THIS" to confirm')!="I WANT TO RESET THIS") return
|
||||
|
@ -482,10 +545,6 @@ function milestoneShown(layer, id) {
|
|||
}
|
||||
|
||||
|
||||
let VERSION = {
|
||||
num: 1.0,
|
||||
name: "Something"
|
||||
}
|
||||
|
||||
VERSION.withoutName = "v" + VERSION.num + (VERSION.pre ? " Pre-Release " + VERSION.pre : VERSION.pre ? " Beta " + VERSION.beta : "")
|
||||
VERSION.withName = VERSION.withoutName + (VERSION.name ? ": " + VERSION.name : "")
|
||||
|
|
49
js/layers.js
49
js/layers.js
|
@ -7,6 +7,7 @@ var layers = {
|
|||
total: new Decimal(0),
|
||||
upgrades: [],
|
||||
milestones: [],
|
||||
buyables: {}, // You don't actually have to initialize this one
|
||||
beep: false,
|
||||
}},
|
||||
color: "#4BEC13",
|
||||
|
@ -67,7 +68,7 @@ var layers = {
|
|||
if (ret.gte("1e20000000")) ret = ret.sqrt().times("1e10000000")
|
||||
return ret;
|
||||
},
|
||||
effDisp(x) { return format(x)+"x" },
|
||||
effDisp(fx) { return format(fx)+"x" },
|
||||
},
|
||||
13: {
|
||||
desc: "Make this layer act like you bought it first.",
|
||||
|
@ -81,6 +82,48 @@ var layers = {
|
|||
}
|
||||
},
|
||||
},
|
||||
buyables: {
|
||||
rows: 1,
|
||||
cols: 1,
|
||||
respec() { // Optional, reset things and give back your currency. Having this function makes a respec button appear
|
||||
player.c.points = player.c.points.add(player.c.spentOnBuyables) // A built-in thing to keep track of this but only keeps a single value
|
||||
resetBuyables("c")
|
||||
doReset("c", 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) { // 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()
|
||||
},
|
||||
effects(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))
|
||||
|
||||
if (x.gte(0)) eff.second = x.pow(0.8)
|
||||
else eff.second = x.times(-1).pow(0.8).times(-1)
|
||||
return eff;
|
||||
},
|
||||
display (){
|
||||
let data = tmp.buyables.c["11"]
|
||||
return "Cost: " + format(data.cost) + " lollipops\n\
|
||||
Amount: " + player.c.buyables["11"] + "\n\
|
||||
Adds + " + format(data.effects.first) + " things and multiplies stuff by " + format(data.effects.second)
|
||||
},
|
||||
unl() { return player.c.unl },
|
||||
canAfford() {return player.c.points.gte(tmp.buyables.c[11].cost)},
|
||||
buy() {
|
||||
cost = tmp.buyables.c[11].cost
|
||||
player.c.points = player.c.points.sub(cost)
|
||||
player.c.buyables[11] = player.c.buyables[11].add(1)
|
||||
player.c.spentOnBuyables = player.c.spentOnBuyables.add(cost) // This is a built-in system that you can use for respeccing but it only works with a single Decimal value
|
||||
},
|
||||
buyMax() {}, // You'll have to handle this yourself if you want
|
||||
},
|
||||
},
|
||||
doReset(layer){
|
||||
if(layers[layer].row > layers["c"].row) fullLayerReset('c') // This is actually the default behavior
|
||||
},
|
||||
|
@ -105,9 +148,9 @@ var layers = {
|
|||
["display-text",
|
||||
function() {return 'I have ' + format(player.points) + ' pointy points!'},
|
||||
{"color": "red", "font-size": "32px", "font-family": "Comic Sans MS"}],
|
||||
"blank",
|
||||
["buyables", "150px"],
|
||||
["toggle", ["c", "beep"]],
|
||||
"milestones", "blank", "blank", "upgrades"],
|
||||
"milestones", "upgrades"],
|
||||
style: {
|
||||
'background-color': 'blue'
|
||||
},
|
||||
|
|
12
js/temp.js
12
js/temp.js
|
@ -15,11 +15,23 @@ function updateTemp() {
|
|||
if (!tmp.layerReqs) tmp.layerReqs = {}
|
||||
for (layer in layers) tmp.layerReqs[layer] = layers[layer].requires()
|
||||
|
||||
if (!tmp.buyables) tmp.buyables = {}
|
||||
for (layer in layers) if (layers[layer].buyables) {
|
||||
if (!tmp.buyables[layer]) tmp.buyables[layer] = {}
|
||||
for (id in player[layer].buyables){
|
||||
if (!tmp.buyables[layer][id]) tmp.buyables[layer][id] = {}
|
||||
tmp.buyables[layer][id]
|
||||
tmp.buyables[layer][id].cost = layers[layer].buyables[id].cost(player[layer].buyables[id])
|
||||
tmp.buyables[layer][id].effects = layers[layer].buyables[id].effects(player[layer].buyables[id])
|
||||
}
|
||||
}
|
||||
|
||||
if (!tmp.gainMults) tmp.gainMults = {}
|
||||
if (!tmp.gainExp) tmp.gainExp = {}
|
||||
if (!tmp.resetGain) tmp.resetGain = {}
|
||||
if (!tmp.nextAt) tmp.nextAt = {}
|
||||
if (!tmp.layerAmt) tmp.layerAmt = {}
|
||||
|
||||
for (layer in layers) {
|
||||
tmp.layerAmt[layer] = layers[layer].baseAmount()
|
||||
tmp.gainMults[layer] = layers[layer].gainMult()
|
||||
|
|
43
js/v.js
43
js/v.js
|
@ -57,6 +57,7 @@ function loadVue() {
|
|||
<button v-if="layers[layer].upgrades[row*10+col].unl()" v-on:click="buyUpg(layer, row*10+col)" v-bind:class="{ [layer]: true, upg: true, bought: player[layer].upgrades.includes(row*10+col), locked: (!(canAffordUpg(layer, row*10+col))&&!player[layer].upgrades.includes(row*10+col)), can: (canAffordUpg(layer, row*10+col)&&!player[layer].upgrades.includes(row*10+col))}" v-bind:style="{'background-color': layers[layer].color}">{{ layers[layer].upgrades[row*10+col].desc }}<span v-if="layers[layer].upgrades[row*10+col].effect"><br>Currently: {{(layers[layer].upgrades[row*10+col].effDisp) ? (layers[layer].upgrades[row*10+col].effDisp(layers[layer].upgrades[row*10+col].effect())) : format(layers[layer].upgrades[row*10+col].effect())}}</span><br><br>Cost: {{ formatWhole(layers[layer].upgrades[row*10+col].cost) }} {{(layers[layer].upgrades[row*10+col].currencyDisplayName ? layers[layer].upgrades[row*10+col].currencyDisplayName : layers[layer].resource)}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
|
@ -70,6 +71,7 @@ function loadVue() {
|
|||
<td v-if="milestoneShown(layer, id)" v-bind:class="{milestone: !player[layer].milestones.includes(id), milestoneDone: player[layer].milestones.includes(id)}"><h3>{{layers[layer].milestones[id].requirementDesc}}</h3><br>{{layers[layer].milestones[id].effectDesc}}<br><span v-if="(layers[layer].milestones[id].toggles)&&(player[layer].milestones.includes(id))" v-for="toggle in layers[layer].milestones[id].toggles"><toggle :layer= "layer" :data= "toggle"></toggle> </span></td></tr>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
|
@ -100,11 +102,44 @@ function loadVue() {
|
|||
`
|
||||
})
|
||||
|
||||
// data = a function returning the content, data2 = a CSS object with the formatting (optional)
|
||||
Vue.component('display-text', {
|
||||
props: ['layer', 'data' , 'data2'],
|
||||
// data = button size, in px
|
||||
Vue.component('buyables', {
|
||||
props: ['layer', 'data'],
|
||||
template: `
|
||||
<span v-bind:style="(data2 ? data2 : {})">{{data()}}</span>
|
||||
<div v-if="layers[layer].buyables" class="upgTable">
|
||||
<button v-if="layers[layer].buyables.respec" v-on:click="respecBuyables(layer)" v-bind:class="{ longUpg: true, can: player[layer].unl, locked: !player[layer].unl }">{{layers[layer].buyables.respecText ? layers[layer].buyables.respecText : "Respec"}}</button><br>
|
||||
<div v-for="row in layers[layer].buyables.rows" class="upgRow">
|
||||
<div v-for="col in layers[layer].buyables.cols" class="upgAlign" v-bind:style="{'margin-left': '7px', 'margin-right': '7px', 'height': (data ? data : '200px'),}">
|
||||
<buyable :layer = "layer" :data = "row*10+col" :size = "data"></buyable>
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
|
||||
// data = id of buyable
|
||||
Vue.component('buyable', {
|
||||
props: ['layer', 'data', 'size'],
|
||||
template: `
|
||||
<div v-if="layers[layer].buyables">
|
||||
<button
|
||||
v-if="layers[layer].buyables[data].unl()"
|
||||
v-bind:class="{ upg: true, can: layers[layer].buyables[data].canAfford(), locked: !layers[layer].buyables[data].canAfford()}"
|
||||
v-bind:style="{'background-color': layers[layer].color, 'height': (size ? size : '200px'), 'width': (size ? size : '200px')}"
|
||||
v-on:click="buyBuyable(layer, data)">
|
||||
<span v-if= "layers[layer].buyables[data].title"><h2>{{layers[layer].buyables[data].title}}</h2><br></span>
|
||||
<span v-bind:style="{'white-space': 'pre-line'}">{{layers[layer].buyables[data].display()}}</span>
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
|
||||
// data = a function returning the content
|
||||
Vue.component('display-text', {
|
||||
props: ['layer', 'data'],
|
||||
template: `
|
||||
<span>{{data()}}</span>
|
||||
`
|
||||
})
|
||||
|
||||
|
|
|
@ -108,6 +108,48 @@ var layers = {
|
|||
onComplete() {console.log("hiii")} // Called when you complete the challenge
|
||||
},
|
||||
},
|
||||
buyables: {
|
||||
rows: 1,
|
||||
cols: 1,
|
||||
respec() { // Optional, reset things and give back your currency. Having this function makes a respec button appear
|
||||
player.c.points = player.c.points.add(player.c.spentOnBuyables) // A built-in thing to keep track of this but only keeps a single value
|
||||
resetBuyables("c")
|
||||
doReset("c", 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) { // 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()
|
||||
},
|
||||
effects(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))
|
||||
|
||||
if (x.gte(0)) eff.second = x.pow(0.8)
|
||||
else eff.second = x.times(-1).pow(0.8).times(-1)
|
||||
return eff;
|
||||
},
|
||||
display (){
|
||||
let data = tmp.buyables.c["11"]
|
||||
return "Cost: " + format(data.cost) + " lollipops\n\
|
||||
Amount: " + player.c.buyables["11"] + "\n\
|
||||
Adds + " + format(data.effects.first) + " things and multiplies stuff by " + format(data.effects.second)
|
||||
},
|
||||
unl() { return player.c.unl },
|
||||
canAfford() {return player.c.points.gte(tmp.buyables.c[11].cost)},
|
||||
buy() {
|
||||
cost = tmp.buyables.c[11].cost
|
||||
player.c.points = player.c.points.sub(cost)
|
||||
player.c.buyables[11] = player.c.buyables[11].add(1)
|
||||
player.c.spentOnBuyables = player.c.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
|
||||
},
|
||||
},
|
||||
convertToDecimal() {
|
||||
// Convert any layer-specific values (besides points, total, and best) to Decimal after loading
|
||||
},
|
||||
|
|
|
@ -53,6 +53,11 @@ td {
|
|||
vertical-align: 0
|
||||
}
|
||||
|
||||
.bigUpgAlign {
|
||||
height: 200px;
|
||||
vertical-align: 0
|
||||
}
|
||||
|
||||
h1, h2, h3, b, input {
|
||||
display: inline;
|
||||
font-family: "Lucida Console", "Courier New", monospace
|
||||
|
|
Loading…
Reference in a new issue