mirror of
https://github.com/tobspr/shapez.io.git
synced 2026-03-02 03:39:21 +00:00
Initial take on wires
This commit is contained in:
@@ -3,7 +3,10 @@ import { BaseItem } from "../base_item";
|
||||
import { Component } from "../component";
|
||||
import { ShapeItem } from "../items/shape_item";
|
||||
|
||||
const maxQueueSize = 10;
|
||||
const maxQueueSize = 4;
|
||||
|
||||
export const ENERGY_GENERATOR_EJECT_SLOT = 0;
|
||||
export const ENERGY_GENERATOR_ACCEPT_SLOT = 4;
|
||||
|
||||
export class EnergyGeneratorComponent extends Component {
|
||||
static getId() {
|
||||
@@ -12,7 +15,8 @@ export class EnergyGeneratorComponent extends Component {
|
||||
|
||||
static getSchema() {
|
||||
return {
|
||||
requiredKey: types.string,
|
||||
requiredKey: types.nullable(types.string),
|
||||
itemsInQueue: types.uint,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -35,20 +39,27 @@ export class EnergyGeneratorComponent extends Component {
|
||||
/**
|
||||
*
|
||||
* @param {BaseItem} item
|
||||
* @param {number} slot
|
||||
*/
|
||||
tryTakeItem(item) {
|
||||
if (/** @type {ShapeItem} */ (item).definition.getHash() !== this.requiredKey) {
|
||||
// Not our shape
|
||||
return false;
|
||||
}
|
||||
tryTakeItem(item, slot) {
|
||||
if (slot === ENERGY_GENERATOR_ACCEPT_SLOT) {
|
||||
// this is the acceptor slot on the wires layer
|
||||
// just destroy it
|
||||
return true;
|
||||
} else {
|
||||
if (/** @type {ShapeItem} */ (item).definition.getHash() !== this.requiredKey) {
|
||||
// Not our shape
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.itemsInQueue >= maxQueueSize) {
|
||||
// Queue is full
|
||||
return false;
|
||||
}
|
||||
if (this.itemsInQueue >= maxQueueSize) {
|
||||
// Queue is full
|
||||
return false;
|
||||
}
|
||||
|
||||
// Take item and put it into the queue
|
||||
++this.itemsInQueue;
|
||||
return true;
|
||||
// Take item and put it into the queue
|
||||
++this.itemsInQueue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,12 @@ import { enumDirection, enumInvertedDirections, Vector } from "../../core/vector
|
||||
import { types } from "../../savegame/serialization";
|
||||
import { BaseItem, enumItemType } from "../base_item";
|
||||
import { Component } from "../component";
|
||||
import { enumLayer } from "../root";
|
||||
|
||||
/** @typedef {{
|
||||
* pos: Vector,
|
||||
* directions: enumDirection[],
|
||||
* layer: enumLayer,
|
||||
* filter?: enumItemType
|
||||
* }} ItemAcceptorSlot */
|
||||
|
||||
@@ -17,6 +19,13 @@ import { Component } from "../component";
|
||||
* acceptedDirection: enumDirection
|
||||
* }} ItemAcceptorLocatedSlot */
|
||||
|
||||
/** @typedef {{
|
||||
* pos: Vector,
|
||||
* directions: enumDirection[],
|
||||
* layer?: enumLayer,
|
||||
* filter?: enumItemType
|
||||
* }} ItemAcceptorSlotConfig */
|
||||
|
||||
export class ItemAcceptorComponent extends Component {
|
||||
static getId() {
|
||||
return "ItemAcceptor";
|
||||
@@ -29,6 +38,9 @@ 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),
|
||||
})
|
||||
),
|
||||
animated: types.bool,
|
||||
@@ -36,6 +48,9 @@ export class ItemAcceptorComponent extends Component {
|
||||
types.structured({
|
||||
pos: types.vector,
|
||||
direction: types.enum(enumDirection),
|
||||
|
||||
// TODO: MIGRATE
|
||||
layer: types.enum(enumLayer),
|
||||
})
|
||||
),
|
||||
};
|
||||
@@ -49,6 +64,7 @@ export class ItemAcceptorComponent extends Component {
|
||||
pos: slot.pos.copy(),
|
||||
directions: slot.directions.slice(),
|
||||
filter: slot.filter,
|
||||
layer: slot.layer,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -58,6 +74,7 @@ export class ItemAcceptorComponent extends Component {
|
||||
beltUnderlaysCopy.push({
|
||||
pos: underlay.pos.copy(),
|
||||
direction: underlay.direction,
|
||||
layer: underlay.layer,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -71,9 +88,9 @@ export class ItemAcceptorComponent extends Component {
|
||||
/**
|
||||
*
|
||||
* @param {object} param0
|
||||
* @param {Array<{pos: Vector, directions: enumDirection[], filter?: enumItemType}>} param0.slots The slots from which we accept items
|
||||
* @param {Array<ItemAcceptorSlotConfig>} param0.slots The slots from which we accept items
|
||||
* @param {boolean=} param0.animated Whether to animate item consumption
|
||||
* @param {Array<{pos: Vector, direction: enumDirection}>=} param0.beltUnderlays Where to render belt underlays
|
||||
* @param {Array<{pos: Vector, direction: enumDirection, layer: enumLayer}>=} param0.beltUnderlays Where to render belt underlays
|
||||
*/
|
||||
constructor({ slots = [], beltUnderlays = [], animated = true }) {
|
||||
super();
|
||||
@@ -82,7 +99,7 @@ export class ItemAcceptorComponent extends Component {
|
||||
|
||||
/**
|
||||
* Fixes belt animations
|
||||
* @type {Array<{ item: BaseItem, slotIndex: number, animProgress: number, direction: enumDirection}>}
|
||||
* @type {Array<{ item: BaseItem, slotIndex: number, animProgress: number, direction: enumDirection }>}
|
||||
*/
|
||||
this.itemConsumptionAnimations = [];
|
||||
|
||||
@@ -94,16 +111,17 @@ export class ItemAcceptorComponent extends Component {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Array<{pos: Vector, directions: enumDirection[], filter?: enumItemType}>} slots
|
||||
* @param {Array<ItemAcceptorSlotConfig>} slots
|
||||
*/
|
||||
setSlots(slots) {
|
||||
/** @type {Array<{pos: Vector, directions: enumDirection[], filter?: enumItemType}>} */
|
||||
/** @type {Array<ItemAcceptorSlot>} */
|
||||
this.slots = [];
|
||||
for (let i = 0; i < slots.length; ++i) {
|
||||
const slot = slots[i];
|
||||
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,
|
||||
@@ -142,9 +160,10 @@ 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) {
|
||||
findMatchingSlot(targetLocalTile, fromLocalDirection, layer) {
|
||||
// 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.
|
||||
@@ -159,6 +178,11 @@ 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]);
|
||||
|
||||
@@ -4,12 +4,14 @@ import { Component } from "../component";
|
||||
import { types } from "../../savegame/serialization";
|
||||
import { gItemRegistry } from "../../core/global_registries";
|
||||
import { Entity } from "../entity";
|
||||
import { enumLayer } from "../root";
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* pos: Vector,
|
||||
* direction: enumDirection,
|
||||
* item: BaseItem,
|
||||
* layer: enumLayer,
|
||||
* progress: number?,
|
||||
* cachedDestSlot?: import("./item_acceptor").ItemAcceptorLocatedSlot,
|
||||
* cachedTargetEntity?: Entity
|
||||
@@ -32,6 +34,9 @@ export class ItemEjectorComponent extends Component {
|
||||
direction: types.enum(enumDirection),
|
||||
item: types.nullable(types.obj(gItemRegistry)),
|
||||
progress: types.float,
|
||||
|
||||
// TODO: Migrate
|
||||
layer: types.enum(enumLayer),
|
||||
})
|
||||
),
|
||||
};
|
||||
@@ -44,6 +49,7 @@ export class ItemEjectorComponent extends Component {
|
||||
slotsCopy.push({
|
||||
pos: slot.pos.copy(),
|
||||
direction: slot.direction,
|
||||
layer: slot.layer,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -56,7 +62,7 @@ export class ItemEjectorComponent extends Component {
|
||||
/**
|
||||
*
|
||||
* @param {object} param0
|
||||
* @param {Array<{pos: Vector, direction: enumDirection}>=} param0.slots The slots to eject on
|
||||
* @param {Array<{pos: Vector, direction: enumDirection, layer?: enumLayer}>=} param0.slots The slots to eject on
|
||||
* @param {boolean=} param0.instantEject If the ejection is instant
|
||||
*/
|
||||
constructor({ slots = [], instantEject = false }) {
|
||||
@@ -77,7 +83,7 @@ export class ItemEjectorComponent extends Component {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array<{pos: Vector, direction: enumDirection}>} slots The slots to eject on
|
||||
* @param {Array<{pos: Vector, direction: enumDirection, layer?: enumLayer}>} slots The slots to eject on
|
||||
*/
|
||||
setSlots(slots) {
|
||||
/** @type {Array<ItemEjectorSlot>} */
|
||||
@@ -89,19 +95,13 @@ export class ItemEjectorComponent extends Component {
|
||||
direction: slot.direction,
|
||||
item: null,
|
||||
progress: 0,
|
||||
layer: slot.layer || enumLayer.regular,
|
||||
cachedDestSlot: null,
|
||||
cachedTargetEntity: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of slots
|
||||
*/
|
||||
getNumSlots() {
|
||||
return this.slots.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns where this slot ejects to
|
||||
* @param {number} index
|
||||
@@ -116,26 +116,17 @@ export class ItemEjectorComponent extends Component {
|
||||
/**
|
||||
* Returns whether any slot ejects to the given local tile
|
||||
* @param {Vector} tile
|
||||
* @param {enumLayer} layer
|
||||
*/
|
||||
anySlotEjectsToLocalTile(tile) {
|
||||
anySlotEjectsToLocalTile(tile, layer) {
|
||||
for (let i = 0; i < this.slots.length; ++i) {
|
||||
if (this.getSlotTargetLocalTile(i).equals(tile)) {
|
||||
if (this.getSlotTargetLocalTile(i).equals(tile) && this.slots[i].layer === layer) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if slot # is currently ejecting
|
||||
* @param {number} slotIndex
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isSlotEjecting(slotIndex) {
|
||||
assert(slotIndex >= 0 && slotIndex < this.slots.length, "Invalid ejector slot: " + slotIndex);
|
||||
return !!this.slots[slotIndex].item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if we can eject on a given slot
|
||||
* @param {number} slotIndex
|
||||
@@ -148,43 +139,18 @@ 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() {
|
||||
getFirstFreeSlot(layer) {
|
||||
for (let i = 0; i < this.slots.length; ++i) {
|
||||
if (this.canEjectOnSlot(i)) {
|
||||
if (this.canEjectOnSlot(i) && this.slots[i].layer === layer) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if any slot is ejecting
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isAnySlotEjecting() {
|
||||
for (let i = 0; i < this.slots.length; ++i) {
|
||||
if (this.slots[i].item) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if any slot is free
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasAnySlotFree() {
|
||||
for (let i = 0; i < this.slots.length; ++i) {
|
||||
if (this.canEjectOnSlot(i)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to eject a given item
|
||||
* @param {number} slotIndex
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
import { Component } from "../component";
|
||||
import { Vector } from "../../core/vector";
|
||||
import { Vector, enumDirection } from "../../core/vector";
|
||||
import { types } from "../../savegame/serialization";
|
||||
|
||||
/** @enum {string} */
|
||||
export const enumPinSlotType = {
|
||||
energyEjector: "energyEjector",
|
||||
positiveEnergyEjector: "positiveEnergyEjector",
|
||||
negativeEnergyEjector: "negativeEnergyEjector",
|
||||
positiveEnergyAcceptor: "positiveEnergyAcceptor",
|
||||
negativeEnergyAcceptor: "positiveEnergyAcceptor",
|
||||
};
|
||||
|
||||
/** @typedef {{
|
||||
* pos: Vector,
|
||||
* type: enumPinSlotType
|
||||
* type: enumPinSlotType,
|
||||
* direction: enumDirection
|
||||
* }} WirePinSlotDefinition */
|
||||
|
||||
/** @typedef {{
|
||||
* pos: Vector,
|
||||
* type: enumPinSlotType,
|
||||
* value: number
|
||||
* direction: enumDirection
|
||||
* }} WirePinSlot */
|
||||
|
||||
export class WiredPinsComponent extends Component {
|
||||
@@ -29,7 +33,6 @@ export class WiredPinsComponent extends Component {
|
||||
types.structured({
|
||||
pos: types.vector,
|
||||
type: types.enum(enumPinSlotType),
|
||||
value: types.float,
|
||||
})
|
||||
),
|
||||
};
|
||||
@@ -58,7 +61,7 @@ export class WiredPinsComponent extends Component {
|
||||
this.slots.push({
|
||||
pos: slotData.pos,
|
||||
type: slotData.type,
|
||||
value: 0.0,
|
||||
direction: slotData.direction,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user