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:
parent
3c56c4772f
commit
5ab3afdd30
@ -197,7 +197,7 @@
|
|||||||
<key>scaleMode</key>
|
<key>scaleMode</key>
|
||||||
<enum type="ScaleMode">Smooth</enum>
|
<enum type="ScaleMode">Smooth</enum>
|
||||||
<key>extrude</key>
|
<key>extrude</key>
|
||||||
<uint>2</uint>
|
<uint>4</uint>
|
||||||
<key>trimThreshold</key>
|
<key>trimThreshold</key>
|
||||||
<uint>2</uint>
|
<uint>2</uint>
|
||||||
<key>trimMargin</key>
|
<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-tier2.png</key>
|
||||||
<key type="filename">sprites/blueprints/underground_belt_exit.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-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-rotater.png</key>
|
||||||
<key type="filename">sprites/blueprints/virtual_processor-shapecompare.png</key>
|
<key type="filename">sprites/blueprints/virtual_processor-shapecompare.png</key>
|
||||||
<key type="filename">sprites/blueprints/virtual_processor-stacker.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-tier2.png</key>
|
||||||
<key type="filename">sprites/buildings/underground_belt_exit.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-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-rotater.png</key>
|
||||||
<key type="filename">sprites/buildings/virtual_processor-shapecompare.png</key>
|
<key type="filename">sprites/buildings/virtual_processor-shapecompare.png</key>
|
||||||
<key type="filename">sprites/buildings/virtual_processor-stacker.png</key>
|
<key type="filename">sprites/buildings/virtual_processor-stacker.png</key>
|
||||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@ -10,7 +10,7 @@ import { GameRoot } from "../root";
|
|||||||
import { enumHubGoalRewards } from "../tutorial_goals";
|
import { enumHubGoalRewards } from "../tutorial_goals";
|
||||||
|
|
||||||
/** @enum {string} */
|
/** @enum {string} */
|
||||||
export const enumRotaterVariants = { ccw: "ccw", fl: "fl" };
|
export const enumRotaterVariants = { ccw: "ccw", rotate180: "rotate180" };
|
||||||
|
|
||||||
export class MetaRotaterBuilding extends MetaBuilding {
|
export class MetaRotaterBuilding extends MetaBuilding {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -36,8 +36,8 @@ export class MetaRotaterBuilding extends MetaBuilding {
|
|||||||
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotaterCCW);
|
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotaterCCW);
|
||||||
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
|
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
|
||||||
}
|
}
|
||||||
case enumRotaterVariants.fl: {
|
case enumRotaterVariants.rotate180: {
|
||||||
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotaterFL);
|
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotater180);
|
||||||
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
|
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)) {
|
if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_rotater_ccw)) {
|
||||||
variants.push(enumRotaterVariants.ccw);
|
variants.push(enumRotaterVariants.ccw);
|
||||||
}
|
}
|
||||||
if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_rotater_fl)) {
|
if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_rotater_180)) {
|
||||||
variants.push(enumRotaterVariants.fl);
|
variants.push(enumRotaterVariants.rotate180);
|
||||||
}
|
}
|
||||||
return variants;
|
return variants;
|
||||||
}
|
}
|
||||||
@ -111,8 +111,8 @@ export class MetaRotaterBuilding extends MetaBuilding {
|
|||||||
entity.components.ItemProcessor.type = enumItemProcessorTypes.rotaterCCW;
|
entity.components.ItemProcessor.type = enumItemProcessorTypes.rotaterCCW;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case enumRotaterVariants.fl: {
|
case enumRotaterVariants.rotate180: {
|
||||||
entity.components.ItemProcessor.type = enumItemProcessorTypes.rotaterFL;
|
entity.components.ItemProcessor.type = enumItemProcessorTypes.rotater180;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
import { types } from "../../savegame/serialization";
|
import { types } from "../../savegame/serialization";
|
||||||
import { BaseItem } from "../base_item";
|
import { BaseItem } from "../base_item";
|
||||||
import { Component } from "../component";
|
import { Component } from "../component";
|
||||||
import { typeItemSingleton } from "../item_resolver";
|
|
||||||
|
|
||||||
/** @enum {string} */
|
/** @enum {string} */
|
||||||
export const enumItemProcessorTypes = {
|
export const enumItemProcessorTypes = {
|
||||||
splitter: "splitter",
|
splitter: "splitter",
|
||||||
splitterWires: "splitterWires",
|
|
||||||
cutter: "cutter",
|
cutter: "cutter",
|
||||||
cutterQuad: "cutterQuad",
|
cutterQuad: "cutterQuad",
|
||||||
rotater: "rotater",
|
rotater: "rotater",
|
||||||
rotaterCCW: "rotaterCCW",
|
rotaterCCW: "rotaterCCW",
|
||||||
rotaterFL: "rotaterFL",
|
rotater180: "rotater180",
|
||||||
stacker: "stacker",
|
stacker: "stacker",
|
||||||
trash: "trash",
|
trash: "trash",
|
||||||
mixer: "mixer",
|
mixer: "mixer",
|
||||||
|
@ -396,9 +396,6 @@ export class HubGoals extends BasicSerializableObject {
|
|||||||
*/
|
*/
|
||||||
getProcessorBaseSpeed(processorType) {
|
getProcessorBaseSpeed(processorType) {
|
||||||
switch (processorType) {
|
switch (processorType) {
|
||||||
case enumItemProcessorTypes.splitterWires:
|
|
||||||
return globalConfig.wiresSpeedItemsPerSecond * 2;
|
|
||||||
|
|
||||||
case enumItemProcessorTypes.trash:
|
case enumItemProcessorTypes.trash:
|
||||||
case enumItemProcessorTypes.hub:
|
case enumItemProcessorTypes.hub:
|
||||||
return 1e30;
|
return 1e30;
|
||||||
@ -427,7 +424,7 @@ export class HubGoals extends BasicSerializableObject {
|
|||||||
case enumItemProcessorTypes.cutterQuad:
|
case enumItemProcessorTypes.cutterQuad:
|
||||||
case enumItemProcessorTypes.rotater:
|
case enumItemProcessorTypes.rotater:
|
||||||
case enumItemProcessorTypes.rotaterCCW:
|
case enumItemProcessorTypes.rotaterCCW:
|
||||||
case enumItemProcessorTypes.rotaterFL:
|
case enumItemProcessorTypes.rotater180:
|
||||||
case enumItemProcessorTypes.stacker: {
|
case enumItemProcessorTypes.stacker: {
|
||||||
assert(
|
assert(
|
||||||
globalConfig.buildingSpeeds[processorType],
|
globalConfig.buildingSpeeds[processorType],
|
||||||
|
@ -70,7 +70,7 @@ export function initMetaBuildingRegistry() {
|
|||||||
// Rotater
|
// Rotater
|
||||||
registerBuildingVariant(11, MetaRotaterBuilding);
|
registerBuildingVariant(11, MetaRotaterBuilding);
|
||||||
registerBuildingVariant(12, MetaRotaterBuilding, enumRotaterVariants.ccw);
|
registerBuildingVariant(12, MetaRotaterBuilding, enumRotaterVariants.ccw);
|
||||||
registerBuildingVariant(13, MetaRotaterBuilding, enumRotaterVariants.fl);
|
registerBuildingVariant(13, MetaRotaterBuilding, enumRotaterVariants.rotate180);
|
||||||
|
|
||||||
// Stacker
|
// Stacker
|
||||||
registerBuildingVariant(14, MetaStackerBuilding);
|
registerBuildingVariant(14, MetaStackerBuilding);
|
||||||
|
@ -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}
|
* @returns {ShapeDefinition}
|
||||||
*/
|
*/
|
||||||
cloneRotateFL() {
|
cloneRotate180() {
|
||||||
const newLayers = this.internalCloneLayers();
|
const newLayers = this.internalCloneLayers();
|
||||||
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
||||||
const quadrants = newLayers[layerIndex];
|
const quadrants = newLayers[layerIndex];
|
||||||
|
@ -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
|
* @param {ShapeDefinition} definition
|
||||||
* @returns {ShapeDefinition}
|
* @returns {ShapeDefinition}
|
||||||
*/
|
*/
|
||||||
shapeActionRotateFL(definition) {
|
shapeActionRotate180(definition) {
|
||||||
const key = "rotate-fl:" + definition.getHash();
|
const key = "rotate-fl:" + definition.getHash();
|
||||||
if (this.operationCache[key]) {
|
if (this.operationCache[key]) {
|
||||||
return /** @type {ShapeDefinition} */ (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(
|
return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle(
|
||||||
rotated
|
rotated
|
||||||
|
@ -16,9 +16,56 @@ import { ShapeItem } from "../items/shape_item";
|
|||||||
*/
|
*/
|
||||||
const MAX_QUEUED_CHARGES = 2;
|
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 {
|
export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
super(root, [ItemProcessorComponent]);
|
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() {
|
update() {
|
||||||
@ -238,310 +285,30 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
const items = processorComp.inputSlots;
|
const items = processorComp.inputSlots;
|
||||||
processorComp.inputSlots = [];
|
processorComp.inputSlots = [];
|
||||||
|
|
||||||
/** @type {Object.<string, { item: BaseItem, sourceSlot: number }>} */
|
/** @type {Object<string, BaseItem>} */
|
||||||
const itemsBySlot = {};
|
const itemsBySlot = {};
|
||||||
for (let i = 0; i < items.length; ++i) {
|
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 = [];
|
const outItems = [];
|
||||||
|
|
||||||
// Whether to track the production towards the analytics
|
/** @type {function(ProcessorImplementationPayload) : void} */
|
||||||
let trackProduction = true;
|
const handler = this.handlers[processorComp.type];
|
||||||
|
assert(handler, "No handler for processor type defined: " + processorComp.type);
|
||||||
|
|
||||||
// DO SOME MAGIC
|
// Call implementation
|
||||||
|
handler({
|
||||||
switch (processorComp.type) {
|
entity,
|
||||||
// SPLITTER
|
items,
|
||||||
case enumItemProcessorTypes.splitterWires:
|
itemsBySlot,
|
||||||
case enumItemProcessorTypes.splitter: {
|
outItems,
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Track produced items
|
// 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);
|
this.root.signals.itemProduced.dispatch(outItems[i].item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -559,4 +326,292 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
remainingTime: timeToProcess,
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ export const enumHubGoalRewards = {
|
|||||||
reward_tunnel: "reward_tunnel",
|
reward_tunnel: "reward_tunnel",
|
||||||
|
|
||||||
reward_rotater_ccw: "reward_rotater_ccw",
|
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_miner_chainable: "reward_miner_chainable",
|
||||||
reward_underground_belt_tier_2: "reward_underground_belt_tier_2",
|
reward_underground_belt_tier_2: "reward_underground_belt_tier_2",
|
||||||
reward_splitter_compact: "reward_splitter_compact",
|
reward_splitter_compact: "reward_splitter_compact",
|
||||||
|
@ -33,7 +33,7 @@ export const enumHubGoalRewardsToContentUnlocked = {
|
|||||||
[enumHubGoalRewards.reward_tunnel]: typed([[MetaUndergroundBeltBuilding, defaultBuildingVariant]]),
|
[enumHubGoalRewards.reward_tunnel]: typed([[MetaUndergroundBeltBuilding, defaultBuildingVariant]]),
|
||||||
|
|
||||||
[enumHubGoalRewards.reward_rotater_ccw]: typed([[MetaRotaterBuilding, enumRotaterVariants.ccw]]),
|
[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_miner_chainable]: typed([[MetaMinerBuilding, enumMinerVariants.chainable]]),
|
||||||
[enumHubGoalRewards.reward_underground_belt_tier_2]: typed([
|
[enumHubGoalRewards.reward_underground_belt_tier_2]: typed([
|
||||||
[MetaUndergroundBeltBuilding, enumUndergroundBeltVariants.tier2],
|
[MetaUndergroundBeltBuilding, enumUndergroundBeltVariants.tier2],
|
||||||
|
@ -2,5 +2,6 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"checkJs": true
|
"checkJs": true
|
||||||
}
|
},
|
||||||
|
"include": ["./**/*.js"]
|
||||||
}
|
}
|
||||||
|
@ -518,7 +518,7 @@ buildings:
|
|||||||
ccw:
|
ccw:
|
||||||
name: Rotate (CCW)
|
name: Rotate (CCW)
|
||||||
description: Rotates shapes counter-clockwise by 90 degrees.
|
description: Rotates shapes counter-clockwise by 90 degrees.
|
||||||
fl:
|
rotate180:
|
||||||
name: Rotate (180)
|
name: Rotate (180)
|
||||||
description: Rotates shapes by 180 degrees.
|
description: Rotates shapes by 180 degrees.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user