Get rid of item ejector / acceptor layers and new wires buildings for now

This commit is contained in:
tobspr 2020-08-10 21:24:58 +02:00
parent 89294c7072
commit 93975df4d5
83 changed files with 847 additions and 3189 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 61 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1003 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

After

Width:  |  Height:  |  Size: 200 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 KiB

After

Width:  |  Height:  |  Size: 479 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 913 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -1,5 +1,4 @@
$buildings: belt, cutter, miner, mixer, painter, rotater, splitter, stacker, trash, underground_belt,
energy_generator, wire, advanced_processor, wire_crossings;
$buildings: belt, cutter, miner, mixer, painter, rotater, splitter, stacker, trash, underground_belt;
@each $building in $buildings {
[data-icon="building_icons/#{$building}.png"] {

View File

@ -53,10 +53,7 @@ export const globalConfig = {
beltSpeedItemsPerSecond: 2,
minerSpeedItemsPerSecond: 0, // COMPUTED
beltItemSpacingByLayer: {
regular: 0.63,
wires: 0.4,
},
itemSpacingOnBelts: 0.63,
wiresSpeedItemsPerSecond: 6,

View File

@ -1,6 +1,5 @@
import { DrawParameters } from "../core/draw_parameters";
import { BasicSerializableObject } from "../savegame/serialization";
import { enumLayer } from "./root";
/** @enum {string} */
export const enumItemType = {
@ -13,15 +12,6 @@ export const enumItemType = {
genericEnergy: "genericEnergy",
};
/** @enum {enumLayer} */
export const enumItemTypeToLayer = {
[enumItemType.shape]: enumLayer.regular,
[enumItemType.color]: enumLayer.regular,
[enumItemType.positiveEnergy]: enumLayer.wires,
[enumItemType.negativeEnergy]: enumLayer.wires,
[enumItemType.genericEnergy]: enumLayer.wires,
};
/**
* Class for items on belts etc. Not an entity for performance reasons
*/

View File

@ -8,7 +8,7 @@ import { enumDirection, enumDirectionToVector, Vector, enumInvertedDirections }
import { BasicSerializableObject, types } from "../savegame/serialization";
import { BaseItem } from "./base_item";
import { Entity } from "./entity";
import { GameRoot } from "./root";
import { GameRoot, enumLayer } from "./root";
const logger = createLogger("belt_path");
@ -115,14 +115,7 @@ export class BeltPath extends BasicSerializableObject {
* @returns {boolean}
*/
canAcceptItem() {
return this.spacingToFirstItem >= this.getItemSpacing();
}
/**
* Returns the spacing between items
*/
getItemSpacing() {
return globalConfig.beltItemSpacingByLayer[this.layer];
return this.spacingToFirstItem >= globalConfig.itemSpacingOnBelts;
}
/**
@ -130,15 +123,15 @@ export class BeltPath extends BasicSerializableObject {
* @param {BaseItem} item
*/
tryAcceptItem(item) {
if (this.spacingToFirstItem >= this.getItemSpacing()) {
if (this.spacingToFirstItem >= globalConfig.itemSpacingOnBelts) {
// So, since we already need one tick to accept this item we will add this directly.
const beltProgressPerTick =
this.root.hubGoals.getBeltBaseSpeed(this.layer) *
this.root.hubGoals.getBeltBaseSpeed() *
this.root.dynamicTickrate.deltaSeconds *
this.getItemSpacing();
globalConfig.itemSpacingOnBelts;
// First, compute how much progress we can make *at max*
const maxProgress = Math.max(0, this.spacingToFirstItem - this.getItemSpacing());
const maxProgress = Math.max(0, this.spacingToFirstItem - globalConfig.itemSpacingOnBelts);
const initialProgress = Math.min(maxProgress, beltProgressPerTick);
this.items.unshift([this.spacingToFirstItem - initialProgress, item]);
@ -178,10 +171,9 @@ export class BeltPath extends BasicSerializableObject {
}
/**
* Recomputes the layer of the path and the target acceptor
* Recomputes cache variables once the path was changed
*/
onPathChanged() {
this.layer = this.entityPath[0].layer;
this.acceptorTarget = this.computeAcceptingEntityAndSlot();
}
@ -208,15 +200,13 @@ export class BeltPath extends BasicSerializableObject {
const ejectSlotTargetWsTile = ejectSlotWsTile.add(ejectSlotWsDirectionVector);
// Try to find the given acceptor component to take the item
// Since there can be cross layer dependencies, check on all layers
const targetEntities = this.root.map.getLayersContentsMultipleXY(
const targetEntity = this.root.map.getLayerContentXY(
ejectSlotTargetWsTile.x,
ejectSlotTargetWsTile.y
ejectSlotTargetWsTile.y,
enumLayer.regular
);
for (let i = 0; i < targetEntities.length; ++i) {
const targetEntity = targetEntities[i];
if (targetEntity) {
const targetStaticComp = targetEntity.components.StaticMapEntity;
const targetBeltComp = targetEntity.components.Belt;
@ -236,19 +226,18 @@ export class BeltPath extends BasicSerializableObject {
const targetAcceptorComp = targetEntity.components.ItemAcceptor;
if (!targetAcceptorComp) {
// Entity doesn't accept items
continue;
return;
}
const ejectingDirection = targetStaticComp.worldDirectionToLocal(ejectSlotWsDirection);
const matchingSlot = targetAcceptorComp.findMatchingSlot(
targetStaticComp.worldToLocalTile(ejectSlotTargetWsTile),
ejectingDirection,
lastEntity.layer
ejectingDirection
);
if (!matchingSlot) {
// No matching slot found
continue;
return;
}
return {
@ -406,7 +395,7 @@ export class BeltPath extends BasicSerializableObject {
this.onPathChanged();
// Extend the path length
const additionalLength = beltComp.getEffectiveLengthTiles(entity.layer);
const additionalLength = beltComp.getEffectiveLengthTiles();
this.totalLength += additionalLength;
DEBUG && logger.log(" Extended total length by", additionalLength, "to", this.totalLength);
@ -449,7 +438,7 @@ export class BeltPath extends BasicSerializableObject {
// All items on that belt are simply lost (for now)
const length = beltComp.getEffectiveLengthTiles(entity.layer);
const length = beltComp.getEffectiveLengthTiles();
// Extend the length of this path
this.totalLength += length;
@ -501,7 +490,7 @@ export class BeltPath extends BasicSerializableObject {
const beltComp = entity.components.Belt;
beltComp.assignedPath = null;
const entityLength = beltComp.getEffectiveLengthTiles(entity.layer);
const entityLength = beltComp.getEffectiveLengthTiles();
assert(this.entityPath.indexOf(entity) >= 0, "Entity not contained for split");
assert(this.entityPath.indexOf(entity) !== 0, "Entity is first");
assert(this.entityPath.indexOf(entity) !== this.entityPath.length - 1, "Entity is last");
@ -519,7 +508,7 @@ export class BeltPath extends BasicSerializableObject {
++firstPathEntityCount;
firstPathEndEntity = otherEntity;
firstPathLength += otherEntity.components.Belt.getEffectiveLengthTiles(otherEntity.layer);
firstPathLength += otherEntity.components.Belt.getEffectiveLengthTiles();
}
DEBUG &&
@ -663,7 +652,7 @@ export class BeltPath extends BasicSerializableObject {
// Ok, first remove the entity
const beltComp = entity.components.Belt;
const beltLength = beltComp.getEffectiveLengthTiles(entity.layer);
const beltLength = beltComp.getEffectiveLengthTiles();
DEBUG &&
logger.log(
@ -772,7 +761,7 @@ export class BeltPath extends BasicSerializableObject {
// Ok, first remove the entity
const beltComp = entity.components.Belt;
const beltLength = beltComp.getEffectiveLengthTiles(entity.layer);
const beltLength = beltComp.getEffectiveLengthTiles();
DEBUG &&
logger.log(
@ -912,7 +901,7 @@ export class BeltPath extends BasicSerializableObject {
beltComp.assignedPath = this;
// Update our length
const additionalLength = beltComp.getEffectiveLengthTiles(entity.layer);
const additionalLength = beltComp.getEffectiveLengthTiles();
this.totalLength += additionalLength;
}
@ -970,7 +959,7 @@ export class BeltPath extends BasicSerializableObject {
let length = 0;
for (let i = 0; i < this.entityPath.length; ++i) {
const entity = this.entityPath[i];
length += entity.components.Belt.getEffectiveLengthTiles(this.layer);
length += entity.components.Belt.getEffectiveLengthTiles();
}
return length;
}
@ -985,9 +974,9 @@ export class BeltPath extends BasicSerializableObject {
// Divide by item spacing on belts since we use throughput and not speed
let beltSpeed =
this.root.hubGoals.getBeltBaseSpeed(this.layer) *
this.root.hubGoals.getBeltBaseSpeed() *
this.root.dynamicTickrate.deltaSeconds *
this.getItemSpacing();
globalConfig.itemSpacingOnBelts;
if (G_IS_DEV && globalConfig.debug.instantBelts) {
beltSpeed *= 100;
@ -1014,7 +1003,7 @@ export class BeltPath extends BasicSerializableObject {
break;
}
minimumDistance = this.getItemSpacing();
minimumDistance = globalConfig.itemSpacingOnBelts;
}
// Check if we have an item which is ready to be emitted
@ -1060,14 +1049,14 @@ export class BeltPath extends BasicSerializableObject {
for (let i = 0; i < this.entityPath.length; ++i) {
const beltComp = this.entityPath[i].components.Belt;
const localLength = beltComp.getEffectiveLengthTiles(this.layer);
const localLength = beltComp.getEffectiveLengthTiles();
if (currentLength + localLength >= progress || i === this.entityPath.length - 1) {
// Min required here due to floating point issues
const localProgress = Math.min(1.0, progress - currentLength);
assert(localProgress >= 0.0, "Invalid local progress: " + localProgress);
const localSpace = beltComp.transformBeltToLocalSpace(localProgress, this.layer);
const localSpace = beltComp.transformBeltToLocalSpace(localProgress);
return this.entityPath[i].components.StaticMapEntity.localTileToWorld(localSpace);
}
currentLength += localLength;
@ -1085,11 +1074,6 @@ export class BeltPath extends BasicSerializableObject {
return;
}
if (this.entityPath[0].layer !== this.root.currentLayer) {
// Don't draw
return;
}
parameters.context.fillStyle = "#d79a25";
parameters.context.strokeStyle = "#d79a25";
parameters.context.beginPath();
@ -1171,7 +1155,7 @@ export class BeltPath extends BasicSerializableObject {
for (let i = 0; i < this.entityPath.length; ++i) {
const entity = this.entityPath[i];
const beltComp = entity.components.Belt;
const beltLength = beltComp.getEffectiveLengthTiles(this.layer);
const beltLength = beltComp.getEffectiveLengthTiles();
// Check if the current items are on the belt
while (trackPos + beltLength >= currentItemPos - 1e-51) {
@ -1182,7 +1166,7 @@ export class BeltPath extends BasicSerializableObject {
"invalid track pos: " + currentItemPos + " vs " + trackPos + " (l =" + beltLength + ")"
);
const localPos = beltComp.transformBeltToLocalSpace(currentItemPos - trackPos, this.layer);
const localPos = beltComp.transformBeltToLocalSpace(currentItemPos - trackPos);
const worldPos = staticComp.localTileToWorld(localPos).toWorldSpaceCenterOfTile();
const distanceAndItem = this.items[currentItemIndex];

View File

@ -1,108 +0,0 @@
import { formatItemsPerSecond } from "../../core/utils";
import { enumDirection, Vector } from "../../core/vector";
import { T } from "../../translations";
import { enumItemType } from "../base_item";
import { EnergyConsumerComponent } from "../components/energy_consumer";
import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { enumLayer, GameRoot } from "../root";
export class MetaAdvancedProcessorBuilding extends MetaBuilding {
constructor() {
super("advanced_processor");
}
getSilhouetteColor() {
return "#25d7b8";
}
getDimensions(variant) {
return new Vector(2, 2);
}
/**
* @param {GameRoot} root
* @param {string} variant
* @returns {Array<[string, string]>}
*/
getAdditionalStatistics(root, variant) {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.advancedProcessor);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
}
/**
* @param {GameRoot} root
*/
getIsUnlocked(root) {
// TODO
return true;
// return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_cutter_and_trash);
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(
new ItemProcessorComponent({
inputsPerCharge: 1,
processorType: enumItemProcessorTypes.advancedProcessor,
})
);
entity.addComponent(
new ItemEjectorComponent({
slots: [
{ pos: new Vector(1, 0), direction: enumDirection.right },
{ pos: new Vector(1, 0), direction: enumDirection.top, layer: enumLayer.wires },
],
})
);
entity.addComponent(
new EnergyConsumerComponent({
bufferSize: 3,
perCharge: 1,
batteryPosition: new Vector(0.63, 0.7),
acceptorSlotIndex: 1,
ejectorSlotIndex: 1,
})
);
entity.addComponent(
new WiredPinsComponent({
slots: [
{
pos: new Vector(0, 0),
direction: enumDirection.top,
type: enumPinSlotType.positiveEnergyAcceptor,
},
{
pos: new Vector(1, 0),
direction: enumDirection.top,
type: enumPinSlotType.negativeEnergyEjector,
},
],
})
);
entity.addComponent(
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 1),
directions: [enumDirection.left],
},
{
pos: new Vector(0, 0),
directions: [enumDirection.top],
filter: enumItemType.positiveEnergy,
layer: enumLayer.wires,
},
],
})
);
}
}

View File

@ -23,7 +23,7 @@ export class MetaBeltBaseBuilding extends MetaBuilding {
* @returns {Array<[string, string]>}
*/
getAdditionalStatistics(root, variant) {
const beltSpeed = root.hubGoals.getBeltBaseSpeed(enumLayer.regular);
const beltSpeed = root.hubGoals.getBeltBaseSpeed();
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(beltSpeed)]];
}
@ -82,7 +82,7 @@ export class MetaBeltBaseBuilding extends MetaBuilding {
const bottomDirection = enumAngleToDirection[(rotation + 180) % 360];
const leftDirection = enumAngleToDirection[(rotation + 270) % 360];
const { ejectors, acceptors } = root.logic.getEjectorsAndAcceptorsAtTile(tile, layer);
const { ejectors, acceptors } = root.logic.getEjectorsAndAcceptorsAtTile(tile);
let hasBottomEjector = false;
let hasRightEjector = false;

View File

@ -1,108 +0,0 @@
import { enumDirection, Vector } from "../../core/vector";
import { enumItemType } from "../base_item";
import { EnergyGeneratorComponent } from "../components/energy_generator";
import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { enumLayer, GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals";
export class MetaEnergyGenerator extends MetaBuilding {
constructor() {
super("energy_generator");
}
getSilhouetteColor() {
return "#c425d7";
}
/**
* @param {GameRoot} root
* @param {string} variant
* @returns {Array<[string, string]>}
*/
getAdditionalStatistics(root, variant) {
// TODO
return [];
}
getDimensions(variant) {
return new Vector(2, 2);
}
/**
* @param {GameRoot} root
*/
getIsUnlocked(root) {
return true;
// return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_cutter_and_trash);
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 1),
directions: [enumDirection.bottom],
filter: enumItemType.shape,
},
{
pos: new Vector(1, 1),
directions: [enumDirection.bottom],
filter: enumItemType.shape,
},
{
pos: new Vector(1, 0),
directions: [enumDirection.top],
layer: enumLayer.wires,
filter: enumItemType.negativeEnergy,
},
],
})
);
entity.addComponent(
new ItemEjectorComponent({
slots: [
{
pos: new Vector(0, 0),
direction: enumDirection.top,
layer: enumLayer.wires,
},
],
})
);
entity.addComponent(
new EnergyGeneratorComponent({
// Set by the energy generator system later
requiredKey: null,
wasteAcceptorSlotIndex: 2,
})
);
entity.addComponent(
new WiredPinsComponent({
slots: [
{
pos: new Vector(0, 0),
type: enumPinSlotType.positiveEnergyEjector,
direction: enumDirection.top,
},
{
pos: new Vector(1, 0),
type: enumPinSlotType.negativeEnergyAcceptor,
direction: enumDirection.top,
},
],
})
);
}
}

View File

@ -1,52 +0,0 @@
import { Loader } from "../../core/loader";
import { enumDirection } from "../../core/vector";
import { enumLayer } from "../root";
import { arrayBeltVariantToRotation, MetaBeltBaseBuilding } from "./belt_base";
export class MetaWireBaseBuilding extends MetaBeltBaseBuilding {
constructor() {
super("wire");
}
getSilhouetteColor() {
return "#c425d7";
}
getLayer() {
return enumLayer.wires;
}
getPreviewSprite(rotationVariant) {
switch (arrayBeltVariantToRotation[rotationVariant]) {
case enumDirection.top: {
return Loader.getSprite("sprites/buildings/wire_top.png");
}
case enumDirection.left: {
return Loader.getSprite("sprites/buildings/wire_left.png");
}
case enumDirection.right: {
return Loader.getSprite("sprites/buildings/wire_right.png");
}
default: {
assertAlways(false, "Invalid belt rotation variant");
}
}
}
getBlueprintSprite(rotationVariant) {
switch (arrayBeltVariantToRotation[rotationVariant]) {
case enumDirection.top: {
return Loader.getSprite("sprites/blueprints/wire_top.png");
}
case enumDirection.left: {
return Loader.getSprite("sprites/blueprints/wire_left.png");
}
case enumDirection.right: {
return Loader.getSprite("sprites/blueprints/wire_right.png");
}
default: {
assertAlways(false, "Invalid belt rotation variant");
}
}
}
}

View File

@ -1,119 +0,0 @@
import { enumDirection, Vector } from "../../core/vector";
import { enumItemType } from "../base_item";
import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
import { Entity } from "../entity";
import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
import { enumLayer, GameRoot } from "../root";
/** @enum {string} */
export const enumWireCrossingVariants = {
// Default = splitter
merger: "merger",
};
export class MetaWireCrossingsBuilding extends MetaBuilding {
constructor() {
super("wire_crossings");
}
getDimensions(variant) {
return new Vector(1, 1);
}
getSilhouetteColor() {
return "#c425d7";
}
getLayer() {
return enumLayer.wires;
}
/**
* @param {GameRoot} root
*/
getAvailableVariants(root) {
return [defaultBuildingVariant, enumWireCrossingVariants.merger];
}
/**
* @param {GameRoot} root
*/
getIsUnlocked(root) {
return true;
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(
new ItemAcceptorComponent({
slots: [], // set later
})
);
entity.addComponent(
new ItemProcessorComponent({
inputsPerCharge: 1,
processorType: enumItemProcessorTypes.splitterWires,
})
);
entity.addComponent(
new ItemEjectorComponent({
slots: [], // set later
})
);
}
/**
*
* @param {Entity} entity
* @param {number} rotationVariant
* @param {string} variant
*/
updateVariants(entity, rotationVariant, variant) {
switch (variant) {
case defaultBuildingVariant: {
entity.components.ItemAcceptor.setSlots([
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
layer: enumLayer.wires,
},
]);
entity.components.ItemEjector.setSlots([
{ pos: new Vector(0, 0), direction: enumDirection.top, layer: enumLayer.wires },
{ pos: new Vector(0, 0), direction: enumDirection.right, layer: enumLayer.wires },
]);
break;
}
case enumWireCrossingVariants.merger: {
entity.components.ItemAcceptor.setSlots([
{
pos: new Vector(0, 0),
directions: [enumDirection.top],
layer: enumLayer.wires,
},
{
pos: new Vector(0, 0),
directions: [enumDirection.right],
layer: enumLayer.wires,
},
]);
entity.components.ItemEjector.setSlots([
{ pos: new Vector(0, 0), direction: enumDirection.bottom, layer: enumLayer.wires },
]);
break;
}
default:
assertAlways(false, "Unknown painter variant: " + variant);
}
}
}

View File

@ -10,8 +10,6 @@ export const enumColors = {
white: "white",
uncolored: "uncolored",
black: "black",
};
/** @enum {string} */
@ -26,8 +24,6 @@ export const enumColorToShortcode = {
[enumColors.white]: "w",
[enumColors.uncolored]: "u",
[enumColors.black]: "0",
};
/** @enum {enumColors} */
@ -54,27 +50,9 @@ export const enumColorsToHexCode = {
// blue + green + red
[enumColors.white]: "#ffffff",
[enumColors.black]: "#31383a",
[enumColors.uncolored]: "#aaaaaa",
};
/** @enum {enumColors} */
export const enumInvertedColors = {
[enumColors.red]: enumColors.cyan,
[enumColors.green]: enumColors.purple,
[enumColors.blue]: enumColors.yellow,
[enumColors.yellow]: enumColors.blue,
[enumColors.purple]: enumColors.green,
[enumColors.cyan]: enumColors.red,
[enumColors.white]: enumColors.black,
[enumColors.black]: enumColors.white,
[enumColors.uncolored]: enumColors.uncolored,
};
const c = enumColors;
/** @enum {Object.<string, string>} */
export const enumColorMixingResults = {
@ -88,7 +66,6 @@ export const enumColorMixingResults = {
[c.cyan]: c.white,
[c.white]: c.white,
[c.black]: c.red,
},
// 0, 255, 0
@ -100,7 +77,6 @@ export const enumColorMixingResults = {
[c.cyan]: c.cyan,
[c.white]: c.white,
[c.black]: c.green,
},
// 0, 255, 0
@ -110,20 +86,17 @@ export const enumColorMixingResults = {
[c.cyan]: c.cyan,
[c.white]: c.white,
[c.black]: c.blue,
},
// 255, 255, 0
[c.yellow]: {
[c.purple]: c.white,
[c.cyan]: c.white,
[c.black]: c.yellow,
},
// 255, 0, 255
[c.purple]: {
[c.cyan]: c.white,
[c.black]: c.purple,
},
// 0, 255, 255
@ -140,24 +113,12 @@ export const enumColorMixingResults = {
[c.uncolored]: {
// auto
},
[c.black]: {
// auto
[c.white]: c.uncolored,
[c.cyan]: c.cyan,
[c.uncolored]: c.uncolored,
},
};
// Create same color lookups
for (const color in enumColors) {
enumColorMixingResults[color][color] = color;
// Anything with white is white again, except for black which creates gray
if (color !== enumColors.black) {
enumColorMixingResults[color][c.white] = c.white;
}
enumColorMixingResults[color][c.white] = c.white;
// Anything with uncolored is the same color
enumColorMixingResults[color][c.uncolored] = color;
}

View File

@ -10,9 +10,7 @@ import { UndergroundBeltComponent } from "./components/underground_belt";
import { UnremovableComponent } from "./components/unremovable";
import { HubComponent } from "./components/hub";
import { StorageComponent } from "./components/storage";
import { EnergyGeneratorComponent } from "./components/energy_generator";
import { WiredPinsComponent } from "./components/wired_pins";
import { EnergyConsumerComponent } from "./components/energy_consumer";
import { BeltUnderlaysComponent } from "./components/belt_underlays";
export function initComponentRegistry() {
@ -27,9 +25,7 @@ export function initComponentRegistry() {
gComponentRegistry.register(UnremovableComponent);
gComponentRegistry.register(HubComponent);
gComponentRegistry.register(StorageComponent);
gComponentRegistry.register(EnergyGeneratorComponent);
gComponentRegistry.register(WiredPinsComponent);
gComponentRegistry.register(EnergyConsumerComponent);
gComponentRegistry.register(BeltUnderlaysComponent);
// IMPORTANT ^^^^^ UPDATE ENTITY COMPONENT STORAGE AFTERWARDS

View File

@ -11,7 +11,6 @@ export const curvedBeltLength = /* Math.PI / 4 */ 0.78;
export const FAKE_BELT_ACCEPTOR_SLOT = {
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
layer: enumLayer.regular,
};
/** @type {Object<enumDirection, import("./item_ejector").ItemEjectorSlot>} */
@ -20,7 +19,6 @@ export const FAKE_BELT_EJECTOR_SLOT_BY_DIRECTION = {
pos: new Vector(0, 0),
direction: enumDirection.top,
item: null,
layer: enumLayer.regular,
progress: 0,
},
@ -28,7 +26,6 @@ export const FAKE_BELT_EJECTOR_SLOT_BY_DIRECTION = {
pos: new Vector(0, 0),
direction: enumDirection.right,
item: null,
layer: enumLayer.regular,
progress: 0,
},
@ -36,7 +33,6 @@ export const FAKE_BELT_EJECTOR_SLOT_BY_DIRECTION = {
pos: new Vector(0, 0),
direction: enumDirection.left,
item: null,
layer: enumLayer.regular,
progress: 0,
},
};
@ -79,14 +75,9 @@ export class BeltComponent extends Component {
/**
* Returns the effective length of this belt in tile space
* @param {enumLayer} layer
* @returns {number}
*/
getEffectiveLengthTiles(layer) {
assert(layer, "no layer given");
if (layer === enumLayer.wires) {
return 1.0;
}
getEffectiveLengthTiles() {
return this.direction === enumDirection.top ? 1.0 : curvedBeltLength;
}
@ -115,62 +106,28 @@ export class BeltComponent extends Component {
* Converts from belt space (0 = start of belt ... 1 = end of belt) to the local
* belt coordinates (-0.5|-0.5 to 0.5|0.5)
* @param {number} progress
* @param {enumLayer} layer
* @returns {Vector}
*/
transformBeltToLocalSpace(progress, layer) {
transformBeltToLocalSpace(progress) {
assert(progress >= 0.0, "Invalid progress ( < 0): " + progress);
switch (this.direction) {
case enumDirection.top:
assert(progress <= 1.02, "Invalid progress: " + progress);
return new Vector(0, 0.5 - progress);
switch (layer) {
case enumLayer.regular: {
switch (this.direction) {
case enumDirection.top:
assert(progress <= 1.02, "Invalid progress: " + progress);
return new Vector(0, 0.5 - progress);
case enumDirection.right: {
assert(progress <= curvedBeltLength + 0.02, "Invalid progress 2: " + progress);
const arcProgress = (progress / curvedBeltLength) * 0.5 * Math.PI;
return new Vector(
0.5 - 0.5 * Math.cos(arcProgress),
0.5 - 0.5 * Math.sin(arcProgress)
);
}
case enumDirection.left: {
assert(progress <= curvedBeltLength + 0.02, "Invalid progress 3: " + progress);
const arcProgress = (progress / curvedBeltLength) * 0.5 * Math.PI;
return new Vector(
-0.5 + 0.5 * Math.cos(arcProgress),
0.5 - 0.5 * Math.sin(arcProgress)
);
}
default:
assertAlways(false, "Invalid belt direction: " + this.direction);
return new Vector(0, 0);
}
case enumDirection.right: {
assert(progress <= curvedBeltLength + 0.02, "Invalid progress 2: " + progress);
const arcProgress = (progress / curvedBeltLength) * 0.5 * Math.PI;
return new Vector(0.5 - 0.5 * Math.cos(arcProgress), 0.5 - 0.5 * Math.sin(arcProgress));
}
case enumLayer.wires: {
const pow = 0.5;
switch (this.direction) {
case enumDirection.top:
assert(progress <= 1.02, "Invalid progress: " + progress);
return new Vector(0, 0.5 - progress);
case enumDirection.right: {
assert(progress <= 1.02, "Invalid progress 2: " + progress);
return progress > 0.5 ? new Vector(progress - 0.5, 0) : new Vector(0, 0.5 - progress);
}
case enumDirection.left: {
assert(progress <= 1.02, "Invalid progress 3: " + progress);
return progress > 0.5
? new Vector(-progress + 0.5, 0)
: new Vector(0, 0.5 - progress);
}
default:
assertAlways(false, "Invalid belt direction: " + this.direction);
return new Vector(0, 0);
}
case enumDirection.left: {
assert(progress <= curvedBeltLength + 0.02, "Invalid progress 3: " + progress);
const arcProgress = (progress / curvedBeltLength) * 0.5 * Math.PI;
return new Vector(-0.5 + 0.5 * Math.cos(arcProgress), 0.5 - 0.5 * Math.sin(arcProgress));
}
default:
assertAlways(false, "Invalid belt direction: " + this.direction);
return new Vector(0, 0);
}
}
}

View File

@ -1,133 +0,0 @@
import { Component } from "../component";
import { types } from "../../savegame/serialization";
import { Vector } from "../../core/vector";
import { BaseItem, enumItemTypeToLayer, enumItemType } from "../base_item";
export class EnergyConsumerComponent extends Component {
static getId() {
return "EnergyConsumer";
}
static getSchema() {
return {
bufferSize: types.float,
perCharge: types.float,
batteryPosition: types.vector,
energyType: types.enum(enumItemType),
wasteType: types.enum(enumItemType),
acceptorSlotIndex: types.uint,
ejectorSlotIndex: types.uint,
stored: types.float,
piledOutput: types.float,
};
}
duplicateWithoutContents() {
return new EnergyConsumerComponent({
bufferSize: this.bufferSize,
perCharge: this.perCharge,
batteryPosition: this.batteryPosition.copy(),
acceptorSlotIndex: this.acceptorSlotIndex,
ejectorSlotIndex: this.ejectorSlotIndex,
});
}
/**
*
* @param {object} param0
* @param {number} param0.bufferSize How much energy this consumer can store
* @param {number} param0.perCharge How much energy this consumer needs per charge
* @param {Vector} param0.batteryPosition world space render offset of the battery icon
* @param {number} param0.acceptorSlotIndex Which slot to accept energy on
* @param {number} param0.ejectorSlotIndex Which slot to eject energy off
*
*/
constructor({
bufferSize = 3,
perCharge = 1,
batteryPosition = new Vector(),
acceptorSlotIndex = 0,
ejectorSlotIndex = 0,
}) {
super();
this.bufferSize = bufferSize;
this.perCharge = perCharge;
this.batteryPosition = batteryPosition;
this.energyType = enumItemType.positiveEnergy;
this.wasteType = enumItemType.negativeEnergy;
this.acceptorSlotIndex = acceptorSlotIndex;
this.ejectorSlotIndex = ejectorSlotIndex;
/**
* How much energy we have stored right now
*/
this.stored = 0;
/**
* How much waste we have piled up so far
*/
this.piledOutput = 0;
}
/**
* Tries to accept a given item
* @param {BaseItem} item
* @param {number} slotIndex
*/
tryAcceptItem(item, slotIndex) {
if (slotIndex !== this.acceptorSlotIndex) {
// Wrong slot
return false;
}
if (item.getItemType() !== this.energyType) {
// Not the right type
return false;
}
if (this.stored >= this.bufferSize) {
// We are full
return false;
}
// All good, consume
this.stored = Math.min(this.stored + 1, this.bufferSize);
return true;
}
/**
* Tries to start the next charge
*/
tryStartNextCharge() {
if (this.hasTooMuchWastePiled()) {
// Too much waste remaining
return false;
}
if (this.stored < this.perCharge) {
// Not enough energy stored
return false;
}
this.stored -= this.perCharge;
this.piledOutput += this.perCharge;
return true;
}
/**
* Returns if there is too much waste piled
*/
hasTooMuchWastePiled() {
return this.piledOutput >= 1.0;
}
/**
* Reduces the waste by the given amount
* @param {number} amount
*/
reduceWaste(amount) {
this.piledOutput = Math.max(0, this.piledOutput - amount);
}
}

View File

@ -1,93 +0,0 @@
import { types } from "../../savegame/serialization";
import { BaseItem, enumItemType } from "../base_item";
import { Component } from "../component";
import { ShapeItem } from "../items/shape_item";
const maxQueueSize = 4;
export class EnergyGeneratorComponent extends Component {
static getId() {
return "EnergyGenerator";
}
static getSchema() {
return {
requiredKey: types.nullable(types.string),
itemsInQueue: types.uint,
wasteAcceptorSlotIndex: types.uint,
};
}
duplicateWithoutContents() {
return new EnergyGeneratorComponent({
requiredKey: null,
wasteAcceptorSlotIndex: this.wasteAcceptorSlotIndex,
});
}
/**
*
* @param {object} param0
* @param {string=} param0.requiredKey Which shape this generator needs, can be null if not computed yet
* @param {number} param0.wasteAcceptorSlotIndex Which slot accepts the waste
*/
constructor({ requiredKey, wasteAcceptorSlotIndex = 0 }) {
super();
this.requiredKey = requiredKey;
/**
* Stores how many items are ready to be converted to energy
* @type {number}
*/
this.itemsInQueue = 0;
/**
* Stores which slot accepts the waste
* @type {number}
*/
this.wasteAcceptorSlotIndex = wasteAcceptorSlotIndex;
}
/**
*
* @param {BaseItem} item
* @param {number} slot
*/
tryTakeItem(item, slot) {
if (slot === this.wasteAcceptorSlotIndex) {
// this is the acceptor slot on the wires layer
// just destroy it
return true;
} else {
if (item.getItemType() !== enumItemType.shape) {
// This shouldn't happen since we have a filter - still, it doesn't hurt
// to check either
assertAlways(
false,
"Energy generator took wrong item: " +
item.getItemType() +
" on slot " +
slot +
" (waste slot = " +
this.wasteAcceptorSlotIndex +
")"
);
return false;
}
if (/** @type {ShapeItem} */ (item).definition.getHash() !== this.requiredKey) {
// Not our shape
return false;
}
if (this.itemsInQueue >= maxQueueSize) {
// Queue is full
return false;
}
// Take item and put it into the queue
++this.itemsInQueue;
return true;
}
}
}

View File

@ -7,7 +7,6 @@ import { enumLayer } from "../root";
/** @typedef {{
* pos: Vector,
* directions: enumDirection[],
* layer: enumLayer,
* filter?: enumItemType
* }} ItemAcceptorSlot */
@ -22,7 +21,6 @@ import { enumLayer } from "../root";
/** @typedef {{
* pos: Vector,
* directions: enumDirection[],
* layer?: enumLayer,
* filter?: enumItemType
* }} ItemAcceptorSlotConfig */
@ -38,9 +36,6 @@ export class ItemAcceptorComponent extends Component {
pos: types.vector,
directions: types.array(types.enum(enumDirection)),
filter: types.nullable(types.enum(enumItemType)),
// TODO: MIGRATE
layer: types.enum(enumLayer),
})
),
};
@ -54,7 +49,6 @@ export class ItemAcceptorComponent extends Component {
pos: slot.pos.copy(),
directions: slot.directions.slice(),
filter: slot.filter,
layer: slot.layer,
});
}
@ -92,7 +86,6 @@ export class ItemAcceptorComponent extends Component {
this.slots.push({
pos: slot.pos,
directions: slot.directions,
layer: slot.layer || enumLayer.regular,
// Which type of item to accept (shape | color | all) @see enumItemType
filter: slot.filter,
@ -147,10 +140,9 @@ export class ItemAcceptorComponent extends Component {
* Tries to find a slot which accepts the current item
* @param {Vector} targetLocalTile
* @param {enumDirection} fromLocalDirection
* @param {enumLayer} layer
* @returns {ItemAcceptorLocatedSlot|null}
*/
findMatchingSlot(targetLocalTile, fromLocalDirection, layer) {
findMatchingSlot(targetLocalTile, fromLocalDirection) {
// We need to invert our direction since the acceptor specifies *from* which direction
// it accepts items, but the ejector specifies *into* which direction it ejects items.
// E.g.: Ejector ejects into "right" direction but acceptor accepts from "left" direction.
@ -165,11 +157,6 @@ export class ItemAcceptorComponent extends Component {
continue;
}
// Make sure the layer matches
if (slot.layer !== layer) {
continue;
}
// Check if the acceptor slot accepts items from our direction
for (let i = 0; i < slot.directions.length; ++i) {
// const localDirection = targetStaticComp.localDirectionToWorld(slot.directions[l]);

View File

@ -12,7 +12,6 @@ import { BeltPath } from "../belt_path";
* pos: Vector,
* direction: enumDirection,
* item: BaseItem,
* layer: enumLayer,
* progress: number?,
* cachedDestSlot?: import("./item_acceptor").ItemAcceptorLocatedSlot,
* cachedBeltPath?: BeltPath,
@ -34,9 +33,6 @@ export class ItemEjectorComponent extends Component {
direction: types.enum(enumDirection),
item: types.nullable(types.obj(gItemRegistry)),
progress: types.float,
// TODO: Migrate
layer: types.enum(enumLayer),
})
),
};
@ -49,7 +45,6 @@ export class ItemEjectorComponent extends Component {
slotsCopy.push({
pos: slot.pos.copy(),
direction: slot.direction,
layer: slot.layer,
});
}
@ -61,7 +56,7 @@ export class ItemEjectorComponent extends Component {
/**
*
* @param {object} param0
* @param {Array<{pos: Vector, direction: enumDirection, layer?: enumLayer}>=} param0.slots The slots to eject on
* @param {Array<{pos: Vector, direction: enumDirection }>=} param0.slots The slots to eject on
*/
constructor({ slots = [] }) {
super();
@ -75,7 +70,7 @@ export class ItemEjectorComponent extends Component {
}
/**
* @param {Array<{pos: Vector, direction: enumDirection, layer?: enumLayer}>} slots The slots to eject on
* @param {Array<{pos: Vector, direction: enumDirection }>} slots The slots to eject on
*/
setSlots(slots) {
/** @type {Array<ItemEjectorSlot>} */
@ -87,7 +82,6 @@ export class ItemEjectorComponent extends Component {
direction: slot.direction,
item: null,
progress: 0,
layer: slot.layer || enumLayer.regular,
cachedDestSlot: null,
cachedTargetEntity: null,
});
@ -108,11 +102,10 @@ export class ItemEjectorComponent extends Component {
/**
* Returns whether any slot ejects to the given local tile
* @param {Vector} tile
* @param {enumLayer} layer
*/
anySlotEjectsToLocalTile(tile, layer) {
anySlotEjectsToLocalTile(tile) {
for (let i = 0; i < this.slots.length; ++i) {
if (this.getSlotTargetLocalTile(i).equals(tile) && this.slots[i].layer === layer) {
if (this.getSlotTargetLocalTile(i).equals(tile)) {
return true;
}
}
@ -131,12 +124,11 @@ export class ItemEjectorComponent extends Component {
/**
* Returns the first free slot on this ejector or null if there is none
* @param {enumLayer} layer
* @returns {number?}
*/
getFirstFreeSlot(layer) {
getFirstFreeSlot() {
for (let i = 0; i < this.slots.length; ++i) {
if (this.canEjectOnSlot(i) && this.slots[i].layer === layer) {
if (this.canEjectOnSlot(i)) {
return i;
}
}

View File

@ -18,7 +18,6 @@ export const enumItemProcessorTypes = {
painter: "painter",
painterDouble: "painterDouble",
painterQuad: "painterQuad",
advancedProcessor: "advancedProcessor",
hub: "hub",
};

View File

@ -103,8 +103,7 @@ export class UndergroundBeltComponent extends Component {
}
// Notice: We assume that for all items the travel distance is the same
const maxItemsInTunnel =
(2 + travelDistance) / globalConfig.beltItemSpacingByLayer[enumLayer.regular];
const maxItemsInTunnel = (2 + travelDistance) / globalConfig.itemSpacingOnBelts;
if (this.pendingItems.length >= maxItemsInTunnel) {
// Simulate a real belt which gets full at some point
return false;
@ -114,8 +113,7 @@ export class UndergroundBeltComponent extends Component {
// This corresponds to the item ejector - it needs 0.5 additional tiles to eject the item.
// So instead of adding 1 we add 0.5 only.
// Additionally it takes 1 tile for the acceptor which we just add on top.
const travelDuration =
(travelDistance + 1.5) / beltSpeed / globalConfig.beltItemSpacingByLayer[enumLayer.regular];
const travelDuration = (travelDistance + 1.5) / beltSpeed / globalConfig.itemSpacingOnBelts;
this.pendingItems.push([item, travelDuration]);

View File

@ -398,14 +398,14 @@ export class GameCore {
if (!this.root.camera.getIsMapOverlayActive()) {
// Underlays for splitters / balancers
systems.beltUnderlays.drawUnderlays(params, enumLayer.regular);
systems.beltUnderlays.drawUnderlays(params);
// Belt items
systems.belt.drawLayerBeltItems(params, enumLayer.regular);
systems.belt.drawBeltItems(params);
// Items being ejected / accepted currently (animations)
systems.itemEjector.drawLayer(params, enumLayer.regular);
systems.itemAcceptor.drawLayer(params, enumLayer.regular);
systems.itemEjector.draw(params);
systems.itemAcceptor.draw(params);
}
// Miner & Static map entities
@ -415,28 +415,15 @@ export class GameCore {
// HUB Overlay
systems.hub.draw(params);
// Energy generator overlay
systems.energyGenerator.draw(params);
// Storage items
systems.storage.draw(params);
// Energy consumer (Battery icons)
systems.energyConsumer.draw(params);
}
// Green wires overlay (not within the if because it can fade)
root.hud.parts.wiresOverlay.draw(params);
if (this.root.currentLayer === enumLayer.wires && !this.root.camera.getIsMapOverlayActive()) {
// Belt sprites & Static map entities
root.map.drawWiresLayer(params);
// Belt items as well as accepted / ejected items
systems.belt.drawLayerBeltItems(params, enumLayer.wires);
systems.itemEjector.drawLayer(params, enumLayer.wires);
systems.itemAcceptor.drawLayer(params, enumLayer.wires);
// Static map entities
root.map.drawWiresForegroundLayer(params);
// pins

View File

@ -169,9 +169,6 @@ export class Entity extends BasicSerializableObject {
const ejectorSprite = Loader.getSprite("sprites/debug/ejector_slot.png");
for (let i = 0; i < ejectorComp.slots.length; ++i) {
const slot = ejectorComp.slots[i];
if (slot.layer !== this.root.currentLayer) {
continue;
}
const slotTile = staticComp.localTileToWorld(slot.pos);
const direction = staticComp.localDirectionToWorld(slot.direction);
const directionVector = enumDirectionToVector[direction];
@ -194,9 +191,6 @@ export class Entity extends BasicSerializableObject {
const acceptorSprite = Loader.getSprite("sprites/debug/acceptor_slot.png");
for (let i = 0; i < acceptorComp.slots.length; ++i) {
const slot = acceptorComp.slots[i];
if (slot.layer !== this.root.currentLayer) {
continue;
}
const slotTile = staticComp.localTileToWorld(slot.pos);
for (let k = 0; k < slot.directions.length; ++k) {
const direction = staticComp.localDirectionToWorld(slot.directions[k]);

View File

@ -13,9 +13,7 @@ import { HubSystem } from "./systems/hub";
import { StaticMapEntitySystem } from "./systems/static_map_entity";
import { ItemAcceptorSystem } from "./systems/item_acceptor";
import { StorageSystem } from "./systems/storage";
import { EnergyGeneratorSystem } from "./systems/energy_generator";
import { WiredPinsSystem } from "./systems/wired_pins";
import { EnergyConsumerSystem } from "./systems/energy_consumer";
import { BeltUnderlaysSystem } from "./systems/belt_underlays";
const logger = createLogger("game_system_manager");
@ -60,15 +58,9 @@ export class GameSystemManager {
/** @type {StorageSystem} */
storage: null,
/** @type {EnergyGeneratorSystem} */
energyGenerator: null,
/** @type {WiredPinsSystem} */
wiredPins: null,
/** @type {EnergyConsumerSystem} */
energyConsumer: null,
/** @type {BeltUnderlaysSystem} */
beltUnderlays: null,
@ -106,14 +98,10 @@ export class GameSystemManager {
add("hub", HubSystem);
add("energyGenerator", EnergyGeneratorSystem);
add("staticMapEntities", StaticMapEntitySystem);
add("wiredPins", WiredPinsSystem);
add("energyConsumer", EnergyConsumerSystem);
add("beltUnderlays", BeltUnderlaysSystem);
// IMPORTANT: Must be after belt system since belt system can change the

View File

@ -3,7 +3,7 @@ import { Component } from "./component";
import { Entity } from "./entity";
/* typehints:end */
import { GameRoot, enumLayer } from "./root";
import { GameRoot } from "./root";
import { GameSystem } from "./game_system";
import { arrayDelete, arrayDeleteValue } from "../core/utils";
import { DrawParameters } from "../core/draw_parameters";
@ -39,9 +39,8 @@ export class GameSystemWithFilter extends GameSystem {
* Calls a function for each matching entity on the screen, useful for drawing them
* @param {DrawParameters} parameters
* @param {function} callback
* @param {enumLayer=} layerFilter Can be null for no filter
*/
forEachMatchingEntityOnScreen(parameters, callback, layerFilter = null) {
forEachMatchingEntityOnScreen(parameters, callback) {
const cullRange = parameters.visibleRect.toTileCullRectangle();
if (this.allEntities.length < 100) {
// So, its much quicker to simply perform per-entity checking
@ -49,9 +48,7 @@ export class GameSystemWithFilter extends GameSystem {
for (let i = 0; i < this.allEntities.length; ++i) {
const entity = this.allEntities[i];
if (cullRange.containsRect(entity.components.StaticMapEntity.getTileSpaceBounds())) {
if (!layerFilter || entity.layer === layerFilter) {
callback(parameters, entity);
}
callback(parameters, entity);
}
}
return;
@ -94,11 +91,6 @@ export class GameSystemWithFilter extends GameSystem {
entityLoop: for (let i = 0; i < entities.length; ++i) {
const entity = entities[i];
// Avoid drawing non-layer contents
if (layerFilter && entity.layer !== layerFilter) {
continue;
}
// Avoid drawing twice
if (seenUids.has(entity.uid)) {
continue;

View File

@ -367,13 +367,9 @@ export class HubGoals extends BasicSerializableObject {
/**
* Belt speed
* @param {enumLayer} layer
* @returns {number} items / sec
*/
getBeltBaseSpeed(layer) {
if (layer === enumLayer.wires) {
return globalConfig.wiresSpeedItemsPerSecond;
}
getBeltBaseSpeed() {
return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt;
}

View File

@ -440,11 +440,6 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
for (let acceptorSlotIndex = 0; acceptorSlotIndex < slots.length; ++acceptorSlotIndex) {
const slot = slots[acceptorSlotIndex];
// Only draw same layer slots
if (slot.layer !== this.root.currentLayer) {
continue;
}
const acceptorSlotWsTile = staticComp.localTileToWorld(slot.pos);
const acceptorSlotWsPos = acceptorSlotWsTile.toWorldSpaceCenterOfTile();
@ -478,20 +473,12 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
// If this entity is on the same layer as the slot - if so, it can either be
// connected, or it can not be connected and thus block the input
if (sourceEntity.layer === slot.layer) {
if (
sourceEjector &&
sourceEjector.anySlotEjectsToLocalTile(
ejectorAcceptLocalTile,
this.root.currentLayer
)
) {
// This one is connected, all good
isConnected = true;
} else {
// This one is blocked
isBlocked = true;
}
if (sourceEjector && sourceEjector.anySlotEjectsToLocalTile(ejectorAcceptLocalTile)) {
// This one is connected, all good
isConnected = true;
} else {
// This one is blocked
isBlocked = true;
}
}
@ -520,11 +507,6 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
for (let ejectorSlotIndex = 0; ejectorSlotIndex < slots.length; ++ejectorSlotIndex) {
const slot = slots[ejectorSlotIndex];
// Only draw same layer slots
if (slot.layer !== this.root.currentLayer) {
continue;
}
const ejectorSlotWsTile = staticComp.localTileToWorld(
ejectorComp.getSlotTargetLocalTile(ejectorSlotIndex)
);
@ -546,21 +528,14 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
const destAcceptor = destEntity.components.ItemAcceptor;
const destStaticComp = destEntity.components.StaticMapEntity;
// If this entity is on the same layer as the slot - if so, it can either be
// connected, or it can not be connected and thus block the input
if (destEntity.layer === slot.layer) {
const destLocalTile = destStaticComp.worldToLocalTile(ejectorSlotWsTile);
const destLocalDir = destStaticComp.worldDirectionToLocal(ejectorSlotWsDirection);
if (
destAcceptor &&
destAcceptor.findMatchingSlot(destLocalTile, destLocalDir, this.root.currentLayer)
) {
// This one is connected, all good
isConnected = true;
} else {
// This one is blocked
isBlocked = true;
}
const destLocalTile = destStaticComp.worldToLocalTile(ejectorSlotWsTile);
const destLocalDir = destStaticComp.worldDirectionToLocal(ejectorSlotWsDirection);
if (destAcceptor && destAcceptor.findMatchingSlot(destLocalTile, destLocalDir)) {
// This one is connected, all good
isConnected = true;
} else {
// This one is blocked
isBlocked = true;
}
}

View File

@ -1,6 +1,5 @@
import { MetaBeltBaseBuilding } from "../../buildings/belt_base";
import { MetaCutterBuilding } from "../../buildings/cutter";
import { MetaEnergyGenerator } from "../../buildings/energy_generator";
import { MetaMinerBuilding } from "../../buildings/miner";
import { MetaMixerBuilding } from "../../buildings/mixer";
import { MetaPainterBuilding } from "../../buildings/painter";
@ -11,7 +10,6 @@ import { MetaTrashBuilding } from "../../buildings/trash";
import { MetaUndergroundBeltBuilding } from "../../buildings/underground_belt";
import { enumLayer } from "../../root";
import { HUDBaseToolbar } from "./base_toolbar";
import { MetaAdvancedProcessorBuilding } from "../../buildings/advanced_processor";
const supportedBuildings = [
MetaBeltBaseBuilding,
@ -24,9 +22,6 @@ const supportedBuildings = [
MetaMixerBuilding,
MetaPainterBuilding,
MetaTrashBuilding,
MetaEnergyGenerator,
MetaAdvancedProcessorBuilding,
];
export class HUDBuildingsToolbar extends HUDBaseToolbar {

View File

@ -66,9 +66,6 @@ export class HUDColorBlindHelper extends BaseHUDPart {
if (ejectorComp) {
for (let i = 0; i < ejectorComp.slots.length; ++i) {
const slot = ejectorComp.slots[i];
if (slot.layer !== this.root.currentLayer) {
continue;
}
if (slot.item && slot.item.getItemType() === enumItemType.color) {
return /** @type {ColorItem} */ (slot.item).color;
}

View File

@ -1,9 +1,7 @@
import { MetaWireBaseBuilding } from "../../buildings/wire_base";
import { enumLayer } from "../../root";
import { HUDBaseToolbar } from "./base_toolbar";
import { MetaWireCrossingsBuilding } from "../../buildings/wire_crossings";
const supportedBuildings = [MetaWireBaseBuilding, MetaWireCrossingsBuilding];
const supportedBuildings = [];
export class HUDWiresToolbar extends HUDBaseToolbar {
constructor(root) {

View File

@ -92,7 +92,7 @@ export class TrailerMaker {
const speed =
globalConfig.tileSize *
globalConfig.beltSpeedItemsPerSecond *
globalConfig.beltItemSpacingByLayer[enumLayer.regular];
globalConfig.itemSpacingOnBelts;
// let time =
// this.currentPlaybackOrigin.distance(Vector.fromSerializedObject(nextMarker.pos)) / speed;
const time = nextMarker.time;

View File

@ -54,12 +54,6 @@ export const KEYMAPPINGS = {
mixer: { keyCode: key("8") },
painter: { keyCode: key("9") },
trash: { keyCode: key("0") },
energy_generator: { keyCode: key("O") },
advanced_processor: { keyCode: key("P") },
// Wires layer
wire: { keyCode: key("1") },
wire_crossings: { keyCode: key("2") },
},
placement: {

View File

@ -3,7 +3,7 @@ import { round2Digits } from "../core/utils";
import { enumDirection, enumDirectionToVector, Vector } from "../core/vector";
import { Entity } from "./entity";
import { MetaBuilding } from "./meta_building";
import { enumLayer, GameRoot } from "./root";
import { GameRoot, enumLayer } from "./root";
import { STOP_PROPAGATION } from "../core/signal";
const logger = createLogger("ingame/logic");
@ -178,10 +178,9 @@ export class GameLogic {
/**
* Returns the acceptors and ejectors which affect the current tile
* @param {Vector} tile
* @param {enumLayer} layer
* @returns {AcceptorsAndEjectorsAffectingTile}
*/
getEjectorsAndAcceptorsAtTile(tile, layer) {
getEjectorsAndAcceptorsAtTile(tile) {
/** @type {EjectorsAffectingTile} */
let ejectors = [];
/** @type {AcceptorsAffectingTile} */
@ -194,10 +193,8 @@ export class GameLogic {
continue;
}
const entities = this.root.map.getLayersContentsMultipleXY(tile.x + dx, tile.y + dy);
for (let i = 0; i < entities.length; ++i) {
const entity = entities[i];
const entity = this.root.map.getLayerContentXY(tile.x + dx, tile.y + dy, enumLayer.regular);
if (entity) {
let ejectorSlots = [];
let acceptorSlots = [];
@ -223,9 +220,6 @@ export class GameLogic {
for (let ejectorSlot = 0; ejectorSlot < ejectorSlots.length; ++ejectorSlot) {
const slot = ejectorSlots[ejectorSlot];
if (slot.layer !== layer) {
continue;
}
const wsTile = staticComp.localTileToWorld(slot.pos);
const wsDirection = staticComp.localDirectionToWorld(slot.direction);
const targetTile = wsTile.add(enumDirectionToVector[wsDirection]);
@ -241,10 +235,6 @@ export class GameLogic {
for (let acceptorSlot = 0; acceptorSlot < acceptorSlots.length; ++acceptorSlot) {
const slot = acceptorSlots[acceptorSlot];
if (slot.layer !== layer) {
continue;
}
const wsTile = staticComp.localTileToWorld(slot.pos);
for (let k = 0; k < slot.directions.length; ++k) {
const direction = slot.directions[k];

View File

@ -48,15 +48,6 @@ export class MapChunkView extends MapChunk {
systems.staticMapEntities.drawChunk(parameters, this);
}
/**
* Draws the wires layer
* @param {DrawParameters} parameters
*/
drawWiresLayer(parameters) {
const systems = this.root.systemMgr.systems;
systems.belt.drawWiresChunk(parameters, this);
}
/**
* Draws the wires layer
* @param {DrawParameters} parameters

View File

@ -167,14 +167,6 @@ export class MapView extends BaseMap {
}
}
/**
* Draws the wires background
* @param {DrawParameters} parameters
*/
drawWiresLayer(parameters) {
this.drawVisibleChunks(parameters, MapChunkView.prototype.drawWiresLayer);
}
/**
* Draws the wires foreground
* @param {DrawParameters} parameters

View File

@ -1,10 +1,8 @@
import { gMetaBuildingRegistry } from "../core/global_registries";
import { createLogger } from "../core/logging";
import { MetaAdvancedProcessorBuilding } from "./buildings/advanced_processor";
import { MetaBeltBuilding } from "./buildings/belt";
import { MetaBeltBaseBuilding } from "./buildings/belt_base";
import { enumCutterVariants, MetaCutterBuilding } from "./buildings/cutter";
import { MetaEnergyGenerator } from "./buildings/energy_generator";
import { MetaHubBuilding } from "./buildings/hub";
import { enumMinerVariants, MetaMinerBuilding } from "./buildings/miner";
import { MetaMixerBuilding } from "./buildings/mixer";
@ -14,8 +12,6 @@ import { enumSplitterVariants, MetaSplitterBuilding } from "./buildings/splitter
import { MetaStackerBuilding } from "./buildings/stacker";
import { enumTrashVariants, MetaTrashBuilding } from "./buildings/trash";
import { enumUndergroundBeltVariants, MetaUndergroundBeltBuilding } from "./buildings/underground_belt";
import { MetaWireBaseBuilding } from "./buildings/wire_base";
import { enumWireCrossingVariants, MetaWireCrossingsBuilding } from "./buildings/wire_crossings";
import { gBuildingVariants, registerBuildingVariant } from "./building_codes";
import { defaultBuildingVariant } from "./meta_building";
@ -33,10 +29,6 @@ export function initMetaBuildingRegistry() {
gMetaBuildingRegistry.register(MetaBeltBuilding);
gMetaBuildingRegistry.register(MetaUndergroundBeltBuilding);
gMetaBuildingRegistry.register(MetaHubBuilding);
gMetaBuildingRegistry.register(MetaEnergyGenerator);
gMetaBuildingRegistry.register(MetaWireBaseBuilding);
gMetaBuildingRegistry.register(MetaAdvancedProcessorBuilding);
gMetaBuildingRegistry.register(MetaWireCrossingsBuilding);
// Belt
registerBuildingVariant(1, MetaBeltBaseBuilding, defaultBuildingVariant, 0);
@ -86,21 +78,6 @@ export function initMetaBuildingRegistry() {
// Hub
registerBuildingVariant(26, MetaHubBuilding);
// Energy generator
registerBuildingVariant(27, MetaEnergyGenerator);
// Wire
registerBuildingVariant(28, MetaWireBaseBuilding, defaultBuildingVariant, 0);
registerBuildingVariant(29, MetaWireBaseBuilding, defaultBuildingVariant, 1);
registerBuildingVariant(30, MetaWireBaseBuilding, defaultBuildingVariant, 2);
// Advanced processor
registerBuildingVariant(31, MetaAdvancedProcessorBuilding);
// Wire crossing
registerBuildingVariant(32, MetaWireCrossingsBuilding);
registerBuildingVariant(33, MetaWireCrossingsBuilding, enumWireCrossingVariants.merger);
// Propagate instances
for (const key in gBuildingVariants) {
gBuildingVariants[key].metaInstance = gMetaBuildingRegistry.findByClass(

View File

@ -5,13 +5,7 @@ import { DrawParameters } from "../core/draw_parameters";
import { createLogger } from "../core/logging";
import { Vector } from "../core/vector";
import { BasicSerializableObject, types } from "../savegame/serialization";
import {
enumColors,
enumColorsToHexCode,
enumColorToShortcode,
enumShortcodeToColor,
enumInvertedColors,
} from "./colors";
import { enumColors, enumColorsToHexCode, enumColorToShortcode, enumShortcodeToColor } from "./colors";
import { THEME } from "./theme";
const rusha = require("rusha");
@ -598,23 +592,6 @@ export class ShapeDefinition extends BasicSerializableObject {
return new ShapeDefinition({ layers: newLayers });
}
/**
* Clones the shape and inverts all colors
*/
cloneAndInvertColors() {
const newLayers = this.internalCloneLayers();
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
const quadrants = newLayers[layerIndex];
for (let quadrantIndex = 0; quadrantIndex < 4; ++quadrantIndex) {
const item = quadrants[quadrantIndex];
if (item) {
item.color = enumInvertedColors[item.color];
}
}
}
return new ShapeDefinition({ layers: newLayers });
}
/**
* Clones the shape and colors everything in the given colors
* @param {[enumColors, enumColors, enumColors, enumColors]} colors

View File

@ -179,22 +179,6 @@ export class ShapeDefinitionManager extends BasicSerializableObject {
));
}
/**
* Generates a definition for inverting all colors on that shape
* @param {ShapeDefinition} definition
* @returns {ShapeDefinition}
*/
shapeActionInvertColors(definition) {
const key = "invert:" + definition.getHash();
if (this.operationCache[key]) {
return /** @type {ShapeDefinition} */ (this.operationCache[key]);
}
const inverted = definition.cloneAndInvertColors();
return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle(
inverted
));
}
/**
* Generates a definition for painting it with the 4 colors
* @param {ShapeDefinition} definition

View File

@ -13,9 +13,6 @@ import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { MapChunkView } from "../map_chunk_view";
import { defaultBuildingVariant } from "../meta_building";
import { enumLayer } from "../root";
import { MetaWireBaseBuilding } from "../buildings/wire_base";
import { enumItemType } from "../base_item";
export const BELT_ANIM_COUNT = 28;
@ -320,14 +317,10 @@ export class BeltSystem extends GameSystemWithFilter {
/**
* Draws all belt paths
* @param {DrawParameters} parameters
* @param {enumLayer} layer
*/
drawLayerBeltItems(parameters, layer) {
drawBeltItems(parameters) {
for (let i = 0; i < this.beltPaths.length; ++i) {
const path = this.beltPaths[i];
if (path.layer === layer) {
path.draw(parameters);
}
this.beltPaths[i].draw(parameters);
}
}
@ -497,13 +490,13 @@ export class BeltSystem extends GameSystemWithFilter {
}
// Limit speed to avoid belts going backwards
const speedMultiplier = Math.min(this.root.hubGoals.getBeltBaseSpeed(enumLayer.regular), 10);
const speedMultiplier = Math.min(this.root.hubGoals.getBeltBaseSpeed(), 10);
// SYNC with systems/item_acceptor.js:drawEntityUnderlays!
// 126 / 42 is the exact animation speed of the png animation
const animationIndex = Math.floor(
((this.root.time.realtimeNow() * speedMultiplier * BELT_ANIM_COUNT * 126) / 42) *
globalConfig.beltItemSpacingByLayer[enumLayer.regular]
globalConfig.itemSpacingOnBelts
);
const contents = chunk.contents;
for (let y = 0; y < globalConfig.mapChunkSize; ++y) {
@ -526,35 +519,6 @@ export class BeltSystem extends GameSystemWithFilter {
1;
}
/**
* Draws a given chunk
* @param {DrawParameters} parameters
* @param {MapChunkView} chunk
*/
drawWiresChunk(parameters, chunk) {
if (parameters.zoomLevel < globalConfig.mapChunkOverviewMinZoom) {
return;
}
const contents = chunk.wireContents;
for (let y = 0; y < globalConfig.mapChunkSize; ++y) {
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
const entity = contents[x][y];
if (entity && entity.components.Belt) {
const direction = entity.components.Belt.direction;
const sprite = this.wireSprites[direction];
entity.components.StaticMapEntity.drawSpriteOnFullEntityBounds(
parameters,
sprite,
0,
false
);
}
}
}
}
/**
* Draws the belt path debug overlays
* @param {DrawParameters} parameters

View File

@ -1,12 +1,11 @@
import { GameSystemWithFilter } from "../game_system_with_filter";
import { BeltUnderlaysComponent } from "../components/belt_underlays";
import { BELT_ANIM_COUNT } from "./belt";
import { Loader } from "../../core/loader";
import { enumLayer } from "../root";
import { Entity } from "../entity";
import { enumDirectionToAngle } from "../../core/vector";
import { globalConfig } from "../../core/config";
import { drawRotatedSprite } from "../../core/draw_utils";
import { Loader } from "../../core/loader";
import { enumDirectionToAngle } from "../../core/vector";
import { BeltUnderlaysComponent } from "../components/belt_underlays";
import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { BELT_ANIM_COUNT } from "./belt";
export class BeltUnderlaysSystem extends GameSystemWithFilter {
constructor(root) {
@ -22,32 +21,25 @@ export class BeltUnderlaysSystem extends GameSystemWithFilter {
/**
* Draws the acceptor underlays
* @param {import("../../core/draw_utils").DrawParameters} parameters
* @param {enumLayer} layer
*/
drawUnderlays(parameters, layer) {
this.forEachMatchingEntityOnScreen(parameters, this.drawEntityUnderlays.bind(this, layer));
drawUnderlays(parameters) {
this.forEachMatchingEntityOnScreen(parameters, this.drawEntityUnderlays.bind(this));
}
/**
* @param {enumLayer} layer
* @param {import("../../core/draw_utils").DrawParameters} parameters
* @param {Entity} entity
*/
drawEntityUnderlays(layer, parameters, entity) {
drawEntityUnderlays(parameters, entity) {
const staticComp = entity.components.StaticMapEntity;
const underlayComp = entity.components.BeltUnderlays;
if (entity.layer !== layer) {
// Not our layer
return;
}
if (!staticComp.shouldBeDrawn(parameters)) {
return;
}
// Limit speed to avoid belts going backwards
const speedMultiplier = Math.min(this.root.hubGoals.getBeltBaseSpeed(layer), 10);
const speedMultiplier = Math.min(this.root.hubGoals.getBeltBaseSpeed(), 10);
const underlays = underlayComp.underlays;
for (let i = 0; i < underlays.length; ++i) {
@ -59,7 +51,7 @@ export class BeltUnderlaysSystem extends GameSystemWithFilter {
// SYNC with systems/belt.js:drawSingleEntity!
const animationIndex = Math.floor(
((this.root.time.realtimeNow() * speedMultiplier * BELT_ANIM_COUNT * 126) / 42) *
globalConfig.beltItemSpacingByLayer[layer]
globalConfig.itemSpacingOnBelts
);
drawRotatedSprite({

View File

@ -1,90 +0,0 @@
import { DrawParameters } from "../../core/draw_parameters";
import { Loader } from "../../core/loader";
import { clamp } from "../../core/utils";
import { enumItemType } from "../base_item";
import { EnergyConsumerComponent } from "../components/energy_consumer";
import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { NEGATIVE_ENERGY_ITEM_SINGLETON } from "../items/negative_energy_item";
import { POSITIVE_ENERGY_ITEM_SINGLETON } from "../items/positive_energy_item";
export class EnergyConsumerSystem extends GameSystemWithFilter {
constructor(root) {
super(root, [EnergyConsumerComponent]);
this.batterySprites = [
Loader.getSprite("sprites/wires/battery_empty.png"),
Loader.getSprite("sprites/wires/battery_low.png"),
Loader.getSprite("sprites/wires/battery_medium.png"),
Loader.getSprite("sprites/wires/battery_full.png"),
];
this.piledWasteSprite = Loader.getSprite("sprites/wires/waste_piled.png");
}
update() {
for (let i = 0; i < this.allEntities.length; ++i) {
const entity = this.allEntities[i];
const energyConsumerComp = entity.components.EnergyConsumer;
if (energyConsumerComp.piledOutput >= 1.0) {
// Try to get rid of waste
const ejectorComp = entity.components.ItemEjector;
const item = this.getItemSingletonByType(energyConsumerComp.wasteType);
if (ejectorComp.tryEject(energyConsumerComp.ejectorSlotIndex, item)) {
// Got rid of waste
energyConsumerComp.reduceWaste(1.0);
}
}
}
}
/**
*
* @param {enumItemType} itemType
*/
getItemSingletonByType(itemType) {
switch (itemType) {
case enumItemType.positiveEnergy:
return POSITIVE_ENERGY_ITEM_SINGLETON;
case enumItemType.negativeEnergy:
return NEGATIVE_ENERGY_ITEM_SINGLETON;
default:
assertAlways(false, "Bad item type: " + itemType);
}
}
/**
* Draws everything
* @param {DrawParameters} parameters
*/
draw(parameters) {
this.forEachMatchingEntityOnScreen(parameters, this.drawSingleEntity.bind(this));
}
/**
* Draws a given entity
* @param {DrawParameters} parameters
* @param {Entity} entity
*/
drawSingleEntity(parameters, entity) {
const staticComp = entity.components.StaticMapEntity;
const consumerComp = entity.components.EnergyConsumer;
const position = staticComp.localTileToWorld(consumerComp.batteryPosition).toWorldSpaceCenterOfTile();
if (consumerComp.hasTooMuchWastePiled()) {
this.piledWasteSprite.drawCachedCentered(parameters, position.x, position.y, 12);
} else {
const percentage = consumerComp.stored / consumerComp.bufferSize;
const index = clamp(
Math.round(percentage * this.batterySprites.length),
0,
this.batterySprites.length - 1
);
this.batterySprites[index].drawCachedCentered(parameters, position.x, position.y, 12);
}
}
}

View File

@ -1,97 +0,0 @@
import { DrawParameters } from "../../core/draw_parameters";
import { formatBigNumber } from "../../core/utils";
import { T } from "../../translations";
import { EnergyGeneratorComponent } from "../components/energy_generator";
import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { POSITIVE_ENERGY_ITEM_SINGLETON } from "../items/positive_energy_item";
import { ShapeDefinition } from "../shape_definition";
import { Loader } from "../../core/loader";
import { globalConfig } from "../../core/config";
export class EnergyGeneratorSystem extends GameSystemWithFilter {
constructor(root) {
super(root, [EnergyGeneratorComponent]);
this.energyGeneratorOverlay = Loader.getSprite("sprites/misc/energy_generator_overlay.png");
}
draw(parameters) {
this.forEachMatchingEntityOnScreen(parameters, this.drawEntity.bind(this));
}
/**
* Returns which shape is required for a given generator
* @param {Entity} entity
*/
getShapeRequiredForGenerator(entity) {
return "CuCuCuCu";
}
update() {
for (let i = 0; i < this.allEntities.length; ++i) {
const entity = this.allEntities[i];
const energyGenComp = entity.components.EnergyGenerator;
const ejectorComp = entity.components.ItemEjector;
if (!energyGenComp.requiredKey) {
// Compute required key for this generator
energyGenComp.requiredKey = this.getShapeRequiredForGenerator(entity);
}
if (energyGenComp.itemsInQueue > 0) {
// FIXME: Find slot dynamically
if (ejectorComp.tryEject(0, POSITIVE_ENERGY_ITEM_SINGLETON)) {
energyGenComp.itemsInQueue -= 1;
}
}
}
}
/**
* @param {DrawParameters} parameters
* @param {Entity} entity
*/
drawEntity(parameters, entity) {
const context = parameters.context;
const staticComp = entity.components.StaticMapEntity;
if (!staticComp.shouldBeDrawn(parameters)) {
return;
}
const energyGenComp = entity.components.EnergyGenerator;
if (!energyGenComp.requiredKey) {
// Not initialized yet
return;
}
const pos = staticComp.getTileSpaceBounds().getCenter().toWorldSpace();
const definition = ShapeDefinition.fromShortKey(energyGenComp.requiredKey);
definition.draw(pos.x, pos.y, parameters, 30);
// Draw background
this.energyGeneratorOverlay.drawCachedCentered(
parameters,
pos.x,
pos.y,
globalConfig.tileSize * 2 + 8
);
// TODO
const energyGenerated = 5;
// deliver: Deliver
// toGenerateEnergy: For <x> energy
context.font = "bold 9px GameFont";
context.fillStyle = "#64666e";
context.textAlign = "left";
context.fillText(T.buildings.energy_generator.deliver.toUpperCase(), pos.x - 25, pos.y - 18);
context.fillText(T.buildings.energy_generator.toGenerateEnergy.toUpperCase(), pos.x - 25, pos.y + 27);
context.font = "700 9px GameFont";
context.fillStyle = "#dee1ea";
context.fillText("" + formatBigNumber(energyGenerated), pos.x + 1, pos.y + 27);
}
}

View File

@ -23,11 +23,8 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
// Process item consumption animations to avoid items popping from the belts
for (let animIndex = 0; animIndex < animations.length; ++animIndex) {
const anim = animations[animIndex];
const layer = aceptorComp.slots[anim.slotIndex].layer;
anim.animProgress +=
progress *
this.root.hubGoals.getBeltBaseSpeed(layer) *
globalConfig.beltItemSpacingByLayer[layer];
progress * this.root.hubGoals.getBeltBaseSpeed() * globalConfig.itemSpacingOnBelts;
if (anim.animProgress > 1) {
// Original
// animations.splice(animIndex, 1);
@ -44,18 +41,16 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
/**
* Draws the acceptor items
* @param {DrawParameters} parameters
* @param {enumLayer} layer
*/
drawLayer(parameters, layer) {
this.forEachMatchingEntityOnScreen(parameters, this.drawEntityRegularLayer.bind(this, layer));
draw(parameters) {
this.forEachMatchingEntityOnScreen(parameters, this.drawEntityRegularLayer.bind(this));
}
/**
* @param {enumLayer} layer
* @param {DrawParameters} parameters
* @param {Entity} entity
*/
drawEntityRegularLayer(layer, parameters, entity) {
drawEntityRegularLayer(parameters, entity) {
const staticComp = entity.components.StaticMapEntity;
const acceptorComp = entity.components.ItemAcceptor;
@ -69,10 +64,6 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
];
const slotData = acceptorComp.slots[slotIndex];
if (slotData.layer !== layer) {
// Don't draw non-regular slots for now
continue;
}
const slotWorldPos = staticComp.applyRotationToVector(slotData.pos).add(staticComp.origin);
const fadeOutDirection = enumDirectionToVector[staticComp.localDirectionToWorld(direction)];

View File

@ -3,11 +3,10 @@ import { DrawParameters } from "../../core/draw_parameters";
import { createLogger } from "../../core/logging";
import { Rectangle } from "../../core/rectangle";
import { enumDirection, enumDirectionToVector, Vector } from "../../core/vector";
import { BaseItem, enumItemTypeToLayer } from "../base_item";
import { BaseItem } from "../base_item";
import { ItemEjectorComponent } from "../components/item_ejector";
import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { enumLayer } from "../root";
const logger = createLogger("systems/ejector");
@ -166,8 +165,7 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
const matchingSlot = targetAcceptorComp.findMatchingSlot(
targetStaticComp.worldToLocalTile(ejectSlotTargetWsTile),
targetStaticComp.worldDirectionToLocal(ejectSlotWsDirection),
ejectorSlot.layer
targetStaticComp.worldDirectionToLocal(ejectSlotWsDirection)
);
if (!matchingSlot) {
@ -219,8 +217,8 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
1,
sourceSlot.progress +
progressGrowth *
this.root.hubGoals.getBeltBaseSpeed(sourceSlot.layer) *
globalConfig.beltItemSpacingByLayer[sourceSlot.layer]
this.root.hubGoals.getBeltBaseSpeed() *
globalConfig.itemSpacingOnBelts
);
// Check if we are still in the process of ejecting, can't proceed then
@ -272,8 +270,6 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
// TODO: Kinda hacky. How to solve this properly? Don't want to go through inheritance hell.
// Also its just a few cases (hope it stays like this .. :x).
const itemLayer = enumItemTypeToLayer[item.getItemType()];
const beltComp = receiver.components.Belt;
if (beltComp) {
const path = beltComp.assignedPath;
@ -297,15 +293,12 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
const itemProcessorComp = receiver.components.ItemProcessor;
if (itemProcessorComp) {
// Make sure its the same layer
if (itemLayer === receiver.layer) {
// Its an item processor ..
if (itemProcessorComp.tryTakeItem(item, slotIndex)) {
return true;
}
// Item processor can have nothing else
return false;
// Its an item processor ..
if (itemProcessorComp.tryTakeItem(item, slotIndex)) {
return true;
}
// Item processor can have nothing else
return false;
}
const undergroundBeltComp = receiver.components.UndergroundBelt;
@ -336,35 +329,22 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
return false;
}
const energyGeneratorComp = receiver.components.EnergyGenerator;
if (energyGeneratorComp) {
if (energyGeneratorComp.tryTakeItem(item, slotIndex)) {
// Passed it over
return true;
}
// Energy generator comp can't have anything else
return false;
}
return false;
}
/**
* Draws the given layer
* Draws everything
* @param {DrawParameters} parameters
* @param {enumLayer} layer
*/
drawLayer(parameters, layer) {
this.forEachMatchingEntityOnScreen(parameters, this.drawSingleEntity.bind(this, layer));
draw(parameters) {
this.forEachMatchingEntityOnScreen(parameters, this.drawSingleEntity.bind(this));
}
/**
* @param {enumLayer} layer
* @param {DrawParameters} parameters
* @param {Entity} entity
*/
drawSingleEntity(layer, parameters, entity) {
drawSingleEntity(parameters, entity) {
const ejectorComp = entity.components.ItemEjector;
const staticComp = entity.components.StaticMapEntity;
@ -381,11 +361,6 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
continue;
}
if (slot.layer !== layer) {
// Not our layer
continue;
}
const realPosition = slot.pos.rotateFastMultipleOf90(staticComp.rotation);
const realDirection = Vector.transformDirectionFromMultipleOf90(
slot.direction,

View File

@ -1,6 +1,6 @@
import { globalConfig } from "../../core/config";
import { BaseItem, enumItemType } from "../base_item";
import { enumColorMixingResults, enumInvertedColors } from "../colors";
import { enumColorMixingResults } from "../colors";
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
@ -48,11 +48,11 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
if (ejectorComp.canEjectOnSlot(preferredSlot)) {
slot = preferredSlot;
} else {
slot = ejectorComp.getFirstFreeSlot(entity.layer);
slot = ejectorComp.getFirstFreeSlot();
}
} else {
// We can eject on any slot
slot = ejectorComp.getFirstFreeSlot(entity.layer);
slot = ejectorComp.getFirstFreeSlot();
}
if (slot !== null) {
@ -354,35 +354,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
break;
}
// ADVANCED PROCESSING
case enumItemProcessorTypes.advancedProcessor: {
const item = items[0].item;
if (item.getItemType() === enumItemType.color) {
const colorItem = /** @type {ColorItem} */ (items[0].item);
const newColor = enumInvertedColors[colorItem.color];
outItems.push({
item: new ColorItem(newColor),
requiredSlot: 0,
});
} else if (item.getItemType() === enumItemType.shape) {
const shapeItem = /** @type {ShapeItem} */ (items[0].item);
const newItem = this.root.shapeDefinitionMgr.shapeActionInvertColors(
shapeItem.definition
);
outItems.push({
item: new ShapeItem(newItem),
requiredSlot: 0,
});
} else {
assertAlways(false, "Bad item type: " + item.getItemType() + " for advanced processor.");
}
break;
}
default:
assertAlways(false, "Unkown item processor type: " + processorComp.type);
}

View File

@ -1,10 +1,9 @@
import { GameSystem } from "../game_system";
import { DrawParameters } from "../../core/draw_parameters";
import { globalConfig } from "../../core/config";
import { MapChunkView } from "../map_chunk_view";
import { DrawParameters } from "../../core/draw_parameters";
import { Loader } from "../../core/loader";
import { enumDirection } from "../../core/vector";
import { enumLayer } from "../root";
import { GameSystem } from "../game_system";
import { MapChunkView } from "../map_chunk_view";
export class StaticMapEntitySystem extends GameSystem {
constructor(root) {

View File

@ -22,8 +22,7 @@ export class StorageSystem extends GameSystemWithFilter {
if (storageComp.storedItem && storageComp.storedCount > 0) {
const ejectorComp = entity.components.ItemEjector;
/* FIXME: WIRES */
const nextSlot = ejectorComp.getFirstFreeSlot(enumLayer.regular);
const nextSlot = ejectorComp.getFirstFreeSlot();
if (nextSlot !== null) {
if (ejectorComp.tryEject(nextSlot, storageComp.storedItem)) {
storageComp.storedCount--;

View File

@ -395,7 +395,7 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
if (remainingTime <= 0) {
const ejectorComp = entity.components.ItemEjector;
const nextSlotIndex = ejectorComp.getFirstFreeSlot(entity.layer);
const nextSlotIndex = ejectorComp.getFirstFreeSlot();
if (nextSlotIndex !== null) {
if (ejectorComp.tryEject(nextSlotIndex, nextItem)) {
items.shift();

View File

@ -14,14 +14,6 @@ export class WiredPinsSystem extends GameSystemWithFilter {
super(root, [WiredPinsComponent]);
this.pinSprites = {
[enumPinSlotType.positiveEnergyEjector]: Loader.getSprite("sprites/wires/pin_positive_eject.png"),
[enumPinSlotType.positiveEnergyAcceptor]: Loader.getSprite(
"sprites/wires/pin_positive_accept.png"
),
[enumPinSlotType.negativeEnergyEjector]: Loader.getSprite("sprites/wires/pin_negative_eject.png"),
[enumPinSlotType.negativeEnergyAcceptor]: Loader.getSprite(
"sprites/wires/pin_negative_accept.png"
),
[enumPinSlotType.logicalEjector]: Loader.getSprite("sprites/wires/pin_negative_eject.png"),
[enumPinSlotType.logicalAcceptor]: Loader.getSprite("sprites/wires/pin_negative_accept.png"),
};

View File

@ -448,11 +448,6 @@ buildings:
name: &belt Conveyor Belt
description: Transports items, hold and drag to place multiple.
wire:
default:
name: &wire Energy Wire
description: Allows you to transport energy.
# Internal name for the Extractor
miner:
default:
@ -495,11 +490,6 @@ buildings:
name: Cutter (Quad)
description: Cuts shapes into four parts. <strong>If you use only one part, be sure to destroy the other parts or it will stall!</strong>
advanced_processor:
default:
name: &advanced_processor Color Inverter
description: Accepts a color or shape and inverts it.
rotater:
default:
name: &rotater Rotate
@ -547,25 +537,6 @@ buildings:
name: Storage
description: Stores excess items, up to a given capacity. Can be used as an overflow gate.
energy_generator:
deliver: Deliver
# This will be shown before the amount, so for example 'For 123 Energy'
toGenerateEnergy: For
default:
name: &energy_generator Energy Generator
description: Generates energy by consuming shapes.
wire_crossings:
default:
name: &wire_crossings Wire Splitter
description: Splits a energy wire into two.
merger:
name: Wire Merger
description: Merges two energy wires into one.
storyRewards:
# Those are the rewards gained from completing the store
reward_cutter_and_trash:
@ -826,14 +797,11 @@ keybindings:
underground_belt: *underground_belt
miner: *miner
cutter: *cutter
advanced_processor: *advanced_processor
rotater: *rotater
stacker: *stacker
mixer: *mixer
energy_generator: *energy_generator
painter: *painter
trash: *trash
wire: *wire
pipette: Pipette
rotateWhilePlacing: Rotate