mirror of
https://github.com/thepaperpilot/The-Modding-Tree.git
synced 2025-01-31 23:51:37 +00:00
Achievements
This commit is contained in:
parent
d9d2f777a7
commit
923f096aa0
12 changed files with 173 additions and 14 deletions
|
@ -39,4 +39,5 @@ All display text can be basic HTML instead (But you can't use most Vue features
|
||||||
- [Custom Tab Layouts](custom-tab-layouts.md): An optional way to give your tabs a different layout.
|
- [Custom Tab Layouts](custom-tab-layouts.md): An optional way to give your tabs a different layout.
|
||||||
You can even create entirely new components to use.
|
You can even create entirely new components to use.
|
||||||
- [Subtabs and Microtabs](subtabs-and-microtabs.md): Create subtabs for your tabs, as well as "microtab" components that you can put inside the tabs.
|
- [Subtabs and Microtabs](subtabs-and-microtabs.md): Create subtabs for your tabs, as well as "microtab" components that you can put inside the tabs.
|
||||||
|
- [Achievements](milestones.md): How to create achievements for a layer (or for the whole game).
|
||||||
- [Updating TMT](updating-tmt.md): Using Github Desktop to update your mod's version of TMT.
|
- [Updating TMT](updating-tmt.md): Using Github Desktop to update your mod's version of TMT.
|
||||||
|
|
55
docs/achievements.md
Normal file
55
docs/achievements.md
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#Achievements
|
||||||
|
|
||||||
|
Achievements are awarded to the player when they meet a certain goal, and give some benefit.
|
||||||
|
Currently, they are pretty basic, but additional features will be added later to help.
|
||||||
|
|
||||||
|
You can make global achievements by putting them in a side layer (make its row "side" instead of a number)
|
||||||
|
|
||||||
|
Useful functions for dealing with achievements and implementing their effects:
|
||||||
|
|
||||||
|
- hasAchievement(layer, id): determine if the player has the Achievement
|
||||||
|
- achievementEffect(layer, id): Returns the current effects of the achievement, if any
|
||||||
|
|
||||||
|
|
||||||
|
Achievements should be formatted like this:
|
||||||
|
|
||||||
|
```js
|
||||||
|
achievements: {
|
||||||
|
rows: # of rows
|
||||||
|
cols: # of columns
|
||||||
|
11: {
|
||||||
|
name: "Blah",
|
||||||
|
more features
|
||||||
|
}
|
||||||
|
etc
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Each achievement should have an id where the first digit is the row and the second digit is the column.
|
||||||
|
Individual achievement can have these features:
|
||||||
|
|
||||||
|
- name: **optional**, displayed at the top of the achievement. The only visible text.
|
||||||
|
It can also be a function that returns updating text. Can use basic HTML.
|
||||||
|
|
||||||
|
- 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.
|
||||||
|
|
||||||
|
- 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.
|
||||||
|
|
||||||
|
- unlocked(): **optional**, A function returning a bool to determine if the achievement is visible or not. Default is unlocked.
|
||||||
|
|
||||||
|
- onComplete() - **optional**, this function will be called when the achievement is completed.
|
||||||
|
|
||||||
|
- style: **Optional**, Applies CSS to this achievement, 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
|
||||||
|
|
||||||
|
- 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.
|
|
@ -36,14 +36,14 @@ These are the existing components, but you can create more in v.js:
|
||||||
- prestige-button: The argument is a string that the prestige button should say before the amount of
|
- prestige-button: The argument is a string that the prestige button should say before the amount of
|
||||||
currency you will gain. It can also be a function that returns updating text.
|
currency you will gain. It can also be a function that returns updating text.
|
||||||
|
|
||||||
- upgrades, milestones, challs: Display the upgrades, milestones, and challenges for a layer, as appropriate.
|
- upgrades, milestones, challs, achievements: Display the upgrades, milestones, and challenges for a layer, as appropriate.
|
||||||
|
|
||||||
- buyables, clickables: Display all of the buyables/clickables for this layer, as appropriate. The argument optional,
|
- buyables, clickables: Display all of the buyables/clickables for this layer, as appropriate. The argument optional,
|
||||||
and is the size of the boxes in pixels.
|
and is the size of the boxes in pixels.
|
||||||
|
|
||||||
- microtabs: Display a set of subtabs for an area. The argument is the name of the set of microtabs in the "microtabs" feature.
|
- microtabs: Display a set of subtabs for an area. The argument is the name of the set of microtabs in the "microtabs" feature.
|
||||||
|
|
||||||
- upgrade, milestone, chall, buyable: An individual upgrade, challenge, etc. The argument is the id.
|
- upgrade, milestone, chall, buyable, clickable, achievement: An individual upgrade, challenge, etc. The argument is the id.
|
||||||
This can be used if you want to have upgrades split up across multiple subtabs, for example.
|
This can be used if you want to have upgrades split up across multiple subtabs, for example.
|
||||||
|
|
||||||
- bar: Display a bar. The argument is the id of the bar to display.
|
- bar: Display a bar. The argument is the id of the bar to display.
|
||||||
|
|
|
@ -90,6 +90,10 @@ Key:
|
||||||
- bars: Display some information as a progress bar, gague, or similar. They are highly customizable, and can be vertical as well.
|
- bars: Display some information as a progress bar, gague, or similar. They are highly customizable, and can be vertical as well.
|
||||||
[Explanations are in a separate file.](bars.md)
|
[Explanations are in a separate file.](bars.md)
|
||||||
|
|
||||||
|
- achievements: Kind of like milestones, but with a different display style and some other differences. Extra features are on the way at a later date!
|
||||||
|
[Explanations are in a separate file.](achievements.md)
|
||||||
|
|
||||||
|
|
||||||
# Prestige formula features
|
# Prestige formula features
|
||||||
|
|
||||||
- baseResource: The name of the resource that determines how much of the main currency you gain on reset.
|
- baseResource: The name of the resource that determines how much of the main currency you gain on reset.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#Milestones
|
#Milestones
|
||||||
|
|
||||||
Milestones should be formatted like this:
|
Milestones are awarded to the player when they meet a certain goal, and give some benefit. Milestones should be formatted like this:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
milestones: {
|
milestones: {
|
||||||
|
@ -21,7 +21,7 @@ Milestone features:
|
||||||
- effectDesc: A string describing the reward for having the milestone. *You will have to implement the reward elsewhere.*
|
- effectDesc: A string describing the reward for having the milestone. *You will have to implement the reward elsewhere.*
|
||||||
It can also be a function that returns updating text. Can use basic HTML.
|
It can also be a function that returns updating text. Can use basic HTML.
|
||||||
|
|
||||||
- done(): A function returning a boolean to determine if the milestone has been fulfilled.
|
- done(): A function returning a boolean to determine if the milestone should be awarded.
|
||||||
|
|
||||||
- toggles: *optional*, Creates toggle buttons that appear on the milestone when it is unlocked.
|
- toggles: *optional*, Creates toggle buttons that appear on the milestone when it is unlocked.
|
||||||
The toggles can toggle a given boolean value in a layer.
|
The toggles can toggle a given boolean value in a layer.
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# Upgrades
|
# Upgrades
|
||||||
|
|
||||||
Upgrades are stored in the following format:
|
|
||||||
|
|
||||||
Useful functions for dealing with Upgrades and implementing their effects:
|
Useful functions for dealing with Upgrades and implementing their effects:
|
||||||
|
|
||||||
- hasUpgrade(layer, id): determine if the player has the upgrade
|
- hasUpgrade(layer, id): determine if the player has the upgrade
|
||||||
|
@ -9,6 +7,7 @@ Useful functions for dealing with Upgrades and implementing their effects:
|
||||||
|
|
||||||
Hint: Basic point gain is calculated in game.js's "getPointGain".
|
Hint: Basic point gain is calculated in game.js's "getPointGain".
|
||||||
|
|
||||||
|
Upgrades are stored in the following format:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
upgrades: {
|
upgrades: {
|
||||||
|
|
|
@ -17,9 +17,9 @@ let modInfo = {
|
||||||
// Set your version in num and name, but leave the tmt values so people know what version it is
|
// Set your version in num and name, but leave the tmt values so people know what version it is
|
||||||
let VERSION = {
|
let VERSION = {
|
||||||
num: "2.0",
|
num: "2.0",
|
||||||
name: "Finally making some progress!",
|
name: "Pinnacle of Achievement Mountain",
|
||||||
tmtNum: "2.0",
|
tmtNum: "2.0",
|
||||||
tmtName: "Finally making some progress!"
|
tmtName: "Pinnacle of Achievement Mountain"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines if it should show points/sec
|
// Determines if it should show points/sec
|
||||||
|
@ -182,6 +182,7 @@ function doReset(layer, force=false) {
|
||||||
|
|
||||||
addPoints(layer, gain)
|
addPoints(layer, gain)
|
||||||
updateMilestones(layer)
|
updateMilestones(layer)
|
||||||
|
updateAchievements(layer)
|
||||||
|
|
||||||
if (!player[layer].unlocked) {
|
if (!player[layer].unlocked) {
|
||||||
player[layer].unlocked = true;
|
player[layer].unlocked = true;
|
||||||
|
@ -312,6 +313,7 @@ function gameLoop(diff) {
|
||||||
|
|
||||||
for (layer in layers){
|
for (layer in layers){
|
||||||
if (layers[layer].milestones) updateMilestones(layer);
|
if (layers[layer].milestones) updateMilestones(layer);
|
||||||
|
if (layers[layer].achievements) updateAchievements(layer)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.hasNaN&&!NaNalert) {
|
if (player.hasNaN&&!NaNalert) {
|
||||||
|
|
|
@ -52,6 +52,16 @@ function updateLayers(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (layers[layer].achievements){
|
||||||
|
for (thing in layers[layer].achievements){
|
||||||
|
if (!isNaN(thing)){
|
||||||
|
layers[layer].achievements[thing].id = thing
|
||||||
|
layers[layer].achievements[thing].layer = layer
|
||||||
|
if (layers[layer].achievements[thing].unlocked === undefined)
|
||||||
|
layers[layer].achievements[thing].unlocked = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (layers[layer].challenges){
|
if (layers[layer].challenges){
|
||||||
for (thing in layers[layer].challenges){
|
for (thing in layers[layer].challenges){
|
||||||
if (!isNaN(thing)){
|
if (!isNaN(thing)){
|
||||||
|
|
34
js/layers.js
34
js/layers.js
|
@ -576,8 +576,8 @@ addLayer("a", {
|
||||||
}},
|
}},
|
||||||
color: "yellow",
|
color: "yellow",
|
||||||
requires: new Decimal (1),
|
requires: new Decimal (1),
|
||||||
resource: "idk",
|
resource: "achievement power",
|
||||||
baseResource: "candies",
|
baseResource: "achievements",
|
||||||
baseAmount() {return player.points},
|
baseAmount() {return player.points},
|
||||||
type: "normal", // A "Custom" type which is effectively static
|
type: "normal", // A "Custom" type which is effectively static
|
||||||
exponent: 0.5,
|
exponent: 0.5,
|
||||||
|
@ -589,9 +589,35 @@ addLayer("a", {
|
||||||
},
|
},
|
||||||
row: "side",
|
row: "side",
|
||||||
layerShown() {return true},
|
layerShown() {return true},
|
||||||
tooltipUnlocked() { // Optional, tooltip displays when the layer is locked
|
tooltip() { // Optional, tooltip displays when the layer is locked
|
||||||
return ("YEETS")
|
return ("Achievements")
|
||||||
},
|
},
|
||||||
|
achievements: {
|
||||||
|
rows: 2,
|
||||||
|
cols: 3,
|
||||||
|
11: {
|
||||||
|
name: "Get me!",
|
||||||
|
done() {return true}, // This one is a freebie
|
||||||
|
goalTooltip: "How did this happen?", // Shows when achievement is not completed
|
||||||
|
doneTooltip: "You did it!", // Showed when the achievement is completed
|
||||||
|
},
|
||||||
|
12: {
|
||||||
|
name: "Impossible!",
|
||||||
|
done() {return false},
|
||||||
|
goalTooltip: "Mwahahaha!", // Shows when achievement is not completed
|
||||||
|
doneTooltip: "HOW????", // Showed when the achievement is completed
|
||||||
|
},
|
||||||
|
13: {
|
||||||
|
name: "EIEIO",
|
||||||
|
done() {return player.f.points.gte(1)},
|
||||||
|
goalTooltip: "Get a farm point.", // Shows when achievement is not completed
|
||||||
|
doneTooltip: "Get a farm point.\n\nReward: The dinosaur is now your friend.", // Showed when the achievement is completed
|
||||||
|
onComplete() {console.log("Bork bork bork!")}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tabFormat: [
|
||||||
|
"main-display", "blank", "blank", "achievements",
|
||||||
|
]
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
17
js/utils.js
17
js/utils.js
|
@ -93,6 +93,7 @@ function getStartPlayer() {
|
||||||
playerdata[layer].spentOnBuyables = new Decimal(0)
|
playerdata[layer].spentOnBuyables = new Decimal(0)
|
||||||
playerdata[layer].upgrades = []
|
playerdata[layer].upgrades = []
|
||||||
playerdata[layer].milestones = []
|
playerdata[layer].milestones = []
|
||||||
|
playerdata[layer].achievements = []
|
||||||
playerdata[layer].challenges = getStartChallenges(layer)
|
playerdata[layer].challenges = getStartChallenges(layer)
|
||||||
if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)) {
|
if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)) {
|
||||||
playerdata.subtabs[layer] = {}
|
playerdata.subtabs[layer] = {}
|
||||||
|
@ -368,6 +369,10 @@ function hasMilestone(layer, id){
|
||||||
return (player[layer].milestones.includes(toNumber(id)) || player[layer].milestones.includes(id.toString()))
|
return (player[layer].milestones.includes(toNumber(id)) || player[layer].milestones.includes(id.toString()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasAchievement(layer, id){
|
||||||
|
return (player[layer].achievements.includes(toNumber(id)) || player[layer].achievements.includes(id.toString()))
|
||||||
|
}
|
||||||
|
|
||||||
function hasChallenge(layer, id){
|
function hasChallenge(layer, id){
|
||||||
return (player[layer].challenges[id])
|
return (player[layer].challenges[id])
|
||||||
}
|
}
|
||||||
|
@ -404,6 +409,9 @@ function buyableEffect(layer, id){
|
||||||
return (tmp[layer].buyables[id].effect)
|
return (tmp[layer].buyables[id].effect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function achievementEffect(layer, id){
|
||||||
|
return (tmp[layer].achievements[id].effect)
|
||||||
|
}
|
||||||
|
|
||||||
function canAffordPurchase(layer, thing, cost) {
|
function canAffordPurchase(layer, thing, cost) {
|
||||||
if (thing.currencyInternalName){
|
if (thing.currencyInternalName){
|
||||||
|
@ -540,6 +548,15 @@ function updateMilestones(layer){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateAchievements(layer){
|
||||||
|
for (id in layers[layer].achievements){
|
||||||
|
if (!isNaN(id) && !(player[layer].achievements.includes(id)) && layers[layer].achievements[id].done()) {
|
||||||
|
player[layer].achievements.push(id)
|
||||||
|
if (layers[layer].achievements[id].onComplete) layers[layer].achievements[id].onComplete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function addTime(diff, layer) {
|
function addTime(diff, layer) {
|
||||||
let data = player
|
let data = player
|
||||||
let time = data.timePlayed
|
let time = data.timePlayed
|
||||||
|
|
30
js/v.js
30
js/v.js
|
@ -291,6 +291,36 @@ function loadVue() {
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
Vue.component('achievements', {
|
||||||
|
props: ['layer'],
|
||||||
|
template: `
|
||||||
|
<div v-if="layers[layer].achievements" class="upgTable">
|
||||||
|
<div v-for="row in layers[layer].achievements.rows" class="upgRow">
|
||||||
|
<div v-for="col in layers[layer].achievements.cols"><div v-if="layers[layer].achievements[row*10+col]!== undefined && tmp[layer].achievements[row*10+col].unlocked" class="upgAlign">
|
||||||
|
<achievement :layer = "layer" :data = "row*10+col" v-bind:style="tmp[layer].componentStyles.achievement"></achievement>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
|
||||||
|
// data = id
|
||||||
|
Vue.component('achievement', {
|
||||||
|
props: ['layer', 'data'],
|
||||||
|
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')
|
||||||
|
"
|
||||||
|
|
||||||
|
v-bind:style="[(!tmp[layer].achievements[data].unlocked) ? {'visibility': 'hidden'} : {}, tmp[layer].achievements[data].style,]">
|
||||||
|
<span v-if= "tmp[layer].achievements[data].name"><br><h3 v-html="tmp[layer].achievements[data].name"></h3><br></span>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
// NOT FOR USE IN STANDARD TAB FORMATTING
|
// NOT FOR USE IN STANDARD TAB FORMATTING
|
||||||
Vue.component('tab-buttons', {
|
Vue.component('tab-buttons', {
|
||||||
|
|
19
style.css
19
style.css
|
@ -200,6 +200,20 @@ h1, h2, h3, b, input {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.achievement {
|
||||||
|
height: 90px;
|
||||||
|
width: 90px;
|
||||||
|
border-radius: 25%;
|
||||||
|
border: 2px solid;
|
||||||
|
border-color: rgba(255, 255, 255, 0.125) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.25) rgba(255, 255, 255, 0.125);
|
||||||
|
font-size: 10px;
|
||||||
|
color: white;
|
||||||
|
text-shadow: 0px 0px 2px #000000;
|
||||||
|
}
|
||||||
|
.achievement:hover {
|
||||||
|
box-shadow: 0px 0px 10px var(--points);
|
||||||
|
}
|
||||||
|
|
||||||
.buyable {
|
.buyable {
|
||||||
height: 200px;
|
height: 200px;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
|
@ -541,6 +555,7 @@ ul {
|
||||||
.treeOverlay {
|
.treeOverlay {
|
||||||
z-index: 200000;
|
z-index: 200000;
|
||||||
pointer-events:none;
|
pointer-events:none;
|
||||||
|
overflow:hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.overlayThing {
|
.overlayThing {
|
||||||
|
@ -551,6 +566,6 @@ ul {
|
||||||
.sideLayers {
|
.sideLayers {
|
||||||
pointer-events:auto;
|
pointer-events:auto;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 35px;
|
right: 55px;
|
||||||
top: 55px;
|
top: 65px;
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue