Implemented card shop

This commit is contained in:
thepaperpilot 2021-01-28 23:04:46 -06:00
parent e246a97376
commit 0fa5e0fd13
11 changed files with 223 additions and 25 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 698 B

After

Width:  |  Height:  |  Size: 711 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -99,7 +99,7 @@ addLayer("flowers", {
player[this.layer].realTime += diff;
}
let jobLevel = new Decimal(getJobLevel(this.layer));
if (jobLevel.neq(player[this.layer].lastLevel)) {
if (jobLevel.neq(player[this.layer].lastLevel) && player[this.layer].lastLevel.lte(100)) {
doPopup("none", `Level ${formatWhole(jobLevel)}`, "Level Up!", 3, layers[this.layer].color);
player[this.layer].lastLevel = jobLevel;
}

View file

@ -1,26 +1,76 @@
function createCard(title, description, onDraw) {
return { title, description, onDraw };
function createCard(title, description = "", onDraw = null, modifyNextCard = null) {
return { title, description, onDraw, modifyNextCard };
}
const nothingCard = () => createCard("His job is not to wield power but to draw attention away from it.", "Do nothing.", () => {});
const gainPointsCard = () => createCard("Don't Panic.", "Successfully study some properties", () => addPoints("study", getResetGain("study")));
const cards = {
nothing: createCard("His job is not to wield power but to draw attention away from it.", "Do nothing."),
gainPoints: createCard("Don't Panic.", "Successfully study some properties.", () => addPoints("study", getResetGain("study"))),
gainBigPoints: createCard("In his experience the Universe simply didn't work like that.", "Successfully study a very large amount of properties. Destroy this card.", (canDestroy = true) => {
addPoints("study", getResetGain("study").pow(1.5));
if (canDestroy) {
const index = player.study.cards.findIndex(el => el[0] === "gainBigPoints");
if (index >= 0) {
player.study.cards.splice(index, 1);
}
}
}),
gainInsight: createCard("And it shall be called... the Earth.", "Gain a key insight.", () => player.study.insights = player.study.insights.add(1)),
gainBigInsight: createCard("Yes! I shall design this computer for you.", "Gain key insights based on the number of cards in the deck.", () => player.study.insights = player.study.insights.add(new Decimal(player.study.cards.length).sqrt().floor())),
playTwice: createCard("Oh no, not again.", "Play the next card twice.", null, nextCard => {
if (nextCard[0] in cards && cards[nextCard[0]].onDraw) {
cards[nextCard[0]].onDraw();
cards[nextCard[0]].onDraw(false);
}
}),
increasePointsGain: createCard("Have another drink, enjoy yourself.", () => `Permanently increase studied properties gain by 10%.<br/><br/>Currently: +${formatWhole(player.study.increasePointsGain.times(10))}%`, () => player.study.increasePointsGain = player.study.increasePointsGain.add(1)),
multiplyPointsGain: createCard("Reality is frequently inaccurate.", () => `Permanently multiply studied properties gain by x1.01<br/><br/>Currently: x${format(new Decimal(1.01).pow(player.study.multiplyPointsGain))}`, () => player.study.multiplyPointsGain = player.study.multiplyPointsGain.add(1)),
sellDiscount: createCard("It doesn't grow on trees you know.", () => `Permanently multiply sell cost by 0.9<br/><br/>Currently: x${format(new Decimal(0.9).pow(player.study.sellDiscount))}`, () => player.study.sellDiscount = player.study.sellDiscount.add(1)),
soldOut: createCard("Out of Stock!")
};
const shopCards = [
{ card: "gainPoints", price: 3 },
{ card: "gainInsight", price: 5 },
{ card: "gainBigPoints", price: 23 },
{ card: "gainBigInsight", price: 42 },
{ card: "playTwice", price: 50 },
{ card: "increasePointsGain", price: 10 },
{ card: "multiplyPointsGain", price: 25 },
{ card: "sellDiscount", price: 80 },
];
const baseCards = () => {
return [ nothingCard(), nothingCard(), nothingCard(), nothingCard(), nothingCard(), nothingCard(), gainPointsCard(), gainPointsCard(), gainPointsCard() ];
return [ ["nothing", 0], ["nothing", 0], ["nothing", 0], ["nothing", 0], ["gainPoints", 0], ["gainPoints", 0], ["gainPoints", 0], ["gainPoints", 0], ["gainInsight", 0], ["gainInsight", 0] ];
};
const cardFormat = (card, id = "", width = "200px", height = "300px") => {
// TODO observe/science symbol
return ["display-text", `<div id="${id}" class="card ${id && "flipCard"}" style="width: ${width}; height: ${height};">
const getShop = (numCards = 3) => {
return new Array(numCards).fill(1).map(() => shopCards[Math.floor(Math.random() * shopCards.length)]);
};
const cardFormat = (card, id = "", className = "", onclick = "", width = "200px", height = "300px") => {
return card == null ? null : ["display-text", `
<div id="${id}" class="card ${className}" style="width: ${width}; height: ${height};" onclick="${onclick}">
<span style="border-bottom: 1px solid white; margin: 0; max-height: calc(50% - 30px); padding-bottom: 10px;">
<h3>${card.title}</h3>
<h3>${cards[card].title}</h3>
</span>
<span style="flex-basis: 0%;"><span>${card.description}</span></span>
<span style="flex-basis: 0%;"><span>${isFunction(cards[card].description) ? cards[card].description() : cards[card].description}</span></span>
<span style="flex-shrink: 1"></span>
<img src="images/Time2wait.svg"/>
</div>`];
</div>`];
};
function purchaseCard(index) {
const { card, price } = player.study.shop[index];
if (card && player.study.insights.gte(price)) {
player.study.insights = player.study.insights.sub(price);
player.study.shop[index] = { card: null, price: "" };
player.study.cards.push([card, 0]);
}
}
const DRAW_PERIOD = 10;
const REFRESH_PERIOD = 300;
addLayer("study", {
name: "study",
resource: "properties studied",
@ -33,15 +83,20 @@ addLayer("study", {
return {
unlocked: true,
points: new Decimal(0),
insights: new Decimal(0),
total: new Decimal(0),
xp: new Decimal(0),
lastLevel: new Decimal(0),
realTime: 0,
timeLoopActive: false,
drawPeriod: 10,
drawProgress: 0,
refreshProgress: 0,
cards: baseCards(),
lastCard: null
lastCard: null,
shop: getShop(),
increasePointsGain: new Decimal(0),
multiplyPointsGain: new Decimal(0),
sellDiscount: new Decimal(0)
};
},
getResetGain() {
@ -50,32 +105,99 @@ addLayer("study", {
}
let gain = new Decimal(10);
gain = gain.times(new Decimal(1.1).pow(getJobLevel(this.layer)));
gain = gain.times(player.study.increasePointsGain.times(0.1).add(1));
gain = gain.times(new Decimal(1.01).pow(player.study.multiplyPointsGain));
return gain;
},
tabFormat: {
"Main": {
content: () => [
"main-display",
["display-text", `Next draw in ${new Decimal(player.study.drawPeriod - player.study.drawProgress).clampMax(9.99).toFixed(2)} seconds`],
["display-text", `<span>You have <h2 style="color: ${studyColor}; text-shadow: ${studyColor} 0 0 10px">${formatWhole(player.study.points)}</h2> properties studied,<br/>and <h2 style="color: darkcyan; text-shadow: darkcyan 0 0 10px">${formatWhole(player.study.insights)}</h2> key insights</span>`],
"blank",
player.study.lastCard == null ? null : cardFormat(player.study.lastCard, "mainCard")
// TODO add milestones to buy new cards (2), remove cards(4), random encounters(6), and upgrade cards(8)
["display-text", (() => {
if (!hasMilestone("study", 0)) {
return "Discover new ways to study at level 2";
}
if (!hasMilestone("study", 1)) {
return "Discover new ways to study at level 4";
}
if (!hasMilestone("study", 3)) {
return "Discover new ways to study at level 6";
}
if (!hasMilestone("study", 4)) {
return "Discover new ways to study at level 8";
}
return "";
})()],
"blank",
["display-text", `Next draw in ${new Decimal(DRAW_PERIOD - player.study.drawProgress).clampMax(DRAW_PERIOD - 0.01).toFixed(2)} seconds`],
"blank",
cardFormat(player.study.lastCard[0], "mainCard", "flipCard"),
"blank",
["milestones-filtered", [2, 5, 6]]
]
},
"Deck": {
content: () => [["row", player.study.cards.map(card => cardFormat(card))]]
content: () => [["row", player.study.cards.map(card => cardFormat(card[0]))]]
},
"Buy Cards": {
content: () => [
["display-text", `<span>You have <h2 style="color: darkcyan; text-shadow: darkcyan 0 0 10px">${formatWhole(player.study.insights)}</h2> key insights</span>`],
"blank",
["display-text", `Cards refresh in ${new Decimal(REFRESH_PERIOD - player.study.refreshProgress).clampMax(REFRESH_PERIOD - 0.01).toFixed(2)} seconds`],
"blank",
["row", player.study.shop.map(({ card, price }, i) =>
["column", [
card == null ? cardFormat("soldOut") : cardFormat(card, "", "shopCard flipCard", `purchaseCard(${i})`),
"blank",
["display-text", `<h2 style="color: darkcyan; text-shadow: darkcyan 0 0 10px">${price ? formatWhole(price) : "" /*zero width space*/}</h2>`]
], { margin: "auto 10px 20px", cursor: "pointer", opacity: card != null && player.study.insights.gte(price) ? 1 : 0.5 }]), { width: "100%" }]
],
unlocked: () => hasMilestone("study", 0)
},
"Sell Cards": {
content: () => [
["display-text", `<span>You have <h2 style="color: ${studyColor}; text-shadow: ${studyColor} 0 0 10px">${formatWhole(player.study.points)}</h2> properties studied`],
"blank",
["clickable", 11],
"blank",
],
unlocked: () => hasMilestone("study", 1)
}
},
update(diff) {
if (player.tab === this.layer || player[this.layer].timeLoopActive) {
player[this.layer].realTime += diff;
player[this.layer].drawProgress += diff;
if (player[this.layer].drawProgress > player[this.layer].drawPeriod) {
if (player[this.layer].drawProgress > DRAW_PERIOD) {
player[this.layer].drawProgress = 0;
const newCard = player[this.layer].cards[Math.floor(Math.random() * player.study.cards.length)];
// TODO proc lastCard
newCard.onDraw();
if (player[this.layer].lastCard[0] in cards && cards[player[this.layer].lastCard[0]].modifyNextCard) {
cards[player[this.layer].lastCard[0]].modifyNextCard(newCard);
} else if (cards[newCard[0]].onDraw) {
cards[newCard[0]].onDraw();
}
player[this.layer].lastCard = newCard;
const card = document.getElementById("mainCard");
if (card != null) {
card.classList.remove("flipCard");
void card.offsetWidth;
card.classList.add("flipCard");
}
}
if (hasMilestone("study", 0)) {
player[this.layer].refreshProgress += diff;
}
if (player[this.layer].refreshProgress > REFRESH_PERIOD) {
player[this.layer].refreshProgress = 0;
player[this.layer].shop = getShop();
for (let card of document.getElementsByClassName("shopCard")) {
if (card != null) {
card.classList.remove("flipCard");
void card.offsetWidth;
card.classList.add("flipCard");
}
}
}
}
let jobLevel = new Decimal(getJobLevel(this.layer));
@ -89,5 +211,72 @@ addLayer("study", {
player[this.layer].xp = player[this.layer].xp.add(xpGain);
},
milestones: {
0: {
requirementDescription: "Level 2",
done: () => player.study.xp.gte(10)
},
1: {
requirementDescription: "Level 4",
done: () => player.study.xp.gte(1e3)
},
2: {
title: "And all dared to brave unknown terrors, to do mighty deeds,",
requirementDescription: "Level 5",
"effectDescription": "Unlock ??? job",
done: () => player.study.xp.gte(1e4)
},
3: {
requirementDescription: "Level 6",
done: () => player.study.xp.gte(1e5)
},
4: {
requirementDescription: "Level 8",
done: () => player.study.xp.gte(1e7)
},
5: {
title: "to boldly split infinitives that no man had split before—",
requirementDescription: "Level 10",
"effectDescription": "Unlock ??? job",
done: () => player.study.xp.gte(1e9),
unlocked: () => hasMilestone("study", 2)
},
6: {
title: "and thus was the Empire forged.",
requirementDescription: "Level 25",
"effectDescription": "Unlock ???",
done: () => player.study.xp.gte(1e24),
unlocked: () => hasMilestone("study", 5)
}
},
clickables: {
rows: 1,
cols: 1,
11: {
title: "They obstinately persisted in their absence.<br/>",
style: {
width: "200px",
height: "200px"
},
display() {
return `Remove a card from your deck. Cost multiplies by 100 for each card sold.<br/><br/>Cost: ${formatWhole(this.cost())} properties studied`;
},
cost(x) {
let cost = new Decimal(1e3).times(new Decimal(100).pow(player[this.layer].cardsSold));
cost = cost.times(new Decimal(0.9).pow(player[this.layer].sellDiscount));
return cost;
},
canClick() {
if (player[this.layer].cards.length <= 1) {
return false;
}
return false;
return player[this.layer].points.gte(this.cost());
},
onClick() {
player[this.layer].points = player[this.layer].points.sub(this.cost());
setBuyableAmount(this.layer, this.id, getBuyableAmount(this.layer, this.id).add(1));
},
unlocked: () => hasMilestone("study", 1)
}
}
});

View file

@ -12,13 +12,16 @@ let modInfo = {
// Set your version in num and name
let VERSION = {
num: "0.1",
num: "0.11",
name: "Chapter 2",
};
let changelog = `<h1>Changelog:</h1><br>
<h3>v0.0</h3><br>
- Chapter 1 Demo`;
<br><h3>v0.1</h3><br>
- Beginning of Chapter 2<br>
- Cards mechanic in Study Flowers job<br>
<br><h3>v0.0</h3><br>
- Chapter 1 Demo<br>`;
let winText = "Congratulations! You have reached the end and beaten this game, but for now...";
@ -79,5 +82,10 @@ function fixOldSave(oldVersion){
if (oldVersion === "0.0") {
player.chapter = 1;
player.flowers.points = player.flowers.points.clampMax(1e9);
player.flowers.points = player.flowers.points.clampMax(player.flowers.xp);
} else if (oldVersion === "0.1") {
player.flowers.xp = player.flowers.xp.clampMax(1e15);
player.flowers.points = player.flowers.points.clampMax(player.flowers.xp);
player.study.cards = baseCards();
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View file

@ -756,6 +756,7 @@ button > * {
.card > span {
flex-basis: 30%;
display: flex;
z-index: 1;
}
.card > img {