Fix and improve bluespace lockers (#13139)

* add invulnerable plastitanium wall prototype

* fix command ClearBluespaceLockerLinks.cs

* fix and improve BluespaceLockerSystem.cs

* fix normal plastitanium wall suffix

* fix capitalization

* fix capability to create one way lockers
This commit is contained in:
Chief-Engineer
2022-12-24 22:35:03 -06:00
committed by GitHub
parent faca40b8d5
commit b7af5e6109
5 changed files with 142 additions and 20 deletions

View File

@@ -27,7 +27,7 @@ public sealed class ClearBluespaceLockerLinks : IConsoleCommand
var entityManager = IoCManager.Resolve<IEntityManager>();
if (entityManager.TryGetComponent<EntityStorageComponent>(entityUid, out var originComponent))
if (entityManager.TryGetComponent<BluespaceLockerComponent>(entityUid, out var originComponent))
entityManager.RemoveComponent(entityUid, originComponent);
}
}

View File

@@ -53,10 +53,16 @@ public sealed class LinkBluespaceLocker : IConsoleCommand
entityManager.EnsureComponent<BluespaceLockerComponent>(originUid, out var originBluespaceComponent);
originBluespaceComponent.BluespaceLinks.Add(targetComponent);
entityManager.EnsureComponent<BluespaceLockerComponent>(targetUid, out var targetBluespaceComponent);
if (bidirectional)
{
entityManager.EnsureComponent<BluespaceLockerComponent>(targetUid, out var targetBluespaceComponent);
targetBluespaceComponent.BluespaceLinks.Add(originComponent);
}
else if (targetBluespaceComponent.BluespaceLinks.Count == 0)
{
targetBluespaceComponent.AllowSentient = false;
targetBluespaceComponent.TransportEntities = false;
targetBluespaceComponent.TransportGas = false;
}
}
}

View File

@@ -27,4 +27,35 @@ public sealed class BluespaceLockerComponent : Component
/// </summary>
[DataField("bluespaceLinks"), ViewVariables(VVAccess.ReadOnly)]
public HashSet<EntityStorageComponent> BluespaceLinks = new();
/// <summary>
/// Each time the system attempts to get a link, it will link additional lockers to ensure the minimum amount
/// are linked.
/// </summary>
[DataField("minBluespaceLinks"), ViewVariables(VVAccess.ReadWrite)]
public uint MinBluespaceLinks;
/// <summary>
/// Determines if links automatically added are restricted to the same map
/// </summary>
[DataField("pickLinksFromSameMap"), ViewVariables(VVAccess.ReadWrite)]
public bool PickLinksFromSameMap;
/// <summary>
/// Determines if links automatically added must have ResistLockerComponent
/// </summary>
[DataField("pickLinksFromResistLockers"), ViewVariables(VVAccess.ReadWrite)]
public bool PickLinksFromResistLockers = true;
/// <summary>
/// Determines if links automatically added are restricted to being on a station
/// </summary>
[DataField("pickLinksFromStationGrids"), ViewVariables(VVAccess.ReadWrite)]
public bool PickLinksFromStationGrids = true;
/// <summary>
/// Determines if links automatically added are bidirectional
/// </summary>
[DataField("autoLinksBidirectional"), ViewVariables(VVAccess.ReadWrite)]
public bool AutoLinksBidirectional;
}

View File

@@ -1,14 +1,19 @@
using System.Linq;
using Content.Server.Lock;
using Content.Server.Mind.Components;
using Content.Server.Resist;
using Content.Server.Station.Components;
using Content.Server.Storage.Components;
using Content.Server.Tools.Systems;
using Microsoft.Extensions.DependencyModel;
using Content.Shared.Coordinates;
using Robust.Shared.Random;
namespace Content.Server.Storage.EntitySystems;
public sealed class BluespaceLockerSystem : EntitySystem
{
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IRobustRandom _robustRandom = default!;
[Dependency] private readonly EntityStorageSystem _entityStorage = default!;
[Dependency] private readonly WeldableSystem _weldableSystem = default!;
[Dependency] private readonly LockSystem _lockSystem = default!;
@@ -17,23 +22,27 @@ public sealed class BluespaceLockerSystem : EntitySystem
{
base.Initialize();
SubscribeLocalEvent<BluespaceLockerComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<BluespaceLockerComponent, StorageBeforeOpenEvent>(PreOpen);
SubscribeLocalEvent<BluespaceLockerComponent, StorageAfterCloseEvent>(PostClose);
}
private void OnStartup(EntityUid uid, BluespaceLockerComponent component, ComponentStartup args)
{
GetTargetStorage(component);
}
private void PreOpen(EntityUid uid, BluespaceLockerComponent component, StorageBeforeOpenEvent args)
{
EntityStorageComponent? entityStorageComponent = null;
if (component.BluespaceLinks is not { Count: > 0 })
return;
if (!Resolve(uid, ref entityStorageComponent))
return;
// Select target
var targetContainerStorageComponent = component.BluespaceLinks.ToArray()[new Random().Next(0, component.BluespaceLinks.Count)];
var targetContainerStorageComponent = GetTargetStorage(component);
if (targetContainerStorageComponent == null)
return;
BluespaceLockerComponent? targetContainerBluespaceComponent = null;
// Close target if it is open
@@ -41,8 +50,7 @@ public sealed class BluespaceLockerSystem : EntitySystem
_entityStorage.CloseStorage(targetContainerStorageComponent.Owner, targetContainerStorageComponent);
// Apply bluespace effects if target is not a bluespace locker, otherwise let it handle it
if (!Resolve(targetContainerStorageComponent.Owner, ref targetContainerBluespaceComponent, false) ||
targetContainerBluespaceComponent.BluespaceLinks is not { Count: > 0 })
if (!Resolve(targetContainerStorageComponent.Owner, ref targetContainerBluespaceComponent, false))
{
// Move contained items
if (component.TransportEntities)
@@ -62,18 +70,84 @@ public sealed class BluespaceLockerSystem : EntitySystem
}
}
private bool ValidLink(BluespaceLockerComponent component, EntityStorageComponent link)
{
return link.Owner.Valid && link.LifeStage != ComponentLifeStage.Deleted;
}
private bool ValidAutolink(BluespaceLockerComponent component, EntityStorageComponent link)
{
if (!ValidLink(component, link))
return false;
if (component.PickLinksFromSameMap &&
link.Owner.ToCoordinates().GetMapId(_entityManager) == component.Owner.ToCoordinates().GetMapId(_entityManager))
return false;
if (component.PickLinksFromStationGrids &&
!_entityManager.HasComponent<StationMemberComponent>(link.Owner.ToCoordinates().GetGridUid(_entityManager)))
return false;
if (component.PickLinksFromResistLockers &&
!_entityManager.HasComponent<ResistLockerComponent>(link.Owner))
return false;
return true;
}
private EntityStorageComponent? GetTargetStorage(BluespaceLockerComponent component)
{
while (true)
{
// Ensure MinBluespaceLinks
if (component.BluespaceLinks.Count < component.MinBluespaceLinks)
{
// Get an shuffle the list of all EntityStorages
var storages = _entityManager.EntityQuery<EntityStorageComponent>().ToArray();
_robustRandom.Shuffle(storages);
// Add valid candidates till MinBluespaceLinks is met
foreach (var storage in storages)
{
if (!ValidAutolink(component, storage))
continue;
component.BluespaceLinks.Add(storage);
if (component.AutoLinksBidirectional)
{
_entityManager.EnsureComponent<BluespaceLockerComponent>(storage.Owner, out var targetBluespaceComponent);
targetBluespaceComponent.BluespaceLinks.Add(_entityManager.GetComponent<EntityStorageComponent>(component.Owner));
}
if (component.BluespaceLinks.Count >= component.MinBluespaceLinks)
break;
}
}
// If there are no possible link targets and no links, return null
if (component.BluespaceLinks.Count == 0)
return null;
// Attempt to select, validate, and return a link
var links = component.BluespaceLinks.ToArray();
var link = links[_robustRandom.Next(0, component.BluespaceLinks.Count)];
if (ValidLink(component, link))
return link;
component.BluespaceLinks.Remove(link);
}
}
private void PostClose(EntityUid uid, BluespaceLockerComponent component, StorageAfterCloseEvent args)
{
EntityStorageComponent? entityStorageComponent = null;
if (component.BluespaceLinks is not { Count: > 0 })
return;
if (!Resolve(uid, ref entityStorageComponent))
return;
// Select target
var targetContainerStorageComponent = component.BluespaceLinks.ToArray()[new Random().Next(0, component.BluespaceLinks.Count)];
var targetContainerStorageComponent = GetTargetStorage(component);
if (targetContainerStorageComponent == null)
return;
// Move contained items
if (component.TransportEntities)

View File

@@ -388,17 +388,31 @@
- type: entity
parent: BaseWall
id: WallPlastitaniumIndestructible
name: plastitanium wall
suffix: indestructible
components:
- type: Tag
tags:
- Wall
- type: Sprite
sprite: Structures/Walls/plastitanium.rsi
- type: Icon
sprite: Structures/Walls/plastitanium.rsi
- type: IconSmooth
key: walls
base: plastitanium
- type: entity
parent: WallPlastitaniumIndestructible
id: WallPlastitanium
name: plastitanium wall
suffix: ""
components:
- type: Tag
tags:
- Wall
- RCDDeconstructWhitelist
- type: Sprite
sprite: Structures/Walls/plastitanium.rsi
- type: Icon
sprite: Structures/Walls/plastitanium.rsi
- type: Destructible
thresholds:
- trigger:
@@ -412,9 +426,6 @@
max: 1
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: IconSmooth
key: walls
base: plastitanium
- type: entity
parent: BaseWall