Create progress tracker utility function

This commit is contained in:
Seth Posner 2022-12-05 16:30:23 -08:00
parent 65622c84c7
commit ee48800c37
5 changed files with 126 additions and 179 deletions

View file

@ -1,11 +1,12 @@
import Collapsible from "components/layout/Collapsible.vue";
import { createBar } from "features/bars/bar";
import type { Clickable, ClickableOptions, GenericClickable } from "features/clickables/clickable";
import { createClickable } from "features/clickables/clickable";
import type { GenericConversion } from "features/conversion";
import type { CoercableComponent, JSXFunction, OptionsFunc, Replace } from "features/feature";
import { jsx, setDefault } from "features/feature";
import { GenericMilestone } from "features/milestones/milestone";
import { displayResource } from "features/resources/resource";
import { displayResource, Resource, trackTotal } from "features/resources/resource";
import type { GenericTree, GenericTreeNode, TreeNode, TreeNodeOptions } from "features/trees/tree";
import { createTreeNode } from "features/trees/tree";
import type { Modifier } from "game/modifiers";
@ -14,7 +15,8 @@ import { DefaultValue, persistent } from "game/persistence";
import player from "game/player";
import type { DecimalSource } from "util/bignum";
import Decimal, { format } from "util/bignum";
import type { WithRequired } from "util/common";
import { formatWhole } from "util/break_eternity";
import { Direction, WithRequired } from "util/common";
import type {
Computable,
GetComputableType,
@ -22,10 +24,13 @@ import type {
ProcessedComputable
} from "util/computed";
import { convertComputable, processComputable } from "util/computed";
import { getFirstFeature, renderColJSX, renderJSX } from "util/vue";
import type { Ref } from "vue";
import { getFirstFeature, render, renderColJSX, renderJSX, VueFeature } from "util/vue";
import { Ref, watch, watchEffect } from "vue";
import { computed, unref } from "vue";
import "./common.css";
import { main } from "./projEntry";
import Spacer from "components/layout/Spacer.vue";
import Modal from "components/Modal.vue";
/** An object that configures a {@link ResetButton} */
export interface ResetButtonOptions extends ClickableOptions {
@ -389,3 +394,74 @@ export function createCollapsibleMilestones(milestones: Record<string, GenericMi
display
};
}
export function setUpDailyProgressTracker(options: {
resource: Resource,
goal: DecimalSource,
name: string,
day: number,
color: string,
modal?: {
show: Ref<boolean>,
display: VueFeature | CoercableComponent
}
}) {
const total = trackTotal(options.resource);
const dayProgress = createBar(() => ({
direction: Direction.Right,
width: 600,
height: 25,
fillStyle: { backgroundColor: options.color },
textStyle: { color: 'var(--feature-foreground)' },
progress: () =>
main.day.value === options.day
? Decimal.div(
Decimal.add(total.value, 1).log10(),
Decimal.log10(options.goal)
)
: 1,
display: jsx(() =>
main.day.value === options.day ? (
<>
{formatWhole(total.value)}/{formatWhole(options.goal)}
</>
) : (
""
)
)
}));
const trackerDisplay = jsx(() => <>
<div>
{main.day.value === options.day
? <>Reach {formatWhole(options.goal)} total {options.resource.displayName} to complete the day</>
: <>{options.name} Complete!</>
}
{
options.modal
? <> - <button
class="button"
style="display: inline-block;"
onClick={() => options.modal!.show.value = true}>
Check Modifiers
</button></>
: undefined
}
</div>
{render(dayProgress)}
{options.modal ? render(options.modal.display) : undefined}
</>);
watchEffect(() => {
if (main.day.value === options.day && Decimal.gte(total.value, options.goal)) {
main.completeDay();
}
});
return {
total,
trackerDisplay
}
}

View file

@ -3,6 +3,7 @@
* @hidden
*/
import Spacer from "components/layout/Spacer.vue";
import { setUpDailyProgressTracker } from "data/common";
import { main } from "data/projEntry";
import { createBar } from "features/bars/bar";
import { createBuyable, GenericBuyable } from "features/buyable";
@ -24,12 +25,8 @@ const day = 6;
const layer = createLayer(id, function (this: BaseLayer) {
const name = "Boxes";
const color = "#964B00";
const colorDark = "#964B00";
const totalBoxesGoal = 5e4;
const boxes = createResource<DecimalSource>(0, "boxes");
const totalBoxes = trackTotal(boxes);
const boxesConversion = createCumulativeConversion(() => ({
scaling: createPolynomialScaling(1e10, 1),
@ -148,35 +145,13 @@ const layer = createLayer(id, function (this: BaseLayer) {
})) as GenericBuyable;
const buyables = { logBoxesBuyable, ashBoxesBuyable, coalBoxesBuyable };
const dayProgress = createBar(() => ({
direction: Direction.Right,
width: 600,
height: 25,
fillStyle: `backgroundColor: ${colorDark}`,
textStyle: "color: var(--feature-foreground)",
progress: () =>
main.day.value === day
? Decimal.div(
Decimal.log10(Decimal.add(totalBoxes.value, 1)),
Decimal.log10(totalBoxesGoal)
)
: 1,
display: jsx(() =>
main.day.value === day ? (
<>
{formatWhole(totalBoxes.value)}/{formatWhole(totalBoxesGoal)}
</>
) : (
""
)
)
}));
watchEffect(() => {
if (main.day.value === day && Decimal.gte(totalBoxes.value, totalBoxesGoal)) {
main.completeDay();
}
});
const { total: totalBoxes, trackerDisplay } = setUpDailyProgressTracker({
resource: boxes,
goal: 5e4,
name,
day,
color
})
return {
name,
@ -190,14 +165,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
minWidth: 700,
display: jsx(() => (
<>
<div>
{main.day.value === day
? `Reach ${formatWhole(totalBoxesGoal)} total ${
boxes.displayName
} to complete the day`
: `${name} Complete!`}
</div>
{render(dayProgress)}
{render(trackerDisplay)}
<Spacer />
<MainDisplay resource={boxes} color={color} style="margin-bottom: 0" />
<Spacer />

View file

@ -7,20 +7,18 @@ import Modal from "components/Modal.vue";
import MainDisplay from "features/resources/MainDisplay.vue";
import Row from "components/layout/Row.vue";
import Column from "components/layout/Column.vue";
import { createCollapsibleModifierSections } from "data/common";
import { createCollapsibleModifierSections, setUpDailyProgressTracker } from "data/common";
import { main } from "data/projEntry";
import { createBar } from "features/bars/bar";
import { createBuyable, GenericBuyable } from "features/buyable";
import { createClickable } from "features/clickables/clickable";
import { jsx, JSXFunction, showIf, StyleValue, Visibility } from "features/feature";
import { createResource, Resource, trackTotal } from "features/resources/resource";
import { createResource, Resource } from "features/resources/resource";
import { globalBus } from "game/events";
import { BaseLayer, createLayer } from "game/layers";
import { persistent } from "game/persistence";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import { Direction } from "util/common";
import { render, renderRow } from "util/vue";
import { computed, ref, unref, watchEffect } from "vue";
import { computed, ref, unref } from "vue";
import trees from "./trees";
import {
createAdditiveModifier,
@ -60,31 +58,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
const colorText = "var(--foreground)";
const coal = createResource<DecimalSource>(0, "coal");
const totalCoal = trackTotal(coal);
const ash = createResource<DecimalSource>(0, "ash");
const totalCoalGoal = 1e7;
const dayProgress = createBar(() => ({
direction: Direction.Right,
width: 600,
height: 25,
fillStyle: `backgroundColor: ${colorCoal}`,
progress: () =>
main.day.value === day
? Decimal.log10(Decimal.add(totalCoal.value, 1)).div(Math.log10(totalCoalGoal))
: 1,
display: jsx(() =>
main.day.value === day ? (
<>
{formatWhole(totalCoal.value)}/{formatWhole(totalCoalGoal)}
</>
) : (
""
)
)
}));
const activeFires = persistent<DecimalSource>(0);
const fireLogs = computed(() => Decimal.times(activeFires.value, 1000));
const fireCoal = computed(() => Decimal.times(activeFires.value, 0.1));
@ -744,11 +719,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
ash.value = Decimal.times(diff, computedAshGain.value).plus(ash.value);
});
watchEffect(() => {
if (main.day.value === day && Decimal.gte(totalCoal.value, totalCoalGoal)) {
main.completeDay();
const { total: totalCoal, trackerDisplay } = setUpDailyProgressTracker({
resource: coal,
goal: 1e7,
name,
day,
color: colorCoal,
modal: {
show: showModifiersModal,
display: modifiersModal
}
});
})
return {
name,
@ -780,23 +761,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
minWidth: 700,
display: jsx(() => (
<>
<div>
{main.day.value === day
? `Reach ${formatWhole(totalCoalGoal)} ${
coal.displayName
} to complete the day`
: `${name} Complete!`}{" "}
-{" "}
<button
class="button"
style="display: inline-block;"
onClick={() => (showModifiersModal.value = true)}
>
Check Modifiers
</button>
</div>
{render(dayProgress)}
{render(modifiersModal)}
{render(trackerDisplay)}
<Spacer />
<MainDisplay
resource={coal}

View file

@ -3,6 +3,7 @@
* @hidden
*/
import Spacer from "components/layout/Spacer.vue";
import { setUpDailyProgressTracker } from "data/common";
import { main } from "data/projEntry";
import { createBar } from "features/bars/bar";
import { BuyableOptions, createBuyable, GenericBuyable } from "features/buyable";
@ -25,12 +26,8 @@ const day = 5;
const layer = createLayer(id, function (this: BaseLayer) {
const name = "Paper";
const color = "#E8DCB8";
const colorDark = "#E8DCB8";
const totalPaperGoal = 5e3;
const paper = createResource<DecimalSource>(0, "paper");
const totalPaper = trackTotal(paper);
const pulp = createResource<DecimalSource>(
computed(() =>
@ -162,34 +159,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
kilnBook
};
const dayProgress = createBar(() => ({
direction: Direction.Right,
width: 600,
height: 25,
fillStyle: `backgroundColor: ${colorDark}`,
textStyle: "color: var(--feature-foreground)",
progress: () =>
main.day.value === day
? Decimal.div(
Decimal.log10(Decimal.add(totalPaper.value, 1)),
Decimal.log10(totalPaperGoal)
)
: 1,
display: jsx(() =>
main.day.value === day ? (
<>
{formatWhole(totalPaper.value)}/{formatWhole(totalPaperGoal)}
</>
) : (
""
)
)
}));
watchEffect(() => {
if (main.day.value === day && Decimal.gte(totalPaper.value, totalPaperGoal)) {
main.completeDay();
}
const { total: totalPaper, trackerDisplay } = setUpDailyProgressTracker({
resource: paper,
goal: 5e3,
name,
day,
color
});
return {
@ -203,14 +178,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
minWidth: 700,
display: jsx(() => (
<>
<div>
{main.day.value === day
? `Reach ${formatWhole(totalPaperGoal)} total ${
paper.displayName
} to complete the day`
: `${name} Complete!`}
</div>
{render(dayProgress)}
{render(trackerDisplay)}
<Spacer />
<MainDisplay resource={paper} color={color} style="margin-bottom: 0" />
<Spacer />

View file

@ -4,7 +4,7 @@
*/
import Spacer from "components/layout/Spacer.vue";
import Modal from "components/Modal.vue";
import { createCollapsibleModifierSections } from "data/common";
import { createCollapsibleModifierSections, setUpDailyProgressTracker } from "data/common";
import { main } from "data/projEntry";
import { createBar } from "features/bars/bar";
import { createBuyable, GenericBuyable } from "features/buyable";
@ -12,7 +12,7 @@ import { createClickable } from "features/clickables/clickable";
import { jsx, showIf } from "features/feature";
import { createHotkey } from "features/hotkey";
import MainDisplay from "features/resources/MainDisplay.vue";
import { createResource, Resource, trackTotal } from "features/resources/resource";
import { createResource, Resource } from "features/resources/resource";
import { createUpgrade } from "features/upgrades/upgrade";
import { globalBus } from "game/events";
import { BaseLayer, createLayer } from "game/layers";
@ -46,11 +46,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
const colorDark = "green";
const logs = createResource<DecimalSource>(0, "logs");
const totalLogs = trackTotal(logs);
// Think of saplings as spent trees
const saplings = createResource<DecimalSource>(0, "saplings");
const totalLogGoal = 1e4;
const ema = ref<DecimalSource>(0);
const totalTrees = createSequentialModifier(() => [
@ -233,26 +231,6 @@ const layer = createLayer(id, function (this: BaseLayer) {
})) as GenericBuyable & { display: { title: string }; resource: Resource };
const row1Buyables = [autoCuttingBuyable1, autoPlantingBuyable1, expandingForestBuyable];
const dayProgress = createBar(() => ({
direction: Direction.Right,
width: 600,
height: 25,
fillStyle: `backgroundColor: ${colorDark}`,
progress: () =>
main.day.value === day
? Decimal.log10(Decimal.add(totalLogs.value, 1)).div(Math.log10(totalLogGoal))
: 1,
display: jsx(() =>
main.day.value === day ? (
<>
{formatWhole(totalLogs.value)}/{formatWhole(totalLogGoal)}
</>
) : (
""
)
)
}));
const manualCuttingAmount = createSequentialModifier(() => [
createAdditiveModifier(() => ({
addend: 1,
@ -641,12 +619,6 @@ const layer = createLayer(id, function (this: BaseLayer) {
saplings.value = Decimal.sub(saplings.value, amountPlanted);
});
watchEffect(() => {
if (main.day.value === day && Decimal.gte(totalLogs.value, totalLogGoal)) {
main.completeDay();
}
});
const netSaplingGain = computed(() =>
Decimal.sub(computedAutoCuttingAmount.value, computedAutoPlantingAmount.value)
);
@ -669,6 +641,18 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const { total: totalLogs, trackerDisplay } = setUpDailyProgressTracker({
resource: logs,
goal: 1e4,
name,
day,
color: colorDark,
modal: {
show: showModifiersModal,
display: modifiersModal
}
});
return {
name,
color: colorBright,
@ -689,21 +673,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
minWidth: 700,
display: jsx(() => (
<>
<div>
{main.day.value === day
? `Reach ${formatWhole(1e4)} ${logs.displayName} to complete the day`
: `${name} Complete!`}{" "}
-{" "}
<button
class="button"
style="display: inline-block;"
onClick={() => (showModifiersModal.value = true)}
>
Check Modifiers
</button>
</div>
{render(dayProgress)}
{render(modifiersModal)}
{render(trackerDisplay)}
<Spacer />
<MainDisplay
resource={logs}