1
0
Fork 0
mirror of https://github.com/Acamaeda/The-Modding-Tree.git synced 2024-11-24 17:31:50 +00:00

Achievements

This commit is contained in:
Acamaeda 2020-10-14 21:43:16 -04:00
parent d9d2f777a7
commit 923f096aa0
12 changed files with 173 additions and 14 deletions

View file

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

55
docs/achievements.md Normal file
View 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.

View file

@ -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
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,
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.
- 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.
- bar: Display a bar. The argument is the id of the bar to display.

View file

@ -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.
[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
- baseResource: The name of the resource that determines how much of the main currency you gain on reset.

View file

@ -1,6 +1,6 @@
#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
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.*
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.
The toggles can toggle a given boolean value in a layer.

View file

@ -1,7 +1,5 @@
# Upgrades
Upgrades are stored in the following format:
Useful functions for dealing with Upgrades and implementing their effects:
- 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".
Upgrades are stored in the following format:
```js
upgrades: {

View file

@ -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
let VERSION = {
num: "2.0",
name: "Finally making some progress!",
name: "Pinnacle of Achievement Mountain",
tmtNum: "2.0",
tmtName: "Finally making some progress!"
tmtName: "Pinnacle of Achievement Mountain"
}
// Determines if it should show points/sec
@ -182,6 +182,7 @@ function doReset(layer, force=false) {
addPoints(layer, gain)
updateMilestones(layer)
updateAchievements(layer)
if (!player[layer].unlocked) {
player[layer].unlocked = true;
@ -312,6 +313,7 @@ function gameLoop(diff) {
for (layer in layers){
if (layers[layer].milestones) updateMilestones(layer);
if (layers[layer].achievements) updateAchievements(layer)
}
if (player.hasNaN&&!NaNalert) {

View file

@ -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){
for (thing in layers[layer].challenges){
if (!isNaN(thing)){

View file

@ -576,8 +576,8 @@ addLayer("a", {
}},
color: "yellow",
requires: new Decimal (1),
resource: "idk",
baseResource: "candies",
resource: "achievement power",
baseResource: "achievements",
baseAmount() {return player.points},
type: "normal", // A "Custom" type which is effectively static
exponent: 0.5,
@ -589,9 +589,35 @@ addLayer("a", {
},
row: "side",
layerShown() {return true},
tooltipUnlocked() { // Optional, tooltip displays when the layer is locked
return ("YEETS")
tooltip() { // Optional, tooltip displays when the layer is locked
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",
]
},
)

View file

@ -93,6 +93,7 @@ function getStartPlayer() {
playerdata[layer].spentOnBuyables = new Decimal(0)
playerdata[layer].upgrades = []
playerdata[layer].milestones = []
playerdata[layer].achievements = []
playerdata[layer].challenges = getStartChallenges(layer)
if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)) {
playerdata.subtabs[layer] = {}
@ -368,6 +369,10 @@ function hasMilestone(layer, id){
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){
return (player[layer].challenges[id])
}
@ -404,6 +409,9 @@ function buyableEffect(layer, id){
return (tmp[layer].buyables[id].effect)
}
function achievementEffect(layer, id){
return (tmp[layer].achievements[id].effect)
}
function canAffordPurchase(layer, thing, cost) {
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) {
let data = player
let time = data.timePlayed

30
js/v.js
View file

@ -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
Vue.component('tab-buttons', {

View file

@ -200,6 +200,20 @@ h1, h2, h3, b, input {
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 {
height: 200px;
width: 200px;
@ -541,6 +555,7 @@ ul {
.treeOverlay {
z-index: 200000;
pointer-events:none;
overflow:hidden;
}
.overlayThing {
@ -551,6 +566,6 @@ ul {
.sideLayers {
pointer-events:auto;
position: absolute;
right: 35px;
top: 55px;
right: 55px;
top: 65px;
}