mirror of
https://github.com/thepaperpilot/Advent-Incremental.git
synced 2024-11-21 08:12:41 +00:00
Merge branch 'day-24-packing'
This commit is contained in:
commit
7b115697a0
33 changed files with 1405 additions and 65 deletions
File diff suppressed because one or more lines are too long
1
saves/Day 22 Complete.txt
Normal file
1
saves/Day 22 Complete.txt
Normal file
File diff suppressed because one or more lines are too long
1
saves/Day 23 Complete.txt
Normal file
1
saves/Day 23 Complete.txt
Normal file
File diff suppressed because one or more lines are too long
|
@ -42,6 +42,35 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
<Modal
|
||||||
|
:modelValue="main.creditsOpen.value"
|
||||||
|
@update:model-value="value => (main.creditsOpen.value = value)"
|
||||||
|
>
|
||||||
|
<template v-slot:header>
|
||||||
|
<h2>Credits</h2>
|
||||||
|
</template>
|
||||||
|
<template v-slot:body>
|
||||||
|
<div>
|
||||||
|
<component :is=convertComputable(main.credits) />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!--<div v-if="main.loreScene.value !== -1">
|
||||||
|
<Scene :day="main.loreScene.value" />
|
||||||
|
<br />
|
||||||
|
You can help continue the <i>advent</i>ure at:
|
||||||
|
<a
|
||||||
|
href="https://discord.gg/WzejVAx"
|
||||||
|
class="info-modal-discord-link"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<span class="material-icons info-modal-discord">discord</span>
|
||||||
|
The Paper Pilot Community
|
||||||
|
</a>
|
||||||
|
</div>-->
|
||||||
|
</template>
|
||||||
|
</Modal>
|
||||||
|
<!--<component :is="main.particles" />-->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -52,6 +81,7 @@ import Scene from "data/Scene.vue";
|
||||||
import type { GenericLayer } from "game/layers";
|
import type { GenericLayer } from "game/layers";
|
||||||
import { layers } from "game/layers";
|
import { layers } from "game/layers";
|
||||||
import player from "game/player";
|
import player from "game/player";
|
||||||
|
import { convertComputable } from "util/computed";
|
||||||
import { computeOptionalComponent } from "util/vue";
|
import { computeOptionalComponent } from "util/vue";
|
||||||
import { computed, toRef, unref } from "vue";
|
import { computed, toRef, unref } from "vue";
|
||||||
import Layer from "./Layer.vue";
|
import Layer from "./Layer.vue";
|
||||||
|
|
|
@ -26,11 +26,10 @@
|
||||||
import projInfo from "data/projInfo.json";
|
import projInfo from "data/projInfo.json";
|
||||||
import type { CoercableComponent } from "features/feature";
|
import type { CoercableComponent } from "features/feature";
|
||||||
import type { FeatureNode } from "game/layers";
|
import type { FeatureNode } from "game/layers";
|
||||||
import type { Persistent } from "game/persistence";
|
|
||||||
import player from "game/player";
|
import player from "game/player";
|
||||||
import { computeComponent, computeOptionalComponent, processedPropType, wrapRef } from "util/vue";
|
import { computeComponent, computeOptionalComponent, processedPropType, unwrapRef } from "util/vue";
|
||||||
import type { PropType, Ref } from "vue";
|
import type { PropType, Ref } from "vue";
|
||||||
import { computed, defineComponent, nextTick, toRefs, unref, watch } from "vue";
|
import { computed, defineComponent, toRefs, unref } from "vue";
|
||||||
import Context from "./Context.vue";
|
import Context from "./Context.vue";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
@ -67,7 +66,7 @@ export default defineComponent({
|
||||||
const component = computeComponent(display);
|
const component = computeComponent(display);
|
||||||
const minimizedComponent = computeOptionalComponent(minimizedDisplay);
|
const minimizedComponent = computeOptionalComponent(minimizedDisplay);
|
||||||
const showGoBack = computed(
|
const showGoBack = computed(
|
||||||
() => projInfo.allowGoBack && index.value > 0 && !minimized.value
|
() => projInfo.allowGoBack && index.value > 0 && !unwrapRef(minimized)
|
||||||
);
|
);
|
||||||
|
|
||||||
function goBack() {
|
function goBack() {
|
||||||
|
|
|
@ -98,7 +98,7 @@ const isPaused = computed({
|
||||||
});
|
});
|
||||||
|
|
||||||
const canAutoSave = computed(
|
const canAutoSave = computed(
|
||||||
() => (layers as any).main?.days[(layers as any).main?.day.value - 1].opened.value
|
() => (layers as any).main?.day.value >= 25 || (layers as any).main?.days[(layers as any).main?.day.value - 1].opened.value
|
||||||
);
|
);
|
||||||
|
|
||||||
const autosaveTitle = jsx(() => (
|
const autosaveTitle = jsx(() => (
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
masteryLock,
|
masteryLock,
|
||||||
wallpaper: day < 8
|
wallpaper: day < 8
|
||||||
}"
|
}"
|
||||||
v-if="opened.value"
|
v-if="opened.value && visibility !== Visibility.None"
|
||||||
>
|
>
|
||||||
<div class="ribbon" v-if="day >= 8" />
|
<div class="ribbon" v-if="day >= 8" />
|
||||||
<Tooltip :display="layers[layer ?? '']?.name ?? ''" :direction="Direction.Up" yoffset="5px">
|
<Tooltip :display="layers[layer ?? '']?.name ?? ''" :direction="Direction.Up" yoffset="5px">
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else-if="visibility !== Visibility.None"
|
||||||
class="day feature dontMerge"
|
class="day feature dontMerge"
|
||||||
:class="{ can: canOpen, locked: !canOpen, canOpen, mastered: unref(mastered) }"
|
:class="{ can: canOpen, locked: !canOpen, canOpen, mastered: unref(mastered) }"
|
||||||
@click="tryUnlock"
|
@click="tryUnlock"
|
||||||
|
@ -47,6 +47,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Notif from "components/Notif.vue";
|
import Notif from "components/Notif.vue";
|
||||||
|
import { Visibility } from "features/feature";
|
||||||
import Tooltip from "features/tooltips/Tooltip.vue";
|
import Tooltip from "features/tooltips/Tooltip.vue";
|
||||||
import { layers } from "game/layers";
|
import { layers } from "game/layers";
|
||||||
import Decimal from "util/bignum";
|
import Decimal from "util/bignum";
|
||||||
|
@ -66,6 +67,7 @@ const props = defineProps<{
|
||||||
recentlyUpdated: Ref<boolean>;
|
recentlyUpdated: Ref<boolean>;
|
||||||
shouldNotify: ProcessedComputable<boolean>;
|
shouldNotify: ProcessedComputable<boolean>;
|
||||||
mastered: Ref<boolean>;
|
mastered: Ref<boolean>;
|
||||||
|
visibility?: Visibility;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-if="day >= 21"
|
v-if="day >= 21"
|
||||||
:src="sleigh"
|
:src="day >= 23 ? packing : sleigh"
|
||||||
class="scene-item"
|
class="scene-item"
|
||||||
style="left: 10%; bottom: 56%; transform: rotate(24deg); width: 100px; height: 100px"
|
style="left: 10%; bottom: 56%; transform: rotate(24deg); width: 100px; height: 100px"
|
||||||
/>
|
/>
|
||||||
|
@ -116,6 +116,7 @@ import presents from "./symbols/presents.png";
|
||||||
import reindeer from "./symbols/reindeer.png";
|
import reindeer from "./symbols/reindeer.png";
|
||||||
import sleigh from "./symbols/sleigh.png";
|
import sleigh from "./symbols/sleigh.png";
|
||||||
import routing from "./symbols/gps.png";
|
import routing from "./symbols/gps.png";
|
||||||
|
import packing from "./symbols/sleighWSack.png";
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
day: number;
|
day: number;
|
||||||
|
|
|
@ -29,3 +29,13 @@
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
margin-bottom: -5%;
|
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);
|
||||||
|
}
|
207
src/data/credits.tsx
Normal file
207
src/data/credits.tsx
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
import Spacer from "components/layout/Spacer.vue";
|
||||||
|
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",
|
||||||
|
help: "ducdat0507"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Routing",
|
||||||
|
creator: "thepaperpilot, ducdat0507"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Present Packing",
|
||||||
|
creator: "Escapee, emanresu",
|
||||||
|
help: "thepaperpilot",
|
||||||
|
fs: "26px"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const display = jsx(() => (
|
||||||
|
<div style="text-align: center; line-spacing: 5px; width: 700px">
|
||||||
|
<h1>Advent Incremental</h1>
|
||||||
|
<br />
|
||||||
|
<h2>Created by thepaperpilot and friends</h2>
|
||||||
|
<Spacer />
|
||||||
|
{dayCredits.map(({ name, help, other, creator, fs }, day) =>
|
||||||
|
render(
|
||||||
|
jsx(() => (
|
||||||
|
<div style="position: relative">
|
||||||
|
<span style="width: calc(100% - 260px); display: inline-block;">
|
||||||
|
<h1
|
||||||
|
style={{
|
||||||
|
color: unref(
|
||||||
|
layers[main.days[day].layer ?? ""]?.color ?? "white"
|
||||||
|
),
|
||||||
|
fontSize: fs ?? "30px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Day {day + 1} - {name}
|
||||||
|
</h1>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
Created by {creator} <br />
|
||||||
|
{help != null ? (
|
||||||
|
<>
|
||||||
|
With help from {help}
|
||||||
|
<br />
|
||||||
|
</>
|
||||||
|
) : undefined}
|
||||||
|
{other
|
||||||
|
? other?.map(other => (
|
||||||
|
<>
|
||||||
|
{other}
|
||||||
|
<br />
|
||||||
|
</>
|
||||||
|
))
|
||||||
|
: undefined}
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
</span>
|
||||||
|
<img
|
||||||
|
style={`position: absolute; top: 5px; ${
|
||||||
|
day % 2 ? "left" : "right"
|
||||||
|
}: 20px; width: 100px;`}
|
||||||
|
src={main.days[day].symbol}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
<h1>Special Thanks</h1>
|
||||||
|
<p>Nekosity</p>
|
||||||
|
<p>Yhvr</p>
|
||||||
|
<p>Ducdat0507</p>
|
||||||
|
<p>Haley</p>
|
||||||
|
<p>emanresu</p>
|
||||||
|
<br />
|
||||||
|
<p style="width: 600px">
|
||||||
|
And last but not least, a massive thanks to everyone who played and provided feedback on
|
||||||
|
the game.
|
||||||
|
</p>
|
||||||
|
<Spacer />
|
||||||
|
<h1 style="font-family: 'Great Vibes', cursive">Thanks for playing!</h1>
|
||||||
|
<Spacer />
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
|
||||||
|
export { display as credits };
|
|
@ -36,6 +36,7 @@ import reindeer from "./reindeer";
|
||||||
import trees from "./trees";
|
import trees from "./trees";
|
||||||
import workshop from "./workshop";
|
import workshop from "./workshop";
|
||||||
import wrappingPaper from "./wrapping-paper";
|
import wrappingPaper from "./wrapping-paper";
|
||||||
|
import packing from "./packing";
|
||||||
|
|
||||||
export type BoxesBuyable = ElfBuyable & {
|
export type BoxesBuyable = ElfBuyable & {
|
||||||
resource: Resource;
|
resource: Resource;
|
||||||
|
@ -58,11 +59,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
enabled: workshop.milestones.extraExpansionMilestone5.earned
|
enabled: workshop.milestones.extraExpansionMilestone5.earned
|
||||||
})),
|
})),
|
||||||
reindeer.reindeer.vixen.modifier,
|
reindeer.reindeer.vixen.modifier,
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: 1.1,
|
||||||
|
description: "120 Presents Packed",
|
||||||
|
enabled: packing.packingMilestones.boxBoost.earned
|
||||||
|
})),
|
||||||
createExponentialModifier(() => ({
|
createExponentialModifier(() => ({
|
||||||
exponent: 1.1,
|
exponent: 1.1,
|
||||||
description: "Bell Level 2",
|
description: "Bell Level 2",
|
||||||
enabled: management.elfTraining.boxElfTraining.milestones[1].earned
|
enabled: management.elfTraining.boxElfTraining.milestones[1].earned
|
||||||
}))
|
})),
|
||||||
|
|
||||||
]) as WithRequired<Modifier, "description" | "revert">;
|
]) as WithRequired<Modifier, "description" | "revert">;
|
||||||
|
|
||||||
const boxesConversion = createCumulativeConversion(() => ({
|
const boxesConversion = createCumulativeConversion(() => ({
|
||||||
|
|
|
@ -42,6 +42,7 @@ import reindeer from "./reindeer";
|
||||||
import routing from "./routing";
|
import routing from "./routing";
|
||||||
import trees from "./trees";
|
import trees from "./trees";
|
||||||
import workshop from "./workshop";
|
import workshop from "./workshop";
|
||||||
|
import packing from "./packing"
|
||||||
|
|
||||||
const id = "cloth";
|
const id = "cloth";
|
||||||
const day = 8;
|
const day = 8;
|
||||||
|
@ -500,6 +501,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
description: "Yellow Dye",
|
description: "Yellow Dye",
|
||||||
enabled: dyes.masteryEffectActive
|
enabled: dyes.masteryEffectActive
|
||||||
})),
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: 10,
|
||||||
|
description: "600 Presents Packed",
|
||||||
|
enabled: packing.packingMilestones.clothBoost.earned
|
||||||
|
})),
|
||||||
reindeer.reindeer.cupid.modifier
|
reindeer.reindeer.cupid.modifier
|
||||||
]) as WithRequired<Modifier, "description" | "revert">;
|
]) as WithRequired<Modifier, "description" | "revert">;
|
||||||
const computedShearingAmount = computed(() => shearingAmount.apply(1));
|
const computedShearingAmount = computed(() => shearingAmount.apply(1));
|
||||||
|
|
|
@ -44,6 +44,7 @@ import plastic from "./plastic";
|
||||||
import reindeer from "./reindeer";
|
import reindeer from "./reindeer";
|
||||||
import trees from "./trees";
|
import trees from "./trees";
|
||||||
import wrappingPaper from "./wrapping-paper";
|
import wrappingPaper from "./wrapping-paper";
|
||||||
|
import packing from "./packing";
|
||||||
|
|
||||||
interface BetterFertilizerUpgOptions {
|
interface BetterFertilizerUpgOptions {
|
||||||
canAfford: () => boolean;
|
canAfford: () => boolean;
|
||||||
|
@ -237,10 +238,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
|
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
|
||||||
if (Decimal.gte(v, 10000)) v = Decimal.pow(v, 2).div(10000);
|
if (Decimal.gte(v, 10000)) v = Decimal.pow(v, 2).div(10000);
|
||||||
v = Decimal.pow(0.95, paper.books.kilnBook.totalAmount.value).times(v);
|
v = Decimal.pow(0.95, paper.books.kilnBook.totalAmount.value).times(v);
|
||||||
return Decimal.pow(1.1, v).times(1e7);
|
return Decimal.pow(packing.packingMilestones.coalBoost.earned.value ? 1.05 : 1.1, v).times(1e7);
|
||||||
},
|
},
|
||||||
inverseCost(x: DecimalSource) {
|
inverseCost(x: DecimalSource) {
|
||||||
let v = Decimal.div(x, 1e7).log(1.1);
|
let v = Decimal.div(x, 1e7).log(packing.packingMilestones.coalBoost.earned.value ? 1.05 : 1.1);
|
||||||
v = v.div(Decimal.pow(0.95, paper.books.kilnBook.totalAmount.value));
|
v = v.div(Decimal.pow(0.95, paper.books.kilnBook.totalAmount.value));
|
||||||
if (Decimal.gte(v, 10000)) v = Decimal.mul(v, 10000).root(2);
|
if (Decimal.gte(v, 10000)) v = Decimal.mul(v, 10000).root(2);
|
||||||
if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(2);
|
if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(2);
|
||||||
|
@ -299,7 +300,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
|
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
|
||||||
if (Decimal.gte(v, 10000)) v = Decimal.pow(v, 2).div(10000);
|
if (Decimal.gte(v, 10000)) v = Decimal.pow(v, 2).div(10000);
|
||||||
v = Decimal.pow(0.95, paper.books.coalDrillBook.totalAmount.value).times(v);
|
v = Decimal.pow(0.95, paper.books.coalDrillBook.totalAmount.value).times(v);
|
||||||
let cost = Decimal.pow(1.15, v).times(10);
|
let cost = Decimal.pow(packing.packingMilestones.coalBoost.earned.value ? 1.075 : 1.15, v).times(10);
|
||||||
if (management.elfTraining.fertilizerElfTraining.milestones[2].earned.value) {
|
if (management.elfTraining.fertilizerElfTraining.milestones[2].earned.value) {
|
||||||
cost = cost.div(Decimal.add(trees.totalLogs.value, Math.E).ln());
|
cost = cost.div(Decimal.add(trees.totalLogs.value, Math.E).ln());
|
||||||
}
|
}
|
||||||
|
@ -315,7 +316,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
if (management.elfTraining.fertilizerElfTraining.milestones[2].earned.value) {
|
if (management.elfTraining.fertilizerElfTraining.milestones[2].earned.value) {
|
||||||
x = Decimal.mul(x, Decimal.add(trees.totalLogs.value, Math.E).ln());
|
x = Decimal.mul(x, Decimal.add(trees.totalLogs.value, Math.E).ln());
|
||||||
}
|
}
|
||||||
let v = Decimal.div(x, 10).log(1.15);
|
let v = Decimal.div(x, 10).log(packing.packingMilestones.coalBoost.earned.value ? 1.075 : 1.15);
|
||||||
v = v.div(Decimal.pow(0.95, paper.books.coalDrillBook.totalAmount.value));
|
v = v.div(Decimal.pow(0.95, paper.books.coalDrillBook.totalAmount.value));
|
||||||
if (Decimal.gte(v, 10000)) v = Decimal.mul(v, 10000).root(2);
|
if (Decimal.gte(v, 10000)) v = Decimal.mul(v, 10000).root(2);
|
||||||
if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(2);
|
if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(2);
|
||||||
|
|
17
src/data/layers/credits.tsx
Normal file
17
src/data/layers/credits.tsx
Normal file
|
@ -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(() =>
|
||||||
|
<div>
|
||||||
|
TODO: layer
|
||||||
|
</div>),
|
||||||
|
name,
|
||||||
|
day
|
||||||
|
}
|
||||||
|
})
|
|
@ -39,6 +39,7 @@ import toys from "./toys";
|
||||||
import factory from "./factory";
|
import factory from "./factory";
|
||||||
import reindeer from "./reindeer";
|
import reindeer from "./reindeer";
|
||||||
import routing from "./routing";
|
import routing from "./routing";
|
||||||
|
import packing from "./packing";
|
||||||
|
|
||||||
interface Dye {
|
interface Dye {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -171,20 +172,21 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
multiplier: 2,
|
multiplier: 2,
|
||||||
description: "Wetter Dyes",
|
description: "Wetter Dyes",
|
||||||
enabled: upgrades.yellowDyeUpg.bought
|
enabled: upgrades.yellowDyeUpg.bought
|
||||||
}))
|
})),
|
||||||
);
|
|
||||||
modifiers.push(
|
|
||||||
createMultiplicativeModifier(() => ({
|
createMultiplicativeModifier(() => ({
|
||||||
multiplier: () => Decimal.add(cloth.cloth.value, Math.E).ln(),
|
multiplier: () => Decimal.add(cloth.cloth.value, Math.E).ln(),
|
||||||
description: "Gingersnap Level 1",
|
description: "Gingersnap Level 1",
|
||||||
enabled: management.elfTraining.clothElfTraining.milestones[0].earned
|
enabled: management.elfTraining.clothElfTraining.milestones[0].earned
|
||||||
}))
|
})),
|
||||||
);
|
|
||||||
modifiers.push(
|
|
||||||
createMultiplicativeModifier(() => ({
|
createMultiplicativeModifier(() => ({
|
||||||
multiplier: 2,
|
multiplier: 2,
|
||||||
description: "Carol Level 1",
|
description: "Carol Level 1",
|
||||||
enabled: management.elfTraining.dyeElfTraining.milestones[0].earned
|
enabled: management.elfTraining.dyeElfTraining.milestones[0].earned
|
||||||
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: 5,
|
||||||
|
description: "977,000,000 Presents Packed",
|
||||||
|
enabled: packing.packingMilestones.primaryDyeBoost.earned
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -728,6 +730,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
Decimal.add(dyes.orange.amount.value, 1)
|
Decimal.add(dyes.orange.amount.value, 1)
|
||||||
.log2()
|
.log2()
|
||||||
.plus(1)
|
.plus(1)
|
||||||
|
.mul(packing.packingMilestones.secondaryDyeBoost.earned.value ? 2 : 1)
|
||||||
.pow(oil.row3Upgrades[1].bought.value ? 2.5 : 1)
|
.pow(oil.row3Upgrades[1].bought.value ? 2.5 : 1)
|
||||||
),
|
),
|
||||||
green1: computed(() =>
|
green1: computed(() =>
|
||||||
|
@ -739,6 +742,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
Decimal.add(dyes.green.amount.value, 1)
|
Decimal.add(dyes.green.amount.value, 1)
|
||||||
.log2()
|
.log2()
|
||||||
.plus(1)
|
.plus(1)
|
||||||
|
.mul(packing.packingMilestones.secondaryDyeBoost.earned.value ? 2 : 1)
|
||||||
.pow(upgrades.coalUpg.bought.value ? 2 : 1)
|
.pow(upgrades.coalUpg.bought.value ? 2 : 1)
|
||||||
),
|
),
|
||||||
purple1: computed(() =>
|
purple1: computed(() =>
|
||||||
|
@ -746,7 +750,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
.pow(upgrades.coalUpg.bought.value ? 1.2 : 1)
|
.pow(upgrades.coalUpg.bought.value ? 1.2 : 1)
|
||||||
.pow(management.elfTraining.clothElfTraining.milestones[3].earned.value ? 1.1 : 1)
|
.pow(management.elfTraining.clothElfTraining.milestones[3].earned.value ? 1.1 : 1)
|
||||||
),
|
),
|
||||||
purple2: computed(() => Decimal.add(dyes.purple.amount.value, 1).log2().plus(1)),
|
purple2: computed(() =>
|
||||||
|
Decimal.add(dyes.purple.amount.value, 1)
|
||||||
|
.log2()
|
||||||
|
.plus(1)
|
||||||
|
.mul(packing.packingMilestones.secondaryDyeBoost.earned.value ? 2 : 1)
|
||||||
|
),
|
||||||
black1: computed(() =>
|
black1: computed(() =>
|
||||||
Decimal.pow(2, Decimal.add(dyes.black.amount.value, 1).log2().sqrt())
|
Decimal.pow(2, Decimal.add(dyes.black.amount.value, 1).log2().sqrt())
|
||||||
.pow(upgrades.coalUpg.bought.value ? 1.2 : 1)
|
.pow(upgrades.coalUpg.bought.value ? 1.2 : 1)
|
||||||
|
|
|
@ -39,6 +39,7 @@ import wrappingPaper from "./wrapping-paper";
|
||||||
import dyes, { enumColor } from "./dyes";
|
import dyes, { enumColor } from "./dyes";
|
||||||
import ribbon from "./ribbon";
|
import ribbon from "./ribbon";
|
||||||
import letters from "./letters";
|
import letters from "./letters";
|
||||||
|
import packing from "./packing";
|
||||||
|
|
||||||
export interface ElfBuyable extends GenericBuyable {
|
export interface ElfBuyable extends GenericBuyable {
|
||||||
/** The inverse function of the cost formula, used to calculate the maximum amount that can be bought by elves. */
|
/** The inverse function of the cost formula, used to calculate the maximum amount that can be bought by elves. */
|
||||||
|
@ -455,6 +456,23 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
enabled: elvesMilestone2.earned
|
enabled: elvesMilestone2.earned
|
||||||
}))
|
}))
|
||||||
]);
|
]);
|
||||||
|
const packingCooldown = createSequentialModifier(() => [
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: 2,
|
||||||
|
description: "6 Elves Trained",
|
||||||
|
enabled: elvesMilestone.earned
|
||||||
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: () => Decimal.times(paper.books.packingBook.totalAmount.value, 0.1).add(1),
|
||||||
|
description: "The Tetris Effect",
|
||||||
|
enabled: () => Decimal.gt(paper.books.packingBook.totalAmount.value, 0)
|
||||||
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: 2,
|
||||||
|
description: "10 Elves Trained",
|
||||||
|
enabled: elvesMilestone2.earned
|
||||||
|
}))
|
||||||
|
]);
|
||||||
|
|
||||||
const [generalTab, generalTabCollapsed] = createCollapsibleModifierSections(() => [
|
const [generalTab, generalTabCollapsed] = createCollapsibleModifierSections(() => [
|
||||||
{
|
{
|
||||||
|
@ -590,6 +608,13 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
base: 10,
|
base: 10,
|
||||||
unit: "/s",
|
unit: "/s",
|
||||||
visible: plastic.masteryEffectActive
|
visible: plastic.masteryEffectActive
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Jingle Auto-Buy Frequency",
|
||||||
|
modifier: packingCooldown,
|
||||||
|
base: 10,
|
||||||
|
unit: "/s",
|
||||||
|
visible: packing.upgrades.packingElf.bought
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
const showModifiersModal = ref(false);
|
const showModifiersModal = ref(false);
|
||||||
|
@ -732,7 +757,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
onPurchase() {
|
onPurchase() {
|
||||||
options.onPurchase?.();
|
options.onPurchase?.();
|
||||||
if (
|
if (
|
||||||
!["Peppermint", "Twinkle", "Cocoa", "Frosty", "Carol"].includes(
|
!["Peppermint", "Twinkle", "Cocoa", "Frosty", "Carol", "Jingle"].includes(
|
||||||
options.name
|
options.name
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
@ -1013,6 +1038,20 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
buyMax: () => management.elfTraining.plasticElfTraining.milestones[4].earned.value
|
buyMax: () => management.elfTraining.plasticElfTraining.milestones[4].earned.value
|
||||||
});
|
});
|
||||||
const wrappingPaperElves = [dyeElf, plasticElf];
|
const wrappingPaperElves = [dyeElf, plasticElf];
|
||||||
|
|
||||||
|
const packingElf = createElf({
|
||||||
|
name: "Jingle",
|
||||||
|
description: "Jingle will automatically hire more elves to help out with packing the sleigh.",
|
||||||
|
buyable: [packing.helpers.elf, packing.helpers.loader],
|
||||||
|
cooldownModifier: packingCooldown,
|
||||||
|
visibility: () => showIf(packing.upgrades.packingElf.bought.value),
|
||||||
|
buyMax: true,
|
||||||
|
onAutoPurchase(buyable, amount) {
|
||||||
|
if (buyable === packing.helpers.loader && !management.elfTraining.packingElfTraining.milestones[3].earned.value) {
|
||||||
|
buyable.amount.value = Decimal.sub(buyable.amount.value, amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
const elves = {
|
const elves = {
|
||||||
cuttersElf,
|
cuttersElf,
|
||||||
plantersElf,
|
plantersElf,
|
||||||
|
@ -1031,7 +1070,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
oilElf,
|
oilElf,
|
||||||
metalElf,
|
metalElf,
|
||||||
dyeElf,
|
dyeElf,
|
||||||
plasticElf
|
plasticElf,
|
||||||
|
packingElf
|
||||||
};
|
};
|
||||||
const totalElves = computed(() => Object.values(elves).filter(elf => elf.bought.value).length);
|
const totalElves = computed(() => Object.values(elves).filter(elf => elf.bought.value).length);
|
||||||
|
|
||||||
|
@ -1278,6 +1318,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
buyProgress: persistent<DecimalSource>(0),
|
buyProgress: persistent<DecimalSource>(0),
|
||||||
amountOfTimesDone: persistent<number>(0),
|
amountOfTimesDone: persistent<number>(0),
|
||||||
bought: persistent<boolean>(false)
|
bought: persistent<boolean>(false)
|
||||||
|
},
|
||||||
|
packingElf: {
|
||||||
|
buyProgress: persistent<DecimalSource>(0),
|
||||||
|
amountOftimesDone: persistent<number>(0),
|
||||||
|
bought: persistent<boolean>(false)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
milestones: [
|
milestones: [
|
||||||
|
@ -1333,7 +1378,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
fireElves,
|
fireElves,
|
||||||
plasticElves,
|
plasticElves,
|
||||||
managementElves,
|
managementElves,
|
||||||
managementElves2.concat(wrappingPaperElves)
|
managementElves2.concat(wrappingPaperElves),
|
||||||
|
[packingElf]
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{milestonesDisplay()}
|
{milestonesDisplay()}
|
||||||
|
|
|
@ -26,7 +26,6 @@ import boxes from "./boxes";
|
||||||
import cloth from "./cloth";
|
import cloth from "./cloth";
|
||||||
import coal from "./coal";
|
import coal from "./coal";
|
||||||
import dyes from "./dyes";
|
import dyes from "./dyes";
|
||||||
import elves from "./elves";
|
|
||||||
import metal from "./metal";
|
import metal from "./metal";
|
||||||
import oil from "./oil";
|
import oil from "./oil";
|
||||||
import paper from "./paper";
|
import paper from "./paper";
|
||||||
|
@ -38,6 +37,8 @@ import { Resource } from "features/resources/resource";
|
||||||
import { isArray } from "@vue/shared";
|
import { isArray } from "@vue/shared";
|
||||||
import { createTab } from "features/tabs/tab";
|
import { createTab } from "features/tabs/tab";
|
||||||
import routing from "./routing";
|
import routing from "./routing";
|
||||||
|
import packing from "./packing";
|
||||||
|
import elves from "./elves";
|
||||||
|
|
||||||
const id = "management";
|
const id = "management";
|
||||||
const day = 12;
|
const day = 12;
|
||||||
|
@ -190,11 +191,15 @@ const layer = createLayer(id, () => {
|
||||||
"Cocoa",
|
"Cocoa",
|
||||||
"Twinkle",
|
"Twinkle",
|
||||||
"Carol",
|
"Carol",
|
||||||
"Tinsel"
|
"Tinsel",
|
||||||
|
"Jingle"
|
||||||
].indexOf(elf.name) + 1;
|
].indexOf(elf.name) + 1;
|
||||||
if (elf.name == "Star" || elf.name == "Bell") {
|
if (elf.name == "Star" || elf.name == "Bell") {
|
||||||
costMulti /= 3;
|
costMulti /= 3;
|
||||||
}
|
}
|
||||||
|
if (elf.name == "Jingle") {
|
||||||
|
costMulti *= 100000;
|
||||||
|
}
|
||||||
const costBase = 4000 * costMulti;
|
const costBase = 4000 * costMulti;
|
||||||
const expRequiredForNextLevel = computed(() => Decimal.pow(5, level.value).mul(costBase));
|
const expRequiredForNextLevel = computed(() => Decimal.pow(5, level.value).mul(costBase));
|
||||||
const level = computed(() =>
|
const level = computed(() =>
|
||||||
|
@ -1145,6 +1150,70 @@ const layer = createLayer(id, () => {
|
||||||
visibility: () => showIf(plasticElfMilestones[3].earned.value && main.day.value >= 16)
|
visibility: () => showIf(plasticElfMilestones[3].earned.value && main.day.value >= 16)
|
||||||
}))
|
}))
|
||||||
] as Array<GenericMilestone>;
|
] as Array<GenericMilestone>;
|
||||||
|
const packingElfMilestones = [
|
||||||
|
createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: "Jingle Level 1",
|
||||||
|
effectDisplay: "Double elf packing speed"
|
||||||
|
},
|
||||||
|
shouldEarn: () => packingElfTraining.level.value >= 1
|
||||||
|
})),
|
||||||
|
createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: "Jingle Level 2",
|
||||||
|
effectDisplay: jsx(() => (
|
||||||
|
<>
|
||||||
|
Each elf assistant increases packing speed by 10%
|
||||||
|
<br />
|
||||||
|
Currently: +
|
||||||
|
{formatWhole(
|
||||||
|
Decimal.times(packing.helpers.elf.amount.value, 0.1).times(100)
|
||||||
|
)}
|
||||||
|
%
|
||||||
|
</>
|
||||||
|
))
|
||||||
|
},
|
||||||
|
shouldEarn: () => packingElfTraining.level.value >= 2,
|
||||||
|
visibility: () => showIf(packingElfMilestones[0].earned.value)
|
||||||
|
})),
|
||||||
|
createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: "Jingle Level 3",
|
||||||
|
effectDisplay: jsx(() => (
|
||||||
|
<>
|
||||||
|
Multiply packing speed by the number of completed packing milestones
|
||||||
|
<br />
|
||||||
|
Currently:{" "}
|
||||||
|
{formatWhole(
|
||||||
|
Object.values(packing.packingMilestones).filter(
|
||||||
|
milestone => milestone.earned.value
|
||||||
|
).length + 1
|
||||||
|
)}
|
||||||
|
x
|
||||||
|
</>
|
||||||
|
))
|
||||||
|
},
|
||||||
|
shouldEarn: () => packingElfTraining.level.value >= 3,
|
||||||
|
visibility: () => showIf(packingElfMilestones[1].earned.value)
|
||||||
|
})),
|
||||||
|
createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: "Jingle Level 4",
|
||||||
|
effectDisplay: "Jingle will now also buy loaders"
|
||||||
|
},
|
||||||
|
shouldEarn: () => packingElfTraining.level.value >= 4,
|
||||||
|
visibility: () => showIf(packingElfMilestones[2].earned.value && main.day.value >= 16)
|
||||||
|
})),
|
||||||
|
createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: "Jingle Level 5",
|
||||||
|
effectDisplay:
|
||||||
|
"Multipliers to elf packing speed also apply to loaders at reduced rate"
|
||||||
|
},
|
||||||
|
shouldEarn: () => packingElfTraining.level.value >= 5,
|
||||||
|
visibility: () => showIf(packingElfMilestones[3].earned.value && main.day.value >= 16)
|
||||||
|
}))
|
||||||
|
] as Array<GenericMilestone>;
|
||||||
// ------------------------------------------------------------------------------- Milestone display
|
// ------------------------------------------------------------------------------- Milestone display
|
||||||
|
|
||||||
const currentShown = persistent<string>("Holly");
|
const currentShown = persistent<string>("Holly");
|
||||||
|
@ -1225,8 +1294,10 @@ const layer = createLayer(id, () => {
|
||||||
);
|
);
|
||||||
const dyeElfTraining = createElfTraining(elves.elves.dyeElf, dyeElfMilestones);
|
const dyeElfTraining = createElfTraining(elves.elves.dyeElf, dyeElfMilestones);
|
||||||
const plasticElfTraining = createElfTraining(elves.elves.plasticElf, plasticElfMilestones);
|
const plasticElfTraining = createElfTraining(elves.elves.plasticElf, plasticElfMilestones);
|
||||||
|
const packingElfTraining = createElfTraining(elves.elves.packingElf, packingElfMilestones);
|
||||||
const row5Elves = [coalDrillElfTraining, heavyDrillElfTraining, oilElfTraining];
|
const row5Elves = [coalDrillElfTraining, heavyDrillElfTraining, oilElfTraining];
|
||||||
const row6Elves = [metalElfTraining, dyeElfTraining, plasticElfTraining];
|
const row6Elves = [metalElfTraining, dyeElfTraining, plasticElfTraining];
|
||||||
|
const row7Elves = [packingElfTraining];
|
||||||
const elfTraining = {
|
const elfTraining = {
|
||||||
cutterElfTraining,
|
cutterElfTraining,
|
||||||
planterElfTraining,
|
planterElfTraining,
|
||||||
|
@ -1245,7 +1316,8 @@ const layer = createLayer(id, () => {
|
||||||
oilElfTraining,
|
oilElfTraining,
|
||||||
heavyDrillElfTraining,
|
heavyDrillElfTraining,
|
||||||
dyeElfTraining,
|
dyeElfTraining,
|
||||||
plasticElfTraining
|
plasticElfTraining,
|
||||||
|
packingElfTraining
|
||||||
};
|
};
|
||||||
const day12Elves = [
|
const day12Elves = [
|
||||||
cutterElfTraining,
|
cutterElfTraining,
|
||||||
|
@ -1324,6 +1396,11 @@ const layer = createLayer(id, () => {
|
||||||
multiplier: 2,
|
multiplier: 2,
|
||||||
description: "Focus Upgrade 1",
|
description: "Focus Upgrade 1",
|
||||||
enabled: focusUpgrade1.bought
|
enabled: focusUpgrade1.bought
|
||||||
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: () => Decimal.pow(2, packing.packingResets.value),
|
||||||
|
description: `${format(6.4e9)} ${packing.packedPresents.displayName}`,
|
||||||
|
enabled: packing.packingMilestones.moreFocus.earned
|
||||||
}))
|
}))
|
||||||
]) as WithRequired<Modifier, "revert" | "description">;
|
]) as WithRequired<Modifier, "revert" | "description">;
|
||||||
const maximumElvesModifier = createSequentialModifier(() => [
|
const maximumElvesModifier = createSequentialModifier(() => [
|
||||||
|
@ -1355,8 +1432,8 @@ const layer = createLayer(id, () => {
|
||||||
direction: Direction.Right,
|
direction: Direction.Right,
|
||||||
width: 566,
|
width: 566,
|
||||||
height: 50,
|
height: 50,
|
||||||
style: `border-radius: 4px 4px 0 0`,
|
style: `border-radius: 0`,
|
||||||
borderStyle: `border-radius: 4px 4px 0 0`,
|
borderStyle: `border-radius: 0`,
|
||||||
fillStyle: () => ({
|
fillStyle: () => ({
|
||||||
background: focusTime.value > 0 ? color : "#7f7f00",
|
background: focusTime.value > 0 ? color : "#7f7f00",
|
||||||
animation: focusTime.value > 0 ? "1s focused-focus-bar linear infinite" : "",
|
animation: focusTime.value > 0 ? "1s focused-focus-bar linear infinite" : "",
|
||||||
|
@ -1401,7 +1478,9 @@ const layer = createLayer(id, () => {
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
style: {
|
style: {
|
||||||
width: "300px"
|
width: "570px",
|
||||||
|
minHeight: "80px",
|
||||||
|
zIndex: 4
|
||||||
},
|
},
|
||||||
canClick: () => Decimal.eq(focusCooldown.value, 0),
|
canClick: () => Decimal.eq(focusCooldown.value, 0),
|
||||||
onClick() {
|
onClick() {
|
||||||
|
@ -1420,10 +1499,20 @@ const layer = createLayer(id, () => {
|
||||||
let x = 0;
|
let x = 0;
|
||||||
focusTargets.value = {};
|
focusTargets.value = {};
|
||||||
const newCount = Decimal.min(count, range);
|
const newCount = Decimal.min(count, range);
|
||||||
|
if (packing.packingMilestones.focusSelected.earned.value) {
|
||||||
|
const elf = Object.values(elfTraining).find(
|
||||||
|
training => training.name === currentShown.value
|
||||||
|
);
|
||||||
|
const roll = elf?.name ?? "";
|
||||||
|
if (!focusTargets.value[roll] && unref(elf?.visibility) === Visibility.Visible) {
|
||||||
|
focusTargets.value[roll] = true;
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
}
|
||||||
while (newCount.gt(x)) {
|
while (newCount.gt(x)) {
|
||||||
const elf = Object.values(elfTraining)[Math.floor(Math.random() * range)];
|
const elf = Object.values(elfTraining)[Math.floor(Math.random() * range)];
|
||||||
const roll = elf?.name ?? "";
|
const roll = elf?.name ?? "";
|
||||||
if (!focusTargets.value[roll] && unref(elf.visibility) === Visibility.Visible) {
|
if (!focusTargets.value[roll] && unref(elf?.visibility) === Visibility.Visible) {
|
||||||
focusTargets.value[roll] = true;
|
focusTargets.value[roll] = true;
|
||||||
x++;
|
x++;
|
||||||
}
|
}
|
||||||
|
@ -1770,6 +1859,12 @@ const layer = createLayer(id, () => {
|
||||||
modifier: plasticElfTraining.elfXPGain,
|
modifier: plasticElfTraining.elfXPGain,
|
||||||
base: 0.1,
|
base: 0.1,
|
||||||
unit: " XP"
|
unit: " XP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Jingle XP Gain per Action",
|
||||||
|
modifier: packingElfTraining.elfXPGain,
|
||||||
|
base: 0.1,
|
||||||
|
unit: " XP"
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
const showModifiersModal = ref(false);
|
const showModifiersModal = ref(false);
|
||||||
|
@ -2055,17 +2150,18 @@ const layer = createLayer(id, () => {
|
||||||
Click on an elf to see their milestones.
|
Click on an elf to see their milestones.
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<Spacer />
|
<Spacer />
|
||||||
{render(focusButton)}
|
|
||||||
{renderGrid(upgrades, upgrades2)}
|
{renderGrid(upgrades, upgrades2)}
|
||||||
<Spacer />
|
<Spacer />
|
||||||
{renderGrid(
|
{renderGrid(
|
||||||
|
[focusButton],
|
||||||
[focusMeter],
|
[focusMeter],
|
||||||
treeElfTraining,
|
treeElfTraining,
|
||||||
coalElfTraining,
|
coalElfTraining,
|
||||||
fireElfTraining,
|
fireElfTraining,
|
||||||
plasticElvesTraining,
|
plasticElvesTraining,
|
||||||
row5Elves,
|
row5Elves,
|
||||||
row6Elves
|
row6Elves,
|
||||||
|
row7Elves
|
||||||
)}
|
)}
|
||||||
<Spacer />
|
<Spacer />
|
||||||
{currentElfDisplay()}
|
{currentElfDisplay()}
|
||||||
|
|
|
@ -41,6 +41,7 @@ import reindeer from "./reindeer";
|
||||||
import sleigh from "./sleigh";
|
import sleigh from "./sleigh";
|
||||||
import factory from "./factory";
|
import factory from "./factory";
|
||||||
import routing from "./routing";
|
import routing from "./routing";
|
||||||
|
import packing from "./packing";
|
||||||
|
|
||||||
const id = "metal";
|
const id = "metal";
|
||||||
const day = 7;
|
const day = 7;
|
||||||
|
@ -128,6 +129,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
exponent: 1.2,
|
exponent: 1.2,
|
||||||
description: "100% Sleigh Fixed",
|
description: "100% Sleigh Fixed",
|
||||||
enabled: sleigh.milestones.milestone8.earned
|
enabled: sleigh.milestones.milestone8.earned
|
||||||
|
})),
|
||||||
|
createExponentialModifier(() => ({
|
||||||
|
exponent: 1.5,
|
||||||
|
description: "69,200 Presents Packed",
|
||||||
|
enabled: packing.packingMilestones.metalBoost.earned
|
||||||
}))
|
}))
|
||||||
]);
|
]);
|
||||||
const computedOrePurity = computed(() => orePurity.apply(0.1));
|
const computedOrePurity = computed(() => orePurity.apply(0.1));
|
||||||
|
@ -386,6 +392,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
})),
|
})),
|
||||||
createMultiplicativeModifier(() => ({
|
createMultiplicativeModifier(() => ({
|
||||||
multiplier: computedOreSpeed
|
multiplier: computedOreSpeed
|
||||||
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: computedOreSpeed,
|
||||||
|
description: "1,670,000 Presents Packed",
|
||||||
|
enabled: packing.packingMilestones.oreBoost.earned
|
||||||
}))
|
}))
|
||||||
]);
|
]);
|
||||||
const computedOreGain = computed(() => oreGain.apply(0));
|
const computedOreGain = computed(() => oreGain.apply(0));
|
||||||
|
|
|
@ -45,6 +45,7 @@ import toys from "./toys";
|
||||||
import factory from "./factory";
|
import factory from "./factory";
|
||||||
import reindeer from "./reindeer";
|
import reindeer from "./reindeer";
|
||||||
import routing from "./routing";
|
import routing from "./routing";
|
||||||
|
import packing from "./packing"
|
||||||
|
|
||||||
const id = "oil";
|
const id = "oil";
|
||||||
const day = 9;
|
const day = 9;
|
||||||
|
@ -924,6 +925,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
description: "Red Dye",
|
description: "Red Dye",
|
||||||
enabled: dyes.masteryEffectActive
|
enabled: dyes.masteryEffectActive
|
||||||
})),
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: 3,
|
||||||
|
description: "2,800 Presents Packaged",
|
||||||
|
enabled: packing.packingMilestones.oilBoost.earned
|
||||||
|
})),
|
||||||
createExponentialModifier(() => ({
|
createExponentialModifier(() => ({
|
||||||
exponent: 1.2,
|
exponent: 1.2,
|
||||||
description: "Diamond-tipped drills",
|
description: "Diamond-tipped drills",
|
||||||
|
|
658
src/data/layers/packing.tsx
Normal file
658
src/data/layers/packing.tsx
Normal file
|
@ -0,0 +1,658 @@
|
||||||
|
import { isArray } from "@vue/shared";
|
||||||
|
import SpacerVue from "components/layout/Spacer.vue";
|
||||||
|
import { createCollapsibleModifierSections, setUpDailyProgressTracker } from "data/common";
|
||||||
|
import { main } from "data/projEntry";
|
||||||
|
import { createBar } from "features/bars/bar";
|
||||||
|
import { createBuyable, GenericBuyable } from "features/buyable";
|
||||||
|
import { createClickable } from "features/clickables/clickable";
|
||||||
|
import { jsx, showIf } from "features/feature";
|
||||||
|
import { createMilestone, GenericMilestone } from "features/milestones/milestone";
|
||||||
|
import MainDisplayVue from "features/resources/MainDisplay.vue";
|
||||||
|
import { createResource, trackBest, trackTotal, Resource } from "features/resources/resource";
|
||||||
|
import { createLayer, BaseLayer } from "game/layers";
|
||||||
|
import {
|
||||||
|
createAdditiveModifier,
|
||||||
|
createMultiplicativeModifier,
|
||||||
|
createSequentialModifier
|
||||||
|
} from "game/modifiers";
|
||||||
|
import { persistent } from "game/persistence";
|
||||||
|
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
|
||||||
|
import { Direction } from "util/common";
|
||||||
|
import { render, renderGrid, renderRow } from "util/vue";
|
||||||
|
import { computed, ComputedRef, ref, unref } from "vue";
|
||||||
|
import metal from "./metal";
|
||||||
|
import oil from "./oil";
|
||||||
|
import { createCollapsibleMilestones } from "data/common";
|
||||||
|
import { globalBus } from "game/events";
|
||||||
|
import { createUpgrade, GenericUpgrade } from "features/upgrades/upgrade";
|
||||||
|
import elves, { ElfBuyable } from "./elves";
|
||||||
|
import management from "./management";
|
||||||
|
import paper from "./paper";
|
||||||
|
import ModalVue from "components/Modal.vue";
|
||||||
|
import ribbon from "./ribbon";
|
||||||
|
import { createReset } from "features/reset";
|
||||||
|
import ResourceVue from "features/resources/Resource.vue";
|
||||||
|
|
||||||
|
const id = "packing";
|
||||||
|
const day = 24;
|
||||||
|
|
||||||
|
const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
|
const name = "Packing the Sleigh";
|
||||||
|
const color = "lightblue";
|
||||||
|
|
||||||
|
const packedPresents = createResource<DecimalSource>(0, "packed presents");
|
||||||
|
const bestPresents = trackBest(packedPresents);
|
||||||
|
const totalPresents = trackTotal(packedPresents);
|
||||||
|
const totalPresentsResource = createResource<DecimalSource>(
|
||||||
|
computed(() => totalPresents.value),
|
||||||
|
"total packed presents"
|
||||||
|
);
|
||||||
|
|
||||||
|
const sledSpace = 64e6;
|
||||||
|
const packingResets = persistent<number>(0);
|
||||||
|
|
||||||
|
const packingReset = createReset(() => ({
|
||||||
|
thingsToReset: [elf as any, loader as any, packedPresents],
|
||||||
|
onReset() {
|
||||||
|
packingResets.value++;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
const resetPacking = createClickable(() => ({
|
||||||
|
display: {
|
||||||
|
description:
|
||||||
|
"Oh no! You've run out of space! You'll need to take all the presents out and repack them more tightly..."
|
||||||
|
},
|
||||||
|
visibility: () =>
|
||||||
|
showIf(Decimal.lt(packedPresents.value, 8e9) && Decimal.lte(remainingSize.value, 0)),
|
||||||
|
onClick: packingReset.reset
|
||||||
|
}));
|
||||||
|
|
||||||
|
const packingProgress = persistent<DecimalSource>(0);
|
||||||
|
const packingProgressBar = createBar(() => ({
|
||||||
|
direction: Direction.Right,
|
||||||
|
width: 100,
|
||||||
|
height: 10,
|
||||||
|
fillStyle: {
|
||||||
|
animation: "15s packing-bar linear infinite"
|
||||||
|
},
|
||||||
|
progress: () => packingProgress.value
|
||||||
|
}));
|
||||||
|
const manualAmount = computed(() =>
|
||||||
|
Decimal.add(
|
||||||
|
Decimal.times(computedElfPackingSpeed.value, elf.amount.value),
|
||||||
|
Decimal.times(computedLoaderPackingSpeed.value, loader.amount.value)
|
||||||
|
).times(2)
|
||||||
|
);
|
||||||
|
const packPresent = createClickable(() => ({
|
||||||
|
display: {
|
||||||
|
description: jsx(() => (
|
||||||
|
<>
|
||||||
|
{upgrades2.manual.bought.value ? (
|
||||||
|
<h3>Pack {format(manualAmount.value)} presents</h3>
|
||||||
|
) : (
|
||||||
|
<h3>Pack a present</h3>
|
||||||
|
)}
|
||||||
|
<br />
|
||||||
|
{render(packingProgressBar)}
|
||||||
|
</>
|
||||||
|
))
|
||||||
|
},
|
||||||
|
style: "min-height: 60px; width: 200px",
|
||||||
|
visibility: () => showIf(Decimal.gt(remainingSize.value, 0)),
|
||||||
|
canClick: () => Decimal.gte(packingProgress.value, 1),
|
||||||
|
onClick() {
|
||||||
|
if (Decimal.lt(packingProgress.value, 1)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const amount = upgrades2.manual.bought.value ? manualAmount.value : 1;
|
||||||
|
packedPresents.value = Decimal.add(packedPresents.value, amount).min(
|
||||||
|
currentMaxPresents.value
|
||||||
|
);
|
||||||
|
packingProgress.value = 0;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
const packingDensity = computed(() => {
|
||||||
|
switch (packingResets.value) {
|
||||||
|
default:
|
||||||
|
return 0.6;
|
||||||
|
case 1:
|
||||||
|
return 0.7;
|
||||||
|
case 2:
|
||||||
|
return 0.85;
|
||||||
|
case 3:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const packedPresentsSize = computed(() =>
|
||||||
|
Decimal.times(packedPresents.value, 0.008).dividedBy(packingDensity.value)
|
||||||
|
);
|
||||||
|
const currentMaxPresents = computed(() =>
|
||||||
|
Decimal.times(sledSpace, packingDensity.value).div(0.008)
|
||||||
|
);
|
||||||
|
const remainingSize = computed(() => Decimal.sub(sledSpace, packedPresentsSize.value));
|
||||||
|
|
||||||
|
const elfPackingSpeed = createSequentialModifier(() => [
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: () => Decimal.pow(0.5, packingResets.value),
|
||||||
|
description: "Better Organization",
|
||||||
|
enabled: () => packingResets.value >= 1
|
||||||
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: 2,
|
||||||
|
description: "Jingle Level 1",
|
||||||
|
enabled: management.elfTraining.packingElfTraining.milestones[0].earned
|
||||||
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: () => Decimal.times(helpers.elf.amount.value, 0.005).plus(1),
|
||||||
|
description: "Jingle Level 2",
|
||||||
|
enabled: management.elfTraining.packingElfTraining.milestones[1].earned
|
||||||
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: () =>
|
||||||
|
1 + Object.values(packingMilestones).filter(milestone => milestone.earned).length,
|
||||||
|
description: "Jingle Level 3",
|
||||||
|
enabled: management.elfTraining.packingElfTraining.milestones[2].earned
|
||||||
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: () => Decimal.log10(packedPresents.value).plus(1),
|
||||||
|
description: "10,000 Presents Packed",
|
||||||
|
enabled: () => Decimal.gte(packedPresents.value, 1e4)
|
||||||
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: () => Decimal.times(management.totalElfLevels.value, 0.05).add(1),
|
||||||
|
description: "Communal Assistance",
|
||||||
|
enabled: upgrades.elfLevel.bought
|
||||||
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: () => Decimal.pow(1.02, ribbon.ribbon.value),
|
||||||
|
description: "Spare Bows",
|
||||||
|
enabled: upgrades2.ribbons.bought
|
||||||
|
}))
|
||||||
|
]);
|
||||||
|
const computedElfPackingSpeed = computed(() => elfPackingSpeed.apply(1));
|
||||||
|
|
||||||
|
const loaderPackingSpeed = createSequentialModifier(() => [
|
||||||
|
createAdditiveModifier(() => ({
|
||||||
|
addend: () => Decimal.times(elf.amount.value, 5),
|
||||||
|
description: "Loading Assistants",
|
||||||
|
enabled: upgrades2.assistantSynergy.bought
|
||||||
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: () => Decimal.pow(0.5, packingResets.value),
|
||||||
|
description: "Better Organization",
|
||||||
|
enabled: () => packingResets.value >= 1
|
||||||
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: () => Decimal.sqrt(elfPackingSpeed.apply(1)),
|
||||||
|
description: "Jingle Level 5",
|
||||||
|
enabled: management.elfTraining.packingElfTraining.milestones[4].earned
|
||||||
|
}))
|
||||||
|
]);
|
||||||
|
const computedLoaderPackingSpeed = computed(() => loaderPackingSpeed.apply(1000));
|
||||||
|
const elf = createBuyable(() => ({
|
||||||
|
visibility: () => showIf(Decimal.gte(totalPresents.value, 10)),
|
||||||
|
cost() {
|
||||||
|
let v = this.amount.value;
|
||||||
|
v = Decimal.pow(0.98, paper.books.packingBook.totalAmount.value).times(v);
|
||||||
|
return Decimal.pow(1.2, v).times(10).floor();
|
||||||
|
},
|
||||||
|
inverseCost(cost: DecimalSource) {
|
||||||
|
let amount = Decimal.div(cost, 10).log(1.2);
|
||||||
|
amount = amount.div(Decimal.pow(0.98, paper.books.packingBook.totalAmount.value));
|
||||||
|
return Decimal.isNaN(amount) ? Decimal.dZero : amount.floor().max(0);
|
||||||
|
},
|
||||||
|
resource: totalPresentsResource,
|
||||||
|
display: jsx(() => (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
<h3>Hire an elf assistant</h3>
|
||||||
|
</div>
|
||||||
|
Packs {format(computedElfPackingSpeed.value)} presents per second
|
||||||
|
<div>
|
||||||
|
<br />
|
||||||
|
Amount: {formatWhole(helpers.elf.amount.value)}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<br />
|
||||||
|
Currently packing{" "}
|
||||||
|
{format(
|
||||||
|
Decimal.times(helpers.elf.amount.value, computedElfPackingSpeed.value)
|
||||||
|
)}{" "}
|
||||||
|
presents per second
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Requires: {formatWhole(unref(helpers.elf.cost!))}{" "}
|
||||||
|
{helpers.elf.resource!.displayName}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)),
|
||||||
|
style: {
|
||||||
|
width: "200px"
|
||||||
|
}
|
||||||
|
})) as ElfBuyable;
|
||||||
|
const loader = createBuyable(() => ({
|
||||||
|
visibility: () => showIf(upgrades.loaderUnlock.bought.value),
|
||||||
|
metalCost: computed(() => Decimal.pow(1.2, helpers.loader.amount.value).times(1e70)),
|
||||||
|
oilCost: computed(() => Decimal.pow(1.2, helpers.loader.amount.value).times(1e25)),
|
||||||
|
canPurchase(
|
||||||
|
this: GenericBuyable & {
|
||||||
|
metalCost: ComputedRef<DecimalSource>;
|
||||||
|
oilCost: ComputedRef<DecimalSource>;
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
Decimal.gte(metal.metal.value, this.metalCost.value) &&
|
||||||
|
Decimal.gte(oil.oil.value, this.oilCost.value)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onPurchase() {
|
||||||
|
metal.metal.value = Decimal.sub(metal.metal.value, this.metalCost.value);
|
||||||
|
oil.oil.value = Decimal.sub(oil.oil.value, this.oilCost.value);
|
||||||
|
this.amount.value = Decimal.add(this.amount.value, 1);
|
||||||
|
},
|
||||||
|
inverseCost() {
|
||||||
|
const metalAmount = Decimal.div(metal.metal.value, 1e40).log(1.5);
|
||||||
|
const oilAmount = Decimal.div(oil.oil.value, 1e20).log(1.5);
|
||||||
|
if (Decimal.isNaN(metalAmount) || Decimal.isNaN(oilAmount)) return Decimal.dZero;
|
||||||
|
return Decimal.min(metalAmount, oilAmount).floor().max(0);
|
||||||
|
},
|
||||||
|
display: jsx(() => (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
<h3>Build a loader</h3>
|
||||||
|
</div>
|
||||||
|
Loads {format(computedLoaderPackingSpeed.value)} presents per second
|
||||||
|
<div>
|
||||||
|
<br />
|
||||||
|
Amount: {formatWhole(helpers.loader.amount.value)}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<br />
|
||||||
|
Currently packing{" "}
|
||||||
|
{format(
|
||||||
|
Decimal.times(helpers.loader.amount.value, computedLoaderPackingSpeed.value)
|
||||||
|
)}{" "}
|
||||||
|
persents per second
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Cost:{" "}
|
||||||
|
{displayCost(
|
||||||
|
metal.metal,
|
||||||
|
helpers.loader.metalCost.value,
|
||||||
|
metal.metal.displayName
|
||||||
|
)}
|
||||||
|
,{displayCost(oil.oil, helpers.loader.oilCost.value, oil.oil.displayName)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)),
|
||||||
|
style: {
|
||||||
|
width: "200px"
|
||||||
|
}
|
||||||
|
})) as ElfBuyable & {
|
||||||
|
metalCost: ComputedRef<DecimalSource>;
|
||||||
|
oilCost: ComputedRef<DecimalSource>;
|
||||||
|
};
|
||||||
|
const helpers = { elf, loader };
|
||||||
|
|
||||||
|
const upgrades = {
|
||||||
|
packingElf: createUpgrade(() => ({
|
||||||
|
display: {
|
||||||
|
title: "An Elf's Elf",
|
||||||
|
description: "Train an Elf to help you hire more Elves."
|
||||||
|
},
|
||||||
|
cost: 1000,
|
||||||
|
resource: totalPresentsResource,
|
||||||
|
style: {
|
||||||
|
width: "200px"
|
||||||
|
},
|
||||||
|
visibility() {
|
||||||
|
return showIf(Decimal.gte(packedPresents.value, 10) || this.bought.value);
|
||||||
|
},
|
||||||
|
onPurchase() {
|
||||||
|
main.days[12].recentlyUpdated.value = true;
|
||||||
|
elves.elves.packingElf.bought.value = true;
|
||||||
|
}
|
||||||
|
})),
|
||||||
|
loaderUnlock: createUpgrade(() => ({
|
||||||
|
display: {
|
||||||
|
title: "Heavy Machinery",
|
||||||
|
description:
|
||||||
|
"Those construction vehicles you have from building the workshop should be useful for loading presents too."
|
||||||
|
},
|
||||||
|
cost: 1000000,
|
||||||
|
resource: totalPresentsResource,
|
||||||
|
style: {
|
||||||
|
width: "200px"
|
||||||
|
},
|
||||||
|
visibility() {
|
||||||
|
return showIf(Decimal.gte(totalPresents.value, 10000) || this.bought.value);
|
||||||
|
}
|
||||||
|
})),
|
||||||
|
elfLevel: createUpgrade(() => ({
|
||||||
|
display: {
|
||||||
|
title: "Communal Assistance",
|
||||||
|
description: "Each elf level increases elf packing speed by 5%"
|
||||||
|
},
|
||||||
|
cost: 100000000,
|
||||||
|
resource: totalPresentsResource,
|
||||||
|
style: {
|
||||||
|
width: "200px"
|
||||||
|
},
|
||||||
|
visibility() {
|
||||||
|
return showIf(Decimal.gte(totalPresents.value, 10000000) || this.bought.value);
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
const upgrades2 = {
|
||||||
|
ribbons: createUpgrade(() => ({
|
||||||
|
display: {
|
||||||
|
title: "Spare Bows",
|
||||||
|
description: "Each ribbon multiplies elf packing speed by 1.02x"
|
||||||
|
},
|
||||||
|
cost: 2e9,
|
||||||
|
resource: totalPresentsResource,
|
||||||
|
style: {
|
||||||
|
width: "200px"
|
||||||
|
},
|
||||||
|
visibility() {
|
||||||
|
return showIf(Decimal.gte(totalPresents.value, 1e9) || this.bought.value);
|
||||||
|
}
|
||||||
|
})),
|
||||||
|
assistantSynergy: createUpgrade(() => ({
|
||||||
|
display: {
|
||||||
|
title: "Loading Assistants",
|
||||||
|
description:
|
||||||
|
"Each elf assistant increases how much the loader can load per second by 5"
|
||||||
|
},
|
||||||
|
cost: 5e9,
|
||||||
|
resource: totalPresentsResource,
|
||||||
|
style: {
|
||||||
|
width: "200px"
|
||||||
|
},
|
||||||
|
visibility() {
|
||||||
|
return showIf(Decimal.gte(totalPresents.value, 4.8e9) || this.bought.value);
|
||||||
|
}
|
||||||
|
})),
|
||||||
|
manual: createUpgrade(() => ({
|
||||||
|
display: {
|
||||||
|
title: "DIY",
|
||||||
|
description:
|
||||||
|
"Each present manually packed gives 2 seconds of automatic present packing production"
|
||||||
|
},
|
||||||
|
cost: 1e10,
|
||||||
|
resource: totalPresentsResource,
|
||||||
|
style: {
|
||||||
|
width: "200px"
|
||||||
|
},
|
||||||
|
visibility() {
|
||||||
|
return showIf(Decimal.gte(totalPresents.value, 5e9) || this.bought.value);
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
|
||||||
|
const packingMilestones: Record<string, GenericMilestone> = {
|
||||||
|
logBoost: createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: `25 ${packedPresents.displayName}`,
|
||||||
|
effectDisplay: "Trees size is raised to the 1.25th power"
|
||||||
|
},
|
||||||
|
shouldEarn: () => Decimal.gte(packedPresents.value, 25)
|
||||||
|
})),
|
||||||
|
boxBoost: createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: `120 ${packedPresents.displayName}`,
|
||||||
|
effectDisplay: "Create 10% more boxes"
|
||||||
|
},
|
||||||
|
shouldEarn: () => Decimal.gte(packedPresents.value, 120),
|
||||||
|
visibility: () => showIf(packingMilestones.logBoost.earned.value)
|
||||||
|
})),
|
||||||
|
clothBoost: createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: `600 ${packedPresents.displayName}`,
|
||||||
|
effectDisplay: "Sheep grow 10x as much wool"
|
||||||
|
},
|
||||||
|
shouldEarn: () => Decimal.gte(packedPresents.value, 600),
|
||||||
|
visibility: () => showIf(packingMilestones.boxBoost.earned.value)
|
||||||
|
})),
|
||||||
|
oilBoost: createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: `2,800 ${packedPresents.displayName}`,
|
||||||
|
effectDisplay: "Triple drill power"
|
||||||
|
},
|
||||||
|
shouldEarn: () => Decimal.gte(packedPresents.value, 2800),
|
||||||
|
visibility: () => showIf(packingMilestones.clothBoost.earned.value)
|
||||||
|
})),
|
||||||
|
packingBoost: createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: `10,000 ${packedPresents.displayName}`,
|
||||||
|
effectDisplay: "Multiply packing speed by log(presents)"
|
||||||
|
},
|
||||||
|
shouldEarn: () => Decimal.gte(packedPresents.value, 2800),
|
||||||
|
visibility: () => showIf(packingMilestones.clothBoost.earned.value)
|
||||||
|
})),
|
||||||
|
coalBoost: createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: `14,000 ${packedPresents.displayName}`,
|
||||||
|
effectDisplay: "Coal producer costs grow half as fast"
|
||||||
|
},
|
||||||
|
shouldEarn: () => Decimal.gte(packedPresents.value, 14000),
|
||||||
|
visibility: () => showIf(packingMilestones.oilBoost.earned.value)
|
||||||
|
})),
|
||||||
|
metalBoost: createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: `69,200 ${packedPresents.displayName}`,
|
||||||
|
effectDisplay: "Raise ore purity to the 1.5th power"
|
||||||
|
},
|
||||||
|
shouldEarn: () => Decimal.gte(packedPresents.value, 69200),
|
||||||
|
visibility: () => showIf(packingMilestones.coalBoost.earned.value)
|
||||||
|
})),
|
||||||
|
wrappingPaperBoost: createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: `340,000 ${packedPresents.displayName}`,
|
||||||
|
effectDisplay: "Double the strength of wrapping paper bonuses"
|
||||||
|
},
|
||||||
|
shouldEarn: () => Decimal.gte(packedPresents.value, 340000),
|
||||||
|
visibility: () => showIf(packingMilestones.metalBoost.earned.value)
|
||||||
|
})),
|
||||||
|
oreBoost: createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: `1,670,000 ${packedPresents.displayName}`,
|
||||||
|
effectDisplay: "Ore mining speed multiplies ore gain"
|
||||||
|
},
|
||||||
|
shouldEarn: () => Decimal.gte(packedPresents.value, 1670000),
|
||||||
|
visibility: () => showIf(packingMilestones.wrappingPaperBoost.earned.value)
|
||||||
|
})),
|
||||||
|
ribbonBoost: createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: `8,230,000 ${packedPresents.displayName}`,
|
||||||
|
effectDisplay: "Halve ribbon's dye cost"
|
||||||
|
},
|
||||||
|
shouldEarn: () => Decimal.gte(packedPresents.value, 8230000),
|
||||||
|
visibility: () => showIf(packingMilestones.oreBoost.earned.value)
|
||||||
|
})),
|
||||||
|
secondaryDyeBoost: createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: `40,400,000 ${packedPresents.displayName}`,
|
||||||
|
effectDisplay: "Double the second effect of each secondary dye"
|
||||||
|
},
|
||||||
|
shouldEarn: () => Decimal.gte(packedPresents.value, 40400000),
|
||||||
|
visibility: () => showIf(packingMilestones.ribbonBoost.earned.value)
|
||||||
|
})),
|
||||||
|
paperBoost: createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: `199,000,000 ${packedPresents.displayName}`,
|
||||||
|
effectDisplay: "Produce 10x as much paper"
|
||||||
|
},
|
||||||
|
shouldEarn: () => Decimal.gte(packedPresents.value, 199000000),
|
||||||
|
visibility: () => showIf(packingMilestones.secondaryDyeBoost.earned.value)
|
||||||
|
})),
|
||||||
|
primaryDyeBoost: createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: `977,000,000 ${packedPresents.displayName}`,
|
||||||
|
effectDisplay: "Quintuple primary dye gain"
|
||||||
|
},
|
||||||
|
shouldEarn: () => Decimal.gte(packedPresents.value, 977000000),
|
||||||
|
visibility: () => showIf(packingMilestones.paperBoost.earned.value)
|
||||||
|
})),
|
||||||
|
focusSelected: createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: `${format(4.2e9)} ${packedPresents.displayName}`,
|
||||||
|
effectDisplay: "Focusing elves always chooses the selected elf"
|
||||||
|
},
|
||||||
|
shouldEarn: () => Decimal.gte(packedPresents.value, 4.2e9),
|
||||||
|
visibility: () => showIf(packingMilestones.primaryDyeBoost.earned.value)
|
||||||
|
})),
|
||||||
|
moreFocus: createMilestone(() => ({
|
||||||
|
display: {
|
||||||
|
requirement: `${format(6.4e9)} ${packedPresents.displayName}`,
|
||||||
|
effectDisplay: "Each packing reset doubles the max elf focus multiplier"
|
||||||
|
},
|
||||||
|
shouldEarn: () => Decimal.gte(packedPresents.value, 6.4e9),
|
||||||
|
visibility: () => showIf(packingMilestones.focusSelected.earned.value)
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
const { collapseMilestones, display: milestonesDisplay } =
|
||||||
|
createCollapsibleMilestones(packingMilestones);
|
||||||
|
|
||||||
|
const [generalTab, generalTabCollapsed] = createCollapsibleModifierSections(() => [
|
||||||
|
{
|
||||||
|
title: "Elf Packing Speed",
|
||||||
|
modifier: elfPackingSpeed,
|
||||||
|
base: 1,
|
||||||
|
unit: "/s"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Loader Packing Speed",
|
||||||
|
modifier: loaderPackingSpeed,
|
||||||
|
base: 1000,
|
||||||
|
unit: "/s"
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
const showModifiersModal = ref(false);
|
||||||
|
const modifiersModal = jsx(() => (
|
||||||
|
<ModalVue
|
||||||
|
modelValue={showModifiersModal.value}
|
||||||
|
onUpdate:modelValue={(value: boolean) => (showModifiersModal.value = value)}
|
||||||
|
v-slots={{
|
||||||
|
header: () => <h2>{name} Modifiers</h2>,
|
||||||
|
body: generalTab
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
const { trackerDisplay } = setUpDailyProgressTracker({
|
||||||
|
resource: packedPresents,
|
||||||
|
ignoreTotal: true,
|
||||||
|
goal: 8e9,
|
||||||
|
name,
|
||||||
|
day,
|
||||||
|
background: {
|
||||||
|
gradient: "packing-bar",
|
||||||
|
duration: "15s"
|
||||||
|
},
|
||||||
|
textColor: "var(--bought)",
|
||||||
|
modal: {
|
||||||
|
show: showModifiersModal,
|
||||||
|
display: modifiersModal
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
globalBus.on("update", diff => {
|
||||||
|
if (Decimal.lt(main.day.value, day)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Decimal.gte(packingProgress.value, 1)) {
|
||||||
|
packingProgress.value = 1;
|
||||||
|
} else {
|
||||||
|
packingProgress.value = Decimal.add(packingProgress.value, diff);
|
||||||
|
if (packPresent.isHolding.value) {
|
||||||
|
packPresent.onClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Decimal.lt(remainingSize.value, 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
packedPresents.value = Decimal.add(
|
||||||
|
Decimal.times(helpers.elf.amount.value, computedElfPackingSpeed.value),
|
||||||
|
Decimal.times(helpers.loader.amount.value, computedLoaderPackingSpeed.value)
|
||||||
|
)
|
||||||
|
.times(diff)
|
||||||
|
.plus(packedPresents.value)
|
||||||
|
.min(currentMaxPresents.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
name,
|
||||||
|
day,
|
||||||
|
color,
|
||||||
|
packedPresents,
|
||||||
|
bestPresents,
|
||||||
|
totalPresents,
|
||||||
|
packingResets,
|
||||||
|
packingProgress,
|
||||||
|
helpers,
|
||||||
|
upgrades,
|
||||||
|
upgrades2,
|
||||||
|
packingMilestones,
|
||||||
|
collapseMilestones,
|
||||||
|
generalTabCollapsed,
|
||||||
|
minWidth: 700,
|
||||||
|
display: jsx(() => (
|
||||||
|
<>
|
||||||
|
{render(trackerDisplay)}
|
||||||
|
<SpacerVue />
|
||||||
|
<MainDisplayVue resource={packedPresents} color={color} style="margin-bottom: 0" />
|
||||||
|
{packingResets.value === 0 ? null : (
|
||||||
|
<div>
|
||||||
|
<SpacerVue />
|
||||||
|
You've restarted packing {formatWhole(packingResets.value)} times,
|
||||||
|
<br />
|
||||||
|
packing a total of{" "}
|
||||||
|
<ResourceVue resource={totalPresentsResource} color={color} /> presents
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<SpacerVue />
|
||||||
|
<p>
|
||||||
|
The bag has {format(remainingSize.value)} m<sup>3</sup> empty room
|
||||||
|
</p>
|
||||||
|
<SpacerVue />
|
||||||
|
{render(resetPacking)}
|
||||||
|
{render(packPresent)}
|
||||||
|
{main.day.value === day - 1 ? <SpacerVue /> : null}
|
||||||
|
{renderRow(...Object.values(helpers))}
|
||||||
|
<SpacerVue />
|
||||||
|
{renderGrid(Object.values(upgrades), Object.values(upgrades2))}
|
||||||
|
<SpacerVue />
|
||||||
|
{milestonesDisplay()}
|
||||||
|
</>
|
||||||
|
)),
|
||||||
|
minimizedDisplay: jsx(() => (
|
||||||
|
<div>
|
||||||
|
{name}{" "}
|
||||||
|
<span class="desc">
|
||||||
|
{formatWhole(packedPresents.value)} {packedPresents.displayName}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
export default layer;
|
||||||
|
|
||||||
|
function displayCost(
|
||||||
|
res: Resource<DecimalSource> | Resource<DecimalSource>[],
|
||||||
|
cost: DecimalSource,
|
||||||
|
label: string
|
||||||
|
) {
|
||||||
|
const affordable = (isArray(res) ? res : [res]).every(res => Decimal.gte(res.value, cost));
|
||||||
|
return (
|
||||||
|
<span class={affordable ? "" : "unaffordable"}>
|
||||||
|
{format(cost)} {label}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ import coal from "./coal";
|
||||||
import dyes from "./dyes";
|
import dyes from "./dyes";
|
||||||
import elves, { ElfBuyable } from "./elves";
|
import elves, { ElfBuyable } from "./elves";
|
||||||
import management from "./management";
|
import management from "./management";
|
||||||
|
import packing from "./packing";
|
||||||
import plastic from "./plastic";
|
import plastic from "./plastic";
|
||||||
import reindeer from "./reindeer";
|
import reindeer from "./reindeer";
|
||||||
import ribbon from "./ribbon";
|
import ribbon from "./ribbon";
|
||||||
|
@ -131,6 +132,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
if (["Peppermint", "Twinkle", "Cocoa", "Frosty"].includes(options.elfName)) {
|
if (["Peppermint", "Twinkle", "Cocoa", "Frosty"].includes(options.elfName)) {
|
||||||
cost = cost.mul(1e31);
|
cost = cost.mul(1e31);
|
||||||
}
|
}
|
||||||
|
if (["Jingle"].includes(options.elfName)) {
|
||||||
|
cost = cost.mul(1e123);
|
||||||
|
}
|
||||||
if (management.elfTraining.paperElfTraining.milestones[0].earned.value) {
|
if (management.elfTraining.paperElfTraining.milestones[0].earned.value) {
|
||||||
cost = Decimal.div(cost, sumBooks.value.max(1));
|
cost = Decimal.div(cost, sumBooks.value.max(1));
|
||||||
}
|
}
|
||||||
|
@ -156,6 +160,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
if (["Peppermint", "Twinkle", "Cocoa", "Frosty"].includes(options.elfName)) {
|
if (["Peppermint", "Twinkle", "Cocoa", "Frosty"].includes(options.elfName)) {
|
||||||
v = v.div(1e31);
|
v = v.div(1e31);
|
||||||
}
|
}
|
||||||
|
if (["Jingle"].includes(options.elfName)) {
|
||||||
|
v = v.div(1e123);
|
||||||
|
}
|
||||||
v = v.log(scaling);
|
v = v.log(scaling);
|
||||||
|
|
||||||
v = v.div(Decimal.pow(0.95, paperBook.totalAmount.value));
|
v = v.div(Decimal.pow(0.95, paperBook.totalAmount.value));
|
||||||
|
@ -305,6 +312,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
buyableName: "Plastic Buyables",
|
buyableName: "Plastic Buyables",
|
||||||
visibility: () => showIf(plastic.masteryEffectActive.value)
|
visibility: () => showIf(plastic.masteryEffectActive.value)
|
||||||
});
|
});
|
||||||
|
const packingBook = createBook({
|
||||||
|
name: "The Tetris Effect",
|
||||||
|
elfName: "Jingle",
|
||||||
|
buyableName: "Elf Assistants",
|
||||||
|
visibility: () => showIf(packing.upgrades.packingElf.bought.value)
|
||||||
|
})
|
||||||
const books = {
|
const books = {
|
||||||
cuttersBook,
|
cuttersBook,
|
||||||
plantersBook,
|
plantersBook,
|
||||||
|
@ -324,7 +337,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
metalBook,
|
metalBook,
|
||||||
primaryDyeBook,
|
primaryDyeBook,
|
||||||
secondaryDyeBook,
|
secondaryDyeBook,
|
||||||
plasticBook
|
plasticBook,
|
||||||
|
packingBook
|
||||||
};
|
};
|
||||||
const sumBooks = computed(() =>
|
const sumBooks = computed(() =>
|
||||||
Object.values(books).reduce((acc, curr) => acc.add(curr.amount.value), new Decimal(0))
|
Object.values(books).reduce((acc, curr) => acc.add(curr.amount.value), new Decimal(0))
|
||||||
|
@ -425,6 +439,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
description: "Sunshine Wrapping Paper",
|
description: "Sunshine Wrapping Paper",
|
||||||
enabled: () => Decimal.gte(wrappingPaper.boosts.sunshine1.value, 2)
|
enabled: () => Decimal.gte(wrappingPaper.boosts.sunshine1.value, 2)
|
||||||
})),
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: 10,
|
||||||
|
description: "199,000,000 Presents Packed",
|
||||||
|
enabled: packing.packingMilestones.paperBoost.earned
|
||||||
|
})),
|
||||||
reindeer.reindeer.prancer.modifier
|
reindeer.reindeer.prancer.modifier
|
||||||
]) as WithRequired<Modifier, "description" | "revert">;
|
]) as WithRequired<Modifier, "description" | "revert">;
|
||||||
const ashCost = createSequentialModifier(() => [
|
const ashCost = createSequentialModifier(() => [
|
||||||
|
@ -513,7 +532,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
metalBook: { amount: persistent<DecimalSource>(0) },
|
metalBook: { amount: persistent<DecimalSource>(0) },
|
||||||
primaryDyeBook: { amount: persistent<DecimalSource>(0) },
|
primaryDyeBook: { amount: persistent<DecimalSource>(0) },
|
||||||
secondaryDyeBook: { amount: persistent<DecimalSource>(0) },
|
secondaryDyeBook: { amount: persistent<DecimalSource>(0) },
|
||||||
plasticBook: { amount: persistent<DecimalSource>(0) }
|
plasticBook: { amount: persistent<DecimalSource>(0) },
|
||||||
|
packingBook: { amount: persistent<DecimalSource>(0) }
|
||||||
},
|
},
|
||||||
upgrades: {
|
upgrades: {
|
||||||
clothUpgrade: { bought: persistent<boolean>(false) },
|
clothUpgrade: { bought: persistent<boolean>(false) },
|
||||||
|
|
|
@ -141,9 +141,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
zIndex: 4
|
zIndex: 4
|
||||||
},
|
},
|
||||||
canClick: () => Decimal.eq(currCooldown.value, 0),
|
canClick: () => Decimal.eq(currCooldown.value, 0),
|
||||||
onClick() {
|
onClick: focus
|
||||||
focus();
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const cooldown = createSequentialModifier(() => [
|
const cooldown = createSequentialModifier(() => [
|
||||||
|
|
|
@ -22,6 +22,7 @@ import { main } from "../projEntry";
|
||||||
import cloth from "./cloth";
|
import cloth from "./cloth";
|
||||||
import dyes from "./dyes";
|
import dyes from "./dyes";
|
||||||
import elves from "./elves";
|
import elves from "./elves";
|
||||||
|
import packing from "./packing"
|
||||||
|
|
||||||
const id = "ribbon";
|
const id = "ribbon";
|
||||||
const day = 16;
|
const day = 16;
|
||||||
|
@ -38,7 +39,7 @@ const layer = createLayer(id, () => {
|
||||||
[dyes.dyes.orange, dyes.dyes.green, dyes.dyes.purple].includes(currentDyeType.value)
|
[dyes.dyes.orange, dyes.dyes.green, dyes.dyes.purple].includes(currentDyeType.value)
|
||||||
? 2e6
|
? 2e6
|
||||||
: 1e13
|
: 1e13
|
||||||
)
|
).mul(packing.packingMilestones.ribbonBoost.earned.value ? 0.5 : 1)
|
||||||
);
|
);
|
||||||
const currentDyeType = computed(
|
const currentDyeType = computed(
|
||||||
() =>
|
() =>
|
||||||
|
|
|
@ -1002,6 +1002,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
citiesCompleted.value,
|
citiesCompleted.value,
|
||||||
Decimal.times(computedMetaSolvingSpeed.value, diff)
|
Decimal.times(computedMetaSolvingSpeed.value, diff)
|
||||||
).min(5000000);
|
).min(5000000);
|
||||||
|
if (Decimal.isNaN(citiesCompleted.value)) {
|
||||||
|
citiesCompleted.value = 50;
|
||||||
|
}
|
||||||
|
|
||||||
if (metaMilestones[0].earned.value) {
|
if (metaMilestones[0].earned.value) {
|
||||||
management.classrooms.amount.value = Decimal.add(
|
management.classrooms.amount.value = Decimal.add(
|
||||||
|
@ -1149,7 +1152,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
<>
|
<>
|
||||||
You've solved all cities on Earth!
|
You've solved all cities on Earth!
|
||||||
<br />
|
<br />
|
||||||
<span style="text-decoration: line-through">
|
<span style="text-decoration: line-through; font-size: smaller">
|
||||||
(and proved the travelling salesman problem to be O(1))
|
(and proved the travelling salesman problem to be O(1))
|
||||||
</span>
|
</span>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -79,6 +79,23 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes packing-bar {
|
||||||
|
from {
|
||||||
|
background: 0 0 / 170px 170px repeat repeating-linear-gradient(-45deg,
|
||||||
|
rgb(255, 76, 76) 0 10px, white 10px 20px,
|
||||||
|
rgb(65, 255, 95) 20px 30px, white 30px 40px,
|
||||||
|
rgb(76, 76, 255) 40px 50px, white 50px 60px
|
||||||
|
);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
background: 170px 0 / 170px 170px repeat repeating-linear-gradient(-45deg,
|
||||||
|
rgb(255, 76, 76) 0 10px, white 10px 20px,
|
||||||
|
rgb(65, 255, 95) 20px 30px, white 30px 40px,
|
||||||
|
rgb(76, 76, 255) 40px 50px, white 50px 60px
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes reindeer-bar {
|
@keyframes reindeer-bar {
|
||||||
from {
|
from {
|
||||||
background: 0 0 / 28px 28px repeat
|
background: 0 0 / 28px 28px repeat
|
||||||
|
|
|
@ -43,6 +43,7 @@ import factory from "./factory";
|
||||||
import reindeer from "./reindeer";
|
import reindeer from "./reindeer";
|
||||||
import sleigh from "./sleigh";
|
import sleigh from "./sleigh";
|
||||||
import routing from "./routing";
|
import routing from "./routing";
|
||||||
|
import packing from "./packing";
|
||||||
const id = "trees";
|
const id = "trees";
|
||||||
const day = 1;
|
const day = 1;
|
||||||
|
|
||||||
|
@ -590,6 +591,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
||||||
exponent: 1.05,
|
exponent: 1.05,
|
||||||
description: "Un-Processing",
|
description: "Un-Processing",
|
||||||
enabled: paper.upgrades2.treeUpgrade.bought
|
enabled: paper.upgrades2.treeUpgrade.bought
|
||||||
|
})),
|
||||||
|
createExponentialModifier(() => ({
|
||||||
|
exponent: 1.25,
|
||||||
|
description: "25 Presents Packed",
|
||||||
|
enabled: packing.packingMilestones.logBoost.earned
|
||||||
}))
|
}))
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { main } from "../projEntry";
|
||||||
import { default as dyes, type enumColor } from "./dyes";
|
import { default as dyes, type enumColor } from "./dyes";
|
||||||
import elves from "./elves";
|
import elves from "./elves";
|
||||||
import toys from "./toys";
|
import toys from "./toys";
|
||||||
|
import packing from "./packing"
|
||||||
|
|
||||||
const id = "wrappingPaper";
|
const id = "wrappingPaper";
|
||||||
const day = 15;
|
const day = 15;
|
||||||
|
@ -259,21 +260,22 @@ const layer = createLayer(id, () => {
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
const packingBoost = computed(() => packing.packingMilestones.wrappingPaperBoost.earned.value ? 2 : 1)
|
||||||
const boosts = {
|
const boosts = {
|
||||||
christmas1: computed(() =>
|
christmas1: computed(() =>
|
||||||
main.isMastery.value ? 1 : Decimal.add(wrappingPaper.christmas.buyable.amount.value, 1)
|
main.isMastery.value ? 1 : Decimal.add(wrappingPaper.christmas.buyable.amount.value, 1).mul(packingBoost.value)
|
||||||
), // Probably not the best way to do this, but it works
|
), // Probably not the best way to do this, but it works
|
||||||
rainbow1: computed(() =>
|
rainbow1: computed(() =>
|
||||||
main.isMastery.value ? 1 : Decimal.pow(2, wrappingPaper.rainbow.buyable.amount.value)
|
main.isMastery.value ? 1 : Decimal.pow(2, wrappingPaper.rainbow.buyable.amount.value).mul(packingBoost.value)
|
||||||
),
|
),
|
||||||
jazzy1: computed(() =>
|
jazzy1: computed(() =>
|
||||||
main.isMastery.value ? 1 : Decimal.add(wrappingPaper.jazzy.buyable.amount.value, 1)
|
main.isMastery.value ? 1 : Decimal.add(wrappingPaper.jazzy.buyable.amount.value, 1).mul(packingBoost.value)
|
||||||
),
|
),
|
||||||
sunshine1: computed(() =>
|
sunshine1: computed(() =>
|
||||||
main.isMastery.value ? 1 : Decimal.add(wrappingPaper.sunshine.buyable.amount.value, 1)
|
main.isMastery.value ? 1 : Decimal.add(wrappingPaper.sunshine.buyable.amount.value, 1).mul(packingBoost.value)
|
||||||
),
|
),
|
||||||
ocean1: computed(() =>
|
ocean1: computed(() =>
|
||||||
main.isMastery.value ? 1 : Decimal.pow(1.5, wrappingPaper.ocean.buyable.amount.value)
|
main.isMastery.value ? 1 : Decimal.pow(1.5, wrappingPaper.ocean.buyable.amount.value).mul(packingBoost.value)
|
||||||
),
|
),
|
||||||
beach1: computed(() =>
|
beach1: computed(() =>
|
||||||
main.isMastery.value
|
main.isMastery.value
|
||||||
|
@ -281,6 +283,7 @@ const layer = createLayer(id, () => {
|
||||||
: Decimal.add(wrappingPaper.beach.buyable.amount.value, 1)
|
: Decimal.add(wrappingPaper.beach.buyable.amount.value, 1)
|
||||||
.log10()
|
.log10()
|
||||||
.add(1)
|
.add(1)
|
||||||
|
.mul(packingBoost.value)
|
||||||
.pow(toys.milestones.milestone3.earned.value ? 1.6 : 1)
|
.pow(toys.milestones.milestone3.earned.value ? 1.6 : 1)
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,8 +4,10 @@ import {
|
||||||
Component,
|
Component,
|
||||||
GatherProps,
|
GatherProps,
|
||||||
GenericComponent,
|
GenericComponent,
|
||||||
jsx
|
jsx,
|
||||||
|
Visibility
|
||||||
} from "features/feature";
|
} from "features/feature";
|
||||||
|
import { createParticles } from "features/particles/particles";
|
||||||
import { BaseLayer, createLayer, GenericLayer, layers } from "game/layers";
|
import { BaseLayer, createLayer, GenericLayer, layers } from "game/layers";
|
||||||
import { isPersistent, Persistent, persistent } from "game/persistence";
|
import { isPersistent, Persistent, persistent } from "game/persistence";
|
||||||
import type { PlayerData } from "game/player";
|
import type { PlayerData } from "game/player";
|
||||||
|
@ -14,10 +16,10 @@ import { format, formatTime } from "util/bignum";
|
||||||
import { Computable, convertComputable, ProcessedComputable } from "util/computed";
|
import { Computable, convertComputable, ProcessedComputable } from "util/computed";
|
||||||
import { createLazyProxy } from "util/proxies";
|
import { createLazyProxy } from "util/proxies";
|
||||||
import { save } from "util/save";
|
import { save } from "util/save";
|
||||||
import { renderRow, VueFeature } from "util/vue";
|
import { render, renderRow, VueFeature } from "util/vue";
|
||||||
import type { Ref } from "vue";
|
import { computed, Ref, ref, unref, watchEffect } from "vue";
|
||||||
import { computed, ref, unref } from "vue";
|
|
||||||
import "./advent.css";
|
import "./advent.css";
|
||||||
|
import { credits } from "./credits";
|
||||||
import Day from "./Day.vue";
|
import Day from "./Day.vue";
|
||||||
import boxes from "./layers/boxes";
|
import boxes from "./layers/boxes";
|
||||||
import cloth from "./layers/cloth";
|
import cloth from "./layers/cloth";
|
||||||
|
@ -25,19 +27,21 @@ import coal from "./layers/coal";
|
||||||
import dyes from "./layers/dyes";
|
import dyes from "./layers/dyes";
|
||||||
import elves from "./layers/elves";
|
import elves from "./layers/elves";
|
||||||
import factory from "./layers/factory";
|
import factory from "./layers/factory";
|
||||||
|
import presentSymbol from "./layers/factory-components/present.svg";
|
||||||
import letters from "./layers/letters";
|
import letters from "./layers/letters";
|
||||||
import management from "./layers/management";
|
import management from "./layers/management";
|
||||||
import metal from "./layers/metal";
|
import metal from "./layers/metal";
|
||||||
import oil from "./layers/oil";
|
import oil from "./layers/oil";
|
||||||
|
import packing from "./layers/packing";
|
||||||
import paper from "./layers/paper";
|
import paper from "./layers/paper";
|
||||||
import plastic from "./layers/plastic";
|
import plastic from "./layers/plastic";
|
||||||
import reindeer from "./layers/reindeer";
|
import reindeer from "./layers/reindeer";
|
||||||
import ribbon from "./layers/ribbon";
|
import ribbon from "./layers/ribbon";
|
||||||
import routing from "./layers/routing";
|
import routing from "./layers/routing";
|
||||||
|
import sleigh from "./layers/sleigh";
|
||||||
import toys from "./layers/toys";
|
import toys from "./layers/toys";
|
||||||
import trees from "./layers/trees";
|
import trees from "./layers/trees";
|
||||||
import workshop from "./layers/workshop";
|
import workshop from "./layers/workshop";
|
||||||
import sleigh from "./layers/sleigh";
|
|
||||||
import wrappingPaper from "./layers/wrapping-paper";
|
import wrappingPaper from "./layers/wrapping-paper";
|
||||||
import boxesSymbol from "./symbols/cardboardBox.png";
|
import boxesSymbol from "./symbols/cardboardBox.png";
|
||||||
import clothSymbol from "./symbols/cloth.png";
|
import clothSymbol from "./symbols/cloth.png";
|
||||||
|
@ -46,6 +50,7 @@ import dyesSymbol from "./symbols/dyes.png";
|
||||||
import elfSymbol from "./symbols/elf.png";
|
import elfSymbol from "./symbols/elf.png";
|
||||||
import managementSymbol from "./symbols/elfManagement.png";
|
import managementSymbol from "./symbols/elfManagement.png";
|
||||||
import factorySymbol from "./symbols/gears.png";
|
import factorySymbol from "./symbols/gears.png";
|
||||||
|
import routingSymbol from "./symbols/gps.png";
|
||||||
import lettersSymbol from "./symbols/letterbox.png";
|
import lettersSymbol from "./symbols/letterbox.png";
|
||||||
import metalSymbol from "./symbols/metal.png";
|
import metalSymbol from "./symbols/metal.png";
|
||||||
import oilSymbol from "./symbols/oil.png";
|
import oilSymbol from "./symbols/oil.png";
|
||||||
|
@ -54,14 +59,15 @@ import plasticSymbol from "./symbols/plastic.png";
|
||||||
import presentsSymbol from "./symbols/presents.png";
|
import presentsSymbol from "./symbols/presents.png";
|
||||||
import reindeerSymbol from "./symbols/reindeer.png";
|
import reindeerSymbol from "./symbols/reindeer.png";
|
||||||
import ribbonsSymbol from "./symbols/ribbons.png";
|
import ribbonsSymbol from "./symbols/ribbons.png";
|
||||||
|
import packingSymbol from "./symbols/santasSack.png";
|
||||||
|
import sleighSymbol from "./symbols/sleigh.png";
|
||||||
|
import snowflakeSymbol from "./symbols/snowflake.svg";
|
||||||
import workshopSymbol from "./symbols/sws.png";
|
import workshopSymbol from "./symbols/sws.png";
|
||||||
import advFactorySymbol from "./symbols/teddyBear.png";
|
import advFactorySymbol from "./symbols/teddyBear.png";
|
||||||
import treeSymbol from "./symbols/tree.png";
|
import treeSymbol from "./symbols/tree.png";
|
||||||
import toysSymbol from "./symbols/truck.png";
|
import toysSymbol from "./symbols/truck.png";
|
||||||
import advManagementSymbol from "./symbols/workshopMansion.png";
|
import advManagementSymbol from "./symbols/workshopMansion.png";
|
||||||
import wrappingPaperSymbol from "./symbols/wrappingPaper.png";
|
import wrappingPaperSymbol from "./symbols/wrappingPaper.png";
|
||||||
import sleighSymbol from "./symbols/sleigh.png";
|
|
||||||
import routingSymbol from "./symbols/gps.png";
|
|
||||||
|
|
||||||
export interface Day extends VueFeature {
|
export interface Day extends VueFeature {
|
||||||
day: number;
|
day: number;
|
||||||
|
@ -73,10 +79,13 @@ export interface Day extends VueFeature {
|
||||||
opened: Persistent<boolean>;
|
opened: Persistent<boolean>;
|
||||||
recentlyUpdated: Ref<boolean>; // Has the tab recieved an update since the player last opened it?
|
recentlyUpdated: Ref<boolean>; // Has the tab recieved an update since the player last opened it?
|
||||||
shouldNotify: ProcessedComputable<boolean>;
|
shouldNotify: ProcessedComputable<boolean>;
|
||||||
|
visibility?: Visibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const main = createLayer("main", function (this: BaseLayer) {
|
export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
const day = persistent<number>(1);
|
const day = persistent<number>(1);
|
||||||
|
const hasWon = persistent<boolean>(false);
|
||||||
|
|
||||||
const timeUntilNewDay = computed(
|
const timeUntilNewDay = computed(
|
||||||
() => (+new Date(new Date().getFullYear(), 11, day.value) - player.time) / 1000
|
() => (+new Date(new Date().getFullYear(), 11, day.value) - player.time) / 1000
|
||||||
);
|
);
|
||||||
|
@ -86,6 +95,90 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
const loreTitle = ref<string>("");
|
const loreTitle = ref<string>("");
|
||||||
const loreBody = ref<CoercableComponent | undefined>();
|
const loreBody = ref<CoercableComponent | undefined>();
|
||||||
|
|
||||||
|
const creditsOpen = ref<boolean>(false);
|
||||||
|
|
||||||
|
// I don't understand how this works
|
||||||
|
const particles = createParticles(() => ({
|
||||||
|
boundingRect: ref<null | DOMRect>(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(() =>
|
const currentlyMastering = computed(() =>
|
||||||
isMastery.value
|
isMastery.value
|
||||||
? Object.values(layers).find(
|
? Object.values(layers).find(
|
||||||
|
@ -168,6 +261,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
story: string;
|
story: string;
|
||||||
completedStory: string;
|
completedStory: string;
|
||||||
masteredStory: string;
|
masteredStory: string;
|
||||||
|
visibility?: Visibility;
|
||||||
}
|
}
|
||||||
): Day {
|
): Day {
|
||||||
const opened = persistent<boolean>(false);
|
const opened = persistent<boolean>(false);
|
||||||
|
@ -197,7 +291,8 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
story,
|
story,
|
||||||
completedStory,
|
completedStory,
|
||||||
masteredStory,
|
masteredStory,
|
||||||
recentlyUpdated
|
recentlyUpdated,
|
||||||
|
visibility
|
||||||
} = this;
|
} = this;
|
||||||
|
|
||||||
const mastered: Ref<boolean> =
|
const mastered: Ref<boolean> =
|
||||||
|
@ -210,6 +305,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
recentlyUpdated,
|
recentlyUpdated,
|
||||||
shouldNotify,
|
shouldNotify,
|
||||||
mastered,
|
mastered,
|
||||||
|
visibility,
|
||||||
onOpenLore() {
|
onOpenLore() {
|
||||||
const completed = main.day.value > day;
|
const completed = main.day.value > day;
|
||||||
loreScene.value = completed ? day - 1 : -1;
|
loreScene.value = completed ? day - 1 : -1;
|
||||||
|
@ -230,6 +326,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
showLoreModal.value = true;
|
showLoreModal.value = true;
|
||||||
},
|
},
|
||||||
onOpenLayer() {
|
onOpenLayer() {
|
||||||
|
if (day == 25) return;
|
||||||
recentlyUpdated.value = false;
|
recentlyUpdated.value = false;
|
||||||
// 1468 is because two tabs with minWidth of 700px plus the minimized calendar of 60px plus 2 dividers of 4px each
|
// 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) {
|
if (window.matchMedia("(min-width: 1468px)").matches) {
|
||||||
|
@ -248,11 +345,14 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
layers[layer ?? "trees"]!.minimized.value = false;
|
layers[layer ?? "trees"]!.minimized.value = false;
|
||||||
},
|
},
|
||||||
onUnlockLayer() {
|
onUnlockLayer() {
|
||||||
if (layer != null) {
|
if (layer != null || day == 25) {
|
||||||
opened.value = true;
|
opened.value = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
loreScene.value = -1;
|
loreScene.value = -1;
|
||||||
loreTitle.value = unref(layers[layer ?? "trees"]?.name ?? "");
|
loreTitle.value =
|
||||||
|
day == 25
|
||||||
|
? "The End!"
|
||||||
|
: unref(layers[layer ?? "trees"]?.name ?? "");
|
||||||
loreBody.value = story;
|
loreBody.value = story;
|
||||||
if (player.autoPause) player.devSpeed = null;
|
if (player.autoPause) player.devSpeed = null;
|
||||||
showLoreModal.value = true;
|
showLoreModal.value = true;
|
||||||
|
@ -511,11 +611,22 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
createDay(() => ({
|
createDay(() => ({
|
||||||
day: 24,
|
day: 24,
|
||||||
shouldNotify: false,
|
shouldNotify: false,
|
||||||
layer: null, // "packing the presents"
|
layer: "packing",
|
||||||
symbol: "",
|
symbol: packingSymbol,
|
||||||
story: "",
|
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: "",
|
completedStory:
|
||||||
|
"At last, you've crammed in all the presents Santa needs. Santa can take it from here. Good Job!",
|
||||||
masteredStory: ""
|
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... <br><br> <div style='text-align: center'><img class='present-clickable' onclick ='layers.main.showLoreModal.value = false; layers.main.creditsOpen.value = true' src='${presentSymbol}' /><br>Open your present</div><br/>`,
|
||||||
|
completedStory: "",
|
||||||
|
masteredStory: "",
|
||||||
|
visibility: Visibility.None
|
||||||
}))
|
}))
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -548,6 +659,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 {
|
return {
|
||||||
name: "Calendar",
|
name: "Calendar",
|
||||||
days,
|
days,
|
||||||
|
@ -557,6 +678,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
loreScene,
|
loreScene,
|
||||||
loreTitle,
|
loreTitle,
|
||||||
loreBody,
|
loreBody,
|
||||||
|
particles,
|
||||||
showLoreModal,
|
showLoreModal,
|
||||||
completeDay,
|
completeDay,
|
||||||
completeMastery,
|
completeMastery,
|
||||||
|
@ -566,6 +688,9 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
swappingMastery,
|
swappingMastery,
|
||||||
currentlyMastering,
|
currentlyMastering,
|
||||||
masteredDays,
|
masteredDays,
|
||||||
|
creditsOpen,
|
||||||
|
credits,
|
||||||
|
hasWon,
|
||||||
display: jsx(() => (
|
display: jsx(() => (
|
||||||
<>
|
<>
|
||||||
{player.devSpeed === 0 ? <div>Game Paused</div> : null}
|
{player.devSpeed === 0 ? <div>Game Paused</div> : null}
|
||||||
|
@ -596,6 +721,19 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
)
|
)
|
||||||
.map((days: Day[]) => renderRow(...days))}
|
.map((days: Day[]) => renderRow(...days))}
|
||||||
</div>
|
</div>
|
||||||
|
{hasWon.value ? (
|
||||||
|
<>
|
||||||
|
<Spacer />
|
||||||
|
<button
|
||||||
|
class="button"
|
||||||
|
style="font-size: xx-large"
|
||||||
|
onClick={() => (creditsOpen.value = true)}
|
||||||
|
>
|
||||||
|
Open Credits
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
{render(particles)}
|
||||||
</>
|
</>
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
@ -629,7 +767,8 @@ export const getInitialLayers = (
|
||||||
factory,
|
factory,
|
||||||
reindeer,
|
reindeer,
|
||||||
sleigh,
|
sleigh,
|
||||||
routing
|
routing,
|
||||||
|
packing
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
BIN
src/data/symbols/santasSack.png
Normal file
BIN
src/data/symbols/santasSack.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
BIN
src/data/symbols/sleighWSack.png
Normal file
BIN
src/data/symbols/sleighWSack.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 73 KiB |
39
src/data/symbols/snowflake.svg
Normal file
39
src/data/symbols/snowflake.svg
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="50"
|
||||||
|
height="50"
|
||||||
|
viewBox="0 0 13.229166 13.229167"
|
||||||
|
version="1.1"
|
||||||
|
id="svg5"
|
||||||
|
inkscape:export-filename=".png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview7"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false" />
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
id="rect234"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.356532;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
d="M 6.2022054,1.0314616 V 2.4411947 L 5.0069295,1.7507975 4.5883504,2.4758179 6.2022054,3.4070272 V 5.7913778 L 4.1351481,4.5976522 4.1356649,2.7342 H 3.2985067 L 3.2990234,4.1149943 2.0779093,3.4101278 1.712557,4.0431641 2.9217855,4.7413127 1.7156576,5.4384277 2.1337199,6.1629313 3.7589437,5.2244873 5.7464193,6.3722209 3.7558431,7.5215047 2.1301025,6.5830607 1.7120402,7.3080811 2.9186849,8.0046794 1.7089396,8.702828 2.0748088,9.336381 3.2954061,8.6315145 V 10.011792 H 4.1325643 L 4.1320475,8.1483398 6.2280436,6.9380778 v 2.4463623 l -1.6252238,0.9384439 0.4185791,0.724504 1.2066447,-0.696599 v 1.396814 H 6.9592651 V 10.33787 L 8.154541,11.028267 8.5731201,10.303247 6.9592651,9.3720378 V 6.9876872 L 9.0263224,8.1814128 9.0258057,10.044865 H 9.8629639 L 9.8624471,8.6640706 11.083561,9.3689372 11.448914,8.7359009 10.239685,8.0377523 11.445813,7.3406372 11.027751,6.6161336 9.4025269,7.5545776 7.4150513,6.4068441 9.4056274,5.2575602 11.031368,6.1960042 11.44943,5.4709839 10.242786,4.7743856 11.452531,4.076237 11.086662,3.4426839 9.8660645,4.1475505 V 2.7672729 H 9.0289062 L 9.029423,4.6307251 6.9334269,5.8409871 V 3.3946248 L 8.5586507,2.4561808 8.1400716,1.7316772 6.9334269,2.4282756 v -1.396814 z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
|
@ -21,7 +21,7 @@ import type {
|
||||||
import { processComputable } from "util/computed";
|
import { processComputable } from "util/computed";
|
||||||
import { createLazyProxy } from "util/proxies";
|
import { createLazyProxy } from "util/proxies";
|
||||||
import { coerceComponent, isCoercableComponent } from "util/vue";
|
import { coerceComponent, isCoercableComponent } from "util/vue";
|
||||||
import type { Ref } from "vue";
|
import { isReadonly, Ref } from "vue";
|
||||||
import { computed, unref } from "vue";
|
import { computed, unref } from "vue";
|
||||||
|
|
||||||
export const BuyableType = Symbol("Buyable");
|
export const BuyableType = Symbol("Buyable");
|
||||||
|
@ -155,14 +155,18 @@ export function createBuyable<T extends BuyableOptions>(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const cost = unref(genericBuyable.cost);
|
const cost = unref(genericBuyable.cost);
|
||||||
if (genericBuyable.cost != null && genericBuyable.resource != null) {
|
if (
|
||||||
|
genericBuyable.cost != null &&
|
||||||
|
genericBuyable.resource != null &&
|
||||||
|
!isReadonly(genericBuyable.resource)
|
||||||
|
) {
|
||||||
genericBuyable.resource.value = Decimal.sub(
|
genericBuyable.resource.value = Decimal.sub(
|
||||||
genericBuyable.resource.value,
|
genericBuyable.resource.value,
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
cost!
|
cost!
|
||||||
);
|
);
|
||||||
genericBuyable.amount.value = Decimal.add(genericBuyable.amount.value, 1);
|
|
||||||
}
|
}
|
||||||
|
genericBuyable.amount.value = Decimal.add(genericBuyable.amount.value, 1);
|
||||||
genericBuyable.onPurchase?.(cost);
|
genericBuyable.onPurchase?.(cost);
|
||||||
};
|
};
|
||||||
processComputable(buyable as T, "display");
|
processComputable(buyable as T, "display");
|
||||||
|
|
|
@ -134,7 +134,8 @@ export async function loadSave(playerObj: Partial<PlayerData>): Promise<void> {
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
if (
|
if (
|
||||||
player.autosave &&
|
player.autosave &&
|
||||||
(layers as any).main.days[(layers as any).main.day.value - 1].opened.value
|
((layers as any).main.day.value >= 25 ||
|
||||||
|
(layers as any).main.days[(layers as any).main.day.value - 1].opened.value)
|
||||||
) {
|
) {
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
|
@ -142,7 +143,8 @@ setInterval(() => {
|
||||||
window.onbeforeunload = () => {
|
window.onbeforeunload = () => {
|
||||||
if (
|
if (
|
||||||
player.autosave &&
|
player.autosave &&
|
||||||
((layers as any).main.days[(layers as any).main.day.value - 1].opened.value ||
|
((layers as any).main.day.value >= 25 ||
|
||||||
|
(layers as any).main.days[(layers as any).main.day.value - 1].opened.value ||
|
||||||
import.meta.env.DEV)
|
import.meta.env.DEV)
|
||||||
) {
|
) {
|
||||||
save();
|
save();
|
||||||
|
|
Loading…
Reference in a new issue