diff --git a/src/components/Game.vue b/src/components/Game.vue index 7ba0d18..5015ef1 100644 --- a/src/components/Game.vue +++ b/src/components/Game.vue @@ -4,7 +4,6 @@ v-for="(tab, index) in tabs" :key="index" class="tab" - :ref="`tab-${index}`" :style="unref(layers[tab]?.style)" :class="unref(layers[tab]?.classes)" > @@ -14,7 +13,6 @@ v-if="layerKeys.includes(tab)" v-bind="gatherLayerProps(layers[tab]!)" :index="index" - :tab="() => (($refs[`tab-${index}`] as HTMLElement[] | undefined)?.[0])" /> @@ -43,6 +41,35 @@ + + + + + @@ -53,6 +80,7 @@ import Scene from "data/Scene.vue"; import type { GenericLayer } from "game/layers"; import { layers } from "game/layers"; import player from "game/player"; +import { convertComputable } from "util/computed"; import { computeOptionalComponent } from "util/vue"; import { computed, toRef, unref } from "vue"; import Layer from "./Layer.vue"; diff --git a/src/data/Day.vue b/src/data/Day.vue index a63ccc3..e47cb60 100644 --- a/src/data/Day.vue +++ b/src/data/Day.vue @@ -6,7 +6,7 @@ masteryLock, wallpaper: day < 8 }" - v-if="opened.value" + v-if="opened.value && visibility !== Visibility.None" >
@@ -26,7 +26,7 @@
import Notif from "components/Notif.vue"; +import { Visibility } from "features/feature"; import Tooltip from "features/tooltips/Tooltip.vue"; import { layers } from "game/layers"; import Decimal from "util/bignum"; @@ -66,6 +67,7 @@ const props = defineProps<{ recentlyUpdated: Ref; shouldNotify: ProcessedComputable; mastered: Ref; + visibility?: Visibility; }>(); const emit = defineEmits<{ diff --git a/src/data/advent.css b/src/data/advent.css index e6eddbd..80129d6 100644 --- a/src/data/advent.css +++ b/src/data/advent.css @@ -29,3 +29,13 @@ justify-content: space-around; margin-bottom: -5%; } + +.present-clickable { + cursor: pointer; + width: 30%; + text-align: center; + transition: all .2s ease-in-out; +} +.present-clickable:hover { + transform: scale(1.2); +} \ No newline at end of file diff --git a/src/data/credits.tsx b/src/data/credits.tsx new file mode 100644 index 0000000..1fbc25e --- /dev/null +++ b/src/data/credits.tsx @@ -0,0 +1,169 @@ +import { jsx } from "features/feature" +import { layers } from "game/layers" +import { render } from "util/vue" +import { unref } from "vue" + +type Credits = { name: string, creator: string, help?: string, other?: string[], symbol?: string, fs?: string } + +import { main } from "./projEntry" + +const dayCredits: Credits[] = [ + { + name: "Trees", + creator: "thepaperpilot", + help: "Jacorb, Escapee", + }, + { + name: "The Workshop", + creator: "thepaperpilot", + help: "Jacorb, emanresu", + }, + { + name: "Coal", + creator: "Escapee", + help: "Jacorb, thepaperpilot", + }, + { + name: "Elf Training", + creator: "thepaperpilot", + help: "incremental_gamer, emanresu", + }, + { + name: "Paper", + creator: "thepaperpilot", + help: "Adsaf" + }, + { + name: "Boxes", + creator: "thepaperpilot", + help: "ducdat0507", + }, + { + name: "Metal", + creator: "Escapee", + help: "ducdat0507, thepaperpilot, yhvr", + }, + { + name: "Cloth", + creator: "thepaperpilot", + help: "emanresu, Jacorb" + }, + { + name: "Oil", + creator: "ducdat0507", + help: "thepaperpilot, Jacorb, incremental_gamer", + }, + { + name: "Plastic", + creator: "thepaperpilot", + help: "Jacorb" + }, + { + name: "Dyes", + creator: "Jacorb", + help: "thepaperpilot, ducdat0507" + }, + { + name: "Management", + creator: "incremental_gamer, downvoid, thepaperpilot, Escapee", + }, + { + name: "Management II", + creator: "incremental_gamer, downvoid, thepaperpilot, Escapee", + }, + { + name: "Letters", + creator: "thepaperpilot", + }, + { + name: "Wrapping Paper", + creator: "emanresu, thepaperpilot, Escapee", + fs: '28px' + }, + { + name: "Ribbons", + creator: "thepaperpilot, Escapee", + }, + { + name: "Toys", + creator: "downvoid", + help: "thepaperpilot" + }, + { + name: "Factory", + creator: "incremental_gamer", + help: "thepaperpilot, ducdat, downvoid, emanresu, yhvr", + other: [ + "Art by emanresu" + ], + }, + { + name: "Factory II", + creator: "downvoid", + help: "thepaperpilot", + other: [ + "Art by emanresu" + ], + }, + { + name: "Presents", + creator: "incremental_gamer", + help: "ducdat0507", + other: [ + "Art by emanresu" + ], + }, + { + name: "Reindeer", + creator: "thepaperpilot" + }, + { + name: "Sleigh Repair", + creator: "downvoid" + }, + { + name: "Routing", + creator: "thepaperpilot" + }, + { + name: "Present Packing", + creator: "Escapee", + fs: '26px' + } +] + +const display = jsx(() => ( +
+

Advent Incremental

+
+

Created by thepaperpilot and friends

+




+ { + dayCredits.map(({name, help, other, creator, fs}, day) => ( + render(jsx(() =>
+ +

Day {day+1} - {name}

+

+ Created by {creator}
+ {help ? <>With help from {help}
: undefined} + {other ? other?.map((other) => <>{other}
) : undefined} +

+
+ +
)) + )) + } +

Credits created by emanresu

+


+

Special Thanks

+

Nekosity

+

Yhvr

+

Ducdat0507

+

Haley

+
+

And last but not least, a massive thanks to everyone who played and provided feedback on the game.

+

Thanks for playing!

+
+)) + +export { display as credits } \ No newline at end of file diff --git a/src/data/layers/credits.tsx b/src/data/layers/credits.tsx new file mode 100644 index 0000000..580dbcd --- /dev/null +++ b/src/data/layers/credits.tsx @@ -0,0 +1,17 @@ +import { jsx } from "features/feature"; +import { createLayer } from "game/layers" + +const id = "credits" +const day = 25; +const name = "Credits" +const credits = createLayer(id, () => { + + return { + display: jsx(() => +
+ TODO: layer +
), + name, + day + } +}) \ No newline at end of file diff --git a/src/data/projEntry.tsx b/src/data/projEntry.tsx index a8830d0..09484a4 100644 --- a/src/data/projEntry.tsx +++ b/src/data/projEntry.tsx @@ -4,7 +4,8 @@ import { Component, GatherProps, GenericComponent, - jsx + jsx, + Visibility } from "features/feature"; import { BaseLayer, createLayer, GenericLayer, layers } from "game/layers"; import { isPersistent, Persistent, persistent } from "game/persistence"; @@ -14,8 +15,8 @@ import { format, formatTime } from "util/bignum"; import { Computable, convertComputable, ProcessedComputable } from "util/computed"; import { createLazyProxy } from "util/proxies"; import { save } from "util/save"; -import { renderRow, VueFeature } from "util/vue"; -import type { Ref } from "vue"; +import { render, renderRow, VueFeature } from "util/vue"; +import { Ref, watch, watchEffect } from "vue"; import { computed, ref, unref } from "vue"; import "./advent.css"; import Day from "./Day.vue"; @@ -61,6 +62,10 @@ import toysSymbol from "./symbols/truck.png"; import advManagementSymbol from "./symbols/workshopMansion.png"; import wrappingPaperSymbol from "./symbols/wrappingPaper.png"; import packing from "./layers/packing"; +import snowflakeSymbol from "./symbols/snowflake.svg"; +import presentSymbol from "./layers/factory-components/present.svg"; +import { createParticles } from "features/particles/particles"; +import { credits } from "./credits"; import sleighSymbol from "./symbols/sleigh.png"; import routingSymbol from "./symbols/gps.png"; @@ -74,10 +79,13 @@ export interface Day extends VueFeature { opened: Persistent; recentlyUpdated: Ref; // Has the tab recieved an update since the player last opened it? shouldNotify: ProcessedComputable; + visibility?: Visibility; } export const main = createLayer("main", function (this: BaseLayer) { const day = persistent(1); + const hasWon = persistent(false); + const timeUntilNewDay = computed( () => (+new Date(new Date().getFullYear(), 11, day.value) - player.time) / 1000 ); @@ -87,6 +95,90 @@ export const main = createLayer("main", function (this: BaseLayer) { const loreTitle = ref(""); const loreBody = ref(); + const creditsOpen = ref(false); + + // I don't understand how this works + const particles = createParticles(() => ({ + boundingRect: ref(null), + onContainerResized(boundingRect) { + this.boundingRect.value = boundingRect; + }, + style: "z-index: -1" + })); + + const emitter = particles.addEmitter({ + emit: false, + autoUpdate: true, + lifetime: { min: 10, max: 10 }, + emitterLifetime: -1, + pos: { x: 0, y: 0 }, + frequency: 0.05, + maxParticles: 1000, + behaviors: [ + { + type: "alphaStatic", + config: { + alpha: 1 + } + }, + { + type: "scaleStatic", + config: { + min: 1, + max: 1 + } + }, + { + type: "moveSpeed", + config: { + speed: { + list: [ + { + value: 200, + time: 0 + }, + { + value: 100, + time: 1 + } + ], + isStepped: false + } + } + }, + { + type: "rotationStatic", + config: { + min: 70, + max: 110 + } + }, + { + type: "spawnShape", + config: { + type: "rect", + data: { + x: 0, + y: 0, + w: 1600, + h: 1 + } + } + }, + { + type: "textureSingle", + config: { + texture: snowflakeSymbol + } + } + ] + }); + + watchEffect(() => { + const shouldEmit = day.value === 25; + emitter.then(e => (e.emit = shouldEmit)); + }); + const currentlyMastering = computed(() => isMastery.value ? Object.values(layers).find( @@ -169,6 +261,7 @@ export const main = createLayer("main", function (this: BaseLayer) { story: string; completedStory: string; masteredStory: string; + visibility?: Visibility; } ): Day { const opened = persistent(false); @@ -198,7 +291,8 @@ export const main = createLayer("main", function (this: BaseLayer) { story, completedStory, masteredStory, - recentlyUpdated + recentlyUpdated, + visibility } = this; const mastered: Ref = @@ -211,6 +305,7 @@ export const main = createLayer("main", function (this: BaseLayer) { recentlyUpdated, shouldNotify, mastered, + visibility, onOpenLore() { const completed = main.day.value > day; loreScene.value = completed ? day - 1 : -1; @@ -231,6 +326,7 @@ export const main = createLayer("main", function (this: BaseLayer) { showLoreModal.value = true; }, onOpenLayer() { + if (day == 25) return; recentlyUpdated.value = false; // 1468 is because two tabs with minWidth of 700px plus the minimized calendar of 60px plus 2 dividers of 4px each if (window.matchMedia("(min-width: 1468px)").matches) { @@ -249,11 +345,14 @@ export const main = createLayer("main", function (this: BaseLayer) { layers[layer ?? "trees"]!.minimized.value = false; }, onUnlockLayer() { - if (layer != null) { + if (layer != null || day == 25) { opened.value = true; setTimeout(() => { loreScene.value = -1; - loreTitle.value = unref(layers[layer ?? "trees"]?.name ?? ""); + loreTitle.value = + day == 25 + ? "The End!" + : unref(layers[layer ?? "trees"]?.name ?? ""); loreBody.value = story; if (player.autoPause) player.devSpeed = null; showLoreModal.value = true; @@ -517,6 +616,25 @@ export const main = createLayer("main", function (this: BaseLayer) { story: "You're almost done! The last step is to load up the sleigh with all the presents and get ready to go! You're going to need to pack a lot of presents, so you'll need to make sure you pack them tightly enough. Good Luck!", completedStory: "At last, you've crammed in all the presents Santa needs. Santa can take it from here. Good Job!", masteredStory: "" + })), + createDay(() => ({ + day: 25, + shouldNotify: false, + layer: null, // credits + symbol: snowflakeSymbol, + story: `It's Christmas. Thanks to your efforts, Santa has delivered all the presents to people all over the world. That is, all but one...


Open your present

`, + completedStory: "", + masteredStory: "" + })), + createDay(() => ({ + day: 25, + shouldNotify: false, + layer: null, // credits + symbol: snowflakeSymbol, + story: `It's Christmas. Thanks to your efforts, Santa has delivered all the presents to people all over the world. That is, all but one...


Open your present

`, + completedStory: "", + masteredStory: "", + visibility: Visibility.None })) ]; @@ -549,6 +667,16 @@ export const main = createLayer("main", function (this: BaseLayer) { } } + watchEffect(() => { + if (day.value === 25 && showLoreModal.value === false && !hasWon.value) { + loreScene.value = -1; + loreTitle.value = "Merry Christmas!"; + loreBody.value = days[day.value - 1].story; + showLoreModal.value = true; + hasWon.value = true; + } + }); + return { name: "Calendar", days, @@ -558,6 +686,7 @@ export const main = createLayer("main", function (this: BaseLayer) { loreScene, loreTitle, loreBody, + particles, showLoreModal, completeDay, completeMastery, @@ -567,6 +696,9 @@ export const main = createLayer("main", function (this: BaseLayer) { swappingMastery, currentlyMastering, masteredDays, + creditsOpen, + credits, + hasWon, display: jsx(() => ( <> {player.devSpeed === 0 ?
Game Paused
: null} @@ -597,6 +729,19 @@ export const main = createLayer("main", function (this: BaseLayer) { ) .map((days: Day[]) => renderRow(...days))}
+ {hasWon.value ? ( + <> + + + + ) : null} + {render(particles)} )) }; diff --git a/src/data/symbols/snowflake.svg b/src/data/symbols/snowflake.svg new file mode 100644 index 0000000..b77deec --- /dev/null +++ b/src/data/symbols/snowflake.svg @@ -0,0 +1,39 @@ + + + + + + + + + +