mirror of
https://github.com/thepaperpilot/Advent-Incremental.git
synced 2024-11-21 08:12:41 +00:00
argh merge conflicts
This commit is contained in:
commit
a8e52bba9e
34 changed files with 1343 additions and 349 deletions
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
|
@ -6,7 +6,7 @@
|
|||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"git.ignoreLimitWarning": true,
|
||||
"[typescriptreact]": {
|
||||
"editor.defaultFormatter": "vscode.typescript-language-features"
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
}
|
|
@ -66,8 +66,9 @@ const useHeader = projInfo.useHeader;
|
|||
const loreBody = computeOptionalComponent(main.loreBody);
|
||||
|
||||
function gatherLayerProps(layer: GenericLayer) {
|
||||
const { display, minimized, minWidth, name, color, minimizable, nodes } = layer;
|
||||
return { display, minimized, minWidth, name, color, minimizable, nodes };
|
||||
const { display, minimized, minWidth, name, color, minimizable, nodes, minimizedDisplay } =
|
||||
layer;
|
||||
return { display, minimized, minWidth, name, color, minimizable, nodes, minimizedDisplay };
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
<div class="layer-container" :style="{ '--layer-color': unref(color) }">
|
||||
<button v-if="showGoBack" class="goBack" @click="goBack">❌</button>
|
||||
<button class="layer-tab minimized" v-if="minimized.value" @click="minimized.value = false">
|
||||
<div>{{ unref(name) }}</div>
|
||||
<component v-if="minimizedComponent" :is="minimizedComponent" />
|
||||
<div v-else>{{ unref(name) }}</div>
|
||||
</button>
|
||||
<div class="layer-tab" :class="{ showGoBack }" v-else>
|
||||
<Context @update-nodes="updateNodes">
|
||||
|
@ -21,7 +22,7 @@ import type { CoercableComponent } from "features/feature";
|
|||
import type { FeatureNode } from "game/layers";
|
||||
import type { Persistent } from "game/persistence";
|
||||
import player from "game/player";
|
||||
import { computeComponent, processedPropType, wrapRef } from "util/vue";
|
||||
import { computeComponent, computeOptionalComponent, processedPropType, wrapRef } from "util/vue";
|
||||
import type { PropType, Ref } from "vue";
|
||||
import { computed, defineComponent, nextTick, toRefs, unref, watch } from "vue";
|
||||
import Context from "./Context.vue";
|
||||
|
@ -41,6 +42,7 @@ export default defineComponent({
|
|||
type: processedPropType<CoercableComponent>(Object, String, Function),
|
||||
required: true
|
||||
},
|
||||
minimizedDisplay: processedPropType<CoercableComponent>(Object, String, Function),
|
||||
minimized: {
|
||||
type: Object as PropType<Persistent<boolean>>,
|
||||
required: true
|
||||
|
@ -61,9 +63,10 @@ export default defineComponent({
|
|||
}
|
||||
},
|
||||
setup(props) {
|
||||
const { display, index, minimized, minWidth, tab } = toRefs(props);
|
||||
const { display, index, minimized, minWidth, tab, minimizedDisplay } = toRefs(props);
|
||||
|
||||
const component = computeComponent(display);
|
||||
const minimizedComponent = computeOptionalComponent(minimizedDisplay);
|
||||
const showGoBack = computed(
|
||||
() => projInfo.allowGoBack && index.value > 0 && !minimized.value
|
||||
);
|
||||
|
@ -106,6 +109,7 @@ export default defineComponent({
|
|||
|
||||
return {
|
||||
component,
|
||||
minimizedComponent,
|
||||
showGoBack,
|
||||
updateNodes,
|
||||
unref,
|
||||
|
@ -155,7 +159,7 @@ export default defineComponent({
|
|||
background-color: transparent;
|
||||
}
|
||||
|
||||
.layer-tab.minimized div {
|
||||
.layer-tab.minimized > * {
|
||||
margin: 0;
|
||||
writing-mode: vertical-rl;
|
||||
padding-left: 10px;
|
||||
|
|
|
@ -1,16 +1,31 @@
|
|||
<template>
|
||||
<Modal v-model="isOpen">
|
||||
<template v-slot:header>
|
||||
<h2>Options</h2>
|
||||
<h2>Settings</h2>
|
||||
<div class="option-tabs">
|
||||
<button :class="{ selected: isTab('behaviour') }" @click="setTab('behaviour')">
|
||||
Behaviour
|
||||
</button>
|
||||
<button :class="{ selected: isTab('appearance') }" @click="setTab('appearance')">
|
||||
Appearance
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:body>
|
||||
<Select title="Theme" :options="themes" v-model="theme" />
|
||||
<component :is="settingFieldsComponent" />
|
||||
<Toggle title="Show TPS" v-model="showTPS" />
|
||||
<hr />
|
||||
<div v-if="isTab('behaviour')">
|
||||
<Toggle :title="autosaveTitle" v-model="autosave" />
|
||||
<FeedbackButton v-if="!autosave" class="button save-button" @click="save()"
|
||||
>Manually save</FeedbackButton
|
||||
>
|
||||
<Toggle v-if="projInfo.enablePausing" :title="isPausedTitle" v-model="isPaused" />
|
||||
</div>
|
||||
<div v-if="isTab('appearance')">
|
||||
<Select :title="themeTitle" :options="themes" v-model="theme" />
|
||||
<component :is="settingFieldsComponent" />
|
||||
<Toggle :title="showTPSTitle" v-model="showTPS" />
|
||||
<Toggle :title="progressMethodTitle" v-model="usingLog" />
|
||||
<Toggle :title="alignModifierUnitsTitle" v-model="alignUnits" />
|
||||
</div>
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
||||
|
@ -24,19 +39,36 @@ import Tooltip from "features/tooltips/Tooltip.vue";
|
|||
import player from "game/player";
|
||||
import settings, { settingFields } from "game/settings";
|
||||
import { camelToTitle } from "util/common";
|
||||
import { save } from "util/save";
|
||||
import { coerceComponent, render } from "util/vue";
|
||||
import { computed, ref, toRefs } from "vue";
|
||||
import Select from "./fields/Select.vue";
|
||||
import Toggle from "./fields/Toggle.vue";
|
||||
import FeedbackButton from "./fields/FeedbackButton.vue";
|
||||
|
||||
const isOpen = ref(false);
|
||||
|
||||
const currentTab = ref("behaviour");
|
||||
|
||||
defineExpose({
|
||||
isTab,
|
||||
setTab,
|
||||
save() {
|
||||
save();
|
||||
},
|
||||
open() {
|
||||
isOpen.value = true;
|
||||
}
|
||||
});
|
||||
|
||||
function isTab(tab: string): boolean {
|
||||
return tab == currentTab.value;
|
||||
}
|
||||
|
||||
function setTab(tab: string) {
|
||||
currentTab.value = tab;
|
||||
}
|
||||
|
||||
const themes = Object.keys(rawThemes).map(theme => ({
|
||||
label: camelToTitle(theme),
|
||||
value: theme
|
||||
|
@ -46,8 +78,10 @@ const settingFieldsComponent = computed(() => {
|
|||
return coerceComponent(jsx(() => <>{settingFields.map(render)}</>));
|
||||
});
|
||||
|
||||
const { showTPS, theme } = toRefs(settings);
|
||||
const { autosave, usingLog } = toRefs(player);
|
||||
const { showTPS, theme, usingLog, alignUnits } = toRefs(settings);
|
||||
|
||||
const { autosave, autoPause } = toRefs(player);
|
||||
|
||||
const isPaused = computed({
|
||||
get() {
|
||||
return player.devSpeed === 0;
|
||||
|
@ -58,26 +92,86 @@ const isPaused = computed({
|
|||
});
|
||||
|
||||
const autosaveTitle = jsx(() => (
|
||||
<span>
|
||||
<span class="option-title">
|
||||
Autosave<Tooltip display="Save-specific">*</Tooltip>
|
||||
<desc>Automatically save the game every second or when the game is closed.</desc>
|
||||
</span>
|
||||
));
|
||||
const isPausedTitle = jsx(() => (
|
||||
<span>
|
||||
<span class="option-title">
|
||||
Pause game<Tooltip display="Save-specific">*</Tooltip>
|
||||
<desc>Stop everything from moving.</desc>
|
||||
</span>
|
||||
));
|
||||
const autoPauseTitle = jsx(() => (
|
||||
<span class="option-title">
|
||||
Auto-pause<Tooltip display="Save-specific">*</Tooltip>
|
||||
<desc>
|
||||
Automatically pause the game when a day is completed. It is best to keep this on to
|
||||
avoid over-grinding.
|
||||
</desc>
|
||||
</span>
|
||||
));
|
||||
|
||||
const themeTitle = jsx(() => (
|
||||
<span class="option-title">
|
||||
Theme
|
||||
<desc>How the game looks.</desc>
|
||||
</span>
|
||||
));
|
||||
const showTPSTitle = jsx(() => (
|
||||
<span class="option-title">
|
||||
Show TPS
|
||||
<desc>Show TPS meter at the bottom-left corner of the page.</desc>
|
||||
</span>
|
||||
));
|
||||
const progressMethodTitle = jsx(() => (
|
||||
<span>
|
||||
Use log for progress bar<Tooltip display="Save-specific">*</Tooltip>
|
||||
<span class="option-title">
|
||||
Logarithmic progress bars
|
||||
<desc>Whether progress bars should be normalized for exponential growth.</desc>
|
||||
</span>
|
||||
));
|
||||
const alignModifierUnitsTitle = jsx(() => (
|
||||
<span class="option-title">
|
||||
Align modifier units
|
||||
<desc>Align numbers to the beginning of the unit in modifier view.</desc>
|
||||
</span>
|
||||
));
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style>
|
||||
.option-tabs {
|
||||
border-bottom: 2px solid var(--outline);
|
||||
}
|
||||
|
||||
*:deep() .tooltip-container {
|
||||
.option-tabs button {
|
||||
background-color: transparent;
|
||||
color: var(--foreground);
|
||||
margin-bottom: -2px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
padding: 5px 20px;
|
||||
border: none;
|
||||
border-bottom: 2px solid var(--foreground);
|
||||
}
|
||||
|
||||
.option-tabs button:not(.selected) {
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
|
||||
.option-title .tooltip-container {
|
||||
display: inline;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.option-title desc {
|
||||
display: block;
|
||||
opacity: 0.6;
|
||||
font-size: small;
|
||||
width: 300px;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.save-button {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -8,10 +8,13 @@
|
|||
}
|
||||
|
||||
.modifier-amount {
|
||||
flex-basis: 100px;
|
||||
flex-shrink: 0;
|
||||
text-align: right;
|
||||
}
|
||||
:not(:first-of-type, :last-of-type) > .modifier-amount::after {
|
||||
content: var(--unit);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.modifier-description {
|
||||
flex-grow: 1;
|
||||
|
|
|
@ -87,6 +87,10 @@ function onUpdate(value: SelectOption) {
|
|||
background-color: var(--bought);
|
||||
}
|
||||
|
||||
.vue-input input {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.vue-input input::placeholder {
|
||||
color: var(--link);
|
||||
}
|
||||
|
|
|
@ -44,14 +44,16 @@ input {
|
|||
|
||||
span {
|
||||
width: 100%;
|
||||
padding-right: 41px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* track */
|
||||
input + span::before {
|
||||
content: "";
|
||||
float: right;
|
||||
margin: 5px 0 5px 10px;
|
||||
position: absolute;
|
||||
top: calc(50% - 7px);
|
||||
right: 0px;
|
||||
border-radius: 7px;
|
||||
width: 36px;
|
||||
height: 14px;
|
||||
|
@ -66,7 +68,7 @@ input + span::before {
|
|||
input + span::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
top: calc(50% - 10px);
|
||||
right: 16px;
|
||||
border-radius: 50%;
|
||||
width: 20px;
|
||||
|
|
|
@ -7,7 +7,27 @@
|
|||
style="left: 4%; bottom: 3%; width: 40px; height: 40px"
|
||||
/>
|
||||
<img v-if="day >= 0" :src="tree" class="scene-item" style="left: 10%; bottom: 10%" />
|
||||
<img v-if="day >= 1" :src="workshop" class="scene-item" style="left: 40%; bottom: 12%" />
|
||||
<img
|
||||
v-if="day >= 12"
|
||||
:src="advManagement"
|
||||
class="scene-item"
|
||||
style="left: 33%; bottom: 12%; width: 30%; height: 60%"
|
||||
/>
|
||||
<template v-else>
|
||||
<img
|
||||
v-if="day >= 11"
|
||||
:src="management"
|
||||
class="scene-item"
|
||||
style="left: 28%; bottom: 12%"
|
||||
/>
|
||||
<img
|
||||
v-if="day >= 1"
|
||||
:src="workshop"
|
||||
class="scene-item"
|
||||
style="left: 40%; bottom: 12%"
|
||||
/>
|
||||
<img v-if="day >= 3" :src="elves" class="scene-item" style="left: 52%; bottom: 12%" />
|
||||
</template>
|
||||
<img
|
||||
v-if="day >= 2"
|
||||
:src="coal"
|
||||
|
@ -21,8 +41,11 @@
|
|||
style="left: 72%; bottom: 8%; width: 40px; height: 40px"
|
||||
/>
|
||||
<img v-if="day >= 8" :src="oil" class="scene-item" style="left: 80%; bottom: 6%" />
|
||||
<img v-if="day >= 3" :src="elves" class="scene-item" style="left: 52%; bottom: 12%" />
|
||||
<div v-if="day >= 4" class="scene-bubble" style="left: 50%; bottom: 38%">
|
||||
<div
|
||||
v-if="day >= 4"
|
||||
class="scene-bubble"
|
||||
:style="day >= 12 ? `left: 33%; bottom: 73%` : `left: 50%; bottom: 38%`"
|
||||
>
|
||||
<img v-if="day >= 4" :src="paper" class="scene-item" />
|
||||
<img v-if="day >= 5" :src="boxes" class="scene-item" />
|
||||
<img v-if="day >= 9" :src="plastic" class="scene-item" />
|
||||
|
@ -43,6 +66,8 @@ import cloth from "./symbols/cloth.png";
|
|||
import oil from "./symbols/oil.png";
|
||||
import plastic from "./symbols/plastic.png";
|
||||
import dyes from "./symbols/dyes.png";
|
||||
import management from "./symbols/elfManagement.png";
|
||||
import advManagement from "./symbols/workshopMansion.png";
|
||||
|
||||
defineProps<{
|
||||
day: number;
|
||||
|
@ -52,8 +77,9 @@ defineProps<{
|
|||
<style scoped>
|
||||
.scene {
|
||||
width: 600px;
|
||||
height: 300px;
|
||||
position: relative;
|
||||
max-width: 95%;
|
||||
aspect-ratio: 2/1;
|
||||
}
|
||||
|
||||
.scene::after {
|
||||
|
@ -69,8 +95,8 @@ defineProps<{
|
|||
}
|
||||
|
||||
.scene-item {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
width: 13.3%;
|
||||
height: 26.6%;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
|
@ -78,7 +104,7 @@ defineProps<{
|
|||
.scene-bubble {
|
||||
position: absolute;
|
||||
background: white;
|
||||
height: 60px;
|
||||
height: 20%;
|
||||
padding: 5px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
@ -96,8 +122,9 @@ defineProps<{
|
|||
}
|
||||
|
||||
.scene-bubble .scene-item {
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
height: calc(100% - 10px);
|
||||
width: unset;
|
||||
aspect-ratio: 1/1;
|
||||
position: static;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -20,6 +20,7 @@ import type { Modifier } from "game/modifiers";
|
|||
import type { Persistent } from "game/persistence";
|
||||
import { DefaultValue, persistent } from "game/persistence";
|
||||
import player from "game/player";
|
||||
import settings from "game/settings";
|
||||
import type { DecimalSource } from "util/bignum";
|
||||
import Decimal, { format } from "util/bignum";
|
||||
import { formatWhole } from "util/break_eternity";
|
||||
|
@ -333,7 +334,7 @@ export function createCollapsibleModifierSections(
|
|||
return (
|
||||
<>
|
||||
{hasPreviousSection ? <br /> : null}
|
||||
<div>
|
||||
<div style={{"--unit": settings.alignUnits && s.unit ? "'" + s.unit + "'" : ""}}>
|
||||
{header}
|
||||
<br />
|
||||
{modifiers}
|
||||
|
@ -424,7 +425,7 @@ export function setUpDailyProgressTracker(options: {
|
|||
if (main.day.value !== options.day) return 1;
|
||||
let progress = Decimal.add(total.value, 1);
|
||||
let requirement = options.goal;
|
||||
if (options.usingLog?.value ?? player.usingLog) {
|
||||
if (options.usingLog?.value ?? settings.usingLog) {
|
||||
progress = progress.log10();
|
||||
requirement = Decimal.log10(requirement);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,12 @@ import { createResource, displayResource, Resource } from "features/resources/re
|
|||
import { createUpgrade, GenericUpgrade } from "features/upgrades/upgrade";
|
||||
import { globalBus } from "game/events";
|
||||
import { BaseLayer, createLayer } from "game/layers";
|
||||
import { createExponentialModifier, createSequentialModifier, Modifier } from "game/modifiers";
|
||||
import {
|
||||
createExponentialModifier,
|
||||
createMultiplicativeModifier,
|
||||
createSequentialModifier,
|
||||
Modifier
|
||||
} from "game/modifiers";
|
||||
import { noPersist } from "game/persistence";
|
||||
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
|
||||
import { WithRequired } from "util/common";
|
||||
|
@ -26,8 +31,13 @@ import management from "./management";
|
|||
import paper from "./paper";
|
||||
import plastic from "./plastic";
|
||||
import trees from "./trees";
|
||||
import workshop from "./workshop";
|
||||
|
||||
export type BoxesBuyable = GenericBuyable & { resource: Resource; freeLevels: ComputedRef<DecimalSource>; totalAmount: ComputedRef<Decimal> };
|
||||
export type BoxesBuyable = GenericBuyable & {
|
||||
resource: Resource;
|
||||
freeLevels: ComputedRef<DecimalSource>;
|
||||
totalAmount: ComputedRef<Decimal>;
|
||||
};
|
||||
|
||||
const id = "boxes";
|
||||
const day = 6;
|
||||
|
@ -38,6 +48,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
const boxes = createResource<DecimalSource>(0, "boxes");
|
||||
|
||||
const boxGain = createSequentialModifier(() => [
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: 2,
|
||||
description: "1000% Foundation Completed",
|
||||
enabled: workshop.milestones.extraExpansionMilestone5.earned
|
||||
})),
|
||||
createExponentialModifier(() => ({
|
||||
exponent: 1.1,
|
||||
description: "Bell Level 2",
|
||||
|
@ -178,7 +193,19 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
const logBoxesBuyable = createBuyable(() => ({
|
||||
display: {
|
||||
title: "Carry more logs",
|
||||
description: jsx(() => <>Use boxes to carry even more logs, boosting their gain<br /><br /><div>Amount: {formatWhole(logBoxesBuyable.amount.value)}{Decimal.gt(logBoxesBuyable.freeLevels.value, 0) ? <> (+{formatWhole(logBoxesBuyable.freeLevels.value)})</> : null}</div></>),
|
||||
description: jsx(() => (
|
||||
<>
|
||||
Use boxes to carry even more logs, boosting their gain
|
||||
<br />
|
||||
<br />
|
||||
<div>
|
||||
Amount: {formatWhole(logBoxesBuyable.amount.value)}
|
||||
{Decimal.gt(logBoxesBuyable.freeLevels.value, 0) ? (
|
||||
<> (+{formatWhole(logBoxesBuyable.freeLevels.value)})</>
|
||||
) : null}
|
||||
</div>
|
||||
</>
|
||||
)),
|
||||
effectDisplay: jsx(() => (
|
||||
<>{format(Decimal.div(logBoxesBuyable.totalAmount.value, 2).add(1))}x</>
|
||||
)),
|
||||
|
@ -195,13 +222,34 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
return Decimal.pow(scaling, v).times(100).div(dyes.boosts.orange2.value);
|
||||
},
|
||||
visibility: () => showIf(logsUpgrade.bought.value),
|
||||
freeLevels: computed(() => management.elfTraining.boxElfTraining.milestones[0].earned.value ? Decimal.max(ashBoxesBuyable.amount.value, 1).sqrt().floor().add(Decimal.max(coalBoxesBuyable.amount.value, 1).sqrt().floor()) : 0),
|
||||
totalAmount: computed(() => Decimal.add(logBoxesBuyable.amount.value, logBoxesBuyable.freeLevels.value))
|
||||
freeLevels: computed(() =>
|
||||
management.elfTraining.boxElfTraining.milestones[0].earned.value
|
||||
? Decimal.max(ashBoxesBuyable.amount.value, 1)
|
||||
.sqrt()
|
||||
.floor()
|
||||
.add(Decimal.max(coalBoxesBuyable.amount.value, 1).sqrt().floor())
|
||||
: 0
|
||||
),
|
||||
totalAmount: computed(() =>
|
||||
Decimal.add(logBoxesBuyable.amount.value, logBoxesBuyable.freeLevels.value)
|
||||
)
|
||||
})) as BoxesBuyable;
|
||||
const ashBoxesBuyable = createBuyable(() => ({
|
||||
display: {
|
||||
title: "Carry more ash",
|
||||
description: jsx(() => <>Use boxes to carry even more ash, boosting its gain<br /><br /><div>Amount: {formatWhole(ashBoxesBuyable.amount.value)}{Decimal.gt(ashBoxesBuyable.freeLevels.value, 0) ? <> (+{formatWhole(ashBoxesBuyable.freeLevels.value)})</> : null}</div></>),
|
||||
description: jsx(() => (
|
||||
<>
|
||||
Use boxes to carry even more ash, boosting its gain
|
||||
<br />
|
||||
<br />
|
||||
<div>
|
||||
Amount: {formatWhole(ashBoxesBuyable.amount.value)}
|
||||
{Decimal.gt(ashBoxesBuyable.freeLevels.value, 0) ? (
|
||||
<> (+{formatWhole(ashBoxesBuyable.freeLevels.value)})</>
|
||||
) : null}
|
||||
</div>
|
||||
</>
|
||||
)),
|
||||
effectDisplay: jsx(() => (
|
||||
<>{format(Decimal.div(ashBoxesBuyable.totalAmount.value, 2).add(1))}x</>
|
||||
)),
|
||||
|
@ -218,13 +266,34 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
return Decimal.pow(scaling, v).times(1000).div(dyes.boosts.orange2.value);
|
||||
},
|
||||
visibility: () => showIf(ashUpgrade.bought.value),
|
||||
freeLevels: computed(() => management.elfTraining.boxElfTraining.milestones[0].earned.value ? Decimal.max(logBoxesBuyable.amount.value, 1).sqrt().floor().add(Decimal.max(coalBoxesBuyable.amount.value, 1).sqrt().floor()) : 0),
|
||||
totalAmount: computed(() => Decimal.add(ashBoxesBuyable.amount.value, ashBoxesBuyable.freeLevels.value))
|
||||
freeLevels: computed(() =>
|
||||
management.elfTraining.boxElfTraining.milestones[0].earned.value
|
||||
? Decimal.max(logBoxesBuyable.amount.value, 1)
|
||||
.sqrt()
|
||||
.floor()
|
||||
.add(Decimal.max(coalBoxesBuyable.amount.value, 1).sqrt().floor())
|
||||
: 0
|
||||
),
|
||||
totalAmount: computed(() =>
|
||||
Decimal.add(ashBoxesBuyable.amount.value, ashBoxesBuyable.freeLevels.value)
|
||||
)
|
||||
})) as BoxesBuyable;
|
||||
const coalBoxesBuyable = createBuyable(() => ({
|
||||
display: {
|
||||
title: "Carry more coal",
|
||||
description: jsx(() => <>Use boxes to carry even more coal, boosting its gain<br /><br /><div>Amount: {formatWhole(coalBoxesBuyable.amount.value)}{Decimal.gt(coalBoxesBuyable.freeLevels.value, 0) ? <> (+{formatWhole(coalBoxesBuyable.freeLevels.value)})</> : null}</div></>),
|
||||
description: jsx(() => (
|
||||
<>
|
||||
Use boxes to carry even more coal, boosting its gain
|
||||
<br />
|
||||
<br />
|
||||
<div>
|
||||
Amount: {formatWhole(coalBoxesBuyable.amount.value)}
|
||||
{Decimal.gt(coalBoxesBuyable.freeLevels.value, 0) ? (
|
||||
<> (+{formatWhole(coalBoxesBuyable.freeLevels.value)})</>
|
||||
) : null}
|
||||
</div>
|
||||
</>
|
||||
)),
|
||||
effectDisplay: jsx(() => (
|
||||
<>{format(Decimal.div(coalBoxesBuyable.totalAmount.value, 2).add(1))}x</>
|
||||
)),
|
||||
|
@ -241,8 +310,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
return Decimal.pow(scaling, v).times(1000).div(dyes.boosts.orange2.value);
|
||||
},
|
||||
visibility: () => showIf(coalUpgrade.bought.value),
|
||||
freeLevels: computed(() => management.elfTraining.boxElfTraining.milestones[0].earned.value ? Decimal.max(logBoxesBuyable.amount.value, 1).sqrt().floor().add(Decimal.max(ashBoxesBuyable.amount.value, 1).sqrt().floor()) : 0),
|
||||
totalAmount: computed(() => Decimal.add(coalBoxesBuyable.amount.value, coalBoxesBuyable.freeLevels.value))
|
||||
freeLevels: computed(() =>
|
||||
management.elfTraining.boxElfTraining.milestones[0].earned.value
|
||||
? Decimal.max(logBoxesBuyable.amount.value, 1)
|
||||
.sqrt()
|
||||
.floor()
|
||||
.add(Decimal.max(ashBoxesBuyable.amount.value, 1).sqrt().floor())
|
||||
: 0
|
||||
),
|
||||
totalAmount: computed(() =>
|
||||
Decimal.add(coalBoxesBuyable.amount.value, coalBoxesBuyable.freeLevels.value)
|
||||
)
|
||||
})) as BoxesBuyable;
|
||||
const buyables = { logBoxesBuyable, ashBoxesBuyable, coalBoxesBuyable };
|
||||
|
||||
|
@ -261,7 +339,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
{
|
||||
title: "Boxes Gain",
|
||||
modifier: boxGain,
|
||||
base: 1
|
||||
base: () => boxesConversion.scaling.currentGain(boxesConversion)
|
||||
}
|
||||
]);
|
||||
const showModifiersModal = ref(false);
|
||||
|
@ -300,6 +378,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
row3Upgrades,
|
||||
buyables,
|
||||
minWidth: 700,
|
||||
generalTabCollapsed,
|
||||
display: jsx(() => (
|
||||
<>
|
||||
{render(trackerDisplay)}
|
||||
|
@ -308,10 +387,19 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
<Spacer />
|
||||
{render(makeBoxes)}
|
||||
<Spacer />
|
||||
{renderGrid(Object.values(upgrades), Object.values(row2Upgrades), Object.values(row3Upgrades))}
|
||||
{renderGrid(
|
||||
Object.values(upgrades),
|
||||
Object.values(row2Upgrades),
|
||||
Object.values(row3Upgrades)
|
||||
)}
|
||||
<Spacer />
|
||||
{renderRow(...Object.values(buyables))}
|
||||
</>
|
||||
)),
|
||||
minimizedDisplay: jsx(() => (
|
||||
<div>
|
||||
{name} - {format(boxes.value)} {boxes.displayName}
|
||||
</div>
|
||||
))
|
||||
};
|
||||
});
|
||||
|
|
|
@ -23,7 +23,7 @@ import {
|
|||
createSequentialModifier
|
||||
} from "game/modifiers";
|
||||
import { noPersist, persistent } from "game/persistence";
|
||||
import Decimal, { DecimalSource } from "util/bignum";
|
||||
import Decimal, { DecimalSource, format } from "util/bignum";
|
||||
import { formatWhole } from "util/break_eternity";
|
||||
import { Direction } from "util/common";
|
||||
import { render, renderCol, renderRow } from "util/vue";
|
||||
|
@ -34,6 +34,7 @@ import metal from "./metal";
|
|||
import paper from "./paper";
|
||||
import plastic from "./plastic";
|
||||
import trees from "./trees";
|
||||
import workshop from "./workshop";
|
||||
|
||||
const id = "cloth";
|
||||
const day = 8;
|
||||
|
@ -331,7 +332,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
}));
|
||||
const paperUpgrades = { paperUpgrade4, paperUpgrade3, paperUpgrade2, paperUpgrade1 };
|
||||
|
||||
const hollyEffect = computed(() => Decimal.add(trees.computedAutoCuttingAmount.value, 1).log10().add(1));
|
||||
const hollyEffect = computed(() =>
|
||||
Decimal.add(trees.computedAutoCuttingAmount.value, 1).root(9)
|
||||
);
|
||||
const gingersnapEffect = computed(() => Decimal.add(dyes.dyeSum.value, 10).log10());
|
||||
|
||||
const sheepGain = createSequentialModifier(() => [
|
||||
|
@ -358,6 +361,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
multiplier: hollyEffect,
|
||||
description: "Holly Level 3",
|
||||
enabled: management.elfTraining.cutterElfTraining.milestones[2].earned
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: 2,
|
||||
description: "1000% Foundation Completed",
|
||||
enabled: workshop.milestones.extraExpansionMilestone5.earned
|
||||
}))
|
||||
]);
|
||||
const computedSheepGain = computed(() => sheepGain.apply(1));
|
||||
|
@ -388,6 +396,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
multiplier: hollyEffect,
|
||||
description: "Holly Level 3",
|
||||
enabled: management.elfTraining.cutterElfTraining.milestones[2].earned
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: 2,
|
||||
description: "1000% Foundation Completed",
|
||||
enabled: workshop.milestones.extraExpansionMilestone5.earned
|
||||
}))
|
||||
]);
|
||||
const computedShearingAmount = computed(() => shearingAmount.apply(1));
|
||||
|
@ -418,6 +431,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
multiplier: hollyEffect,
|
||||
description: "Holly Level 3",
|
||||
enabled: management.elfTraining.cutterElfTraining.milestones[2].earned
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: 2,
|
||||
description: "1000% Foundation Completed",
|
||||
enabled: workshop.milestones.extraExpansionMilestone5.earned
|
||||
}))
|
||||
]);
|
||||
const computedSpinningAmount = computed(() => spinningAmount.apply(1));
|
||||
|
@ -557,6 +575,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
{renderCol(...Object.values(paperUpgrades))}
|
||||
</Row>
|
||||
</>
|
||||
)),
|
||||
minimizedDisplay: jsx(() => (
|
||||
<div>
|
||||
{name} - {format(cloth.value)} {cloth.displayName}
|
||||
</div>
|
||||
))
|
||||
};
|
||||
});
|
||||
|
|
|
@ -82,13 +82,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
|
||||
const activeFires = persistent<DecimalSource>(0);
|
||||
const fireLogs = computed(() => Decimal.times(activeFires.value, 1000));
|
||||
const fireCoal = computed(() => {
|
||||
let gain = Decimal.times(activeFires.value, 0.1);
|
||||
if (management.elfTraining.smallfireElfTraining.milestones[0].earned.value) {
|
||||
gain = gain.times(5);
|
||||
}
|
||||
return gain;
|
||||
});
|
||||
const fireCoal = computed(() => Decimal.times(activeFires.value, 0.1));
|
||||
const fireAsh = computed(() => {
|
||||
let gain = Decimal.times(activeFires.value, 50);
|
||||
if (management.elfTraining.smallfireElfTraining.milestones[0].earned.value) {
|
||||
|
@ -263,7 +257,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
Decimal.times(
|
||||
Decimal.pow(activeDrills.value, oil.row2Upgrades[1].bought.value ? 2 : 1),
|
||||
5e7
|
||||
).times(metal.efficientDrill.bought.value ? 2 : 1)
|
||||
)
|
||||
.times(metal.efficientDrill.bought.value ? 2 : 1)
|
||||
.times(management.elfTraining.smallfireElfTraining.milestones[2].earned.value ? 2 : 1)
|
||||
.times(management.elfTraining.bonfireElfTraining.milestones[2].earned.value ? 2 : 1)
|
||||
.times(management.elfTraining.kilnElfTraining.milestones[2].earned.value ? 2 : 1)
|
||||
|
@ -431,6 +426,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
|
||||
if (Decimal.gte(v, 2e6)) v = Decimal.pow(v, 2).div(2e6);
|
||||
v = Decimal.pow(0.95, paper.books.heatedCuttersBook.amount.value).times(v);
|
||||
if (management.elfTraining.heatedCutterElfTraining.milestones[0].earned.value) {
|
||||
v = Decimal.pow(0.95, paper.books.heatedCuttersBook.amount.value).times(v);
|
||||
}
|
||||
return Decimal.add(v, 1).pow(2.5).times(10);
|
||||
},
|
||||
display: {
|
||||
|
@ -451,7 +449,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
|
||||
if (Decimal.gte(v, 2e6)) v = Decimal.pow(v, 2).div(2e6);
|
||||
v = Decimal.pow(0.95, paper.books.heatedPlantersBook.amount.value).times(v);
|
||||
if (management.elfTraining.heatedPlantersElfTraining.milestones[0].earned.value) {
|
||||
if (management.elfTraining.heatedPlanterElfTraining.milestones[0].earned.value) {
|
||||
v = Decimal.pow(0.95, paper.books.heatedPlantersBook.amount.value).times(v);
|
||||
}
|
||||
return Decimal.add(v, 1).pow(2.5).times(10);
|
||||
|
@ -593,7 +591,13 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
enabled: boxes.upgrades.coalUpgrade.bought
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: () => Decimal.div(buildFire.amount.value, 10000).add(1),
|
||||
multiplier: () => {
|
||||
let v = buildFire.amount.value;
|
||||
if (management.elfTraining.smallfireElfTraining.milestones[0].earned.value) {
|
||||
v = Decimal.div(buildBonfire.amount.value, 10).add(v);
|
||||
}
|
||||
return Decimal.div(v, 10000).add(1);
|
||||
},
|
||||
description: "Small Fires Synergy",
|
||||
enabled: elves.elves.smallFireElf.bought
|
||||
})),
|
||||
|
@ -643,6 +647,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
multiplier: oil.extractorCoal,
|
||||
description: "Heavy Extractor",
|
||||
enabled: () => Decimal.gt(oil.activeExtractor.value, 0)
|
||||
})),
|
||||
createExponentialModifier(() => ({
|
||||
exponent: 1.05,
|
||||
description: "Jack Level 2",
|
||||
enabled: management.elfTraining.heatedCutterElfTraining.milestones[1].earned
|
||||
}))
|
||||
]) as WithRequired<Modifier, "description" | "revert">;
|
||||
const computedCoalGain = computed(() => coalGain.apply(0));
|
||||
|
@ -686,7 +695,13 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
enabled: boxes.upgrades.ashUpgrade.bought
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: () => Decimal.div(buildFire.amount.value, 1000).add(1),
|
||||
multiplier: () => {
|
||||
let v = buildFire.amount.value;
|
||||
if (management.elfTraining.smallfireElfTraining.milestones[0].earned.value) {
|
||||
v = Decimal.div(buildBonfire.amount.value, 100).add(v);
|
||||
}
|
||||
return Decimal.div(v, 1000).add(1);
|
||||
},
|
||||
description: "Small Fires Synergy",
|
||||
enabled: elves.elves.smallFireElf.bought
|
||||
})),
|
||||
|
@ -870,7 +885,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
<MainDisplay
|
||||
resource={coal}
|
||||
color={colorCoal}
|
||||
style="margin-bottom: 0"
|
||||
style={{marginBottom: 0}}
|
||||
resourceStyle={{textShadow: 'grey 0px 0px 10px'}}
|
||||
effectDisplay={
|
||||
Decimal.gt(computedCoalGain.value, 0)
|
||||
? `+${format(computedCoalGain.value)}/s`
|
||||
|
@ -942,6 +958,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
{renderGrid(row1upgrades, row2upgrades, row3upgrades)}
|
||||
{renderRow(...row3buyables)}
|
||||
</>
|
||||
)),
|
||||
minimizedDisplay: jsx(() => (
|
||||
<div>
|
||||
{name} - {format(coal.value)} {coal.displayName}
|
||||
</div>
|
||||
))
|
||||
};
|
||||
});
|
||||
|
|
|
@ -29,6 +29,8 @@ import boxes from "./boxes";
|
|||
import cloth from "./cloth";
|
||||
import coal from "./coal";
|
||||
import management from "./management";
|
||||
import metal from "./metal";
|
||||
import oil from "./oil";
|
||||
import paper from "./paper";
|
||||
import plastic from "./plastic";
|
||||
import trees from "./trees";
|
||||
|
@ -310,6 +312,74 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
enabled: elvesMilestone2.earned
|
||||
}))
|
||||
]);
|
||||
const miningDrillCooldown = createSequentialModifier(() => [
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: 2,
|
||||
description: "6 Elves Trained",
|
||||
enabled: elvesMilestone.earned
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: () => Decimal.times(paper.books.miningDrillBook.amount.value, 0.1).add(1),
|
||||
description: "Drills and Mills",
|
||||
enabled: () => Decimal.gt(paper.books.miningDrillBook.amount.value, 0)
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: 2,
|
||||
description: "10 Elves Trained",
|
||||
enabled: elvesMilestone2.earned
|
||||
}))
|
||||
]);
|
||||
const heavyDrillCooldown = createSequentialModifier(() => [
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: 2,
|
||||
description: "6 Elves Trained",
|
||||
enabled: elvesMilestone.earned
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: () => Decimal.times(paper.books.heavyDrillBook.amount.value, 0.1).add(1),
|
||||
description: "Deep in the Earth",
|
||||
enabled: () => Decimal.gt(paper.books.heavyDrillBook.amount.value, 0)
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: 2,
|
||||
description: "10 Elves Trained",
|
||||
enabled: elvesMilestone2.earned
|
||||
}))
|
||||
]);
|
||||
const oilCooldown = createSequentialModifier(() => [
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: 2,
|
||||
description: "6 Elves Trained",
|
||||
enabled: elvesMilestone.earned
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: () => Decimal.times(paper.books.oilBook.amount.value, 0.1).add(1),
|
||||
description: "Burning the Midnight Oil",
|
||||
enabled: () => Decimal.gt(paper.books.oilBook.amount.value, 0)
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: 2,
|
||||
description: "10 Elves Trained",
|
||||
enabled: elvesMilestone2.earned
|
||||
}))
|
||||
]);
|
||||
const metalCooldown = createSequentialModifier(() => [
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: 2,
|
||||
description: "6 Elves Trained",
|
||||
enabled: elvesMilestone.earned
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: () => Decimal.times(paper.books.metalBook.amount.value, 0.1).add(1),
|
||||
description: "Physical Metallurgy",
|
||||
enabled: () => Decimal.gt(paper.books.metalBook.amount.value, 0)
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: 2,
|
||||
description: "10 Elves Trained",
|
||||
enabled: elvesMilestone2.earned
|
||||
}))
|
||||
]);
|
||||
|
||||
const [generalTab, generalTabCollapsed] = createCollapsibleModifierSections(() => [
|
||||
{
|
||||
|
@ -395,6 +465,34 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
base: 10,
|
||||
unit: "/s",
|
||||
visible: elves.clothElf.bought
|
||||
},
|
||||
{
|
||||
title: "Peppermint Auto-Buy Frequency",
|
||||
modifier: miningDrillCooldown,
|
||||
base: 10,
|
||||
unit: "/s",
|
||||
visible: management.elfTraining.expandersElfTraining.milestones[3].earned
|
||||
},
|
||||
{
|
||||
title: "Frosty Auto-Buy Frequency",
|
||||
modifier: heavyDrillCooldown,
|
||||
base: 10,
|
||||
unit: "/s",
|
||||
visible: management.elfTraining.fertilizerElfTraining.milestones[4].earned.value
|
||||
},
|
||||
{
|
||||
title: "Cocoa Auto-Buy Frequency",
|
||||
modifier: oilCooldown,
|
||||
base: 10,
|
||||
unit: "/s",
|
||||
visible: management.elfTraining.heatedCutterElfTraining.milestones[4].earned.value
|
||||
},
|
||||
{
|
||||
title: "Twinkle Auto-Buy Frequency",
|
||||
modifier: metalCooldown,
|
||||
base: 10,
|
||||
unit: "/s",
|
||||
visible: management.elfTraining.expandersElfTraining.milestones[4].earned
|
||||
}
|
||||
]);
|
||||
const showModifiersModal = ref(false);
|
||||
|
@ -428,7 +526,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
customCost?: (amount: DecimalSource) => DecimalSource;
|
||||
hasToggle?: boolean;
|
||||
toggleDesc?: string;
|
||||
onAutoPurchase?: VoidFunction;
|
||||
onAutoPurchase?: (buyable: GenericBuyable & { resource: Resource }) => void;
|
||||
onPurchase?: VoidFunction; // Will get overriden by the custom onpurchase, but that's fine
|
||||
canBuy?: Computable<boolean>;
|
||||
buyMax?: Computable<boolean>;
|
||||
|
@ -461,7 +559,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
) {
|
||||
buyable.amount.value = Decimal.add(buyable.amount.value, 1);
|
||||
buyProgress.value = Decimal.sub(buyProgress.value, cooldown);
|
||||
options.onAutoPurchase?.();
|
||||
options.onAutoPurchase?.(buyable);
|
||||
} else {
|
||||
buyProgress.value = cooldown;
|
||||
break;
|
||||
|
@ -532,21 +630,24 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
description:
|
||||
"Holly will automatically purchase cutters you can afford, without actually spending any logs.",
|
||||
buyable: trees.row1Buyables[0],
|
||||
cooldownModifier: cutterCooldown
|
||||
cooldownModifier: cutterCooldown,
|
||||
buyMax: () => management.elfTraining.cutterElfTraining.milestones[1].earned.value
|
||||
});
|
||||
const plantersElf = createElf({
|
||||
name: "Ivy",
|
||||
description:
|
||||
"Ivy will automatically purchase planters you can afford, without actually spending any logs.",
|
||||
buyable: trees.row1Buyables[1],
|
||||
cooldownModifier: planterCooldown
|
||||
cooldownModifier: planterCooldown,
|
||||
buyMax: () => management.elfTraining.planterElfTraining.milestones[1].earned.value
|
||||
});
|
||||
const expandersElf = createElf({
|
||||
name: "Hope",
|
||||
description:
|
||||
"Hope will automatically purchase forest expanders you can afford, without actually spending any logs.",
|
||||
buyable: trees.row1Buyables[2],
|
||||
cooldownModifier: expanderCooldown
|
||||
cooldownModifier: expanderCooldown,
|
||||
buyMax: () => management.elfTraining.expandersElfTraining.milestones[1].earned.value
|
||||
});
|
||||
const treesElves = [cuttersElf, plantersElf, expandersElf];
|
||||
const heatedCuttersElf = createElf({
|
||||
|
@ -554,7 +655,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
description:
|
||||
"Jack will automatically purchase heated cutters you can afford, without actually spending any coal.",
|
||||
buyable: coal.heatedCutters,
|
||||
cooldownModifier: heatedCutterCooldown
|
||||
cooldownModifier: heatedCutterCooldown,
|
||||
buyMax: () => management.elfTraining.heatedCutterElfTraining.milestones[2].earned.value
|
||||
});
|
||||
const heatedPlantersElf = createElf({
|
||||
name: "Mary",
|
||||
|
@ -657,6 +759,77 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
visibility: () => showIf(plastic.elfUpgrades.clothElf.bought.value)
|
||||
});
|
||||
const plasticElves = [paperElf, boxElf, clothElf];
|
||||
const miningDrillElf = createElf({
|
||||
name: "Peppermint",
|
||||
description:
|
||||
"Peppermint will automatically purchase all mining drills you can afford, without actually spending any resources.",
|
||||
buyable: coal.buildDrill,
|
||||
cooldownModifier: miningDrillCooldown,
|
||||
visibility: () =>
|
||||
showIf(management.elfTraining.expandersElfTraining.milestones[3].earned.value),
|
||||
hasToggle: true,
|
||||
toggleDesc: "Activate auto-purchased mining drills",
|
||||
onAutoPurchase() {
|
||||
if (miningDrillElf.toggle.value) {
|
||||
coal.activeDrills.value = Decimal.add(coal.activeDrills.value, 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
const heavyDrillElf = createElf({
|
||||
name: "Frosty",
|
||||
description:
|
||||
"Frosty will automatically purchase all drill types in the oil section, without actually spending any resources.",
|
||||
buyable: [oil.buildHeavy, oil.buildHeavy2, oil.buildExtractor],
|
||||
cooldownModifier: heavyDrillCooldown,
|
||||
visibility: () =>
|
||||
showIf(management.elfTraining.fertilizerElfTraining.milestones[4].earned.value),
|
||||
hasToggle: true,
|
||||
toggleDesc: "Activate auto-purchased oil drills",
|
||||
onAutoPurchase(buyable) {
|
||||
if (heavyDrillElf.toggle.value) {
|
||||
if (buyable === oil.buildHeavy) {
|
||||
oil.activeHeavy.value = Decimal.add(oil.activeHeavy.value, 1);
|
||||
} else if (buyable === oil.buildHeavy) {
|
||||
oil.activeHeavy.value = Decimal.add(oil.activeHeavy.value, 1);
|
||||
} else if (buyable === oil.buildHeavy) {
|
||||
oil.activeHeavy.value = Decimal.add(oil.activeHeavy.value, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
const oilElf = createElf({
|
||||
name: "Cocoa",
|
||||
description:
|
||||
"Cocoa will automatically purchase all oil-using machines you can afford, without actually spending any resources.",
|
||||
buyable: [oil.buildPump, oil.buildBurner, oil.buildSmelter],
|
||||
cooldownModifier: oilCooldown,
|
||||
visibility: () =>
|
||||
showIf(management.elfTraining.heatedCutterElfTraining.milestones[4].earned.value),
|
||||
hasToggle: true,
|
||||
toggleDesc: "Activate auto-purchased oil-using machines",
|
||||
onAutoPurchase(buyable) {
|
||||
if (heavyDrillElf.toggle.value) {
|
||||
if (buyable === oil.buildPump) {
|
||||
oil.activePump.value = Decimal.add(oil.activePump.value, 1);
|
||||
} else if (buyable === oil.buildBurner) {
|
||||
oil.activeBurner.value = Decimal.add(oil.activeBurner.value, 1);
|
||||
} else if (buyable === oil.buildSmelter) {
|
||||
oil.activeSmelter.value = Decimal.add(oil.activeSmelter.value, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
const managementElves = [miningDrillElf, heavyDrillElf, oilElf];
|
||||
const metalElf = createElf({
|
||||
name: "Twinkle",
|
||||
description:
|
||||
"Twinkle will automatically purchase all metal buyables you can afford, without actually spending any resources.",
|
||||
buyable: [metal.oreDrill, metal.industrialCrucible, metal.hotterForge],
|
||||
cooldownModifier: metalCooldown,
|
||||
visibility: () =>
|
||||
showIf(management.elfTraining.expandersElfTraining.milestones[4].earned.value)
|
||||
});
|
||||
const managementElves2 = [metalElf];
|
||||
const elves = {
|
||||
cuttersElf,
|
||||
plantersElf,
|
||||
|
@ -669,7 +842,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
kilnElf,
|
||||
paperElf,
|
||||
boxElf,
|
||||
clothElf
|
||||
clothElf,
|
||||
miningDrillElf,
|
||||
heavyDrillElf,
|
||||
oilElf,
|
||||
metalElf
|
||||
};
|
||||
const totalElves = computed(() => Object.values(elves).filter(elf => elf.bought.value).length);
|
||||
|
||||
|
@ -849,7 +1026,14 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
{render(modifiersModal)}
|
||||
<Spacer />
|
||||
<div style="width: 600px">
|
||||
{renderGrid(treesElves, coalElves, fireElves, plasticElves)}
|
||||
{renderGrid(
|
||||
treesElves,
|
||||
coalElves,
|
||||
fireElves,
|
||||
plasticElves,
|
||||
managementElves,
|
||||
managementElves2
|
||||
)}
|
||||
</div>
|
||||
{milestonesDisplay()}
|
||||
</>
|
||||
|
|
|
@ -1,50 +1,41 @@
|
|||
import Spacer from "components/layout/Spacer.vue";
|
||||
import Sqrt from "components/math/Sqrt.vue";
|
||||
import Fraction from "components/math/Fraction.vue";
|
||||
import Sqrt from "components/math/Sqrt.vue";
|
||||
import Modal from "components/Modal.vue";
|
||||
import { createCollapsibleMilestones, createCollapsibleModifierSections } from "data/common";
|
||||
import { main } from "data/projEntry";
|
||||
import { createBar, GenericBar } from "features/bars/bar";
|
||||
import { createClickable, GenericClickable } from "features/clickables/clickable";
|
||||
import { jsx, JSXFunction, showIf } from "features/feature";
|
||||
import { createBuyable } from "features/buyable";
|
||||
import { createClickable } from "features/clickables/clickable";
|
||||
import { jsx, showIf } from "features/feature";
|
||||
import { createMilestone, GenericMilestone } from "features/milestones/milestone";
|
||||
import { createUpgrade } from "features/upgrades/upgrade";
|
||||
import { globalBus } from "game/events";
|
||||
import { createLayer } from "game/layers";
|
||||
import { Persistent, persistent } from "game/persistence";
|
||||
import {
|
||||
createAdditiveModifier,
|
||||
createMultiplicativeModifier,
|
||||
createSequentialModifier,
|
||||
Modifier
|
||||
} from "game/modifiers";
|
||||
import { persistent } from "game/persistence";
|
||||
import Decimal, { DecimalSource, format, formatTime, formatWhole } from "util/bignum";
|
||||
import { Direction } from "util/common";
|
||||
import { render, renderCol, renderGrid, renderRow } from "util/vue";
|
||||
import { computed, ComputedRef, ref, Ref } from "vue";
|
||||
import { createTabFamily } from "features/tabs/tabFamily";
|
||||
import { createTab } from "features/tabs/tab";
|
||||
import elves from "./elves";
|
||||
import trees from "./trees";
|
||||
import { globalBus } from "game/events";
|
||||
import { createMultiplicativeModifier, createSequentialModifier, Modifier } from "game/modifiers";
|
||||
import Modal from "components/Modal.vue";
|
||||
import { createBuyable, GenericBuyable } from "features/buyable";
|
||||
import { createUpgrade } from "features/upgrades/upgrade";
|
||||
import coal from "./coal";
|
||||
import paper from "./paper";
|
||||
import { render, renderCol, renderGrid } from "util/vue";
|
||||
import { computed, ComputedRef, ref, Ref, unref, watchEffect } from "vue";
|
||||
import boxes from "./boxes";
|
||||
import metal from "./metal";
|
||||
import cloth from "./cloth";
|
||||
import plastic from "./plastic";
|
||||
import coal from "./coal";
|
||||
import dyes from "./dyes";
|
||||
import elves from "./elves";
|
||||
import metal from "./metal";
|
||||
import paper from "./paper";
|
||||
import plastic from "./plastic";
|
||||
import trees from "./trees";
|
||||
|
||||
const id = "management";
|
||||
const day = 12;
|
||||
|
||||
interface ElfTrainingClickable extends GenericClickable {
|
||||
name: string,
|
||||
state: Persistent<boolean>,
|
||||
displayMilestone: JSXFunction,
|
||||
level: ComputedRef<number>,
|
||||
exp: Persistent<DecimalSource>,
|
||||
milestones: GenericMilestone[],
|
||||
timeForExp: ComputedRef<DecimalSource>,
|
||||
amountOfTimesDone: Ref<number>,
|
||||
elfXPGainComputed: ComputedRef<DecimalSource>,
|
||||
elfXPGain: Modifier,
|
||||
}
|
||||
const advancedDay = 13;
|
||||
|
||||
const layer = createLayer(id, () => {
|
||||
const name = "Management";
|
||||
|
@ -58,12 +49,24 @@ const layer = createLayer(id, () => {
|
|||
height: 25,
|
||||
fillStyle: `backgroundColor: ${color}`,
|
||||
progress: () =>
|
||||
main.day.value === day ? totalElfLevels.value / (elves.totalElves.value * 5) : 1,
|
||||
main.day.value === day
|
||||
? day12Elves.reduce((acc, curr) => acc + Math.min(1, curr.level.value / 3), 0) /
|
||||
day12Elves.length
|
||||
: main.day.value === advancedDay && main.days[advancedDay - 1].opened.value
|
||||
? day13Elves.reduce((acc, curr) => acc + Math.min(1, curr.level.value / 5), 0) /
|
||||
day13Elves.length
|
||||
: 1,
|
||||
display: jsx(() =>
|
||||
main.day.value === day ? (
|
||||
main.day.value === day ||
|
||||
(main.day.value === advancedDay && main.days[advancedDay - 1].opened.value) ? (
|
||||
<>
|
||||
{formatWhole(totalElfLevels.value)}/{formatWhole(elves.totalElves.value * 5)}{" "}
|
||||
elf levels
|
||||
{formatWhole(
|
||||
Decimal.times(
|
||||
unref(dayProgress.progress),
|
||||
main.day.value === advancedDay ? 80 : 36
|
||||
)
|
||||
)}
|
||||
/{main.day.value === advancedDay ? 80 : 36} elf levels
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
|
@ -78,7 +81,9 @@ const layer = createLayer(id, () => {
|
|||
}
|
||||
return elfLevel;
|
||||
});
|
||||
|
||||
const totalElfExp = computed(() =>
|
||||
Object.values(elfTraining).reduce((acc, curr) => acc.add(curr.exp.value), new Decimal(0))
|
||||
);
|
||||
|
||||
// ------------------------------------------------------------------------------- Upgrades
|
||||
|
||||
|
@ -105,12 +110,12 @@ const layer = createLayer(id, () => {
|
|||
}));
|
||||
const globalXPModifier = createSequentialModifier(() => [
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: () => classroomEffect.value,
|
||||
multiplier: classroomEffect,
|
||||
description: "Classroom Effect",
|
||||
enabled: () => classroomUpgrade.bought.value
|
||||
enabled: classroomUpgrade.bought
|
||||
}))
|
||||
]);
|
||||
const globalXPModifierComputed = globalXPModifier.apply(1);
|
||||
const globalXPModifierComputed = computed(() => globalXPModifier.apply(1));
|
||||
|
||||
// ------------------------------------------------------------------------------- Training core function
|
||||
|
||||
|
@ -124,15 +129,33 @@ const layer = createLayer(id, () => {
|
|||
...modifiers: Modifier[]
|
||||
) {
|
||||
const exp = persistent<DecimalSource>(0);
|
||||
const expRequiredForNextLevel = computed(() => Decimal.pow(10, level.value).mul(1e4));
|
||||
let costMulti =
|
||||
[
|
||||
"Holly",
|
||||
"Ivy",
|
||||
"Hope",
|
||||
"Jack",
|
||||
"Mary",
|
||||
"Noel",
|
||||
"Joy",
|
||||
"Faith",
|
||||
"Snowball",
|
||||
"Star",
|
||||
"Bell",
|
||||
"Gingersnap"
|
||||
].indexOf(elf.name) + 1;
|
||||
if (elf.name == "Star" || elf.name == "Bell") {
|
||||
costMulti /= 3;
|
||||
}
|
||||
const costBase = Decimal.mul(4000, costMulti);
|
||||
const expRequiredForNextLevel = computed(() => Decimal.pow(5, level.value).mul(costBase));
|
||||
const level = computed(() =>
|
||||
Decimal.min(
|
||||
Decimal.mul(9, exp.value).div(1e4).add(1).log10().floor(),
|
||||
schools.amount.value
|
||||
).toNumber()
|
||||
Decimal.affordGeometricSeries(exp.value, costBase, 5, 0)
|
||||
.min(schools.amount.value)
|
||||
.toNumber()
|
||||
);
|
||||
const expToNextLevel = computed(() =>
|
||||
Decimal.sub(exp.value, Decimal.pow(10, level.value).sub(1).div(9).mul(1e4))
|
||||
Decimal.sub(exp.value, Decimal.sumGeometricSeries(level.value, costBase, 5, 0))
|
||||
);
|
||||
const bar = createBar(() => ({
|
||||
direction: Direction.Right,
|
||||
|
@ -142,15 +165,22 @@ const layer = createLayer(id, () => {
|
|||
"margin-top": "8px",
|
||||
"box-shadow": focusTargets.value[elf.name]
|
||||
? "0 0 12px " + (currentShown.value == elf.name ? "black" : "white")
|
||||
: "",
|
||||
: ""
|
||||
}),
|
||||
baseStyle: "margin-top: 0",
|
||||
fillStyle: "margin-top: 0; transition-duration: 0s",
|
||||
borderStyle: () => Decimal.gte(level.value, schools.amount.value) ? "border-color: red" : "",
|
||||
borderStyle: () =>
|
||||
Decimal.gte(level.value, schools.amount.value) ? "border-color: red" : "",
|
||||
progress: () => Decimal.div(expToNextLevel.value, expRequiredForNextLevel.value),
|
||||
display: jsx(() => Decimal.gte(level.value, schools.amount.value)
|
||||
? <>Limit reached</>
|
||||
: <>{format(expToNextLevel.value)}/{format(expRequiredForNextLevel.value)} XP</>)
|
||||
display: jsx(() =>
|
||||
Decimal.gte(level.value, schools.amount.value) ? (
|
||||
<>Limit reached</>
|
||||
) : (
|
||||
<>
|
||||
{format(expToNextLevel.value)}/{format(expRequiredForNextLevel.value)} XP
|
||||
</>
|
||||
)
|
||||
)
|
||||
}));
|
||||
const { collapseMilestones: state, display: displayMilestone } =
|
||||
createCollapsibleMilestones(milestones as Record<number, GenericMilestone>);
|
||||
|
@ -162,20 +192,23 @@ const layer = createLayer(id, () => {
|
|||
createMultiplicativeModifier(() => ({
|
||||
multiplier: focusMulti,
|
||||
description: "Focus Multiplier",
|
||||
enabled: () => focusRolling.value <= 0 && focusTargets.value[elf.name] == true
|
||||
enabled: () =>
|
||||
Decimal.gt(focusTime.value, 0) && focusTargets.value[elf.name] == true
|
||||
})),
|
||||
...modifiers
|
||||
]);
|
||||
const elfXPGainComputed = computed(() => elfXPGain.apply(0.1));
|
||||
const click = createClickable(() => ({
|
||||
display: {
|
||||
title: elf.name,
|
||||
title: jsx(() => (
|
||||
<>
|
||||
{elf.name} - LV {formatWhole(level.value)}
|
||||
</>
|
||||
)),
|
||||
description: jsx(() => (
|
||||
<>
|
||||
{elf.name} is currently at level {formatWhole(level.value)}, and
|
||||
achieved a total of {format(exp.value)} XP.
|
||||
They buy buyables {formatWhole(elf.computedAutoBuyCooldown.value)} times per
|
||||
second, gaining{" "}
|
||||
{elf.name} can buy buyables {formatWhole(elf.computedAutoBuyCooldown.value)}{" "}
|
||||
times per second, gaining{" "}
|
||||
{Decimal.gte(level.value, schools.amount.value)
|
||||
? 0
|
||||
: format(
|
||||
|
@ -191,7 +224,7 @@ const layer = createLayer(id, () => {
|
|||
},
|
||||
style: () => ({
|
||||
width: "190px",
|
||||
background: currentShown.value == elf.name ? "var(--foreground)" : "",
|
||||
background: currentShown.value == elf.name ? "var(--foreground)" : ""
|
||||
}),
|
||||
onClick() {
|
||||
currentShown.value = elf.name;
|
||||
|
@ -219,7 +252,12 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Holly Level 1",
|
||||
effectDisplay: jsx(() => <>Multiply log gain by (<Sqrt>Cutter amount</Sqrt>)<sup>3</sup>.</>)
|
||||
effectDisplay: jsx(() => (
|
||||
<>
|
||||
Multiply log gain by <sup>9</sup>
|
||||
<Sqrt>Cutter amount</Sqrt>.
|
||||
</>
|
||||
))
|
||||
},
|
||||
shouldEarn: () => cutterElfTraining.level.value >= 1
|
||||
})),
|
||||
|
@ -234,7 +272,12 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Holly Level 3",
|
||||
effectDisplay: jsx(() => <>Multiply all cloth actions' effectiveness by (<Sqrt>Cutter amount</Sqrt>)<sup>3</sup>.</>)
|
||||
effectDisplay: jsx(() => (
|
||||
<>
|
||||
Multiply all cloth actions' effectiveness by log<sub>10</sub>(Cutter
|
||||
amount).
|
||||
</>
|
||||
))
|
||||
},
|
||||
visibility: () => showIf(cutterElfMilestones[1].earned.value),
|
||||
shouldEarn: () => cutterElfTraining.level.value >= 3
|
||||
|
@ -242,7 +285,7 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Holly Level 4",
|
||||
effectDisplay: "Multiply cutting speed by 1.1 per day completed"
|
||||
effectDisplay: "Multiply auto cutting amount by 1.1 per day completed"
|
||||
},
|
||||
visibility: () => showIf(cutterElfMilestones[2].earned.value && main.day.value >= 13),
|
||||
shouldEarn: () => cutterElfTraining.level.value >= 4
|
||||
|
@ -275,7 +318,14 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Ivy Level 3",
|
||||
effectDisplay: jsx(() => <>Planting speed is multiplied by 2<sup>(log<sub>10</sub>(logs)<sup>0.2</sup>)</sup></>)
|
||||
effectDisplay: jsx(() => (
|
||||
<>
|
||||
Auto planting speed is multiplied by 2
|
||||
<sup>
|
||||
(log<sub>10</sub>(logs)<sup>0.2</sup>)
|
||||
</sup>
|
||||
</>
|
||||
))
|
||||
},
|
||||
visibility: () => showIf(planterElfMilestones[1].earned.value),
|
||||
shouldEarn: () => planterElfTraining.level.value >= 3
|
||||
|
@ -291,7 +341,8 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Ivy Level 5",
|
||||
effectDisplay: "Boost planting/cutting speed based on which is falling behind"
|
||||
effectDisplay:
|
||||
"The lesser of auto planting and cutting amounts is increased to match the greater"
|
||||
},
|
||||
visibility: () => showIf(planterElfMilestones[3].earned.value && main.day.value >= 13),
|
||||
shouldEarn: () => planterElfTraining.level.value >= 5
|
||||
|
@ -301,7 +352,7 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Hope Level 1",
|
||||
effectDisplay: "Planting speed boosts forest size"
|
||||
effectDisplay: "Forest size grows by trees planted per second raised to ^0.99"
|
||||
},
|
||||
shouldEarn: () => expandersElfTraining.level.value >= 1
|
||||
})),
|
||||
|
@ -316,7 +367,8 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Hope Level 3",
|
||||
effectDisplay: "The workshop can be expanded past 100%, but costs scale faster."
|
||||
effectDisplay:
|
||||
"The workshop can be expanded past 100%, but costs scale faster. It also buys max now."
|
||||
},
|
||||
visibility: () => showIf(expanderElfMilestones[1].earned.value),
|
||||
shouldEarn: () => expandersElfTraining.level.value >= 3
|
||||
|
@ -342,7 +394,7 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Jack Level 1",
|
||||
effectDisplay: "Heated cutters are less expensive."
|
||||
effectDisplay: '"Fahrenheit 451" affects "Heated Cutters" twice.'
|
||||
},
|
||||
shouldEarn: () => heatedCutterElfTraining.level.value >= 1
|
||||
})),
|
||||
|
@ -365,7 +417,11 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Jack Level 4",
|
||||
effectDisplay: "Oil gain is multiplied based on total elf levels."
|
||||
effectDisplay: jsx(() => (
|
||||
<>
|
||||
Oil gain is multiplied by <Sqrt>total elf levels</Sqrt>.
|
||||
</>
|
||||
))
|
||||
},
|
||||
visibility: () =>
|
||||
showIf(heatedCutterElfMilestones[2].earned.value && main.day.value >= 13),
|
||||
|
@ -374,7 +430,7 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Jack Level 5",
|
||||
effectDisplay: "Unlock an elf that autobuys oil buyables."
|
||||
effectDisplay: "Unlock an elf that autobuys oil-using machines."
|
||||
},
|
||||
visibility: () =>
|
||||
showIf(heatedCutterElfMilestones[3].earned.value && main.day.value >= 13),
|
||||
|
@ -392,7 +448,7 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Mary Level 2",
|
||||
effectDisplay: "Double automatic tree planting speed"
|
||||
effectDisplay: "Metal gain is raised to the 1.1."
|
||||
},
|
||||
visibility: () => showIf(heatedPlanterElfMilestones[0].earned.value),
|
||||
shouldEarn: () => heatedPlanterElfTraining.level.value >= 2
|
||||
|
@ -408,7 +464,7 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Mary Level 4",
|
||||
effectDisplay: "Metal gain is raised to the 1.1."
|
||||
effectDisplay: "Double automatic tree planting speed"
|
||||
},
|
||||
visibility: () =>
|
||||
showIf(heatedPlanterElfMilestones[2].earned.value && main.day.value >= 13),
|
||||
|
@ -417,7 +473,11 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Mary Level 5",
|
||||
effectDisplay: jsx(() => <>Auto smelting speed is multiplied by <Sqrt>total XP/1000</Sqrt>.</>)
|
||||
effectDisplay: jsx(() => (
|
||||
<>
|
||||
Auto smelting speed is multiplied by <Sqrt>total XP/1000</Sqrt>.
|
||||
</>
|
||||
))
|
||||
},
|
||||
visibility: () =>
|
||||
showIf(heatedPlanterElfMilestones[3].earned.value && main.day.value >= 13),
|
||||
|
@ -428,9 +488,13 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Noel Level 1",
|
||||
effectDisplay: jsx(() => <>Log gain is multiplied by <Sqrt>total elf levels</Sqrt>.</>)
|
||||
effectDisplay: jsx(() => (
|
||||
<>
|
||||
Log gain is multiplied by <Sqrt>total elf levels</Sqrt>.
|
||||
</>
|
||||
))
|
||||
},
|
||||
shouldEarn: () => heatedPlanterElfTraining.level.value >= 1
|
||||
shouldEarn: () => fertilizerElfTraining.level.value >= 1
|
||||
})),
|
||||
createMilestone(() => ({
|
||||
display: {
|
||||
|
@ -438,7 +502,7 @@ const layer = createLayer(id, () => {
|
|||
effectDisplay: `"The Garden Tree's Handbook" affects "Fertilized Soil" twice`
|
||||
},
|
||||
visibility: () => showIf(fertilizerElfMilestones[0].earned.value),
|
||||
shouldEarn: () => heatedPlanterElfTraining.level.value >= 2
|
||||
shouldEarn: () => fertilizerElfTraining.level.value >= 2
|
||||
})),
|
||||
createMilestone(() => ({
|
||||
display: {
|
||||
|
@ -446,16 +510,20 @@ const layer = createLayer(id, () => {
|
|||
effectDisplay: "Divide the mining drill cost by ln(Total logs + e)"
|
||||
},
|
||||
visibility: () => showIf(fertilizerElfMilestones[1].earned.value),
|
||||
shouldEarn: () => heatedPlanterElfTraining.level.value >= 3
|
||||
shouldEarn: () => fertilizerElfTraining.level.value >= 3
|
||||
})),
|
||||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Noel Level 4",
|
||||
effectDisplay: jsx(() => <>Reduce oil refinery cost by (Plastic amount)<sup>2</sup></>)
|
||||
effectDisplay: jsx(() => (
|
||||
<>
|
||||
Reduce oil refinery cost by (Plastic amount)<sup>2</sup>
|
||||
</>
|
||||
))
|
||||
},
|
||||
visibility: () =>
|
||||
showIf(fertilizerElfMilestones[2].earned.value && main.day.value >= 13),
|
||||
shouldEarn: () => heatedPlanterElfTraining.level.value >= 4
|
||||
shouldEarn: () => fertilizerElfTraining.level.value >= 4
|
||||
})),
|
||||
createMilestone(() => ({
|
||||
display: {
|
||||
|
@ -471,7 +539,7 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Joy Level 1",
|
||||
effectDisplay: "Multiply small fire efficiency by 5."
|
||||
effectDisplay: "Small Fire synergy counts bonfires at reduced rate."
|
||||
},
|
||||
shouldEarn: () => smallfireElfTraining.level.value >= 1
|
||||
})),
|
||||
|
@ -619,7 +687,11 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Star Level 4",
|
||||
effectDisplay: jsx(() => <>Multiply XP requirements by 0.95<sup>(total books)</sup></>)
|
||||
effectDisplay: jsx(() => (
|
||||
<>
|
||||
Multiply XP requirements by 0.95<sup>(total books)</sup>
|
||||
</>
|
||||
))
|
||||
},
|
||||
visibility: () => showIf(paperElfMilestones[2].earned.value && main.day.value >= 13),
|
||||
shouldEarn: () => paperElfTraining.level.value >= 4
|
||||
|
@ -637,7 +709,11 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Bell Level 1",
|
||||
effectDisplay: jsx(() => <>Every box buyable adds <Sqrt>level</Sqrt> levels to same-row box buyables.</>)
|
||||
effectDisplay: jsx(() => (
|
||||
<>
|
||||
Every box buyable adds <Sqrt>level</Sqrt> levels to same-row box buyables.
|
||||
</>
|
||||
))
|
||||
},
|
||||
shouldEarn: () => boxElfTraining.level.value >= 1
|
||||
})),
|
||||
|
@ -685,7 +761,11 @@ const layer = createLayer(id, () => {
|
|||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Gingersnap Level 2",
|
||||
effectDisplay: jsx(() => <>Multiply all cloth actions' effectiveness by log<sub>10</sub>(dye sum + 10)</>)
|
||||
effectDisplay: jsx(() => (
|
||||
<>
|
||||
Multiply all cloth actions' effectiveness by log<sub>10</sub>(dye sum + 10)
|
||||
</>
|
||||
))
|
||||
},
|
||||
visibility: () => showIf(clothElfMilestones[0].earned.value),
|
||||
shouldEarn: () => clothElfTraining.level.value >= 2
|
||||
|
@ -698,26 +778,39 @@ const layer = createLayer(id, () => {
|
|||
visibility: () => showIf(clothElfMilestones[1].earned.value),
|
||||
shouldEarn: () => clothElfTraining.level.value >= 3,
|
||||
onComplete() {
|
||||
(["red", "yellow", "blue", "orange", "green", "purple"] as const).forEach(dyeColor => {
|
||||
(["red", "yellow", "blue", "orange", "green", "purple"] as const).forEach(
|
||||
dyeColor => {
|
||||
dyes.dyes[dyeColor].amount.value = 0;
|
||||
dyes.dyes[dyeColor].buyable.amount.value = 0;
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
})),
|
||||
createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "Gingersnap Level 4",
|
||||
effectDisplay: jsx(() => <>Multiply ALL dye gain by{" "}
|
||||
<Fraction><div><Sqrt>classrooms</Sqrt></div><div>2</div></Fraction>+1,
|
||||
but reset all dyes.</>)
|
||||
effectDisplay: jsx(() => (
|
||||
<>
|
||||
Multiply ALL dye gain by{" "}
|
||||
<Fraction>
|
||||
<div>
|
||||
<Sqrt>classrooms</Sqrt>
|
||||
</div>
|
||||
<div>2</div>
|
||||
</Fraction>
|
||||
+1, but reset all dyes.
|
||||
</>
|
||||
))
|
||||
},
|
||||
visibility: () => showIf(clothElfMilestones[2].earned.value && main.day.value >= 13),
|
||||
shouldEarn: () => clothElfTraining.level.value >= 4,
|
||||
onComplete() {
|
||||
(["red", "yellow", "blue", "orange", "green", "purple"] as const).forEach(dyeColor => {
|
||||
(["red", "yellow", "blue", "orange", "green", "purple"] as const).forEach(
|
||||
dyeColor => {
|
||||
dyes.dyes[dyeColor].amount.value = 0;
|
||||
dyes.dyes[dyeColor].buyable.amount.value = 0;
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
})),
|
||||
createMilestone(() => ({
|
||||
|
@ -796,7 +889,35 @@ const layer = createLayer(id, () => {
|
|||
paperElfTraining,
|
||||
boxElfTraining,
|
||||
clothElfTraining
|
||||
} as Record<string, ElfTrainingClickable>;
|
||||
};
|
||||
const day12Elves = [
|
||||
cutterElfTraining,
|
||||
planterElfTraining,
|
||||
expandersElfTraining,
|
||||
heatedCutterElfTraining,
|
||||
heatedPlanterElfTraining,
|
||||
fertilizerElfTraining,
|
||||
smallfireElfTraining,
|
||||
bonfireElfTraining,
|
||||
kilnElfTraining,
|
||||
paperElfTraining,
|
||||
boxElfTraining,
|
||||
clothElfTraining
|
||||
];
|
||||
const day13Elves = [
|
||||
cutterElfTraining,
|
||||
planterElfTraining,
|
||||
expandersElfTraining,
|
||||
heatedCutterElfTraining,
|
||||
heatedPlanterElfTraining,
|
||||
fertilizerElfTraining,
|
||||
smallfireElfTraining,
|
||||
bonfireElfTraining,
|
||||
kilnElfTraining,
|
||||
paperElfTraining,
|
||||
boxElfTraining,
|
||||
clothElfTraining
|
||||
];
|
||||
|
||||
// ------------------------------------------------------------------------------- Update
|
||||
|
||||
|
@ -813,13 +934,15 @@ const layer = createLayer(id, () => {
|
|||
);
|
||||
}
|
||||
}
|
||||
focusTime.value = Math.max(focusTime.value - diff, 0);
|
||||
focusCooldown.value = Math.max(focusCooldown.value - diff, 0);
|
||||
|
||||
if (focusRolling.value > 0) {
|
||||
focusRolling.value += diff;
|
||||
focusMulti.value = Decimal.pow(focusMaxMulti.value, 1 - Math.abs(Math.sin((focusRolling.value - 1) * 3)));
|
||||
rerollFocusTargets(12, 3);
|
||||
} else {
|
||||
focusRolling.value = Math.min(focusRolling.value + diff, 0);
|
||||
if (Decimal.eq(focusTime.value, 0)) {
|
||||
focusTargets.value = {};
|
||||
focusMulti.value = Decimal.pow(
|
||||
focusMaxMulti.value,
|
||||
1 - Math.abs(Math.sin((Date.now() / 1000) * 2))
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -827,9 +950,35 @@ const layer = createLayer(id, () => {
|
|||
|
||||
const focusMulti = persistent<DecimalSource>(1);
|
||||
const focusTargets = persistent<Record<string, boolean>>({});
|
||||
const focusRolling = persistent<number>(0);
|
||||
const focusCooldown = persistent<number>(0);
|
||||
const focusTime = persistent<number>(0);
|
||||
|
||||
const focusMaxMulti = computed<DecimalSource>(() => 10);
|
||||
const focusMaxMultiModifiers = createSequentialModifier(() => [
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: 2,
|
||||
description: "Focus Upgrade 1",
|
||||
enabled: focusUpgrade1.bought
|
||||
}))
|
||||
]);
|
||||
const maximumElvesModifier = createSequentialModifier(() => [
|
||||
createAdditiveModifier(() => ({
|
||||
addend: 1,
|
||||
description: "Focus Upgrade 2",
|
||||
enabled: focusUpgrade2.bought
|
||||
}))
|
||||
]);
|
||||
|
||||
const cooldownModifiers = createSequentialModifier(() => [
|
||||
createAdditiveModifier(() => ({
|
||||
addend: -5,
|
||||
description: "Focus Upgrade 3",
|
||||
enabled: focusUpgrade3.bought
|
||||
}))
|
||||
]);
|
||||
|
||||
const focusMaxMulti = computed(() => focusMaxMultiModifiers.apply(10));
|
||||
const maximumElves = computed(() => maximumElvesModifier.apply(3));
|
||||
const cooldown = computed(() => cooldownModifiers.apply(15));
|
||||
|
||||
const focusMeter = createBar(() => ({
|
||||
direction: Direction.Right,
|
||||
|
@ -837,9 +986,27 @@ const layer = createLayer(id, () => {
|
|||
height: 25,
|
||||
style: `border-radius: 4px 4px 0 0`,
|
||||
borderStyle: `border-radius: 4px 4px 0 0`,
|
||||
fillStyle: `background: ${color}; transition: none`,
|
||||
progress: () => Decimal.sub(focusMulti.value, 1).div(Decimal.sub(focusMaxMulti.value, 1)).toNumber(),
|
||||
display: jsx(() => <>{format(focusMulti.value)}x</>)
|
||||
fillStyle: () => ({
|
||||
background: focusTime.value > 0 ? color : "#7f7f00",
|
||||
opacity: focusTime.value > 0 ? focusTime.value / 10 : 1,
|
||||
transition: "none"
|
||||
}),
|
||||
progress: () =>
|
||||
Decimal.sub(focusMulti.value, 1).div(Decimal.sub(focusMaxMulti.value, 1)).toNumber(),
|
||||
display: jsx(() => (
|
||||
<>
|
||||
{format(focusMulti.value)}x
|
||||
{focusTime.value > 0 ? (
|
||||
<>
|
||||
{" "}
|
||||
to {Object.keys(focusTargets.value).join(", ")} for{" "}
|
||||
{formatTime(focusTime.value)}
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</>
|
||||
))
|
||||
})) as GenericBar;
|
||||
|
||||
const focusButton = createClickable(() => ({
|
||||
|
@ -847,35 +1014,35 @@ const layer = createLayer(id, () => {
|
|||
title: "Focus",
|
||||
description: jsx(() => (
|
||||
<>
|
||||
{focusRolling.value <= 0
|
||||
? <>Motivate elves to focus, multiplying 3 random elves' XP gain by up to {format(focusMaxMulti.value)}x</>
|
||||
: "Click to stop the focus bar"
|
||||
}
|
||||
{focusRolling.value < 0
|
||||
? <><br/>Reroll cooldown: {formatTime(-focusRolling.value)}</>
|
||||
: ""
|
||||
}
|
||||
Motivate elves to focus, multiplying 3 random elves' XP gain by up to{" "}
|
||||
{format(focusMaxMulti.value)}x for 10 seconds, equal to the focus bar's effect.
|
||||
{Decimal.gte(focusCooldown.value, 0) ? (
|
||||
<>
|
||||
<br />
|
||||
Reroll cooldown: {formatTime(focusCooldown.value)}
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</>
|
||||
))
|
||||
},
|
||||
style: {
|
||||
width: "300px"
|
||||
},
|
||||
canClick: () => focusRolling.value >= 0,
|
||||
canClick: () => Decimal.eq(focusCooldown.value, 0),
|
||||
onClick() {
|
||||
if (focusRolling.value == 0) {
|
||||
focusRolling.value = 1;
|
||||
} else if (focusRolling.value > 0) {
|
||||
focusRolling.value = -30;
|
||||
}
|
||||
focusCooldown.value = Decimal.fromValue(cooldown.value).toNumber();
|
||||
focusTime.value = 10;
|
||||
rerollFocusTargets(12, maximumElves.value);
|
||||
}
|
||||
}));
|
||||
|
||||
function rerollFocusTargets(range: number, count: number) {
|
||||
function rerollFocusTargets(range: number, count: DecimalSource) {
|
||||
let x = 0;
|
||||
focusTargets.value = {};
|
||||
count = Math.min(count, range);
|
||||
while (x < count) {
|
||||
const newCount = Decimal.min(count, range);
|
||||
while (newCount.gt(x)) {
|
||||
const roll = Object.values(elfTraining)[Math.floor(Math.random() * range)]?.name ?? "";
|
||||
if (!focusTargets.value[roll]) {
|
||||
focusTargets.value[roll] = true;
|
||||
|
@ -883,19 +1050,46 @@ const layer = createLayer(id, () => {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
const focusUpgrade1 = createUpgrade(() => ({
|
||||
display: {
|
||||
title: "Focus Booster",
|
||||
description: "Multiplies the maximum experience multiplier from focus by 2"
|
||||
},
|
||||
resource: trees.logs,
|
||||
cost: 1e25
|
||||
}));
|
||||
const focusUpgrade2 = createUpgrade(() => ({
|
||||
display: {
|
||||
title: "Focus Buffer",
|
||||
description: "Increase elves affected by focus by 1"
|
||||
},
|
||||
resource: trees.logs,
|
||||
cost: 1e30
|
||||
}));
|
||||
const focusUpgrade3 = createUpgrade(() => ({
|
||||
display: {
|
||||
title: "Focus Upgrader",
|
||||
description: "Focus can now be rerolled every 10 seconds"
|
||||
},
|
||||
resource: trees.logs,
|
||||
cost: 1e35
|
||||
}));
|
||||
const upgrades = [focusUpgrade1, focusUpgrade2, focusUpgrade3];
|
||||
// ------------------------------------------------------------------------------- Schools
|
||||
|
||||
const schoolCost = computed(() => {
|
||||
const schoolFactor = Decimal.pow(10, schools.amount.value);
|
||||
const nerfedSchoolFactor = Decimal.pow(5, schools.amount.value);
|
||||
const woodFactor = Decimal.pow(2e4, Decimal.pow(schools.amount.value, 0.75));
|
||||
const coalFactor = Decimal.pow(2000, schools.amount.value);
|
||||
return {
|
||||
wood: schoolFactor.mul(1e21),
|
||||
coal: schoolFactor.mul(1e32),
|
||||
paper: schoolFactor.mul(1e19),
|
||||
boxes: schoolFactor.mul(1e13),
|
||||
metalIngots: schoolFactor.mul(1e12),
|
||||
wood: woodFactor.mul(1e21),
|
||||
coal: coalFactor.mul(1e32),
|
||||
paper: coalFactor.mul(1e18),
|
||||
boxes: woodFactor.mul(1e13),
|
||||
metalIngots: nerfedSchoolFactor.mul(1e12),
|
||||
cloth: schoolFactor.mul(1e4),
|
||||
plastic: schoolFactor.mul(1e6),
|
||||
plastic: nerfedSchoolFactor.mul(1e6),
|
||||
dye: Decimal.add(schools.amount.value, 1).mul(10000)
|
||||
};
|
||||
});
|
||||
|
@ -906,11 +1100,11 @@ const layer = createLayer(id, () => {
|
|||
<h3>Build a School</h3>
|
||||
<div>
|
||||
You gotta start somewhere, right? Each school increases the maximum level for
|
||||
elves by 1, up to 5.
|
||||
elves by 1, maximum of {main.day.value === 12 ? 3 : 5} schools.
|
||||
</div>
|
||||
<div>You have {formatWhole(schools.amount.value)} schools,
|
||||
which are currently letting elves learn up to level{" "}
|
||||
{formatWhole(schools.amount.value)}.
|
||||
<div>
|
||||
You have {formatWhole(schools.amount.value)} schools, which are currently
|
||||
letting elves learn up to level {formatWhole(schools.amount.value)}.
|
||||
</div>
|
||||
<div>
|
||||
Costs {format(schoolCost.value.wood)} logs, {format(schoolCost.value.coal)}{" "}
|
||||
|
@ -946,27 +1140,26 @@ const layer = createLayer(id, () => {
|
|||
plastic.plastic.value = Decimal.sub(plastic.plastic.value, schoolCost.value.plastic);
|
||||
this.amount.value = Decimal.add(this.amount.value, 1);
|
||||
},
|
||||
purchaseLimit: 5,
|
||||
purchaseLimit() {
|
||||
if (main.days[advancedDay - 1].opened.value) return 5
|
||||
return 3
|
||||
},
|
||||
visibility: computed(() => showIf(teaching.bought.value)),
|
||||
style: "width: 600px"
|
||||
}));
|
||||
|
||||
const classroomCost = computed(() => {
|
||||
const classroomFactor = Decimal.add(schools.amount.value, 1).pow(1.5);
|
||||
const classroomFactor = Decimal.add(classrooms.amount.value, 1).pow(1.5);
|
||||
return {
|
||||
wood: classroomFactor.mul(1e21),
|
||||
coal: classroomFactor.mul(1e32),
|
||||
paper: classroomFactor.mul(1e19),
|
||||
paper: classroomFactor.mul(1e18),
|
||||
boxes: classroomFactor.mul(1e13),
|
||||
metalIngots: classroomFactor.mul(1e12),
|
||||
cloth: classroomFactor.mul(1e4),
|
||||
plastic: classroomFactor.mul(1e6),
|
||||
dye: classroomFactor.mul(10000)
|
||||
metalIngots: classroomFactor.mul(1e12)
|
||||
};
|
||||
});
|
||||
|
||||
const classroomEffect = computed(() => {
|
||||
return Decimal.add(classrooms.amount.value, 1).sqrt();
|
||||
return Decimal.add(classrooms.amount.value, 1).pow(0.9);
|
||||
});
|
||||
|
||||
const classrooms = createBuyable(() => ({
|
||||
|
@ -975,44 +1168,32 @@ const layer = createLayer(id, () => {
|
|||
<h3>Build a Classroom</h3>
|
||||
<div>
|
||||
Hopefully it makes the school a bit less boring. Multiplies elves' XP gain by{" "}
|
||||
<Sqrt>Classrooms + 1</Sqrt>.
|
||||
</div>
|
||||
<div>You have {formatWhole(schools.amount.value)} classrooms,
|
||||
which are currently multiplying elves' XP gain by {format(classroomEffect.value)}
|
||||
(Classrooms + 1)<sup>0.9</sup>.
|
||||
</div>
|
||||
<div>
|
||||
Costs {format(classroomCost.value.wood)} logs,{" "}
|
||||
{format(classroomCost.value.coal)} coal, {format(classroomCost.value.paper)}{" "}
|
||||
paper, {format(classroomCost.value.boxes)} boxes,{" "}
|
||||
{format(classroomCost.value.metalIngots)} metal ingots,{" "}
|
||||
{format(classroomCost.value.cloth)} cloth, {format(classroomCost.value.plastic)}{" "}
|
||||
plastic, and requires {format(classroomCost.value.dye)} of red, yellow, and blue
|
||||
dye
|
||||
You have {formatWhole(classrooms.amount.value)} classrooms, which are currently
|
||||
multiplying elves' XP gain by {format(classroomEffect.value)}
|
||||
</div>
|
||||
<div>
|
||||
Costs {format(classroomCost.value.wood)} logs,
|
||||
{format(classroomCost.value.paper)} paper, {format(classroomCost.value.boxes)}{" "}
|
||||
boxes, {format(classroomCost.value.metalIngots)} metal ingots
|
||||
</div>
|
||||
</>
|
||||
)),
|
||||
canPurchase(): boolean {
|
||||
return (
|
||||
classroomCost.value.wood.lte(trees.logs.value) &&
|
||||
classroomCost.value.coal.lte(coal.coal.value) &&
|
||||
classroomCost.value.paper.lte(paper.paper.value) &&
|
||||
classroomCost.value.boxes.lte(boxes.boxes.value) &&
|
||||
classroomCost.value.metalIngots.lte(metal.metal.value) &&
|
||||
classroomCost.value.cloth.lte(cloth.cloth.value) &&
|
||||
classroomCost.value.plastic.lte(plastic.plastic.value) &&
|
||||
classroomCost.value.dye.lte(dyes.dyes.blue.amount.value) &&
|
||||
classroomCost.value.dye.lte(dyes.dyes.red.amount.value) &&
|
||||
classroomCost.value.dye.lte(dyes.dyes.yellow.amount.value)
|
||||
classroomCost.value.metalIngots.lte(metal.metal.value)
|
||||
);
|
||||
},
|
||||
onPurchase() {
|
||||
trees.logs.value = Decimal.sub(trees.logs.value, classroomCost.value.wood);
|
||||
coal.coal.value = Decimal.sub(coal.coal.value, classroomCost.value.coal);
|
||||
paper.paper.value = Decimal.sub(paper.paper.value, classroomCost.value.paper);
|
||||
boxes.boxes.value = Decimal.sub(boxes.boxes.value, classroomCost.value.boxes);
|
||||
metal.metal.value = Decimal.sub(metal.metal.value, classroomCost.value.metalIngots);
|
||||
cloth.cloth.value = Decimal.sub(cloth.cloth.value, classroomCost.value.cloth);
|
||||
plastic.plastic.value = Decimal.sub(plastic.plastic.value, classroomCost.value.plastic);
|
||||
this.amount.value = Decimal.add(this.amount.value, 1);
|
||||
},
|
||||
visibility: computed(() => showIf(classroomUpgrade.bought.value)),
|
||||
|
@ -1022,6 +1203,22 @@ const layer = createLayer(id, () => {
|
|||
// ------------------------------------------------------------------------------- Modifiers
|
||||
|
||||
const [generalTab, generalTabCollapsed] = createCollapsibleModifierSections(() => [
|
||||
{
|
||||
title: "Elves affected by Focus",
|
||||
modifier: maximumElvesModifier,
|
||||
base: 3
|
||||
},
|
||||
{
|
||||
title: "Maximum Focus Effect",
|
||||
modifier: focusMaxMultiModifiers,
|
||||
base: 10
|
||||
},
|
||||
{
|
||||
title: "Focus Cooldown",
|
||||
modifier: cooldownModifiers,
|
||||
unit: " secs",
|
||||
base: 15
|
||||
},
|
||||
{
|
||||
title: "Global XP Gain",
|
||||
modifier: globalXPModifier,
|
||||
|
@ -1112,6 +1309,16 @@ const layer = createLayer(id, () => {
|
|||
/>
|
||||
));
|
||||
|
||||
watchEffect(() => {
|
||||
if (main.day.value === day && day12Elves.every(elf => elf.level.value >= 3)) {
|
||||
main.completeDay();
|
||||
} else if (
|
||||
main.day.value === advancedDay &&
|
||||
day13Elves.every(elf => elf.level.value >= 5)
|
||||
) {
|
||||
main.completeDay();
|
||||
}
|
||||
});
|
||||
|
||||
// ------------------------------------------------------------------------------- Return
|
||||
|
||||
|
@ -1123,6 +1330,7 @@ const layer = createLayer(id, () => {
|
|||
|
||||
elfTraining,
|
||||
totalElfLevels,
|
||||
totalElfExp,
|
||||
currentShown,
|
||||
generalTabCollapsed,
|
||||
|
||||
|
@ -1132,12 +1340,19 @@ const layer = createLayer(id, () => {
|
|||
classroomUpgrade,
|
||||
|
||||
focusMultiplier: focusMulti,
|
||||
upgrades,
|
||||
focusTargets,
|
||||
focusRolling,
|
||||
focusCooldown,
|
||||
focusTime,
|
||||
|
||||
display: jsx(() => (
|
||||
<>
|
||||
{main.day.value === day ? `Get all elves to level 5.` : `${name} Complete!`} -
|
||||
{main.day.value === day
|
||||
? `Get all elves to level 3.`
|
||||
: main.day.value === advancedDay && main.days[advancedDay - 1].opened.value
|
||||
? `Get all elves to level 5.`
|
||||
: `${name} Complete!`}{" "}
|
||||
-
|
||||
<button
|
||||
class="button"
|
||||
style="display: inline-block;"
|
||||
|
@ -1148,14 +1363,17 @@ const layer = createLayer(id, () => {
|
|||
{render(modifiersModal)}
|
||||
{render(dayProgress)}
|
||||
<br />
|
||||
{renderCol(schools, classrooms)}{" "}
|
||||
{renderCol(schools, classrooms)}
|
||||
{renderGrid([teaching, classroomUpgrade])}
|
||||
{
|
||||
Decimal.gt(schools.amount.value, 0) ? <>
|
||||
<Spacer />
|
||||
{Decimal.gt(schools.amount.value, 0) ? (
|
||||
<>
|
||||
<br />
|
||||
Click on an elf to see their milestones.
|
||||
<br/><br/>
|
||||
<br />
|
||||
<br />
|
||||
{render(focusButton)}
|
||||
{renderGrid(upgrades)}
|
||||
<br />
|
||||
{renderGrid(
|
||||
[focusMeter],
|
||||
|
@ -1166,8 +1384,10 @@ const layer = createLayer(id, () => {
|
|||
)}
|
||||
<Spacer />
|
||||
{currentElfDisplay()}
|
||||
</> : ""
|
||||
}
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</>
|
||||
))
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@ import Toggle from "components/fields/Toggle.vue";
|
|||
import Modal from "components/Modal.vue";
|
||||
import { createCollapsibleModifierSections, setUpDailyProgressTracker } from "data/common";
|
||||
import { jsx, showIf } from "features/feature";
|
||||
import { createResource, trackBest } from "features/resources/resource";
|
||||
import { createResource, Resource, trackBest } from "features/resources/resource";
|
||||
import { BaseLayer, createLayer } from "game/layers";
|
||||
import Decimal, { DecimalSource } from "lib/break_eternity";
|
||||
import { render, renderRow } from "util/vue";
|
||||
|
@ -12,6 +12,7 @@ import { persistent } from "game/persistence";
|
|||
import { globalBus } from "game/events";
|
||||
import {
|
||||
createAdditiveModifier,
|
||||
createExponentialModifier,
|
||||
createMultiplicativeModifier,
|
||||
createSequentialModifier
|
||||
} from "game/modifiers";
|
||||
|
@ -30,6 +31,8 @@ import boxes from "./boxes";
|
|||
import cloth from "./cloth";
|
||||
import plastic from "./plastic";
|
||||
import dyes from "./dyes";
|
||||
import management from "./management";
|
||||
import workshop from "./workshop";
|
||||
|
||||
const id = "metal";
|
||||
const day = 7;
|
||||
|
@ -78,6 +81,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
multiplier: () => Decimal.add(cloth.cloth.value, 1).log10().plus(1),
|
||||
description: "Glistening Paint",
|
||||
enabled: dyes.upgrades.redDyeUpg.bought
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: () =>
|
||||
Decimal.div(workshop.foundationProgress.value, 10).floor().div(10).add(1),
|
||||
description: "400% Foundation Completed",
|
||||
enabled: workshop.milestones.extraExpansionMilestone2.earned
|
||||
})),
|
||||
createExponentialModifier(() => ({
|
||||
exponent: 1.1,
|
||||
description: "Mary Level 2",
|
||||
enabled: management.elfTraining.heatedPlanterElfTraining.milestones[1].earned
|
||||
}))
|
||||
]);
|
||||
const computedOrePurity = computed(() => orePurity.apply(0.1));
|
||||
|
@ -108,6 +122,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
multiplier: () => Decimal.add(plastic.activeRefinery.value, 1).sqrt(),
|
||||
description: "De Louvre",
|
||||
enabled: dyes.upgrades.redDyeUpg2.bought
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: () => Decimal.div(management.totalElfExp.value, 1000).add(1).sqrt(),
|
||||
description: "Mary Level 5",
|
||||
enabled: management.elfTraining.heatedPlanterElfTraining.milestones[4].earned
|
||||
}))
|
||||
]);
|
||||
const computedAutoSmeltSpeed = computed(() => autoSmeltSpeed.apply(0));
|
||||
|
@ -359,7 +378,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
.gte(10)
|
||||
),
|
||||
style: { width: "200px" }
|
||||
})) as GenericBuyable;
|
||||
})) as GenericBuyable & { resource: Resource };
|
||||
const industrialCrucible = createBuyable(() => ({
|
||||
resource: noPersist(metal),
|
||||
cost() {
|
||||
|
@ -382,7 +401,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
Decimal.gte(bestOre.value, 50)
|
||||
),
|
||||
style: { width: "200px" }
|
||||
})) as GenericBuyable;
|
||||
})) as GenericBuyable & { resource: Resource };
|
||||
const autoSmeltEnabled = persistent<boolean>(true);
|
||||
const hotterForge = createBuyable(() => ({
|
||||
resource: coal.coal,
|
||||
|
@ -403,7 +422,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
visibility: () =>
|
||||
showIf(Decimal.gte(hotterForge.amount.value, 1) || industrialFurnace.bought.value),
|
||||
style: { width: "200px" }
|
||||
})) as GenericBuyable;
|
||||
})) as GenericBuyable & { resource: Resource };
|
||||
const hotterForgeEffect = computed(() => Decimal.times(hotterForge.amount.value, 0.25));
|
||||
|
||||
globalBus.on("update", diff => {
|
||||
|
@ -573,6 +592,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
)}
|
||||
{renderRow(oreDrill, industrialCrucible, hotterForge)}
|
||||
</>
|
||||
)),
|
||||
minimizedDisplay: jsx(() => (
|
||||
<div>
|
||||
{name} - {format(metal.value)} {metal.displayName}
|
||||
</div>
|
||||
))
|
||||
};
|
||||
});
|
||||
|
|
|
@ -35,6 +35,8 @@ import { formatGain } from "util/bignum";
|
|||
import plastic from "./plastic";
|
||||
import paper from "./paper";
|
||||
import dyes from "./dyes";
|
||||
import management from "./management";
|
||||
import workshop from "./workshop";
|
||||
|
||||
const id = "oil";
|
||||
const day = 9;
|
||||
|
@ -247,8 +249,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
<br />
|
||||
Pump that oil from the ground.
|
||||
<br />
|
||||
Gain oil based on the number of Heavy buildings active and well
|
||||
depth, but coal usage is multiplied by {row2Upgrades[3].bought.value ? 4 : 5}×.
|
||||
Gain oil based on the number of Heavy buildings active and well depth, but coal
|
||||
usage is multiplied by {row2Upgrades[3].bought.value ? 4 : 5}×.
|
||||
<br />
|
||||
<br />
|
||||
Currently:
|
||||
|
@ -718,6 +720,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
multiplier: () => coalEffectiveness.value,
|
||||
description: "Effectiveness",
|
||||
enabled: () => Decimal.lt(coalEffectiveness.value, 1)
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: () =>
|
||||
Decimal.div(workshop.foundationProgress.value, 10).floor().div(10).add(1),
|
||||
description: "600% Foundation Completed",
|
||||
enabled: workshop.milestones.extraExpansionMilestone3.earned
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: () => Decimal.sqrt(management.totalElfLevels.value),
|
||||
description: "Jack Level 4",
|
||||
enabled: management.elfTraining.heatedCutterElfTraining.milestones[3].earned
|
||||
}))
|
||||
]);
|
||||
const computedOilSpeed = computed(() => oilSpeed.apply(0));
|
||||
|
@ -947,6 +960,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
<MainDisplay
|
||||
resource={oil}
|
||||
color={color}
|
||||
resourceStyle={{textShadow: 'grey 0px 0px 10px'}}
|
||||
sticky={true}
|
||||
productionDisplay={jsx(() => (
|
||||
<>
|
||||
|
@ -1068,7 +1082,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
{Decimal.gte(totalOil.value, 50) ? oilMilestonesDisplay() : ""}
|
||||
</>
|
||||
);
|
||||
})
|
||||
}),
|
||||
minimizedDisplay: jsx(() => (
|
||||
<div>
|
||||
{name} - {format(oil.value)} {oil.displayName}
|
||||
</div>
|
||||
))
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import plastic from "./plastic";
|
|||
import trees from "./trees";
|
||||
import dyes from "./dyes";
|
||||
import management from "./management";
|
||||
import workshop from "./workshop";
|
||||
|
||||
const id = "paper";
|
||||
const day = 5;
|
||||
|
@ -38,7 +39,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
const paper = createResource<DecimalSource>(0, "paper");
|
||||
|
||||
const pulp = createResource<DecimalSource>(
|
||||
computed(() => Decimal.min(Decimal.div(trees.logs.value, 1e9), Decimal.div(coal.ash.value, computedAshCost.value))),
|
||||
computed(() =>
|
||||
Decimal.min(
|
||||
Decimal.div(trees.logs.value, 1e9),
|
||||
Decimal.div(coal.ash.value, computedAshCost.value)
|
||||
)
|
||||
),
|
||||
"pulp"
|
||||
);
|
||||
|
||||
|
@ -49,7 +55,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
roundUpCost: true,
|
||||
spend(gain, cost) {
|
||||
trees.logs.value = Decimal.sub(trees.logs.value, Decimal.times(cost, 1e9));
|
||||
coal.ash.value = Decimal.sub(coal.ash.value, Decimal.times(cost, computedAshCost.value));
|
||||
coal.ash.value = Decimal.sub(
|
||||
coal.ash.value,
|
||||
Decimal.times(cost, computedAshCost.value)
|
||||
);
|
||||
},
|
||||
gainModifier: paperGain
|
||||
}));
|
||||
|
@ -68,7 +77,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
<span style="font-size: large">
|
||||
Cost: {displayResource(trees.logs, cost)} {pulp.displayName} (
|
||||
{formatWhole(Decimal.times(cost, 1e9))} {trees.logs.displayName};{" "}
|
||||
{formatWhole(Decimal.times(cost, computedAshCost.value))} {coal.ash.displayName})
|
||||
{formatWhole(Decimal.times(cost, computedAshCost.value))}{" "}
|
||||
{coal.ash.displayName})
|
||||
</span>
|
||||
</>
|
||||
);
|
||||
|
@ -187,6 +197,34 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
buyableName: "Cloth Buyables",
|
||||
visibility: () => showIf(elves.elves.clothElf.bought.value)
|
||||
});
|
||||
const miningDrillBook = createBook({
|
||||
name: "Drills and Mills",
|
||||
elfName: "Peppermint",
|
||||
buyableName: "Mining Drill",
|
||||
visibility: () =>
|
||||
showIf(management.elfTraining.expandersElfTraining.milestones[3].earned.value)
|
||||
});
|
||||
const heavyDrillBook = createBook({
|
||||
name: "Deep in the Earth",
|
||||
elfName: "Frosty",
|
||||
buyableName: "Oil Drills",
|
||||
visibility: () =>
|
||||
showIf(management.elfTraining.fertilizerElfTraining.milestones[4].earned.value)
|
||||
});
|
||||
const oilBook = createBook({
|
||||
name: "Burning the Midnight Oil",
|
||||
elfName: "Cocoa",
|
||||
buyableName: "Oil-Consuming Machines",
|
||||
visibility: () =>
|
||||
showIf(management.elfTraining.heatedCutterElfTraining.milestones[4].earned.value)
|
||||
});
|
||||
const metalBook = createBook({
|
||||
name: "Physical Metallurgy",
|
||||
elfName: "Twinkle",
|
||||
buyableName: "Metal Buyables",
|
||||
visibility: () =>
|
||||
showIf(management.elfTraining.expandersElfTraining.milestones[4].earned.value)
|
||||
});
|
||||
const books = {
|
||||
cuttersBook,
|
||||
plantersBook,
|
||||
|
@ -199,9 +237,15 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
kilnBook,
|
||||
paperBook,
|
||||
boxBook,
|
||||
clothBook
|
||||
clothBook,
|
||||
miningDrillBook,
|
||||
heavyDrillBook,
|
||||
oilBook,
|
||||
metalBook
|
||||
};
|
||||
const sumBooks = computed(() => Object.values(books).reduce((acc, curr) => acc.add(curr.amount.value), new Decimal(0)));
|
||||
const sumBooks = computed(() =>
|
||||
Object.values(books).reduce((acc, curr) => acc.add(curr.amount.value), new Decimal(0))
|
||||
);
|
||||
|
||||
const clothUpgrade = createUpgrade(() => ({
|
||||
resource: noPersist(paper),
|
||||
|
@ -257,11 +301,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
multiplier: dyes.boosts.yellow1,
|
||||
description: "Yellow Dye Boost 1",
|
||||
enabled: () => Decimal.gte(dyes.dyes.yellow.amount.value, 1)
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: 2,
|
||||
description: "1000% Foundation Completed",
|
||||
enabled: workshop.milestones.extraExpansionMilestone5.earned
|
||||
}))
|
||||
]) as WithRequired<Modifier, "description" | "revert">;
|
||||
const ashCost = createSequentialModifier(() => [
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: .1,
|
||||
multiplier: 0.1,
|
||||
description: "Star Level 2",
|
||||
enabled: management.elfTraining.paperElfTraining.milestones[1].earned
|
||||
}))
|
||||
|
@ -340,6 +389,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
<Spacer />
|
||||
{renderCol(...Object.values(books))}
|
||||
</>
|
||||
)),
|
||||
minimizedDisplay: jsx(() => (
|
||||
<div>
|
||||
{name} - {format(paper.value)} {paper.displayName}
|
||||
</div>
|
||||
))
|
||||
};
|
||||
});
|
||||
|
|
|
@ -32,6 +32,8 @@ import boxes from "./boxes";
|
|||
import metal from "./metal";
|
||||
import oil from "./oil";
|
||||
import dyes from "./dyes";
|
||||
import management from "./management";
|
||||
import workshop from "./workshop";
|
||||
|
||||
const id = "plastic";
|
||||
const day = 10;
|
||||
|
@ -66,7 +68,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
resource: metal.metal,
|
||||
cost() {
|
||||
const v = new Decimal(this.amount.value);
|
||||
return Decimal.pow(1.2, v).times(1e7);
|
||||
let cost = Decimal.pow(1.2, v).times(1e7);
|
||||
if (management.elfTraining.fertilizerElfTraining.milestones[3].earned.value) {
|
||||
cost = Decimal.sub(cost, Decimal.pow(plastic.value, 2)).max(0);
|
||||
}
|
||||
return cost;
|
||||
},
|
||||
display: jsx(() => (
|
||||
<>
|
||||
|
@ -257,6 +263,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
multiplier: dyes.boosts.yellow1,
|
||||
description: "Yellow Dye Boost 1",
|
||||
enabled: () => Decimal.gte(dyes.dyes.yellow.amount.value, 1)
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: () =>
|
||||
Decimal.div(workshop.foundationProgress.value, 10).floor().div(10).add(1),
|
||||
description: "800% Foundation Completed",
|
||||
enabled: workshop.milestones.extraExpansionMilestone4.earned
|
||||
}))
|
||||
]);
|
||||
const computedPlasticGain = computed(() => plasticGain.apply(0));
|
||||
|
@ -299,11 +311,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
<>
|
||||
{render(trackerDisplay)}
|
||||
<Spacer />
|
||||
<MainDisplay resource={plastic} color={color} style="margin-bottom: 0" effectDisplay={
|
||||
<MainDisplay
|
||||
resource={plastic}
|
||||
color={color}
|
||||
style="margin-bottom: 0"
|
||||
effectDisplay={
|
||||
Decimal.gt(computedPlasticGain.value, 0)
|
||||
? `+${format(computedPlasticGain.value)}/s`
|
||||
: undefined
|
||||
} />
|
||||
}
|
||||
/>
|
||||
<Spacer />
|
||||
<Column>
|
||||
{render(buildRefinery)}
|
||||
|
@ -319,6 +336,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
{renderCol(clothTools, clothElf, clothGains)}
|
||||
</Row>
|
||||
</>
|
||||
)),
|
||||
minimizedDisplay: jsx(() => (
|
||||
<div>
|
||||
{name} - {format(plastic.value)} {plastic.displayName}
|
||||
</div>
|
||||
))
|
||||
};
|
||||
});
|
||||
|
|
|
@ -27,7 +27,7 @@ import { noPersist, persistent } from "game/persistence";
|
|||
import Decimal, { DecimalSource, format, formatGain, formatLimit, formatWhole } from "util/bignum";
|
||||
import { Direction, WithRequired } from "util/common";
|
||||
import { render, renderGrid, renderRow } from "util/vue";
|
||||
import { computed, ref } from "vue";
|
||||
import { computed, ref, watch } from "vue";
|
||||
import boxes from "./boxes";
|
||||
import cloth from "./cloth";
|
||||
import coal from "./coal";
|
||||
|
@ -83,6 +83,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
addend: dyes.boosts.blue1,
|
||||
description: "Blue Dye Boost 1",
|
||||
enabled: () => Decimal.gte(dyes.dyes.blue.amount.value, 1)
|
||||
})),
|
||||
createAdditiveModifier(() => ({
|
||||
addend: () => Decimal.pow(computedManualCuttingAmount.value, 0.99),
|
||||
description: "Hope Level 1",
|
||||
enabled: management.elfTraining.expandersElfTraining.milestones[0].earned
|
||||
}))
|
||||
]) as WithRequired<Modifier, "description" | "revert">;
|
||||
const trees = createResource(
|
||||
|
@ -201,6 +206,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 2).div(50);
|
||||
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
|
||||
if (Decimal.gte(v, 2e6)) v = Decimal.pow(v, 2).div(2e6);
|
||||
if (Decimal.gte(v, 2e30)) v = Decimal.pow(v,10000).div(Decimal.pow(2e30,9999));
|
||||
v = Decimal.pow(0.95, paper.books.cuttersBook.amount.value).times(v);
|
||||
return Decimal.times(100, v).add(200);
|
||||
},
|
||||
|
@ -217,8 +223,13 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 2).div(50);
|
||||
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
|
||||
if (Decimal.gte(v, 2e6)) v = Decimal.pow(v, 2).div(2e6);
|
||||
if (Decimal.gte(v, 2e30)) v = Decimal.pow(v,10000).div(Decimal.pow(2e30,9999));
|
||||
v = Decimal.pow(0.95, paper.books.plantersBook.amount.value).times(v);
|
||||
return Decimal.times(100, v).add(200);
|
||||
let cost = Decimal.times(100, v).add(200);
|
||||
if (management.elfTraining.planterElfTraining.milestones[3].earned.value) {
|
||||
cost = Decimal.div(cost, 10);
|
||||
}
|
||||
return cost;
|
||||
},
|
||||
display: {
|
||||
title: "Generic Planters",
|
||||
|
@ -232,6 +243,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
let v = this.amount.value;
|
||||
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
|
||||
if (Decimal.gte(v, 1e5)) v = Decimal.pow(v, 2).div(1e5);
|
||||
if (Decimal.gte(v, 1e15)) v = Decimal.pow(v, 10).div(1e135);
|
||||
v = Decimal.pow(0.95, paper.books.expandersBook.amount.value).times(v);
|
||||
return Decimal.pow(Decimal.add(v, 1), 1.5).times(500);
|
||||
},
|
||||
|
@ -282,7 +294,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
enabled: researchUpgrade2.bought
|
||||
})),
|
||||
createAdditiveModifier(() => ({
|
||||
addend: () => Decimal.div(workshop.foundationProgress.value, 5).floor(),
|
||||
addend: () =>
|
||||
Decimal.div(workshop.foundationProgress.value, 5).floor(),
|
||||
description: "10% Foundation Completed",
|
||||
enabled: workshop.milestones.autoCutMilestone1.earned
|
||||
})),
|
||||
|
@ -305,9 +318,28 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
multiplier: 4,
|
||||
description: "Lumberjack Jeans",
|
||||
enabled: cloth.treesUpgrades.treesUpgrade2.bought
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: () => Decimal.pow(1.1, main.day.value),
|
||||
description: "Holly Level 4",
|
||||
enabled: management.elfTraining.cutterElfTraining.milestones[3].earned
|
||||
})),
|
||||
createAdditiveModifier(() => ({
|
||||
addend: () =>
|
||||
Decimal.sub(lastAutoCuttingAmount.value, lastAutoPlantedAmount.value).max(0),
|
||||
description: "Ivy Level 5",
|
||||
enabled: management.elfTraining.planterElfTraining.milestones[4].earned
|
||||
}))
|
||||
]) as WithRequired<Modifier, "description" | "revert">;
|
||||
const computedAutoCuttingAmount = computed(() => autoCuttingAmount.apply(0));
|
||||
const lastAutoCuttingAmount = ref<DecimalSource>(0);
|
||||
setInterval(
|
||||
() =>
|
||||
watch(computedAutoCuttingAmount, cut => {
|
||||
lastAutoCuttingAmount.value = cut;
|
||||
}),
|
||||
0
|
||||
);
|
||||
|
||||
const manualPlantingAmount = createSequentialModifier(() => [
|
||||
createAdditiveModifier(() => ({
|
||||
|
@ -377,13 +409,32 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
description: "Ivy Level 1",
|
||||
enabled: management.elfTraining.planterElfTraining.milestones[0].earned
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: () => Decimal.pow(trees.value, 0.2).log10().pow_base(2),
|
||||
description: "Ivy Level 3",
|
||||
enabled: management.elfTraining.planterElfTraining.milestones[2].earned
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: 2,
|
||||
description: "Mary Level 2",
|
||||
enabled: management.elfTraining.planterElfTraining.milestones[1].earned
|
||||
description: "Mary Level 4",
|
||||
enabled: management.elfTraining.heatedPlanterElfTraining.milestones[3].earned
|
||||
})),
|
||||
createAdditiveModifier(() => ({
|
||||
addend: () =>
|
||||
Decimal.sub(lastAutoPlantedAmount.value, lastAutoCuttingAmount.value).max(0),
|
||||
description: "Ivy Level 5",
|
||||
enabled: management.elfTraining.planterElfTraining.milestones[4].earned
|
||||
}))
|
||||
]) as WithRequired<Modifier, "description" | "revert">;
|
||||
const computedAutoPlantingAmount = computed(() => autoPlantingAmount.apply(0));
|
||||
const lastAutoPlantedAmount = ref<DecimalSource>(0);
|
||||
setInterval(
|
||||
() =>
|
||||
watch(computedAutoPlantingAmount, planted => {
|
||||
lastAutoPlantedAmount.value = planted;
|
||||
}),
|
||||
0
|
||||
);
|
||||
|
||||
const logGain = createSequentialModifier(() => [
|
||||
createMultiplicativeModifier(() => ({
|
||||
|
@ -397,7 +448,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
enabled: researchUpgrade2.bought
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: () => Decimal.div(workshop.foundationProgress.value, 20).add(1),
|
||||
multiplier: () => workshop.milestones.extraExpansionMilestone1.earned.value
|
||||
? Decimal.pow(1.02, workshop.foundationProgress.value) : Decimal.div(workshop.foundationProgress.value, 20).add(1),
|
||||
description: "1% Foundation Completed",
|
||||
enabled: workshop.milestones.logGainMilestone1.earned
|
||||
})),
|
||||
|
@ -444,9 +496,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
enabled: dyes.upgrades.blueDyeUpg.bought
|
||||
})),
|
||||
createMultiplicativeModifier(() => ({
|
||||
multiplier: computed(() =>
|
||||
Decimal.add(computedAutoCuttingAmount.value, 1).log10().plus(1)
|
||||
),
|
||||
multiplier: computed(() => Decimal.add(computedAutoCuttingAmount.value, 1).root(9)),
|
||||
description: "Holly Level 1",
|
||||
enabled: management.elfTraining.cutterElfTraining.milestones[0].earned
|
||||
})),
|
||||
|
@ -770,6 +820,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
<Spacer />
|
||||
{renderRow(...row1Buyables)}
|
||||
</>
|
||||
)),
|
||||
minimizedDisplay: jsx(() => (
|
||||
<div>
|
||||
{name} - {format(logs.value)} {logs.displayName}
|
||||
</div>
|
||||
))
|
||||
};
|
||||
});
|
||||
|
|
|
@ -8,33 +8,24 @@ import { main } from "data/projEntry";
|
|||
import { createBar } from "features/bars/bar";
|
||||
import { createClickable } from "features/clickables/clickable";
|
||||
import {
|
||||
Conversion,
|
||||
addSoftcap,
|
||||
createIndependentConversion,
|
||||
createPolynomialScaling,
|
||||
ScalingFunction
|
||||
createPolynomialScaling
|
||||
} from "features/conversion";
|
||||
import { jsx, showIf } from "features/feature";
|
||||
import { createHotkey } from "features/hotkey";
|
||||
import { createMilestone } from "features/milestones/milestone";
|
||||
import { createResource, displayResource, Resource } from "features/resources/resource";
|
||||
import { createResource, displayResource } from "features/resources/resource";
|
||||
import { BaseLayer, createLayer } from "game/layers";
|
||||
import { createExponentialModifier, createSequentialModifier } from "game/modifiers";
|
||||
import { noPersist } from "game/persistence";
|
||||
import Decimal, { DecimalSource, formatWhole } from "util/bignum";
|
||||
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
|
||||
import { Direction } from "util/common";
|
||||
import { render } from "util/vue";
|
||||
import { computed, unref, watchEffect } from "vue";
|
||||
import elves from "./elves";
|
||||
import trees from "./trees";
|
||||
import management from "./management";
|
||||
|
||||
interface FoundationConversionOptions {
|
||||
scaling: ScalingFunction;
|
||||
baseResource: Resource;
|
||||
gainResource: Resource;
|
||||
roundUpCost: boolean;
|
||||
buyMax: boolean;
|
||||
spend: (gain: DecimalSource, spent: DecimalSource) => void;
|
||||
}
|
||||
import trees from "./trees";
|
||||
|
||||
const id = "workshop";
|
||||
const day = 2;
|
||||
|
@ -45,22 +36,34 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
|
||||
const foundationProgress = createResource<DecimalSource>(0, "foundation progress");
|
||||
|
||||
const foundationConversion: Conversion<FoundationConversionOptions> =
|
||||
createIndependentConversion(() => ({
|
||||
scaling: createPolynomialScaling(250, 1.5),
|
||||
const foundationConversion = createIndependentConversion(() => ({
|
||||
scaling: addSoftcap(
|
||||
addSoftcap(createPolynomialScaling(250, 1.5), 5387, 1 / 1e10),
|
||||
1e20,
|
||||
3e8
|
||||
),
|
||||
baseResource: trees.logs,
|
||||
gainResource: noPersist(foundationProgress),
|
||||
roundUpCost: true,
|
||||
buyMax: false,
|
||||
// buyMax: management.elfTraining.expandersElfTraining.milestones[2].earned,
|
||||
spend(gain, spent) {
|
||||
trees.logs.value = Decimal.sub(trees.logs.value, spent);
|
||||
}
|
||||
},
|
||||
costModifier: createSequentialModifier(() => [
|
||||
createExponentialModifier(() => ({
|
||||
exponent: 0.95,
|
||||
description: "Holly Level 5",
|
||||
enabled: management.elfTraining.cutterElfTraining.milestones[4].earned
|
||||
}))
|
||||
])
|
||||
}));
|
||||
|
||||
const buildFoundation = createClickable(() => ({
|
||||
display: jsx(() => (
|
||||
<>
|
||||
<b style="font-size: x-large">Build part of the foundation</b>
|
||||
<b style="font-size: x-large">
|
||||
Build {formatWhole(foundationConversion.actualGain.value)}% of the foundation
|
||||
</b>
|
||||
<br />
|
||||
<br />
|
||||
<span style="font-size: large">
|
||||
|
@ -75,10 +78,15 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
</span>
|
||||
</>
|
||||
)),
|
||||
visibility: () => showIf(Decimal.lt(foundationProgress.value, 100)),
|
||||
visibility: () =>
|
||||
showIf(
|
||||
Decimal.lt(foundationProgress.value, 100) ||
|
||||
management.elfTraining.expandersElfTraining.milestones[2].earned.value
|
||||
),
|
||||
canClick: () =>
|
||||
Decimal.gte(foundationConversion.actualGain.value, 1) &&
|
||||
Decimal.lt(foundationProgress.value, 100),
|
||||
Decimal.gte(trees.logs.value, foundationConversion.currentAt.value) &&
|
||||
(Decimal.lt(foundationProgress.value, 100) ||
|
||||
management.elfTraining.expandersElfTraining.milestones[2].earned.value),
|
||||
onClick() {
|
||||
if (!unref(this.canClick)) {
|
||||
return;
|
||||
|
@ -171,52 +179,67 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
}));
|
||||
const extraExpansionMilestone1 = createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "120% Foundation Completed",
|
||||
requirement: "200% Foundation Completed",
|
||||
effectDisplay: "The 1% milestone is now +2% and multiplicative"
|
||||
},
|
||||
shouldEarn: () => Decimal.gte(foundationProgress.value, 120),
|
||||
shouldEarn: () => Decimal.gte(foundationProgress.value, 200),
|
||||
visibility: () =>
|
||||
showIf(management.elfTraining.expandersElfTraining.milestones[2].earned.value),
|
||||
showIf(
|
||||
logGainMilestone3.earned.value &&
|
||||
management.elfTraining.expandersElfTraining.milestones[2].earned.value
|
||||
),
|
||||
showPopups: shouldShowPopups
|
||||
}));
|
||||
const extraExpansionMilestone2 = createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "140% Foundation Completed",
|
||||
requirement: "400% Foundation Completed",
|
||||
effectDisplay: "Gain +10% metal for every 10% foundation completed"
|
||||
},
|
||||
shouldEarn: () => Decimal.gte(foundationProgress.value, 140),
|
||||
shouldEarn: () => Decimal.gte(foundationProgress.value, 400),
|
||||
visibility: () =>
|
||||
showIf(management.elfTraining.expandersElfTraining.milestones[2].earned.value),
|
||||
showIf(
|
||||
extraExpansionMilestone1.earned.value &&
|
||||
management.elfTraining.expandersElfTraining.milestones[2].earned.value
|
||||
),
|
||||
showPopups: shouldShowPopups
|
||||
}));
|
||||
const extraExpansionMilestone3 = createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "160% Foundation Completed",
|
||||
requirement: "600% Foundation Completed",
|
||||
effectDisplay: "Gain +10% oil for every 10% foundation completed"
|
||||
},
|
||||
shouldEarn: () => Decimal.gte(foundationProgress.value, 160),
|
||||
shouldEarn: () => Decimal.gte(foundationProgress.value, 600),
|
||||
visibility: () =>
|
||||
showIf(management.elfTraining.expandersElfTraining.milestones[2].earned.value),
|
||||
showIf(
|
||||
extraExpansionMilestone2.earned.value &&
|
||||
management.elfTraining.expandersElfTraining.milestones[2].earned.value
|
||||
),
|
||||
showPopups: shouldShowPopups
|
||||
}));
|
||||
const extraExpansionMilestone4 = createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "180% Foundation Completed",
|
||||
requirement: "800% Foundation Completed",
|
||||
effectDisplay: "Gain +10% plastic for every 10% foundation completed"
|
||||
},
|
||||
shouldEarn: () => Decimal.gte(foundationProgress.value, 180),
|
||||
shouldEarn: () => Decimal.gte(foundationProgress.value, 800),
|
||||
visibility: () =>
|
||||
showIf(management.elfTraining.expandersElfTraining.milestones[2].earned.value),
|
||||
showIf(
|
||||
extraExpansionMilestone3.earned.value &&
|
||||
management.elfTraining.expandersElfTraining.milestones[2].earned.value
|
||||
),
|
||||
showPopups: shouldShowPopups
|
||||
}));
|
||||
const extraExpansionMilestone5 = createMilestone(() => ({
|
||||
display: {
|
||||
requirement: "200% Foundation Completed",
|
||||
requirement: "1000% Foundation Completed",
|
||||
effectDisplay: "Double paper, boxes, and all cloth actions"
|
||||
},
|
||||
shouldEarn: () => Decimal.gte(foundationProgress.value, 200),
|
||||
shouldEarn: () => Decimal.gte(foundationProgress.value, 1000),
|
||||
visibility: () =>
|
||||
showIf(management.elfTraining.expandersElfTraining.milestones[2].earned.value),
|
||||
showIf(
|
||||
extraExpansionMilestone4.earned.value &&
|
||||
management.elfTraining.expandersElfTraining.milestones[2].earned.value
|
||||
),
|
||||
showPopups: shouldShowPopups
|
||||
}));
|
||||
const milestones = {
|
||||
|
@ -280,11 +303,19 @@ const layer = createLayer(id, function (this: BaseLayer) {
|
|||
</h2>
|
||||
% completed
|
||||
</div>
|
||||
{Decimal.lt(foundationProgress.value, 100) ? <Spacer /> : null}
|
||||
{Decimal.lt(foundationProgress.value, 100) ||
|
||||
management.elfTraining.expandersElfTraining.milestones[2].earned.value ? (
|
||||
<Spacer />
|
||||
) : null}
|
||||
{render(buildFoundation)}
|
||||
<Spacer />
|
||||
{milestonesDisplay()}
|
||||
</>
|
||||
)),
|
||||
minimizedDisplay: jsx(() => (
|
||||
<div>
|
||||
{name} - {format(foundationProgress.value)} {foundationProgress.displayName}
|
||||
</div>
|
||||
))
|
||||
};
|
||||
});
|
||||
|
|
|
@ -148,7 +148,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
loreScene.value = -1;
|
||||
loreTitle.value = unref(layers[layer ?? "trees"]?.name ?? "");
|
||||
loreBody.value = story;
|
||||
player.devSpeed = null;
|
||||
if (player.autoPause) player.devSpeed = null;
|
||||
showLoreModal.value = true;
|
||||
}, 1000);
|
||||
}
|
||||
|
@ -262,23 +262,25 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
createDay(() => ({
|
||||
day: 12,
|
||||
shouldNotify: false,
|
||||
layer: null,
|
||||
layer: "management",
|
||||
symbol: managementSymbol,
|
||||
story: "You watch as the elves work, and you realize that they could probably be trained to help out better. Just then, Santa comes over to check on your progress. You reply that you're doing fine, except that the elves may need a bit of behavior management. Santa offers to help, saying that he doesn't want to leave you to do everything. Unfortunately for you, the behavior problems won't fix themselves, so let's get to work!",
|
||||
completedStory: ""
|
||||
completedStory:
|
||||
"Woo! You are exhausted - this layer felt really long to you. It's great seeing the elves so productive, although you worry a bit about your own job security now! Good Job!"
|
||||
})),
|
||||
createDay(() => ({
|
||||
day: 13,
|
||||
shouldNotify: false,
|
||||
layer: null, // ""
|
||||
layer: null, // "management" (advanced)
|
||||
symbol: "",
|
||||
story: "",
|
||||
completedStory: ""
|
||||
story: "So after a good night's rest you decide that maybe making these elves able to do all the work for you isn't something to be scared of, but rather encouraged. Let's spend another day continuing to train them up and really get this place spinning. They are Santa's elves after all, they're supposed to be able to run everything without you!",
|
||||
completedStory:
|
||||
"The elves are doing an incredible job, and Santa does not seem keen on firing you - Score! Now you can get to work on guiding this properly trained highly functional group of hard workers to make Christmas as great as possible. Good Job!"
|
||||
})),
|
||||
createDay(() => ({
|
||||
day: 14,
|
||||
shouldNotify: false,
|
||||
layer: null, // ""
|
||||
layer: null, // "letters to santa"
|
||||
symbol: "",
|
||||
story: "",
|
||||
completedStory: ""
|
||||
|
@ -372,7 +374,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
showLoreModal.value = true;
|
||||
day.value++;
|
||||
main.minimized.value = false;
|
||||
player.devSpeed = 0;
|
||||
if (player.autoPause) player.devSpeed = 0;
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -436,6 +438,7 @@ export const getInitialLayers = (
|
|||
plastic,
|
||||
dyes,
|
||||
wrappingPaper,
|
||||
management
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -459,7 +462,7 @@ export function fixOldSave(
|
|||
if (!["0.0", "0.1", "0.2", "0.3", "0.4"].includes(oldVersion ?? "")) {
|
||||
return;
|
||||
}
|
||||
player.offlineProd = false;
|
||||
/*player.offlineProd = false;
|
||||
delete player.layers?.management;
|
||||
if ((player.layers?.main as LayerData<typeof main> | undefined)?.days?.[11]) {
|
||||
(player.layers!.main as LayerData<typeof main>).days![11].opened = false;
|
||||
|
@ -470,6 +473,6 @@ export function fixOldSave(
|
|||
}
|
||||
if (player.tabs) {
|
||||
player.tabs = player.tabs.filter(l => l !== "management");
|
||||
}
|
||||
}*/
|
||||
}
|
||||
/* eslint-enable @typescript-eslint/no-unused-vars */
|
||||
|
|
BIN
src/data/symbols/letterbox.png
Normal file
BIN
src/data/symbols/letterbox.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
src/data/symbols/workshopMansion.png
Normal file
BIN
src/data/symbols/workshopMansion.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
|
@ -299,7 +299,12 @@ globalBus.on("loadSettings", settings => {
|
|||
registerSettingField(
|
||||
jsx(() => (
|
||||
<Toggle
|
||||
title="Hide Maxed Challenges"
|
||||
title={jsx(() => (
|
||||
<span class="option-title">
|
||||
Hide maxed challenges
|
||||
<desc>Hide challenges that have been fully completed.</desc>
|
||||
</span>
|
||||
))}
|
||||
onUpdate:modelValue={value => (settings.hideChallenges = value)}
|
||||
modelValue={settings.hideChallenges}
|
||||
/>
|
||||
|
|
|
@ -511,6 +511,8 @@ export function addSoftcap(
|
|||
): ScalingFunction {
|
||||
return {
|
||||
...scaling,
|
||||
currentAt: conversion => softcap(scaling.currentAt(conversion), unref(cap), Decimal.recip(unref(power))),
|
||||
nextAt: conversion => softcap(scaling.nextAt(conversion), unref(cap), Decimal.recip(unref(power))),
|
||||
currentGain: conversion =>
|
||||
softcap(scaling.currentGain(conversion), unref(cap), unref(power))
|
||||
};
|
||||
|
|
|
@ -204,7 +204,12 @@ const msDisplayOptions = Object.values(MilestoneDisplay).map(option => ({
|
|||
registerSettingField(
|
||||
jsx(() => (
|
||||
<Select
|
||||
title="Show Milestones"
|
||||
title={jsx(() => (
|
||||
<span class="option-title">
|
||||
Show milestones
|
||||
<desc>Select which milestones to display based on criterias.</desc>
|
||||
</span>
|
||||
))}
|
||||
options={msDisplayOptions}
|
||||
onUpdate:modelValue={value => (settings.msDisplay = value as MilestoneDisplay)}
|
||||
modelValue={settings.msDisplay}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
>
|
||||
<div class="main-display">
|
||||
<span v-if="showPrefix">You have </span>
|
||||
<ResourceVue :resource="resource" :color="color || 'white'" />
|
||||
<ResourceVue :resource="resource" :color="color || 'white'" :style="resourceStyle" />
|
||||
{{ resource.displayName
|
||||
}}<!-- remove whitespace -->
|
||||
<span v-if="effectComponent"
|
||||
|
@ -27,7 +27,7 @@
|
|||
>
|
||||
<div class="main-display">
|
||||
<span v-if="showPrefix">You have </span>
|
||||
<ResourceVue :resource="resource" :color="color || 'white'" />
|
||||
<ResourceVue :resource="resource" :color="color || 'white'" :style="resourceStyle" />
|
||||
{{ resource.displayName
|
||||
}}<!-- remove whitespace -->
|
||||
<span v-if="effectComponent"
|
||||
|
@ -56,6 +56,7 @@ const _props = withDefaults(defineProps<{
|
|||
color?: string;
|
||||
classes?: Record<string, boolean>;
|
||||
style?: StyleValue;
|
||||
resourceStyle?: StyleValue;
|
||||
effectDisplay?: CoercableComponent;
|
||||
productionDisplay?: CoercableComponent;
|
||||
sticky?: boolean
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<h2 :style="{ color, 'text-shadow': '0px 0px 10px ' + color }">
|
||||
<h2 :style="[{ color, 'text-shadow': '0px 0px 10px ' + color }, style ?? {}]">
|
||||
{{ amount }}
|
||||
</h2>
|
||||
</template>
|
||||
|
@ -7,11 +7,12 @@
|
|||
<script setup lang="ts">
|
||||
import type { Resource } from "features/resources/resource";
|
||||
import { displayResource } from "features/resources/resource";
|
||||
import { computed } from "vue";
|
||||
import { computed, StyleValue } from "vue";
|
||||
|
||||
const props = defineProps<{
|
||||
resource: Resource;
|
||||
color: string;
|
||||
style?: StyleValue;
|
||||
}>();
|
||||
|
||||
const amount = computed(() => displayResource(props.resource));
|
||||
|
|
|
@ -109,7 +109,7 @@ export interface LayerOptions {
|
|||
color?: Computable<string>;
|
||||
/**
|
||||
* The layout of this layer's features.
|
||||
* When the layer is open in {@link game/player.PlayerData.tabs}, this is the content that is display.
|
||||
* When the layer is open in {@link game/player.PlayerData.tabs}, this is the content that is displayed.
|
||||
*/
|
||||
display: Computable<CoercableComponent>;
|
||||
/** An object of classes that should be applied to the display. */
|
||||
|
@ -126,6 +126,11 @@ export interface LayerOptions {
|
|||
* Defaults to true.
|
||||
*/
|
||||
minimizable?: Computable<boolean>;
|
||||
/**
|
||||
* The layout of this layer's features.
|
||||
* When the layer is open in {@link game/player.PlayerData.tabs}, but the tab is {@link Layer.minimized} this is the content that is displayed.
|
||||
*/
|
||||
minimizedDisplay?: Computable<CoercableComponent>;
|
||||
/**
|
||||
* Whether or not to force the go back button to be hidden.
|
||||
* If true, go back will be hidden regardless of {@link data/projInfo.allowGoBack}.
|
||||
|
@ -170,6 +175,7 @@ export type Layer<T extends LayerOptions> = Replace<
|
|||
name: GetComputableTypeWithDefault<T["name"], string>;
|
||||
minWidth: GetComputableTypeWithDefault<T["minWidth"], 600>;
|
||||
minimizable: GetComputableTypeWithDefault<T["minimizable"], true>;
|
||||
minimizedDisplay: GetComputableType<T["minimizedDisplay"]>;
|
||||
forceHideGoBack: GetComputableType<T["forceHideGoBack"]>;
|
||||
}
|
||||
>;
|
||||
|
@ -231,6 +237,7 @@ export function createLayer<T extends LayerOptions>(
|
|||
setDefault(layer, "minWidth", 600);
|
||||
processComputable(layer as T, "minimizable");
|
||||
setDefault(layer, "minimizable", true);
|
||||
processComputable(layer as T, "minimizedDisplay");
|
||||
|
||||
return layer as unknown as Layer<T>;
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import "components/common/modifiers.css";
|
||||
import type { CoercableComponent } from "features/feature";
|
||||
import { jsx } from "features/feature";
|
||||
import settings from "game/settings";
|
||||
import type { DecimalSource } from "util/bignum";
|
||||
import Decimal, { format } from "util/bignum";
|
||||
import type { WithRequired } from "util/common";
|
||||
|
@ -9,6 +10,7 @@ import { convertComputable } from "util/computed";
|
|||
import { createLazyProxy } from "util/proxies";
|
||||
import { renderJSX } from "util/vue";
|
||||
import { computed, unref } from "vue";
|
||||
import player from "./player";
|
||||
|
||||
/**
|
||||
* An object that can be used to apply or unapply some modification to a number.
|
||||
|
@ -272,7 +274,7 @@ export function createModifierSection(
|
|||
baseText: CoercableComponent = "Base"
|
||||
) {
|
||||
return (
|
||||
<div>
|
||||
<div style={{"--unit": settings.alignUnits ? "'" + unit + "'" : ""}}>
|
||||
<h3>
|
||||
{title}
|
||||
{subtitle ? <span class="subtitle"> ({subtitle})</span> : null}
|
||||
|
|
|
@ -34,8 +34,9 @@ export interface PlayerData {
|
|||
modVersion: string;
|
||||
/** A dictionary of layer save data. */
|
||||
layers: Record<string, LayerData<unknown>>;
|
||||
/** Whether to use log for progress toward finishing the day, or use linear. */
|
||||
usingLog: boolean;
|
||||
|
||||
/** Should the game be paused when the player complete a day? */
|
||||
autoPause: boolean;
|
||||
}
|
||||
|
||||
/** The proxied player that is used to track NaN values. */
|
||||
|
@ -68,7 +69,8 @@ const state = reactive<PlayerData>({
|
|||
modID: "",
|
||||
modVersion: "",
|
||||
layers: {},
|
||||
usingLog: false
|
||||
|
||||
autoPause: true,
|
||||
});
|
||||
|
||||
/** Convert a player save data object into a JSON string. Unwraps refs. */
|
||||
|
|
|
@ -18,6 +18,13 @@ export interface Settings {
|
|||
theme: Themes;
|
||||
/** Whether or not to cap the project at 20 ticks per second. */
|
||||
unthrottled: boolean;
|
||||
|
||||
/** Game-specific settings */
|
||||
|
||||
/** Whether to use log for progress toward finishing the day, or use linear. */
|
||||
usingLog: boolean;
|
||||
/** Whether to align modifiers to the unit. */
|
||||
alignUnits: boolean;
|
||||
}
|
||||
|
||||
const state = reactive<Partial<Settings>>({
|
||||
|
@ -25,7 +32,10 @@ const state = reactive<Partial<Settings>>({
|
|||
saves: [],
|
||||
showTPS: true,
|
||||
theme: Themes.Nordic,
|
||||
unthrottled: false
|
||||
unthrottled: false,
|
||||
|
||||
usingLog: false,
|
||||
alignUnits: false,
|
||||
});
|
||||
|
||||
watch(
|
||||
|
@ -57,7 +67,10 @@ export const hardResetSettings = (window.hardResetSettings = () => {
|
|||
active: "",
|
||||
saves: [],
|
||||
showTPS: true,
|
||||
theme: Themes.Nordic
|
||||
theme: Themes.Nordic,
|
||||
|
||||
usingLog: false,
|
||||
alignUnits: false,
|
||||
};
|
||||
globalBus.emit("loadSettings", settings);
|
||||
Object.assign(state, settings);
|
||||
|
|
71
src/main.css
71
src/main.css
|
@ -66,3 +66,74 @@ ul {
|
|||
.Vue-Toastification__toast {
|
||||
margin: unset;
|
||||
}
|
||||
|
||||
/* Scrollbar stuff */
|
||||
|
||||
* {
|
||||
scrollbar-color: #ffffff0f var(--accent1);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
appearance: none;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: #ffffff0f;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
--back-color: var(--accent1);
|
||||
background: linear-gradient(90deg, var(--back-color), var(--back-color)) no-repeat content-box;
|
||||
border: 2px solid transparent;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
--back-color: var(--foreground);
|
||||
}
|
||||
::-webkit-scrollbar-button:single-button {
|
||||
--back-color: transparent;
|
||||
--arrow-color: var(--accent1);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
::-webkit-scrollbar-button:single-button:hover {
|
||||
--back-color: #ffffff0f;
|
||||
--arrow-color: var(--foreground);
|
||||
}
|
||||
::-webkit-scrollbar-button:single-button:active {
|
||||
--back-color: var(--foreground);
|
||||
--arrow-color: var(--background);
|
||||
}
|
||||
::-webkit-scrollbar-button:single-button:disabled {
|
||||
--arrow-color: var(--foreground);
|
||||
}
|
||||
::-webkit-scrollbar-button:single-button:vertical:decrement {
|
||||
background:
|
||||
conic-gradient(#0000 37.5%, var(--arrow-color) 37.5% 62.5%, #0000 62.5%) no-repeat content-box,
|
||||
linear-gradient(90deg, var(--back-color), var(--back-color)) no-repeat content-box;
|
||||
background-size: 60% 50%, 100% 100%;
|
||||
background-position: 50% 20%, 0% 0%;
|
||||
}
|
||||
::-webkit-scrollbar-button:single-button:vertical:increment {
|
||||
background:
|
||||
conic-gradient(var(--arrow-color) 12.5%, #0000 12.5% 87.5%, var(--arrow-color) 87.5%) no-repeat content-box,
|
||||
linear-gradient(90deg, var(--back-color), var(--back-color)) no-repeat content-box;
|
||||
background-size: 60% 50%, 100% 100%;
|
||||
background-position: 50% 80%, 0% 0%;
|
||||
}
|
||||
::-webkit-scrollbar-button:single-button:horizontal:decrement {
|
||||
background:
|
||||
conic-gradient(#0000 12.5%, var(--arrow-color) 12.5% 37.5%, #0000 37.5%) no-repeat content-box,
|
||||
linear-gradient(90deg, var(--back-color), var(--back-color)) no-repeat content-box;
|
||||
background-size: 50% 60%, 100% 100%;
|
||||
background-position: 20% 50%, 0% 0%;
|
||||
}
|
||||
::-webkit-scrollbar-button:single-button:horizontal:increment {
|
||||
background:
|
||||
conic-gradient(#0000 62.5%, var(--arrow-color) 62.5% 87.5%, #0000 87.5%) no-repeat content-box,
|
||||
linear-gradient(90deg, var(--back-color), var(--back-color)) no-repeat content-box;
|
||||
background-size: 50% 60%, 100% 100%;
|
||||
background-position: 80% 50%, 0% 0%;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner {
|
||||
background: #070710;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,11 @@ export default defineConfig({
|
|||
vue: "vue/dist/vue.esm-bundler.js"
|
||||
}
|
||||
},
|
||||
server: {
|
||||
hmr: {
|
||||
clientPort: process.env.CODESPACES ? 443 : undefined
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
vue(),
|
||||
vueJsx({
|
||||
|
|
Loading…
Reference in a new issue