diff --git a/android-chrome-192x192.png b/android-chrome-192x192.png
index f30638e..dd0de30 100644
Binary files a/android-chrome-192x192.png and b/android-chrome-192x192.png differ
diff --git a/android-chrome-512x512.png b/android-chrome-512x512.png
index 471ad70..1e22a44 100644
Binary files a/android-chrome-512x512.png and b/android-chrome-512x512.png differ
diff --git a/apple-touch-icon.png b/apple-touch-icon.png
index 9be13a2..e16532e 100644
Binary files a/apple-touch-icon.png and b/apple-touch-icon.png differ
diff --git a/favicon-16x16.png b/favicon-16x16.png
index c1f5c4d..562afdb 100644
Binary files a/favicon-16x16.png and b/favicon-16x16.png differ
diff --git a/favicon-32x32.png b/favicon-32x32.png
index 5458bbf..039a8eb 100644
Binary files a/favicon-32x32.png and b/favicon-32x32.png differ
diff --git a/favicon.ico b/favicon.ico
index 81292ac..851f357 100644
Binary files a/favicon.ico and b/favicon.ico differ
diff --git a/js/Layers/flowers.js b/js/Layers/flowers.js
index 596bbf2..6a8a261 100644
--- a/js/Layers/flowers.js
+++ b/js/Layers/flowers.js
@@ -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;
}
diff --git a/js/Layers/study.js b/js/Layers/study.js
index 96889d0..7c33452 100644
--- a/js/Layers/study.js
+++ b/js/Layers/study.js
@@ -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%.
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
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
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", `
+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", `
+
- ${card.title}
+ ${cards[card].title}
-
${card.description}
+
${isFunction(cards[card].description) ? cards[card].description() : cards[card].description}
![](images/Time2wait.svg)
-
`];
+
`];
};
+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", `You have ${formatWhole(player.study.points)}
properties studied,
and ${formatWhole(player.study.insights)}
key insights`],
"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", `You have ${formatWhole(player.study.insights)}
key insights`],
+ "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", `${price ? formatWhole(price) : "" /*zero width space*/}
`]
+ ], { 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", `You have ${formatWhole(player.study.points)}
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.
",
+ style: {
+ width: "200px",
+ height: "200px"
+ },
+ display() {
+ return `Remove a card from your deck. Cost multiplies by 100 for each card sold.
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)
+ }
+ }
});
diff --git a/js/mod.js b/js/mod.js
index e455281..c76099b 100644
--- a/js/mod.js
+++ b/js/mod.js
@@ -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 = `Changelog:
- v0.0
- - Chapter 1 Demo`;
+
v0.1
+ - Beginning of Chapter 2
+ - Cards mechanic in Study Flowers job
+
v0.0
+ - Chapter 1 Demo
`;
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();
}
}
\ No newline at end of file
diff --git a/mstile-150x150.png b/mstile-150x150.png
index becdc42..e8525a7 100644
Binary files a/mstile-150x150.png and b/mstile-150x150.png differ
diff --git a/style.css b/style.css
index 55484bb..7a1535a 100644
--- a/style.css
+++ b/style.css
@@ -756,6 +756,7 @@ button > * {
.card > span {
flex-basis: 30%;
display: flex;
+ z-index: 1;
}
.card > img {