1
0
Fork 0
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:
Acamaeda 2020-09-30 20:25:14 -04:00
parent 37286ac520
commit 2933537307
7 changed files with 223 additions and 25 deletions

View file

@ -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>

View file

@ -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 : "")

View file

@ -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'
},

View file

@ -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
View file

@ -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>&nbsp;</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>
`
})

View file

@ -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
},

View file

@ -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