Skip to content

Commit

Permalink
Working sale point
Browse files Browse the repository at this point in the history
  • Loading branch information
whatston3 committed Jan 15, 2025
1 parent 6e79662 commit 118975b
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 205 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public sealed partial class GasDepositExtractorComponent : Component
[DataField("port")]
public string PortName { get; set; } = "port";

// Storing the last
// Storing the last known extraction state.
[ViewVariables]
public GasDepositExtractorState LastState { get; set; } = GasDepositExtractorState.Off;
}
18 changes: 5 additions & 13 deletions Content.Server/_NF/Atmos/Components/GasSaleConsoleComponent.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Content.Server._NF.Atmos.EntitySystems;
using Content.Shared.Atmos;
using Content.Shared.DeviceLinking;
using Content.Shared.Stacks;
using Robust.Shared.Prototypes;

Expand All @@ -9,18 +7,12 @@ namespace Content.Server._NF.Atmos.Components;
[RegisterComponent, Access(typeof(GasDepositSystem))]
public sealed partial class GasSaleConsoleComponent : Component
{
// Source port for commands (query, sell).
// Currency type to spawn when gas is sold.
[DataField]
public ProtoId<SourcePortPrototype> CommandPortName = "GasSaleConsoleSender";
public ProtoId<StackPrototype> CashType = "Credit";

// Sink port for contents (contents)
// The radius around the console in meters to check for gas sale points.
// Can be modified individually when mapping, so that consoles have a further reach.
[DataField]
public ProtoId<SinkPortPrototype> ResponsePortName = "GasSaleConsoleReceiver";

// Currency type to spawn on sold
[DataField]
public ProtoId<StackPrototype> Currency = "Credit";

[ViewVariables]
public GasMixture LastKnownMixture = new();
public int SellPointDistance = 8;
}
10 changes: 0 additions & 10 deletions Content.Server/_NF/Atmos/Components/GasSalePointComponent.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using Content.Server._NF.Atmos.EntitySystems;
using Content.Shared.Atmos;
using Content.Shared.DeviceLinking;
using Robust.Shared.Prototypes;

namespace Content.Server._NF.Atmos.Components;

Expand All @@ -14,12 +12,4 @@ public sealed partial class GasSalePointComponent : Component
// An unlimited internal gas storage, tracking how much gas has been put into the entity.
[ViewVariables]
public GasMixture GasStorage = new();

// Sink port for clear commands.
[DataField]
public ProtoId<SinkPortPrototype> CommandPortName = "GasSalePointReceiver";

// Source port for responses.
[DataField]
public ProtoId<SourcePortPrototype> ResponsePortName = "GasSalePointSender";
}
177 changes: 80 additions & 97 deletions Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using System.Numerics;
using Content.Server._NF.Atmos.Components;
using Content.Server.Administration.Logs;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Piping.Components;
using Content.Server.Audio;
using Content.Server.DeviceLinking.Events;
using Content.Server.DeviceLinking.Systems;
using Content.Server.DeviceNetwork;
using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.NodeGroups;
using Content.Server.NodeContainer.Nodes;
Expand All @@ -20,11 +19,13 @@
using Content.Shared.Bank.Components;
using Content.Shared.Construction.Components;
using Content.Shared.Database;
using Content.Shared.DeviceNetwork;
using Content.Shared.Examine;
using Content.Shared.Interaction;
using Content.Shared.Power;
using Content.Shared.Stacks;
using Robust.Server.Audio;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.Map.Components;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
Expand All @@ -47,21 +48,16 @@ public sealed class GasDepositSystem : EntitySystem
[Dependency] private readonly AppearanceSystem _appearance = default!;
[Dependency] private readonly DeviceLinkSystem _deviceLink = default!;
[Dependency] private readonly StackSystem _stack = default!;
[Dependency] private readonly TransformSystem _transform = default!;
[Dependency] private readonly AudioSystem _audio = default!;

// The fraction that a deposit's volume should be depleted to before it is considered "low volume".
private const float LowMoleCoefficient = 0.25f;
// The maximum distance to check for nearby gas sale points when selling gas.
private const double DefaultMaxSalePointDistance = 8.0;

// Surveillance camera data. This generally should contain nothing
// except for the subnet that this camera is on -
// this is because of the fact that the PacketEvent already
// contains the sender UID, and that this will always be targeted
// towards the sender that pinged the camera.
public const string GasSaleQueryCommand = "gas_sale_query";
public const string GasSaleQueryResponse = "gas_sale_contents";
public const string GasSaleSellCommand = "gas_sale_sell";
public const string GasSaleSellResponse = "gas_sale_value";
private static readonly SoundPathSpecifier ApproveSound = new("/Audio/Effects/Cargo/ping.ogg");

public const string GasSaleQueryData = "gas_sale_contents_data";
public const string GasSaleSellData = "gas_sale_value_data";

/// <inheritdoc/>
public override void Initialize()
Expand All @@ -82,13 +78,11 @@ public override void Initialize()
SubscribeLocalEvent<GasDepositExtractorComponent, GasPressurePumpChangeOutputPressureMessage>(OnOutputPressureChangeMessage);
SubscribeLocalEvent<GasDepositExtractorComponent, GasPressurePumpToggleStatusMessage>(OnToggleStatusMessage);

SubscribeLocalEvent<GasSalePointComponent, MapInitEvent>(OnSalePointMapInit);
SubscribeLocalEvent<GasSalePointComponent, AtmosDeviceUpdateEvent>(OnSalePointUpdate);

SubscribeLocalEvent<GasSaleConsoleComponent, MapInitEvent>(OnSaleConsoleMapInit);
SubscribeLocalEvent<GasSaleConsoleComponent, BoundUIOpenedEvent>(OnConsoleUiOpened);
SubscribeLocalEvent<GasSaleConsoleComponent, GasSaleSellMessage>(OnSaleRequest);
SubscribeLocalEvent<GasSaleConsoleComponent, SignalReceivedEvent>(OnConsoleSignalReceived);
SubscribeLocalEvent<GasSaleConsoleComponent, GasSaleSellMessage>(OnConsoleSell);
SubscribeLocalEvent<GasSaleConsoleComponent, GasSaleRefreshMessage>(OnConsoleRefresh);
}

private void OnExtractorMapInit(EntityUid uid, GasDepositExtractorComponent extractor, MapInitEvent args)
Expand Down Expand Up @@ -293,20 +287,6 @@ private void UpdateAppearance(EntityUid uid, GasDepositExtractorComponent? extra
_appearance.SetData(uid, GasDepositExtractorVisuals.State, extractor.LastState, appearance);
}

private void OnSaleConsoleMapInit(EntityUid uid, GasSaleConsoleComponent component, MapInitEvent args)
{
// Console: sends commands, receives responses.
_deviceLink.EnsureSourcePorts(uid, component.CommandPortName);
_deviceLink.EnsureSinkPorts(uid, component.ResponsePortName);
}

private void OnSalePointMapInit(EntityUid uid, GasSalePointComponent component, MapInitEvent args)
{
// Gas point: receives commands, sends responses.
_deviceLink.EnsureSourcePorts(uid, component.ResponsePortName);
_deviceLink.EnsureSinkPorts(uid, component.CommandPortName);
}

// Atmos update: take any gas from the connecting network and push it into the pump.
private void OnSalePointUpdate(EntityUid uid, GasSalePointComponent component, ref AtmosDeviceUpdateEvent args)
{
Expand All @@ -321,96 +301,99 @@ private void OnSalePointUpdate(EntityUid uid, GasSalePointComponent component, r
{
_atmosphere.Merge(component.GasStorage, net.Air);
net.Air.Clear();
SendSalePointContents(uid, component);
}
}

private void OnSaleRequest(EntityUid uid, GasSaleConsoleComponent component, GasSaleSellMessage args)
private void OnConsoleUiOpened(EntityUid uid, GasSaleConsoleComponent component, BoundUIOpenedEvent args)
{
if (TryComp<ApcPowerReceiverComponent>(uid, out var power) && !power.Powered)
return;

NetworkPayload payload = new NetworkPayload()
{
{ DeviceNetworkConstants.Command, GasSaleSellCommand }
};

_deviceLink.InvokePort(uid, component.CommandPortName, payload);
UpdateConsoleInterface(uid, component);
}

private void SendSalePointContents(EntityUid uid, GasSalePointComponent component)
private void OnConsoleRefresh(EntityUid uid, GasSaleConsoleComponent component, GasSaleRefreshMessage args)
{
var payload = new NetworkPayload()
{
{ DeviceNetworkConstants.Command, GasSaleQueryResponse },
{ GasSaleQueryData, component.GasStorage }
};
_deviceLink.InvokePort(uid, component.ResponsePortName, payload);
UpdateConsoleInterface(uid, component);
}

private void OnConsoleSignalReceived(EntityUid uid, GasSaleConsoleComponent component, ref SignalReceivedEvent args)
private void OnConsoleSell(EntityUid uid, GasSaleConsoleComponent component, GasSaleSellMessage args)
{
var payload = args.Data;
if (payload == null || !payload.ContainsKey(DeviceNetworkConstants.Command))
var xform = Transform(uid);
if (xform.GridUid is not EntityUid gridUid)
{
_ui.SetUiState(uid, GasSaleConsoleUiKey.Key,
new GasSaleConsoleBoundUserInterfaceState(0, new GasMixture(), false));
return;
}

var command = payload[DeviceNetworkConstants.Command];
switch (command)
var mixture = new GasMixture();
foreach (var salePoint in GetNearbySalePoints(uid, gridUid))
{
case GasSaleQueryResponse:
// Add contents to UI
if (!payload.TryGetValue(GasSaleQueryData, out GasMixture? mixture)
|| mixture == null)
return;
component.LastKnownMixture = mixture;
break;
case GasSaleSellResponse:
if (!payload.TryGetValue(GasSaleSellData, out int? saleValue)
|| saleValue == null
|| saleValue.Value <= 0)
return;
_stack.SpawnMultiple(component.Currency, saleValue.Value, Transform(uid).Coordinates);
UpdateConsoleInterface(uid, component, new GasMixture());
component.LastKnownMixture = new();
break;
_atmosphere.Merge(mixture, salePoint.Comp.GasStorage);
salePoint.Comp.GasStorage.Clear();
}

var amount = _atmosphere.GetPrice(mixture);
if (TryComp<MarketModifierComponent>(uid, out var priceMod))
amount *= priceMod.Mod;

var stackPrototype = _prototype.Index<StackPrototype>(component.CashType);
_stack.Spawn((int) amount, stackPrototype, xform.Coordinates);
_audio.PlayPvs(ApproveSound, uid);
_ui.SetUiState(uid, GasSaleConsoleUiKey.Key,
new GasSaleConsoleBoundUserInterfaceState((int) 0, new GasMixture(), false));
}

private void OnSalePointSignalReceived(EntityUid uid, GasSalePointComponent component, ref SignalReceivedEvent args)
private void UpdateConsoleInterface(EntityUid uid, GasSaleConsoleComponent component)
{
var payload = args.Data;
if (payload == null || !payload.ContainsKey(DeviceNetworkConstants.Command))
return;

var command = payload[DeviceNetworkConstants.Command];
switch (command)
if (Transform(uid).GridUid is not EntityUid gridUid)
{
case GasSaleQueryCommand:
SendSalePointContents(uid, component);
break;
case GasSaleSellCommand:
var salePayload = new NetworkPayload()
{
{ DeviceNetworkConstants.Command, GasSaleSellResponse },
{ GasSaleSellData, (int)_atmosphere.GetPrice(component.GasStorage) }
};
_deviceLink.InvokePort(uid, component.ResponsePortName, salePayload);
component.GasStorage.Clear();
break;
_ui.SetUiState(uid, GasSaleConsoleUiKey.Key,
new GasSaleConsoleBoundUserInterfaceState(0, new GasMixture(), false));
return;
}

GetNearbyMixtures(uid, gridUid, out var mixture, out var amount);
if (TryComp<MarketModifierComponent>(uid, out var priceMod))
amount *= priceMod.Mod;

_ui.SetUiState(uid, GasSaleConsoleUiKey.Key,
new GasSaleConsoleBoundUserInterfaceState((int) amount, mixture, mixture.TotalMoles > 0));
}

private void OnConsoleUiOpened(EntityUid uid, GasSaleConsoleComponent component, BoundUIOpenedEvent args)
private void GetNearbyMixtures(EntityUid consoleUid, EntityUid gridUid, out GasMixture mixture, out double value)
{
UpdateConsoleInterface(uid, component, component.LastKnownMixture);
mixture = new GasMixture();

foreach (var salePoint in GetNearbySalePoints(consoleUid, gridUid))
_atmosphere.Merge(mixture, salePoint.Comp.GasStorage);

value = _atmosphere.GetPrice(mixture);
}

private void UpdateConsoleInterface(EntityUid uid, GasSaleConsoleComponent component, GasMixture mixture)
private List<Entity<GasSalePointComponent>> GetNearbySalePoints(EntityUid consoleUid, EntityUid gridUid)
{
float marketMod = 1.0f;
if (TryComp<MarketModifierComponent>(uid, out var mod))
marketMod = mod.Mod;
List<Entity<GasSalePointComponent>> ret = new();

var query = AllEntityQuery<GasSalePointComponent, TransformComponent>();

var consolePosition = Transform(consoleUid).Coordinates.Position;
var maxSalePointDistance = DefaultMaxSalePointDistance;

// Get the mapped checking distance from the console
if (TryComp<GasSaleConsoleComponent>(consoleUid, out var cargoShuttleComponent))
maxSalePointDistance = cargoShuttleComponent.SellPointDistance;

while (query.MoveNext(out var uid, out var comp, out var compXform))
{
if (compXform.ParentUid != gridUid
|| !compXform.Anchored
|| Vector2.Distance(consolePosition, compXform.Coordinates.Position) > maxSalePointDistance)
{
continue;
}

ret.Add((uid, comp));
}

_ui.SetUiState(uid, GasSaleConsoleUiKey.Key, new GasSaleConsoleBoundUserInterfaceState((int)(_atmosphere.GetPrice(mixture) * marketMod), mixture, mixture.TotalMoles > 0));
return ret;
}
}
16 changes: 16 additions & 0 deletions Content.Shared/_NF/Atmos/Events/GasSalePointEvents.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Robust.Shared.Serialization;

namespace Content.Shared._NF.Atmos.Events;

/// <summary>
/// Raised on a client requesting gas to be sold.
/// </summary>
[Serializable, NetSerializable]
public sealed class GasSaleSellMessage : BoundUserInterfaceMessage;

/// <summary>
/// Raised on a client requesting the gas console's state be refreshed
/// Similar to the appraise button on the cargo consoles.
/// </summary>
[Serializable, NetSerializable]
public sealed class GasSaleRefreshMessage : BoundUserInterfaceMessage;
9 changes: 0 additions & 9 deletions Content.Shared/_NF/Atmos/Events/GasSaleSellMessage.cs

This file was deleted.

5 changes: 0 additions & 5 deletions Resources/Locale/en-US/_NF/machine-linking/receiver_ports.ftl

This file was deleted.

This file was deleted.

8 changes: 0 additions & 8 deletions Resources/Maps/_NF/POI/edison.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19069,10 +19069,6 @@ entities:
rot: -1.5707963267948966 rad
pos: -2.5,14.5
parent: 2
- type: DeviceLinkSource
linkedPorts:
3663:
- GasSaleConsoleSender: GasSalePointReceiver
- proto: GasSalePoint
entities:
- uid: 3663
Expand All @@ -19081,10 +19077,6 @@ entities:
rot: 3.141592653589793 rad
pos: -2.5,12.5
parent: 2
- type: DeviceLinkSource
linkedPorts:
4317:
- GasSalePointSender: GasSaleConsoleReceiver
- proto: GasThermoMachineFreezer
entities:
- uid: 3201
Expand Down
9 changes: 0 additions & 9 deletions Resources/Prototypes/_NF/DeviceLinking/sink_ports.yml

This file was deleted.

Loading

0 comments on commit 118975b

Please sign in to comment.