Added ritual UI/X

This commit is contained in:
thepaperpilot 2021-05-01 00:51:16 -05:00
parent 0d8df5f00b
commit dfe9a8586d
11 changed files with 167 additions and 16 deletions

BIN
images/distillRune.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
images/flowersRune.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
images/generatorsRune.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
images/sandsRune.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
images/studyRune.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View file

@ -326,7 +326,8 @@ addLayer("flowers", {
selectFlowers: {
title: "Collecting",
color: flowersColor,
style: { minHeight: "50px" },
class: { 'candypop-selector': true },
style: { minHeight: "50px", color: "black", backgroundColor: flowersColor },
canClick: () => player.flowers.sacrificeType !== "flowers",
onClick: () => player.flowers.sacrificeType = "flowers",
unlocked: () => tmp.flowers.layerShown
@ -334,7 +335,8 @@ addLayer("flowers", {
selectDistill: {
title: "Distilling",
color: distillColor,
style: { minHeight: "50px" },
class: { 'candypop-selector': true },
style: { minHeight: "50px", color: "black", backgroundColor: distillColor },
canClick: () => player.flowers.sacrificeType !== "distill",
onClick: () => player.flowers.sacrificeType = "distill",
unlocked: () => tmp.distill.layerShown
@ -342,7 +344,8 @@ addLayer("flowers", {
selectStudy: {
title: "Studying",
color: studyColor,
style: { minHeight: "50px" },
class: { 'candypop-selector': true },
style: { minHeight: "50px", color: "black", backgroundColor: studyColor },
canClick: () => player.flowers.sacrificeType !== "study",
onClick: () => player.flowers.sacrificeType = "study",
unlocked: () => tmp.study.layerShown
@ -350,7 +353,8 @@ addLayer("flowers", {
selectSands: {
title: "Experimenting",
color: sandsColor,
style: { minHeight: "50px" },
class: { 'candypop-selector': true },
style: { minHeight: "50px", color: "black", backgroundColor: sandsColor },
canClick: () => player.flowers.sacrificeType !== "sands",
onClick: () => player.flowers.sacrificeType = "sands",
unlocked: () => tmp.sands.layerShown
@ -358,7 +362,8 @@ addLayer("flowers", {
selectGenerators: {
title: "Generating",
color: electricColor,
style: { minHeight: "50px" },
class: { 'candypop-selector': true },
style: { minHeight: "50px", color: "black", backgroundColor: electricColor },
canClick: () => player.flowers.sacrificeType !== "generators",
onClick: () => player.flowers.sacrificeType = "generators",
unlocked: () => tmp.generators.layerShown
@ -366,7 +371,8 @@ addLayer("flowers", {
selectRituals: {
title: "Rituals",
color: ritualsColor,
style: { minHeight: "50px" },
class: { 'candypop-selector': true },
style: { minHeight: "50px", color: "white", backgroundColor: ritualsColor },
canClick: () => player.flowers.sacrificeType !== "rituals",
onClick: () => player.flowers.sacrificeType = "rituals",
unlocked: () => tmp.rituals.layerShown

View file

@ -402,9 +402,12 @@ addLayer("generators", {
// TODO ritual charger,
"perc1": {
title: "1%",
class: { 'generator-selector': true },
style: {
width: "60px",
minHeight: "60px"
minHeight: "60px",
color: "black",
backgroundColor: electricColor
},
canClick: () => player.generators.allocPerc.neq(0.01),
onClick: () => {
@ -413,9 +416,12 @@ addLayer("generators", {
},
"perc10": {
title: "10%",
class: { 'generator-selector': true },
style: {
width: "60px",
minHeight: "60px"
minHeight: "60px",
color: "black",
backgroundColor: electricColor
},
canClick: () => player.generators.allocPerc.neq(0.1),
onClick: () => {
@ -424,9 +430,12 @@ addLayer("generators", {
},
"perc50": {
title: "50%",
class: { 'generator-selector': true },
style: {
width: "60px",
minHeight: "60px"
minHeight: "60px",
color: "black",
backgroundColor: electricColor
},
canClick: () => player.generators.allocPerc.neq(0.5),
onClick: () => {
@ -435,9 +444,12 @@ addLayer("generators", {
},
"perc100": {
title: "100%",
class: { 'generator-selector': true },
style: {
width: "60px",
minHeight: "60px"
minHeight: "60px",
color: "black",
backgroundColor: electricColor
},
canClick: () => player.generators.allocPerc.neq(1),
onClick: () => {

View file

@ -1,12 +1,47 @@
Vue.component("rune", {
props: ["layer", "data"],
template: `<div class="upgAlign">
<button class="upg can rune" style="width: 60px; min-height: 60px;"
v-on:click="setRune(data)"
v-bind:style="{
background: 'url(images/' + player.rituals.board[\`\$\{data[0]\}\$\{data[1]\}\`] + 'Rune.webp) no-repeat center / contain ' + (layers[player.rituals.board[\`\$\{data[0]\}\$\{data[1]\}\`]]?.color || ritualsColor)
}">
</button>
</div>`
})
const rituals = {
xp: {
title: "Ritual of Doctrina",
pattern: [ [ 0, 1 ], [ 1, 0 ] ],
effect: amount => new Decimal(amount),
effectDisplay: () => format(ritualEffect("xp")) + " xp/s",
unlocked: () => true
}
};
function ritualEffect(id) {
let effect = rituals[id].effect(player.rituals.rituals[id] || 0);
if (player.generators.ritualsActive && (player.tab === "generators" || player.generators.timeLoopActive)) {
effect = effect.sqrt();
}
return effect;
}
// Note: id is the corresponding *buyable* ID
function createRuneSelector(id, rune) {
// TODO image based on rune
return {
color: layers[rune]?.color,
color: layers[rune]?.color || ritualsColor,
class: {
rune: true
},
style: {
width: "60px",
minHeight: "60px",
"--count": () => (getBuyableAmount("rituals", id)?.toNumber() || 0) - Object.values(player.rituals.board).filter(r => r === rune).length
background: rune ? 'url(images/' + rune + 'Rune.webp) no-repeat center / contain' : '',
backgroundColor: layers[rune]?.color || ritualsColor,
"--count": rune === null ? "" : () => (getBuyableAmount("rituals", id)?.toNumber() || 0) - Object.values(player.rituals.board).filter(r => r === rune).length
},
canClick: () => player.rituals.selectedRune !== rune,
onClick: () => player.rituals.selectedRune = rune
@ -19,6 +54,7 @@ function createRuneBuyable(id, title) {
display() {
return `Craft another rune<br/><br/>Currently: ${formatWhole(getBuyableAmount("rituals", this.id))}<br/><br/>Cost: ${format(this.cost())} ${layers[id].resource}`;
},
runeType: id,
color: layers[id].color,
style: {
width: '160px',
@ -39,6 +75,75 @@ function createRuneBuyable(id, title) {
};
}
function getRows() {
let rows = 3;
if (hasMilestone("rituals", 1)) {
rows++;
}
if (hasMilestone("rituals", 4)) {
rows++;
}
return rows;
}
function getCols() {
let cols = 3;
if (hasMilestone("rituals", 0)) {
cols++;
}
if (hasMilestone("rituals", 3)) {
cols++;
}
return cols;
}
function setRune([row, col]) {
if (player.rituals.selectedRune == null || (getBuyableAmount("rituals", Object.values(layers.rituals.buyables).find(b => b.runeType === player.rituals.selectedRune).id)?.toNumber() || 0) - Object.values(player.rituals.board).filter(r => r === player.rituals.selectedRune).length > 0) {
player.rituals.board[`${row}${col}`] = player.rituals.selectedRune;
player.rituals.rituals = getRituals();
}
}
function checkRitual(ritual, top, left) {
// Store a lookup table of what runes this pattern is using
const types = {};
for (let r = 0; r < ritual.pattern.length; r++) {
for (let c = 0; c < ritual.pattern[r].length; c++) {
let patternTile = ritual.pattern[r][c];
let tile = player.rituals.board[`${top + r}${left + c}`];
if ((patternTile in types && types[patternTile] !== tile) ||
tile == null) {
return false;
}
types[patternTile] = tile;
}
}
return true;
}
function getRituals() {
const rows = getRows();
const cols = getCols();
const ritualCounts = {};
Object.entries(rituals).forEach(([id, ritual]) => {
let ritualCount = 0;
for (let row = 0; row < rows && row <= rows - ritual.pattern.length; row++) {
for (let col = 0; col < cols && col <= cols - ritual.pattern[0].length; col++) {
// [row, col] is the top left of the ritual
// TODO allow negative numbers to represent "not this type"
if (checkRitual(ritual, row, col)) {
ritualCount++;
}
}
}
if (ritualCount > 0) {
ritualCounts[id] = ritualCount;
}
});
return ritualCounts;
}
addLayer("rituals", {
name: "rituals",
image: "images/bright-72804.jpg",
@ -54,7 +159,8 @@ addLayer("rituals", {
lastLevel: new Decimal(0),
timeLoopActive: false,
board: {},
selectedRune: null
selectedRune: null,
rituals: {}
};
},
tabFormat: () => player.tab !== "rituals" ? [] : [
@ -64,6 +170,10 @@ addLayer("rituals", {
"blank",
["sticky", ["36px", ["clickables"]]],
"blank",
...new Array(getRows()).fill(0).map((_,row) => ["row", new Array(getCols()).fill(0).map((_,col) => ["rune", [row, col]])]),
"blank",
...Object.keys(rituals).filter(id => ritualEffect(id).gt(0)).map(id => ["display-text", `${rituals[id].title} (${player.rituals.rituals[id]}): ${rituals[id].effectDisplay()}`]),
"blank",
["milestones-filtered", [2, 5, 6]]
],
update(diff) {
@ -71,6 +181,9 @@ addLayer("rituals", {
if (player.generators.ritualsActive && (player.tab === "generators" || player.generators.timeLoopActive)) {
diff = diff / 10;
}
let xpGain = ritualEffect("xp");
player[this.layer].xp = player[this.layer].xp.add(xpGain);
checkJobXP(this.layer);
}
},
milestones: {
@ -99,7 +212,7 @@ addLayer("rituals", {
5: {
title: "You must not be seen.",
requirementDescription: "Level 10",
"effectDescription": "Unlock the Ritual of Ascent",
"effectDescription": "Unlock the Ritual of Ascensio",
done: () => player.rituals.xp.gte(1e9),
unlocked: () => hasMilestone("rituals", 2)
},
@ -112,6 +225,8 @@ addLayer("rituals", {
}
},
clickables: {
rows: 1,
cols: 7,
11: {
title: "Clear All",
style: {

View file

@ -349,7 +349,7 @@ function loadVue() {
</div>
`
})
// data = button size, in px
Vue.component("clickables", {
props: ["layer", "data"],
@ -381,7 +381,7 @@ function loadVue() {
<button
v-if="tmp[layer].clickables && tmp[layer].clickables[data]!== undefined && tmp[layer].clickables[data].unlocked !== false"
v-bind:class="{ upg: true, can: tmp[layer].clickables[data].canClick !== false, locked: tmp[layer].clickables[data].canClick === false, ...tmp[layer].clickables[data].class}"
v-bind:style="[tmp[layer].clickables[data].canClick !== false ? {'background-color': tmp[layer].clickables[data].color || tmp[layer].color} : {}, size ? {'height': size, 'width': size} : {}, tmp[layer].clickables[data].style]"
v-bind:style="[tmp[layer].clickables[data].canClick !== false ? {'background-color': tmp[layer].clickables[data].color || tmp[layer].color} : { 'background-color': tmp[layer].clickables[data].style?.backgroundColor }, size ? {'height': size, 'width': size} : {}, tmp[layer].clickables[data].style]"
v-on="handlers">
<span v-if="tmp[layer].clickables[data].title">
<!--suppress HtmlUnknownTag -->

View file

@ -136,6 +136,7 @@ function fixSave() {
fixData(defaultData, player);
setBuyableAmount("distill", "retort", (getBuyableAmount("distill", "retort") || new Decimal(0)).max(5));
player.sands.chipping = false;
player.rituals.rituals = getRituals();
for (let layer in layers) {
if (player[layer].best !== undefined) {

View file

@ -1135,3 +1135,20 @@ b, h3 {
font-size: large;
transform: translate(-50%, -50%);
}
.upg.locked.candypop-selector {
box-shadow: #f1ebd9 0 0 8px 4px;
transition-property: transform;
}
.upg.locked.generator-selector {
box-shadow: #89C6FF 0 0 8px 4px;
transition-property: transform;
}
.upg.locked.rune {
box-shadow: #1e1e1e 0 0 8px 12px;
transition-property: transform;
}
.rune {
transition-property: transform, box-shadow;
}