Adding a random gate (#41627)
* Added random gate * minor edit * cleaning up my shit after trying to do something faster * new lines * some changes * joke * UI * Long Division * Dont use ctrl + x in 3 am * I hope these are the final touches * One thing, I don't know why * noname commit * no way, 1kk of code lines edit * sudo rm -rf ... and something there... * update * sometimes its sad
This commit is contained in:
parent
56b3ef91d7
commit
0b2c9671d6
|
|
@ -0,0 +1,5 @@
|
||||||
|
using Content.Shared.DeviceLinking.Systems;
|
||||||
|
|
||||||
|
namespace Content.Client.DeviceLinking.Systems;
|
||||||
|
|
||||||
|
public sealed class RandomGateSystem : SharedRandomGateSystem;
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
using Content.Shared.DeviceLinking;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
|
|
||||||
|
namespace Content.Client.DeviceLinking.UI;
|
||||||
|
|
||||||
|
[UsedImplicitly]
|
||||||
|
public sealed class RandomGateBoundUserInterface : BoundUserInterface
|
||||||
|
{
|
||||||
|
private RandomGateSetupWindow? _window;
|
||||||
|
|
||||||
|
public RandomGateBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { }
|
||||||
|
|
||||||
|
protected override void Open()
|
||||||
|
{
|
||||||
|
base.Open();
|
||||||
|
_window = this.CreateWindow<RandomGateSetupWindow>();
|
||||||
|
_window.OnApplyPressed += OnProbabilityChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnProbabilityChanged(string value)
|
||||||
|
{
|
||||||
|
if (!float.TryParse(value, out var probability))
|
||||||
|
return;
|
||||||
|
|
||||||
|
SendPredictedMessage(new RandomGateProbabilityChangedMessage(probability));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void UpdateState(BoundUserInterfaceState state)
|
||||||
|
{
|
||||||
|
base.UpdateState(state);
|
||||||
|
if (state is not RandomGateBoundUserInterfaceState castState || _window == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_window.SetProbability(castState.SuccessProbability * 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||||
|
Title="{Loc 'random-gate-menu-setup'}"
|
||||||
|
MinSize="260 115">
|
||||||
|
<BoxContainer Orientation="Vertical" Margin="5" SeparationOverride="10">
|
||||||
|
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||||
|
<Label Text="{Loc 'random-gate-menu-settings'}" VerticalAlignment="Center" />
|
||||||
|
<Control HorizontalExpand="True" />
|
||||||
|
<LineEdit Name="ProbabilityInput" MinSize="70 0" />
|
||||||
|
</BoxContainer>
|
||||||
|
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||||
|
<Control HorizontalExpand="True" />
|
||||||
|
<Button Name="ApplyButton"
|
||||||
|
Text="{Loc 'random-gate-menu-apply'}"
|
||||||
|
HorizontalAlignment="Right" />
|
||||||
|
</BoxContainer>
|
||||||
|
</BoxContainer>
|
||||||
|
</controls:FancyWindow>
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
using Content.Client.UserInterface.Controls;
|
||||||
|
using Robust.Client.AutoGenerated;
|
||||||
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
|
||||||
|
namespace Content.Client.DeviceLinking.UI;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Window for setting up the random gate probability.
|
||||||
|
/// </summary>
|
||||||
|
[GenerateTypedNameReferences]
|
||||||
|
public sealed partial class RandomGateSetupWindow : FancyWindow
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when the "Apply" button is pressed.
|
||||||
|
/// </summary>
|
||||||
|
public event Action<string>? OnApplyPressed;
|
||||||
|
|
||||||
|
public RandomGateSetupWindow()
|
||||||
|
{
|
||||||
|
RobustXamlLoader.Load(this);
|
||||||
|
ApplyButton.OnPressed += _ => OnApplyPressed?.Invoke(ProbabilityInput.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetProbability(float probability)
|
||||||
|
{
|
||||||
|
ProbabilityInput.Text = probability.ToString("0.00");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
using Content.Shared.DeviceLinking.Components;
|
||||||
|
using Content.Shared.DeviceLinking.Events;
|
||||||
|
using Content.Shared.DeviceLinking.Systems;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
|
namespace Content.Server.DeviceLinking.Systems;
|
||||||
|
|
||||||
|
public sealed class RandomGateSystem : SharedRandomGateSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly DeviceLinkSystem _deviceLink = default!;
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<RandomGateComponent, SignalReceivedEvent>(OnSignalReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSignalReceived(Entity<RandomGateComponent> ent, ref SignalReceivedEvent args)
|
||||||
|
{
|
||||||
|
if (args.Port != ent.Comp.InputPort)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var output = _random.Prob(ent.Comp.SuccessProbability);
|
||||||
|
if (output != ent.Comp.LastOutput)
|
||||||
|
{
|
||||||
|
ent.Comp.LastOutput = output;
|
||||||
|
Dirty(ent);
|
||||||
|
_deviceLink.SendSignal(ent.Owner, ent.Comp.OutputPort, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.DeviceLinking.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A component for a random gate, which outputs a signal with a given probability.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
|
public sealed partial class RandomGateComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The input port for receiving signals.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public ProtoId<SinkPortPrototype> InputPort = "RandomGateInput";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The output port for sending signals.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public ProtoId<SourcePortPrototype> OutputPort = "Output";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The last output state of the gate.
|
||||||
|
/// </summary>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public bool LastOutput;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The probability (0.0 to 1.0) that the gate will output a signal.
|
||||||
|
/// </summary>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public float SuccessProbability = 0.5f;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.DeviceLinking;
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class RandomGateBoundUserInterfaceState(float successProbability) : BoundUserInterfaceState
|
||||||
|
{
|
||||||
|
public float SuccessProbability = successProbability;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class RandomGateProbabilityChangedMessage(float probability) : BoundUserInterfaceMessage
|
||||||
|
{
|
||||||
|
public float Probability = probability;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum RandomGateUiKey : byte
|
||||||
|
{
|
||||||
|
Key
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
using Content.Shared.DeviceLinking.Components;
|
||||||
|
using Content.Shared.UserInterface;
|
||||||
|
|
||||||
|
namespace Content.Shared.DeviceLinking.Systems;
|
||||||
|
|
||||||
|
public abstract class SharedRandomGateSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
SubscribeLocalEvent<RandomGateComponent, AfterActivatableUIOpenEvent>(OnAfterActivatableUIOpen);
|
||||||
|
SubscribeLocalEvent<RandomGateComponent, RandomGateProbabilityChangedMessage>(OnProbabilityChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnAfterActivatableUIOpen(Entity<RandomGateComponent> ent, ref AfterActivatableUIOpenEvent args)
|
||||||
|
{
|
||||||
|
UpdateUI(ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnProbabilityChanged(Entity<RandomGateComponent> ent, ref RandomGateProbabilityChangedMessage args)
|
||||||
|
{
|
||||||
|
ent.Comp.SuccessProbability = Math.Clamp(args.Probability, 0f, 100f) / 100f;
|
||||||
|
Dirty(ent);
|
||||||
|
UpdateUI(ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateUI(Entity<RandomGateComponent> ent)
|
||||||
|
{
|
||||||
|
if (!_ui.HasUi(ent.Owner, RandomGateUiKey.Key))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_ui.SetUiState(ent.Owner, RandomGateUiKey.Key, new RandomGateBoundUserInterfaceState(ent.Comp.SuccessProbability));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
random-gate-menu-settings = Success Probability (%):
|
||||||
|
random-gate-menu-setup = Random Gate Setup
|
||||||
|
random-gate-menu-apply = Apply
|
||||||
|
|
@ -86,3 +86,6 @@ signal-port-description-logic-memory-input = Signal to load into the memory cell
|
||||||
|
|
||||||
signal-port-name-logic-enable = Enable
|
signal-port-name-logic-enable = Enable
|
||||||
signal-port-description-logic-enable = Only loads the input signal into the memory cell when HIGH.
|
signal-port-description-logic-enable = Only loads the input signal into the memory cell when HIGH.
|
||||||
|
|
||||||
|
signal-port-name-logic-random-input = Input Signal
|
||||||
|
signal-port-description-logic-random-input = Receives any signal to trigger a random output.
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,11 @@
|
||||||
name: signal-port-name-logic-enable
|
name: signal-port-name-logic-enable
|
||||||
description: signal-port-description-logic-enable
|
description: signal-port-description-logic-enable
|
||||||
|
|
||||||
|
- type: sinkPort
|
||||||
|
id: RandomGateInput
|
||||||
|
name: signal-port-name-logic-random-input
|
||||||
|
description: signal-port-description-logic-random-input
|
||||||
|
|
||||||
- type: sinkPort
|
- type: sinkPort
|
||||||
id: SetParticleDelta
|
id: SetParticleDelta
|
||||||
name: signal-port-name-set-particle-delta
|
name: signal-port-name-set-particle-delta
|
||||||
|
|
|
||||||
|
|
@ -291,3 +291,29 @@
|
||||||
- Output
|
- Output
|
||||||
- type: Construction
|
- type: Construction
|
||||||
node: memory_cell
|
node: memory_cell
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: BaseLogicItem
|
||||||
|
id: RandomGate
|
||||||
|
name: random gate
|
||||||
|
description: A logic gate that outputs a random signal when input changes.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
layers:
|
||||||
|
- state: base
|
||||||
|
- state: random_gate
|
||||||
|
- type: RandomGate
|
||||||
|
- type: DeviceLinkSink
|
||||||
|
ports:
|
||||||
|
- RandomGateInput
|
||||||
|
- type: DeviceLinkSource
|
||||||
|
ports:
|
||||||
|
- Output
|
||||||
|
- type: UserInterface
|
||||||
|
interfaces:
|
||||||
|
enum.RandomGateUiKey.Key:
|
||||||
|
type: RandomGateBoundUserInterface
|
||||||
|
- type: ActivatableUI
|
||||||
|
key: enum.RandomGateUiKey.Key
|
||||||
|
- type: Construction
|
||||||
|
node: random_gate
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,14 @@
|
||||||
- material: Cable
|
- material: Cable
|
||||||
amount: 2
|
amount: 2
|
||||||
doAfter: 1
|
doAfter: 1
|
||||||
|
- to: random_gate
|
||||||
|
steps:
|
||||||
|
- material: MetalRod
|
||||||
|
amount: 1
|
||||||
|
doAfter: 1
|
||||||
|
- material: Cable
|
||||||
|
amount: 1
|
||||||
|
doAfter: 1
|
||||||
- node: logic_gate
|
- node: logic_gate
|
||||||
entity: LogicGateOr
|
entity: LogicGateOr
|
||||||
edges:
|
edges:
|
||||||
|
|
@ -102,3 +110,17 @@
|
||||||
- !type:SpawnPrototype
|
- !type:SpawnPrototype
|
||||||
prototype: CableApcStack1
|
prototype: CableApcStack1
|
||||||
amount: 2
|
amount: 2
|
||||||
|
- node: random_gate
|
||||||
|
entity: RandomGate
|
||||||
|
edges:
|
||||||
|
- to: empty
|
||||||
|
steps:
|
||||||
|
- tool: Prying
|
||||||
|
doAfter: 2
|
||||||
|
completed:
|
||||||
|
- !type:SpawnPrototype
|
||||||
|
prototype: CableApcStack1
|
||||||
|
amount: 1
|
||||||
|
- !type:SpawnPrototype
|
||||||
|
prototype: PartRodMetal1
|
||||||
|
amount: 1
|
||||||
|
|
|
||||||
|
|
@ -37,3 +37,11 @@
|
||||||
targetNode: memory_cell
|
targetNode: memory_cell
|
||||||
category: construction-category-tools
|
category: construction-category-tools
|
||||||
objectType: Item
|
objectType: Item
|
||||||
|
|
||||||
|
- type: construction
|
||||||
|
id: RandomGate
|
||||||
|
graph: LogicGate
|
||||||
|
startNode: start
|
||||||
|
targetNode: random_gate
|
||||||
|
category: construction-category-tools
|
||||||
|
objectType: Item
|
||||||
|
|
|
||||||
|
|
@ -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, 2024. Sprites logic_a logic_b logic_o were made by 0tito (github) for SS14",
|
"copyright": "or.png originally created by Kevin Zheng, 2022. All are modified by deltanedas (github) for SS14, 2024. Sprites logic_a logic_b logic_o were made by 0tito (github) for SS14. 2025, added random_gate.png by borsh.",
|
||||||
"size": {
|
"size": {
|
||||||
"x": 32,
|
"x": 32,
|
||||||
"y": 32
|
"y": 32
|
||||||
|
|
@ -51,6 +51,9 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "memory_cell"
|
"name": "memory_cell"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "random_gate"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 215 B |
Loading…
Reference in New Issue