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} -
`]; +
`]; }; +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 {