diff --git a/Content.Server/Salvage/SalvageGridComponent.cs b/Content.Server/Salvage/SalvageGridComponent.cs
index ba9e89aaa4..be8a12f9d6 100644
--- a/Content.Server/Salvage/SalvageGridComponent.cs
+++ b/Content.Server/Salvage/SalvageGridComponent.cs
@@ -9,6 +9,6 @@
///
/// The magnet that spawned this grid.
///
- public SalvageMagnetComponent? SpawnerMagnet;
+ public EntityUid? SpawnerMagnet;
}
}
diff --git a/Content.Server/Salvage/SalvageMagnetComponent.cs b/Content.Server/Salvage/SalvageMagnetComponent.cs
index 69b0cbdf5d..38c993d404 100644
--- a/Content.Server/Salvage/SalvageMagnetComponent.cs
+++ b/Content.Server/Salvage/SalvageMagnetComponent.cs
@@ -1,4 +1,5 @@
using Content.Shared.Radio;
+using Content.Shared.Random;
using Content.Shared.Salvage;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@@ -12,33 +13,19 @@ namespace Content.Server.Salvage
[Access(typeof(SalvageSystem))]
public sealed class SalvageMagnetComponent : SharedSalvageMagnetComponent
{
- ///
- /// Offset relative to magnet used as centre of the placement circle.
- ///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("offset")]
- public Vector2 Offset = Vector2.Zero; // TODO: Maybe specify a direction, and find the nearest edge of the magnets grid the salvage can fit at
-
- ///
- /// Minimum distance from the offset position that will be used as a salvage's spawnpoint.
- ///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("offsetRadiusMin")]
- public float OffsetRadiusMin = 24f;
-
///
/// Maximum distance from the offset position that will be used as a salvage's spawnpoint.
///
[ViewVariables(VVAccess.ReadWrite)]
[DataField("offsetRadiusMax")]
- public float OffsetRadiusMax = 48f;
+ public float OffsetRadiusMax = 32;
///
/// The entity attached to the magnet
///
[ViewVariables(VVAccess.ReadOnly)]
[DataField("attachedEntity")]
- public EntityUid? AttachedEntity = null;
+ public EntityUid? AttachedEntity;
///
/// Current state of this magnet
@@ -95,18 +82,34 @@ namespace Content.Server.Salvage
///
/// Current how much charge the magnet currently has
///
+ [DataField("chargeRemaining")]
public int ChargeRemaining = 5;
///
/// How much capacity the magnet can hold
///
+ [DataField("chargeCapacity")]
public int ChargeCapacity = 5;
///
/// Used as a guard to prevent spamming the appearance system
///
+ [DataField("previousCharge")]
public int PreviousCharge = 5;
+ ///
+ /// The chance that a random procgen asteroid will be
+ /// generated rather than a static salvage prototype.
+ ///
+ [DataField("asteroidChance"), ViewVariables(VVAccess.ReadWrite)]
+ public float AsteroidChance = 0.6f;
+
+ ///
+ /// A weighted random prototype corresponding to
+ /// what asteroid entities will be generated.
+ ///
+ [DataField("asteroidPool", customTypeSerializer: typeof(PrototypeIdSerializer)), ViewVariables(VVAccess.ReadWrite)]
+ public string AsteroidPool = "RandomAsteroidPool";
}
[CopyByRef, DataRecord]
diff --git a/Content.Server/Salvage/SalvageSystem.Expeditions.cs b/Content.Server/Salvage/SalvageSystem.Expeditions.cs
index 7269c571e6..12a1032cac 100644
--- a/Content.Server/Salvage/SalvageSystem.Expeditions.cs
+++ b/Content.Server/Salvage/SalvageSystem.Expeditions.cs
@@ -178,14 +178,14 @@ public sealed partial class SalvageSystem
// Handle payout after expedition has finished
if (expedition.Completed)
{
- _sawmill.Debug($"Completed mission {expedition.MissionParams.MissionType} with seed {expedition.MissionParams.Seed}");
+ Log.Debug($"Completed mission {expedition.MissionParams.MissionType} with seed {expedition.MissionParams.Seed}");
component.NextOffer = _timing.CurTime + TimeSpan.FromSeconds(_cooldown);
Announce(uid, Loc.GetString("salvage-expedition-mission-completed"));
GiveRewards(expedition);
}
else
{
- _sawmill.Debug($"Failed mission {expedition.MissionParams.MissionType} with seed {expedition.MissionParams.Seed}");
+ Log.Debug($"Failed mission {expedition.MissionParams.MissionType} with seed {expedition.MissionParams.Seed}");
component.NextOffer = _timing.CurTime + TimeSpan.FromSeconds(_failedCooldown);
Announce(uid, Loc.GetString("salvage-expedition-mission-failed"));
}
diff --git a/Content.Server/Salvage/SalvageSystem.cs b/Content.Server/Salvage/SalvageSystem.cs
index c74933b02a..a3df1c5976 100644
--- a/Content.Server/Salvage/SalvageSystem.cs
+++ b/Content.Server/Salvage/SalvageSystem.cs
@@ -1,28 +1,30 @@
+using System.Linq;
using Content.Server.Construction;
using Content.Server.GameTicking;
-using Content.Server.Radio.Components;
using Content.Server.Radio.EntitySystems;
-using Content.Shared.CCVar;
using Content.Shared.Examine;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Radio;
using Content.Shared.Salvage;
using Robust.Server.GameObjects;
-using Robust.Server.Maps;
using Robust.Shared.Configuration;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Utility;
-using System.Linq;
using Content.Server.Chat.Managers;
-using Content.Server.Chat.Systems;
using Content.Server.Parallax;
using Content.Server.Procedural;
using Content.Server.Shuttles.Systems;
using Content.Server.Station.Systems;
+using Content.Server.Worldgen.Systems;
+using Content.Shared.CCVar;
+using Content.Shared.Random;
+using Content.Shared.Random.Helpers;
+using Robust.Server.Maps;
+using Robust.Shared.Map.Components;
using Robust.Shared.Timing;
namespace Content.Server.Salvage
@@ -49,18 +51,15 @@ namespace Content.Server.Salvage
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly UserInterfaceSystem _ui = default!;
- private static readonly int SalvageLocationPlaceAttempts = 16;
+ private const int SalvageLocationPlaceAttempts = 16;
// TODO: This is probably not compatible with multi-station
private readonly Dictionary _salvageGridStates = new();
- private ISawmill _sawmill = default!;
-
public override void Initialize()
{
base.Initialize();
- _sawmill = Logger.GetSawmill("salvage");
SubscribeLocalEvent(OnInteractHand);
SubscribeLocalEvent(OnRefreshParts);
SubscribeLocalEvent(OnUpgradeExamine);
@@ -105,24 +104,21 @@ namespace Content.Server.Salvage
if (!Resolve(uid, ref component, false))
return;
- int timeLeft = Convert.ToInt32(component.MagnetState.Until.TotalSeconds - currentTime.TotalSeconds);
- if (component.MagnetState.StateType == MagnetStateType.Inactive)
- component.ChargeRemaining = 5;
- else if (component.MagnetState.StateType == MagnetStateType.Holding)
+ var timeLeft = Convert.ToInt32(component.MagnetState.Until.TotalSeconds - currentTime.TotalSeconds);
+
+ component.ChargeRemaining = component.MagnetState.StateType switch
{
- component.ChargeRemaining = (timeLeft / (Convert.ToInt32(component.HoldTime.TotalSeconds) / component.ChargeCapacity)) + 1;
- }
- else if (component.MagnetState.StateType == MagnetStateType.Detaching)
- component.ChargeRemaining = 0;
- else if (component.MagnetState.StateType == MagnetStateType.CoolingDown)
- {
- component.ChargeRemaining = component.ChargeCapacity - (timeLeft / (Convert.ToInt32(component.CooldownTime.TotalSeconds) / component.ChargeCapacity)) - 1;
- }
- if (component.PreviousCharge != component.ChargeRemaining)
- {
- _appearanceSystem.SetData(uid, SalvageMagnetVisuals.ChargeState, component.ChargeRemaining);
- component.PreviousCharge = component.ChargeRemaining;
- }
+ MagnetStateType.Inactive => 5,
+ MagnetStateType.Holding => timeLeft / (Convert.ToInt32(component.HoldTime.TotalSeconds) / component.ChargeCapacity) + 1,
+ MagnetStateType.Detaching => 0,
+ MagnetStateType.CoolingDown => component.ChargeCapacity - timeLeft / (Convert.ToInt32(component.CooldownTime.TotalSeconds) / component.ChargeCapacity) - 1,
+ _ => component.ChargeRemaining
+ };
+
+ if (component.PreviousCharge == component.ChargeRemaining)
+ return;
+ _appearanceSystem.SetData(uid, SalvageMagnetVisuals.ChargeState, component.ChargeRemaining);
+ component.PreviousCharge = component.ChargeRemaining;
}
private void OnGridRemoval(GridRemovalEvent ev)
@@ -130,34 +126,37 @@ namespace Content.Server.Salvage
// If we ever want to give magnets names, and announce them individually, we would need to loop this, before removing it.
if (_salvageGridStates.Remove(ev.EntityUid))
{
- if (EntityManager.TryGetComponent(ev.EntityUid, out var salvComp) && salvComp.SpawnerMagnet != null)
- Report(salvComp.SpawnerMagnet.Owner, salvComp.SpawnerMagnet.SalvageChannel, "salvage-system-announcement-spawn-magnet-lost");
+ if (TryComp(ev.EntityUid, out var salvComp) &&
+ TryComp(salvComp.SpawnerMagnet, out var magnet))
+ Report(salvComp.SpawnerMagnet.Value, magnet.SalvageChannel, "salvage-system-announcement-spawn-magnet-lost");
// For the very unlikely possibility that the salvage magnet was on a salvage, we will not return here
}
foreach(var gridState in _salvageGridStates)
{
foreach(var magnet in gridState.Value.ActiveMagnets)
{
- if (magnet.AttachedEntity == ev.EntityUid)
- {
- magnet.AttachedEntity = null;
- magnet.MagnetState = MagnetState.Inactive;
- return;
- }
+ if (!TryComp(magnet, out var magnetComponent))
+ continue;
+
+ if (magnetComponent.AttachedEntity != ev.EntityUid)
+ continue;
+ magnetComponent.AttachedEntity = null;
+ magnetComponent.MagnetState = MagnetState.Inactive;
+ return;
}
}
}
private void OnMagnetRemoval(EntityUid uid, SalvageMagnetComponent component, ComponentShutdown args)
{
- if (component.MagnetState.StateType == MagnetStateType.Inactive) return;
-
- var magnetTranform = EntityManager.GetComponent(component.Owner);
- if (!(magnetTranform.GridUid is EntityUid gridId) || !_salvageGridStates.TryGetValue(gridId, out var salvageGridState))
- {
+ if (component.MagnetState.StateType == MagnetStateType.Inactive)
return;
- }
- salvageGridState.ActiveMagnets.Remove(component);
+
+ var magnetTranform = Transform(uid);
+ if (magnetTranform.GridUid is not { } gridId || !_salvageGridStates.TryGetValue(gridId, out var salvageGridState))
+ return;
+
+ salvageGridState.ActiveMagnets.Remove(uid);
Report(uid, component.SalvageChannel, "salvage-system-announcement-spawn-magnet-lost");
if (component.AttachedEntity.HasValue)
{
@@ -169,6 +168,7 @@ namespace Content.Server.Salvage
{
Report(uid, component.SalvageChannel, "salvage-system-announcement-spawn-no-debris-available");
}
+
component.MagnetState = MagnetState.Inactive;
}
@@ -187,13 +187,13 @@ namespace Content.Server.Salvage
private void OnExamined(EntityUid uid, SalvageMagnetComponent component, ExaminedEvent args)
{
- var gotGrid = false;
- var remainingTime = TimeSpan.Zero;
-
if (!args.IsInDetailsRange)
return;
- if (Transform(uid).GridUid is EntityUid gridId &&
+ var gotGrid = false;
+ var remainingTime = TimeSpan.Zero;
+
+ if (Transform(uid).GridUid is { } gridId &&
_salvageGridStates.TryGetValue(gridId, out var salvageGridState))
{
remainingTime = component.MagnetState.Until - salvageGridState.CurrentTime;
@@ -201,8 +201,9 @@ namespace Content.Server.Salvage
}
else
{
- Logger.WarningS("salvage", "Failed to load salvage grid state, can't display remaining time");
+ Log.Warning("Failed to load salvage grid state, can't display remaining time");
}
+
switch (component.MagnetState.StateType)
{
case MagnetStateType.Inactive:
@@ -223,7 +224,7 @@ namespace Content.Server.Salvage
args.PushMarkup(Loc.GetString("salvage-system-magnet-examined-active", ("timeLeft", Math.Ceiling(remainingTime.TotalSeconds))));
break;
default:
- throw new NotImplementedException("Unexpected magnet state type");
+ throw new ArgumentOutOfRangeException();
}
}
@@ -232,57 +233,56 @@ namespace Content.Server.Salvage
if (args.Handled)
return;
args.Handled = true;
- StartMagnet(component, args.User);
+ StartMagnet(uid, component, args.User);
UpdateAppearance(uid, component);
}
- private void StartMagnet(SalvageMagnetComponent component, EntityUid user)
+ private void StartMagnet(EntityUid uid, SalvageMagnetComponent component, EntityUid user)
{
switch (component.MagnetState.StateType)
{
case MagnetStateType.Inactive:
- ShowPopup("salvage-system-report-activate-success", component, user);
- SalvageGridState? gridState;
- var magnetTransform = EntityManager.GetComponent(component.Owner);
- EntityUid gridId = magnetTransform.GridUid ?? throw new InvalidOperationException("Magnet had no grid associated");
- if (!_salvageGridStates.TryGetValue(gridId, out gridState))
+ ShowPopup(uid, "salvage-system-report-activate-success", user);
+ var magnetTransform = Transform(uid);
+ var gridId = magnetTransform.GridUid ?? throw new InvalidOperationException("Magnet had no grid associated");
+ if (!_salvageGridStates.TryGetValue(gridId, out var gridState))
{
gridState = new SalvageGridState();
_salvageGridStates[gridId] = gridState;
}
- gridState.ActiveMagnets.Add(component);
+ gridState.ActiveMagnets.Add(uid);
component.MagnetState = new MagnetState(MagnetStateType.Attaching, gridState.CurrentTime + component.AttachingTime);
- RaiseLocalEvent(new SalvageMagnetActivatedEvent(component.Owner));
- Report(component.Owner, component.SalvageChannel, "salvage-system-report-activate-success");
+ RaiseLocalEvent(new SalvageMagnetActivatedEvent(uid));
+ Report(uid, component.SalvageChannel, "salvage-system-report-activate-success");
break;
case MagnetStateType.Attaching:
case MagnetStateType.Holding:
- ShowPopup("salvage-system-report-already-active", component, user);
+ ShowPopup(uid, "salvage-system-report-already-active", user);
break;
case MagnetStateType.Detaching:
case MagnetStateType.CoolingDown:
- ShowPopup("salvage-system-report-cooling-down", component, user);
+ ShowPopup(uid, "salvage-system-report-cooling-down", user);
break;
default:
- throw new NotImplementedException("Unexpected magnet state type");
+ throw new ArgumentOutOfRangeException();
}
}
- private void ShowPopup(string messageKey, SalvageMagnetComponent component, EntityUid user)
+ private void ShowPopup(EntityUid uid, string messageKey, EntityUid user)
{
- _popupSystem.PopupEntity(Loc.GetString(messageKey), component.Owner, user);
+ _popupSystem.PopupEntity(Loc.GetString(messageKey), uid, user);
}
private void SafeDeleteSalvage(EntityUid salvage)
{
if(!EntityManager.TryGetComponent(salvage, out var salvageTransform))
{
- Logger.ErrorS("salvage", "Salvage entity was missing transform component");
+ Log.Error("Salvage entity was missing transform component");
return;
}
if (salvageTransform.GridUid == null)
{
- Logger.ErrorS("salvage", "Salvage entity has no associated grid?");
+ Log.Error( "Salvage entity has no associated grid?");
return;
}
@@ -296,125 +296,124 @@ namespace Content.Server.Salvage
// Salvage mobs are NEVER immune (even if they're from a different salvage, they shouldn't be here)
continue;
}
- Transform(playerEntityUid).AttachParent(salvageTransform.ParentUid);
+ _transform.SetParent(playerEntityUid, salvageTransform.ParentUid);
}
}
// Deletion has to happen before grid traversal re-parents players.
- EntityManager.DeleteEntity(salvage);
+ Del(salvage);
}
- private void TryGetSalvagePlacementLocation(SalvageMagnetComponent component, out MapCoordinates coords, out Angle angle)
+ private bool TryGetSalvagePlacementLocation(EntityUid uid, SalvageMagnetComponent component, Box2 bounds, out MapCoordinates coords, out Angle angle)
{
- coords = MapCoordinates.Nullspace;
+ var xform = Transform(uid);
angle = Angle.Zero;
- var tsc = Transform(component.Owner);
- coords = new EntityCoordinates(component.Owner, component.Offset).ToMap(EntityManager);
+ coords = new EntityCoordinates(uid, new Vector2(0, -component.OffsetRadiusMax)).ToMap(EntityManager, _transform);
- if (_mapManager.TryGetGrid(tsc.GridUid, out var magnetGrid) && TryComp(magnetGrid.Owner, out var gridXform))
+ if (xform.GridUid is not null)
+ angle = _transform.GetWorldRotation(Transform(xform.GridUid.Value));
+
+ for (var i = 0; i < SalvageLocationPlaceAttempts; i++)
{
- angle = gridXform.WorldRotation;
+ var randomRadius = _random.NextFloat(component.OffsetRadiusMax);
+ var randomOffset = _random.NextAngle().ToWorldVec() * randomRadius;
+ var finalCoords = coords.Offset(randomOffset);
+
+ var box2 = Box2.CenteredAround(finalCoords.Position, bounds.Size);
+ var box2Rot = new Box2Rotated(box2, angle, finalCoords.Position);
+
+ // This doesn't stop it from spawning on top of random things in space
+ // Might be better like this, ghosts could stop it before
+ if (_mapManager.FindGridsIntersecting(finalCoords.MapId, box2Rot).Any())
+ continue;
+ coords = finalCoords;
+ return true;
}
+ return false;
}
- private IEnumerable GetAllSalvageMaps() =>
- _prototypeManager.EnumeratePrototypes();
-
- private bool SpawnSalvage(SalvageMagnetComponent component)
+ private bool SpawnSalvage(EntityUid uid, SalvageMagnetComponent component)
{
- TryGetSalvagePlacementLocation(component, out var spl, out var spAngle);
+ var salvMap = _mapManager.CreateMap();
- var forcedSalvage = _configurationManager.GetCVar(CCVars.SalvageForced);
- List allSalvageMaps;
- if (string.IsNullOrWhiteSpace(forcedSalvage))
+ Box2 bounds;
+ EntityUid? salvageEnt = null;
+ SalvageMapPrototype? salvageProto = null;
+ if (_random.Prob(component.AsteroidChance))
{
- allSalvageMaps = GetAllSalvageMaps().ToList();
+ var asteroidProto = _prototypeManager.Index(component.AsteroidPool).Pick(_random);
+ salvageEnt = Spawn(asteroidProto, new MapCoordinates(0, 0, salvMap));
+ bounds = Comp(salvageEnt.Value).LocalAABB;
}
else
{
- allSalvageMaps = new();
- if (_prototypeManager.TryIndex(forcedSalvage, out var forcedMap))
- {
- allSalvageMaps.Add(forcedMap);
- }
- else
- {
- Logger.ErrorS("c.s.salvage", $"Unable to get forced salvage map prototype {forcedSalvage}");
- }
+ var forcedSalvage = _configurationManager.GetCVar(CCVars.SalvageForced);
+ salvageProto = string.IsNullOrWhiteSpace(forcedSalvage)
+ ? _random.Pick(_prototypeManager.EnumeratePrototypes().ToList())
+ : _prototypeManager.Index(forcedSalvage);
+
+ bounds = salvageProto.Bounds;
}
- SalvageMapPrototype? map = null;
- Vector2 spawnLocation = Vector2.Zero;
-
- for (var i = 0; i < allSalvageMaps.Count; i++)
+ if (!TryGetSalvagePlacementLocation(uid, component, bounds, out var spawnLocation, out var spawnAngle))
{
- SalvageMapPrototype attemptedMap = _random.PickAndTake(allSalvageMaps);
- for (var attempt = 0; attempt < SalvageLocationPlaceAttempts; attempt++)
- {
- var randomRadius = _random.NextFloat(component.OffsetRadiusMin, component.OffsetRadiusMax);
- var randomOffset = _random.NextAngle().ToWorldVec() * randomRadius;
- spawnLocation = spl.Position + randomOffset;
-
- var box2 = Box2.CenteredAround(spawnLocation + attemptedMap.Bounds.Center, attemptedMap.Bounds.Size);
- var box2rot = new Box2Rotated(box2, spAngle, spawnLocation);
-
- // This doesn't stop it from spawning on top of random things in space
- // Might be better like this, ghosts could stop it before
- if (!_mapManager.FindGridsIntersecting(spl.MapId, box2rot).Any())
- {
- map = attemptedMap;
- break;
- }
- }
- if (map != null)
- {
- break;
- }
- }
-
- if (map == null)
- {
- Report(component.Owner, component.SalvageChannel, "salvage-system-announcement-spawn-no-debris-available");
+ Report(uid, component.SalvageChannel, "salvage-system-announcement-spawn-no-debris-available");
+ _mapManager.DeleteMap(salvMap);
return false;
}
- var opts = new MapLoadOptions
+ if (salvageEnt is { } ent)
{
- Offset = spawnLocation
- };
-
- var salvageEntityId = _map.LoadGrid(spl.MapId, map.MapPath.ToString(), opts);
- if (salvageEntityId == null)
- {
- Report(component.Owner, component.SalvageChannel, "salvage-system-announcement-spawn-debris-disintegrated");
- return false;
+ var salvXForm = Transform(ent);
+ _transform.SetParent(ent, salvXForm, _mapManager.GetMapEntityId(spawnLocation.MapId));
+ _transform.SetWorldPosition(salvXForm, spawnLocation.Position);
}
- component.AttachedEntity = salvageEntityId;
- var gridcomp = EntityManager.EnsureComponent(salvageEntityId.Value);
- gridcomp.SpawnerMagnet = component;
+ else if (salvageProto != null)
+ {
+ var opts = new MapLoadOptions
+ {
+ Offset = spawnLocation.Position,
+ Rotation = spawnAngle
+ };
- var pulledTransform = EntityManager.GetComponent(salvageEntityId.Value);
- pulledTransform.WorldRotation = spAngle;
+ if (!_map.TryLoad(spawnLocation.MapId, salvageProto.MapPath.ToString(), out var roots, opts) ||
+ roots.FirstOrNull() is not { } root)
+ {
+ Report(uid, component.SalvageChannel, "salvage-system-announcement-spawn-debris-disintegrated");
+ _mapManager.DeleteMap(salvMap);
+ return false;
+ }
- Report(component.Owner, component.SalvageChannel, "salvage-system-announcement-arrived", ("timeLeft", component.HoldTime.TotalSeconds));
+ salvageEnt = root;
+ }
+ else
+ {
+ throw new InvalidOperationException("No asteroid generated and no salvage prototype present.");
+ }
+
+ component.AttachedEntity = salvageEnt;
+ var gridcomp = EnsureComp(salvageEnt.Value);
+ gridcomp.SpawnerMagnet = uid;
+ _transform.SetWorldRotation(salvageEnt.Value, spawnAngle);
+
+ Report(uid, component.SalvageChannel, "salvage-system-announcement-arrived", ("timeLeft", component.HoldTime.TotalSeconds));
+ _mapManager.DeleteMap(salvMap);
return true;
}
private void Report(EntityUid source, string channelName, string messageKey, params (string, object)[] args)
{
- if (!TryComp(source, out var radio)) return;
-
var message = args.Length == 0 ? Loc.GetString(messageKey) : Loc.GetString(messageKey, args);
var channel = _prototypeManager.Index(channelName);
_radioSystem.SendRadioMessage(source, message, channel, source);
}
- private void Transition(SalvageMagnetComponent magnet, TimeSpan currentTime)
+ private void Transition(EntityUid uid, SalvageMagnetComponent magnet, TimeSpan currentTime)
{
switch (magnet.MagnetState.StateType)
{
case MagnetStateType.Attaching:
- if (SpawnSalvage(magnet))
+ if (SpawnSalvage(uid, magnet))
{
magnet.MagnetState = new MagnetState(MagnetStateType.Holding, currentTime + magnet.HoldTime);
}
@@ -424,7 +423,7 @@ namespace Content.Server.Salvage
}
break;
case MagnetStateType.Holding:
- Report(magnet.Owner, magnet.SalvageChannel, "salvage-system-announcement-losing", ("timeLeft", magnet.DetachingTime.TotalSeconds));
+ Report(uid, magnet.SalvageChannel, "salvage-system-announcement-losing", ("timeLeft", magnet.DetachingTime.TotalSeconds));
magnet.MagnetState = new MagnetState(MagnetStateType.Detaching, currentTime + magnet.DetachingTime);
break;
case MagnetStateType.Detaching:
@@ -434,41 +433,42 @@ namespace Content.Server.Salvage
}
else
{
- Logger.ErrorS("salvage", "Salvage detaching was expecting attached entity but it was null");
+ Log.Error("Salvage detaching was expecting attached entity but it was null");
}
- Report(magnet.Owner, magnet.SalvageChannel, "salvage-system-announcement-lost");
+ Report(uid, magnet.SalvageChannel, "salvage-system-announcement-lost");
magnet.MagnetState = new MagnetState(MagnetStateType.CoolingDown, currentTime + magnet.CooldownTime);
break;
case MagnetStateType.CoolingDown:
magnet.MagnetState = MagnetState.Inactive;
break;
}
- UpdateAppearance(magnet.Owner, magnet);
- UpdateChargeStateAppearance(magnet.Owner, currentTime, magnet);
+ UpdateAppearance(uid, magnet);
+ UpdateChargeStateAppearance(uid, currentTime, magnet);
}
public override void Update(float frameTime)
{
var secondsPassed = TimeSpan.FromSeconds(frameTime);
// Keep track of time, and state per grid
- foreach (var gridIdAndState in _salvageGridStates)
+ foreach (var (uid, state) in _salvageGridStates)
{
- var state = gridIdAndState.Value;
if (state.ActiveMagnets.Count == 0) continue;
- var gridId = gridIdAndState.Key;
// Not handling the case where the salvage we spawned got paused
// They both need to be paused, or it doesn't make sense
- if (MetaData(gridId).EntityPaused) continue;
+ if (MetaData(uid).EntityPaused) continue;
state.CurrentTime += secondsPassed;
- var deleteQueue = new RemQueue();
+ var deleteQueue = new RemQueue();
foreach(var magnet in state.ActiveMagnets)
{
- UpdateChargeStateAppearance(magnet.Owner, state.CurrentTime, magnet);
- if (magnet.MagnetState.Until > state.CurrentTime) continue;
- Transition(magnet, state.CurrentTime);
- if (magnet.MagnetState.StateType == MagnetStateType.Inactive)
+ if (!TryComp(magnet, out var magnetComp))
+ continue;
+
+ UpdateChargeStateAppearance(magnet, state.CurrentTime, magnetComp);
+ if (magnetComp.MagnetState.Until > state.CurrentTime) continue;
+ Transition(magnet, magnetComp, state.CurrentTime);
+ if (magnetComp.MagnetState.StateType == MagnetStateType.Inactive)
{
deleteQueue.Add(magnet);
}
@@ -488,7 +488,7 @@ namespace Content.Server.Salvage
public sealed class SalvageGridState
{
public TimeSpan CurrentTime { get; set; }
- public List ActiveMagnets { get; } = new();
+ public List ActiveMagnets { get; } = new();
}
}
diff --git a/Content.Server/Worldgen/Systems/LocalityLoaderSystem.cs b/Content.Server/Worldgen/Systems/LocalityLoaderSystem.cs
index 97ed4c50be..2f3cffbe11 100644
--- a/Content.Server/Worldgen/Systems/LocalityLoaderSystem.cs
+++ b/Content.Server/Worldgen/Systems/LocalityLoaderSystem.cs
@@ -21,7 +21,11 @@ public sealed class LocalityLoaderSystem : BaseWorldSystem
while (e.MoveNext(out var uid, out var loadable, out var xform))
{
if (!controllerQuery.TryGetComponent(xform.MapUid, out var controller))
- return;
+ {
+ RaiseLocalEvent(uid, new LocalStructureLoadedEvent());
+ RemCompDeferred(uid);
+ continue;
+ }
var coords = GetChunkCoords(uid, xform);
var done = false;
diff --git a/Resources/Prototypes/Entities/Structures/Machines/salvage.yml b/Resources/Prototypes/Entities/Structures/Machines/salvage.yml
index 56c6689b3e..e029a27051 100644
--- a/Resources/Prototypes/Entities/Structures/Machines/salvage.yml
+++ b/Resources/Prototypes/Entities/Structures/Machines/salvage.yml
@@ -71,8 +71,14 @@
description: Locates salvage.
components:
- type: SalvageMagnet
- offsetRadiusMin: 12
- offsetRadiusMax: 48
+ offsetRadiusMax: 32
- type: ApcPowerReceiver
powerLoad: 1000
+- type: weightedRandom
+ id: RandomAsteroidPool
+ weights:
+ AsteroidSalvageSmall: 3
+ AsteroidSalvageMedium: 7
+ AsteroidSalvageLarge: 5
+ AsteroidSalvageHuge: 3
diff --git a/Resources/Prototypes/Entities/World/Debris/asteroids.yml b/Resources/Prototypes/Entities/World/Debris/asteroids.yml
index 0c55e9060f..99b46be9a6 100644
--- a/Resources/Prototypes/Entities/World/Debris/asteroids.yml
+++ b/Resources/Prototypes/Entities/World/Debris/asteroids.yml
@@ -16,18 +16,31 @@
FloorAsteroidCoarseSand0:
- id: WallRock
prob: 0.5
- - id: WallRockGold
- prob: 0.01
- - id: WallRockSilver
- prob: 0.04
- - id: WallRockPlasma
- prob: 0.09
+ orGroup: rock
- id: WallRockTin
- prob: 0.2
- - id: WallRockUranium
- prob: 0.07
+ prob: 0.15
+ orGroup: rock
- id: WallRockQuartz
- prob: 0.2
+ prob: 0.15
+ orGroup: rock
+ - id: WallRockGold
+ prob: 0.05
+ orGroup: rock
+ - id: WallRockSilver
+ prob: 0.05
+ orGroup: rock
+ - id: WallRockPlasma
+ prob: 0.05
+ orGroup: rock
+ - id: WallRockUranium
+ prob: 0.02
+ orGroup: rock
+ - id: WallRockBananium
+ prob: 0.02
+ orGroup: rock
+ - id: WallRockArtifactFragment
+ prob: 0.01
+ orGroup: rock
- type: GCAbleObject
queue: SpaceDebris
- type: IFF
@@ -74,3 +87,51 @@
- type: BlobFloorPlanBuilder
radius: 12
floorPlacements: 36
+
+- type: entity
+ id: AsteroidSalvageSmall
+ parent: BaseAsteroidDebris
+ name: Salvage Asteroid Small
+ noSpawn: true
+ components:
+ - type: MapGrid
+ - type: BlobFloorPlanBuilder
+ blobDrawProb: 0.66
+ radius: 15
+ floorPlacements: 100
+
+- type: entity
+ id: AsteroidSalvageMedium
+ parent: BaseAsteroidDebris
+ name: Salvage Asteroid Medium
+ noSpawn: true
+ components:
+ - type: MapGrid
+ - type: BlobFloorPlanBuilder
+ blobDrawProb: 0.66
+ radius: 17
+ floorPlacements: 150
+
+- type: entity
+ id: AsteroidSalvageLarge
+ parent: BaseAsteroidDebris
+ name: Salvage Asteroid Large
+ noSpawn: true
+ components:
+ - type: MapGrid
+ - type: BlobFloorPlanBuilder
+ blobDrawProb: 0.66
+ radius: 20
+ floorPlacements: 200
+
+- type: entity
+ id: AsteroidSalvageHuge
+ parent: BaseAsteroidDebris
+ name: Salvage Asteroid Huge
+ noSpawn: true
+ components:
+ - type: MapGrid
+ - type: BlobFloorPlanBuilder
+ blobDrawProb: 0.66
+ radius: 23
+ floorPlacements: 250