1
0
Fork 0
mirror of https://github.com/thepaperpilot/Advent-Incremental.git synced 2025-03-21 21:51:45 +00:00

makes components move items

This commit is contained in:
circle-gon 2022-12-19 01:16:07 +00:00
parent 39bbbe0c25
commit 621d4c1beb

View file

@ -40,6 +40,40 @@ function getRelativeCoords(e: MouseEvent) {
y: e.clientY - rect.top
};
}
function iterateDirection(dir: FactoryDirection, func: (dir: FactoryDirection) => void) {
switch (dir) {
case FactoryDirections.None:
return;
case FactoryDirections.Any:
func(Direction.Up);
func(Direction.Right);
func(Direction.Down);
func(Direction.Left);
break;
default:
func(dir);
}
}
function directionToNum(dir: Direction) {
switch (dir) {
case Direction.Left:
case Direction.Up:
return -1;
case Direction.Right:
case Direction.Down:
return 1;
}
}
function getDirection(dir: Direction) {
switch (dir) {
case Direction.Left:
case Direction.Right:
return "h";
case Direction.Up:
case Direction.Down:
return "v";
}
}
const factorySize = {
width: 50,
@ -58,16 +92,12 @@ const factory = createLayer(id, () => {
name: "Cursor",
description: "Use this to move.",
tick: 0,
directionIn: FactoryDirections.None,
directionOut: FactoryDirections.None,
consumption: {},
consumptionStock: {},
production: {},
productionStock: {}
},
conveyor: {
directionIn: FactoryDirections.Any,
directionOut: FactoryDirections.Any,
imageSrc: conveyor,
name: "Conveyor",
description: "Moves 1 item per tick.",
@ -78,8 +108,6 @@ const factory = createLayer(id, () => {
productionStock: {}
},
square: {
directionIn: FactoryDirections.Any,
directionOut: FactoryDirections.None,
imageSrc: square,
name: "???",
description: "Produces 1 square every 1 tick.",
@ -97,20 +125,22 @@ const factory = createLayer(id, () => {
type FactoryCompNames = keyof typeof FACTORY_COMPONENTS;
type BuildableCompName = Exclude<FactoryCompNames, "cursor">;
interface FactoryComponent {
type: BuildableCompName;
ticksDone: number;
// current consumption stock
interface FactoryComponentProducers {
type: Exclude<BuildableCompName, "conveyor">;
consumptionStock: Record<string, number>;
// current production stock
productionStock: Record<string, number>;
ticksDone: number;
}
interface FactoryComponentConveyor {
type: "conveyor";
directionOut: Direction;
directionIn: Direction;
}
type FactoryComponent = FactoryComponentConveyor | FactoryComponentProducers;
interface FactoryComponentDeclaration {
tick: number;
directionIn: FactoryDirection;
directionOut: FactoryDirection;
imageSrc: string;
name: string;
description: string;
@ -130,10 +160,32 @@ const factory = createLayer(id, () => {
canProduce?: ComputedRef<boolean>;
}
interface FactoryInternal {
interface FactoryInternalBase {
sprite: Sprite;
canProduce: ComputedRef<boolean>;
}
interface FactoryInternalConveyor extends FactoryInternalBase {
type: "conveyor";
// packages are sorted by last first, first last
// [componentMade5SecondsAgo, componentMade4SecondsAgo...]
packages: Block[];
nextPackages: Block[];
}
interface FactoryInternalProducer extends FactoryInternalBase {
type: Exclude<BuildableCompName, "conveyor">;
}
type FactoryInternal = FactoryInternalConveyor | FactoryInternalProducer;
interface Block {
sprite: Sprite;
type: string;
// in block amts, not screen
x: number;
y: number;
lastX: number;
lastY: number;
}
// mouse positions
const mouseCoords = reactive({
@ -161,16 +213,32 @@ const factory = createLayer(id, () => {
backgroundAlpha: 0
});
const graphicContainer = new Graphics();
const spriteContainer = new Container();
let spriteContainer = new Container();
const movingBlocks = new Container();
graphicContainer.zIndex = 1;
app.stage.addChild(graphicContainer, spriteContainer, movingBlocks);
app.stage.sortableChildren = true;
globalBus.on("update", diff => {
globalBus.on("onLoad", async () => {
spriteContainer.destroy({
children: true
});
spriteContainer = new Container();
app.stage.addChild(spriteContainer);
for (const y of components.value.keys()) {
for (const x of components.value[y].keys()) {
const data = components.value[y][x];
if (data === null) continue;
await addFactoryComp(x, y, data.type);
}
}
});
globalBus.on("update", async diff => {
// will change soon:tm:
const tick = diff;
// make them produce
for (const y of components.value.keys()) {
for (const x of components.value[y].keys()) {
const data = components.value[y][x];
@ -178,53 +246,185 @@ const factory = createLayer(id, () => {
//console.log(compData, data)
if (data === null || compData === null) continue;
const factoryData = FACTORY_COMPONENTS[data.type];
if (data.ticksDone >= factoryData.tick) {
if (!compData.canProduce.value) continue;
const cyclesDone = Math.floor(data.ticksDone / factoryData.tick);
console.log("produce", data.ticksDone, factoryData.tick);
factoryData.onProduce?.(cyclesDone);
for (const [key, val] of Object.entries(factoryData.consumption)) {
data.consumptionStock[key] -= val;
if (data.type === "conveyor") {
if (compData.type !== "conveyor") throw new TypeError("this should not happen");
// conveyor part
// use a copy
for (const [key, block] of [...compData.packages].entries()) {
const dirType = getDirection(data.directionOut);
const dirAmt = directionToNum(data.directionOut);
if (dirType === "h") {
if (block.x <= block.lastX + dirAmt) {
// hit border
if (
(dirAmt === -1 && x === 0) ||
(dirAmt === 1 && x === components.value[y].length - 1)
)
continue;
const compBehind = compInternalData[y][x + dirAmt];
const storedComp = components.value[y][x + dirAmt];
// empty spot
if (compBehind === null) continue;
if (compBehind.type === "conveyor") {
const val = storedComp as FactoryComponentConveyor;
if (
!(
data.directionOut === Direction.Left &&
val.directionIn === Direction.Right
) &&
!(
data.directionOut === Direction.Right &&
val.directionIn === Direction.Left
)
) {
// component next does not accept this
continue;
}
// push it to the next conveyor, kill it from the
// curent conveyor
compBehind.nextPackages.push(block);
compData.packages.splice(key, 1);
} else {
// send it to the factory
// destory its sprite and data
(storedComp as FactoryComponentProducers).consumptionStock[
block.type
]++;
block.sprite.destroy();
movingBlocks.removeChild(block.sprite);
compData.packages.splice(key, 1);
}
} else {
block.x += tick * dirAmt;
block.sprite.x = block.x * blockSize;
}
} else {
if (block.y <= block.lastY + dirAmt) {
// hit border
if (
(dirAmt === -1 && y === 0) ||
(dirAmt === 1 && y === components.value.length - 1)
)
continue;
const compBehind = compInternalData[y + dirAmt][x];
const storedComp = components.value[y + dirAmt][x];
// empty spot
if (compBehind === null) continue;
if (compBehind.type === "conveyor") {
const val = storedComp as FactoryComponentConveyor;
if (
!(
data.directionOut === Direction.Up &&
val.directionIn === Direction.Down
) &&
!(
data.directionOut === Direction.Down &&
val.directionIn === Direction.Up
)
) {
// component next does not accept this
continue;
}
// push it to the next conveyor, kill it from the
// curent conveyor
compBehind.nextPackages.push(block);
compData.packages.splice(key, 1);
} else {
// send it to the factory
// destory its sprite and data
const factoryData = storedComp as FactoryComponentProducers;
factoryData.consumptionStock[block.type]++;
block.sprite.destroy();
movingBlocks.removeChild(block.sprite);
compData.packages.splice(key, 1);
}
} else {
block.y += tick * dirAmt;
block.sprite.y = block.y * blockSize;
}
}
}
for (const [key, val] of Object.entries(factoryData.production)) {
data.productionStock[key] -= val;
}
data.ticksDone -= cyclesDone * factoryData.tick;
} else {
data.ticksDone += tick;
// factory part
// PRODUCTION
if (data.ticksDone >= factoryData.tick) {
if (!compData.canProduce.value) continue;
const cyclesDone = Math.floor(data.ticksDone / factoryData.tick);
factoryData.onProduce?.(cyclesDone);
for (const [key, val] of Object.entries(factoryData.consumption)) {
data.consumptionStock[key] -= val;
}
for (const [key, val] of Object.entries(factoryData.production)) {
data.productionStock[key] -= val;
}
data.ticksDone -= cyclesDone * factoryData.tick;
} else {
data.ticksDone += tick;
}
// now look at each component direction and see if it accepts items coming in
// components are 1x1 so simple math for now
if (
y < components.value.length - 1 &&
components.value[y + 1][x]?.type === "conveyor"
) {
const val = components.value[y + 1][x] as FactoryComponentConveyor;
// todo: give this a predefined order
}
}
}
}
});
/*async function changeFactoryComponent(y: number, x: number) {
const comp = componentData.value[y][x];
if (comp === null) return;
const data = FACTORY_COMPONENTS[comp.type];
const sprite = await positionSprite(
FACTORY_COMPONENTS[comp.type].imageSrc,
y * blockHeight.value,
x * blockWidth.value,
blockWidth.value,
blockHeight.value
);
components[y][x] = {
sprite,
async function addFactoryComp(x: number, y: number, type: BuildableCompName) {
const factoryBaseData = FACTORY_COMPONENTS[compSelected.value];
const sheet = await Assets.load(factoryBaseData.imageSrc);
const sprite = new Sprite(sheet);
sprite.x = x * blockSize;
sprite.y = y * blockSize;
sprite.width = blockSize;
sprite.height = blockSize;
components.value[y][x] = {
type,
ticksDone: 0,
directionIn: type === "conveyor" ? Direction.Right : undefined,
directionOut: type === "conveyor" ? Direction.Left : undefined,
consumptionStock:
type === "conveyor" ? undefined : structuredClone(factoryBaseData.consumptionStock),
productionStock:
type === "conveyor" ? undefined : structuredClone(factoryBaseData.productionStock)
} as FactoryComponent;
const isConveyor = compSelected.value === "conveyor";
compInternalData[y][x] = {
type,
packages: isConveyor ? [] : undefined,
nextPackages: isConveyor ? [] : undefined,
canProduce: computed(() => {
if (!(data.canProduce?.value ?? true)) return false;
for (const [key, res] of Object.entries(comp.productionStock)) {
if (type === "conveyor") return true;
if (!(factoryBaseData.canProduce?.value ?? true)) return false;
// this should NEVER be null
const compData = components.value[y][x] as FactoryComponentProducers;
for (const [key, res] of Object.entries(compData.productionStock)) {
// if the current stock + production is more than you can handle
if (res + data.production[key] > data.productionStock[key]) return false;
if (
res + factoryBaseData.production[key] >
factoryBaseData.productionStock[key]
)
return false;
}
for (const [key, res] of Object.entries(comp.consumptionStock)) {
for (const [key, res] of Object.entries(compData.consumptionStock)) {
// make sure you have enough to produce
if (res < data.consumptionStock[key]) return false;
if (res < factoryBaseData.consumptionStock[key]) return false;
}
return true;
})
};
}),
sprite
} as FactoryInternal;
spriteContainer.addChild(sprite);
}*/
}
// draw graphics
function updateGraphics() {
@ -234,7 +434,7 @@ const factory = createLayer(id, () => {
spriteContainer.x = mapOffset.x * blockSize + app.view.width / 2;
spriteContainer.y = mapOffset.y * blockSize + app.view.height / 2;
if (isMouseHoverShown.value && compSelected.value === "cursor") {
if (isMouseHoverShown.value && compSelected.value !== "cursor") {
const { tx, ty } = spriteContainer.localTransform;
graphicContainer.beginFill(0x808080);
graphicContainer.drawRect(
@ -272,49 +472,23 @@ const factory = createLayer(id, () => {
async function onFactoryPointerUp(e: PointerEvent) {
// make sure they're not dragging and that
// they aren't trying to put down a cursor
if (!pointerDrag.value && compSelected.value !== "cursor") {
if (!pointerDrag.value) {
const { tx, ty } = spriteContainer.localTransform;
let { x, y } = getRelativeCoords(e);
x = roundDownTo(x - tx, blockSize) / blockSize;
y = roundDownTo(y - ty, blockSize) / blockSize;
const factoryBaseData = FACTORY_COMPONENTS[compSelected.value];
const sheet = await Assets.load(factoryBaseData.imageSrc);
const sprite = new Sprite(sheet);
console.log(x, y);
sprite.x = x * blockSize;
sprite.y = y * blockSize;
sprite.width = blockSize;
sprite.height = blockSize;
components.value[y][x] = {
type: compSelected.value,
ticksDone: 0,
consumptionStock: structuredClone(factoryBaseData.consumptionStock),
productionStock: structuredClone(factoryBaseData.productionStock)
};
compInternalData[y][x] = {
canProduce: computed(() => {
if (!(factoryBaseData.canProduce?.value ?? true)) return false;
// this should NEVER be null
const compData = components.value[y][x] as FactoryComponent;
for (const [key, res] of Object.entries(compData.productionStock)) {
// if the current stock + production is more than you can handle
if (
res + factoryBaseData.production[key] >
factoryBaseData.productionStock[key]
)
return false;
}
for (const [key, res] of Object.entries(compData.consumptionStock)) {
// make sure you have enough to produce
if (res < factoryBaseData.consumptionStock[key]) return false;
}
return true;
}),
sprite
};
spriteContainer.addChild(sprite);
if (e.button === 0) {
if (compSelected.value !== "cursor") {
await addFactoryComp(x, y, compSelected.value);
}
} else if (e.button === 2) {
const data = compInternalData[y][x];
if (data === null) return;
components.value[y][x] = null;
compInternalData[y][x] = null;
data.sprite.destroy();
spriteContainer.removeChild(data.sprite);
}
}
window.removeEventListener("pointerup", onFactoryPointerUp);
@ -356,6 +530,7 @@ const factory = createLayer(id, () => {
onPointerdown={onFactoryPointerDown}
onPointerenter={onFactoryMouseEnter}
onPointerleave={onFactoryMouseLeave}
onContextmenu={(e: MouseEvent) => e.preventDefault()}
/>
<div cellspacing="0" cellpadding="0" border="0" class="container">
<div style="line-height: 2.5em; min-height: 2.5em">