some more minor fixes and a hotfix for codespaces

This commit is contained in:
circle-gon 2022-12-12 22:54:01 +00:00
parent 6d268f95fb
commit ecfa65548d
2 changed files with 169 additions and 94 deletions

View file

@ -11,16 +11,14 @@ import { createLayer } from "game/layers";
import { Persistent, persistent } from "game/persistence"; import { Persistent, persistent } from "game/persistence";
import Decimal, { DecimalSource, format, formatTime, formatWhole } from "util/bignum"; import Decimal, { DecimalSource, format, formatTime, formatWhole } from "util/bignum";
import { Direction } from "util/common"; import { Direction } from "util/common";
import { render, renderCol, renderGrid, renderRow } from "util/vue"; import { render, renderCol, renderGrid } from "util/vue";
import { computed, ComputedRef, ref, Ref } from "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 elves from "./elves";
import trees from "./trees"; import trees from "./trees";
import { globalBus } from "game/events"; import { globalBus } from "game/events";
import { createMultiplicativeModifier, createSequentialModifier, Modifier } from "game/modifiers"; import { createMultiplicativeModifier, createSequentialModifier, Modifier } from "game/modifiers";
import Modal from "components/Modal.vue"; import Modal from "components/Modal.vue";
import { createBuyable, GenericBuyable } from "features/buyable"; import { createBuyable } from "features/buyable";
import { createUpgrade } from "features/upgrades/upgrade"; import { createUpgrade } from "features/upgrades/upgrade";
import coal from "./coal"; import coal from "./coal";
import paper from "./paper"; import paper from "./paper";
@ -35,16 +33,16 @@ const day = 12;
const advancedDay = 13; const advancedDay = 13;
interface ElfTrainingClickable extends GenericClickable { interface ElfTrainingClickable extends GenericClickable {
name: string, name: string;
state: Persistent<boolean>, state: Persistent<boolean>;
displayMilestone: JSXFunction, displayMilestone: JSXFunction;
level: ComputedRef<number>, level: ComputedRef<number>;
exp: Persistent<DecimalSource>, exp: Persistent<DecimalSource>;
milestones: GenericMilestone[], milestones: GenericMilestone[];
timeForExp: ComputedRef<DecimalSource>, timeForExp: ComputedRef<DecimalSource>;
amountOfTimesDone: Ref<number>, amountOfTimesDone: Ref<number>;
elfXPGainComputed: ComputedRef<DecimalSource>, elfXPGainComputed: ComputedRef<DecimalSource>;
elfXPGain: Modifier, elfXPGain: Modifier;
} }
const layer = createLayer(id, () => { const layer = createLayer(id, () => {
@ -59,7 +57,10 @@ const layer = createLayer(id, () => {
height: 25, height: 25,
fillStyle: `backgroundColor: ${color}`, fillStyle: `backgroundColor: ${color}`,
progress: () => progress: () =>
main.day.value === day ? Object.values(elfTraining).reduce((acc, curr) => acc + curr.level.value / 3, 0) / Object.keys(elves).length : 1, main.day.value === day
? Object.values(elfTraining).reduce((acc, curr) => acc + curr.level.value / 3, 0) /
Object.keys(elves).length
: 1,
display: jsx(() => display: jsx(() =>
main.day.value === day ? ( main.day.value === day ? (
<> <>
@ -80,7 +81,6 @@ const layer = createLayer(id, () => {
return elfLevel; return elfLevel;
}); });
// ------------------------------------------------------------------------------- Upgrades // ------------------------------------------------------------------------------- Upgrades
const teaching = createUpgrade(() => ({ const teaching = createUpgrade(() => ({
@ -143,15 +143,22 @@ const layer = createLayer(id, () => {
"margin-top": "8px", "margin-top": "8px",
"box-shadow": focusTargets.value[elf.name] "box-shadow": focusTargets.value[elf.name]
? "0 0 12px " + (currentShown.value == elf.name ? "black" : "white") ? "0 0 12px " + (currentShown.value == elf.name ? "black" : "white")
: "", : ""
}), }),
baseStyle: "margin-top: 0", baseStyle: "margin-top: 0",
fillStyle: "margin-top: 0; transition-duration: 0s", 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), progress: () => Decimal.div(expToNextLevel.value, expRequiredForNextLevel.value),
display: jsx(() => Decimal.gte(level.value, schools.amount.value) display: jsx(() =>
? <>Limit reached</> Decimal.gte(level.value, schools.amount.value) ? (
: <>{format(expToNextLevel.value)}/{format(expRequiredForNextLevel.value)} XP</>) <>Limit reached</>
) : (
<>
{format(expToNextLevel.value)}/{format(expRequiredForNextLevel.value)} XP
</>
)
)
})); }));
const { collapseMilestones: state, display: displayMilestone } = const { collapseMilestones: state, display: displayMilestone } =
createCollapsibleMilestones(milestones as Record<number, GenericMilestone>); createCollapsibleMilestones(milestones as Record<number, GenericMilestone>);
@ -163,7 +170,7 @@ const layer = createLayer(id, () => {
createMultiplicativeModifier(() => ({ createMultiplicativeModifier(() => ({
multiplier: focusMulti, multiplier: focusMulti,
description: "Focus Multiplier", description: "Focus Multiplier",
enabled: () => focusRolling.value <= 0 && focusTargets.value[elf.name] == true enabled: () => focusTime.value > 0 && focusTargets.value[elf.name] == true
})), })),
...modifiers ...modifiers
]); ]);
@ -173,10 +180,9 @@ const layer = createLayer(id, () => {
title: elf.name, title: elf.name,
description: jsx(() => ( description: jsx(() => (
<> <>
{elf.name} is currently at level {formatWhole(level.value)}, and {elf.name} is currently at level {formatWhole(level.value)}, and achieved a
achieved a total of {format(exp.value)} XP. total of {format(exp.value)} XP. They buy buyables{" "}
They buy buyables {formatWhole(elf.computedAutoBuyCooldown.value)} times per {formatWhole(elf.computedAutoBuyCooldown.value)} times per second, gaining{" "}
second, gaining{" "}
{Decimal.gte(level.value, schools.amount.value) {Decimal.gte(level.value, schools.amount.value)
? 0 ? 0
: format( : format(
@ -192,7 +198,7 @@ const layer = createLayer(id, () => {
}, },
style: () => ({ style: () => ({
width: "190px", width: "190px",
background: currentShown.value == elf.name ? "var(--foreground)" : "", background: currentShown.value == elf.name ? "var(--foreground)" : ""
}), }),
onClick() { onClick() {
currentShown.value = elf.name; currentShown.value = elf.name;
@ -220,7 +226,12 @@ const layer = createLayer(id, () => {
createMilestone(() => ({ createMilestone(() => ({
display: { display: {
requirement: "Holly Level 1", requirement: "Holly Level 1",
effectDisplay: jsx(() => <>Multiply log gain by <sup>3</sup><Sqrt>Cutter amount</Sqrt>.</>) effectDisplay: jsx(() => (
<>
Multiply log gain by <sup>3</sup>
<Sqrt>Cutter amount</Sqrt>.
</>
))
}, },
shouldEarn: () => cutterElfTraining.level.value >= 1 shouldEarn: () => cutterElfTraining.level.value >= 1
})), })),
@ -235,7 +246,12 @@ const layer = createLayer(id, () => {
createMilestone(() => ({ createMilestone(() => ({
display: { display: {
requirement: "Holly Level 3", requirement: "Holly Level 3",
effectDisplay: jsx(() => <>Multiply all cloth actions' effectiveness by <sup>3</sup><Sqrt>Cutter amount</Sqrt>.</>) effectDisplay: jsx(() => (
<>
Multiply all cloth actions' effectiveness by <sup>3</sup>
<Sqrt>Cutter amount</Sqrt>.
</>
))
}, },
visibility: () => showIf(cutterElfMilestones[1].earned.value), visibility: () => showIf(cutterElfMilestones[1].earned.value),
shouldEarn: () => cutterElfTraining.level.value >= 3 shouldEarn: () => cutterElfTraining.level.value >= 3
@ -276,7 +292,14 @@ const layer = createLayer(id, () => {
createMilestone(() => ({ createMilestone(() => ({
display: { display: {
requirement: "Ivy Level 3", 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(() => (
<>
Planting speed is multiplied by 2
<sup>
(log<sub>10</sub>(logs)<sup>0.2</sup>)
</sup>
</>
))
}, },
visibility: () => showIf(planterElfMilestones[1].earned.value), visibility: () => showIf(planterElfMilestones[1].earned.value),
shouldEarn: () => planterElfTraining.level.value >= 3 shouldEarn: () => planterElfTraining.level.value >= 3
@ -317,7 +340,8 @@ const layer = createLayer(id, () => {
createMilestone(() => ({ createMilestone(() => ({
display: { display: {
requirement: "Hope Level 3", requirement: "Hope Level 3",
effectDisplay: "The workshop can be expanded past 100%, but costs scale faster. It also buys max now." effectDisplay:
"The workshop can be expanded past 100%, but costs scale faster. It also buys max now."
}, },
visibility: () => showIf(expanderElfMilestones[1].earned.value), visibility: () => showIf(expanderElfMilestones[1].earned.value),
shouldEarn: () => expandersElfTraining.level.value >= 3 shouldEarn: () => expandersElfTraining.level.value >= 3
@ -418,7 +442,11 @@ const layer = createLayer(id, () => {
createMilestone(() => ({ createMilestone(() => ({
display: { display: {
requirement: "Mary Level 5", 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: () => visibility: () =>
showIf(heatedPlanterElfMilestones[3].earned.value && main.day.value >= 13), showIf(heatedPlanterElfMilestones[3].earned.value && main.day.value >= 13),
@ -429,7 +457,11 @@ const layer = createLayer(id, () => {
createMilestone(() => ({ createMilestone(() => ({
display: { display: {
requirement: "Noel Level 1", 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: () => heatedPlanterElfTraining.level.value >= 1
})), })),
@ -452,7 +484,11 @@ const layer = createLayer(id, () => {
createMilestone(() => ({ createMilestone(() => ({
display: { display: {
requirement: "Noel Level 4", 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: () => visibility: () =>
showIf(fertilizerElfMilestones[2].earned.value && main.day.value >= 13), showIf(fertilizerElfMilestones[2].earned.value && main.day.value >= 13),
@ -620,7 +656,11 @@ const layer = createLayer(id, () => {
createMilestone(() => ({ createMilestone(() => ({
display: { display: {
requirement: "Star Level 4", 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), visibility: () => showIf(paperElfMilestones[2].earned.value && main.day.value >= 13),
shouldEarn: () => paperElfTraining.level.value >= 4 shouldEarn: () => paperElfTraining.level.value >= 4
@ -638,7 +678,11 @@ const layer = createLayer(id, () => {
createMilestone(() => ({ createMilestone(() => ({
display: { display: {
requirement: "Bell Level 1", 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 shouldEarn: () => boxElfTraining.level.value >= 1
})), })),
@ -686,7 +730,11 @@ const layer = createLayer(id, () => {
createMilestone(() => ({ createMilestone(() => ({
display: { display: {
requirement: "Gingersnap Level 2", 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), visibility: () => showIf(clothElfMilestones[0].earned.value),
shouldEarn: () => clothElfTraining.level.value >= 2 shouldEarn: () => clothElfTraining.level.value >= 2
@ -699,26 +747,39 @@ const layer = createLayer(id, () => {
visibility: () => showIf(clothElfMilestones[1].earned.value), visibility: () => showIf(clothElfMilestones[1].earned.value),
shouldEarn: () => clothElfTraining.level.value >= 3, shouldEarn: () => clothElfTraining.level.value >= 3,
onComplete() { onComplete() {
(["red", "yellow", "blue", "orange", "green", "purple"] as const).forEach(dyeColor => { (["red", "yellow", "blue", "orange", "green", "purple"] as const).forEach(
dyes.dyes[dyeColor].amount.value = 0; dyeColor => {
dyes.dyes[dyeColor].buyable.amount.value = 0; dyes.dyes[dyeColor].amount.value = 0;
}); dyes.dyes[dyeColor].buyable.amount.value = 0;
}
);
} }
})), })),
createMilestone(() => ({ createMilestone(() => ({
display: { display: {
requirement: "Gingersnap Level 4", requirement: "Gingersnap Level 4",
effectDisplay: jsx(() => <>Multiply ALL dye gain by{" "} effectDisplay: jsx(() => (
<Fraction><div><Sqrt>classrooms</Sqrt></div><div>2</div></Fraction>+1, <>
but reset all dyes.</>) 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), visibility: () => showIf(clothElfMilestones[2].earned.value && main.day.value >= 13),
shouldEarn: () => clothElfTraining.level.value >= 4, shouldEarn: () => clothElfTraining.level.value >= 4,
onComplete() { onComplete() {
(["red", "yellow", "blue", "orange", "green", "purple"] as const).forEach(dyeColor => { (["red", "yellow", "blue", "orange", "green", "purple"] as const).forEach(
dyes.dyes[dyeColor].amount.value = 0; dyeColor => {
dyes.dyes[dyeColor].buyable.amount.value = 0; dyes.dyes[dyeColor].amount.value = 0;
}); dyes.dyes[dyeColor].buyable.amount.value = 0;
}
);
} }
})), })),
createMilestone(() => ({ createMilestone(() => ({
@ -814,13 +875,13 @@ const layer = createLayer(id, () => {
); );
} }
} }
focusTime.value = Math.max(focusTime.value - diff, 0);
if (focusRolling.value > 0) { focusCooldown.value = Math.max(focusCooldown.value - diff, 0);
focusRolling.value += diff; if (focusTime.value > 0) {
focusMulti.value = Decimal.pow(focusMaxMulti.value, 1 - Math.abs(Math.sin((focusRolling.value - 1) * 3))); focusMulti.value = Decimal.pow(
rerollFocusTargets(12, 3); focusMaxMulti.value,
} else { 1 - Math.abs(Math.sin((Date.now() / 1000) * 2))
focusRolling.value = Math.min(focusRolling.value + diff, 0); );
} }
}); });
@ -828,7 +889,8 @@ const layer = createLayer(id, () => {
const focusMulti = persistent<DecimalSource>(1); const focusMulti = persistent<DecimalSource>(1);
const focusTargets = persistent<Record<string, boolean>>({}); 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 focusMaxMulti = computed<DecimalSource>(() => 10);
@ -839,7 +901,8 @@ const layer = createLayer(id, () => {
style: `border-radius: 4px 4px 0 0`, style: `border-radius: 4px 4px 0 0`,
borderStyle: `border-radius: 4px 4px 0 0`, borderStyle: `border-radius: 4px 4px 0 0`,
fillStyle: `background: ${color}; transition: none`, fillStyle: `background: ${color}; transition: none`,
progress: () => Decimal.sub(focusMulti.value, 1).div(Decimal.sub(focusMaxMulti.value, 1)).toNumber(), progress: () =>
Decimal.sub(focusMulti.value, 1).div(Decimal.sub(focusMaxMulti.value, 1)).toNumber(),
display: jsx(() => <>{format(focusMulti.value)}x</>) display: jsx(() => <>{format(focusMulti.value)}x</>)
})) as GenericBar; })) as GenericBar;
@ -848,27 +911,26 @@ const layer = createLayer(id, () => {
title: "Focus", title: "Focus",
description: jsx(() => ( description: jsx(() => (
<> <>
{focusRolling.value <= 0 Motivate elves to focus, multiplying 3 random elves' XP gain by up to{" "}
? <>Motivate elves to focus, multiplying 3 random elves' XP gain by up to {format(focusMaxMulti.value)}x</> {format(focusMaxMulti.value)}x, equal to the focus bars' effect.
: "Click to stop the focus bar" {focusCooldown.value > 0 ? (
} <>
{focusRolling.value < 0 <br />
? <><br/>Reroll cooldown: {formatTime(-focusRolling.value)}</> Reroll cooldown: {formatTime(focusCooldown.value)}
: "" </>
} ) : (
""
)}
</> </>
)) ))
}, },
style: { style: {
width: "300px" width: "300px"
}, },
canClick: () => focusRolling.value >= 0, canClick: () => focusCooldown.value === 0,
onClick() { onClick() {
if (focusRolling.value == 0) { focusCooldown.value = 15;
focusRolling.value = 1; focusTime.value = 10;
} else if (focusRolling.value > 0) {
focusRolling.value = -30;
}
} }
})); }));
@ -909,9 +971,9 @@ const layer = createLayer(id, () => {
You gotta start somewhere, right? Each school increases the maximum level for You gotta start somewhere, right? Each school increases the maximum level for
elves by 1, up to 5. elves by 1, up to 5.
</div> </div>
<div>You have {formatWhole(schools.amount.value)} schools, <div>
which are currently letting elves learn up to level{" "} You have {formatWhole(schools.amount.value)} schools, which are currently
{formatWhole(schools.amount.value)}. letting elves learn up to level {formatWhole(schools.amount.value)}.
</div> </div>
<div> <div>
Costs {format(schoolCost.value.wood)} logs, {format(schoolCost.value.coal)}{" "} Costs {format(schoolCost.value.wood)} logs, {format(schoolCost.value.coal)}{" "}
@ -978,8 +1040,9 @@ const layer = createLayer(id, () => {
Hopefully it makes the school a bit less boring. Multiplies elves' XP gain by{" "} Hopefully it makes the school a bit less boring. Multiplies elves' XP gain by{" "}
<Sqrt>Classrooms + 1</Sqrt>. <Sqrt>Classrooms + 1</Sqrt>.
</div> </div>
<div>You have {formatWhole(schools.amount.value)} classrooms, <div>
which are currently multiplying elves' XP gain by {format(classroomEffect.value)} You have {formatWhole(classrooms.amount.value)} classrooms, which are currently
multiplying elves' XP gain by {format(classroomEffect.value)}
</div> </div>
<div> <div>
Costs {format(classroomCost.value.wood)} logs,{" "} Costs {format(classroomCost.value.wood)} logs,{" "}
@ -1113,7 +1176,6 @@ const layer = createLayer(id, () => {
/> />
)); ));
// ------------------------------------------------------------------------------- Return // ------------------------------------------------------------------------------- Return
return { return {
@ -1134,11 +1196,17 @@ const layer = createLayer(id, () => {
focusMultiplier: focusMulti, focusMultiplier: focusMulti,
focusTargets, focusTargets,
focusRolling, focusCooldown,
focusTime,
display: jsx(() => ( display: jsx(() => (
<> <>
{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!`} - {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 <button
class="button" class="button"
style="display: inline-block;" style="display: inline-block;"
@ -1148,16 +1216,16 @@ const layer = createLayer(id, () => {
</button> </button>
{render(modifiersModal)} {render(modifiersModal)}
{render(dayProgress)} {render(dayProgress)}
<br/> <br />
{renderCol(schools, classrooms)}{" "} {renderCol(schools, classrooms)} {renderGrid([teaching, classroomUpgrade])}
{renderGrid([teaching, classroomUpgrade])} {Decimal.gt(schools.amount.value, 0) ? (
{ <>
Decimal.gt(schools.amount.value, 0) ? <> <br />
<br/>
Click on an elf to see their milestones. Click on an elf to see their milestones.
<br/><br/> <br />
<br />
{render(focusButton)} {render(focusButton)}
<br/> <br />
{renderGrid( {renderGrid(
[focusMeter], [focusMeter],
treeElfTraining, treeElfTraining,
@ -1167,8 +1235,10 @@ const layer = createLayer(id, () => {
)} )}
<Spacer /> <Spacer />
{currentElfDisplay()} {currentElfDisplay()}
</> : "" </>
} ) : (
""
)}
</> </>
)) ))
}; };

View file

@ -24,6 +24,11 @@ export default defineConfig({
vue: "vue/dist/vue.esm-bundler.js" vue: "vue/dist/vue.esm-bundler.js"
} }
}, },
server: {
hmr: {
clientPort: process.env.CODESPACES ? 443 : undefined
}
},
plugins: [ plugins: [
vue(), vue(),
vueJsx({ vueJsx({