add memory cell and rework logic construction (#24983)
* rework construction to be deconstructable, add memory cell * update textures * add code * add memory cell and ports, empty circuit * d --------- Co-authored-by: deltanedas <@deltanedas:kde.org>
@@ -0,0 +1,40 @@
|
|||||||
|
using Content.Server.DeviceLinking.Systems;
|
||||||
|
using Content.Shared.DeviceLinking;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Server.DeviceLinking.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Memory cell that sets the output to the input when enabled.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, Access(typeof(MemoryCellSystem))]
|
||||||
|
public sealed partial class MemoryCellComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Name of the input port.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public ProtoId<SinkPortPrototype> InputPort = "MemoryInput";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Name of the enable port.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public ProtoId<SinkPortPrototype> EnablePort = "MemoryEnable";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Name of the output port.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public ProtoId<SourcePortPrototype> OutputPort = "Output";
|
||||||
|
|
||||||
|
// State
|
||||||
|
[DataField]
|
||||||
|
public SignalState InputState = SignalState.Low;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public SignalState EnableState = SignalState.Low;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public bool LastOutput;
|
||||||
|
}
|
||||||
74
Content.Server/DeviceLinking/Systems/MemoryCellSystem.cs
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
using Content.Server.DeviceLinking.Components;
|
||||||
|
using Content.Server.DeviceLinking.Events;
|
||||||
|
using Content.Server.DeviceNetwork;
|
||||||
|
using Content.Shared.DeviceLinking;
|
||||||
|
|
||||||
|
namespace Content.Server.DeviceLinking.Systems;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles the control of output based on the input and enable ports.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class MemoryCellSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly DeviceLinkSystem _deviceLink = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<MemoryCellComponent, ComponentInit>(OnInit);
|
||||||
|
SubscribeLocalEvent<MemoryCellComponent, SignalReceivedEvent>(OnSignalReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float deltaTime)
|
||||||
|
{
|
||||||
|
base.Update(deltaTime);
|
||||||
|
|
||||||
|
var query = EntityQueryEnumerator<MemoryCellComponent, DeviceLinkSourceComponent>();
|
||||||
|
while (query.MoveNext(out var uid, out var comp, out var source))
|
||||||
|
{
|
||||||
|
if (comp.InputState == SignalState.Momentary)
|
||||||
|
comp.InputState = SignalState.Low;
|
||||||
|
if (comp.EnableState == SignalState.Momentary)
|
||||||
|
comp.EnableState = SignalState.Low;
|
||||||
|
|
||||||
|
UpdateOutput((uid, comp, source));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnInit(Entity<MemoryCellComponent> ent, ref ComponentInit args)
|
||||||
|
{
|
||||||
|
var (uid, comp) = ent;
|
||||||
|
_deviceLink.EnsureSinkPorts(uid, comp.InputPort, comp.EnablePort);
|
||||||
|
_deviceLink.EnsureSourcePorts(uid, comp.OutputPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSignalReceived(Entity<MemoryCellComponent> ent, ref SignalReceivedEvent args)
|
||||||
|
{
|
||||||
|
var state = SignalState.Momentary;
|
||||||
|
args.Data?.TryGetValue(DeviceNetworkConstants.LogicState, out state);
|
||||||
|
|
||||||
|
if (args.Port == ent.Comp.InputPort)
|
||||||
|
ent.Comp.InputState = state;
|
||||||
|
else if (args.Port == ent.Comp.EnablePort)
|
||||||
|
ent.Comp.EnableState = state;
|
||||||
|
|
||||||
|
UpdateOutput(ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateOutput(Entity<MemoryCellComponent, DeviceLinkSourceComponent?> ent)
|
||||||
|
{
|
||||||
|
if (!Resolve(ent, ref ent.Comp2))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ent.Comp1.EnableState == SignalState.Low)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var value = ent.Comp1.InputState != SignalState.Low;
|
||||||
|
if (value == ent.Comp1.LastOutput)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ent.Comp1.LastOutput = value;
|
||||||
|
_deviceLink.SendSignal(ent, ent.Comp1.OutputPort, value, ent.Comp2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -81,3 +81,8 @@ signal-port-description-logic-input-b = Second input of a logic gate.
|
|||||||
|
|
||||||
signal-port-name-logic-input = Input
|
signal-port-name-logic-input = Input
|
||||||
signal-port-description-logic-input = Input to the edge detector, cannot be a pulse signal.
|
signal-port-description-logic-input = Input to the edge detector, cannot be a pulse signal.
|
||||||
|
|
||||||
|
signal-port-description-logic-memory-input = Signal to load into the memory cell, when enabled.
|
||||||
|
|
||||||
|
signal-port-name-logic-enable = Enable
|
||||||
|
signal-port-description-logic-enable = Only loads the input signal into the memory cell when HIGH.
|
||||||
|
|||||||
@@ -93,6 +93,16 @@
|
|||||||
name: signal-port-name-logic-input
|
name: signal-port-name-logic-input
|
||||||
description: signal-port-description-logic-input
|
description: signal-port-description-logic-input
|
||||||
|
|
||||||
|
- type: sinkPort
|
||||||
|
id: MemoryInput
|
||||||
|
name: signal-port-name-logic-input
|
||||||
|
description: signal-port-description-logic-memory-input
|
||||||
|
|
||||||
|
- type: sinkPort
|
||||||
|
id: MemoryEnable
|
||||||
|
name: signal-port-name-logic-enable
|
||||||
|
description: signal-port-description-logic-enable
|
||||||
|
|
||||||
- type: sinkPort
|
- type: sinkPort
|
||||||
id: SetParticleDelta
|
id: SetParticleDelta
|
||||||
name: signal-port-name-set-particle-delta
|
name: signal-port-name-set-particle-delta
|
||||||
|
|||||||
@@ -1,12 +1,24 @@
|
|||||||
- type: entity
|
- type: entity
|
||||||
abstract: true
|
|
||||||
parent: BaseItem
|
parent: BaseItem
|
||||||
id: BaseLogicItem
|
id: LogicEmptyCircuit
|
||||||
|
name: empty circuit
|
||||||
|
description: Something seems to be missing.
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Devices/gates.rsi
|
sprite: Objects/Devices/gates.rsi
|
||||||
|
layers:
|
||||||
|
- state: base
|
||||||
- type: Anchorable
|
- type: Anchorable
|
||||||
- type: Rotatable
|
- type: Rotatable
|
||||||
|
- type: Construction
|
||||||
|
graph: LogicGate
|
||||||
|
node: empty
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
abstract: true
|
||||||
|
parent: LogicEmptyCircuit
|
||||||
|
id: BaseLogicItem
|
||||||
|
components:
|
||||||
- type: DeviceNetwork
|
- type: DeviceNetwork
|
||||||
deviceNetId: Wireless
|
deviceNetId: Wireless
|
||||||
receiveFrequencyId: BasicDevice
|
receiveFrequencyId: BasicDevice
|
||||||
@@ -23,6 +35,7 @@
|
|||||||
- type: Sprite
|
- type: Sprite
|
||||||
layers:
|
layers:
|
||||||
- state: base
|
- state: base
|
||||||
|
- state: logic
|
||||||
- state: or
|
- state: or
|
||||||
map: [ "enum.LogicGateLayers.Gate" ]
|
map: [ "enum.LogicGateLayers.Gate" ]
|
||||||
- type: LogicGate
|
- type: LogicGate
|
||||||
@@ -38,7 +51,6 @@
|
|||||||
lastSignals:
|
lastSignals:
|
||||||
Output: false
|
Output: false
|
||||||
- type: Construction
|
- type: Construction
|
||||||
graph: LogicGate
|
|
||||||
node: logic_gate
|
node: logic_gate
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
- type: GenericVisualizer
|
- type: GenericVisualizer
|
||||||
@@ -124,7 +136,9 @@
|
|||||||
description: Splits rising and falling edges into unique pulses and detects how edgy you are.
|
description: Splits rising and falling edges into unique pulses and detects how edgy you are.
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
state: edge_detector
|
layers:
|
||||||
|
- state: base
|
||||||
|
- state: edge_detector
|
||||||
- type: EdgeDetector
|
- type: EdgeDetector
|
||||||
- type: DeviceLinkSink
|
- type: DeviceLinkSink
|
||||||
ports:
|
ports:
|
||||||
@@ -137,7 +151,6 @@
|
|||||||
OutputHigh: false
|
OutputHigh: false
|
||||||
OutputLow: false
|
OutputLow: false
|
||||||
- type: Construction
|
- type: Construction
|
||||||
graph: LogicGate
|
|
||||||
node: edge_detector
|
node: edge_detector
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
@@ -147,7 +160,9 @@
|
|||||||
description: Generates signals in response to powernet changes. Can be cycled between cable voltages.
|
description: Generates signals in response to powernet changes. Can be cycled between cable voltages.
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
state: power_sensor
|
layers:
|
||||||
|
- state: base
|
||||||
|
- state: power_sensor
|
||||||
- type: PowerSensor
|
- type: PowerSensor
|
||||||
- type: PowerSwitchable
|
- type: PowerSwitchable
|
||||||
examineText: power-sensor-voltage-examine
|
examineText: power-sensor-voltage-examine
|
||||||
@@ -183,5 +198,25 @@
|
|||||||
PowerCharging: false
|
PowerCharging: false
|
||||||
PowerDischarging: false
|
PowerDischarging: false
|
||||||
- type: Construction
|
- type: Construction
|
||||||
graph: LogicGate
|
|
||||||
node: power_sensor
|
node: power_sensor
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: BaseLogicItem
|
||||||
|
id: MemoryCell
|
||||||
|
name: memory cell
|
||||||
|
description: A D-Latch circuit that stores a signal which can be changed depending on input and enable ports.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
layers:
|
||||||
|
- state: base
|
||||||
|
- state: memory_cell
|
||||||
|
- type: MemoryCell
|
||||||
|
- type: DeviceLinkSink
|
||||||
|
ports:
|
||||||
|
- MemoryInput
|
||||||
|
- MemoryEnable
|
||||||
|
- type: DeviceLinkSource
|
||||||
|
ports:
|
||||||
|
- Output
|
||||||
|
- type: Construction
|
||||||
|
node: memory_cell
|
||||||
|
|||||||
@@ -4,38 +4,104 @@
|
|||||||
graph:
|
graph:
|
||||||
- node: start
|
- node: start
|
||||||
edges:
|
edges:
|
||||||
- to: logic_gate
|
- to: empty
|
||||||
steps:
|
steps:
|
||||||
- material: Steel
|
- material: Steel
|
||||||
amount: 3
|
amount: 3
|
||||||
doAfter: 1
|
doAfter: 1
|
||||||
|
- node: empty
|
||||||
|
entity: LogicEmptyCircuit
|
||||||
|
edges:
|
||||||
|
- to: start
|
||||||
|
steps:
|
||||||
|
- tool: Screwing
|
||||||
|
doAfter: 2
|
||||||
|
completed:
|
||||||
|
- !type:SpawnPrototype
|
||||||
|
prototype: SheetSteel1
|
||||||
|
amount: 3
|
||||||
|
- !type:DeleteEntity {}
|
||||||
|
- to: logic_gate
|
||||||
|
steps:
|
||||||
- material: Cable
|
- material: Cable
|
||||||
amount: 2
|
amount: 2
|
||||||
doAfter: 1
|
doAfter: 1
|
||||||
- to: edge_detector
|
- to: edge_detector
|
||||||
steps:
|
steps:
|
||||||
- material: Steel
|
- material: Glass
|
||||||
amount: 3
|
amount: 2
|
||||||
doAfter: 1
|
doAfter: 1
|
||||||
- material: Cable
|
- material: Cable
|
||||||
amount: 2
|
amount: 2
|
||||||
doAfter: 1
|
doAfter: 1
|
||||||
- to: power_sensor
|
- to: power_sensor
|
||||||
steps:
|
steps:
|
||||||
- material: Steel
|
|
||||||
amount: 3
|
|
||||||
doAfter: 1
|
|
||||||
- material: Cable
|
|
||||||
amount: 2
|
|
||||||
doAfter: 1
|
|
||||||
- tag: Multitool
|
- tag: Multitool
|
||||||
icon:
|
icon:
|
||||||
sprite: Objects/Tools/multitool.rsi
|
sprite: Objects/Tools/multitool.rsi
|
||||||
state: icon
|
state: icon
|
||||||
name: a multitool
|
name: a multitool
|
||||||
|
- material: Cable
|
||||||
|
amount: 2
|
||||||
|
doAfter: 1
|
||||||
|
- to: memory_cell
|
||||||
|
steps:
|
||||||
|
- tag: CapacitorStockPart
|
||||||
|
icon:
|
||||||
|
sprite: Objects/Misc/stock_parts.rsi
|
||||||
|
state: capacitor
|
||||||
|
name: a capacitor
|
||||||
|
- material: Cable
|
||||||
|
amount: 2
|
||||||
|
doAfter: 1
|
||||||
- node: logic_gate
|
- node: logic_gate
|
||||||
entity: LogicGateOr
|
entity: LogicGateOr
|
||||||
|
edges:
|
||||||
|
- to: empty
|
||||||
|
steps:
|
||||||
|
- tool: Prying
|
||||||
|
doAfter: 2
|
||||||
|
completed:
|
||||||
|
- !type:SpawnPrototype
|
||||||
|
prototype: CableApcStack1
|
||||||
|
amount: 2
|
||||||
- node: edge_detector
|
- node: edge_detector
|
||||||
entity: EdgeDetector
|
entity: EdgeDetector
|
||||||
|
edges:
|
||||||
|
- to: empty
|
||||||
|
steps:
|
||||||
|
- tool: Prying
|
||||||
|
doAfter: 2
|
||||||
|
completed:
|
||||||
|
- !type:SpawnPrototype
|
||||||
|
prototype: SheetGlass1
|
||||||
|
amount: 2
|
||||||
|
- !type:SpawnPrototype
|
||||||
|
prototype: CableApcStack1
|
||||||
|
amount: 2
|
||||||
- node: power_sensor
|
- node: power_sensor
|
||||||
entity: PowerSensor
|
entity: PowerSensor
|
||||||
|
edges:
|
||||||
|
- to: empty
|
||||||
|
steps:
|
||||||
|
- tool: Prying
|
||||||
|
doAfter: 2
|
||||||
|
completed:
|
||||||
|
- !type:SpawnPrototype
|
||||||
|
prototype: Multitool
|
||||||
|
- !type:SpawnPrototype
|
||||||
|
prototype: CableApcStack1
|
||||||
|
amount: 2
|
||||||
|
- node: memory_cell
|
||||||
|
entity: MemoryCell
|
||||||
|
edges:
|
||||||
|
- to: empty
|
||||||
|
steps:
|
||||||
|
- tool: Prying
|
||||||
|
doAfter: 2
|
||||||
|
completed:
|
||||||
|
- !type:SpawnPrototype
|
||||||
|
prototype: CapacitorStockPart
|
||||||
|
- !type:SpawnPrototype
|
||||||
|
prototype: CableApcStack1
|
||||||
|
amount: 2
|
||||||
|
|||||||
@@ -41,3 +41,14 @@
|
|||||||
description: A power network checking device for signals.
|
description: A power network checking device for signals.
|
||||||
icon: { sprite: Objects/Devices/gates.rsi, state: power_sensor }
|
icon: { sprite: Objects/Devices/gates.rsi, state: power_sensor }
|
||||||
objectType: Item
|
objectType: Item
|
||||||
|
|
||||||
|
- type: construction
|
||||||
|
name: memory cell
|
||||||
|
id: MemoryCell
|
||||||
|
graph: LogicGate
|
||||||
|
startNode: start
|
||||||
|
targetNode: memory_cell
|
||||||
|
category: construction-category-tools
|
||||||
|
description: A memory cell for signals.
|
||||||
|
icon: { sprite: Objects/Devices/gates.rsi, state: memory_cell }
|
||||||
|
objectType: Item
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 6.9 KiB |
BIN
Resources/Textures/Objects/Devices/gates.rsi/logic.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
Resources/Textures/Objects/Devices/gates.rsi/memory_cell.png
Normal file
|
After Width: | Height: | Size: 228 B |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"license": "CC-BY-SA-3.0",
|
"license": "CC-BY-SA-3.0",
|
||||||
"copyright": "or.png originally created by Kevin Zheng, 2022. All are modified by deltanedas (github) for SS14, 2023.",
|
"copyright": "or.png originally created by Kevin Zheng, 2022. All are modified by deltanedas (github) for SS14, 2024.",
|
||||||
"size": {
|
"size": {
|
||||||
"x": 32,
|
"x": 32,
|
||||||
"y": 32
|
"y": 32
|
||||||
@@ -10,6 +10,9 @@
|
|||||||
{
|
{
|
||||||
"name": "base"
|
"name": "base"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "logic"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "or"
|
"name": "or"
|
||||||
},
|
},
|
||||||
@@ -36,6 +39,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "power_sensor"
|
"name": "power_sensor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "memory_cell"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 6.9 KiB |