mirror of
https://github.com/tobspr/shapez.io.git
synced 2026-03-02 03:39:21 +00:00
Implement wire networks, add levers
This commit is contained in:
@@ -13,6 +13,7 @@ import { Entity } from "../entity";
|
||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||
import { MapChunkView } from "../map_chunk_view";
|
||||
import { defaultBuildingVariant } from "../meta_building";
|
||||
import { getCodeFromBuildingData } from "../building_codes";
|
||||
|
||||
export const BELT_ANIM_COUNT = 28;
|
||||
|
||||
@@ -169,6 +170,13 @@ export class BeltSystem extends GameSystemWithFilter {
|
||||
targetStaticComp.rotation = rotation;
|
||||
metaBelt.updateVariants(targetEntity, rotationVariant, defaultBuildingVariant);
|
||||
|
||||
// Update code as well
|
||||
targetStaticComp.code = getCodeFromBuildingData(
|
||||
metaBelt,
|
||||
defaultBuildingVariant,
|
||||
rotationVariant
|
||||
);
|
||||
|
||||
// Now add it again
|
||||
this.addEntityToPaths(targetEntity);
|
||||
|
||||
|
||||
48
src/js/game/systems/lever.js
Normal file
48
src/js/game/systems/lever.js
Normal file
@@ -0,0 +1,48 @@
|
||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||
import { LeverComponent } from "../components/lever";
|
||||
import { BOOL_TRUE_SINGLETON, BOOL_FALSE_SINGLETON } from "../items/boolean_item";
|
||||
import { MapChunkView } from "../map_chunk_view";
|
||||
import { globalConfig } from "../../core/config";
|
||||
import { Loader } from "../../core/loader";
|
||||
|
||||
export class LeverSystem extends GameSystemWithFilter {
|
||||
constructor(root) {
|
||||
super(root, [LeverComponent]);
|
||||
|
||||
this.spriteOn = Loader.getSprite("sprites/wires/lever_on.png");
|
||||
this.spriteOff = Loader.getSprite("sprites/buildings/lever.png");
|
||||
}
|
||||
|
||||
update() {
|
||||
for (let i = 0; i < this.allEntities.length; ++i) {
|
||||
const entity = this.allEntities[i];
|
||||
|
||||
const leverComp = entity.components.Lever;
|
||||
const pinsComp = entity.components.WiredPins;
|
||||
|
||||
// Simply sync the status to the first slot
|
||||
pinsComp.slots[0].value = leverComp.toggled ? BOOL_TRUE_SINGLETON : BOOL_FALSE_SINGLETON;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a given chunk
|
||||
* @param {import("../../core/draw_utils").DrawParameters} parameters
|
||||
* @param {MapChunkView} chunk
|
||||
*/
|
||||
drawChunk(parameters, chunk) {
|
||||
const contents = chunk.contents;
|
||||
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.Lever) {
|
||||
const sprite = entity.components.Lever.toggled ? this.spriteOn : this.spriteOff;
|
||||
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
staticComp.drawSpriteOnFullEntityBounds(parameters, sprite, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
78
src/js/game/systems/logic_gate.js
Normal file
78
src/js/game/systems/logic_gate.js
Normal file
@@ -0,0 +1,78 @@
|
||||
import { LogicGateComponent, enumLogicGateType } from "../components/logic_gate";
|
||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||
import { BaseItem, enumItemType } from "../base_item";
|
||||
import { enumPinSlotType } from "../components/wired_pins";
|
||||
import { BOOL_TRUE_SINGLETON, BOOL_FALSE_SINGLETON, BooleanItem } from "../items/boolean_item";
|
||||
|
||||
export class LogicGateSystem extends GameSystemWithFilter {
|
||||
constructor(root) {
|
||||
super(root, [LogicGateComponent]);
|
||||
|
||||
this.boundOperations = {
|
||||
[enumLogicGateType.and]: this.compute_AND.bind(this),
|
||||
};
|
||||
}
|
||||
|
||||
update() {
|
||||
for (let i = 0; i < this.allEntities.length; ++i) {
|
||||
const entity = this.allEntities[i];
|
||||
const logicComp = entity.components.LogicGate;
|
||||
const slotComp = entity.components.WiredPins;
|
||||
|
||||
const slotValues = [];
|
||||
|
||||
for (let i = 0; i < slotComp.slots.length; ++i) {
|
||||
const slot = slotComp.slots[i];
|
||||
if (slot.type !== enumPinSlotType.logicalAcceptor) {
|
||||
continue;
|
||||
}
|
||||
if (slot.linkedNetwork) {
|
||||
slotValues.push(slot.linkedNetwork.currentValue);
|
||||
} else {
|
||||
slotValues.push(null);
|
||||
}
|
||||
}
|
||||
|
||||
const result = this.boundOperations[logicComp.type](slotValues);
|
||||
|
||||
// @TODO: For now we hardcode the value to always be slot 0
|
||||
assert(
|
||||
slotValues.length === slotComp.slots.length - 1,
|
||||
"Bad slot config, should have N acceptor slots and 1 ejector"
|
||||
);
|
||||
assert(slotComp.slots[0].type === enumPinSlotType.logicalEjector, "Slot 0 should be ejector");
|
||||
|
||||
slotComp.slots[0].value = result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array<BaseItem|null>} parameters
|
||||
* @returns {BaseItem}
|
||||
*/
|
||||
compute_AND(parameters) {
|
||||
assert(parameters.length === 2, "bad parameter count for AND");
|
||||
|
||||
const param1 = parameters[0];
|
||||
const param2 = parameters[1];
|
||||
if (!param1 || !param2) {
|
||||
// Not enough params
|
||||
return null;
|
||||
}
|
||||
|
||||
const itemType = param1.getItemType();
|
||||
|
||||
if (itemType !== param2.getItemType()) {
|
||||
// Differing type
|
||||
return BOOL_FALSE_SINGLETON;
|
||||
}
|
||||
|
||||
if (itemType === enumItemType.boolean) {
|
||||
return /** @type {BooleanItem} */ (param1).value && /** @type {BooleanItem} */ (param2).value
|
||||
? BOOL_TRUE_SINGLETON
|
||||
: BOOL_FALSE_SINGLETON;
|
||||
}
|
||||
|
||||
return BOOL_FALSE_SINGLETON;
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,69 @@ import { Loader } from "../../core/loader";
|
||||
import { Entity } from "../entity";
|
||||
import { gMetaBuildingRegistry } from "../../core/global_registries";
|
||||
import { MetaWireBuilding, arrayWireRotationVariantToType } from "../buildings/wire";
|
||||
import { Vector } from "../../core/vector";
|
||||
import {
|
||||
Vector,
|
||||
enumDirection,
|
||||
enumDirectionToVector,
|
||||
arrayAllDirections,
|
||||
enumInvertedDirections,
|
||||
} from "../../core/vector";
|
||||
import { defaultBuildingVariant } from "../meta_building";
|
||||
import { createLogger } from "../../core/logging";
|
||||
import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins";
|
||||
import { getCodeFromBuildingData } from "../building_codes";
|
||||
import { BaseItem, enumItemType } from "../base_item";
|
||||
|
||||
const logger = createLogger("wires");
|
||||
|
||||
let networkUidCounter = 0;
|
||||
|
||||
const VERBOSE_WIRES = false;
|
||||
|
||||
export class WireNetwork {
|
||||
constructor() {
|
||||
/**
|
||||
* Who contributes to this network
|
||||
* @type {Array<{ entity: Entity, slot: import("../components/wired_pins").WirePinSlot }>} */
|
||||
this.providers = [];
|
||||
|
||||
/**
|
||||
* Who takes values from this network
|
||||
* @type {Array<{ entity: Entity, slot: import("../components/wired_pins").WirePinSlot }>} */
|
||||
this.receivers = [];
|
||||
|
||||
/**
|
||||
* All connected slots
|
||||
* @type {Array<{ entity: Entity, slot: import("../components/wired_pins").WirePinSlot }>}
|
||||
*/
|
||||
this.allSlots = [];
|
||||
|
||||
/**
|
||||
* Which wires are in this network
|
||||
* @type {Array<Entity>}
|
||||
*/
|
||||
this.wires = [];
|
||||
|
||||
/**
|
||||
* The current value of this network
|
||||
* @type {BaseItem}
|
||||
*/
|
||||
this.currentValue = null;
|
||||
|
||||
/**
|
||||
* Whether this network has a value conflict, that is, more than one
|
||||
* sender has sent a value
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.valueConflict = false;
|
||||
|
||||
/**
|
||||
* Unique network identifier
|
||||
* @type {number}
|
||||
*/
|
||||
this.uid = ++networkUidCounter;
|
||||
}
|
||||
}
|
||||
|
||||
export class WireSystem extends GameSystemWithFilter {
|
||||
constructor(root) {
|
||||
@@ -22,6 +83,327 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
|
||||
this.root.signals.entityDestroyed.add(this.updateSurroundingWirePlacement, this);
|
||||
this.root.signals.entityAdded.add(this.updateSurroundingWirePlacement, this);
|
||||
|
||||
this.root.signals.entityDestroyed.add(this.queueRecomputeIfWire, this);
|
||||
this.root.signals.entityChanged.add(this.queueRecomputeIfWire, this);
|
||||
this.root.signals.entityAdded.add(this.queueRecomputeIfWire, this);
|
||||
|
||||
this.needsRecompute = true;
|
||||
|
||||
/**
|
||||
* @type {Array<WireNetwork>}
|
||||
*/
|
||||
this.networks = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates the wires network if the given entity is relevant for it
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
queueRecomputeIfWire(entity) {
|
||||
if (!this.root.gameInitialized) {
|
||||
return;
|
||||
}
|
||||
if (entity.components.Wire || entity.components.WiredPins) {
|
||||
this.needsRecompute = true;
|
||||
this.networks = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recomputes the whole wires network
|
||||
*/
|
||||
recomputeWiresNetwork() {
|
||||
this.needsRecompute = false;
|
||||
logger.log("Recomputing wires network");
|
||||
|
||||
this.networks = [];
|
||||
|
||||
// Clear all network references
|
||||
const wireEntities = this.root.entityMgr.getAllWithComponent(WireComponent);
|
||||
for (let i = 0; i < wireEntities.length; ++i) {
|
||||
wireEntities[i].components.Wire.linkedNetwork = null;
|
||||
}
|
||||
|
||||
const pinEntities = this.root.entityMgr.getAllWithComponent(WiredPinsComponent);
|
||||
for (let i = 0; i < pinEntities.length; ++i) {
|
||||
const slots = pinEntities[i].components.WiredPins.slots;
|
||||
for (let k = 0; k < slots.length; ++k) {
|
||||
slots[k].linkedNetwork = null;
|
||||
}
|
||||
}
|
||||
|
||||
VERBOSE_WIRES && logger.log("Recomputing slots");
|
||||
|
||||
// Iterate over all ejector slots
|
||||
for (let i = 0; i < pinEntities.length; ++i) {
|
||||
const entity = pinEntities[i];
|
||||
const slots = entity.components.WiredPins.slots;
|
||||
for (let k = 0; k < slots.length; ++k) {
|
||||
const slot = slots[k];
|
||||
|
||||
// Ejectors are computed directly, acceptors are just set
|
||||
if (slot.type === enumPinSlotType.logicalEjector && !slot.linkedNetwork) {
|
||||
this.findNetworkForEjector(entity, slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the network for the given slot
|
||||
* @param {Entity} initialEntity
|
||||
* @param {import("../components/wired_pins").WirePinSlot} slot
|
||||
*/
|
||||
findNetworkForEjector(initialEntity, slot) {
|
||||
let currentNetwork = new WireNetwork();
|
||||
VERBOSE_WIRES &&
|
||||
logger.log(
|
||||
"Finding network for entity",
|
||||
initialEntity.uid,
|
||||
initialEntity.components.StaticMapEntity.origin.toString(),
|
||||
"(nw-id:",
|
||||
currentNetwork.uid,
|
||||
")"
|
||||
);
|
||||
const entitiesToVisit = [
|
||||
{
|
||||
entity: initialEntity,
|
||||
slot,
|
||||
},
|
||||
];
|
||||
|
||||
while (entitiesToVisit.length > 0) {
|
||||
const nextData = entitiesToVisit.pop();
|
||||
const nextEntity = nextData.entity;
|
||||
|
||||
const wireComp = nextEntity.components.Wire;
|
||||
const staticComp = nextEntity.components.StaticMapEntity;
|
||||
|
||||
VERBOSE_WIRES && logger.log("Visiting", staticComp.origin.toString(), "(", nextEntity.uid, ")");
|
||||
|
||||
// Where to search for neighbours
|
||||
let newSearchDirections = [];
|
||||
let newSearchTile = null;
|
||||
|
||||
//// WIRE
|
||||
if (wireComp) {
|
||||
// Sanity check
|
||||
assert(
|
||||
!wireComp.linkedNetwork || wireComp.linkedNetwork === currentNetwork,
|
||||
"Mismatching wire network on wire entity " +
|
||||
(wireComp.linkedNetwork ? wireComp.linkedNetwork.uid : "<empty>") +
|
||||
" vs " +
|
||||
currentNetwork.uid +
|
||||
" @ " +
|
||||
staticComp.origin.toString()
|
||||
);
|
||||
|
||||
if (!wireComp.linkedNetwork) {
|
||||
// This one is new! :D
|
||||
VERBOSE_WIRES && logger.log(" Visited new wire:", staticComp.origin.toString());
|
||||
wireComp.linkedNetwork = currentNetwork;
|
||||
currentNetwork.wires.push(nextEntity);
|
||||
|
||||
newSearchDirections = arrayAllDirections;
|
||||
newSearchTile = nextEntity.components.StaticMapEntity.origin;
|
||||
}
|
||||
}
|
||||
|
||||
//// PINS
|
||||
const pinsComp = nextEntity.components.WiredPins;
|
||||
if (pinsComp) {
|
||||
const slot = nextData.slot;
|
||||
assert(slot, "No slot set for next entity");
|
||||
|
||||
if (slot.type === enumPinSlotType.logicalEjector) {
|
||||
VERBOSE_WIRES &&
|
||||
logger.log(" Visiting ejector slot", staticComp.origin.toString(), "->", slot.type);
|
||||
} else if (slot.type === enumPinSlotType.logicalAcceptor) {
|
||||
VERBOSE_WIRES &&
|
||||
logger.log(" Visiting acceptor slot", staticComp.origin.toString(), "->", slot.type);
|
||||
} else {
|
||||
assertAlways(false, "Bad slot type: " + slot.type);
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
assert(
|
||||
!slot.linkedNetwork || slot.linkedNetwork === currentNetwork,
|
||||
"Mismatching wire network on pin slot entity " +
|
||||
(slot.linkedNetwork ? slot.linkedNetwork.uid : "<empty>") +
|
||||
" vs " +
|
||||
currentNetwork.uid
|
||||
);
|
||||
if (!slot.linkedNetwork) {
|
||||
// This one is new
|
||||
VERBOSE_WIRES && logger.log(" Visited new slot:", staticComp.origin.toString());
|
||||
|
||||
// Add to the right list
|
||||
if (slot.type === enumPinSlotType.logicalEjector) {
|
||||
currentNetwork.providers.push({ entity: nextEntity, slot });
|
||||
} else if (slot.type === enumPinSlotType.logicalAcceptor) {
|
||||
currentNetwork.receivers.push({ entity: nextEntity, slot });
|
||||
} else {
|
||||
assertAlways(false, "unknown slot type:" + slot.type);
|
||||
}
|
||||
|
||||
// Register on the network
|
||||
currentNetwork.allSlots.push({ entity: nextEntity, slot });
|
||||
slot.linkedNetwork = currentNetwork;
|
||||
|
||||
// Specify where to search next
|
||||
newSearchDirections = [staticComp.localDirectionToWorld(slot.direction)];
|
||||
newSearchTile = staticComp.localTileToWorld(slot.pos);
|
||||
}
|
||||
}
|
||||
|
||||
if (newSearchTile) {
|
||||
// Find new surrounding wire targets
|
||||
const newTargets = this.findSurroundingWireTargets(newSearchTile, newSearchDirections);
|
||||
|
||||
VERBOSE_WIRES && logger.log(" Found", newTargets, "new targets to visit!");
|
||||
for (let i = 0; i < newTargets.length; ++i) {
|
||||
entitiesToVisit.push(newTargets[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
currentNetwork.providers.length > 0 &&
|
||||
(currentNetwork.wires.length > 0 || currentNetwork.receivers.length > 0)
|
||||
) {
|
||||
this.networks.push(currentNetwork);
|
||||
VERBOSE_WIRES && logger.log("Attached new network with uid", currentNetwork);
|
||||
} else {
|
||||
// Unregister network again
|
||||
for (let i = 0; i < currentNetwork.wires.length; ++i) {
|
||||
currentNetwork.wires[i].components.Wire.linkedNetwork = null;
|
||||
}
|
||||
|
||||
for (let i = 0; i < currentNetwork.allSlots.length; ++i) {
|
||||
currentNetwork.allSlots[i].slot.linkedNetwork = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds surrounding entities which are not yet assigned to a network
|
||||
* @param {Vector} tile
|
||||
* @param {Array<enumDirection>} directions
|
||||
* @returns {Array<any>}
|
||||
*/
|
||||
findSurroundingWireTargets(tile, directions) {
|
||||
let result = [];
|
||||
|
||||
VERBOSE_WIRES &&
|
||||
logger.log(" Searching for new targets at", tile.toString(), "and d=", directions);
|
||||
|
||||
for (let i = 0; i < directions.length; ++i) {
|
||||
const direction = directions[i];
|
||||
const offset = enumDirectionToVector[direction];
|
||||
const searchTile = tile.add(offset);
|
||||
|
||||
const contents = this.root.map.getLayersContentsMultipleXY(searchTile.x, searchTile.y);
|
||||
for (let k = 0; k < contents.length; ++k) {
|
||||
const entity = contents[k];
|
||||
const wireComp = entity.components.Wire;
|
||||
|
||||
// Check for wire
|
||||
if (wireComp && !wireComp.linkedNetwork) {
|
||||
// Wires accept connections from everywhere
|
||||
result.push({
|
||||
entity,
|
||||
});
|
||||
}
|
||||
|
||||
// Check for connected slots
|
||||
const pinComp = entity.components.WiredPins;
|
||||
if (pinComp) {
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
|
||||
// Go over all slots and see if they are connected
|
||||
const pinSlots = pinComp.slots;
|
||||
for (let j = 0; j < pinSlots.length; ++j) {
|
||||
const slot = pinSlots[j];
|
||||
|
||||
// Check if the position matches
|
||||
const pinPos = staticComp.localTileToWorld(slot.pos);
|
||||
if (!pinPos.equals(searchTile)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if the direction (inverted) matches
|
||||
const pinDirection = staticComp.localDirectionToWorld(slot.direction);
|
||||
if (pinDirection !== enumInvertedDirections[direction]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result.push({
|
||||
entity,
|
||||
slot,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VERBOSE_WIRES && logger.log(" -> Found", result.length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the wires network
|
||||
*/
|
||||
update() {
|
||||
if (this.needsRecompute) {
|
||||
this.recomputeWiresNetwork();
|
||||
}
|
||||
|
||||
// Re-compute values of all networks
|
||||
for (let i = 0; i < this.networks.length; ++i) {
|
||||
const network = this.networks[i];
|
||||
|
||||
// Reset conflicts
|
||||
network.valueConflict = false;
|
||||
|
||||
// Aggregate values of all senders
|
||||
const senders = network.providers;
|
||||
let value = null;
|
||||
for (let k = 0; k < senders.length; ++k) {
|
||||
const senderSlot = senders[k];
|
||||
const slotValue = senderSlot.slot.value;
|
||||
|
||||
// The first sender can just put in his value
|
||||
if (!value) {
|
||||
value = slotValue;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the slot is empty itself, just skip it
|
||||
if (!slotValue) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If there is already an value, compare if it matches ->
|
||||
// otherwise there is a conflict
|
||||
if (value.equals(slotValue)) {
|
||||
// All good
|
||||
continue;
|
||||
}
|
||||
|
||||
// There is a conflict, this means the value will be null anyways
|
||||
network.valueConflict = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Assign value
|
||||
if (network.valueConflict) {
|
||||
network.currentValue = null;
|
||||
} else {
|
||||
network.currentValue = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,11 +417,43 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
|
||||
const entity = contents[x][y];
|
||||
if (entity && entity.components.Wire) {
|
||||
const wireType = entity.components.Wire.type;
|
||||
const sprite = this.wireSprites[wireType];
|
||||
const wireComp = entity.components.Wire;
|
||||
const wireType = wireComp.type;
|
||||
const network = wireComp.linkedNetwork;
|
||||
|
||||
let opacity = 1;
|
||||
let spriteSet = this.wireSprites;
|
||||
|
||||
if (!network) {
|
||||
opacity = 0.3;
|
||||
} else {
|
||||
if (network.valueConflict) {
|
||||
opacity = 1;
|
||||
// TODO
|
||||
} else {
|
||||
if (network.currentValue) {
|
||||
if (
|
||||
network.currentValue.getItemType() === enumItemType.boolean &&
|
||||
// @ts-ignore
|
||||
network.currentValue.value === 0
|
||||
) {
|
||||
opacity = 0.5;
|
||||
} else {
|
||||
opacity = 1;
|
||||
}
|
||||
} else {
|
||||
opacity = 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const sprite = spriteSet[wireType];
|
||||
|
||||
assert(sprite, "Unknown wire type: " + wireType);
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
parameters.context.globalAlpha = opacity;
|
||||
staticComp.drawSpriteOnFullEntityBounds(parameters, sprite, 0);
|
||||
parameters.context.globalAlpha = 1;
|
||||
|
||||
if (G_IS_DEV && globalConfig.debug.renderWireRotations) {
|
||||
parameters.context.fillStyle = "red";
|
||||
@@ -68,6 +482,25 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DEBUG Rendering
|
||||
if (G_IS_DEV && globalConfig.debug.renderWireNetworkInfos) {
|
||||
if (entity) {
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
const wireComp = entity.components.Wire;
|
||||
|
||||
// Draw network info for wires
|
||||
if (wireComp && wireComp.linkedNetwork) {
|
||||
parameters.context.fillStyle = "red";
|
||||
parameters.context.font = "5px Tahoma";
|
||||
parameters.context.fillText(
|
||||
"W" + wireComp.linkedNetwork.uid,
|
||||
(staticComp.origin.x + 0.5) * globalConfig.tileSize,
|
||||
(staticComp.origin.y + 0.5) * globalConfig.tileSize
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,6 +519,8 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.log("Updating surrounding wire placement");
|
||||
|
||||
const metaWire = gMetaBuildingRegistry.findByClass(MetaWireBuilding);
|
||||
|
||||
// Compute affected area
|
||||
@@ -130,6 +565,13 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
targetStaticComp.rotation = rotation;
|
||||
metaWire.updateVariants(targetEntity, rotationVariant, defaultBuildingVariant);
|
||||
|
||||
// Update code as well
|
||||
targetStaticComp.code = getCodeFromBuildingData(
|
||||
metaWire,
|
||||
defaultBuildingVariant,
|
||||
rotationVariant
|
||||
);
|
||||
|
||||
// Make sure the chunks know about the update
|
||||
this.root.signals.entityChanged.dispatch(targetEntity);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||
import { enumLayer } from "../root";
|
||||
import { STOP_PROPAGATION } from "../../core/signal";
|
||||
import { drawRotatedSprite } from "../../core/draw_utils";
|
||||
import { GLOBAL_APP } from "../../core/globals";
|
||||
|
||||
export class WiredPinsSystem extends GameSystemWithFilter {
|
||||
constructor(root) {
|
||||
@@ -187,9 +188,23 @@ export class WiredPinsSystem extends GameSystemWithFilter {
|
||||
const value = slot.value;
|
||||
if (value) {
|
||||
const offset = new Vector(0, -5).rotated(effectiveRotation);
|
||||
|
||||
value.draw(worldPos.x + offset.x, worldPos.y + offset.y, parameters, 12);
|
||||
}
|
||||
|
||||
// Debug view
|
||||
if (G_IS_DEV && globalConfig.debug.renderWireNetworkInfos) {
|
||||
const offset = new Vector(0, -10).rotated(effectiveRotation);
|
||||
const network = slot.linkedNetwork;
|
||||
parameters.context.fillStyle = "blue";
|
||||
parameters.context.font = "5px Tahoma";
|
||||
parameters.context.textAlign = "center";
|
||||
parameters.context.fillText(
|
||||
network ? "S" + network.uid : "???",
|
||||
(tile.x + 0.5) * globalConfig.tileSize + offset.x,
|
||||
(tile.y + 0.5) * globalConfig.tileSize + offset.y
|
||||
);
|
||||
parameters.context.textAlign = "left";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user