This commit is contained in:
Seth Posner 2022-12-05 10:27:42 -08:00
commit 65622c84c7
13 changed files with 132 additions and 7428 deletions

7406
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -32,7 +32,7 @@
<Scene :day="main.loreScene.value" />
<br />
You can help continue the <i>advent</i>ure at:
<a href="https://discord.gg/WzejVAx" class="info-modal-discord-link">
<a href="https://discord.gg/WzejVAx" class="info-modal-discord-link" target="_blank">
<span class="material-icons info-modal-discord">discord</span>
The Paper Pilot Community
</a>

View file

@ -21,19 +21,32 @@
<div class="link" @click="openChangelog">Changelog</div>
<br />
<div>
<a :href="discordLink" v-if="discordLink" class="info-modal-discord-link">
<a
:href="discordLink"
v-if="discordLink"
class="info-modal-discord-link"
target="_blank"
>
<span class="material-icons info-modal-discord">discord</span>
{{ discordName }}
</a>
</div>
<div>
<a href="https://discord.gg/WzejVAx" class="info-modal-discord-link">
<a
href="https://discord.gg/WzejVAx"
class="info-modal-discord-link"
target="_blank"
>
<span class="material-icons info-modal-discord">discord</span>
The Paper Pilot Community
</a>
</div>
<div>
<a href="https://discord.gg/F3xveHV" class="info-modal-discord-link">
<a
href="https://discord.gg/F3xveHV"
class="info-modal-discord-link"
target="_blank"
>
<span class="material-icons info-modal-discord">discord</span>
The Modding Tree
</a>

View file

@ -35,6 +35,7 @@ const props = defineProps<{
day: number;
symbol: string;
opened: Ref<boolean>;
recentlyUpdated: Ref<boolean>;
shouldNotify: ProcessedComputable<boolean>;
}>();

View file

@ -74,6 +74,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
title: "Carry logs in boxes",
description: "Double log gain and unlock a new elf for training"
},
onPurchase () {
main.days[3].recentlyUpdated.value = true;
},
resource: boxes,
cost: 100
}));
@ -82,6 +85,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
title: "Carry ash in boxes",
description: "Double ash gain and unlock a new elf for training"
},
onPurchase () {
main.days[3].recentlyUpdated.value = true;
},
resource: boxes,
cost: 1000
}));
@ -90,6 +96,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
title: "Carry coal in boxes",
description: "Double coal gain and unlock a new elf for training"
},
onPurchase () {
main.days[3].recentlyUpdated.value = true;
},
resource: boxes,
cost: 4000
}));

View file

@ -92,7 +92,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
const buildFire = createBuyable(() => ({
resource: trees.logs,
cost() {
let v = Decimal.times(buildBonfire.amount.value, unref(buildBonfire.cost!)).plus(this.amount.value);
let v = Decimal.times(buildBonfire.amount.value, unref(buildBonfire.cost!)).plus(
this.amount.value
);
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
if (Decimal.gte(v, 10000)) v = Decimal.pow(v, 2).div(10000);
v = Decimal.pow(0.95, paper.books.smallFireBook.amount.value).times(v);
@ -586,7 +588,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
createExponentialModifier(() => ({
exponent: 1.25,
description: "3 Elves Trained",
enabled: elves.milestones[2].earned
enabled: elves.milestones[2].earned,
supportLowNumbers: true
}))
]);
const computedCoalGain = computed(() => coalGain.apply(0));

View file

@ -286,6 +286,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
hasToggle?: boolean;
toggleDesc?: string;
onAutoPurchase?: VoidFunction;
onPurchase?: VoidFunction; // Will get overriden by the custom onpurchase, but that's fine
} & Partial<ClickableOptions>
) {
const trainingCost = computed(() => Decimal.pow(4, totalElves.value).times(1e6));
@ -353,7 +354,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
showCost: !upgrade.bought.value
}),
style: "width: 190px",
onPurchase: elfReset.reset
onPurchase () {
options.onPurchase?.();
elfReset.reset();
}
};
}) as GenericUpgrade & {
buyProgress: Ref<number>;
@ -420,6 +424,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
if (smallFireElf.toggle.value) {
coal.activeFires.value = Decimal.add(coal.activeFires.value, 1);
}
},
onPurchase () {
main.days[4].recentlyUpdated.value = true;
}
});
const bonfireElf = createElf({
@ -437,6 +444,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
coal.buildFire.amount.value = Decimal.sub(coal.buildFire.amount.value, unref(this.buyable.cost!));
coal.activeFires.value = Decimal.sub(coal.activeFires.value, unref(this.buyable.cost!));
}
},
onPurchase () {
main.days[4].recentlyUpdated.value = true;
}
});
const kilnElf = createElf({
@ -452,6 +462,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
if (kilnElf.toggle.value) {
coal.activeKilns.value = Decimal.add(coal.activeKilns.value, 1);
}
},
onPurchase () {
main.days[4].recentlyUpdated.value = true;
}
});
const fireElves = [smallFireElf, bonfireElf, kilnElf];

View file

@ -24,7 +24,7 @@ import {
Modifier
} from "game/modifiers";
import { persistent } from "game/persistence";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import Decimal, { DecimalSource, format, formatWhole, formatLimit } from "util/bignum";
import { Direction, WithRequired } from "util/common";
import { render, renderRow } from "util/vue";
import { computed, ref, watchEffect } from "vue";
@ -39,7 +39,7 @@ const day = 1;
// how much to prioritize this' income
// vs the previous ones
const SMOOTHING_FACTOR = 0.5;
const SMOOTHING_FACTOR = 0.1;
const layer = createLayer(id, function (this: BaseLayer) {
const name = "Trees";
const colorBright = "#4BDC13";
@ -79,6 +79,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
computed(() => Decimal.sub(totalTrees.apply(10), saplings.value)),
"trees"
);
const computedTotalTrees = computed(() => totalTrees.apply(10));
const manualCutUpgrade1 = createUpgrade(() => ({
resource: logs,
@ -421,7 +422,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
enabled: boxes.upgrades.logsUpgrade.bought
})),
createExponentialModifier(() => ({
exponent: 1.1,
exponent: 1.2,
description: "100% Foundation Completed",
enabled: workshop.milestones.logGainMilestone3.earned
}))
@ -623,7 +624,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
trees.value,
Decimal.times(computedAutoCuttingAmount.value, diff)
);
const logsGained = logGain.apply(amountCut);
const logsGained = Decimal.mul(logGain.apply(1), amountCut);
const effectiveLogsGained = Decimal.div(logsGained, diff);
ema.value = Decimal.mul(effectiveLogsGained, SMOOTHING_FACTOR).add(
@ -708,16 +709,13 @@ const layer = createLayer(id, function (this: BaseLayer) {
resource={logs}
color={colorBright}
style="margin-bottom: 0"
effectDisplay={
productionDisplay={
Decimal.gt(computedAutoCuttingAmount.value, 0)
? `expected: +${format(
logGain.apply(computedAutoCuttingAmount.value)
)}/s, average: +${format(ema.value)}/s (${format(
Decimal.div(
ema.value,
logGain.apply(computedAutoCuttingAmount.value)
).mul(100)
)}% efficent)`
? `+${format(ema.value)}/s average<br/>equilibrium: +${formatLimit([
[Decimal.mul(logGain.apply(1), computedAutoCuttingAmount.value), "cutting speed"],
[Decimal.mul(logGain.apply(1), computedAutoPlantingAmount.value), "planting speed"],
[Decimal.mul(logGain.apply(1), Decimal.mul(computedTotalTrees.value, 20)), "forest cap"]
], "/s")}`
: undefined
}
/>
@ -725,7 +723,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
resource={saplings}
color={colorDark}
style="margin-bottom: 0"
effectDisplay={
productionDisplay={
{
[-1]: `${formatWhole(netSaplingGain.value)}/s`,
0: undefined,
@ -737,7 +735,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
resource={trees}
color={colorDark}
style="margin-bottom: 0"
effectDisplay={
productionDisplay={
{
[-1]: `${formatWhole(netTreeGain.value)}/s`,
0: undefined,
@ -748,10 +746,6 @@ const layer = createLayer(id, function (this: BaseLayer) {
<Spacer />
{renderRow(cutTree, plantTree)}
<div>Tip: You can hold down on actions to perform them automatically</div>
<div>
Note: your average log gain will be equal to your expected log gain if you have
enough trees to support your chopping
</div>
<Spacer />
{renderRow(...row1Upgrades)}
{renderRow(...row2Upgrades)}

View file

@ -18,7 +18,7 @@ import { createHotkey } from "features/hotkey";
import { createMilestone } from "features/milestones/milestone";
import { createResource, displayResource, Resource } from "features/resources/resource";
import { BaseLayer, createLayer } from "game/layers";
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";
@ -161,7 +161,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
const logGainMilestone3 = createMilestone(() => ({
display: {
requirement: "100% Foundation Completed",
effectDisplay: "Trees' log gain is now raised to the 1.1th power"
effectDisplay: "Log per tree is raised to the 1.2th power"
},
shouldEarn: () => Decimal.gte(foundationProgress.value, 100),
visibility: () => showIf(morePlantsMilestone1.earned.value),
@ -216,10 +216,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
</div>
{render(dayProgress)}
<Spacer />
{render(buildFoundation)}
<div>
<span>The foundation is </span>
<h2 style={`color: ${color}; text-shadow: 0 0 10px ${color}`}>
{ formatWhole( foundationProgress.value ) }
</h2>
% completed
</div>
{Decimal.lt(foundationProgress.value, 100) ? (
<div>You have {formatWhole(foundationProgress.value)}% completed</div>
<Spacer />
) : null}
{render(buildFoundation)}
<Spacer />
{milestonesDisplay()}
</>

View file

@ -11,7 +11,12 @@ import { persistent } from "game/persistence";
import type { PlayerData } from "game/player";
import player from "game/player";
import { format, formatTime } from "util/bignum";
import { Computable, convertComputable, ProcessedComputable } from "util/computed";
import {
Computable,
convertComputable,
processComputable,
ProcessedComputable
} from "util/computed";
import { createLazyProxy } from "util/proxies";
import { renderRow, VueFeature } from "util/vue";
import type { Ref } from "vue";
@ -38,6 +43,7 @@ export interface Day extends VueFeature {
story: string;
completedStory: string;
opened: Ref<boolean>;
recentlyUpdated: Ref<boolean>; // Has the tab recieved an update since the player last opened it?
shouldNotify: ProcessedComputable<boolean>;
}
@ -60,24 +66,39 @@ export const main = createLayer("main", function (this: BaseLayer) {
}
): Day {
const opened = persistent<boolean>(false);
const recentlyUpdated = persistent<boolean>(false);
return createLazyProxy(() => {
const day = optionsFunc();
const shouldNotify = convertComputable(day.shouldNotify);
const optionsShouldNotify = convertComputable(day.shouldNotify);
const shouldNotify = convertComputable(
() => unref(optionsShouldNotify) || unref(recentlyUpdated)
);
return {
...day,
opened,
shouldNotify,
recentlyUpdated,
[Component]: Day as GenericComponent,
[GatherProps]: function (this: Day) {
const { day, layer, symbol, opened, shouldNotify, story, completedStory } =
this;
const {
day,
layer,
symbol,
opened,
shouldNotify,
story,
completedStory,
recentlyUpdated
} = this;
return {
day,
symbol,
opened,
recentlyUpdated,
shouldNotify,
onOpenLore() {
const completed = main.day.value > day;
@ -91,6 +112,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
showLoreModal.value = true;
},
onOpenLayer() {
recentlyUpdated.value = false;
// 1468 is because two tabs with minWidth of 700px plus the minimized calendar of 60px plus 2 dividers of 4px each
if (window.matchMedia("(min-width: 1468px)").matches) {
// Desktop, allow multiple tabs to be open

View file

@ -13,6 +13,10 @@
<span v-if="effectComponent"
>, <component :is="effectComponent" ref="effectRef"
/></span>
<span v-if="productionComponent">
<br/>
<component :is="productionComponent" ref="effectRef"
/></span>
</div>
</div>
</Sticky>
@ -34,6 +38,7 @@ const _props = defineProps<{
classes?: Record<string, boolean>;
style?: StyleValue;
effectDisplay?: CoercableComponent;
productionDisplay?: CoercableComponent;
}>();
const props = toRefs(_props);
@ -43,6 +48,10 @@ const effectComponent = computeOptionalComponent(
props.effectDisplay as Ref<CoercableComponent | undefined>
);
const productionComponent = computeOptionalComponent(
props.productionDisplay as Ref<CoercableComponent | undefined>
);
const showPrefix = computed(() => {
return Decimal.lt(props.resource.value, "1e1000");
});

View file

@ -12,6 +12,7 @@ export const {
formatTime,
toPlaces,
formatSmall,
formatLimit,
invertOOM
} = numberUtils;
@ -29,6 +30,7 @@ declare global {
formatTime: (s: number) => string;
toPlaces: (x: DecimalSource, precision: number, maxAccepted: DecimalSource) => string;
formatSmall: (x: DecimalSource, precision?: number) => string;
formatLimit: (list: [DecimalSource, string][], unit: string) => string ;
invertOOM: (x: DecimalSource) => Decimal;
}
}
@ -41,6 +43,7 @@ window.formatWhole = formatWhole;
window.formatTime = formatTime;
window.toPlaces = toPlaces;
window.formatSmall = formatSmall;
window.formatLimit = formatLimit;
window.invertOOM = invertOOM;
export default Decimal;

View file

@ -194,3 +194,15 @@ export function invertOOM(x: DecimalSource): Decimal {
return x;
}
export function formatLimit(list: [DecimalSource, string][], unit: string): string {
let num = list[0][0];
let str = list[0][1];
for (let i = 1; i < list.length; i++) {
if (Decimal.lt(list[i][0], num)) {
num = list[i][0];
str = list[i][1];
}
}
return format(num) + unit + ", limited by " + str;
}