Merge branch 'main' into day-21-reindeer

This commit is contained in:
thepaperpilot 2022-12-23 22:28:43 -06:00
commit a9daaa3ac3
12 changed files with 547 additions and 44 deletions

File diff suppressed because one or more lines are too long

View file

@ -69,6 +69,7 @@
<div v-if="day >= 4" class="scene-bubble left" style="left: 64%; bottom: 37%">
<img v-if="day >= 17" :src="toys" class="scene-item" />
<img v-if="day >= 18" :src="advFactory" class="scene-item" />
<img v-if="day >= 19" :src="presents" class="scene-item" />
</div>
</div>
</template>
@ -93,6 +94,7 @@ import ribbons from "./symbols/ribbons.png";
import toys from "./symbols/truck.png";
import factory from "./symbols/gears.png";
import advFactory from "./symbols/teddyBear.png";
import presents from "./symbols/presents.png";
defineProps<{
day: number;

View file

@ -28,6 +28,7 @@ import { render, renderGrid } from "util/vue";
import { computed, ComputedRef, ref, unref } from "vue";
import dyes from "./dyes";
import elves, { ElfBuyable } from "./elves";
import factory from "./factory";
import management from "./management";
import paper from "./paper";
import plastic from "./plastic";
@ -589,7 +590,36 @@ const layer = createLayer(id, function (this: BaseLayer) {
Decimal.add(plasticBoxesBuyable.amount.value, plasticBoxesBuyable.freeLevels.value)
)
})) as BoxesBuyable;
const presentBuyable = createBuyable(() => ({
display: {
title: "Carry presents in boxes",
description: jsx(() => (
<>
Use boxes to carry presents, boosting its gain
<br />
<br />
<div>Amount: {formatWhole(presentBuyable.amount.value)} boxes</div>
</>
)),
effectDisplay: jsx(() => (
<>{format(Decimal.div(presentBuyable.amount.value, 10).add(1).pow(2))}x</>
)),
showAmount: false
},
resource: noPersist(boxes),
cost() {
return Decimal.pow(2, presentBuyable.amount.value).mul(1e87);
},
inverseCost(x: DecimalSource) {
const amt = Decimal.div(x, 1e87).log2();
return Decimal.isNaN(amt) ? Decimal.dZero : amt.floor().max(0);
},
freeLevels: computed(() => 0),
totalAmount: computed(() => presentBuyable.amount.value),
visibility: () => showIf(factory.upgrades[3][3].bought.value)
})) as BoxesBuyable;
const buyables2 = { oreBoxesBuyable, metalBoxesBuyable, plasticBoxesBuyable };
const buyables3 = { presentBuyable };
globalBus.on("update", diff => {
if (Decimal.lt(main.day.value, day)) {
return;
@ -679,6 +709,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
row3Upgrades,
buyables,
buyables2,
buyables3,
minWidth: 700,
generalTabCollapsed,
display: jsx(() => (
@ -705,7 +736,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
Object.values(row3Upgrades)
)}
<Spacer />
{renderGrid(Object.values(buyables), Object.values(buyables2))}
{renderGrid(
Object.values(buyables),
Object.values(buyables2),
Object.values(buyables3)
)}
</>
)),
minimizedDisplay: jsx(() => (

View file

@ -876,7 +876,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
name: "Bell",
description:
"Bell will automatically purchase all box buyables you can afford, without actually spending any boxes.",
buyable: [...Object.values(boxes.buyables), ...Object.values(boxes.buyables2)],
buyable: [
...Object.values(boxes.buyables),
...Object.values(boxes.buyables2),
...Object.values(boxes.buyables3)
],
cooldownModifier: boxCooldown,
visibility: () => showIf(plastic.elfUpgrades.boxElf.bought.value)
});

View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50"
height="50"
viewBox="0 0 13.229166 13.229167"
version="1.1"
id="svg5"
sodipodi:docname="advent.svg"
inkscape:version="1.2.1 (9c6d41e4, 2022-07-14)"
inkscape:export-filename="advent/boxmaker.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="3.0909964"
inkscape:cx="3.0734426"
inkscape:cy="59.527731"
inkscape:window-width="1309"
inkscape:window-height="804"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0"
inkscape:current-layer="layer1" /><defs
id="defs2" /><g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"><rect
style="fill:#e6e6e6;fill-opacity:1;stroke:#838390;stroke-width:0.764057;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
id="rect28545-6"
width="12.46511"
height="12.46511"
x="0.38202849"
y="0.38202882"
rx="1.246511" /><image
width="11.600364"
height="11.600364"
preserveAspectRatio="none"
xlink:href="data:image/png;base64,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
"
id="image727"
x="0.74370372"
y="0.35876995" /></g></svg>

After

Width:  |  Height:  |  Size: 6.9 KiB

View file

@ -40,9 +40,11 @@ import _plastic from "../symbols/plastic.png";
import boxes from "./boxes";
import coal from "./coal";
import dyes from "./dyes";
import _box from "../symbols/cardboardBox.png";
import _bear from "./factory-components/bear.svg";
import _bearMaker from "./factory-components/bearmaker.svg";
import _block from "./factory-components/block.svg";
import _boxMaker from "./factory-components/boxmaker.svg";
import _blockMaker from "./factory-components/blockmaker.svg";
import _bucket from "./factory-components/bucket.svg";
import _bucketMaker from "./factory-components/bucketmaker.svg";
@ -75,6 +77,8 @@ import _truck from "./factory-components/truck.svg";
import _truckMaker from "./factory-components/truckmaker.svg";
import _wheel from "./factory-components/wheel.svg";
import _wheelMaker from "./factory-components/wheelmaker.svg";
import _present from "./factory-components/present.svg";
import _presentMaker from "./factory-components/presentmaker.svg";
import Factory from "./Factory.vue";
import metal from "./metal";
import oil from "./oil";
@ -85,6 +89,7 @@ import Toy from "./Toy.vue";
import toys from "./toys";
import trees from "./trees";
import workshop from "./workshop";
import ribbon from "./ribbon";
const id = "factory";
@ -94,6 +99,7 @@ const presentsDay = 20;
const toyGoal = 750;
const advancedToyGoal = 1500;
const presentsGoal = 8e9;
// 20x20 block size
// TODO: unhardcode stuff
@ -138,6 +144,16 @@ const factory = createLayer(id, () => {
const bears = createResource<DecimalSource>(0, "teddy bears");
const bucketAndShovels = createResource<DecimalSource>(0, "shovel and pails");
const consoles = createResource<DecimalSource>(0, "consoles");
const presents = createResource<DecimalSource>(0, "presents");
const allToys = {
clothes: toys.clothes,
woodenBlocks: toys.woodenBlocks,
trucks: toys.trucks,
bears,
bucketAndShovels,
consoles
};
function getRelativeCoords(e: MouseEvent) {
const rect = (e.target as HTMLElement).getBoundingClientRect();
@ -172,6 +188,11 @@ const factory = createLayer(id, () => {
multiplier: 1.4,
description: "6000 toys",
enabled: toys.milestones.milestone6.earned
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.log10(trees.logs.value).div(100).add(1),
description: "Burn some logs",
enabled: betterLighting.bought
}))
]) as WithRequired<Modifier, "revert" | "description">;
const computedEnergy = computed(() => energy.apply(0));
@ -227,9 +248,33 @@ const factory = createLayer(id, () => {
addend: expandFactory.amount,
description: "Expand Factory",
enabled: () => Decimal.gt(expandFactory.amount.value, 0)
})),
createAdditiveModifier(() => ({
addend: 5,
description: "Factory eXPerience",
enabled: betterFactory.bought
}))
]);
const computedFactorySize = computed(() => new Decimal(factorySize.apply(7)).toNumber());
const presentMultipliers = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({
multiplier: computedToyMultiplier,
description: "Tickspeed overflow",
enabled: () => computedToyMultiplier.value.gt(1)
})),
createMultiplicativeModifier(() => ({
multiplier: () =>
Decimal.div(boxes.buyables3.presentBuyable.amount.value, 10).add(1).pow(2),
description: "Carry presents in boxes",
enabled: carryPresents.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.add(ribbon.ribbon.value, 1),
description: "With a bow",
enabled: bowUpgrade.bought
}))
]);
const computedPresentMultipliers = computed(() => presentMultipliers.apply(1));
const energyBar = createBar(() => ({
width: 680,
@ -317,6 +362,10 @@ const factory = createLayer(id, () => {
return str;
}
// this keeps track of which toy the present factory has consumed
// it cycles around, so each toy is used evenly
let toysIndex = 0;
const FACTORY_COMPONENTS = {
cursor: {
imageSrc: _cursor,
@ -459,7 +508,8 @@ const factory = createLayer(id, () => {
plank: {
amount: computed(() => (upgrades[0][0].bought.value ? 2 : 1))
}
}
},
visible: main.days[presentsDay - 1].opened
} as FactoryComponentDeclaration,
thread: {
imageSrc: _threadMaker,
@ -604,6 +654,25 @@ const factory = createLayer(id, () => {
},
visible: main.days[advancedDay - 1].opened
} as FactoryComponentDeclaration,
boxMaker: {
imageSrc: _boxMaker,
key: "shift+9",
name: "Box Maker",
type: "processor",
description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.boxMaker)),
energyCost: 3,
tick: 1,
inputs: {
plank: {
amount: 2
}
},
outputs: {
box: {
amount: 2
}
}
} as FactoryComponentDeclaration,
blocks: {
imageSrc: _blockMaker,
key: "ctrl+1",
@ -755,6 +824,93 @@ const factory = createLayer(id, () => {
}
},
visible: main.days[advancedDay - 1].opened
} as FactoryComponentDeclaration,
present: {
imageSrc: _presentMaker,
type: "processor",
// idk about this
key: "ctrl+7",
name: "Present Wrapper",
description: computed(
() =>
`Takes in 4 dye, 4 plastic, 1 cloth, 2 boxes, and ${formatWhole(
computedToyMultiplier.value
)} toys of any type (from storage) to produce ${formatWhole(
computedPresentMultipliers.value
)} presents every tick.` +
(catalysts.bought.value
? " You can feed it wheels, buttons, stuffing, and circuit boards to increase its output."
: "")
),
tick: 1,
energyCost: 50,
inputs: {
dye: {
amount: 4
},
plastic: {
amount: 4
},
cloth: {
amount: 1
},
box: {
amount: 2
}
},
catalysts: computed(() => {
if (!catalysts.bought.value) return [] as ResourceNames[];
return {
wheel: {
amount: 1
},
buttons: {
amount: 1
},
stuffing: {
amount: 1
},
circuitBoard: {
amount: 1
}
};
}),
canProduce: computed(() => {
return Object.values(allToys).some(i =>
Decimal.gte(i.value, computedToyMultiplier.value)
);
}),
onProduce(times, stock) {
const value = Object.values(allToys);
let sumCatalysts: DecimalSource = catalysts.bought.value
? (["wheel", "buttons", "stuffing", "circuitBoard"] as const)
.map(c => stock?.[c] ?? 0)
.reduce(Decimal.add, Decimal.dZero)
.add(1)
: 1;
if (stock) {
(["wheel", "buttons", "stuffing", "circuitBoard"] as const).forEach(
c => delete stock[c]
);
}
while (times > 0) {
while (Decimal.lt(value[toysIndex].value, computedToyMultiplier.value)) {
toysIndex = (toysIndex + 1) % value.length;
}
const toyToPick = Object.values(allToys)[toysIndex];
toysIndex = (toysIndex + 1) % value.length;
toyToPick.value = Decimal.sub(toyToPick.value, computedToyMultiplier.value);
times--;
presents.value = Decimal.add(
presents.value,
Decimal.times(computedPresentMultipliers.value, sumCatalysts)
);
sumCatalysts = 1;
}
},
visible: main.days[presentsDay - 1].opened
} as FactoryComponentDeclaration
} as Record<string, FactoryComponentDeclaration>;
const RESOURCES = {
@ -784,6 +940,10 @@ const factory = createLayer(id, () => {
name: "Planks",
imageSrc: _plank
},
box: {
name: "Boxes",
imageSrc: _box
},
thread: {
name: "Thread",
imageSrc: _thread
@ -901,9 +1061,13 @@ const factory = createLayer(id, () => {
inputs?: Stock;
/** amount it produces */
outputs?: Stock;
catalysts?: ProcessedComputable<Stock>;
/** on produce, do something */
onProduce?: (times: number) => void;
onProduce?: (
times: number,
stock: Partial<Record<ResourceNames, number>> | undefined
) => void;
/** can it produce? (in addtion to the stock check) */
canProduce?: ComputedRef<boolean>;
}
@ -956,10 +1120,21 @@ const factory = createLayer(id, () => {
// trained elves
const costCheapener = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.add(presents.value, 1).log10().add(1),
description: "Excitment Upgrade",
enabled: excitmentUpgrade.bought
}))
]);
const computedCostCheapeners = computed(() => costCheapener.apply(1));
const clothesBuyable = createBuyable(() => ({
resource: toys.clothes,
cost() {
return Decimal.pow(2, Decimal.add(this.amount.value, 5));
return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div(
computedCostCheapeners.value
);
},
display: {
title: "Train elves to make clothes",
@ -970,7 +1145,9 @@ const factory = createLayer(id, () => {
const blocksBuyable = createBuyable(() => ({
resource: toys.woodenBlocks,
cost() {
return Decimal.pow(2, Decimal.add(this.amount.value, 5));
return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div(
computedCostCheapeners.value
);
},
display: {
title: "Train elves to make wooden blocks",
@ -981,7 +1158,9 @@ const factory = createLayer(id, () => {
const trucksBuyable = createBuyable(() => ({
resource: toys.trucks,
cost() {
return Decimal.pow(2, Decimal.add(this.amount.value, 5));
return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div(
computedCostCheapeners.value
);
},
display: {
title: "Train elves to make toy trucks",
@ -992,7 +1171,9 @@ const factory = createLayer(id, () => {
const bearsBuyable = createBuyable(() => ({
resource: noPersist(bears),
cost() {
return Decimal.pow(2, Decimal.add(this.amount.value, 5));
return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div(
computedCostCheapeners.value
);
},
display: {
title: "Train elves to make bears",
@ -1004,7 +1185,9 @@ const factory = createLayer(id, () => {
const bucketBuyable = createBuyable(() => ({
resource: noPersist(bucketAndShovels),
cost() {
return Decimal.pow(2, Decimal.add(this.amount.value, 5));
return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div(
computedCostCheapeners.value
);
},
display: {
title: "Train elves to make shovel and pails",
@ -1016,7 +1199,9 @@ const factory = createLayer(id, () => {
const consolesBuyable = createBuyable(() => ({
resource: noPersist(consoles),
cost() {
return Decimal.pow(2, Decimal.add(this.amount.value, 5));
return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div(
computedCostCheapeners.value
);
},
display: {
title: "Train elves to make consoles",
@ -1057,7 +1242,7 @@ const factory = createLayer(id, () => {
showAmount: false
},
style: "width: 200px",
visible: () => showIf(main.days[advancedDay - 1].opened.value)
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})) as GenericBuyable;
const oilFuel = createBuyable(() => ({
resource: oil.oil,
@ -1071,7 +1256,7 @@ const factory = createLayer(id, () => {
showAmount: false
},
style: "width: 200px",
visible: () => showIf(main.days[advancedDay - 1].opened.value)
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})) as GenericBuyable;
const carryToys = createBuyable(() => ({
resource: boxes.boxes,
@ -1087,9 +1272,90 @@ const factory = createLayer(id, () => {
showAmount: false
},
style: "width: 200px",
visible: () => showIf(main.days[advancedDay - 1].opened.value)
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})) as GenericBuyable;
const betterFactory = createUpgrade(() => ({
resource: noPersist(presents),
cost: 100,
display: {
title: "Factory eXPerience",
description: "Factory size is increased by 5."
},
visibility: () => showIf(main.days[presentsDay - 1].opened.value)
}));
const betterLighting = createUpgrade(() => ({
resource: noPersist(presents),
cost: 300,
display: {
title: "Burn some logs",
description: "More energy needed? Let's burn some logs! Logs boosts maximum energy.",
effectDisplay: jsx(() => (
<>x{format(Decimal.log10(trees.logs.value).div(100).add(1))}</>
))
},
visibility: () => showIf(betterFactory.bought.value)
}));
const excitmentUpgrade = createUpgrade(() => ({
resource: noPersist(presents),
cost: 1000,
display: {
title: "Faster Elf Training",
description:
"Apparently elves like presents. Let's use it to train them to work on the factory faster! Presents divides the requirement for factory elf training.",
effectDisplay: jsx(() => <>/{format(Decimal.add(presents.value, 1).log10().add(1))}</>)
},
visibility: () => showIf(betterLighting.bought.value)
}));
const carryPresents = createUpgrade(() => ({
resource: noPersist(presents),
cost: 5000,
display: {
title: "Carrying more stuff in boxes",
description:
"Boxes seem really useful for carrying stuff. Why don't we use them to carry presents as well? Unlocks 2 new buyables (one of them is in the boxes layer)."
},
visibility: () => showIf(excitmentUpgrade.bought.value)
}));
const carryBoxes = createBuyable(() => ({
resource: noPersist(presents),
cost() {
return Decimal.add(carryBoxes.amount.value, 1)
.pow(1.5)
.mul(Decimal.pow(2, carryBoxes.amount.value))
.mul(1000);
},
style: "width: 400px",
display: {
title: "Carry boxes in... presents?",
description:
"Presents are made out of boxes, so shouldn't they be able to hold boxes as well? Apparently it makes the boxes more durable. Each level multiplies boxes gain by 1.5.",
effectDisplay: jsx(() => <>x{format(Decimal.pow(1.5, carryBoxes.amount.value))}</>)
},
visibility: () => showIf(carryPresents.bought.value)
})) as GenericBuyable;
const catalysts = createUpgrade(() => ({
resource: noPersist(presents),
cost: 10000,
display: {
title: "Better Presents",
description:
"Instead of trying to make more presents, how about we make the ones we make better? Unlocks catalysts for the present maker."
},
visibility: () => showIf(carryPresents.bought.value)
}));
const bowUpgrade = createUpgrade(() => ({
resource: noPersist(presents),
cost: 1e7,
display: {
title: "With a bow",
description:
"These presents need ribbon to make the bows, right? Multiply present gain by the amount of ribbon you have"
},
visibility: () => showIf(catalysts.bought.value)
}));
const factoryBuyables = { expandFactory, oilFuel, carryToys };
const factoryBuyables2 = { carryBoxes };
const upgrades = [
[
createUpgrade(() => ({
@ -1100,7 +1366,7 @@ const factory = createLayer(id, () => {
description:
"Double sawmill consumption and production and metal supplier efficiency"
},
visible: () => showIf(main.days[advancedDay - 1].opened.value)
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: paper.paper,
@ -1109,7 +1375,7 @@ const factory = createLayer(id, () => {
title: "News Ticker",
description: "Paper boosts tick speed"
},
visible: () => showIf(main.days[advancedDay - 1].opened.value)
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: toys.trucks,
@ -1118,7 +1384,7 @@ const factory = createLayer(id, () => {
title: "Haul wood in trucks",
description: "Trucks multiply wood gain"
},
visible: () => showIf(main.days[advancedDay - 1].opened.value)
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: metal.metal,
@ -1127,7 +1393,7 @@ const factory = createLayer(id, () => {
title: "Diamond-tipped drills",
description: "Drill power ^1.2"
},
visible: () => showIf(main.days[advancedDay - 1].opened.value)
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
}))
],
[
@ -1138,7 +1404,7 @@ const factory = createLayer(id, () => {
title: "Larger wood pieces",
description: "Wooden block producers produce 3x as much"
},
visible: () => showIf(main.days[advancedDay - 1].opened.value)
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: dyes.dyes.red.amount,
@ -1147,7 +1413,7 @@ const factory = createLayer(id, () => {
title: "Colorful clothes",
description: "Dye producers produce 4x as much"
},
visible: () => showIf(main.days[advancedDay - 1].opened.value)
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: plastic.plastic,
@ -1156,7 +1422,7 @@ const factory = createLayer(id, () => {
title: "Improved plastic producers",
description: "Plastic producers produce 4x as much"
},
visible: () => showIf(main.days[advancedDay - 1].opened.value)
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: oil.oil,
@ -1165,7 +1431,7 @@ const factory = createLayer(id, () => {
title: "Capitalism",
description: "Console production is tripled"
},
visible: () => showIf(main.days[advancedDay - 1].opened.value)
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
}))
],
[
@ -1176,7 +1442,7 @@ const factory = createLayer(id, () => {
title: "Brighter work rooms",
description: "Unused electricity makes ticks faster"
},
visible: () => showIf(main.days[advancedDay - 1].opened.value)
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: dyes.dyes.blue.amount,
@ -1185,7 +1451,7 @@ const factory = createLayer(id, () => {
title: "Colorful teddy bears",
description: "Teddy bears produce 2x as much"
},
visible: () => showIf(main.days[advancedDay - 1].opened.value)
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: dyes.dyes.black.amount,
@ -1194,7 +1460,7 @@ const factory = createLayer(id, () => {
title: "New Colors",
description: "Unlock white dye"
},
visible: () => showIf(main.days[advancedDay - 1].opened.value)
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: boxes.boxes,
@ -1203,9 +1469,11 @@ const factory = createLayer(id, () => {
title: "Carry ticks in boxes",
description: "Tick speed x1.5"
},
visible: () => showIf(main.days[advancedDay - 1].opened.value)
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
}))
]
],
[betterFactory, betterLighting, excitmentUpgrade, carryPresents],
[catalysts, bowUpgrade]
];
// pixi
@ -1239,6 +1507,9 @@ const factory = createLayer(id, () => {
let loaded = false;
globalBus.on("onLoad", async () => {
if (loaded) {
return;
}
loaded = false;
spriteContainer.destroy({
@ -1311,8 +1582,6 @@ const factory = createLayer(id, () => {
const factoryTicks = Decimal.times(computedActualTickRate.value, diff).toNumber();
//debugger
// make them produce
for (const id in components.value) {
const [x, y] = id.split("x").map(p => +p);
const _data = components.value[id];
@ -1375,7 +1644,7 @@ const factory = createLayer(id, () => {
if (data.ticksDone >= factoryData.tick) {
if (compData.canProduce.value) {
const cyclesDone = Math.floor(data.ticksDone / factoryData.tick);
factoryData.onProduce?.(cyclesDone);
factoryData.onProduce?.(cyclesDone, data.inputStock);
if (factoryData.inputs !== undefined) {
if (data.inputStock === undefined) data.inputStock = {};
for (const [key, val] of Object.entries(factoryData.inputs)) {
@ -1822,6 +2091,20 @@ const factory = createLayer(id, () => {
function togglePaused() {
paused.value = !paused.value;
}
function handleDrag(drag: DragEvent, name: FactoryCompNames) {
drag.dataTransfer!.setData("name", name);
}
function handleDrop(drag: DragEvent) {
drag.preventDefault();
const { tx, ty } = spriteContainer.localTransform;
let { x, y } = getRelativeCoords(drag);
x = roundDownTo(x - tx, blockSize) / blockSize;
y = roundDownTo(y - ty, blockSize) / blockSize;
const name = drag.dataTransfer!.getData("name");
if (components.value[x + "x" + y] == null) {
addFactoryComp(x, y, { type: name });
}
}
// ------------------------------------------------------------------------------- Tabs
@ -1838,12 +2121,17 @@ const factory = createLayer(id, () => {
{Object.entries(FACTORY_COMPONENTS).map(value => {
const key = value[0] as FactoryCompNames;
const item = value[1];
if (unref(item.visible) === false) {
return null;
}
return (
<div class="comp">
<img
src={item.imageSrc}
class={{ selected: compSelected.value === key }}
onClick={() => onCompClick(key)}
draggable="true"
onDragstart={drag => handleDrag(drag, key)}
/>
{item.extraImage == null ? null : (
<img src={item.extraImage} class="producedItem" />
@ -1879,7 +2167,7 @@ const factory = createLayer(id, () => {
});
function showStockAmount(
stocks: Partial<Record<ResourceNames, number>> | undefined,
stocks: Partial<Record<ResourceNames, number>> | undefined | Record<string, never>,
stockData: Stock | undefined,
title: string,
showAmount = true
@ -1938,7 +2226,11 @@ const factory = createLayer(id, () => {
<>
{showStockAmount(
(compHovered.value as FactoryComponentProcessor).inputStock,
FACTORY_COMPONENTS[compHovered.value.type].inputs,
{
...(FACTORY_COMPONENTS[compHovered.value.type].inputs ?? {}),
...(unref(FACTORY_COMPONENTS[compHovered.value.type].catalysts) ??
{})
},
"Inputs:"
)}
{showStockAmount(
@ -1996,6 +2288,8 @@ const factory = createLayer(id, () => {
? `Reach ${format(
advancedToyGoal
)} for each toy to complete the day`
: main.day.value === presentsDay
? `Reach ${format(presentsGoal)} presents`
: `${name} Complete!`}{" "}
-{" "}
<button
@ -2016,7 +2310,7 @@ const factory = createLayer(id, () => {
color="cornflowerblue"
/>
<Toy resource={toys.trucks} image={_truck} color="cadetblue" />
{main.days[advancedDay - 1].opened.value ? (
{main.days[advancedDay - 1].opened.value === true ? (
<>
<Toy resource={bears} image={_bear} color="teal" />
<Toy
@ -2031,6 +2325,11 @@ const factory = createLayer(id, () => {
/>
</>
) : null}
{main.days[presentsDay - 1].opened.value === true ? (
<>
<Toy resource={presents} image={_present} color="green" />
</>
) : undefined}
</Row>
<Spacer />
<MainDisplay
@ -2042,7 +2341,11 @@ const factory = createLayer(id, () => {
/>
{renderRow(...Object.values(elfBuyables))}
<Spacer />
{renderRow(...Object.values(factoryBuyables))}
{renderGrid(
Object.values(factoryBuyables),
Object.values(factoryBuyables2)
)}
<Spacer />
<Spacer />
{renderGrid(...(upgrades as VueFeature[][]))}
</>
@ -2063,6 +2366,8 @@ const factory = createLayer(id, () => {
onPointerenter={onFactoryMouseEnter}
onPointerleave={onFactoryMouseLeave}
onContextmenu={(e: MouseEvent) => e.preventDefault()}
onDrop={(e: DragEvent) => handleDrop(e)}
onDragover={(e: DragEvent) => e.preventDefault()}
/>
{componentsList()}
{hoveredComponent()}
@ -2089,6 +2394,11 @@ const factory = createLayer(id, () => {
modifier: tickRate,
base: 1,
unit: "/s"
},
{
title: "Present Multipliers",
modifier: presentMultipliers,
base: 1
}
]);
const showModifiersModal = ref(false);
@ -2105,7 +2415,10 @@ const factory = createLayer(id, () => {
<>
<br />
Note: the actual tick rate is capped at 5 TPS, but you'll gain extra
toys based on excessive tick rate as a compensation.
toys based on excessive tick rate as compensation.{" "}
{main.days[presentsDay - 1].opened.value === true
? "Present maker's toy requirement and production is also affected by tick overflow."
: undefined}
</>
) : (
""
@ -2133,6 +2446,8 @@ const factory = createLayer(id, () => {
.map(r => Decimal.div(r.value, advancedToyGoal).clampMax(1))
.reduce(Decimal.add, Decimal.dZero)
.div(6)
: main.day.value === presentsDay
? Decimal.div(presents.value, presentsGoal).clampMax(1)
: 1,
display: jsx(() =>
main.day.value === day ? (
@ -2158,6 +2473,10 @@ const factory = createLayer(id, () => {
}{" "}
/ 6
</>
) : main.day.value === presentsDay ? (
<>
{formatWhole(presents.value)}/{formatWhole(presentsGoal)} presents
</>
) : (
""
)
@ -2184,6 +2503,8 @@ const factory = createLayer(id, () => {
].filter(d => Decimal.gte(d.value, advancedToyGoal)).length >= 6
) {
main.completeDay();
} else if (main.day.value === presentsDay && Decimal.gte(presents.value, presentsGoal)) {
main.completeDay();
}
});
@ -2200,8 +2521,11 @@ const factory = createLayer(id, () => {
bears,
bucketAndShovels,
consoles,
presents,
tabs,
factoryBuyables,
factoryBuyables2,
carryBoxes,
generalTabCollapsed,
hotkeys,
upgrades,

View file

@ -76,10 +76,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
if (Decimal.lt(processingProgress.value, computedProcessingCooldown.value)) {
return;
}
const amount = Decimal.div(
processingProgress.value,
computedProcessingCooldown.value
).floor();
const amount = Decimal.div(processingProgress.value, computedProcessingCooldown.value)
.floor()
.max(1);
letters.value = Decimal.times(amount, computedLettersGain.value)
.add(letters.value)
.min(8e9);

View file

@ -151,8 +151,10 @@
justify-content: space-evenly;
align-items: flex-start;
align-content: flex-start;
justify-content: flex-start;
width: 148px;
direction: ltr;
text-align: left;
}
.comp-list::after {
@ -176,6 +178,11 @@
pointer-events: all;
}
.comp-list .comp > img:first-child {
width: 50px;
height: 50px;
}
.comp-list .comp:nth-child(3)::after,
.comp-list .comp:nth-child(4)::after {
content: "";
@ -192,7 +199,7 @@
.comp-list .comp:nth-child(4)::after {
left: -50px;
}
.comp-list .comp img.selected:not(.producedItem) {
.comp-list .comp img.selected, .comp-list .comp img.selected + img {
transform: translate(-5px, -5px);
filter: drop-shadow(2px 2px 0 var(--foreground)) drop-shadow(5px 5px 5px #0007);
}

View file

@ -143,6 +143,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
style: "width: 600px; min-height: unset"
}));
watchEffect(() => {
if (Decimal.lt(computedMaxFoundation.value, foundationProgress.value)) {
foundationProgress.value = Decimal.min(0, computedMaxFoundation.value);
}
});
const buildFoundationHK = createHotkey(() => ({
key: "w",
description: "Build foundation",

View file

@ -49,11 +49,12 @@ import metalSymbol from "./symbols/metal.png";
import oilSymbol from "./symbols/oil.png";
import paperSymbol from "./symbols/paperStacks.png";
import plasticSymbol from "./symbols/plastic.png";
import presentsSymbol from "./symbols/presents.png";
import ribbonsSymbol from "./symbols/ribbons.png";
import workshopSymbol from "./symbols/sws.png";
import advFactorySymbol from "./symbols/teddyBear.png";
import treeSymbol from "./symbols/tree.png";
import toysSymbol from "./symbols/truck.png";
import advFactorySymbol from "./symbols/teddyBear.png";
import advManagementSymbol from "./symbols/workshopMansion.png";
import wrappingPaperSymbol from "./symbols/wrappingPaper.png";
@ -465,10 +466,11 @@ export const main = createLayer("main", function (this: BaseLayer) {
createDay(() => ({
day: 20,
shouldNotify: false,
layer: null, // "presents"
symbol: wrappingPaperSymbol,
story: "",
completedStory: "",
layer: "factory",
symbol: presentsSymbol,
story: "Santa comes by again, and tells you that just toys may not be appealing enough. He tells you that you should probably wrap them in some wrapping paper so that it's more of a surprise. You try to argue that you've already done too much for him and deserve a day off, but Santa argues that it's for the benefit of everyone and that you'll get your vacation soon. Oh well, time to get back to the factory and expand it even more. Here we go again!",
completedStory:
"That was a lot of work, but it certainly felt worth actually using all those decorative supplies you'd previously made. One more sleepless night down, just a handful more to go. Good Job!",
masteredStory: ""
})),
createDay(() => ({

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB