Merge branch 'day-20-factory' of https://github.com/thepaperpilot/Advent-Incremental into day-20-factory

This commit is contained in:
ducdat0507 2022-12-21 13:40:58 +07:00
commit 67b093a7b0
2 changed files with 108 additions and 52 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -1,20 +1,21 @@
import { jsx } from "features/feature";
import { createLayer } from "game/layers";
import { Application } from "@pixi/app"; import { Application } from "@pixi/app";
import { Sprite } from "@pixi/sprite";
import { Graphics } from "@pixi/graphics";
import { Assets } from "@pixi/assets"; import { Assets } from "@pixi/assets";
import Factory from "./Factory.vue"; import { Container } from "@pixi/display";
import conveyor from "./factory-components/conveyor.png"; import { Graphics } from "@pixi/graphics";
import cursor from "./factory-components/cursor.jpg"; import { Sprite } from "@pixi/sprite";
import square from "./factory-components/square.jpg"; import { jsx } from "features/feature";
import { computed, ComputedRef, reactive, Ref, ref, watchEffect } from "vue"; import { globalBus } from "game/events";
import { Direction } from "util/common"; import { createLayer } from "game/layers";
import { Persistent, persistent, State } from "game/persistence"; import { Persistent, persistent, State } from "game/persistence";
import player from "game/player"; import player from "game/player";
import { Direction } from "util/common";
import { computed, ComputedRef, reactive, ref, watchEffect } from "vue";
import conveyor from "./factory-components/conveyor.png";
import cursor from "./factory-components/cursor.jpg";
import rotate from "./factory-components/rotate_rectangle.png";
import square from "./factory-components/square.jpg";
import Factory from "./Factory.vue";
import "./styles/factory.css"; import "./styles/factory.css";
import { globalBus } from "game/events";
import { Container } from "@pixi/display";
const id = "factory"; const id = "factory";
@ -31,7 +32,7 @@ enum FactoryDirections {
type FactoryDirection = FactoryDirections | Direction; type FactoryDirection = FactoryDirections | Direction;
function roundDownTo(num: number, multiple: number) { function roundDownTo(num: number, multiple: number) {
return Math.floor(num / multiple) * multiple; return Math.floor((num + multiple / 2) / multiple) * multiple;
} }
function getRelativeCoords(e: MouseEvent) { function getRelativeCoords(e: MouseEvent) {
const rect = (e.target as HTMLElement).getBoundingClientRect(); const rect = (e.target as HTMLElement).getBoundingClientRect();
@ -54,6 +55,13 @@ function iterateDirection(dir: FactoryDirection, func: (dir: FactoryDirection) =
func(dir); func(dir);
} }
} }
function rotateDir(dir: Direction, relative = Direction.Right) {
const directions = [Direction.Up, Direction.Right, Direction.Down, Direction.Left];
let index = directions.indexOf(dir);
index += directions.indexOf(relative);
index = index % directions.length;
return directions[index];
}
function directionToNum(dir: Direction) { function directionToNum(dir: Direction) {
switch (dir) { switch (dir) {
case Direction.Left: case Direction.Left:
@ -97,6 +105,16 @@ const factory = createLayer(id, () => {
production: {}, production: {},
productionStock: {} productionStock: {}
}, },
rotate: {
imageSrc: rotate,
name: "Rotate",
description: "Use this to rotate components.",
tick: 0,
consumption: {},
consumptionStock: {},
production: {},
productionStock: {}
},
conveyor: { conveyor: {
imageSrc: conveyor, imageSrc: conveyor,
name: "Conveyor", name: "Conveyor",
@ -105,7 +123,15 @@ const factory = createLayer(id, () => {
consumption: {}, consumption: {},
consumptionStock: {}, consumptionStock: {},
production: {}, production: {},
productionStock: {} productionStock: {},
ports: {
[Direction.Left]: {
type: "input"
},
[Direction.Right]: {
type: "output"
}
}
}, },
square: { square: {
imageSrc: square, imageSrc: square,
@ -121,14 +147,17 @@ const factory = createLayer(id, () => {
consumption: {}, consumption: {},
consumptionStock: {} consumptionStock: {}
} }
} as Record<"cursor" | "conveyor" | "square", FactoryComponentDeclaration>; } as const;
const RESOURCES = { const RESOURCES = {
square: square square: square
} as Record<string, string>; } as Record<string, string>;
type FactoryCompNames = keyof typeof FACTORY_COMPONENTS; type FactoryCompNames = keyof typeof FACTORY_COMPONENTS;
type BuildableCompName = Exclude<FactoryCompNames, "cursor">; type BuildableCompName = Exclude<FactoryCompNames, "cursor">;
interface FactoryComponentProducers extends Record<string, State> { interface FactoryComponentBase extends Record<string, State> {
direction: Direction;
}
interface FactoryComponentProducers extends FactoryComponentBase {
type: Exclude<BuildableCompName, "conveyor">; type: Exclude<BuildableCompName, "conveyor">;
consumptionStock: Record<string, number>; consumptionStock: Record<string, number>;
@ -136,11 +165,11 @@ const factory = createLayer(id, () => {
productionStock: Record<string, number>; productionStock: Record<string, number>;
ticksDone: number; ticksDone: number;
} }
interface FactoryComponentConveyor extends Record<string, State> { interface FactoryComponentConveyor extends FactoryComponentBase {
type: "conveyor"; type: "conveyor";
directionOut: Direction;
} }
type FactoryComponent = FactoryComponentConveyor | FactoryComponentProducers; type FactoryComponent = FactoryComponentBase &
(FactoryComponentConveyor | FactoryComponentProducers);
interface FactoryComponentDeclaration { interface FactoryComponentDeclaration {
tick: number; tick: number;
imageSrc: string; imageSrc: string;
@ -176,7 +205,6 @@ const factory = createLayer(id, () => {
} }
interface FactoryInternalProducer extends FactoryInternalBase { interface FactoryInternalProducer extends FactoryInternalBase {
type: Exclude<BuildableCompName, "conveyor">; type: Exclude<BuildableCompName, "conveyor">;
startingFrom: "up" | "right" | "down" | "left";
} }
type FactoryInternal = FactoryInternalConveyor | FactoryInternalProducer; type FactoryInternal = FactoryInternalConveyor | FactoryInternalProducer;
@ -246,8 +274,9 @@ const factory = createLayer(id, () => {
// load every sprite here so pixi doesn't complain about loading multiple times // load every sprite here so pixi doesn't complain about loading multiple times
await Assets.load(Object.values(FACTORY_COMPONENTS).map(x => x.imageSrc)); await Assets.load(Object.values(FACTORY_COMPONENTS).map(x => x.imageSrc));
if (Array.isArray(components.value)) components.value = {}; if (Array.isArray(components.value)) {
else components.value = {};
} else {
for (const id in components.value) { for (const id in components.value) {
const data = components.value[id]; const data = components.value[id];
console.log(id, data); console.log(id, data);
@ -256,8 +285,9 @@ const factory = createLayer(id, () => {
continue; continue;
} }
const [x, y] = id.split("x").map(p => +p); const [x, y] = id.split("x").map(p => +p);
addFactoryComp(x, y, data.type); addFactoryComp(x, y, data);
} }
}
loaded = true; loaded = true;
}); });
@ -289,8 +319,9 @@ const factory = createLayer(id, () => {
compData.packages = compData.packages.concat(compData.nextPackages); compData.packages = compData.packages.concat(compData.nextPackages);
compData.nextPackages = []; compData.nextPackages = [];
for (const [key, block] of [...compData.packages].entries()) { for (const [key, block] of [...compData.packages].entries()) {
const dirType = getDirection(data.directionOut); const inputDirection = rotateDir(data.direction, Direction.Left);
const dirAmt = directionToNum(data.directionOut); const dirType = getDirection(inputDirection);
const dirAmt = directionToNum(inputDirection);
if (dirType === "h") { if (dirType === "h") {
if (block.x <= block.lastX + dirAmt) { if (block.x <= block.lastX + dirAmt) {
const compBehind = compInternalData[x + dirAmt + "x" + y]; const compBehind = compInternalData[x + dirAmt + "x" + y];
@ -378,26 +409,22 @@ const factory = createLayer(id, () => {
//debugger; //debugger;
if ( if (
components.value[x + "x" + (y + 1)]?.type === "conveyor" && components.value[x + "x" + (y + 1)]?.type === "conveyor" &&
(compInternalData[x + "x" + (y + 1)] as FactoryInternalProducer) components.value[x + "x" + (y + 1)].direction === Direction.Up
.startingFrom === "up"
) { ) {
yInc = 1; yInc = 1;
} else if ( } else if (
components.value[x + "x" + (y - 1)]?.type === "conveyor" && components.value[x + "x" + (y - 1)]?.type === "conveyor" &&
(compInternalData[x + "x" + (y - 1)] as FactoryInternalProducer) components.value[x + "x" + (y + 1)].direction === Direction.Down
.startingFrom === "down"
) { ) {
yInc = -1; yInc = -1;
} else if ( } else if (
components.value[x + 1 + "x" + y]?.type === "conveyor" && components.value[x + 1 + "x" + y]?.type === "conveyor" &&
(compInternalData[x + 1 + "x" + y] as FactoryInternalProducer).startingFrom === components.value[x + "x" + (y + 1)].direction === Direction.Right
"right"
) { ) {
xInc = 1; xInc = 1;
} else if ( } else if (
components.value[x - 1 + "x" + y]?.type === "conveyor" && components.value[x - 1 + "x" + y]?.type === "conveyor" &&
(compInternalData[x - 1 + "x" + y] as FactoryInternalProducer).startingFrom === components.value[x + "x" + (y + 1)].direction === Direction.Left
"left"
) { ) {
xInc = -1; xInc = -1;
} }
@ -457,11 +484,15 @@ const factory = createLayer(id, () => {
taskIsRunning = false; taskIsRunning = false;
}); });
function addFactoryComp(x: number, y: number, type: BuildableCompName) { function addFactoryComp(
x: number,
y: number,
data: Partial<FactoryComponent> & { type: BuildableCompName }
) {
if (x < -factorySize.width || x >= factorySize.width) return; if (x < -factorySize.width || x >= factorySize.width) return;
if (y < -factorySize.height || y >= factorySize.height) return; if (y < -factorySize.height || y >= factorySize.height) return;
const factoryBaseData = FACTORY_COMPONENTS[type]; const factoryBaseData = FACTORY_COMPONENTS[data.type];
const sheet = Assets.get(factoryBaseData.imageSrc); const sheet = Assets.get(factoryBaseData.imageSrc);
const sprite = new Sprite(sheet); const sprite = new Sprite(sheet);
@ -469,32 +500,39 @@ const factory = createLayer(id, () => {
sprite.y = y * blockSize; sprite.y = y * blockSize;
sprite.width = blockSize; sprite.width = blockSize;
sprite.height = blockSize; sprite.height = blockSize;
sprite.anchor.x = 0.5;
sprite.anchor.y = 0.5;
sprite.rotation =
([Direction.Right, Direction.Down, Direction.Left, Direction.Up].indexOf(
data.direction ?? Direction.Right
) *
Math.PI) /
2;
console.log("!!", data, sprite);
components.value[x + "x" + y] = { components.value[x + "x" + y] = {
type,
ticksDone: 0, ticksDone: 0,
directionIn: type === "conveyor" ? Direction.Right : undefined, direction: Direction.Right,
directionOut: type === "conveyor" ? Direction.Left : undefined,
consumptionStock: consumptionStock:
type === "conveyor" data.type === "conveyor"
? undefined ? undefined
: Object.fromEntries( : Object.fromEntries(
Object.keys(factoryBaseData.consumptionStock).map(i => [i, 0]) Object.keys(factoryBaseData.consumptionStock).map(i => [i, 0])
), ),
productionStock: productionStock:
type === "conveyor" data.type === "conveyor"
? undefined ? undefined
: Object.fromEntries( : Object.fromEntries(
Object.keys(factoryBaseData.productionStock).map(i => [i, 0]) Object.keys(factoryBaseData.productionStock).map(i => [i, 0])
) ),
...data
} as FactoryComponent; } as FactoryComponent;
const isConveyor = type === "conveyor"; const isConveyor = data.type === "conveyor";
compInternalData[x + "x" + y] = { compInternalData[x + "x" + y] = {
type, type: data.type,
packages: isConveyor ? [] : undefined, packages: isConveyor ? [] : undefined,
nextPackages: isConveyor ? [] : undefined, nextPackages: isConveyor ? [] : undefined,
startingFrom: "left",
canProduce: computed(() => { canProduce: computed(() => {
if (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 FactoryComponentProducers; const compData = components.value[x + "x" + y] as FactoryComponentProducers;
@ -528,12 +566,16 @@ const factory = createLayer(id, () => {
spriteContainer.x = movingBlocks.x = calculatedX; spriteContainer.x = movingBlocks.x = calculatedX;
spriteContainer.y = movingBlocks.y = calculatedY; spriteContainer.y = movingBlocks.y = calculatedY;
if (isMouseHoverShown.value && compSelected.value !== "cursor") { if (
isMouseHoverShown.value &&
compSelected.value !== "cursor" &&
compSelected.value !== "rotate"
) {
const { tx, ty } = spriteContainer.localTransform; const { tx, ty } = spriteContainer.localTransform;
graphicContainer.beginFill(0x808080); graphicContainer.beginFill(0x808080);
graphicContainer.drawRect( graphicContainer.drawRect(
roundDownTo(mouseCoords.x - tx, blockSize) + tx, roundDownTo(mouseCoords.x - tx, blockSize) + tx - blockSize / 2,
roundDownTo(mouseCoords.y - ty, blockSize) + ty, roundDownTo(mouseCoords.y - ty, blockSize) + ty - blockSize / 2,
blockSize, blockSize,
blockSize blockSize
); );
@ -590,15 +632,29 @@ 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 !== "cursor") { if (compSelected.value === "rotate") {
if (components.value[x + "x" + y] === undefined) if (
addFactoryComp(x, y, compSelected.value); 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
)
};
compInternalData[x + "x" + y].sprite.rotation += Math.PI / 2;
}
} else if (compSelected.value !== "cursor") {
if (components.value[x + "x" + y] == null) {
addFactoryComp(x, y, { type: compSelected.value });
}
} }
} else if (e.button === 2) { } else if (e.button === 2) {
const data = compInternalData[x + "x" + y]; const data = compInternalData[x + "x" + y];
if (data === undefined) return; if (data === undefined) return;
delete components.value[x + "x" + y]; delete components.value[x + "x" + y];
delete compInternalData[x + "x" + y];
spriteContainer.removeChild(data.sprite); spriteContainer.removeChild(data.sprite);
} }
} }