mirror of
https://github.com/tobspr/shapez.io.git
synced 2026-03-02 03:39:21 +00:00
Add constant signal emitters
This commit is contained in:
@@ -5,11 +5,7 @@ import { BasicSerializableObject } from "../savegame/serialization";
|
||||
export const enumItemType = {
|
||||
shape: "shape",
|
||||
color: "color",
|
||||
positiveEnergy: "positiveEnergy",
|
||||
negativeEnergy: "negativeEnergy",
|
||||
|
||||
// Can be used for filters
|
||||
genericEnergy: "genericEnergy",
|
||||
boolean: "boolean",
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
51
src/js/game/buildings/constant_signal.js
Normal file
51
src/js/game/buildings/constant_signal.js
Normal file
@@ -0,0 +1,51 @@
|
||||
import { enumDirection, Vector } from "../../core/vector";
|
||||
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
|
||||
import { Entity } from "../entity";
|
||||
import { MetaBuilding } from "../meta_building";
|
||||
import { enumLayer, GameRoot } from "../root";
|
||||
import { ConstantSignalComponent } from "../components/constant_signal";
|
||||
|
||||
export class MetaConstantSignalBuilding extends MetaBuilding {
|
||||
constructor() {
|
||||
super("constant_signal");
|
||||
}
|
||||
|
||||
getSilhouetteColor() {
|
||||
return "#2bafda";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
*/
|
||||
getIsUnlocked(root) {
|
||||
// @todo
|
||||
return G_IS_DEV;
|
||||
}
|
||||
|
||||
getLayer() {
|
||||
return enumLayer.wires;
|
||||
}
|
||||
|
||||
getDimensions() {
|
||||
return new Vector(1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the entity at the given location
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
setupEntityComponents(entity) {
|
||||
entity.addComponent(
|
||||
new WiredPinsComponent({
|
||||
slots: [
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.top,
|
||||
type: enumPinSlotType.logicalEjector,
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
entity.addComponent(new ConstantSignalComponent({}));
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { StorageComponent } from "./components/storage";
|
||||
import { WiredPinsComponent } from "./components/wired_pins";
|
||||
import { BeltUnderlaysComponent } from "./components/belt_underlays";
|
||||
import { WireComponent } from "./components/wire";
|
||||
import { ConstantSignalComponent } from "./components/constant_signal";
|
||||
|
||||
export function initComponentRegistry() {
|
||||
gComponentRegistry.register(StaticMapEntityComponent);
|
||||
@@ -25,6 +26,7 @@ export function initComponentRegistry() {
|
||||
gComponentRegistry.register(WiredPinsComponent);
|
||||
gComponentRegistry.register(BeltUnderlaysComponent);
|
||||
gComponentRegistry.register(WireComponent);
|
||||
gComponentRegistry.register(ConstantSignalComponent);
|
||||
|
||||
// IMPORTANT ^^^^^ UPDATE ENTITY COMPONENT STORAGE AFTERWARDS
|
||||
|
||||
|
||||
30
src/js/game/components/constant_signal.js
Normal file
30
src/js/game/components/constant_signal.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import { gItemRegistry } from "../../core/global_registries";
|
||||
import { types } from "../../savegame/serialization";
|
||||
import { Component } from "../component";
|
||||
import { BaseItem } from "../base_item";
|
||||
|
||||
export class ConstantSignalComponent extends Component {
|
||||
static getId() {
|
||||
return "ConstantSignal";
|
||||
}
|
||||
|
||||
static getSchema() {
|
||||
return {
|
||||
signal: types.nullable(types.obj(gItemRegistry)),
|
||||
};
|
||||
}
|
||||
|
||||
duplicateWithoutContents() {
|
||||
return new ConstantSignalComponent({ signal: this.signal });
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {object} param0
|
||||
* @param {BaseItem=} param0.signal The signal to store
|
||||
*/
|
||||
constructor({ signal = null }) {
|
||||
super();
|
||||
this.signal = signal;
|
||||
}
|
||||
}
|
||||
@@ -87,25 +87,7 @@ export class ItemAcceptorComponent extends Component {
|
||||
*/
|
||||
canAcceptItem(slotIndex, item) {
|
||||
const slot = this.slots[slotIndex];
|
||||
return this.filterMatches(slot.filter, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the given filter matches
|
||||
* @param {enumItemType|null} filter
|
||||
* @param {BaseItem} item
|
||||
*/
|
||||
filterMatches(filter, item) {
|
||||
if (!filter) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const itemType = item.getItemType();
|
||||
if (filter === enumItemType.genericEnergy) {
|
||||
return itemType === enumItemType.positiveEnergy || itemType === enumItemType.negativeEnergy;
|
||||
}
|
||||
|
||||
return itemType === filter;
|
||||
return !slot.filter || slot.filter === item.getItemType();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,6 +11,7 @@ import { StorageComponent } from "./components/storage";
|
||||
import { UndergroundBeltComponent } from "./components/underground_belt";
|
||||
import { WiredPinsComponent } from "./components/wired_pins";
|
||||
import { WireComponent } from "./components/wire";
|
||||
import { ConstantSignalComponent } from "./components/constant_signal";
|
||||
/* typehints:end */
|
||||
|
||||
/**
|
||||
@@ -57,6 +58,9 @@ export class EntityComponentStorage {
|
||||
/** @type {WireComponent} */
|
||||
this.Wire;
|
||||
|
||||
/** @type {ConstantSignalComponent} */
|
||||
this.ConstantSignal;
|
||||
|
||||
/* typehints:end */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import { StorageSystem } from "./systems/storage";
|
||||
import { WiredPinsSystem } from "./systems/wired_pins";
|
||||
import { BeltUnderlaysSystem } from "./systems/belt_underlays";
|
||||
import { WireSystem } from "./systems/wire";
|
||||
import { ConstantSignalSystem } from "./systems/constant_signal";
|
||||
|
||||
const logger = createLogger("game_system_manager");
|
||||
|
||||
@@ -68,6 +69,9 @@ export class GameSystemManager {
|
||||
/** @type {WireSystem} */
|
||||
wire: null,
|
||||
|
||||
/** @type {ConstantSignalSystem} */
|
||||
constantSignal: null,
|
||||
|
||||
/* typehints:end */
|
||||
};
|
||||
this.systemUpdateOrder = [];
|
||||
@@ -108,6 +112,8 @@ export class GameSystemManager {
|
||||
|
||||
add("beltUnderlays", BeltUnderlaysSystem);
|
||||
|
||||
add("constantSignal", ConstantSignalSystem);
|
||||
|
||||
// IMPORTANT: Must be after belt system since belt system can change the
|
||||
// orientation of an entity after it is placed -> the item acceptor cache
|
||||
// then would be invalid
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { enumLayer } from "../../root";
|
||||
import { HUDBaseToolbar } from "./base_toolbar";
|
||||
import { MetaWireBuilding } from "../../buildings/wire";
|
||||
import { MetaConstantSignalBuilding } from "../../buildings/constant_signal";
|
||||
|
||||
const supportedBuildings = [MetaWireBuilding];
|
||||
const supportedBuildings = [MetaWireBuilding, MetaConstantSignalBuilding];
|
||||
|
||||
export class HUDWiresToolbar extends HUDBaseToolbar {
|
||||
constructor(root) {
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { gItemRegistry } from "../core/global_registries";
|
||||
import { ShapeItem } from "./items/shape_item";
|
||||
import { ColorItem } from "./items/color_item";
|
||||
import { PositiveEnergyItem } from "./items/positive_energy_item";
|
||||
import { NegativeEnergyItem } from "./items/negative_energy_item";
|
||||
import { BooleanItem } from "./items/boolean_item";
|
||||
|
||||
export function initItemRegistry() {
|
||||
gItemRegistry.register(ShapeItem);
|
||||
gItemRegistry.register(ColorItem);
|
||||
gItemRegistry.register(PositiveEnergyItem);
|
||||
gItemRegistry.register(NegativeEnergyItem);
|
||||
gItemRegistry.register(BooleanItem);
|
||||
}
|
||||
|
||||
53
src/js/game/items/boolean_item.js
Normal file
53
src/js/game/items/boolean_item.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import { DrawParameters } from "../../core/draw_parameters";
|
||||
import { Loader } from "../../core/loader";
|
||||
import { types } from "../../savegame/serialization";
|
||||
import { BaseItem, enumItemType } from "../base_item";
|
||||
|
||||
export class BooleanItem extends BaseItem {
|
||||
static getId() {
|
||||
return "boolean_item";
|
||||
}
|
||||
|
||||
static getSchema() {
|
||||
return types.uint;
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
deserialize(data) {
|
||||
this.value = data;
|
||||
}
|
||||
|
||||
getItemType() {
|
||||
return enumItemType.boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} value
|
||||
*/
|
||||
constructor(value) {
|
||||
super();
|
||||
this.value = value ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {number} size
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
draw(x, y, parameters, size = 12) {
|
||||
let sprite;
|
||||
if (this.value) {
|
||||
sprite = Loader.getSprite("sprites/wires/boolean_true.png");
|
||||
} else {
|
||||
sprite = Loader.getSprite("sprites/wires/boolean_false.png");
|
||||
}
|
||||
sprite.drawCachedCentered(parameters, x, y, size * 1.5);
|
||||
}
|
||||
}
|
||||
|
||||
export const BOOL_FALSE_SINGLETON = new BooleanItem(0);
|
||||
export const BOOL_TRUE_SINGLETON = new BooleanItem(1);
|
||||
@@ -1,37 +0,0 @@
|
||||
import { DrawParameters } from "../../core/draw_parameters";
|
||||
import { Loader } from "../../core/loader";
|
||||
import { types } from "../../savegame/serialization";
|
||||
import { BaseItem, enumItemType } from "../base_item";
|
||||
|
||||
export class NegativeEnergyItem extends BaseItem {
|
||||
static getId() {
|
||||
return "negative_energy";
|
||||
}
|
||||
|
||||
static getSchema() {
|
||||
return types.uint;
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
deserialize(data) {}
|
||||
|
||||
getItemType() {
|
||||
return enumItemType.negativeEnergy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {number} size
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
draw(x, y, parameters, size = 12) {
|
||||
const sprite = Loader.getSprite("sprites/wires/negative_energy.png");
|
||||
sprite.drawCachedCentered(parameters, x, y, size * 1.5);
|
||||
}
|
||||
}
|
||||
|
||||
export const NEGATIVE_ENERGY_ITEM_SINGLETON = new NegativeEnergyItem();
|
||||
@@ -1,37 +0,0 @@
|
||||
import { DrawParameters } from "../../core/draw_parameters";
|
||||
import { Loader } from "../../core/loader";
|
||||
import { types } from "../../savegame/serialization";
|
||||
import { BaseItem, enumItemType } from "../base_item";
|
||||
|
||||
export class PositiveEnergyItem extends BaseItem {
|
||||
static getId() {
|
||||
return "positive_energy";
|
||||
}
|
||||
|
||||
static getSchema() {
|
||||
return types.uint;
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
deserialize(data) {}
|
||||
|
||||
getItemType() {
|
||||
return enumItemType.positiveEnergy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {number} size
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
draw(x, y, parameters, size = 12) {
|
||||
const sprite = Loader.getSprite("sprites/wires/positive_energy.png");
|
||||
sprite.drawCachedCentered(parameters, x, y, size * 1.5);
|
||||
}
|
||||
}
|
||||
|
||||
export const POSITIVE_ENERGY_ITEM_SINGLETON = new PositiveEnergyItem();
|
||||
@@ -56,6 +56,7 @@ export const KEYMAPPINGS = {
|
||||
trash: { keyCode: key("0") },
|
||||
|
||||
wire: { keyCode: key("1") },
|
||||
constant_signal: { keyCode: key("2") },
|
||||
},
|
||||
|
||||
placement: {
|
||||
|
||||
@@ -15,6 +15,7 @@ import { enumUndergroundBeltVariants, MetaUndergroundBeltBuilding } from "./buil
|
||||
import { MetaWireBuilding } from "./buildings/wire";
|
||||
import { gBuildingVariants, registerBuildingVariant } from "./building_codes";
|
||||
import { defaultBuildingVariant } from "./meta_building";
|
||||
import { MetaConstantSignalBuilding } from "./buildings/constant_signal";
|
||||
|
||||
const logger = createLogger("building_registry");
|
||||
|
||||
@@ -31,6 +32,7 @@ export function initMetaBuildingRegistry() {
|
||||
gMetaBuildingRegistry.register(MetaUndergroundBeltBuilding);
|
||||
gMetaBuildingRegistry.register(MetaHubBuilding);
|
||||
gMetaBuildingRegistry.register(MetaWireBuilding);
|
||||
gMetaBuildingRegistry.register(MetaConstantSignalBuilding);
|
||||
|
||||
// Belt
|
||||
registerBuildingVariant(1, MetaBeltBaseBuilding, defaultBuildingVariant, 0);
|
||||
@@ -86,6 +88,9 @@ export function initMetaBuildingRegistry() {
|
||||
registerBuildingVariant(29, MetaWireBuilding, defaultBuildingVariant, 2);
|
||||
registerBuildingVariant(30, MetaWireBuilding, defaultBuildingVariant, 3);
|
||||
|
||||
// Constant signal
|
||||
registerBuildingVariant(31, MetaConstantSignalBuilding);
|
||||
|
||||
// Propagate instances
|
||||
for (const key in gBuildingVariants) {
|
||||
gBuildingVariants[key].metaInstance = gMetaBuildingRegistry.findByClass(
|
||||
|
||||
98
src/js/game/systems/constant_signal.js
Normal file
98
src/js/game/systems/constant_signal.js
Normal file
@@ -0,0 +1,98 @@
|
||||
import { ConstantSignalComponent } from "../components/constant_signal";
|
||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||
import { Entity } from "../entity";
|
||||
import { DialogWithForm } from "../../core/modal_dialog_elements";
|
||||
import { FormElementInput } from "../../core/modal_dialog_forms";
|
||||
import { enumColors } from "../colors";
|
||||
import { ColorItem } from "../items/color_item";
|
||||
import trim from "trim";
|
||||
import { BOOL_TRUE_SINGLETON, BOOL_FALSE_SINGLETON } from "../items/boolean_item";
|
||||
import { ShapeDefinition } from "../shape_definition";
|
||||
import { ShapeItem } from "../items/shape_item";
|
||||
|
||||
export class ConstantSignalSystem extends GameSystemWithFilter {
|
||||
constructor(root) {
|
||||
super(root, [ConstantSignalComponent]);
|
||||
|
||||
this.root.signals.entityManuallyPlaced.add(this.querySigalValue, this);
|
||||
}
|
||||
|
||||
update() {
|
||||
// Set signals
|
||||
for (let i = 0; i < this.allEntities.length; ++i) {
|
||||
const entity = this.allEntities[i];
|
||||
const pinsComp = entity.components.WiredPins;
|
||||
const signalComp = entity.components.ConstantSignal;
|
||||
pinsComp.slots[0].value = signalComp.signal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the entity to enter a valid signal code
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
querySigalValue(entity) {
|
||||
if (!entity.components.ConstantSignal) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ok, query, but also save the uid because it could get stale
|
||||
const uid = entity.uid;
|
||||
|
||||
const signalValueInput = new FormElementInput({
|
||||
id: "markerName",
|
||||
label: null,
|
||||
placeholder: "",
|
||||
defaultValue: "",
|
||||
validator: val => this.parseSignalCode(val),
|
||||
});
|
||||
const dialog = new DialogWithForm({
|
||||
app: this.root.app,
|
||||
title: "Set Signal",
|
||||
desc: "Enter a shape code, color or '0' or '1'",
|
||||
formElements: [signalValueInput],
|
||||
buttons: ["cancel", "ok:good"],
|
||||
});
|
||||
this.root.hud.parts.dialogs.internalShowDialog(dialog);
|
||||
dialog.buttonSignals.ok.add(() => {
|
||||
if (!this.root || !this.root.entityMgr) {
|
||||
// Game got stopped
|
||||
return;
|
||||
}
|
||||
|
||||
const entityRef = this.root.entityMgr.findByUid(uid, false);
|
||||
if (!entityRef) {
|
||||
// outdated
|
||||
return;
|
||||
}
|
||||
|
||||
const constantComp = entityRef.components.ConstantSignal;
|
||||
if (!constantComp) {
|
||||
// no longer interesting
|
||||
return;
|
||||
}
|
||||
|
||||
constantComp.signal = this.parseSignalCode(signalValueInput.getValue());
|
||||
});
|
||||
}
|
||||
|
||||
parseSignalCode(code) {
|
||||
code = trim(code);
|
||||
if (enumColors[code]) {
|
||||
return new ColorItem(code);
|
||||
}
|
||||
if (code === "1" || code === "true") {
|
||||
return BOOL_TRUE_SINGLETON;
|
||||
}
|
||||
|
||||
if (code === "0" || code === "false") {
|
||||
return BOOL_FALSE_SINGLETON;
|
||||
}
|
||||
|
||||
if (ShapeDefinition.isValidShortKey(code)) {
|
||||
return new ShapeItem(this.root.shapeDefinitionMgr.getShapeFromShortKey(code));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -183,7 +183,7 @@ export class WiredPinsSystem extends GameSystemWithFilter {
|
||||
// Draw contained item to visualize whats emitted
|
||||
const value = slot.value;
|
||||
if (value) {
|
||||
value.draw(worldPos.x, worldPos.y, parameters, 12);
|
||||
value.draw(worldPos.x, worldPos.y, parameters, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user