Local Material Silo (#36492)
* Material Silo * fix board, fix copyright * a bit of review.... for the vibe.... * a tiny bit of review * 4 spaced * sloths no good very tiny nitpick * fix ui flickers * oops * slightly lower range * Sloth Review --------- Co-authored-by: ScarKy0 <scarky0@onet.eu>
This commit is contained in:
@@ -102,14 +102,18 @@ public sealed class MaterialStorageSystem : SharedMaterialStorageSystem
|
||||
if (!base.TryInsertMaterialEntity(user, toInsert, receiver, storage, material, composition))
|
||||
return false;
|
||||
_audio.PlayPvs(storage.InsertingSound, receiver);
|
||||
_popup.PopupEntity(Loc.GetString("machine-insert-item", ("user", user), ("machine", receiver),
|
||||
("item", toInsert)), receiver);
|
||||
_popup.PopupEntity(Loc.GetString("machine-insert-item",
|
||||
("user", user),
|
||||
("machine", receiver),
|
||||
("item", toInsert)),
|
||||
receiver);
|
||||
QueueDel(toInsert);
|
||||
|
||||
// Logging
|
||||
TryComp<StackComponent>(toInsert, out var stack);
|
||||
var count = stack?.Count ?? 1;
|
||||
_adminLogger.Add(LogType.Action, LogImpact.Low,
|
||||
_adminLogger.Add(LogType.Action,
|
||||
LogImpact.Low,
|
||||
$"{ToPrettyString(user):player} inserted {count} {ToPrettyString(toInsert):inserted} into {ToPrettyString(receiver):receiver}");
|
||||
return true;
|
||||
}
|
||||
|
||||
119
Content.Server/Materials/OreSiloSystem.cs
Normal file
119
Content.Server/Materials/OreSiloSystem.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using Content.Server.Pinpointer;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Materials.OreSilo;
|
||||
using Robust.Server.GameStates;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Server.Materials;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public sealed class OreSiloSystem : SharedOreSiloSystem
|
||||
{
|
||||
[Dependency] private readonly EntityLookupSystem _entityLookup = default!;
|
||||
[Dependency] private readonly NavMapSystem _navMap = default!;
|
||||
[Dependency] private readonly PvsOverrideSystem _pvsOverride = default!;
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _userInterface = default!;
|
||||
|
||||
private const float OreSiloPreloadRangeSquared = 225f; // ~1 screen
|
||||
|
||||
private readonly HashSet<Entity<OreSiloClientComponent>> _clientLookup = new();
|
||||
private readonly HashSet<(NetEntity, string, string)> _clientInformation = new();
|
||||
private readonly HashSet<EntityUid> _silosToAdd = new();
|
||||
private readonly HashSet<EntityUid> _silosToRemove = new();
|
||||
|
||||
protected override void UpdateOreSiloUi(Entity<OreSiloComponent> ent)
|
||||
{
|
||||
if (!_userInterface.IsUiOpen(ent.Owner, OreSiloUiKey.Key))
|
||||
return;
|
||||
_clientLookup.Clear();
|
||||
_clientInformation.Clear();
|
||||
|
||||
var xform = Transform(ent);
|
||||
|
||||
// Sneakily uses override with TComponent parameter
|
||||
_entityLookup.GetEntitiesInRange(xform.Coordinates, ent.Comp.Range, _clientLookup);
|
||||
|
||||
foreach (var client in _clientLookup)
|
||||
{
|
||||
// don't show already-linked clients.
|
||||
if (client.Comp.Silo is not null)
|
||||
continue;
|
||||
|
||||
var netEnt = GetNetEntity(client);
|
||||
var name = Identity.Name(client, EntityManager);
|
||||
var beacon = _navMap.GetNearestBeaconString(client.Owner, onlyName: true);
|
||||
|
||||
var txt = Loc.GetString("ore-silo-ui-itemlist-entry",
|
||||
("name", name),
|
||||
("beacon", beacon),
|
||||
("linked", ent.Comp.Clients.Contains(client)),
|
||||
("inRange", true));
|
||||
|
||||
_clientInformation.Add((netEnt, txt, beacon));
|
||||
}
|
||||
|
||||
// Get all clients of this silo, including those out of range.
|
||||
foreach (var client in ent.Comp.Clients)
|
||||
{
|
||||
var netEnt = GetNetEntity(client);
|
||||
var name = Identity.Name(client, EntityManager);
|
||||
var beacon = _navMap.GetNearestBeaconString(client, onlyName: true);
|
||||
var inRange = CanTransmitMaterials((ent, ent), client);
|
||||
|
||||
var txt = Loc.GetString("ore-silo-ui-itemlist-entry",
|
||||
("name", name),
|
||||
("beacon", beacon),
|
||||
("linked", ent.Comp.Clients.Contains(client)),
|
||||
("inRange", inRange));
|
||||
|
||||
_clientInformation.Add((netEnt, txt, beacon));
|
||||
}
|
||||
|
||||
_userInterface.SetUiState(ent.Owner, OreSiloUiKey.Key, new OreSiloBuiState(_clientInformation));
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
// Solving an annoying problem: we need to send the silo to people who are near the silo so that
|
||||
// Things don't start wildly mispredicting. We do this as cheaply as possible via grid-based local-pos checks.
|
||||
// Sloth okay-ed this in the interim until a better solution comes around.
|
||||
|
||||
var actorQuery = EntityQueryEnumerator<ActorComponent, TransformComponent>();
|
||||
while (actorQuery.MoveNext(out _, out var actorComp, out var actorXform))
|
||||
{
|
||||
_silosToAdd.Clear();
|
||||
_silosToRemove.Clear();
|
||||
|
||||
var clientQuery = EntityQueryEnumerator<OreSiloClientComponent, TransformComponent>();
|
||||
while (clientQuery.MoveNext(out _, out var clientComp, out var clientXform))
|
||||
{
|
||||
if (clientComp.Silo == null)
|
||||
continue;
|
||||
|
||||
// We limit it to same-grid checks only for peak perf
|
||||
if (actorXform.GridUid != clientXform.GridUid)
|
||||
continue;
|
||||
|
||||
if ((actorXform.LocalPosition - clientXform.LocalPosition).LengthSquared() <= OreSiloPreloadRangeSquared)
|
||||
{
|
||||
_silosToAdd.Add(clientComp.Silo.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
_silosToRemove.Add(clientComp.Silo.Value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var toRemove in _silosToRemove)
|
||||
{
|
||||
_pvsOverride.RemoveSessionOverride(toRemove, actorComp.PlayerSession);
|
||||
}
|
||||
foreach (var toAdd in _silosToAdd)
|
||||
{
|
||||
_pvsOverride.AddSessionOverride(toAdd, actorComp.PlayerSession);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -436,12 +436,12 @@ public sealed partial class NavMapSystem : SharedNavMapSystem
|
||||
/// to the position of <paramref name="ent"/> from the nearest beacon.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string GetNearestBeaconString(Entity<TransformComponent?> ent)
|
||||
public string GetNearestBeaconString(Entity<TransformComponent?> ent, bool onlyName = false)
|
||||
{
|
||||
if (!Resolve(ent, ref ent.Comp))
|
||||
return Loc.GetString("nav-beacon-pos-no-beacons");
|
||||
|
||||
return GetNearestBeaconString(_transformSystem.GetMapCoordinates(ent, ent.Comp));
|
||||
return GetNearestBeaconString(_transformSystem.GetMapCoordinates(ent, ent.Comp), onlyName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -449,11 +449,14 @@ public sealed partial class NavMapSystem : SharedNavMapSystem
|
||||
/// to <paramref name="coordinates"/> from the nearest beacon.
|
||||
/// </summary>
|
||||
|
||||
public string GetNearestBeaconString(MapCoordinates coordinates)
|
||||
public string GetNearestBeaconString(MapCoordinates coordinates, bool onlyName = false)
|
||||
{
|
||||
if (!TryGetNearestBeacon(coordinates, out var beacon, out var pos))
|
||||
return Loc.GetString("nav-beacon-pos-no-beacons");
|
||||
|
||||
if (onlyName)
|
||||
return beacon.Value.Comp.Text!;
|
||||
|
||||
var gridOffset = Angle.Zero;
|
||||
if (_mapManager.TryFindGridAt(pos.Value, out var grid, out _))
|
||||
gridOffset = Transform(grid).LocalRotation;
|
||||
|
||||
Reference in New Issue
Block a user