UX update, more mobile friendly

This commit is contained in:
ducdat0507 2022-12-22 18:50:59 +07:00
parent 5e1da63401
commit 546d8dba50
12 changed files with 403 additions and 245 deletions

View file

@ -1,6 +1,6 @@
<template> <template>
<span style="white-space: nowrap"> <span style="white-space: nowrap">
<span style="font-size: larger; font-family: initial">&radic;</span> <span style="font-size: larger; font-family: initial; font-weight: bold">&radic;</span>
<div style="display: inline-block; border-top: 1px solid; padding-left: 0.2em"> <div style="display: inline-block; border-top: 1px solid; padding-left: 0.2em">
<slot /> <slot />
</div> </div>

View file

@ -27,7 +27,7 @@ onMounted(() => {
top: 0; top: 0;
bottom: 0; bottom: 0;
right: 0; right: 0;
width: 500px; width: 100%;
touch-action: none; touch-action: none;
} }
</style> </style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"><path d="M30.25 42.75q-.95.45-1.9.1t-1.4-1.3l-6.35-13.6-5.9 8.25q-.65.9-1.675.55T12 35.3V7.1q0-.95.85-1.35.85-.4 1.6.15L36.6 23.3q.85.7.475 1.7t-1.425 1h-10.4l6.2 13.45q.45.95.1 1.9t-1.3 1.4Z" fill="white" stroke="black"/></svg>

After

Width:  |  Height:  |  Size: 291 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"><path d="M13.05 42q-1.2 0-2.1-.9-.9-.9-.9-2.1V10.5H9.5q-.65 0-1.075-.425Q8 9.65 8 9q0-.65.425-1.075Q8.85 7.5 9.5 7.5h7.9q0-.65.425-1.075Q18.25 6 18.9 6h10.2q.65 0 1.075.425.425.425.425 1.075h7.9q.65 0 1.075.425Q40 8.35 40 9q0 .65-.425 1.075-.425.425-1.075.425h-.55V39q0 1.2-.9 2.1-.9.9-2.1.9Zm5.3-8.8q0 .65.425 1.075.425.425 1.075.425.65 0 1.075-.425.425-.425.425-1.075V16.25q0-.65-.425-1.075-.425-.425-1.075-.425-.65 0-1.075.425-.425.425-.425 1.075Zm8.3 0q0 .65.425 1.075.425.425 1.075.425.65 0 1.075-.425.425-.425.425-1.075V16.25q0-.65-.425-1.075-.425-.425-1.075-.425-.65 0-1.075.425-.425.425-.425 1.075Z" fill="white" stroke="black"/></svg>

After

Width:  |  Height:  |  Size: 706 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"><path d="M7.9 23.6q-.75 0-1.2-.525-.45-.525-.3-1.225.35-1.55.925-3Q7.9 17.4 8.7 16.05q.4-.65 1.075-.7.675-.05 1.225.5.4.35.45.9.05.55-.2 1-.7 1.15-1.175 2.325Q9.6 21.25 9.35 22.4q-.1.55-.5.875-.4.325-.95.325Zm12.15 20.1q-1.45-.35-2.9-.925Q15.7 42.2 14.4 41.4q-.65-.4-.7-1.1-.05-.7.5-1.3.35-.35.85-.4.5-.05.9.2 1.15.7 2.275 1.175 1.125.475 2.325.775.5.1.85.525.35.425.35.975 0 .75-.5 1.175-.5.425-1.2.275Zm-11.35-8q-.8-1.3-1.375-2.775Q6.75 31.45 6.4 29.85q-.15-.7.275-1.225Q7.1 28.1 7.9 28.1q.5 0 .925.325.425.325.525.875.25 1.25.7 2.425.45 1.175 1.15 2.225.3.45.25 1-.05.55-.45.95-.55.55-1.225.5-.675-.05-1.075-.7Zm19.25 7.95q-.7.2-1.2-.225-.5-.425-.5-1.175 0-.5.35-.925.35-.425.85-.575 5.05-1.35 8.3-5.375Q39 31.35 39 25.85q0-6.35-4.325-10.675Q30.35 10.85 24 10.85h-1l2.85 2.85q.45.45.45 1.1 0 .65-.45 1.1-.45.45-1.1.45-.65 0-1.1-.45l-5.5-5.5q-.25-.25-.35-.5-.1-.25-.1-.55 0-.3.1-.55.1-.25.35-.5l5.5-5.5q.45-.45 1.1-.45.65 0 1.1.45.45.45.45 1.1 0 .65-.45 1.1L23 7.85h1q7.55 0 12.775 5.225Q42 18.3 42 25.85q0 6.55-3.925 11.425Q34.15 42.15 27.95 43.65Z" fill="white" stroke="black"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"><path d="M40.2 23.6q-.5 0-.925-.35-.425-.35-.525-.85-.25-1.2-.725-2.35-.475-1.15-1.175-2.3-.25-.45-.2-1 .05-.55.45-.95.55-.55 1.25-.475.7.075 1.1.725.8 1.3 1.35 2.725t.9 3.025q.15.7-.3 1.25-.45.55-1.2.55ZM26.3 42.2q0-.5.35-.925.35-.425.85-.525 1.15-.25 2.3-.725t2.3-1.175q.45-.25.975-.225.525.025.925.425.55.55.475 1.25-.075.7-.725 1.1-1.35.85-2.775 1.4-1.425.55-2.875.9-.7.15-1.25-.3-.55-.45-.55-1.2Zm10.8-6.3q-.35-.35-.4-.925-.05-.575.2-1.025.7-1.15 1.15-2.3.45-1.15.7-2.35.1-.5.5-.85t.95-.35q.75 0 1.175.525.425.525.275 1.225-.4 1.6-.95 3.05-.55 1.45-1.3 2.75-.4.65-1.075.725-.675.075-1.225-.475Zm-17.05 7.8Q13.9 42.3 10 37.35q-3.9-4.95-3.9-11.5 0-7.55 5.225-12.775Q16.55 7.85 24.1 7.85h1L22.25 5q-.45-.45-.45-1.1 0-.65.45-1.1.45-.45 1.1-.45.65 0 1.1.45l5.5 5.5q.25.25.35.5.1.25.1.55 0 .3-.1.55-.1.25-.35.5l-5.5 5.5q-.45.45-1.1.45-.65 0-1.1-.45-.45-.45-.45-1.1 0-.65.45-1.1l2.85-2.85h-1q-6.35 0-10.675 4.325Q9.1 19.5 9.1 25.85q0 5.5 3.25 9.525t8.3 5.325q.5.1.85.525.35.425.35.975 0 .75-.55 1.2-.55.45-1.25.3Z" fill="white" stroke="black"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -11,20 +11,26 @@ import { Persistent, persistent, State } from "game/persistence";
import Decimal, { format, formatWhole } from "util/bignum"; import Decimal, { format, formatWhole } from "util/bignum";
import { Direction } from "util/common"; import { Direction } from "util/common";
import { computed, ComputedRef, reactive, ref, watchEffect } from "vue"; import { computed, ComputedRef, reactive, ref, watchEffect } from "vue";
import conveyor from "./factory-components/conveyor.png"; import _conveyor from "./factory-components/conveyor.png";
import cursor from "./factory-components/cursor.jpg"; import _cursor from "./factory-components/cursor.svg";
import rotate from "./factory-components/rotate_rectangle.png"; import _delete from "./factory-components/delete.svg";
import wood from "./factory-components/rotate_rectangle.png"; import _rotateLeft from "./factory-components/rotateLeft.svg";
import block from "./factory-components/rotate_rectangle.png"; import _rotateRight from "./factory-components/rotateRight.svg";
import cloth from "./factory-components/rotate_rectangle.png"; import _wood from "./factory-components/rotate_rectangle.png";
import dye from "./factory-components/rotate_rectangle.png"; import _block from "./factory-components/rotate_rectangle.png";
import clothes from "./factory-components/rotate_rectangle.png"; import _cloth from "./factory-components/rotate_rectangle.png";
import plastic from "./factory-components/rotate_rectangle.png"; import _dye from "./factory-components/rotate_rectangle.png";
import metal from "./factory-components/rotate_rectangle.png"; import _clothes from "./factory-components/rotate_rectangle.png";
import truck from "./factory-components/rotate_rectangle.png"; import _plastic from "./factory-components/rotate_rectangle.png";
import _metal from "./factory-components/rotate_rectangle.png";
import _truck from "./factory-components/rotate_rectangle.png";
import Factory from "./Factory.vue"; import Factory from "./Factory.vue";
import "./styles/factory.css"; import "./styles/factory.css";
import coal from "./coal"; import coal from "./coal";
import { createBar } from "features/bars/bar";
import { render } from "util/vue";
import { createTab } from "features/tabs/tab";
import { createTabFamily } from "features/tabs/tabFamily";
const id = "factory"; const id = "factory";
@ -83,34 +89,82 @@ const factory = createLayer(id, () => {
const name = "The Factory"; const name = "The Factory";
const color = "grey"; const color = "grey";
// ---------------------------------------------- Energy
const energy = computed(() => Decimal.add(1, coal.coal.value).log10()); const energy = computed(() => Decimal.add(1, coal.coal.value).log10());
const energyConsumption = computed(() => const energyConsumption = computed(() =>
Object.values(components.value) Object.values(components.value)
.map(c => FACTORY_COMPONENTS[c.type].energyCost ?? 0) .map(c => FACTORY_COMPONENTS[c.type]?.energyCost ?? 0)
.reduce((a, b) => a + b, 0) .reduce((a, b) => a + b, 0)
); );
const tickRate = computed(() => const tickRate = computed(() =>
Decimal.div(energyConsumption.value, energy.value).recip().pow(2).min(1) Decimal.div(energyConsumption.value || 1, energy.value)
.recip()
.pow(2)
.min(1)
); );
const energyBar = createBar(() => ({
width: 680,
height: 50,
direction: Direction.Right,
classes: { "energy-bar": true },
style: { borderRadius: "var(--border-radius) var(--border-radius) 0 0" },
borderStyle: { borderRadius: "var(--border-radius) var(--border-radius) 0 0" },
fillStyle: () => ({
backgroundColor: Decimal.gt(energyConsumption.value, energy.value) ? "red" : "yellow"
}),
progress: () =>
Decimal.gt(energyConsumption.value, energy.value)
? Decimal.sub(1, Decimal.div(energy.value, energyConsumption.value))
: Decimal.sub(1, Decimal.div(energyConsumption.value, energy.value)),
display: jsx(() => (
<>
{formatWhole(energyConsumption.value)} / {formatWhole(energy.value)} energy used
{Decimal.lt(tickRate.value, 1) ? (
<>{" (" + format(Decimal.mul(tickRate.value, 100))}% efficiency)</>
) : (
""
)}
</>
))
}));
// ---------------------------------------------- Components // ---------------------------------------------- Components
const FACTORY_COMPONENTS = { const FACTORY_COMPONENTS = {
cursor: { cursor: {
imageSrc: cursor, imageSrc: _cursor,
name: "Cursor", name: "Cursor",
description: "Use this to move.", type: "command",
description: "Drag to move around.",
tick: 0 tick: 0
}, },
rotate: { delete: {
imageSrc: rotate, imageSrc: _delete,
name: "Rotate", name: "Delete",
description: "Use this to rotate components.", type: "command",
description: "Remove components from the board.",
tick: 0
},
rotateLeft: {
imageSrc: _rotateLeft,
name: "Rotate Left",
type: "command",
description: "Use this to rotate components counter-clockwise.",
tick: 0
},
rotateRight: {
imageSrc: _rotateRight,
name: "Rotate Right",
type: "command",
description: "Use this to rotate components clockwise.",
tick: 0 tick: 0
}, },
conveyor: { conveyor: {
imageSrc: conveyor, imageSrc: _conveyor,
name: "Conveyor", name: "Conveyor",
type: "conveyor",
description: "Moves items at 1 block per second.", description: "Moves items at 1 block per second.",
energyCost: 1, energyCost: 1,
tick: 1, tick: 1,
@ -124,8 +178,9 @@ const factory = createLayer(id, () => {
} }
}, },
wood: { wood: {
imageSrc: wood, imageSrc: _wood,
name: "Wood Machine", name: "Wood Machine",
type: "processor",
description: "Produces 1 wood every 1 second.", description: "Produces 1 wood every 1 second.",
energyCost: 10, energyCost: 10,
tick: 1, tick: 1,
@ -136,8 +191,9 @@ const factory = createLayer(id, () => {
} }
}, },
cloth: { cloth: {
imageSrc: cloth, imageSrc: _cloth,
name: "Cloth Machine", name: "Cloth Machine",
type: "processor",
description: "Produces 1 cloth every 1 second.", description: "Produces 1 cloth every 1 second.",
energyCost: 10, energyCost: 10,
tick: 1, tick: 1,
@ -148,8 +204,9 @@ const factory = createLayer(id, () => {
} }
}, },
dye: { dye: {
imageSrc: dye, imageSrc: _dye,
name: "Dye Machine", name: "Dye Machine",
type: "processor",
description: "Produces 1 dye every 1 second.", description: "Produces 1 dye every 1 second.",
energyCost: 10, energyCost: 10,
tick: 1, tick: 1,
@ -160,8 +217,9 @@ const factory = createLayer(id, () => {
} }
}, },
metal: { metal: {
imageSrc: metal, imageSrc: _metal,
name: "Metal Machine", name: "Metal Machine",
type: "processor",
description: "Produces 1 metal every 1 second.", description: "Produces 1 metal every 1 second.",
energyCost: 10, energyCost: 10,
tick: 1, tick: 1,
@ -172,8 +230,9 @@ const factory = createLayer(id, () => {
} }
}, },
plastic: { plastic: {
imageSrc: plastic, imageSrc: _plastic,
name: "Plastic Machine", name: "Plastic Machine",
type: "processor",
description: "Produces 1 plastic every 1 second.", description: "Produces 1 plastic every 1 second.",
energyCost: 10, energyCost: 10,
tick: 1, tick: 1,
@ -184,8 +243,9 @@ const factory = createLayer(id, () => {
} }
}, },
blocks: { blocks: {
imageSrc: block, imageSrc: _block,
name: "Wooden Block Maker", name: "Wooden Block Maker",
type: "processor",
description: "Turns 2 wood into 1 wooden block every second.", description: "Turns 2 wood into 1 wooden block every second.",
energyCost: 20, energyCost: 20,
tick: 1, tick: 1,
@ -201,8 +261,9 @@ const factory = createLayer(id, () => {
} }
}, },
clothes: { clothes: {
imageSrc: clothes, imageSrc: _clothes,
name: "Clothes Maker", name: "Clothes Maker",
type: "processor",
description: "Turns 2 cloth and 1 dye into 1 clothe every second.", description: "Turns 2 cloth and 1 dye into 1 clothe every second.",
energyCost: 20, energyCost: 20,
tick: 1, tick: 1,
@ -221,8 +282,9 @@ const factory = createLayer(id, () => {
} }
}, },
trucks: { trucks: {
imageSrc: truck, imageSrc: _truck,
name: "Trucks Maker", name: "Trucks Maker",
type: "processor",
description: "Turns 2 metal and 1 plastic into 1 truck every second.", description: "Turns 2 metal and 1 plastic into 1 truck every second.",
energyCost: 20, energyCost: 20,
tick: 1, tick: 1,
@ -242,18 +304,20 @@ const factory = createLayer(id, () => {
} }
} as Record<FactoryCompNames, FactoryComponentDeclaration>; } as Record<FactoryCompNames, FactoryComponentDeclaration>;
const RESOURCES = { const RESOURCES = {
wood: wood, wood: _wood,
block: block, block: _block,
cloth: cloth, cloth: _cloth,
dye: dye, dye: _dye,
clothes: clothes, clothes: _clothes,
plastic: plastic, plastic: _plastic,
metal: metal metal: _metal
} as Record<string, string>; } as Record<string, string>;
type FactoryCompNames = type FactoryCompNames =
| "cursor" | "cursor"
| "rotate" | "delete"
| "rotateLeft"
| "rotateRight"
| "conveyor" | "conveyor"
| "wood" | "wood"
| "blocks" | "blocks"
@ -269,7 +333,7 @@ const factory = createLayer(id, () => {
direction: Direction; direction: Direction;
} }
interface FactoryComponentProducer extends FactoryComponentBase { interface FactoryComponentProcessor extends FactoryComponentBase {
type: Exclude<BuildableCompName, "conveyor">; type: Exclude<BuildableCompName, "conveyor">;
inputStock?: Record<string, number>; inputStock?: Record<string, number>;
@ -283,12 +347,13 @@ const factory = createLayer(id, () => {
} }
type FactoryComponent = FactoryComponentBase & type FactoryComponent = FactoryComponentBase &
(FactoryComponentConveyor | FactoryComponentProducer); (FactoryComponentConveyor | FactoryComponentProcessor);
interface FactoryComponentDeclaration { interface FactoryComponentDeclaration {
tick: number; tick: number;
imageSrc: string; imageSrc: string;
name: string; name: string;
type: "command" | "conveyor" | "processor";
description: string; description: string;
energyCost?: number; energyCost?: number;
@ -327,10 +392,10 @@ const factory = createLayer(id, () => {
packages: Block[]; packages: Block[];
nextPackages: Block[]; nextPackages: Block[];
} }
interface FactoryInternalProducer extends FactoryInternalBase { interface FactoryInternalProcessor extends FactoryInternalBase {
type: Exclude<BuildableCompName, "conveyor">; type: Exclude<BuildableCompName, "conveyor">;
} }
type FactoryInternal = FactoryInternalConveyor | FactoryInternalProducer; type FactoryInternal = FactoryInternalConveyor | FactoryInternalProcessor;
interface Block { interface Block {
sprite: Sprite; sprite: Sprite;
@ -413,6 +478,8 @@ const factory = createLayer(id, () => {
} }
} }
updateGraphics();
loaded = true; loaded = true;
}); });
(window as any).internal = compInternalData; (window as any).internal = compInternalData;
@ -463,7 +530,7 @@ const factory = createLayer(id, () => {
} else { } else {
// send it to the factory // send it to the factory
// destory its sprite and data // destory its sprite and data
const factoryData = storedComp as FactoryComponentProducer; const factoryData = storedComp as FactoryComponentProcessor;
if (factoryData.inputStock !== undefined) if (factoryData.inputStock !== undefined)
factoryData.inputStock[block.type] = Math.min( factoryData.inputStock[block.type] = Math.min(
(factoryData.inputStock[block.type] ?? 0) + 1, (factoryData.inputStock[block.type] ?? 0) + 1,
@ -499,7 +566,7 @@ const factory = createLayer(id, () => {
} else { } else {
// send it to the factory // send it to the factory
// destory its sprite and data // destory its sprite and data
const data = storedComp as FactoryComponentProducer; const data = storedComp as FactoryComponentProcessor;
if (factoryData.inputs?.[block.type] !== undefined) { if (factoryData.inputs?.[block.type] !== undefined) {
if (data.inputStock === undefined) data.inputStock = {}; if (data.inputStock === undefined) data.inputStock = {};
data.inputStock[block.type] = data.inputStock[block.type] =
@ -520,8 +587,8 @@ const factory = createLayer(id, () => {
} }
} }
} else { } else {
const data = _data as FactoryComponentProducer; const data = _data as FactoryComponentProcessor;
const compData = _compData as FactoryInternalProducer; const compData = _compData as FactoryInternalProcessor;
// factory part // factory part
// PRODUCTION // PRODUCTION
if (data.ticksDone >= factoryData.tick) { if (data.ticksDone >= factoryData.tick) {
@ -606,16 +673,18 @@ const factory = createLayer(id, () => {
// if X is being moved, then we don't need to adjust x // if X is being moved, then we don't need to adjust x
// however it needs to be aligned if Y is being moved // however it needs to be aligned if Y is being moved
// vice-versa // vice-versa
sprite.x = (x + xInc * 0.3) * blockSize; sprite.x =
sprite.y = (y + yInc * 0.3) * blockSize; (x + xInc * 0.3 + (xInc == 0 ? Math.random() * 0.4 - 0.2 : 0)) * blockSize;
sprite.y =
(y + yInc * 0.3 + (yInc == 0 ? Math.random() * 0.4 - 0.2 : 0)) * blockSize;
sprite.anchor.set(0.5); sprite.anchor.set(0.5);
sprite.width = blockSize / 2.5; sprite.width = blockSize / 2.5;
sprite.height = blockSize / 5; sprite.height = blockSize / 5;
//console.log(sprite); //console.log(sprite);
const block: Block = { const block: Block = {
sprite, sprite,
x: x + xInc * 0.3, x: sprite.x / blockSize,
y: y + yInc * 0.3, y: sprite.y / blockSize,
turbulance: Math.random() * 0.4 - 0.2, turbulance: Math.random() * 0.4 - 0.2,
type: itemToMove[0] type: itemToMove[0]
}; };
@ -637,6 +706,7 @@ const factory = createLayer(id, () => {
if (y < -factorySize.height || y >= factorySize.height) return; if (y < -factorySize.height || y >= factorySize.height) return;
const factoryBaseData = FACTORY_COMPONENTS[data.type]; const factoryBaseData = FACTORY_COMPONENTS[data.type];
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);
@ -678,7 +748,7 @@ const factory = createLayer(id, () => {
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;
// this should NEVER be null // this should NEVER be null
const compData = components.value[x + "x" + y] as FactoryComponentProducer; 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] ?? 0) < val.amount) return false; if ((compData.inputStock?.[res] ?? 0) < val.amount) return false;
@ -694,7 +764,7 @@ const factory = createLayer(id, () => {
return true; return true;
}), }),
sprite sprite
} as FactoryInternalProducer; } as FactoryInternalProcessor;
spriteContainer.addChild(sprite); spriteContainer.addChild(sprite);
} }
@ -710,11 +780,7 @@ const factory = createLayer(id, () => {
spriteContainer.y = movingBlocks.y = calculatedY; spriteContainer.y = movingBlocks.y = calculatedY;
graphicContainer.removeChild(hoverSprite); graphicContainer.removeChild(hoverSprite);
if ( if (isMouseHoverShown.value && compSelected.value !== "cursor") {
isMouseHoverShown.value &&
compSelected.value !== "cursor" &&
compSelected.value !== "rotate"
) {
const { tx, ty } = spriteContainer.localTransform; const { tx, ty } = spriteContainer.localTransform;
graphicContainer.lineStyle(4, 0x808080, 1); graphicContainer.lineStyle(4, 0x808080, 1);
graphicContainer.drawRect( graphicContainer.drawRect(
@ -790,7 +856,7 @@ const factory = createLayer(id, () => {
x = roundDownTo(x - tx, blockSize) / blockSize; x = roundDownTo(x - tx, blockSize) / blockSize;
y = roundDownTo(y - ty, blockSize) / blockSize; y = roundDownTo(y - ty, blockSize) / blockSize;
if (e.button === 0) { if (e.button === 0) {
if (compSelected.value === "rotate") { if (compSelected.value === "rotateLeft") {
if ( if (
components.value[x + "x" + y] != null && components.value[x + "x" + y] != null &&
components.value[x + "x" + y].direction != null components.value[x + "x" + y].direction != null
@ -799,35 +865,52 @@ const factory = createLayer(id, () => {
...components.value[x + "x" + y], ...components.value[x + "x" + y],
direction: rotateDir( direction: rotateDir(
(components.value[x + "x" + y] as FactoryComponentConveyor) (components.value[x + "x" + y] as FactoryComponentConveyor)
.direction .direction,
Direction.Left
)
};
compInternalData[x + "x" + y].sprite.rotation -= Math.PI / 2;
}
} else if (compSelected.value === "rotateRight") {
if (
components.value[x + "x" + y] != null &&
components.value[x + "x" + y].direction != null
) {
components.value[x + "x" + y] = {
...components.value[x + "x" + y],
direction: rotateDir(
(components.value[x + "x" + y] as FactoryComponentConveyor)
.direction,
Direction.Right
) )
}; };
compInternalData[x + "x" + y].sprite.rotation += Math.PI / 2; compInternalData[x + "x" + y].sprite.rotation += Math.PI / 2;
} }
} else if (compSelected.value === "delete") {
const data = compInternalData[x + "x" + y];
if (data === undefined) return;
if (data.type === "conveyor") {
const cData = data as FactoryInternalConveyor;
for (const p of cData.packages) {
p.sprite.destroy();
}
}
delete components.value[x + "x" + y];
delete compInternalData[x + "x" + y];
spriteContainer.removeChild(data.sprite);
} else if (compSelected.value !== "cursor") { } else if (compSelected.value !== "cursor") {
if (components.value[x + "x" + y] == null) { if (components.value[x + "x" + y] == null) {
addFactoryComp(x, y, { type: compSelected.value }); addFactoryComp(x, y, { type: compSelected.value });
} }
} }
} else if (e.button === 2) {
const data = compInternalData[x + "x" + y];
if (data === undefined) return;
if (data.type === "conveyor") {
const cData = data as FactoryInternalConveyor;
for (const p of cData.packages) {
p.sprite.destroy();
}
}
delete components.value[x + "x" + y];
delete compInternalData[x + "x" + y];
spriteContainer.removeChild(data.sprite);
} }
} }
window.removeEventListener("pointerup", onFactoryPointerUp); window.removeEventListener("pointerup", onFactoryPointerUp);
pointerDown.value = pointerDrag.value = false; pointerDown.value = pointerDrag.value = false;
onFactoryPointerMove(e);
} }
function onFactoryMouseEnter() { function onFactoryMouseEnter() {
isMouseHoverShown.value = true; isMouseHoverShown.value = true;
@ -848,176 +931,211 @@ const factory = createLayer(id, () => {
compSelected.value = name; compSelected.value = name;
} }
// ------------------------------------------------------------------------------- Tabs
const tabs = createTabFamily(
{
dashboard: () => ({
tab: createTab(() => ({
display: jsx(() => <>You have 20 energy</>)
})),
display: "Dashboard"
}),
factory: () => ({
tab: createTab(() => ({
display: jsx(() => (
<>
{render(energyBar)}
<div class="factory-container">
<Factory
application={app}
onPointermove={onFactoryPointerMove}
onPointerdown={onFactoryPointerDown}
onPointerenter={onFactoryMouseEnter}
onPointerleave={onFactoryMouseLeave}
onContextmenu={(e: MouseEvent) => e.preventDefault()}
/>
<div class="comp-container">
<div
class={{
"comp-info": true,
active: isComponentHover.value
}}
style={{
top:
Math.floor(
Math.max(
Object.keys(FACTORY_COMPONENTS).indexOf(
whatIsHovered.value
),
0
) / 2
) *
70 +
10 +
"px"
}}
>
{whatIsHovered.value === "" ? undefined : (
<>
<h3>
{FACTORY_COMPONENTS[whatIsHovered.value].name}
</h3>
<br />
{
FACTORY_COMPONENTS[whatIsHovered.value]
.description
}
{FACTORY_COMPONENTS[whatIsHovered.value]
.energyCost ?? 0 ? (
<>
<br />
Energy Consumption:{" "}
{formatWhole(
FACTORY_COMPONENTS[whatIsHovered.value]
.energyCost ?? 0
)}
</>
) : null}
</>
)}
</div>
<div class="comp-list">
{Object.entries(FACTORY_COMPONENTS).map(value => {
const key = value[0] as FactoryCompNames;
const item = value[1];
return (
<img
src={item.imageSrc}
class={{ selected: compSelected.value === key }}
onMouseenter={() => onComponentMouseEnter(key)}
onMouseleave={() => onComponentMouseLeave()}
onClick={() => onCompClick(key)}
/>
);
})}
</div>
</div>
{compHovered.value !== undefined ? (
<div
class="info-container"
id="factory-info"
style={{
...(mouseCoords.x +
(document.getElementById("factory-info")
?.clientWidth ?? 0) >
app.view.width - 30
? { right: app.view.width - mouseCoords.x + "px" }
: { left: mouseCoords.x + "px" }),
...(mouseCoords.y +
(document.getElementById("factory-info")
?.clientHeight ?? 0) >
app.view.height - 30
? { bottom: app.view.height - mouseCoords.y + "px" }
: { top: mouseCoords.y + "px" })
}}
>
<h3>{FACTORY_COMPONENTS[compHovered.value.type].name}</h3>
<br />
{FACTORY_COMPONENTS[compHovered.value.type].description}
<br />
{compHovered.value.type !== "conveyor" ? (
<>
{compHovered.value.inputStock !== undefined ? (
<>
<br />
<h5>Inputs:</h5>
{Object.entries(
compHovered.value.inputStock
).map(x => (
<div>
{x[0]}: {formatWhole(x[1])}
{FACTORY_COMPONENTS[
compHovered.value?.type ??
"cursor"
].inputs?.[x[0]].amount !==
undefined
? " / " +
formatWhole(
FACTORY_COMPONENTS[
compHovered.value
?.type ?? "cursor"
].inputs?.[x[0]].amount ??
0
)
: ""}
{FACTORY_COMPONENTS[
compHovered.value?.type ??
"cursor"
].inputs?.[x[0]].capacity !==
undefined
? " / " +
formatWhole(
FACTORY_COMPONENTS[
compHovered.value
?.type ?? "cursor"
].inputs?.[x[0]]
.capacity ?? 0
)
: ""}
</div>
))}
</>
) : undefined}
{compHovered.value.outputStock !== undefined ? (
<>
<br />
<h5>Outputs:</h5>
{Object.entries(
compHovered.value.outputStock
).map(x => (
<div>
{x[0]}: {formatWhole(x[1])}
{FACTORY_COMPONENTS[
compHovered.value?.type ??
"cursor"
].outputs?.[x[0]].capacity !==
undefined
? " / " +
formatWhole(
FACTORY_COMPONENTS[
compHovered.value
?.type ?? "cursor"
].outputs?.[x[0]]
.capacity ?? 0
)
: ""}
</div>
))}
</>
) : undefined}
</>
) : undefined}
</div>
) : undefined}
</div>
</>
))
})),
display: "Factory"
})
},
() => ({
classes: { "factory-tabs": true }
})
);
return { return {
name, name,
day, day,
color, color,
minWidth: 700, minWidth: 700,
minimizable: false, minimizable: true,
style: { overflow: "hidden" }, style: { overflow: "hidden" },
components, components,
display: jsx(() => ( tabs,
<> display: jsx(() => <>{render(tabs)}</>)
<div class="factory-container">
<Factory
application={app}
onPointermove={onFactoryPointerMove}
onPointerdown={onFactoryPointerDown}
onPointerenter={onFactoryMouseEnter}
onPointerleave={onFactoryMouseLeave}
onContextmenu={(e: MouseEvent) => e.preventDefault()}
/>
<div class="comp-container">
<div
class={{
"comp-info": true,
active: isComponentHover.value
}}
style={{
top:
Math.floor(
Math.max(
Object.keys(FACTORY_COMPONENTS).indexOf(
whatIsHovered.value
),
0
) / 2
) *
70 +
10 +
"px"
}}
>
{whatIsHovered.value === "" ? undefined : (
<>
<h3>{FACTORY_COMPONENTS[whatIsHovered.value].name}</h3>
<br />
{FACTORY_COMPONENTS[whatIsHovered.value].description}
{FACTORY_COMPONENTS[whatIsHovered.value].energyCost ?? 0 ? (
<>
<br />
Energy Consumption:{" "}
{formatWhole(
FACTORY_COMPONENTS[whatIsHovered.value]
.energyCost ?? 0
)}
</>
) : null}
</>
)}
</div>
<div class="comp-list">
{Object.entries(FACTORY_COMPONENTS).map(value => {
const key = value[0] as FactoryCompNames;
const item = value[1];
return (
<img
src={item.imageSrc}
class={{ selected: compSelected.value === key }}
onMouseenter={() => onComponentMouseEnter(key)}
onMouseleave={() => onComponentMouseLeave()}
onClick={() => onCompClick(key)}
/>
);
})}
</div>
</div>
{compHovered.value !== undefined ? (
<div
class="info-container"
id="factory-info"
style={{
...(mouseCoords.x >= 180
? { right: app.view.width - mouseCoords.x + "px" }
: { left: mouseCoords.x + 150 + "px" }),
...(mouseCoords.y +
(document.getElementById("factory-info")?.clientHeight ?? 0) >
app.view.height - 30
? { bottom: app.view.height - mouseCoords.y + "px" }
: { top: mouseCoords.y + "px" })
}}
>
<h3>{FACTORY_COMPONENTS[compHovered.value.type].name}</h3>
<br />
{FACTORY_COMPONENTS[compHovered.value.type].description}
<br />
{compHovered.value.type !== "conveyor" ? (
<>
{compHovered.value.inputStock !== undefined ? (
<>
<br />
<h5>Inputs:</h5>
{Object.entries(compHovered.value.inputStock).map(x => (
<div>
{x[0]}: {formatWhole(x[1])}
{FACTORY_COMPONENTS[
compHovered.value?.type ?? "cursor"
].inputs?.[x[0]].amount !== undefined
? " / " +
formatWhole(
FACTORY_COMPONENTS[
compHovered.value?.type ??
"cursor"
].inputs?.[x[0]].amount ?? 0
)
: ""}
{FACTORY_COMPONENTS[
compHovered.value?.type ?? "cursor"
].inputs?.[x[0]].capacity !== undefined
? " / " +
formatWhole(
FACTORY_COMPONENTS[
compHovered.value?.type ??
"cursor"
].inputs?.[x[0]].capacity ?? 0
)
: ""}
</div>
))}
</>
) : undefined}
{compHovered.value.outputStock !== undefined ? (
<>
<br />
<h5>Outputs:</h5>
{Object.entries(compHovered.value.outputStock).map(
x => (
<div>
{x[0]}: {formatWhole(x[1])}
{FACTORY_COMPONENTS[
compHovered.value?.type ?? "cursor"
].outputs?.[x[0]].capacity !== undefined
? " / " +
formatWhole(
FACTORY_COMPONENTS[
compHovered.value?.type ??
"cursor"
].outputs?.[x[0]].capacity ?? 0
)
: ""}
</div>
)
)}
</>
) : undefined}
</>
) : undefined}
</div>
) : undefined}
</div>
<Spacer />
<div
class={Decimal.gt(energyConsumption.value, energy.value) ? "unaffordable" : ""}
>
Energy Consumption: {formatWhole(energyConsumption.value)} /{" "}
{formatWhole(energy.value)}
<br />
Tick Rate: {format(tickRate.value)} TPS
</div>
</>
))
}; };
}); });
export default factory; export default factory;

View file

@ -36,6 +36,7 @@ import trees from "./trees";
import "./styles/management.css"; import "./styles/management.css";
import { Resource } from "features/resources/resource"; import { Resource } from "features/resources/resource";
import { isArray } from "@vue/shared"; import { isArray } from "@vue/shared";
import { createTab } from "features/tabs/tab";
const id = "management"; const id = "management";
const day = 12; const day = 12;

View file

@ -416,7 +416,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
showIf( showIf(
Decimal.gte(oreDrill.amount.value, 1) && Decimal.gte(oreDrill.amount.value, 1) &&
(coalDrill.bought.value || (coalDrill.bought.value ||
main.days[7].opened.value || (main.days[7].opened.value as boolean) ||
Decimal.lt( Decimal.lt(
coal.computedCoalGain.value, coal.computedCoalGain.value,
Decimal.times(computedOreAmount.value, computedOreSpeed.value).times( Decimal.times(computedOreAmount.value, computedOreSpeed.value).times(

View file

@ -1,10 +1,35 @@
.factory-container { .factory-tabs {
width: 650px; position: absolute !important;
height: 500px; top: 0;
position: relative; bottom: -6px;
background-color: var(--raised-background); left: 0;
right: 0;
border: 0px solid var(--outline);
}
.factory-tabs > :nth-child(2) {
margin-top: 60px !important;
}
.energy-bar .overlayText {
display: inline-block;
padding: 5px 10px;
background: var(--raised-background);
border-radius: var(--border-radius); border-radius: var(--border-radius);
box-shadow: 0 2px 10px rgb(0 0 0 / 50%); box-shadow: 0 1px 5px black;
}
.factory-container {
width: auto;
top: 113px;
bottom: 0;
left: 0px;
right: 0px;
position: absolute;
background-color: var(--raised-background);
overflow: hidden; overflow: hidden;
} }
@ -75,6 +100,16 @@
align-content: flex-start; align-content: flex-start;
background: var(--raised-background); background: var(--raised-background);
} }
.comp-list::before {
content: "";
display: block;
position: absolute;
top: 140px;
height: 2px;
left: 10px;
right: 10px;
background-color: var(--foreground);
}
.comp-list > img { .comp-list > img {
display: block; display: block;
width: 50px; width: 50px;
@ -84,4 +119,4 @@
.comp-list > img.selected { .comp-list > img.selected {
transform: translate(-5px, -5px); transform: translate(-5px, -5px);
filter: drop-shadow(2px 2px 0 var(--foreground)) drop-shadow(5px 5px 5px #0007); filter: drop-shadow(2px 2px 0 var(--foreground)) drop-shadow(5px 5px 5px #0007);
} }

View file

@ -363,7 +363,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
)), )),
minimizedDisplay: jsx(() => ( minimizedDisplay: jsx(() => (
<div> <div>
{name} - {format(toySum.value)} {"total toys"} {name} <span class="desc">{formatWhole(toySum.value)} total toys</span>
</div> </div>
)) ))
}; };