Merge branch 'main' into day-21-reindeer

This commit is contained in:
thepaperpilot 2022-12-23 08:59:40 -06:00
commit 5637e1e248
9 changed files with 730 additions and 69 deletions

View file

@ -98,7 +98,7 @@ const isPaused = computed({
}); });
const canAutoSave = computed( const canAutoSave = computed(
() => (layers as any).main.days[(layers as any).main.day.value - 1].opened.value () => (layers as any).main?.days[(layers as any).main?.day.value - 1].opened.value
); );
const autosaveTitle = jsx(() => ( const autosaveTitle = jsx(() => (

View file

@ -0,0 +1,51 @@
<?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/ribbonmaker.svg"
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="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="1.9225905"
inkscape:cx="54.873881"
inkscape:cy="-1.0402631"
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:#e80000;fill-opacity:1;stroke:#a96625;stroke-width:0;stroke-linecap:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
id="rect31830-6"
width="8.1008177"
height="8.1008177"
x="2.6243083"
y="4.4571147" /><path
id="rect31884-0"
style="fill:#ffff00;fill-opacity:1;stroke:#a96625;stroke-width:0;stroke-linecap:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
d="M 4.57173,0.395005 C 3.56337,0.387105 2.715225,1.17169 2.655568,2.189727 2.601548,3.117815 3.224966,3.949533 4.13093,4.158082 c 0,0 0.911853,0.09505 1.879472,0.188103 l -0.02584,0.04909 h -0.0863 v 3.15743 l -3.31711,0.02015 0.0098,1.675867 3.307292,-0.02015 v 3.38739 H 7.57411 V 9.218753 l 3.237012,-0.01964 -0.0098,-1.675866 -3.227194,0.01964 V 4.485709 c 0.09816,0.0076 0.191391,0.01476 0.272852,0.02015 L 7.78755,4.392171 C 8.738745,4.308221 9.624241,4.222286 9.625164,4.21492 10.532311,4.011573 11.160585,3.183216 11.111895,2.254833 11.056345,1.20362 10.1591,0.396373 9.107883,0.451843 8.359868,0.491803 7.704586,0.966554 7.43305,1.664689 L 6.893031,2.682714 6.337509,1.620247 C 6.069983,0.920565 5.417685,0.44235 4.669911,0.398099 c -0.03284,-0.0019 -0.06566,-0.0028 -0.09819,-0.0031 z M 4.71539,1.4275 c 0.01754,1.3e-4 0.03551,5.21e-4 0.05323,0.0016 0.403484,0.02381 0.755726,0.28191 0.900203,0.659391 l 0.764295,1.46141 -0.04548,0.08578 C 5.760971,3.568571 4.490341,3.464245 4.478193,3.45843 3.989181,3.345785 3.652481,2.896405 3.68186,2.395446 3.71426,1.846385 4.171524,1.42351 4.715388,1.427547 Z m 4.340304,0.05323 c 0.543878,-9.16e-4 0.999105,0.424863 1.028361,0.974101 0.0265,0.501119 -0.312368,0.948496 -0.802018,1.058333 0,0 -1.228253,0.09807 -1.869654,0.162264 L 7.347793,3.551922 8.099168,2.136504 C 8.245809,1.759859 8.599376,1.503781 9.002989,1.482281 c 0.01772,-9.28e-4 0.03516,-0.0015 0.05271,-0.0016 z" /></g></svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View file

@ -0,0 +1,60 @@
<?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/present.svg"
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="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="1.9225905"
inkscape:cx="54.873881"
inkscape:cy="-1.0402631"
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" /><g
id="g33200"
transform="matrix(0.92978329,0,0,0.92978329,0.26683804,0.5413202)"><rect
style="fill:#e80000;fill-opacity:1;stroke:#a96625;stroke-width:0;stroke-linecap:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
id="rect31830-6"
width="8.1008177"
height="8.1008177"
x="2.6243083"
y="4.4571147" /><path
id="rect31884-0"
style="fill:#ffff00;fill-opacity:1;stroke:#a96625;stroke-width:0;stroke-linecap:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
d="M 4.57173,0.395005 C 3.56337,0.387105 2.715225,1.17169 2.655568,2.189727 2.601548,3.117815 3.224966,3.949533 4.13093,4.158082 c 0,0 0.911853,0.09505 1.879472,0.188103 l -0.02584,0.04909 h -0.0863 v 3.15743 l -3.31711,0.02015 0.0098,1.675867 3.307292,-0.02015 v 3.38739 H 7.57411 V 9.218753 l 3.237012,-0.01964 -0.0098,-1.675866 -3.227194,0.01964 V 4.485709 c 0.09816,0.0076 0.191391,0.01476 0.272852,0.02015 L 7.78755,4.392171 C 8.738745,4.308221 9.624241,4.222286 9.625164,4.21492 10.532311,4.011573 11.160585,3.183216 11.111895,2.254833 11.056345,1.20362 10.1591,0.396373 9.107883,0.451843 8.359868,0.491803 7.704586,0.966554 7.43305,1.664689 L 6.893031,2.682714 6.337509,1.620247 C 6.069983,0.920565 5.417685,0.44235 4.669911,0.398099 c -0.03284,-0.0019 -0.06566,-0.0028 -0.09819,-0.0031 z M 4.71539,1.4275 c 0.01754,1.3e-4 0.03551,5.21e-4 0.05323,0.0016 0.403484,0.02381 0.755726,0.28191 0.900203,0.659391 l 0.764295,1.46141 -0.04548,0.08578 C 5.760971,3.568571 4.490341,3.464245 4.478193,3.45843 3.989181,3.345785 3.652481,2.896405 3.68186,2.395446 3.71426,1.846385 4.171524,1.42351 4.715388,1.427547 Z m 4.340304,0.05323 c 0.543878,-9.16e-4 0.999105,0.424863 1.028361,0.974101 0.0265,0.501119 -0.312368,0.948496 -0.802018,1.058333 0,0 -1.228253,0.09807 -1.869654,0.162264 L 7.347793,3.551922 8.099168,2.136504 C 8.245809,1.759859 8.599376,1.503781 9.002989,1.482281 c 0.01772,-9.28e-4 0.03516,-0.0015 0.05271,-0.0016 z" /></g></g></svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -0,0 +1,412 @@
<?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/circuitmaker.svg"
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="1.9225905"
inkscape:cx="54.873881"
inkscape:cy="-1.0402631"
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.38202849"
rx="1.246511" /><image
width="12.635027"
height="12.635027"
preserveAspectRatio="none"
xlink:href="data:image/png;base64,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
"
id="image30954"
x="0.12073317"
y="-0.82161695" /></g></svg>

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -28,11 +28,11 @@ import {
Modifier Modifier
} from "game/modifiers"; } from "game/modifiers";
import { noPersist, Persistent, persistent, State } from "game/persistence"; import { noPersist, Persistent, persistent, State } from "game/persistence";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum"; import Decimal, { DecimalSource, format, formatList, formatWhole } from "util/bignum";
import { Direction, WithRequired } from "util/common"; import { Direction, WithRequired } from "util/common";
import { ProcessedComputable } from "util/computed"; import { ProcessedComputable } from "util/computed";
import { render, renderGrid, renderRow, VueFeature } from "util/vue"; import { render, renderGrid, renderRow, VueFeature } from "util/vue";
import { computed, ComputedRef, reactive, ref, unref, watchEffect } from "vue"; import { computed, ComputedRef, reactive, ref, shallowRef, unref, watchEffect } from "vue";
import _cloth from "../symbols/cloth.png"; import _cloth from "../symbols/cloth.png";
import _dye from "../symbols/dyes.png"; import _dye from "../symbols/dyes.png";
import _metal from "../symbols/metal.png"; import _metal from "../symbols/metal.png";
@ -206,9 +206,12 @@ const factory = createLayer(id, () => {
createMultiplicativeModifier(() => ({ createMultiplicativeModifier(() => ({
multiplier: Decimal.lt(energyEfficiency.value, 1) multiplier: Decimal.lt(energyEfficiency.value, 1)
? 1 ? 1
: Decimal.sub(2, Decimal.div(energyConsumption.value, computedEnergy.value)), : Decimal.sub(
2,
Decimal.div(energyConsumption.value, Decimal.max(computedEnergy.value, 1))
),
description: "Brighter work rooms", description: "Brighter work rooms",
enabled: () => upgrades[2][1].bought.value enabled: () => upgrades[2][0].bought.value
})), })),
createMultiplicativeModifier(() => ({ createMultiplicativeModifier(() => ({
multiplier: 1.5, multiplier: 1.5,
@ -217,6 +220,8 @@ const factory = createLayer(id, () => {
})) }))
]); ]);
const computedTickRate = computed(() => tickRate.apply(1)); const computedTickRate = computed(() => tickRate.apply(1));
const computedActualTickRate = computed(() => Decimal.min(computedTickRate.value, 5));
const computedToyMultiplier = computed(() => Decimal.div(computedTickRate.value, 5).max(1));
const factorySize = createSequentialModifier(() => [ const factorySize = createSequentialModifier(() => [
createAdditiveModifier(() => ({ createAdditiveModifier(() => ({
addend: expandFactory.amount, addend: expandFactory.amount,
@ -285,6 +290,33 @@ const factory = createLayer(id, () => {
// ---------------------------------------------- Components // ---------------------------------------------- Components
function generateComponentDescription(declaration: FactoryComponentDeclaration) {
let str = declaration.inputs === undefined ? "Produces " : "Turns ";
if (declaration.inputs !== undefined) {
str +=
formatList(
Object.entries(declaration.inputs).map(
x =>
formatWhole(unref(x[1].amount)) +
" " +
RESOURCES[x[0] as ResourceNames].name
)
) + " into ";
}
if (declaration.outputs !== undefined) {
str +=
formatList(
Object.entries(declaration.outputs).map(
x =>
formatWhole(unref(x[1].amount)) +
" " +
RESOURCES[x[0] as ResourceNames].name
)
) + " per tick.";
}
return str;
}
const FACTORY_COMPONENTS = { const FACTORY_COMPONENTS = {
cursor: { cursor: {
imageSrc: _cursor, imageSrc: _cursor,
@ -341,7 +373,7 @@ const factory = createLayer(id, () => {
key: "1", key: "1",
name: "Wood Machine", name: "Wood Machine",
type: "processor", type: "processor",
description: "Produces 1 wood per tick.", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.wood)),
energyCost: 10, energyCost: 10,
tick: 1, tick: 1,
outputs: { outputs: {
@ -356,7 +388,7 @@ const factory = createLayer(id, () => {
key: "2", key: "2",
name: "Cloth Machine", name: "Cloth Machine",
type: "processor", type: "processor",
description: "Produces 1 cloth per tick.", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.cloth)),
energyCost: 10, energyCost: 10,
tick: 1, tick: 1,
outputs: { outputs: {
@ -371,7 +403,7 @@ const factory = createLayer(id, () => {
key: "3", key: "3",
name: "Dye Machine", name: "Dye Machine",
type: "processor", type: "processor",
description: "Produces 1 dye per tick.", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.dye)),
energyCost: 10, energyCost: 10,
tick: 1, tick: 1,
outputs: { outputs: {
@ -386,7 +418,7 @@ const factory = createLayer(id, () => {
key: "4", key: "4",
name: "Metal Machine", name: "Metal Machine",
type: "processor", type: "processor",
description: "Produces 1 metal per tick.", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.metal)),
energyCost: 10, energyCost: 10,
tick: 1, tick: 1,
outputs: { outputs: {
@ -401,7 +433,7 @@ const factory = createLayer(id, () => {
key: "5", key: "5",
name: "Plastic Machine", name: "Plastic Machine",
type: "processor", type: "processor",
description: "Produces 1 plastic per tick.", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.plastic)),
energyCost: 10, energyCost: 10,
tick: 1, tick: 1,
outputs: { outputs: {
@ -415,7 +447,7 @@ const factory = createLayer(id, () => {
key: "shift+1", key: "shift+1",
name: "Sawmill", name: "Sawmill",
type: "processor", type: "processor",
description: "Turns 1 wood into 1 plank per tick.", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.plank)),
energyCost: 2, energyCost: 2,
tick: 1, tick: 1,
inputs: { inputs: {
@ -434,7 +466,7 @@ const factory = createLayer(id, () => {
key: "shift+2", key: "shift+2",
name: "Thread Spinner", name: "Thread Spinner",
type: "processor", type: "processor",
description: "Turns 1 cloth into 1 thread per tick.", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.thread)),
energyCost: 2, energyCost: 2,
tick: 1, tick: 1,
inputs: { inputs: {
@ -453,13 +485,7 @@ const factory = createLayer(id, () => {
key: "shift+3", key: "shift+3",
name: "Wheel Crafter", name: "Wheel Crafter",
type: "processor", type: "processor",
// TODO construct descriptions dynamically better description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.wheel)),
description: computed(
() =>
`Turns 1 plastic into ${
toys.milestones.milestone5.earned.value ? "2 wheels" : "1 wheel"
} per tick.`
),
energyCost: 2, energyCost: 2,
tick: 1, tick: 1,
inputs: { inputs: {
@ -478,7 +504,7 @@ const factory = createLayer(id, () => {
key: "shift+4", key: "shift+4",
name: "Button Maker", name: "Button Maker",
type: "processor", type: "processor",
description: "Turns 1 plastic into 2 buttons every second.", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.button)),
energyCost: 2, energyCost: 2,
tick: 1, tick: 1,
inputs: { inputs: {
@ -498,7 +524,7 @@ const factory = createLayer(id, () => {
key: "shift+5", key: "shift+5",
name: "Cloth Shredder", name: "Cloth Shredder",
type: "processor", type: "processor",
description: "Turns 1 cloth into 1 stuffing every second.", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.stuffing)),
energyCost: 2, energyCost: 2,
tick: 1, tick: 1,
inputs: { inputs: {
@ -518,7 +544,7 @@ const factory = createLayer(id, () => {
key: "shift+6", key: "shift+6",
name: "Shovel Maker", name: "Shovel Maker",
type: "processor", type: "processor",
description: "Turns 2 plastic into 1 shovel every second.", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.shovel)),
energyCost: 2, energyCost: 2,
tick: 1, tick: 1,
inputs: { inputs: {
@ -538,7 +564,7 @@ const factory = createLayer(id, () => {
key: "shift+7", key: "shift+7",
name: "Bucket Maker", name: "Bucket Maker",
type: "processor", type: "processor",
description: "Turns 3 plastic into 1 bucket every second.", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.bucket)),
energyCost: 2, energyCost: 2,
tick: 1, tick: 1,
inputs: { inputs: {
@ -558,7 +584,9 @@ const factory = createLayer(id, () => {
key: "shift+8", key: "shift+8",
name: "Circuit Board Manufacturer", name: "Circuit Board Manufacturer",
type: "processor", type: "processor",
description: "Turns 1 metal and 1 plastic into 1 circuit board every second.", description: computed(() =>
generateComponentDescription(FACTORY_COMPONENTS.circuitBoard)
),
energyCost: 2, energyCost: 2,
tick: 1, tick: 1,
inputs: { inputs: {
@ -578,10 +606,10 @@ const factory = createLayer(id, () => {
} as FactoryComponentDeclaration, } as FactoryComponentDeclaration,
blocks: { blocks: {
imageSrc: _blockMaker, imageSrc: _blockMaker,
key: "ctrl+shift+1", key: "ctrl+1",
name: "Wooden Block Maker", name: "Wooden Block Maker",
type: "processor", type: "processor",
description: "Turns 1 plank into 1 wooden block per tick.", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.blocks)),
energyCost: 20, energyCost: 20,
tick: 1, tick: 1,
inputs: { inputs: {
@ -598,10 +626,10 @@ const factory = createLayer(id, () => {
} as FactoryComponentDeclaration, } as FactoryComponentDeclaration,
clothes: { clothes: {
imageSrc: _clothesMaker, imageSrc: _clothesMaker,
key: "ctrl+shift+2", key: "ctrl+2",
name: "Clothes Maker", name: "Clothes Maker",
type: "processor", type: "processor",
description: "Turns 2 threads, 3 cloth, and 1 dye into 1 clothes per tick.", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.clothes)),
energyCost: 20, energyCost: 20,
tick: 1, tick: 1,
inputs: { inputs: {
@ -624,10 +652,10 @@ const factory = createLayer(id, () => {
} as FactoryComponentDeclaration, } as FactoryComponentDeclaration,
trucks: { trucks: {
imageSrc: _truckMaker, imageSrc: _truckMaker,
key: "ctrl+shift+3", key: "ctrl+3",
name: "Trucks Maker", name: "Trucks Maker",
type: "processor", type: "processor",
description: "Turns 2 metal and 4 wheels into 1 truck per tick.", description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.trucks)),
energyCost: 20, energyCost: 20,
tick: 1, tick: 1,
inputs: { inputs: {
@ -647,11 +675,10 @@ const factory = createLayer(id, () => {
} as FactoryComponentDeclaration, } as FactoryComponentDeclaration,
bear: { bear: {
imageSrc: _bearMaker, imageSrc: _bearMaker,
key: "ctrl+shift+4", key: "ctrl+4",
name: "Teddy Bear Maker", name: "Teddy Bear Maker",
type: "processor", type: "processor",
description: description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.bear)),
"Turns 1 thread, 1 stuffing, 1 dye, and 3 buttons into 1 teddy bear every second.",
energyCost: 20, energyCost: 20,
tick: 1, tick: 1,
inputs: { inputs: {
@ -671,17 +698,19 @@ const factory = createLayer(id, () => {
outputs: { outputs: {
bear: { bear: {
amount: computed(() => (upgrades[1][3].bought.value ? 2 : 1)), amount: computed(() => (upgrades[1][3].bought.value ? 2 : 1)),
resource: bears resource: noPersist(bears)
} }
}, },
visible: main.days[advancedDay - 1].opened visible: main.days[advancedDay - 1].opened
} as FactoryComponentDeclaration, } as FactoryComponentDeclaration,
bucketShovel: { bucketShovel: {
imageSrc: _bucketShovelMaker, imageSrc: _bucketShovelMaker,
key: "ctrl+shift+5", key: "ctrl+5",
name: "Shovel and Pail Maker", name: "Shovel and Pail Maker",
type: "processor", type: "processor",
description: "Turns 1 bucket and 1 shovel into 1 shovel and pail every second.", description: computed(() =>
generateComponentDescription(FACTORY_COMPONENTS.bucketShovel)
),
energyCost: 20, energyCost: 20,
tick: 1, tick: 1,
inputs: { inputs: {
@ -695,18 +724,17 @@ const factory = createLayer(id, () => {
outputs: { outputs: {
shovelBucket: { shovelBucket: {
amount: 1, amount: 1,
resource: bucketAndShovels resource: noPersist(bucketAndShovels)
} }
}, },
visible: main.days[advancedDay - 1].opened visible: main.days[advancedDay - 1].opened
} as FactoryComponentDeclaration, } as FactoryComponentDeclaration,
console: { console: {
imageSrc: _consoleMaker, imageSrc: _consoleMaker,
key: "ctrl+shift+6", key: "ctrl+6",
name: "Game Console Maker", name: "Game Console Maker",
type: "processor", type: "processor",
description: description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.console)),
"Turns 1 metal, 3 plastic, and 1 circuit board into 1 game console every second.",
energyCost: 20, energyCost: 20,
tick: 1, tick: 1,
inputs: { inputs: {
@ -723,12 +751,12 @@ const factory = createLayer(id, () => {
outputs: { outputs: {
console: { console: {
amount: computed(() => (upgrades[1][3].bought.value ? 3 : 1)), amount: computed(() => (upgrades[1][3].bought.value ? 3 : 1)),
resource: consoles resource: noPersist(consoles)
} }
}, },
visible: main.days[advancedDay - 1].opened visible: main.days[advancedDay - 1].opened
} as FactoryComponentDeclaration } as FactoryComponentDeclaration
} as const; } as Record<string, FactoryComponentDeclaration>;
const RESOURCES = { const RESOURCES = {
// Raw resources // Raw resources
wood: { wood: {
@ -894,6 +922,10 @@ const factory = createLayer(id, () => {
} }
interface FactoryInternalProcessor extends FactoryInternalBase { interface FactoryInternalProcessor extends FactoryInternalBase {
type: Exclude<BuildableCompName, "conveyor">; type: Exclude<BuildableCompName, "conveyor">;
lastProdTimes: number[];
lastFactoryProd: number;
average: ComputedRef<number | undefined>;
} }
type FactoryInternal = FactoryInternalConveyor | FactoryInternalProcessor; type FactoryInternal = FactoryInternalConveyor | FactoryInternalProcessor;
@ -958,7 +990,7 @@ const factory = createLayer(id, () => {
style: "width: 110px" style: "width: 110px"
})); }));
const bearsBuyable = createBuyable(() => ({ const bearsBuyable = createBuyable(() => ({
resource: bears, resource: noPersist(bears),
cost() { cost() {
return Decimal.pow(2, Decimal.add(this.amount.value, 5)); return Decimal.pow(2, Decimal.add(this.amount.value, 5));
}, },
@ -970,7 +1002,7 @@ const factory = createLayer(id, () => {
visible: () => showIf(main.days[advancedDay - 1].opened.value) visible: () => showIf(main.days[advancedDay - 1].opened.value)
})); }));
const bucketBuyable = createBuyable(() => ({ const bucketBuyable = createBuyable(() => ({
resource: bucketAndShovels, resource: noPersist(bucketAndShovels),
cost() { cost() {
return Decimal.pow(2, Decimal.add(this.amount.value, 5)); return Decimal.pow(2, Decimal.add(this.amount.value, 5));
}, },
@ -982,7 +1014,7 @@ const factory = createLayer(id, () => {
visible: () => showIf(main.days[advancedDay - 1].opened.value) visible: () => showIf(main.days[advancedDay - 1].opened.value)
})); }));
const consolesBuyable = createBuyable(() => ({ const consolesBuyable = createBuyable(() => ({
resource: consoles, resource: noPersist(consoles),
cost() { cost() {
return Decimal.pow(2, Decimal.add(this.amount.value, 5)); return Decimal.pow(2, Decimal.add(this.amount.value, 5));
}, },
@ -1249,9 +1281,6 @@ const factory = createLayer(id, () => {
loaded = true; loaded = true;
watchEffect(updateGraphics); watchEffect(updateGraphics);
}); });
(window as any).internal = compInternalData;
(window as any).comp = components;
(window as any).blocks = movingBlocks;
function moveBlock(block: Block, newBlock: FactoryInternal, blockData: FactoryComponent) { function moveBlock(block: Block, newBlock: FactoryInternal, blockData: FactoryComponent) {
// empty spot // empty spot
@ -1280,7 +1309,7 @@ const factory = createLayer(id, () => {
globalBus.on("update", diff => { globalBus.on("update", diff => {
if (!loaded || paused.value) return; if (!loaded || paused.value) return;
const factoryTicks = Decimal.times(computedTickRate.value, diff).toNumber(); const factoryTicks = Decimal.times(computedActualTickRate.value, diff).toNumber();
//debugger //debugger
// make them produce // make them produce
@ -1361,7 +1390,10 @@ const factory = createLayer(id, () => {
if (val.resource != null) { if (val.resource != null) {
val.resource.value = Decimal.add( val.resource.value = Decimal.add(
val.resource.value, val.resource.value,
unref(val.amount) Decimal.times(
computedToyMultiplier.value,
unref(val.amount)
)
); );
} else { } else {
data.outputStock[key as ResourceNames] = data.outputStock[key as ResourceNames] =
@ -1371,6 +1403,11 @@ const factory = createLayer(id, () => {
} }
} }
data.ticksDone -= cyclesDone * factoryData.tick; data.ticksDone -= cyclesDone * factoryData.tick;
const now = Date.now();
const diff = (now - compData.lastFactoryProd) / 1000;
compData.lastProdTimes.push(diff);
if (compData.lastProdTimes.length > 10) compData.lastProdTimes.shift();
compData.lastFactoryProd = now;
} }
} else { } else {
data.ticksDone += factoryTicks; data.ticksDone += factoryTicks;
@ -1474,6 +1511,7 @@ const factory = createLayer(id, () => {
const factoryBaseData = FACTORY_COMPONENTS[data.type]; const factoryBaseData = FACTORY_COMPONENTS[data.type];
if (factoryBaseData == undefined) return; if (factoryBaseData == undefined) return;
const sheet = Assets.get(factoryBaseData.imageSrc); const sheet = Assets.get(factoryBaseData.imageSrc);
const sprite = new Sprite(sheet); const sprite = new Sprite(sheet);
watchEffect(() => { watchEffect(() => {
@ -1495,6 +1533,7 @@ const factory = createLayer(id, () => {
) * ) *
Math.PI) / Math.PI) /
2; 2;
if (factoryBaseData.extraImage != null) { if (factoryBaseData.extraImage != null) {
const sheet = Assets.get(factoryBaseData.extraImage); const sheet = Assets.get(factoryBaseData.extraImage);
const extraSprite = new Sprite(sheet); const extraSprite = new Sprite(sheet);
@ -1525,6 +1564,30 @@ const factory = createLayer(id, () => {
type: data.type, type: data.type,
packages: isConveyor ? [] : undefined, packages: isConveyor ? [] : undefined,
nextPackages: isConveyor ? [] : undefined, nextPackages: isConveyor ? [] : undefined,
lastProdTimes: !isConveyor ? (reactive([]) as number[]) : undefined,
lastFactoryProd: !isConveyor
? Date.now() -
1000 *
Decimal.div(
(data as FactoryComponentProcessor).ticksDone ?? 0,
computedActualTickRate.value
).toNumber()
: undefined,
average: !isConveyor
? computed(() => {
const times = (compInternalData[x + "x" + y] as FactoryInternalProcessor)
.lastProdTimes;
if (times.length === 0) return undefined;
// times is in SECONDS, not ticks
// seconds * Ticks per second -> ticks taken
return Decimal.mul(times.length, factoryBaseData.tick)
.div(times.reduce((x, n) => x + n, 0))
.div(computedActualTickRate.value)
.toNumber();
})
: undefined,
canProduce: computed(() => { canProduce: computed(() => {
if (data.type === "conveyor") return true; if (data.type === "conveyor") return true;
if (!(factoryBaseData.canProduce?.value ?? true)) return false; if (!(factoryBaseData.canProduce?.value ?? true)) return false;
@ -1532,7 +1595,7 @@ const factory = createLayer(id, () => {
const compData = components.value[x + "x" + y] as FactoryComponentProcessor; const compData = components.value[x + "x" + y] as FactoryComponentProcessor;
if (factoryBaseData.inputs !== undefined) { if (factoryBaseData.inputs !== undefined) {
for (const [res, val] of Object.entries(factoryBaseData.inputs)) for (const [res, val] of Object.entries(factoryBaseData.inputs))
if ((compData.inputStock?.[res as ResourceNames] ?? 0) < val.amount) if ((compData.inputStock?.[res as ResourceNames] ?? 0) < unref(val.amount))
return false; return false;
} }
if (factoryBaseData.outputs !== undefined) { if (factoryBaseData.outputs !== undefined) {
@ -1605,6 +1668,7 @@ const factory = createLayer(id, () => {
const pointerDown = ref(false), const pointerDown = ref(false),
pointerDrag = ref(false), pointerDrag = ref(false),
compHovered = ref<FactoryComponent | undefined>(undefined), compHovered = ref<FactoryComponent | undefined>(undefined),
compInternalHovered = shallowRef<FactoryInternal | undefined>(undefined),
paused = ref(false); paused = ref(false);
function onFactoryPointerMove(e: PointerEvent) { function onFactoryPointerMove(e: PointerEvent) {
@ -1634,12 +1698,12 @@ const factory = createLayer(id, () => {
} }
if (!pointerDown.value && !pointerDrag.value) { if (!pointerDown.value && !pointerDrag.value) {
const { tx, ty } = spriteContainer.localTransform; const { tx, ty } = spriteContainer.localTransform;
compHovered.value = const xyPos =
components.value[ Math.round(roundDownTo(x - tx, blockSize) / blockSize) +
Math.round(roundDownTo(x - tx, blockSize) / blockSize) + "x" +
"x" + Math.round(roundDownTo(y - ty, blockSize) / blockSize);
Math.round(roundDownTo(y - ty, blockSize) / blockSize) compHovered.value = components.value[xyPos];
]; compInternalHovered.value = compInternalData[xyPos];
} }
} }
function onFactoryPointerDown(e: PointerEvent) { function onFactoryPointerDown(e: PointerEvent) {
@ -1727,6 +1791,7 @@ const factory = createLayer(id, () => {
cComp.packages = []; cComp.packages = [];
} else { } else {
const producerComp = components.value[key] as FactoryComponentProcessor; const producerComp = components.value[key] as FactoryComponentProcessor;
const cComp = comp as FactoryInternalProcessor;
if (producerComp.outputStock !== undefined) { if (producerComp.outputStock !== undefined) {
for (const key in producerComp.outputStock) { for (const key in producerComp.outputStock) {
delete producerComp.outputStock[key as ResourceNames]; delete producerComp.outputStock[key as ResourceNames];
@ -1738,6 +1803,8 @@ const factory = createLayer(id, () => {
} }
} }
producerComp.ticksDone = 0; producerComp.ticksDone = 0;
cComp.lastFactoryProd = Date.now();
cComp.lastProdTimes.splice(0, Infinity);
} }
} }
} }
@ -1843,7 +1910,7 @@ const factory = createLayer(id, () => {
} }
const hoveredComponent = jsx(() => { const hoveredComponent = jsx(() => {
if (compHovered.value == null) { if (compHovered.value == null || compInternalHovered.value == null) {
return ""; return "";
} }
const factorySizeOffset = computedFactorySize.value % 2 === 0 ? blockSize / 2 : 0; const factorySizeOffset = computedFactorySize.value % 2 === 0 ? blockSize / 2 : 0;
@ -1866,19 +1933,50 @@ const factory = createLayer(id, () => {
<br /> <br />
{unref(FACTORY_COMPONENTS[compHovered.value.type].description)} {unref(FACTORY_COMPONENTS[compHovered.value.type].description)}
<br /> <br />
{compHovered.value.type !== "conveyor" ? ( {compHovered.value.type !== "conveyor" &&
compInternalHovered.value.type !== "conveyor" ? (
<> <>
{showStockAmount( {showStockAmount(
compHovered.value.inputStock, (compHovered.value as FactoryComponentProcessor).inputStock,
FACTORY_COMPONENTS[compHovered.value.type].inputs, FACTORY_COMPONENTS[compHovered.value.type].inputs,
"Inputs:" "Inputs:"
)} )}
{showStockAmount( {showStockAmount(
compHovered.value.outputStock, (compHovered.value as FactoryComponentProcessor).outputStock,
FACTORY_COMPONENTS[compHovered.value.type].outputs, FACTORY_COMPONENTS[compHovered.value.type].outputs,
"Outputs:", "Outputs:",
false false
)} )}
<br />
Efficency:{" "}
{(compInternalHovered.value as FactoryInternalProcessor).average.value !==
undefined ? (
<span
style={{
color:
(compInternalHovered.value as FactoryInternalProcessor)
.average.value! > 1
? "purple"
: (
compInternalHovered.value as FactoryInternalProcessor
).average.value! >= 0.9
? "green"
: (
compInternalHovered.value as FactoryInternalProcessor
).average.value! >= 0.5
? "yellow"
: "red"
}}
>
{formatWhole(
(compInternalHovered.value as FactoryInternalProcessor).average
.value! * 100
)}
</span>
) : (
"--"
)}
%
</> </>
) : undefined} ) : undefined}
</div> </div>
@ -2000,7 +2098,20 @@ const factory = createLayer(id, () => {
onUpdate:modelValue={(value: boolean) => (showModifiersModal.value = value)} onUpdate:modelValue={(value: boolean) => (showModifiersModal.value = value)}
v-slots={{ v-slots={{
header: () => <h2>{name} Modifiers</h2>, header: () => <h2>{name} Modifiers</h2>,
body: generalTab body: () => (
<>
{render(generalTab)}
{Decimal.gte(computedTickRate.value, 5) ? (
<>
<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.
</>
) : (
""
)}
</>
)
}} }}
/> />
)); ));
@ -2009,7 +2120,7 @@ const factory = createLayer(id, () => {
direction: Direction.Right, direction: Direction.Right,
width: 600, width: 600,
height: 25, height: 25,
fillStyle: `backgroundColor: ${color}`, fillStyle: `animation: 15s factory-bar linear infinite`,
progress: () => progress: () =>
main.day.value === day main.day.value === day
? Decimal.div(toys.clothes.value, toyGoal) ? Decimal.div(toys.clothes.value, toyGoal)
@ -2097,7 +2208,7 @@ const factory = createLayer(id, () => {
display: jsx(() => ( display: jsx(() => (
<> <>
{render(modifiersModal)} {render(modifiersModal)}
{render(tabs)} {render(tabs as VueFeature)}
</> </>
)) ))
}; };

View file

@ -62,4 +62,19 @@
green 10px 20px green 10px 20px
); );
} }
}
@keyframes factory-bar {
from {
background: 0 0 / 114px 114px repeat repeating-linear-gradient(-45deg,
grey 0 10px,
yellow 10px 20px
);
}
to {
background: 114px 0px / 114px 114px repeat repeating-linear-gradient(-45deg,
grey 0 10px,
yellow 10px 20px
);
}
} }

View file

@ -64,7 +64,7 @@
left: 0px; left: 0px;
right: 0px; right: 0px;
position: absolute; position: absolute;
background-color: var(--raised-background); background-color: snow;
overflow: hidden; overflow: hidden;
z-index: 1; z-index: 1;
} }
@ -109,7 +109,7 @@
.comp-info { .comp-info {
position: absolute; position: absolute;
top: 0; top: 0;
right: -10px; right: 0px;
padding: 5px 10px; padding: 5px 10px;
width: max-content; width: max-content;
@ -125,13 +125,14 @@
pointer-events: none; pointer-events: none;
transition: transform 0.3s; transition: transform 0.3s;
z-index: -1; z-index: -2;
} }
.comp-list .comp:nth-child(2n - 1) .comp-info { .comp-list .comp:nth-child(2n - 1) .comp-info {
right: -85px; right: -75px;
} }
.comp-list .comp:hover .comp-info { .comp-list .comp:hover .comp-info {
transform: translateX(calc(20px + 100%)); transform: translateX(calc(20px + 100%));
z-index: -1;
} }
.comp-list { .comp-list {
@ -141,6 +142,7 @@
overflow-x: hidden; overflow-x: hidden;
padding-right: 370px; padding-right: 370px;
direction: rtl; direction: rtl;
padding-left: 10px;
} }
.comp-list-child { .comp-list-child {
@ -158,6 +160,7 @@
position: absolute; position: absolute;
border-right: solid 2px var(--locked); border-right: solid 2px var(--locked);
background: var(--raised-background); background: var(--raised-background);
box-shadow: 0 2px 10px #0007;
top: 0; top: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;

View file

@ -14,7 +14,8 @@ export const {
formatSmall, formatSmall,
formatLimit, formatLimit,
invertOOM, invertOOM,
formatGain formatGain,
formatList
} = numberUtils; } = numberUtils;
export type DecimalSource = RawDecimalSource; export type DecimalSource = RawDecimalSource;
@ -34,6 +35,7 @@ declare global {
formatLimit: (list: [DecimalSource, string][], unit: string) => string; formatLimit: (list: [DecimalSource, string][], unit: string) => string;
invertOOM: (x: DecimalSource) => Decimal; invertOOM: (x: DecimalSource) => Decimal;
formatGain: (x: DecimalSource) => string; formatGain: (x: DecimalSource) => string;
formatList: (x: string[]) => string;
} }
} }
window.Decimal = Decimal; window.Decimal = Decimal;
@ -48,5 +50,6 @@ window.formatSmall = formatSmall;
window.formatLimit = formatLimit; window.formatLimit = formatLimit;
window.invertOOM = invertOOM; window.invertOOM = invertOOM;
window.formatGain = formatGain; window.formatGain = formatGain;
window.formatList = formatList;
export default Decimal; export default Decimal;

View file

@ -219,3 +219,9 @@ export function formatGain(gain: DecimalSource) {
1: `+${format(gain)}/s` 1: `+${format(gain)}/s`
}[Decimal.compare(gain, 0)]; }[Decimal.compare(gain, 0)];
} }
export function formatList(list: string[]) {
if (list.length <= 0) return "";
if (list.length == 1) return list[0];
return list.slice(0, -1).join(", ") + " and " + list[list.length - 1];
}