1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2024-10-27 20:34:29 +00:00

Move item processing into separate methods

This commit is contained in:
tobspr 2020-09-19 17:55:36 +02:00
parent 3c56c4772f
commit 5ab3afdd30
13 changed files with 795 additions and 742 deletions

View File

@ -197,7 +197,7 @@
<key>scaleMode</key>
<enum type="ScaleMode">Smooth</enum>
<key>extrude</key>
<uint>2</uint>
<uint>4</uint>
<key>trimThreshold</key>
<uint>2</uint>
<key>trimMargin</key>
@ -281,6 +281,7 @@
<key type="filename">sprites/blueprints/underground_belt_exit-tier2.png</key>
<key type="filename">sprites/blueprints/underground_belt_exit.png</key>
<key type="filename">sprites/blueprints/virtual_processor-analyzer.png</key>
<key type="filename">sprites/blueprints/virtual_processor-painter.png</key>
<key type="filename">sprites/blueprints/virtual_processor-rotater.png</key>
<key type="filename">sprites/blueprints/virtual_processor-shapecompare.png</key>
<key type="filename">sprites/blueprints/virtual_processor-stacker.png</key>
@ -309,6 +310,7 @@
<key type="filename">sprites/buildings/underground_belt_exit-tier2.png</key>
<key type="filename">sprites/buildings/underground_belt_exit.png</key>
<key type="filename">sprites/buildings/virtual_processor-analyzer.png</key>
<key type="filename">sprites/buildings/virtual_processor-painter.png</key>
<key type="filename">sprites/buildings/virtual_processor-rotater.png</key>
<key type="filename">sprites/buildings/virtual_processor-shapecompare.png</key>
<key type="filename">sprites/buildings/virtual_processor-stacker.png</key>

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -10,7 +10,7 @@ import { GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals";
/** @enum {string} */
export const enumRotaterVariants = { ccw: "ccw", fl: "fl" };
export const enumRotaterVariants = { ccw: "ccw", rotate180: "rotate180" };
export class MetaRotaterBuilding extends MetaBuilding {
constructor() {
@ -36,8 +36,8 @@ export class MetaRotaterBuilding extends MetaBuilding {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotaterCCW);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
}
case enumRotaterVariants.fl: {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotaterFL);
case enumRotaterVariants.rotate180: {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotater180);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
}
}
@ -52,8 +52,8 @@ export class MetaRotaterBuilding extends MetaBuilding {
if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_rotater_ccw)) {
variants.push(enumRotaterVariants.ccw);
}
if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_rotater_fl)) {
variants.push(enumRotaterVariants.fl);
if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_rotater_180)) {
variants.push(enumRotaterVariants.rotate180);
}
return variants;
}
@ -111,8 +111,8 @@ export class MetaRotaterBuilding extends MetaBuilding {
entity.components.ItemProcessor.type = enumItemProcessorTypes.rotaterCCW;
break;
}
case enumRotaterVariants.fl: {
entity.components.ItemProcessor.type = enumItemProcessorTypes.rotaterFL;
case enumRotaterVariants.rotate180: {
entity.components.ItemProcessor.type = enumItemProcessorTypes.rotater180;
break;
}
default:

View File

@ -1,17 +1,15 @@
import { types } from "../../savegame/serialization";
import { BaseItem } from "../base_item";
import { Component } from "../component";
import { typeItemSingleton } from "../item_resolver";
/** @enum {string} */
export const enumItemProcessorTypes = {
splitter: "splitter",
splitterWires: "splitterWires",
cutter: "cutter",
cutterQuad: "cutterQuad",
rotater: "rotater",
rotaterCCW: "rotaterCCW",
rotaterFL: "rotaterFL",
rotater180: "rotater180",
stacker: "stacker",
trash: "trash",
mixer: "mixer",

View File

@ -396,9 +396,6 @@ export class HubGoals extends BasicSerializableObject {
*/
getProcessorBaseSpeed(processorType) {
switch (processorType) {
case enumItemProcessorTypes.splitterWires:
return globalConfig.wiresSpeedItemsPerSecond * 2;
case enumItemProcessorTypes.trash:
case enumItemProcessorTypes.hub:
return 1e30;
@ -427,7 +424,7 @@ export class HubGoals extends BasicSerializableObject {
case enumItemProcessorTypes.cutterQuad:
case enumItemProcessorTypes.rotater:
case enumItemProcessorTypes.rotaterCCW:
case enumItemProcessorTypes.rotaterFL:
case enumItemProcessorTypes.rotater180:
case enumItemProcessorTypes.stacker: {
assert(
globalConfig.buildingSpeeds[processorType],

View File

@ -70,7 +70,7 @@ export function initMetaBuildingRegistry() {
// Rotater
registerBuildingVariant(11, MetaRotaterBuilding);
registerBuildingVariant(12, MetaRotaterBuilding, enumRotaterVariants.ccw);
registerBuildingVariant(13, MetaRotaterBuilding, enumRotaterVariants.fl);
registerBuildingVariant(13, MetaRotaterBuilding, enumRotaterVariants.rotate180);
// Stacker
registerBuildingVariant(14, MetaStackerBuilding);

View File

@ -487,10 +487,10 @@ export class ShapeDefinition extends BasicSerializableObject {
}
/**
* Returns a definition which was rotated 180 degrees (flipped)
* Returns a definition which was rotated 180 degrees
* @returns {ShapeDefinition}
*/
cloneRotateFL() {
cloneRotate180() {
const newLayers = this.internalCloneLayers();
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
const quadrants = newLayers[layerIndex];

View File

@ -161,17 +161,17 @@ export class ShapeDefinitionManager extends BasicSerializableObject {
}
/**
* Generates a definition for rotating a shape counter clockwise
* Generates a definition for rotating a shape FL
* @param {ShapeDefinition} definition
* @returns {ShapeDefinition}
*/
shapeActionRotateFL(definition) {
shapeActionRotate180(definition) {
const key = "rotate-fl:" + definition.getHash();
if (this.operationCache[key]) {
return /** @type {ShapeDefinition} */ (this.operationCache[key]);
}
const rotated = definition.cloneRotateFL();
const rotated = definition.cloneRotate180();
return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle(
rotated

View File

@ -16,9 +16,56 @@ import { ShapeItem } from "../items/shape_item";
*/
const MAX_QUEUED_CHARGES = 2;
/**
* Whole data for a produced item
*
* @typedef {{
* item: BaseItem,
* preferredSlot?: number,
* requiredSlot?: number,
* doNotTrack?: boolean
* }} ProducedItem
*/
/**
* Type of a processor implementation
* @typedef {{
* entity: Entity,
* items: Array<{ item: BaseItem, sourceSlot: number }>,
* itemsBySlot: Object<number, BaseItem>,
* outItems: Array<ProducedItem>
* }} ProcessorImplementationPayload
*/
export class ItemProcessorSystem extends GameSystemWithFilter {
constructor(root) {
super(root, [ItemProcessorComponent]);
/**
* @type {Object<enumItemProcessorTypes, function(ProcessorImplementationPayload) : string>}
*/
this.handlers = {
[enumItemProcessorTypes.splitter]: this.process_SPLITTER,
[enumItemProcessorTypes.cutter]: this.process_CUTTER,
[enumItemProcessorTypes.cutterQuad]: this.process_CUTTER_QUAD,
[enumItemProcessorTypes.rotater]: this.process_ROTATER,
[enumItemProcessorTypes.rotaterCCW]: this.process_ROTATER_CCW,
[enumItemProcessorTypes.rotater180]: this.process_ROTATER_180,
[enumItemProcessorTypes.stacker]: this.process_STACKER,
[enumItemProcessorTypes.trash]: this.process_TRASH,
[enumItemProcessorTypes.mixer]: this.process_MIXER,
[enumItemProcessorTypes.painter]: this.process_PAINTER,
[enumItemProcessorTypes.painterDouble]: this.process_PAINTER_DOUBLE,
[enumItemProcessorTypes.painterQuad]: this.process_PAINTER_QUAD,
[enumItemProcessorTypes.hub]: this.process_HUB,
[enumItemProcessorTypes.filter]: this.process_FILTER,
[enumItemProcessorTypes.reader]: this.process_READER,
};
// Bind all handlers
for (const key in this.handlers) {
this.handlers[key] = this.handlers[key].bind(this);
}
}
update() {
@ -238,310 +285,30 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
const items = processorComp.inputSlots;
processorComp.inputSlots = [];
/** @type {Object.<string, { item: BaseItem, sourceSlot: number }>} */
/** @type {Object<string, BaseItem>} */
const itemsBySlot = {};
for (let i = 0; i < items.length; ++i) {
itemsBySlot[items[i].sourceSlot] = items[i];
itemsBySlot[items[i].sourceSlot] = items[i].item;
}
/** @type {Array<{item: BaseItem, requiredSlot?: number, preferredSlot?: number}>} */
/** @type {Array<ProducedItem>} */
const outItems = [];
// Whether to track the production towards the analytics
let trackProduction = true;
/** @type {function(ProcessorImplementationPayload) : void} */
const handler = this.handlers[processorComp.type];
assert(handler, "No handler for processor type defined: " + processorComp.type);
// DO SOME MAGIC
switch (processorComp.type) {
// SPLITTER
case enumItemProcessorTypes.splitterWires:
case enumItemProcessorTypes.splitter: {
trackProduction = false;
const availableSlots = entity.components.ItemEjector.slots.length;
let nextSlot = processorComp.nextOutputSlot++ % availableSlots;
for (let i = 0; i < items.length; ++i) {
outItems.push({
item: items[i].item,
preferredSlot: (nextSlot + i) % availableSlots,
});
}
break;
}
// CUTTER
case enumItemProcessorTypes.cutter: {
const inputItem = /** @type {ShapeItem} */ (items[0].item);
assert(inputItem instanceof ShapeItem, "Input for cut is not a shape");
const inputDefinition = inputItem.definition;
const cutDefinitions = this.root.shapeDefinitionMgr.shapeActionCutHalf(inputDefinition);
for (let i = 0; i < cutDefinitions.length; ++i) {
const definition = cutDefinitions[i];
if (!definition.isEntirelyEmpty()) {
outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
requiredSlot: i,
});
}
}
break;
}
// CUTTER (Quad)
case enumItemProcessorTypes.cutterQuad: {
const inputItem = /** @type {ShapeItem} */ (items[0].item);
assert(inputItem instanceof ShapeItem, "Input for cut is not a shape");
const inputDefinition = inputItem.definition;
const cutDefinitions = this.root.shapeDefinitionMgr.shapeActionCutQuad(inputDefinition);
for (let i = 0; i < cutDefinitions.length; ++i) {
const definition = cutDefinitions[i];
if (!definition.isEntirelyEmpty()) {
outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
requiredSlot: i,
});
}
}
break;
}
// ROTATER
case enumItemProcessorTypes.rotater: {
const inputItem = /** @type {ShapeItem} */ (items[0].item);
assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape");
const inputDefinition = inputItem.definition;
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCW(inputDefinition);
outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition),
});
break;
}
// ROTATER (CCW)
case enumItemProcessorTypes.rotaterCCW: {
const inputItem = /** @type {ShapeItem} */ (items[0].item);
assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape");
const inputDefinition = inputItem.definition;
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCCW(inputDefinition);
outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition),
});
break;
}
// ROTATER (FL)
case enumItemProcessorTypes.rotaterFL: {
const inputItem = /** @type {ShapeItem} */ (items[0].item);
assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape");
const inputDefinition = inputItem.definition;
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateFL(inputDefinition);
outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition),
});
break;
}
// STACKER
case enumItemProcessorTypes.stacker: {
const lowerItem = /** @type {ShapeItem} */ (itemsBySlot[0].item);
const upperItem = /** @type {ShapeItem} */ (itemsBySlot[1].item);
assert(lowerItem instanceof ShapeItem, "Input for lower stack is not a shape");
assert(upperItem instanceof ShapeItem, "Input for upper stack is not a shape");
const stackedDefinition = this.root.shapeDefinitionMgr.shapeActionStack(
lowerItem.definition,
upperItem.definition
);
outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(stackedDefinition),
});
break;
}
// TRASH
case enumItemProcessorTypes.trash: {
// Well this one is easy .. simply do nothing with the item
break;
}
// MIXER
case enumItemProcessorTypes.mixer: {
// Find both colors and combine them
const item1 = /** @type {ColorItem} */ (items[0].item);
const item2 = /** @type {ColorItem} */ (items[1].item);
assert(item1 instanceof ColorItem, "Input for color mixer is not a color");
assert(item2 instanceof ColorItem, "Input for color mixer is not a color");
const color1 = item1.color;
const color2 = item2.color;
// Try finding mixer color, and if we can't mix it we simply return the same color
const mixedColor = enumColorMixingResults[color1][color2];
let resultColor = color1;
if (mixedColor) {
resultColor = mixedColor;
}
outItems.push({
item: COLOR_ITEM_SINGLETONS[resultColor],
});
break;
}
// PAINTER
case enumItemProcessorTypes.painter: {
const shapeItem = /** @type {ShapeItem} */ (itemsBySlot[0].item);
const colorItem = /** @type {ColorItem} */ (itemsBySlot[1].item);
const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith(
shapeItem.definition,
colorItem.color
);
outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition),
});
break;
}
// PAINTER (DOUBLE)
case enumItemProcessorTypes.painterDouble: {
const shapeItem1 = /** @type {ShapeItem} */ (itemsBySlot[0].item);
const shapeItem2 = /** @type {ShapeItem} */ (itemsBySlot[1].item);
const colorItem = /** @type {ColorItem} */ (itemsBySlot[2].item);
assert(shapeItem1 instanceof ShapeItem, "Input for painter is not a shape");
assert(shapeItem2 instanceof ShapeItem, "Input for painter is not a shape");
assert(colorItem instanceof ColorItem, "Input for painter is not a color");
const colorizedDefinition1 = this.root.shapeDefinitionMgr.shapeActionPaintWith(
shapeItem1.definition,
colorItem.color
);
const colorizedDefinition2 = this.root.shapeDefinitionMgr.shapeActionPaintWith(
shapeItem2.definition,
colorItem.color
);
outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition1),
});
outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition2),
});
break;
}
// PAINTER (QUAD)
case enumItemProcessorTypes.painterQuad: {
const shapeItem = /** @type {ShapeItem} */ (itemsBySlot[0].item);
assert(shapeItem instanceof ShapeItem, "Input for painter is not a shape");
/** @type {Array<enumColors>} */
const colors = [null, null, null, null];
for (let i = 0; i < 4; ++i) {
if (itemsBySlot[i + 1]) {
colors[i] = /** @type {ColorItem} */ (itemsBySlot[i + 1].item).color;
}
}
const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith4Colors(
shapeItem.definition,
/** @type {[string, string, string, string]} */ (colors)
);
outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition),
});
break;
}
// FILTER
case enumItemProcessorTypes.filter: {
// TODO
trackProduction = false;
const item = itemsBySlot[0].item;
const network = entity.components.WiredPins.slots[0].linkedNetwork;
if (!network || !network.currentValue) {
outItems.push({
item,
requiredSlot: 1,
});
break;
}
const value = network.currentValue;
if (value.equals(BOOL_TRUE_SINGLETON) || value.equals(item)) {
outItems.push({
item,
requiredSlot: 0,
});
} else {
outItems.push({
item,
requiredSlot: 1,
});
}
break;
}
// READER
case enumItemProcessorTypes.reader: {
// Pass through the item
const item = itemsBySlot[0].item;
outItems.push({ item });
// Track the item
const readerComp = entity.components.BeltReader;
readerComp.lastItemTimes.push(this.root.time.now());
readerComp.lastItem = item;
break;
}
// HUB
case enumItemProcessorTypes.hub: {
trackProduction = false;
const hubComponent = entity.components.Hub;
assert(hubComponent, "Hub item processor has no hub component");
for (let i = 0; i < items.length; ++i) {
const item = /** @type {ShapeItem} */ (items[i].item);
this.root.hubGoals.handleDefinitionDelivered(item.definition);
}
break;
}
default:
assertAlways(false, "Unkown item processor type: " + processorComp.type);
}
// Call implementation
handler({
entity,
items,
itemsBySlot,
outItems,
});
// Track produced items
if (trackProduction) {
for (let i = 0; i < outItems.length; ++i) {
for (let i = 0; i < outItems.length; ++i) {
if (!outItems[i].doNotTrack) {
this.root.signals.itemProduced.dispatch(outItems[i].item);
}
}
@ -559,4 +326,292 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
remainingTime: timeToProcess,
});
}
/**
* @param {ProcessorImplementationPayload} payload
*/
process_SPLITTER(payload) {
// trackProduction = false;
const availableSlots = payload.entity.components.ItemEjector.slots.length;
const processorComp = payload.entity.components.ItemProcessor;
const nextSlot = processorComp.nextOutputSlot++ % availableSlots;
for (let i = 0; i < payload.items.length; ++i) {
payload.outItems.push({
item: payload.items[i].item,
preferredSlot: (nextSlot + i) % availableSlots,
doNotTrack: true,
});
}
return true;
}
/**
* @param {ProcessorImplementationPayload} payload
*/
process_CUTTER(payload) {
const inputItem = /** @type {ShapeItem} */ (payload.items[0].item);
assert(inputItem instanceof ShapeItem, "Input for cut is not a shape");
const inputDefinition = inputItem.definition;
const cutDefinitions = this.root.shapeDefinitionMgr.shapeActionCutHalf(inputDefinition);
for (let i = 0; i < cutDefinitions.length; ++i) {
const definition = cutDefinitions[i];
if (!definition.isEntirelyEmpty()) {
payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
requiredSlot: i,
});
}
}
}
/**
* @param {ProcessorImplementationPayload} payload
*/
process_CUTTER_QUAD(payload) {
const inputItem = /** @type {ShapeItem} */ (payload.items[0].item);
assert(inputItem instanceof ShapeItem, "Input for cut is not a shape");
const inputDefinition = inputItem.definition;
const cutDefinitions = this.root.shapeDefinitionMgr.shapeActionCutQuad(inputDefinition);
for (let i = 0; i < cutDefinitions.length; ++i) {
const definition = cutDefinitions[i];
if (!definition.isEntirelyEmpty()) {
payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
requiredSlot: i,
});
}
}
}
/**
* @param {ProcessorImplementationPayload} payload
*/
process_ROTATER(payload) {
const inputItem = /** @type {ShapeItem} */ (payload.items[0].item);
assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape");
const inputDefinition = inputItem.definition;
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCW(inputDefinition);
payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition),
});
}
/**
* @param {ProcessorImplementationPayload} payload
*/
process_ROTATER_CCW(payload) {
const inputItem = /** @type {ShapeItem} */ (payload.items[0].item);
assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape");
const inputDefinition = inputItem.definition;
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCCW(inputDefinition);
payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition),
});
}
/**
* @param {ProcessorImplementationPayload} payload
*/
process_ROTATER_180(payload) {
const inputItem = /** @type {ShapeItem} */ (payload.items[0].item);
assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape");
const inputDefinition = inputItem.definition;
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotate180(inputDefinition);
payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition),
});
}
/**
* @param {ProcessorImplementationPayload} payload
*/
process_STACKER(payload) {
const lowerItem = /** @type {ShapeItem} */ (payload.itemsBySlot[0]);
const upperItem = /** @type {ShapeItem} */ (payload.itemsBySlot[1]);
assert(lowerItem instanceof ShapeItem, "Input for lower stack is not a shape");
assert(upperItem instanceof ShapeItem, "Input for upper stack is not a shape");
const stackedDefinition = this.root.shapeDefinitionMgr.shapeActionStack(
lowerItem.definition,
upperItem.definition
);
payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(stackedDefinition),
});
}
/**
* @param {ProcessorImplementationPayload} payload
*/
process_TRASH(payload) {
// Do nothing ..
}
/**
* @param {ProcessorImplementationPayload} payload
*/
process_MIXER(payload) {
// Find both colors and combine them
const item1 = /** @type {ColorItem} */ (payload.items[0].item);
const item2 = /** @type {ColorItem} */ (payload.items[1].item);
assert(item1 instanceof ColorItem, "Input for color mixer is not a color");
assert(item2 instanceof ColorItem, "Input for color mixer is not a color");
const color1 = item1.color;
const color2 = item2.color;
// Try finding mixer color, and if we can't mix it we simply return the same color
const mixedColor = enumColorMixingResults[color1][color2];
let resultColor = color1;
if (mixedColor) {
resultColor = mixedColor;
}
payload.outItems.push({
item: COLOR_ITEM_SINGLETONS[resultColor],
});
}
/**
* @param {ProcessorImplementationPayload} payload
*/
process_PAINTER(payload) {
const shapeItem = /** @type {ShapeItem} */ (payload.itemsBySlot[0]);
const colorItem = /** @type {ColorItem} */ (payload.itemsBySlot[1]);
const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith(
shapeItem.definition,
colorItem.color
);
payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition),
});
}
/**
* @param {ProcessorImplementationPayload} payload
*/
process_PAINTER_DOUBLE(payload) {
const shapeItem1 = /** @type {ShapeItem} */ (payload.itemsBySlot[0]);
const shapeItem2 = /** @type {ShapeItem} */ (payload.itemsBySlot[1]);
const colorItem = /** @type {ColorItem} */ (payload.itemsBySlot[2]);
assert(shapeItem1 instanceof ShapeItem, "Input for painter is not a shape");
assert(shapeItem2 instanceof ShapeItem, "Input for painter is not a shape");
assert(colorItem instanceof ColorItem, "Input for painter is not a color");
const colorizedDefinition1 = this.root.shapeDefinitionMgr.shapeActionPaintWith(
shapeItem1.definition,
colorItem.color
);
const colorizedDefinition2 = this.root.shapeDefinitionMgr.shapeActionPaintWith(
shapeItem2.definition,
colorItem.color
);
payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition1),
});
payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition2),
});
}
/**
* @param {ProcessorImplementationPayload} payload
*/
process_PAINTER_QUAD(payload) {
const shapeItem = /** @type {ShapeItem} */ (payload.itemsBySlot[0]);
assert(shapeItem instanceof ShapeItem, "Input for painter is not a shape");
/** @type {Array<enumColors>} */
const colors = [null, null, null, null];
for (let i = 0; i < 4; ++i) {
if (payload.itemsBySlot[i + 1]) {
colors[i] = /** @type {ColorItem} */ (payload.itemsBySlot[i + 1]).color;
}
}
const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith4Colors(
shapeItem.definition,
/** @type {[string, string, string, string]} */ (colors)
);
payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition),
});
}
/**
* @param {ProcessorImplementationPayload} payload
*/
process_FILTER(payload) {
const item = payload.itemsBySlot[0];
const network = payload.entity.components.WiredPins.slots[0].linkedNetwork;
if (!network || !network.currentValue) {
payload.outItems.push({
item,
requiredSlot: 1,
doNotTrack: true,
});
return;
}
const value = network.currentValue;
if (value.equals(BOOL_TRUE_SINGLETON) || value.equals(item)) {
payload.outItems.push({
item,
requiredSlot: 0,
doNotTrack: true,
});
} else {
payload.outItems.push({
item,
requiredSlot: 1,
doNotTrack: true,
});
}
}
/**
* @param {ProcessorImplementationPayload} payload
*/
process_READER(payload) {
// Pass through the item
const item = payload.itemsBySlot[0];
payload.outItems.push({
item,
doNotTrack: true,
});
// Track the item
const readerComp = payload.entity.components.BeltReader;
readerComp.lastItemTimes.push(this.root.time.now());
readerComp.lastItem = item;
}
/**
* @param {ProcessorImplementationPayload} payload
*/
process_HUB(payload) {
const hubComponent = payload.entity.components.Hub;
assert(hubComponent, "Hub item processor has no hub component");
for (let i = 0; i < payload.items.length; ++i) {
const item = /** @type {ShapeItem} */ (payload.items[i].item);
this.root.hubGoals.handleDefinitionDelivered(item.definition);
}
}
}

View File

@ -15,7 +15,7 @@ export const enumHubGoalRewards = {
reward_tunnel: "reward_tunnel",
reward_rotater_ccw: "reward_rotater_ccw",
reward_rotater_fl: "reward_rotater_fl",
reward_rotater_180: "reward_rotater_fl",
reward_miner_chainable: "reward_miner_chainable",
reward_underground_belt_tier_2: "reward_underground_belt_tier_2",
reward_splitter_compact: "reward_splitter_compact",

View File

@ -33,7 +33,7 @@ export const enumHubGoalRewardsToContentUnlocked = {
[enumHubGoalRewards.reward_tunnel]: typed([[MetaUndergroundBeltBuilding, defaultBuildingVariant]]),
[enumHubGoalRewards.reward_rotater_ccw]: typed([[MetaRotaterBuilding, enumRotaterVariants.ccw]]),
[enumHubGoalRewards.reward_rotater_fl]: typed([[MetaRotaterBuilding, enumRotaterVariants.fl]]),
[enumHubGoalRewards.reward_rotater_180]: typed([[MetaRotaterBuilding, enumRotaterVariants.rotate180]]),
[enumHubGoalRewards.reward_miner_chainable]: typed([[MetaMinerBuilding, enumMinerVariants.chainable]]),
[enumHubGoalRewards.reward_underground_belt_tier_2]: typed([
[MetaUndergroundBeltBuilding, enumUndergroundBeltVariants.tier2],

View File

@ -2,5 +2,6 @@
"compilerOptions": {
"target": "es6",
"checkJs": true
}
},
"include": ["./**/*.js"]
}

View File

@ -518,7 +518,7 @@ buildings:
ccw:
name: Rotate (CCW)
description: Rotates shapes counter-clockwise by 90 degrees.
fl:
rotate180:
name: Rotate (180)
description: Rotates shapes by 180 degrees.