Merge pull request #301 from crystallpunk-14/ed-05-07-2024-upstream
Upstream sync
This commit is contained in:
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"omnisharp.analyzeOpenDocumentsOnly": true,
|
||||
"dotnet.defaultSolution": "SpaceStation14.sln"
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Client.BarSign.Ui;
|
||||
using Content.Shared.BarSign;
|
||||
using Content.Shared.Power;
|
||||
using Robust.Client.GameObjects;
|
||||
@@ -8,6 +9,7 @@ namespace Content.Client.BarSign;
|
||||
public sealed class BarSignSystem : VisualizerSystem<BarSignComponent>
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly UserInterfaceSystem _ui = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -17,6 +19,9 @@ public sealed class BarSignSystem : VisualizerSystem<BarSignComponent>
|
||||
|
||||
private void OnAfterAutoHandleState(EntityUid uid, BarSignComponent component, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
if (_ui.TryGetOpenUi<BarSignBoundUserInterface>(uid, BarSignUiKey.Key, out var bui))
|
||||
bui.Update(component.Current);
|
||||
|
||||
UpdateAppearance(uid, component);
|
||||
}
|
||||
|
||||
@@ -34,9 +39,9 @@ public sealed class BarSignSystem : VisualizerSystem<BarSignComponent>
|
||||
|
||||
if (powered
|
||||
&& sign.Current != null
|
||||
&& _prototypeManager.TryIndex(sign.Current, out BarSignPrototype? proto))
|
||||
&& _prototypeManager.TryIndex(sign.Current, out var proto))
|
||||
{
|
||||
sprite.LayerSetState(0, proto.Icon);
|
||||
sprite.LayerSetSprite(0, proto.Icon);
|
||||
sprite.LayerSetShader(0, "unshaded");
|
||||
}
|
||||
else
|
||||
|
||||
50
Content.Client/BarSign/Ui/BarSignBoundUserInterface.cs
Normal file
50
Content.Client/BarSign/Ui/BarSignBoundUserInterface.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System.Linq;
|
||||
using Content.Shared.BarSign;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.BarSign.Ui;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class BarSignBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey)
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
|
||||
private BarSignMenu? _menu;
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
var sign = EntMan.GetComponentOrNull<BarSignComponent>(Owner)?.Current is { } current
|
||||
? _prototype.Index(current)
|
||||
: null;
|
||||
var allSigns = Shared.BarSign.BarSignSystem.GetAllBarSigns(_prototype)
|
||||
.OrderBy(p => Loc.GetString(p.Name))
|
||||
.ToList();
|
||||
_menu = new(sign, allSigns);
|
||||
|
||||
_menu.OnSignSelected += id =>
|
||||
{
|
||||
SendMessage(new SetBarSignMessage(id));
|
||||
};
|
||||
|
||||
_menu.OnClose += Close;
|
||||
_menu.OpenCentered();
|
||||
}
|
||||
|
||||
public void Update(ProtoId<BarSignPrototype>? sign)
|
||||
{
|
||||
if (_prototype.TryIndex(sign, out var signPrototype))
|
||||
_menu?.UpdateState(signPrototype);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
if (!disposing)
|
||||
return;
|
||||
_menu?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
19
Content.Client/BarSign/Ui/BarSignMenu.xaml
Normal file
19
Content.Client/BarSign/Ui/BarSignMenu.xaml
Normal file
@@ -0,0 +1,19 @@
|
||||
<controls:FancyWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
Title="{Loc 'barsign-ui-menu'}"
|
||||
MinSize="280 180"
|
||||
SetSize="280 180">
|
||||
<BoxContainer VerticalExpand="True" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="10 5 10 10">
|
||||
<BoxContainer Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
|
||||
<BoxContainer Orientation="Vertical" HorizontalAlignment="Center">
|
||||
<Label Text="{Loc 'barsign-ui-set-label'}" HorizontalAlignment="Center" StyleClasses="LabelSubText" Margin="30 0"/>
|
||||
<customControls:HSeparator Margin="0 0 0 5"/>
|
||||
</BoxContainer>
|
||||
<OptionButton Name="SignOptions" HorizontalAlignment="Center" VerticalAlignment="Center" MinSize="175 60" Margin="0 0 0 20"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</controls:FancyWindow>
|
||||
|
||||
|
||||
50
Content.Client/BarSign/Ui/BarSignMenu.xaml.cs
Normal file
50
Content.Client/BarSign/Ui/BarSignMenu.xaml.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.BarSign;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client.BarSign.Ui;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class BarSignMenu : FancyWindow
|
||||
{
|
||||
private string? _currentId;
|
||||
|
||||
private readonly List<BarSignPrototype> _cachedPrototypes = new();
|
||||
|
||||
public event Action<string>? OnSignSelected;
|
||||
|
||||
public BarSignMenu(BarSignPrototype? currentSign, List<BarSignPrototype> signs)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
_currentId = currentSign?.ID;
|
||||
|
||||
_cachedPrototypes.Clear();
|
||||
_cachedPrototypes = signs;
|
||||
foreach (var proto in _cachedPrototypes)
|
||||
{
|
||||
SignOptions.AddItem(Loc.GetString(proto.Name));
|
||||
}
|
||||
|
||||
SignOptions.OnItemSelected += idx =>
|
||||
{
|
||||
OnSignSelected?.Invoke(_cachedPrototypes[idx.Id].ID);
|
||||
SignOptions.SelectId(idx.Id);
|
||||
};
|
||||
|
||||
if (currentSign != null)
|
||||
{
|
||||
var idx = _cachedPrototypes.IndexOf(currentSign);
|
||||
SignOptions.TrySelectId(idx);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateState(BarSignPrototype newSign)
|
||||
{
|
||||
if (_currentId != null && newSign.ID == _currentId)
|
||||
return;
|
||||
_currentId = newSign.ID;
|
||||
var idx = _cachedPrototypes.IndexOf(newSign);
|
||||
SignOptions.TrySelectId(idx);
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ namespace Content.Client.Clickable
|
||||
Angle cardinalSnapping = sprite.SnapCardinals ? relativeRotation.GetCardinalDir().ToAngle() : Angle.Zero;
|
||||
|
||||
// First we get `localPos`, the clicked location in the sprite-coordinate frame.
|
||||
var entityXform = Matrix3Helpers.CreateInverseTransform(transform.WorldPosition, sprite.NoRotation ? -eye.Rotation : spriteRot - cardinalSnapping);
|
||||
var entityXform = Matrix3Helpers.CreateInverseTransform(spritePos, sprite.NoRotation ? -eye.Rotation : spriteRot - cardinalSnapping);
|
||||
var localPos = Vector2.Transform(Vector2.Transform(worldPos, entityXform), invSpriteMatrix);
|
||||
|
||||
// Check explicitly defined click-able bounds
|
||||
@@ -58,8 +58,11 @@ namespace Content.Client.Clickable
|
||||
// Next check each individual sprite layer using automatically computed click maps.
|
||||
foreach (var spriteLayer in sprite.AllLayers)
|
||||
{
|
||||
if (!spriteLayer.Visible || spriteLayer is not Layer layer)
|
||||
// TODO: Move this to a system and also use SpriteSystem.IsVisible instead.
|
||||
if (!spriteLayer.Visible || spriteLayer is not Layer layer || layer.CopyToShaderParameters != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check the layer's texture, if it has one
|
||||
if (layer.Texture != null)
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class ZoomCommand : LocalizedCommands
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
Vector2 zoom;
|
||||
if (args.Length is not (1 or 2))
|
||||
if (args.Length is not (1 or 2 or 3))
|
||||
{
|
||||
shell.WriteLine(Help);
|
||||
return;
|
||||
@@ -57,11 +57,18 @@ public sealed class ZoomCommand : LocalizedCommands
|
||||
}
|
||||
}
|
||||
|
||||
var scalePvs = true;
|
||||
if (args.Length == 3 && !bool.TryParse(args[2], out scalePvs))
|
||||
{
|
||||
shell.WriteError(LocalizationManager.GetString("cmd-parse-failure-bool", ("arg", args[2])));
|
||||
return;
|
||||
}
|
||||
|
||||
var player = _playerManager.LocalSession?.AttachedEntity;
|
||||
|
||||
if (_entityManager.TryGetComponent<ContentEyeComponent>(player, out var content))
|
||||
{
|
||||
_entityManager.System<ContentEyeSystem>().RequestZoom(player.Value, zoom, true, content);
|
||||
_entityManager.System<ContentEyeSystem>().RequestZoom(player.Value, zoom, true, scalePvs, content);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Client.Verbs;
|
||||
using Content.Shared.Eye.Blinding;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Input;
|
||||
@@ -16,8 +15,6 @@ using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Threading;
|
||||
using Content.Shared.Eye.Blinding.Components;
|
||||
using Robust.Client;
|
||||
using static Content.Shared.Interaction.SharedInteractionSystem;
|
||||
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||
using Content.Shared.Interaction.Events;
|
||||
@@ -360,10 +357,7 @@ namespace Content.Client.Examine
|
||||
|
||||
FormattedMessage message;
|
||||
|
||||
// Basically this just predicts that we can't make out the entity if we have poor vision.
|
||||
var canSeeClearly = !HasComp<BlurryVisionComponent>(playerEnt);
|
||||
|
||||
OpenTooltip(playerEnt.Value, entity, centeredOnCursor, false, knowTarget: canSeeClearly);
|
||||
OpenTooltip(playerEnt.Value, entity, centeredOnCursor, false);
|
||||
|
||||
// Always update tooltip info from client first.
|
||||
// If we get it wrong, server will correct us later anyway.
|
||||
|
||||
@@ -48,6 +48,9 @@ namespace Content.Client.Jittering
|
||||
if(args.Key != _jitterAnimationKey)
|
||||
return;
|
||||
|
||||
if (!args.Finished)
|
||||
return;
|
||||
|
||||
if (TryComp(uid, out AnimationPlayerComponent? animationPlayer)
|
||||
&& TryComp(uid, out SpriteComponent? sprite))
|
||||
_animationPlayer.Play(uid, animationPlayer, GetAnimation(jittering, sprite), _jitterAnimationKey);
|
||||
|
||||
@@ -217,12 +217,12 @@ public sealed partial class LatheMenu : DefaultWindow
|
||||
queuedRecipeBox.Orientation = BoxContainer.LayoutOrientation.Horizontal;
|
||||
|
||||
var queuedRecipeProto = new EntityPrototypeView();
|
||||
queuedRecipeBox.AddChild(queuedRecipeProto);
|
||||
if (_prototypeManager.TryIndex(recipe.Result, out EntityPrototype? entityProto) && entityProto != null)
|
||||
queuedRecipeProto.SetPrototype(entityProto);
|
||||
|
||||
var queuedRecipeLabel = new Label();
|
||||
queuedRecipeLabel.Text = $"{idx}. {recipe.Name}";
|
||||
queuedRecipeBox.AddChild(queuedRecipeProto);
|
||||
queuedRecipeBox.AddChild(queuedRecipeLabel);
|
||||
QueueList.AddChild(queuedRecipeBox);
|
||||
idx++;
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace Content.Client.Launcher
|
||||
private void ChangeLoginTip()
|
||||
{
|
||||
var tipsDataset = _cfg.GetCVar(CCVars.LoginTipsDataset);
|
||||
var loginTipsEnabled = _prototype.TryIndex<DatasetPrototype>(tipsDataset, out var tips);
|
||||
var loginTipsEnabled = _prototype.TryIndex<LocalizedDatasetPrototype>(tipsDataset, out var tips);
|
||||
|
||||
LoginTips.Visible = loginTipsEnabled;
|
||||
if (!loginTipsEnabled)
|
||||
@@ -131,7 +131,7 @@ namespace Content.Client.Launcher
|
||||
|
||||
var randomIndex = _random.Next(tipList.Count);
|
||||
var tip = tipList[randomIndex];
|
||||
LoginTip.SetMessage(tip);
|
||||
LoginTip.SetMessage(Loc.GetString(tip));
|
||||
|
||||
LoginTipTitle.Text = Loc.GetString("connecting-window-tip", ("numberTip", randomIndex));
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ public sealed class LightBehaviorSystem : EntitySystem
|
||||
|
||||
private void OnBehaviorAnimationCompleted(EntityUid uid, LightBehaviourComponent component, AnimationCompletedEvent args)
|
||||
{
|
||||
if (!args.Finished)
|
||||
return;
|
||||
|
||||
var container = component.Animations.FirstOrDefault(x => x.FullKey == args.Key);
|
||||
|
||||
if (container == null)
|
||||
|
||||
@@ -69,6 +69,9 @@ public sealed class RotatingLightSystem : SharedRotatingLightSystem
|
||||
|
||||
private void OnAnimationComplete(EntityUid uid, RotatingLightComponent comp, AnimationCompletedEvent args)
|
||||
{
|
||||
if (!args.Finished)
|
||||
return;
|
||||
|
||||
PlayAnimation(uid, comp);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.Replays.Loading;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
@@ -46,13 +45,19 @@ public sealed class MouseRotatorSystem : SharedMouseRotatorSystem
|
||||
// only raise event if the cardinal direction has changed
|
||||
if (rotator.Simple4DirMode)
|
||||
{
|
||||
var angleDir = angle.GetCardinalDir();
|
||||
if (angleDir == curRot.GetCardinalDir())
|
||||
var eyeRot = _eye.CurrentEye.Rotation; // camera rotation
|
||||
var angleDir = (angle + eyeRot).GetCardinalDir(); // apply GetCardinalDir in the camera frame, not in the world frame
|
||||
if (angleDir == (curRot + eyeRot).GetCardinalDir())
|
||||
return;
|
||||
|
||||
RaisePredictiveEvent(new RequestMouseRotatorRotationSimpleEvent()
|
||||
var rotation = angleDir.ToAngle() - eyeRot; // convert back to world frame
|
||||
if (rotation >= Math.PI) // convert to [-PI, +PI)
|
||||
rotation -= 2 * Math.PI;
|
||||
else if (rotation < -Math.PI)
|
||||
rotation += 2 * Math.PI;
|
||||
RaisePredictiveEvent(new RequestMouseRotatorRotationEvent
|
||||
{
|
||||
Direction = angleDir,
|
||||
Rotation = rotation
|
||||
});
|
||||
|
||||
return;
|
||||
|
||||
@@ -9,7 +9,7 @@ public sealed class ContentEyeSystem : SharedContentEyeSystem
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
|
||||
public void RequestZoom(EntityUid uid, Vector2 zoom, bool ignoreLimit, ContentEyeComponent? content = null)
|
||||
public void RequestZoom(EntityUid uid, Vector2 zoom, bool ignoreLimit, bool scalePvs, ContentEyeComponent? content = null)
|
||||
{
|
||||
if (!Resolve(uid, ref content, false))
|
||||
return;
|
||||
@@ -19,6 +19,14 @@ public sealed class ContentEyeSystem : SharedContentEyeSystem
|
||||
TargetZoom = zoom,
|
||||
IgnoreLimit = ignoreLimit,
|
||||
});
|
||||
|
||||
if (scalePvs)
|
||||
RequestPvsScale(Math.Max(zoom.X, zoom.Y));
|
||||
}
|
||||
|
||||
public void RequestPvsScale(float scale)
|
||||
{
|
||||
RaiseNetworkEvent(new RequestPvsScaleEvent(scale));
|
||||
}
|
||||
|
||||
public void RequestToggleFov()
|
||||
|
||||
@@ -23,8 +23,8 @@ public sealed class RotationVisualizerSystem : SharedRotationVisualsSystem
|
||||
if (args.Sprite == null)
|
||||
return;
|
||||
|
||||
// If not defined, defaults to standing.
|
||||
_appearance.TryGetData<RotationState>(uid, RotationVisuals.RotationState, out var state, args.Component);
|
||||
if (!_appearance.TryGetData<RotationState>(uid, RotationVisuals.RotationState, out var state, args.Component))
|
||||
return;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
|
||||
@@ -129,14 +129,7 @@ public sealed partial class SensorMonitoringWindow : FancyWindow, IComputerWindo
|
||||
|
||||
foreach (var stream in sensor.Streams.Values)
|
||||
{
|
||||
var maxValue = stream.Unit switch
|
||||
{
|
||||
SensorUnit.PressureKpa => 5000, // 5 MPa
|
||||
SensorUnit.Ratio => 1,
|
||||
SensorUnit.PowerW => 1_000_000, // 1 MW
|
||||
SensorUnit.EnergyJ => 2_000_000, // 2 MJ
|
||||
_ => 1000
|
||||
};
|
||||
var maxValue = stream.Samples.Max(x => x.Value);
|
||||
|
||||
// TODO: Better way to do this?
|
||||
var lastSample = stream.Samples.Last();
|
||||
@@ -151,7 +144,7 @@ public sealed partial class SensorMonitoringWindow : FancyWindow, IComputerWindo
|
||||
}
|
||||
});
|
||||
|
||||
Asdf.AddChild(new GraphView(stream.Samples, startTime, curTime, maxValue) { MinHeight = 150 });
|
||||
Asdf.AddChild(new GraphView(stream.Samples, startTime, curTime, maxValue * 1.1f) { MinHeight = 150 });
|
||||
Asdf.AddChild(new PanelContainer { StyleClasses = { StyleBase.ClassLowDivider } });
|
||||
}
|
||||
}
|
||||
|
||||
82
Content.Client/Shuttles/FtlArrivalOverlay.cs
Normal file
82
Content.Client/Shuttles/FtlArrivalOverlay.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Shuttles.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.Shuttles;
|
||||
|
||||
/// <summary>
|
||||
/// Plays a visualization whenever a shuttle is arriving from FTL.
|
||||
/// </summary>
|
||||
public sealed class FtlArrivalOverlay : Overlay
|
||||
{
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowEntities;
|
||||
|
||||
private EntityLookupSystem _lookups;
|
||||
private SharedMapSystem _maps;
|
||||
private SharedTransformSystem _transforms;
|
||||
private SpriteSystem _sprites;
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IPrototypeManager _protos = default!;
|
||||
|
||||
private readonly HashSet<Entity<FtlVisualizerComponent>> _visualizers = new();
|
||||
|
||||
private ShaderInstance _shader;
|
||||
|
||||
public FtlArrivalOverlay()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
_lookups = _entManager.System<EntityLookupSystem>();
|
||||
_transforms = _entManager.System<SharedTransformSystem>();
|
||||
_maps = _entManager.System<SharedMapSystem>();
|
||||
_sprites = _entManager.System<SpriteSystem>();
|
||||
|
||||
_shader = _protos.Index<ShaderPrototype>("unshaded").Instance();
|
||||
}
|
||||
|
||||
protected override bool BeforeDraw(in OverlayDrawArgs args)
|
||||
{
|
||||
_visualizers.Clear();
|
||||
_lookups.GetEntitiesOnMap(args.MapId, _visualizers);
|
||||
|
||||
return _visualizers.Count > 0;
|
||||
}
|
||||
|
||||
protected override void Draw(in OverlayDrawArgs args)
|
||||
{
|
||||
args.WorldHandle.UseShader(_shader);
|
||||
|
||||
foreach (var (uid, comp) in _visualizers)
|
||||
{
|
||||
var grid = comp.Grid;
|
||||
|
||||
if (!_entManager.TryGetComponent(grid, out MapGridComponent? mapGrid))
|
||||
continue;
|
||||
|
||||
var texture = _sprites.GetFrame(comp.Sprite, TimeSpan.FromSeconds(comp.Elapsed), loop: false);
|
||||
comp.Elapsed += (float) _timing.FrameTime.TotalSeconds;
|
||||
|
||||
// Need to manually transform the viewport in terms of the visualizer entity as the grid isn't in position.
|
||||
var (_, _, worldMatrix, invMatrix) = _transforms.GetWorldPositionRotationMatrixWithInv(uid);
|
||||
args.WorldHandle.SetTransform(worldMatrix);
|
||||
var localAABB = invMatrix.TransformBox(args.WorldBounds);
|
||||
|
||||
var tilesEnumerator = _maps.GetLocalTilesEnumerator(grid, mapGrid, localAABB);
|
||||
|
||||
while (tilesEnumerator.MoveNext(out var tile))
|
||||
{
|
||||
var bounds = _lookups.GetLocalBounds(tile, mapGrid.TileSize);
|
||||
|
||||
args.WorldHandle.DrawTextureRect(texture, bounds);
|
||||
}
|
||||
}
|
||||
|
||||
args.WorldHandle.UseShader(null);
|
||||
args.WorldHandle.SetTransform(Matrix3x2.Identity);
|
||||
}
|
||||
}
|
||||
@@ -38,9 +38,8 @@ public sealed partial class ShuttleSystem : SharedShuttleSystem
|
||||
private bool _enableShuttlePosition;
|
||||
private EmergencyShuttleOverlay? _overlay;
|
||||
|
||||
public override void Initialize()
|
||||
private void InitializeEmergency()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeNetworkEvent<EmergencyShuttlePositionMessage>(OnShuttlePosMessage);
|
||||
}
|
||||
|
||||
|
||||
21
Content.Client/Shuttles/Systems/ShuttleSystem.cs
Normal file
21
Content.Client/Shuttles/Systems/ShuttleSystem.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Robust.Client.Graphics;
|
||||
|
||||
namespace Content.Client.Shuttles.Systems;
|
||||
|
||||
public sealed partial class ShuttleSystem
|
||||
{
|
||||
[Dependency] private readonly IOverlayManager _overlays = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
InitializeEmergency();
|
||||
_overlays.AddOverlay(new FtlArrivalOverlay());
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
base.Shutdown();
|
||||
_overlays.RemoveOverlay<FtlArrivalOverlay>();
|
||||
}
|
||||
}
|
||||
@@ -67,11 +67,18 @@ public class RadialContainer : LayoutContainer
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected override void Draw(DrawingHandleScreen handle)
|
||||
{
|
||||
|
||||
const float baseRadius = 100f;
|
||||
const float radiusIncrement = 5f;
|
||||
|
||||
var children = ReserveSpaceForHiddenChildren ? Children : Children.Where(x => x.Visible);
|
||||
var childCount = children.Count();
|
||||
|
||||
// Add padding from the center at higher child counts so they don't overlap.
|
||||
Radius = baseRadius + (childCount * radiusIncrement);
|
||||
|
||||
// Determine the size of the arc, accounting for clockwise and anti-clockwise arrangements
|
||||
var arc = AngularRange.Y - AngularRange.X;
|
||||
|
||||
@@ -18,7 +18,7 @@ public sealed class ActionsAddedTest
|
||||
[Test]
|
||||
public async Task TestCombatActionsAdded()
|
||||
{
|
||||
await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true, DummyTicker = false});
|
||||
await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true, DummyTicker = false });
|
||||
var server = pair.Server;
|
||||
var client = pair.Client;
|
||||
var sEntMan = server.ResolveDependency<IEntityManager>();
|
||||
|
||||
@@ -5,7 +5,7 @@ using Robust.Shared.GameObjects;
|
||||
namespace Content.IntegrationTests.Tests.Body;
|
||||
|
||||
[TestFixture]
|
||||
public sealed class GibTest
|
||||
public sealed class GibTest
|
||||
{
|
||||
[Test]
|
||||
public async Task TestGib()
|
||||
|
||||
@@ -5,7 +5,6 @@ using Content.Shared.Body.Part;
|
||||
using Content.Shared.Rotation;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.Body
|
||||
{
|
||||
@@ -40,13 +39,14 @@ namespace Content.IntegrationTests.Tests.Body
|
||||
var appearanceSystem = entityManager.System<SharedAppearanceSystem>();
|
||||
var xformSystem = entityManager.System<SharedTransformSystem>();
|
||||
|
||||
var map = await pair.CreateTestMap();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var mapId = mapManager.CreateMap();
|
||||
BodyComponent body = null;
|
||||
|
||||
human = entityManager.SpawnEntity("HumanBodyAndAppearanceDummy",
|
||||
new MapCoordinates(Vector2.Zero, mapId));
|
||||
new MapCoordinates(Vector2.Zero, map.MapId));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@@ -61,7 +61,7 @@ namespace Content.IntegrationTests.Tests.Body
|
||||
|
||||
foreach (var leg in legs)
|
||||
{
|
||||
xformSystem.DetachParentToNull(leg.Id, entityManager.GetComponent<TransformComponent>(leg.Id));
|
||||
xformSystem.DetachEntity(leg.Id, entityManager.GetComponent<TransformComponent>(leg.Id));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -60,8 +60,8 @@ namespace Content.IntegrationTests.Tests.Body
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var mapLoader = entityManager.System<MapLoaderSystem>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
|
||||
MapId mapId;
|
||||
EntityUid? grid = null;
|
||||
BodyComponent body = default;
|
||||
RespiratorComponent resp = default;
|
||||
@@ -73,7 +73,7 @@ namespace Content.IntegrationTests.Tests.Body
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
mapId = mapManager.CreateMap();
|
||||
mapSys.CreateMap(out var mapId);
|
||||
Assert.That(mapLoader.TryLoad(mapId, testMapName, out var roots));
|
||||
|
||||
var query = entityManager.GetEntityQuery<MapGridComponent>();
|
||||
@@ -142,8 +142,8 @@ namespace Content.IntegrationTests.Tests.Body
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var cfg = server.ResolveDependency<IConfigurationManager>();
|
||||
var mapLoader = entityManager.System<MapLoaderSystem>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
|
||||
MapId mapId;
|
||||
EntityUid? grid = null;
|
||||
RespiratorComponent respirator = null;
|
||||
EntityUid human = default;
|
||||
@@ -152,7 +152,7 @@ namespace Content.IntegrationTests.Tests.Body
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
mapId = mapManager.CreateMap();
|
||||
mapSys.CreateMap(out var mapId);
|
||||
|
||||
Assert.That(mapLoader.TryLoad(mapId, testMapName, out var ents), Is.True);
|
||||
var query = entityManager.GetEntityQuery<MapGridComponent>();
|
||||
|
||||
@@ -33,10 +33,11 @@ public sealed class SaveLoadReparentTest
|
||||
var mapLoader = entities.System<MapLoaderSystem>();
|
||||
var bodySystem = entities.System<SharedBodySystem>();
|
||||
var containerSystem = entities.System<SharedContainerSystem>();
|
||||
var mapSys = entities.System<SharedMapSystem>();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var mapId = maps.CreateMap();
|
||||
mapSys.CreateMap(out var mapId);
|
||||
maps.CreateGrid(mapId);
|
||||
var human = entities.SpawnEntity("HumanBodyDummy", new MapCoordinates(0, 0, mapId));
|
||||
|
||||
@@ -115,7 +116,7 @@ public sealed class SaveLoadReparentTest
|
||||
mapLoader.SaveMap(mapId, mapPath);
|
||||
maps.DeleteMap(mapId);
|
||||
|
||||
mapId = maps.CreateMap();
|
||||
mapSys.CreateMap(out mapId);
|
||||
Assert.That(mapLoader.TryLoad(mapId, mapPath, out _), Is.True);
|
||||
|
||||
var query = EnumerateQueryEnumerator(
|
||||
|
||||
@@ -38,13 +38,13 @@ public sealed class BuckleDragTest : InteractionTest
|
||||
await RunTicks(5);
|
||||
Assert.That(buckle.Buckled, Is.True);
|
||||
Assert.That(buckle.BuckledTo, Is.EqualTo(STarget));
|
||||
Assert.That(strap.BuckledEntities, Is.EquivalentTo(new[]{sUrist}));
|
||||
Assert.That(strap.BuckledEntities, Is.EquivalentTo(new[] { sUrist }));
|
||||
Assert.That(puller.Pulling, Is.Null);
|
||||
Assert.That(pullable.Puller, Is.Null);
|
||||
Assert.That(pullable.BeingPulled, Is.False);
|
||||
|
||||
// Start pulling, and thus unbuckle them
|
||||
await PressKey(ContentKeyFunctions.TryPullObject, cursorEntity:urist);
|
||||
await PressKey(ContentKeyFunctions.TryPullObject, cursorEntity: urist);
|
||||
await RunTicks(5);
|
||||
Assert.That(buckle.Buckled, Is.False);
|
||||
Assert.That(buckle.BuckledTo, Is.Null);
|
||||
|
||||
@@ -19,11 +19,11 @@ namespace Content.IntegrationTests.Tests;
|
||||
[TestFixture]
|
||||
public sealed class CargoTest
|
||||
{
|
||||
public static HashSet<ProtoId<CargoProductPrototype>> Ignored = new ()
|
||||
{
|
||||
private static readonly HashSet<ProtoId<CargoProductPrototype>> Ignored =
|
||||
[
|
||||
// This is ignored because it is explicitly intended to be able to sell for more than it costs.
|
||||
new("FunCrateGambling")
|
||||
};
|
||||
];
|
||||
|
||||
[Test]
|
||||
public async Task NoCargoOrderArbitrage()
|
||||
|
||||
@@ -9,10 +9,10 @@ namespace Content.IntegrationTests.Tests.Chemistry
|
||||
{
|
||||
public sealed class FixedPoint2SerializationTest : SerializationTest
|
||||
{
|
||||
protected override Assembly[] Assemblies => new[]
|
||||
{
|
||||
protected override Assembly[] Assemblies =>
|
||||
[
|
||||
typeof(FixedPoint2SerializationTest).Assembly
|
||||
};
|
||||
];
|
||||
|
||||
[Test]
|
||||
public void DeserializeNullTest()
|
||||
@@ -53,6 +53,6 @@ namespace Content.IntegrationTests.Tests.Chemistry
|
||||
[DataDefinition]
|
||||
public sealed partial class FixedPoint2TestDefinition
|
||||
{
|
||||
[DataField("unit")] public FixedPoint2? Unit { get; set; } = FixedPoint2.New(5);
|
||||
[DataField] public FixedPoint2? Unit { get; set; } = FixedPoint2.New(5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Content.Server.Chemistry.Containers.EntitySystems;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Shared.Chemistry.Reaction;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.FixedPoint;
|
||||
@@ -76,7 +76,7 @@ public sealed class SolutionRoundingTest
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
var system = server.System<SolutionContainerSystem>();
|
||||
var system = server.System<SharedSolutionContainerSystem>();
|
||||
var beaker = server.EntMan.SpawnEntity("SolutionRoundingTestContainer", testMap.GridCoords);
|
||||
|
||||
system.TryGetSolution(beaker, "beaker", out var newSolutionEnt, out var newSolution);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Content.Server.Chemistry.Containers.EntitySystems;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -11,7 +11,7 @@ namespace Content.IntegrationTests.Tests.Chemistry;
|
||||
// To ensure volume(A) + volume(B) = volume(A+B)
|
||||
// reactions can change this assumption
|
||||
[TestFixture]
|
||||
[TestOf(typeof(SolutionContainerSystem))]
|
||||
[TestOf(typeof(SharedSolutionContainerSystem))]
|
||||
public sealed class SolutionSystemTests
|
||||
{
|
||||
[TestPrototypes]
|
||||
@@ -51,7 +51,7 @@ public sealed class SolutionSystemTests
|
||||
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var protoMan = server.ResolveDependency<IPrototypeManager>();
|
||||
var containerSystem = entityManager.System<SolutionContainerSystem>();
|
||||
var containerSystem = entityManager.System<SharedSolutionContainerSystem>();
|
||||
var testMap = await pair.CreateTestMap();
|
||||
var coordinates = testMap.GridCoords;
|
||||
|
||||
@@ -97,7 +97,7 @@ public sealed class SolutionSystemTests
|
||||
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var protoMan = server.ResolveDependency<IPrototypeManager>();
|
||||
var containerSystem = entityManager.System<SolutionContainerSystem>();
|
||||
var containerSystem = entityManager.System<SharedSolutionContainerSystem>();
|
||||
var coordinates = testMap.GridCoords;
|
||||
|
||||
EntityUid beaker;
|
||||
@@ -141,7 +141,7 @@ public sealed class SolutionSystemTests
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var protoMan = server.ResolveDependency<IPrototypeManager>();
|
||||
var testMap = await pair.CreateTestMap();
|
||||
var containerSystem = entityManager.System<SolutionContainerSystem>();
|
||||
var containerSystem = entityManager.System<SharedSolutionContainerSystem>();
|
||||
var coordinates = testMap.GridCoords;
|
||||
|
||||
EntityUid beaker;
|
||||
@@ -194,7 +194,7 @@ public sealed class SolutionSystemTests
|
||||
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var protoMan = server.ResolveDependency<IPrototypeManager>();
|
||||
var containerSystem = entityManager.System<SolutionContainerSystem>();
|
||||
var containerSystem = entityManager.System<SharedSolutionContainerSystem>();
|
||||
var testMap = await pair.CreateTestMap();
|
||||
var coordinates = testMap.GridCoords;
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using Content.Server.Chemistry.Containers.EntitySystems;
|
||||
using Content.Shared.Chemistry.Reaction;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
@@ -6,6 +5,7 @@ using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.Chemistry
|
||||
{
|
||||
@@ -34,7 +34,7 @@ namespace Content.IntegrationTests.Tests.Chemistry
|
||||
var prototypeManager = server.ResolveDependency<IPrototypeManager>();
|
||||
var testMap = await pair.CreateTestMap();
|
||||
var coordinates = testMap.GridCoords;
|
||||
var solutionContainerSystem = entityManager.System<SolutionContainerSystem>();
|
||||
var solutionContainerSystem = entityManager.System<SharedSolutionContainerSystem>();
|
||||
|
||||
foreach (var reactionPrototype in prototypeManager.EnumeratePrototypes<ReactionPrototype>())
|
||||
{
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Content.IntegrationTests.Tests.Commands
|
||||
|
||||
Assert.That(netMan.IsConnected);
|
||||
|
||||
Assert.That(sPlayerManager.Sessions.Count(), Is.EqualTo(1));
|
||||
Assert.That(sPlayerManager.Sessions, Has.Length.EqualTo(1));
|
||||
// No bans on record
|
||||
Assert.Multiple(async () =>
|
||||
{
|
||||
@@ -50,7 +50,7 @@ namespace Content.IntegrationTests.Tests.Commands
|
||||
|
||||
var banReason = "test";
|
||||
|
||||
Assert.That(sPlayerManager.Sessions.Count(), Is.EqualTo(1));
|
||||
Assert.That(sPlayerManager.Sessions, Has.Length.EqualTo(1));
|
||||
// Ban the client for 24 hours
|
||||
await server.WaitPost(() => sConsole.ExecuteCommand($"ban {clientSession.Name} {banReason} 1440"));
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Content.IntegrationTests.Tests.Commands
|
||||
});
|
||||
|
||||
await pair.RunTicksSync(5);
|
||||
Assert.That(sPlayerManager.Sessions.Count(), Is.EqualTo(0));
|
||||
Assert.That(sPlayerManager.Sessions, Has.Length.EqualTo(0));
|
||||
Assert.That(!netMan.IsConnected);
|
||||
|
||||
// Try to pardon a ban that does not exist
|
||||
@@ -143,11 +143,11 @@ namespace Content.IntegrationTests.Tests.Commands
|
||||
});
|
||||
|
||||
// Reconnect client. Slightly faster than dirtying the pair.
|
||||
Assert.That(sPlayerManager.Sessions.Count(), Is.EqualTo(0));
|
||||
Assert.That(sPlayerManager.Sessions, Is.Empty);
|
||||
client.SetConnectTarget(server);
|
||||
await client.WaitPost(() => netMan.ClientConnect(null!, 0, null!));
|
||||
await pair.RunTicksSync(5);
|
||||
Assert.That(sPlayerManager.Sessions.Count(), Is.EqualTo(1));
|
||||
Assert.That(sPlayerManager.Sessions, Has.Length.EqualTo(1));
|
||||
|
||||
await pair.CleanReturnAsync();
|
||||
}
|
||||
|
||||
@@ -37,9 +37,9 @@ namespace Content.IntegrationTests.Tests.Commands
|
||||
var server = pair.Server;
|
||||
var entManager = server.ResolveDependency<IEntityManager>();
|
||||
var prototypeManager = server.ResolveDependency<IPrototypeManager>();
|
||||
var mobStateSystem = entManager.EntitySysManager.GetEntitySystem<MobStateSystem>();
|
||||
var damSystem = entManager.EntitySysManager.GetEntitySystem<DamageableSystem>();
|
||||
var rejuvenateSystem = entManager.EntitySysManager.GetEntitySystem<RejuvenateSystem>();
|
||||
var mobStateSystem = entManager.System<MobStateSystem>();
|
||||
var damSystem = entManager.System<DamageableSystem>();
|
||||
var rejuvenateSystem = entManager.System<RejuvenateSystem>();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Content.IntegrationTests.Tests.Commands
|
||||
|
||||
var configManager = server.ResolveDependency<IConfigurationManager>();
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var gameTicker = entityManager.EntitySysManager.GetEntitySystem<GameTicker>();
|
||||
var gameTicker = entityManager.System<GameTicker>();
|
||||
|
||||
await pair.RunTicksSync(5);
|
||||
|
||||
|
||||
@@ -43,11 +43,11 @@ namespace Content.IntegrationTests.Tests
|
||||
|
||||
EntityUid dummy = default;
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var mapId = mapManager.CreateMap();
|
||||
var map = await pair.CreateTestMap();
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
var pos = new MapCoordinates(Vector2.Zero, mapId);
|
||||
var pos = new MapCoordinates(Vector2.Zero, map.MapId);
|
||||
var entStorage = serverEntManager.EntitySysManager.GetEntitySystem<EntityStorageSystem>();
|
||||
var container = serverEntManager.SpawnEntity("ContainerOcclusionA", pos);
|
||||
dummy = serverEntManager.SpawnEntity("ContainerOcclusionDummy", pos);
|
||||
@@ -85,11 +85,12 @@ namespace Content.IntegrationTests.Tests
|
||||
|
||||
EntityUid dummy = default;
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var mapId = mapManager.CreateMap();
|
||||
|
||||
var map = await pair.CreateTestMap();
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
var pos = new MapCoordinates(Vector2.Zero, mapId);
|
||||
var pos = new MapCoordinates(Vector2.Zero, map.MapId);
|
||||
var entStorage = serverEntManager.EntitySysManager.GetEntitySystem<EntityStorageSystem>();
|
||||
var container = serverEntManager.SpawnEntity("ContainerOcclusionB", pos);
|
||||
dummy = serverEntManager.SpawnEntity("ContainerOcclusionDummy", pos);
|
||||
@@ -127,11 +128,12 @@ namespace Content.IntegrationTests.Tests
|
||||
|
||||
EntityUid dummy = default;
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var mapId = mapManager.CreateMap();
|
||||
|
||||
var map = await pair.CreateTestMap();
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
var pos = new MapCoordinates(Vector2.Zero, mapId);
|
||||
var pos = new MapCoordinates(Vector2.Zero, map.MapId);
|
||||
var entStorage = serverEntManager.EntitySysManager.GetEntitySystem<EntityStorageSystem>();
|
||||
var containerA = serverEntManager.SpawnEntity("ContainerOcclusionA", pos);
|
||||
var containerB = serverEntManager.SpawnEntity("ContainerOcclusionB", pos);
|
||||
|
||||
@@ -14,39 +14,39 @@ public sealed class DamageSpecifierTest
|
||||
// Test basic math operations.
|
||||
// I've already nearly broken these once. When editing the operators.
|
||||
|
||||
DamageSpecifier input1 = new() { DamageDict = _input1 };
|
||||
DamageSpecifier input2 = new() { DamageDict = _input2 };
|
||||
DamageSpecifier output1 = new() { DamageDict = _output1 };
|
||||
DamageSpecifier output2 = new() { DamageDict = _output2 };
|
||||
DamageSpecifier output3 = new() { DamageDict = _output3 };
|
||||
DamageSpecifier output4 = new() { DamageDict = _output4 };
|
||||
DamageSpecifier output5 = new() { DamageDict = _output5 };
|
||||
DamageSpecifier input1 = new() { DamageDict = Input1 };
|
||||
DamageSpecifier input2 = new() { DamageDict = Input2 };
|
||||
DamageSpecifier output1 = new() { DamageDict = Output1 };
|
||||
DamageSpecifier output2 = new() { DamageDict = Output2 };
|
||||
DamageSpecifier output3 = new() { DamageDict = Output3 };
|
||||
DamageSpecifier output4 = new() { DamageDict = Output4 };
|
||||
DamageSpecifier output5 = new() { DamageDict = Output5 };
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That((-input1).Equals(output1));
|
||||
Assert.That((input1 / 2).Equals(output2));
|
||||
Assert.That((input1 * 2).Equals(output3));
|
||||
Assert.That(-input1, Is.EqualTo(output1));
|
||||
Assert.That(input1 / 2, Is.EqualTo(output2));
|
||||
Assert.That(input1 * 2, Is.EqualTo(output3));
|
||||
});
|
||||
|
||||
var difference = (input1 - input2);
|
||||
Assert.That(difference.Equals(output4));
|
||||
var difference = input1 - input2;
|
||||
Assert.That(difference, Is.EqualTo(output4));
|
||||
|
||||
var difference2 = (-input2) + input1;
|
||||
Assert.That(difference.Equals(difference2));
|
||||
var difference2 = -input2 + input1;
|
||||
Assert.That(difference, Is.EqualTo(difference2));
|
||||
|
||||
difference.Clamp(-0.25f, 0.25f);
|
||||
Assert.That(difference.Equals(output5));
|
||||
Assert.That(difference, Is.EqualTo(output5));
|
||||
}
|
||||
|
||||
static Dictionary<string, FixedPoint2> _input1 = new()
|
||||
private static readonly Dictionary<string, FixedPoint2> Input1 = new()
|
||||
{
|
||||
{ "A", 1.5f },
|
||||
{ "B", 2 },
|
||||
{ "C", 3 }
|
||||
};
|
||||
|
||||
static Dictionary<string, FixedPoint2> _input2 = new()
|
||||
private static readonly Dictionary<string, FixedPoint2> Input2 = new()
|
||||
{
|
||||
{ "A", 1 },
|
||||
{ "B", 2 },
|
||||
@@ -54,28 +54,28 @@ public sealed class DamageSpecifierTest
|
||||
{ "D", 0.05f }
|
||||
};
|
||||
|
||||
static Dictionary<string, FixedPoint2> _output1 = new()
|
||||
private static readonly Dictionary<string, FixedPoint2> Output1 = new()
|
||||
{
|
||||
{ "A", -1.5f },
|
||||
{ "B", -2 },
|
||||
{ "C", -3 }
|
||||
};
|
||||
|
||||
static Dictionary<string, FixedPoint2> _output2 = new()
|
||||
private static readonly Dictionary<string, FixedPoint2> Output2 = new()
|
||||
{
|
||||
{ "A", 0.75f },
|
||||
{ "B", 1 },
|
||||
{ "C", 1.5 }
|
||||
};
|
||||
|
||||
static Dictionary<string, FixedPoint2> _output3 = new()
|
||||
private static readonly Dictionary<string, FixedPoint2> Output3 = new()
|
||||
{
|
||||
{ "A", 3f },
|
||||
{ "B", 4 },
|
||||
{ "C", 6 }
|
||||
};
|
||||
|
||||
static Dictionary<string, FixedPoint2> _output4 = new()
|
||||
private static readonly Dictionary<string, FixedPoint2> Output4 = new()
|
||||
{
|
||||
{ "A", 0.5f },
|
||||
{ "B", 0 },
|
||||
@@ -83,7 +83,7 @@ public sealed class DamageSpecifierTest
|
||||
{ "D", -0.05f }
|
||||
};
|
||||
|
||||
static Dictionary<string, FixedPoint2> _output5 = new()
|
||||
private static readonly Dictionary<string, FixedPoint2> Output5 = new()
|
||||
{
|
||||
{ "A", 0.25f },
|
||||
{ "B", 0 },
|
||||
|
||||
@@ -107,10 +107,11 @@ namespace Content.IntegrationTests.Tests.Damageable
|
||||
|
||||
FixedPoint2 typeDamage;
|
||||
|
||||
var map = await pair.CreateTestMap();
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
var map = sMapManager.CreateMap();
|
||||
var coordinates = new MapCoordinates(0, 0, map);
|
||||
var coordinates = map.MapCoords;
|
||||
|
||||
sDamageableEntity = sEntityManager.SpawnEntity("TestDamageableEntityId", coordinates);
|
||||
sDamageableComponent = sEntityManager.GetComponent<DamageableComponent>(sDamageableEntity);
|
||||
|
||||
@@ -123,24 +123,24 @@ namespace Content.IntegrationTests.Tests.Doors
|
||||
var xformSystem = entityManager.System<SharedTransformSystem>();
|
||||
|
||||
PhysicsComponent physBody = null;
|
||||
EntityUid AirlockPhysicsDummy = default;
|
||||
EntityUid airlockPhysicsDummy = default;
|
||||
EntityUid airlock = default;
|
||||
DoorComponent doorComponent = null;
|
||||
|
||||
var AirlockPhysicsDummyStartingX = -1;
|
||||
var airlockPhysicsDummyStartingX = -1;
|
||||
|
||||
var map = await pair.CreateTestMap();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var mapId = mapManager.CreateMap();
|
||||
var humanCoordinates = new MapCoordinates(new Vector2(airlockPhysicsDummyStartingX, 0), map.MapId);
|
||||
airlockPhysicsDummy = entityManager.SpawnEntity("AirlockPhysicsDummy", humanCoordinates);
|
||||
|
||||
var humanCoordinates = new MapCoordinates(new Vector2(AirlockPhysicsDummyStartingX, 0), mapId);
|
||||
AirlockPhysicsDummy = entityManager.SpawnEntity("AirlockPhysicsDummy", humanCoordinates);
|
||||
|
||||
airlock = entityManager.SpawnEntity("AirlockDummy", new MapCoordinates(new Vector2(0, 0), mapId));
|
||||
airlock = entityManager.SpawnEntity("AirlockDummy", new MapCoordinates(new Vector2(0, 0), map.MapId));
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(entityManager.TryGetComponent(AirlockPhysicsDummy, out physBody), Is.True);
|
||||
Assert.That(entityManager.TryGetComponent(airlockPhysicsDummy, out physBody), Is.True);
|
||||
Assert.That(entityManager.TryGetComponent(airlock, out doorComponent), Is.True);
|
||||
});
|
||||
Assert.That(doorComponent.State, Is.EqualTo(DoorState.Closed));
|
||||
@@ -152,7 +152,7 @@ namespace Content.IntegrationTests.Tests.Doors
|
||||
await server.WaitAssertion(() => Assert.That(physBody, Is.Not.EqualTo(null)));
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
physicsSystem.SetLinearVelocity(AirlockPhysicsDummy, new Vector2(0.5f, 0f), body: physBody);
|
||||
physicsSystem.SetLinearVelocity(airlockPhysicsDummy, new Vector2(0.5f, 0f), body: physBody);
|
||||
});
|
||||
|
||||
for (var i = 0; i < 240; i += 10)
|
||||
@@ -176,7 +176,7 @@ namespace Content.IntegrationTests.Tests.Doors
|
||||
// Blocked by the airlock
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
Assert.That(Math.Abs(xformSystem.GetWorldPosition(AirlockPhysicsDummy).X - 1), Is.GreaterThan(0.01f));
|
||||
Assert.That(Math.Abs(xformSystem.GetWorldPosition(airlockPhysicsDummy).X - 1), Is.GreaterThan(0.01f));
|
||||
});
|
||||
await pair.CleanReturnAsync();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Content.IntegrationTests.Tests
|
||||
{
|
||||
foreach (var proto in prototypeManager.EnumeratePrototypes<EntityPrototype>())
|
||||
{
|
||||
if (proto.NoSpawn || proto.Abstract || pair.IsTestPrototype(proto) || !proto.Components.ContainsKey("Sprite"))
|
||||
if (proto.HideSpawnMenu || proto.Abstract || pair.IsTestPrototype(proto) || !proto.Components.ContainsKey("Sprite"))
|
||||
continue;
|
||||
|
||||
Assert.DoesNotThrow(() =>
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Server.Humanoid.Components;
|
||||
using Content.Shared.Coordinates;
|
||||
using Content.Shared.Prototypes;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
@@ -47,7 +43,7 @@ namespace Content.IntegrationTests.Tests
|
||||
|
||||
foreach (var protoId in protoIds)
|
||||
{
|
||||
var mapId = mapManager.CreateMap();
|
||||
mapSystem.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
// TODO: Fix this better in engine.
|
||||
mapSystem.SetTile(grid.Owner, grid.Comp, Vector2i.Zero, new Tile(1));
|
||||
@@ -155,6 +151,7 @@ namespace Content.IntegrationTests.Tests
|
||||
var prototypeMan = server.ResolveDependency<IPrototypeManager>();
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var sEntMan = server.ResolveDependency<IEntityManager>();
|
||||
var mapSys = server.System<SharedMapSystem>();
|
||||
|
||||
Assert.That(cfg.GetCVar(CVars.NetPVS), Is.False);
|
||||
|
||||
@@ -170,7 +167,7 @@ namespace Content.IntegrationTests.Tests
|
||||
{
|
||||
foreach (var protoId in protoIds)
|
||||
{
|
||||
var mapId = mapManager.CreateMap();
|
||||
mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
var ent = sEntMan.SpawnEntity(protoId, new EntityCoordinates(grid.Owner, 0.5f, 0.5f));
|
||||
foreach (var (_, component) in sEntMan.GetNetComponents(ent))
|
||||
@@ -227,6 +224,7 @@ namespace Content.IntegrationTests.Tests
|
||||
var settings = new PoolSettings { Connected = true, Dirty = true };
|
||||
await using var pair = await PoolManager.GetServerClient(settings);
|
||||
var mapManager = pair.Server.ResolveDependency<IMapManager>();
|
||||
var mapSys = pair.Server.System<SharedMapSystem>();
|
||||
var server = pair.Server;
|
||||
var client = pair.Client;
|
||||
|
||||
@@ -256,7 +254,7 @@ namespace Content.IntegrationTests.Tests
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
mapId = mapManager.CreateMap();
|
||||
mapSys.CreateMap(out mapId);
|
||||
});
|
||||
|
||||
var coords = new MapCoordinates(Vector2.Zero, mapId);
|
||||
|
||||
@@ -16,14 +16,15 @@ namespace Content.IntegrationTests.Tests.Fluids;
|
||||
[TestOf(typeof(SpreaderSystem))]
|
||||
public sealed class FluidSpill
|
||||
{
|
||||
private static PuddleComponent? GetPuddle(IEntityManager entityManager, MapGridComponent mapGrid, Vector2i pos)
|
||||
private static PuddleComponent? GetPuddle(IEntityManager entityManager, Entity<MapGridComponent> mapGrid, Vector2i pos)
|
||||
{
|
||||
return GetPuddleEntity(entityManager, mapGrid, pos)?.Comp;
|
||||
}
|
||||
|
||||
private static Entity<PuddleComponent>? GetPuddleEntity(IEntityManager entityManager, MapGridComponent mapGrid, Vector2i pos)
|
||||
private static Entity<PuddleComponent>? GetPuddleEntity(IEntityManager entityManager, Entity<MapGridComponent> mapGrid, Vector2i pos)
|
||||
{
|
||||
foreach (var uid in mapGrid.GetAnchoredEntities(pos))
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
foreach (var uid in mapSys.GetAnchoredEntities(mapGrid, mapGrid.Comp, pos))
|
||||
{
|
||||
if (entityManager.TryGetComponent(uid, out PuddleComponent? puddleComponent))
|
||||
return (uid, puddleComponent);
|
||||
@@ -39,9 +40,9 @@ public sealed class FluidSpill
|
||||
var server = pair.Server;
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var puddleSystem = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<PuddleSystem>();
|
||||
var puddleSystem = server.System<PuddleSystem>();
|
||||
var mapSystem = server.System<SharedMapSystem>();
|
||||
var gameTiming = server.ResolveDependency<IGameTiming>();
|
||||
MapId mapId;
|
||||
EntityUid gridId = default;
|
||||
|
||||
/*
|
||||
@@ -52,7 +53,7 @@ public sealed class FluidSpill
|
||||
*/
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
mapId = mapManager.CreateMap();
|
||||
mapSystem.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
gridId = grid.Owner;
|
||||
|
||||
@@ -60,12 +61,12 @@ public sealed class FluidSpill
|
||||
{
|
||||
for (var y = 0; y < 3; y++)
|
||||
{
|
||||
grid.Comp.SetTile(new Vector2i(x, y), new Tile(1));
|
||||
mapSystem.SetTile(grid, new Vector2i(x, y), new Tile(1));
|
||||
}
|
||||
}
|
||||
|
||||
entityManager.SpawnEntity("WallReinforced", grid.Comp.GridTileToLocal(new Vector2i(0, 1)));
|
||||
entityManager.SpawnEntity("WallReinforced", grid.Comp.GridTileToLocal(new Vector2i(1, 0)));
|
||||
entityManager.SpawnEntity("WallReinforced", mapSystem.GridTileToLocal(grid, grid.Comp, new Vector2i(0, 1)));
|
||||
entityManager.SpawnEntity("WallReinforced", mapSystem.GridTileToLocal(grid, grid.Comp, new Vector2i(1, 0)));
|
||||
});
|
||||
|
||||
|
||||
@@ -74,10 +75,10 @@ public sealed class FluidSpill
|
||||
{
|
||||
var grid = entityManager.GetComponent<MapGridComponent>(gridId);
|
||||
var solution = new Solution("Blood", FixedPoint2.New(100));
|
||||
var tileRef = grid.GetTileRef(puddleOrigin);
|
||||
var tileRef = mapSystem.GetTileRef(gridId, grid, puddleOrigin);
|
||||
#pragma warning disable NUnit2045 // Interdependent tests
|
||||
Assert.That(puddleSystem.TrySpillAt(tileRef, solution, out _), Is.True);
|
||||
Assert.That(GetPuddle(entityManager, grid, puddleOrigin), Is.Not.Null);
|
||||
Assert.That(GetPuddle(entityManager, (gridId, grid), puddleOrigin), Is.Not.Null);
|
||||
#pragma warning restore NUnit2045
|
||||
});
|
||||
|
||||
@@ -87,7 +88,7 @@ public sealed class FluidSpill
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var grid = entityManager.GetComponent<MapGridComponent>(gridId);
|
||||
var puddle = GetPuddleEntity(entityManager, grid, puddleOrigin);
|
||||
var puddle = GetPuddleEntity(entityManager, (gridId, grid), puddleOrigin);
|
||||
|
||||
#pragma warning disable NUnit2045 // Interdependent tests
|
||||
Assert.That(puddle, Is.Not.Null);
|
||||
@@ -104,7 +105,7 @@ public sealed class FluidSpill
|
||||
}
|
||||
|
||||
var newPos = new Vector2i(x, y);
|
||||
var sidePuddle = GetPuddle(entityManager, grid, newPos);
|
||||
var sidePuddle = GetPuddle(entityManager, (gridId, grid), newPos);
|
||||
Assert.That(sidePuddle, Is.Null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Fluids.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.Fluids
|
||||
{
|
||||
@@ -21,8 +20,7 @@ namespace Content.IntegrationTests.Tests.Fluids
|
||||
|
||||
var testMap = await pair.CreateTestMap();
|
||||
|
||||
var entitySystemManager = server.ResolveDependency<IEntitySystemManager>();
|
||||
var spillSystem = entitySystemManager.GetEntitySystem<PuddleSystem>();
|
||||
var spillSystem = server.System<PuddleSystem>();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
@@ -46,17 +44,19 @@ namespace Content.IntegrationTests.Tests.Fluids
|
||||
var server = pair.Server;
|
||||
|
||||
var testMap = await pair.CreateTestMap();
|
||||
var grid = testMap.Grid.Comp;
|
||||
var grid = testMap.Grid;
|
||||
|
||||
var entitySystemManager = server.ResolveDependency<IEntitySystemManager>();
|
||||
var spillSystem = entitySystemManager.GetEntitySystem<PuddleSystem>();
|
||||
var spillSystem = server.System<PuddleSystem>();
|
||||
var mapSystem = server.System<SharedMapSystem>();
|
||||
|
||||
// Remove all tiles
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
foreach (var tile in grid.GetAllTiles())
|
||||
var tiles = mapSystem.GetAllTiles(grid.Owner, grid.Comp);
|
||||
foreach (var tile in tiles)
|
||||
{
|
||||
grid.SetTile(tile.GridIndices, Tile.Empty);
|
||||
mapSystem.SetTile(grid, tile.GridIndices, Tile.Empty);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ public sealed class FollowerSystemTest
|
||||
var mapMan = server.ResolveDependency<IMapManager>();
|
||||
var sysMan = server.ResolveDependency<IEntitySystemManager>();
|
||||
var logMan = server.ResolveDependency<ILogManager>();
|
||||
var mapSys = server.System<SharedMapSystem>();
|
||||
var logger = logMan.RootSawmill;
|
||||
|
||||
await server.WaitPost(() =>
|
||||
@@ -29,7 +30,7 @@ public sealed class FollowerSystemTest
|
||||
var followerSystem = sysMan.GetEntitySystem<FollowerSystem>();
|
||||
|
||||
// Create a map to spawn the observers on.
|
||||
var map = mapMan.CreateMap();
|
||||
mapSys.CreateMap(out var map);
|
||||
|
||||
// Spawn an observer to be followed.
|
||||
var followed = entMan.SpawnEntity(GameTicker.ObserverPrototypeName, new MapCoordinates(0, 0, map));
|
||||
@@ -41,7 +42,7 @@ public sealed class FollowerSystemTest
|
||||
|
||||
followerSystem.StartFollowingEntity(follower, followed);
|
||||
|
||||
entMan.DeleteEntity(mapMan.GetMapEntityId(map));
|
||||
entMan.DeleteEntity(mapSys.GetMap(map));
|
||||
});
|
||||
await pair.CleanReturnAsync();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#nullable enable
|
||||
using System.Numerics;
|
||||
using Content.Server.Cuffs;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Cuffs.Components;
|
||||
@@ -7,7 +6,6 @@ using Content.Shared.Hands.Components;
|
||||
using Robust.Server.Console;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.GameObjects.Components.ActionBlocking
|
||||
{
|
||||
@@ -52,10 +50,11 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.ActionBlocking
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var host = server.ResolveDependency<IServerConsoleHost>();
|
||||
|
||||
var map = await pair.CreateTestMap();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var mapId = mapManager.CreateMap();
|
||||
var coordinates = new MapCoordinates(Vector2.Zero, mapId);
|
||||
var coordinates = map.MapCoords;
|
||||
|
||||
var cuffableSys = entityManager.System<CuffableSystem>();
|
||||
var xformSys = entityManager.System<SharedTransformSystem>();
|
||||
|
||||
@@ -47,7 +47,7 @@ public sealed class AntagPreferenceTest
|
||||
Assert.That(sys.IsEntityValid(client.AttachedEntity, def), Is.True);
|
||||
|
||||
// By default, traitor/antag preferences are disabled, so the pool should be empty.
|
||||
var sessions = new List<ICommonSession>{pair.Player!};
|
||||
var sessions = new List<ICommonSession> { pair.Player! };
|
||||
var pool = sys.GetPlayerPool(rule, sessions, def);
|
||||
Assert.That(pool.Count, Is.EqualTo(0));
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ public sealed class FailAndStartPresetTest
|
||||
player = pair.Player!.AttachedEntity!.Value;
|
||||
Assert.That(entMan.EntityExists(player));
|
||||
|
||||
ticker.SetGamePreset((GamePresetPrototype?)null);
|
||||
ticker.SetGamePreset((GamePresetPrototype?) null);
|
||||
server.CfgMan.SetCVar(CCVars.GridFill, false);
|
||||
server.CfgMan.SetCVar(CCVars.GameLobbyFallbackEnabled, true);
|
||||
server.CfgMan.SetCVar(CCVars.GameLobbyDefaultPreset, "secret");
|
||||
|
||||
@@ -7,6 +7,7 @@ using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Mind;
|
||||
using Content.Server.Pinpointer;
|
||||
using Content.Server.Roles;
|
||||
using Content.Server.RoundEnd;
|
||||
using Content.Server.Shuttles.Components;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Shared.CCVar;
|
||||
@@ -49,6 +50,7 @@ public sealed class NukeOpsTest
|
||||
var roleSys = server.System<RoleSystem>();
|
||||
var invSys = server.System<InventorySystem>();
|
||||
var factionSys = server.System<NpcFactionSystem>();
|
||||
var roundEndSys = server.System<RoundEndSystem>();
|
||||
|
||||
server.CfgMan.SetCVar(CCVars.GridFill, true);
|
||||
|
||||
@@ -63,11 +65,11 @@ public sealed class NukeOpsTest
|
||||
|
||||
// Opt into the nukies role.
|
||||
await pair.SetAntagPreference("NukeopsCommander", true);
|
||||
await pair.SetAntagPreference( "NukeopsMedic", true, dummies[1].UserId);
|
||||
await pair.SetAntagPreference("NukeopsMedic", true, dummies[1].UserId);
|
||||
|
||||
// Initially, the players have no attached entities
|
||||
Assert.That(pair.Player?.AttachedEntity, Is.Null);
|
||||
Assert.That(dummies.All(x => x.AttachedEntity == null));
|
||||
Assert.That(dummies.All(x => x.AttachedEntity == null));
|
||||
|
||||
// There are no grids or maps
|
||||
Assert.That(entMan.Count<MapComponent>(), Is.Zero);
|
||||
@@ -150,7 +152,8 @@ public sealed class NukeOpsTest
|
||||
}
|
||||
|
||||
// The game rule exists, and all the stations/shuttles/maps are properly initialized
|
||||
var rule = entMan.AllComponents<NukeopsRuleComponent>().Single().Component;
|
||||
var rule = entMan.AllComponents<NukeopsRuleComponent>().Single();
|
||||
var ruleComp = rule.Component;
|
||||
var gridsRule = entMan.AllComponents<RuleGridsComponent>().Single().Component;
|
||||
foreach (var grid in gridsRule.MapGrids)
|
||||
{
|
||||
@@ -158,12 +161,14 @@ public sealed class NukeOpsTest
|
||||
Assert.That(entMan.HasComponent<MapGridComponent>(grid));
|
||||
Assert.That(entMan.HasComponent<StationMemberComponent>(grid));
|
||||
}
|
||||
Assert.That(entMan.EntityExists(rule.TargetStation));
|
||||
Assert.That(entMan.EntityExists(ruleComp.TargetStation));
|
||||
|
||||
Assert.That(entMan.HasComponent<StationDataComponent>(rule.TargetStation));
|
||||
Assert.That(entMan.HasComponent<StationDataComponent>(ruleComp.TargetStation));
|
||||
|
||||
var nukieShuttlEnt = entMan.AllComponents<NukeOpsShuttleComponent>().FirstOrDefault().Uid;
|
||||
var nukieShuttle = entMan.AllComponents<NukeOpsShuttleComponent>().Single();
|
||||
var nukieShuttlEnt = nukieShuttle.Uid;
|
||||
Assert.That(entMan.EntityExists(nukieShuttlEnt));
|
||||
Assert.That(nukieShuttle.Component.AssociatedRule, Is.EqualTo(rule.Uid));
|
||||
|
||||
EntityUid? nukieStationEnt = null;
|
||||
foreach (var grid in gridsRule.MapGrids)
|
||||
@@ -179,12 +184,12 @@ public sealed class NukeOpsTest
|
||||
var nukieStation = entMan.GetComponent<StationMemberComponent>(nukieStationEnt!.Value);
|
||||
|
||||
Assert.That(entMan.EntityExists(nukieStation.Station));
|
||||
Assert.That(nukieStation.Station, Is.Not.EqualTo(rule.TargetStation));
|
||||
Assert.That(nukieStation.Station, Is.Not.EqualTo(ruleComp.TargetStation));
|
||||
|
||||
Assert.That(server.MapMan.MapExists(gridsRule.Map));
|
||||
var nukieMap = mapSys.GetMap(gridsRule.Map!.Value);
|
||||
|
||||
var targetStation = entMan.GetComponent<StationDataComponent>(rule.TargetStation!.Value);
|
||||
var targetStation = entMan.GetComponent<StationDataComponent>(ruleComp.TargetStation!.Value);
|
||||
var targetGrid = targetStation.Grids.First();
|
||||
var targetMap = entMan.GetComponent<TransformComponent>(targetGrid).MapUid!.Value;
|
||||
Assert.That(targetMap, Is.Not.EqualTo(nukieMap));
|
||||
@@ -206,7 +211,7 @@ public sealed class NukeOpsTest
|
||||
Assert.That(LifeStage(targetMap), Is.GreaterThan(EntityLifeStage.Initialized));
|
||||
Assert.That(LifeStage(nukieStationEnt.Value), Is.GreaterThan(EntityLifeStage.Initialized));
|
||||
Assert.That(LifeStage(nukieShuttlEnt), Is.GreaterThan(EntityLifeStage.Initialized));
|
||||
Assert.That(LifeStage(rule.TargetStation), Is.GreaterThan(EntityLifeStage.Initialized));
|
||||
Assert.That(LifeStage(ruleComp.TargetStation), Is.GreaterThan(EntityLifeStage.Initialized));
|
||||
|
||||
// Make sure the player has hands. We've had fucking disarmed nukies before.
|
||||
Assert.That(entMan.HasComponent<HandsComponent>(player));
|
||||
@@ -222,10 +227,10 @@ public sealed class NukeOpsTest
|
||||
}
|
||||
Assert.That(total, Is.GreaterThan(3));
|
||||
|
||||
// Finally lets check the nukie commander passed basic training and figured out how to breathe.
|
||||
// Check the nukie commander passed basic training and figured out how to breathe.
|
||||
var totalSeconds = 30;
|
||||
var totalTicks = (int) Math.Ceiling(totalSeconds / server.Timing.TickPeriod.TotalSeconds);
|
||||
int increment = 5;
|
||||
var increment = 5;
|
||||
var resp = entMan.GetComponent<RespiratorComponent>(player);
|
||||
var damage = entMan.GetComponent<DamageableComponent>(player);
|
||||
for (var tick = 0; tick < totalTicks; tick += increment)
|
||||
@@ -235,7 +240,24 @@ public sealed class NukeOpsTest
|
||||
Assert.That(damage.TotalDamage, Is.EqualTo(FixedPoint2.Zero));
|
||||
}
|
||||
|
||||
ticker.SetGamePreset((GamePresetPrototype?)null);
|
||||
// Check that the round does not end prematurely when agents are deleted in the outpost
|
||||
var nukies = dummyEnts.Where(entMan.HasComponent<NukeOperativeComponent>).Append(player).ToArray();
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
for (var i = 0; i < nukies.Length - 1; i++)
|
||||
{
|
||||
entMan.DeleteEntity(nukies[i]);
|
||||
Assert.That(roundEndSys.IsRoundEndRequested, Is.False,
|
||||
$"The round ended, but {nukies.Length - i - 1} nukies are still alive!");
|
||||
}
|
||||
// Delete the last nukie and make sure the round ends.
|
||||
entMan.DeleteEntity(nukies[^1]);
|
||||
|
||||
Assert.That(roundEndSys.IsRoundEndRequested,
|
||||
"All nukies were deleted, but the round didn't end!");
|
||||
});
|
||||
|
||||
ticker.SetGamePreset((GamePresetPrototype?) null);
|
||||
await pair.CleanReturnAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,29 +34,25 @@ namespace Content.IntegrationTests.Tests
|
||||
|
||||
var testMap = await pair.CreateTestMap();
|
||||
|
||||
EntityUid generator = default;
|
||||
var entityMan = server.ResolveDependency<IEntityManager>();
|
||||
var mapMan = server.ResolveDependency<IMapManager>();
|
||||
var entityMan = server.EntMan;
|
||||
var mapMan = server.MapMan;
|
||||
var mapSys = entityMan.System<SharedMapSystem>();
|
||||
|
||||
MapGridComponent grid1 = null;
|
||||
MapGridComponent grid2 = null;
|
||||
EntityUid grid1Entity = default!;
|
||||
EntityUid grid2Entity = default!;
|
||||
EntityUid generator = default;
|
||||
Entity<MapGridComponent> grid1 = default;
|
||||
Entity<MapGridComponent> grid2 = default;
|
||||
|
||||
// Create grids
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var mapId = testMap.MapId;
|
||||
grid1 = mapMan.CreateGrid(mapId);
|
||||
grid2 = mapMan.CreateGrid(mapId);
|
||||
grid1Entity = grid1.Owner;
|
||||
grid2Entity = grid2.Owner;
|
||||
grid1 = mapMan.CreateGridEntity(mapId);
|
||||
grid2 = mapMan.CreateGridEntity(mapId);
|
||||
|
||||
mapSys.SetTile(grid1Entity, grid1, Vector2i.Zero, new Tile(1));
|
||||
mapSys.SetTile(grid2Entity, grid2, Vector2i.Zero, new Tile(1));
|
||||
mapSys.SetTile(grid1, grid1, Vector2i.Zero, new Tile(1));
|
||||
mapSys.SetTile(grid2, grid2, Vector2i.Zero, new Tile(1));
|
||||
|
||||
generator = entityMan.SpawnEntity("GridGravityGeneratorDummy", new EntityCoordinates(grid1Entity, 0.5f, 0.5f));
|
||||
generator = entityMan.SpawnEntity("GridGravityGeneratorDummy", new EntityCoordinates(grid1, 0.5f, 0.5f));
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(entityMan.HasComponent<GravityGeneratorComponent>(generator));
|
||||
@@ -77,8 +73,8 @@ namespace Content.IntegrationTests.Tests
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(generatorComponent.GravityActive, Is.True);
|
||||
Assert.That(!entityMan.GetComponent<GravityComponent>(grid1Entity).EnabledVV);
|
||||
Assert.That(entityMan.GetComponent<GravityComponent>(grid2Entity).EnabledVV);
|
||||
Assert.That(!entityMan.GetComponent<GravityComponent>(grid1).EnabledVV);
|
||||
Assert.That(entityMan.GetComponent<GravityComponent>(grid2).EnabledVV);
|
||||
});
|
||||
|
||||
// Re-enable needs power so it turns off again.
|
||||
@@ -95,7 +91,7 @@ namespace Content.IntegrationTests.Tests
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(generatorComponent.GravityActive, Is.False);
|
||||
Assert.That(entityMan.GetComponent<GravityComponent>(grid2Entity).EnabledVV, Is.False);
|
||||
Assert.That(entityMan.GetComponent<GravityComponent>(grid2).EnabledVV, Is.False);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -48,13 +48,9 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
|
||||
var sysMan = server.ResolveDependency<IEntitySystemManager>();
|
||||
var handSys = sysMan.GetEntitySystem<SharedHandsSystem>();
|
||||
|
||||
var mapId = MapId.Nullspace;
|
||||
var coords = MapCoordinates.Nullspace;
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
mapId = mapManager.CreateMap();
|
||||
coords = new MapCoordinates(Vector2.Zero, mapId);
|
||||
});
|
||||
var map = await pair.CreateTestMap();
|
||||
var mapId = map.MapId;
|
||||
var coords = map.MapCoords;
|
||||
|
||||
await server.WaitIdleAsync();
|
||||
EntityUid user = default;
|
||||
@@ -119,13 +115,9 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
|
||||
var sysMan = server.ResolveDependency<IEntitySystemManager>();
|
||||
var handSys = sysMan.GetEntitySystem<SharedHandsSystem>();
|
||||
|
||||
var mapId = MapId.Nullspace;
|
||||
var coords = MapCoordinates.Nullspace;
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
mapId = mapManager.CreateMap();
|
||||
coords = new MapCoordinates(Vector2.Zero, mapId);
|
||||
});
|
||||
var map = await pair.CreateTestMap();
|
||||
var mapId = map.MapId;
|
||||
var coords = map.MapCoords;
|
||||
|
||||
await server.WaitIdleAsync();
|
||||
EntityUid user = default;
|
||||
@@ -190,13 +182,9 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
|
||||
var sysMan = server.ResolveDependency<IEntitySystemManager>();
|
||||
var handSys = sysMan.GetEntitySystem<SharedHandsSystem>();
|
||||
|
||||
var mapId = MapId.Nullspace;
|
||||
var coords = MapCoordinates.Nullspace;
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
mapId = mapManager.CreateMap();
|
||||
coords = new MapCoordinates(Vector2.Zero, mapId);
|
||||
});
|
||||
var map = await pair.CreateTestMap();
|
||||
var mapId = map.MapId;
|
||||
var coords = map.MapCoords;
|
||||
|
||||
await server.WaitIdleAsync();
|
||||
EntityUid user = default;
|
||||
@@ -261,13 +249,9 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
|
||||
var sysMan = server.ResolveDependency<IEntitySystemManager>();
|
||||
var handSys = sysMan.GetEntitySystem<SharedHandsSystem>();
|
||||
|
||||
var mapId = MapId.Nullspace;
|
||||
var coords = MapCoordinates.Nullspace;
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
mapId = mapManager.CreateMap();
|
||||
coords = new MapCoordinates(Vector2.Zero, mapId);
|
||||
});
|
||||
var map = await pair.CreateTestMap();
|
||||
var mapId = map.MapId;
|
||||
var coords = map.MapCoords;
|
||||
|
||||
await server.WaitIdleAsync();
|
||||
EntityUid user = default;
|
||||
@@ -331,13 +315,9 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
|
||||
var handSys = sysMan.GetEntitySystem<SharedHandsSystem>();
|
||||
var conSystem = sysMan.GetEntitySystem<SharedContainerSystem>();
|
||||
|
||||
var mapId = MapId.Nullspace;
|
||||
var coords = MapCoordinates.Nullspace;
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
mapId = mapManager.CreateMap();
|
||||
coords = new MapCoordinates(Vector2.Zero, mapId);
|
||||
});
|
||||
var map = await pair.CreateTestMap();
|
||||
var mapId = map.MapId;
|
||||
var coords = map.MapCoords;
|
||||
|
||||
await server.WaitIdleAsync();
|
||||
EntityUid user = default;
|
||||
|
||||
@@ -39,10 +39,11 @@ namespace Content.IntegrationTests.Tests.Interaction
|
||||
EntityUid other = default;
|
||||
MapCoordinates mapCoordinates = default;
|
||||
|
||||
var map = await pair.CreateTestMap();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var mapId = mapManager.CreateMap();
|
||||
var coordinates = new MapCoordinates(Vector2.Zero, mapId);
|
||||
var coordinates = map.MapCoords;
|
||||
|
||||
origin = sEntities.SpawnEntity(HumanId, coordinates);
|
||||
other = sEntities.SpawnEntity(HumanId, coordinates);
|
||||
|
||||
@@ -571,11 +571,11 @@ public abstract partial class InteractionTest
|
||||
|
||||
var tile = Tile.Empty;
|
||||
var serverCoords = SEntMan.GetCoordinates(coords ?? TargetCoords);
|
||||
var pos = serverCoords.ToMap(SEntMan, Transform);
|
||||
var pos = Transform.ToMapCoordinates(serverCoords);
|
||||
await Server.WaitPost(() =>
|
||||
{
|
||||
if (MapMan.TryFindGridAt(pos, out _, out var grid))
|
||||
tile = grid.GetTileRef(serverCoords).Tile;
|
||||
if (MapMan.TryFindGridAt(pos, out var gridUid, out var grid))
|
||||
tile = MapSystem.GetTileRef(gridUid, grid, serverCoords).Tile;
|
||||
});
|
||||
|
||||
Assert.That(tile.TypeId, Is.EqualTo(targetTile.TypeId));
|
||||
@@ -757,33 +757,41 @@ public abstract partial class InteractionTest
|
||||
/// <summary>
|
||||
/// Set the tile at the target position to some prototype.
|
||||
/// </summary>
|
||||
protected async Task SetTile(string? proto, NetCoordinates? coords = null, MapGridComponent? grid = null)
|
||||
protected async Task SetTile(string? proto, NetCoordinates? coords = null, Entity<MapGridComponent>? grid = null)
|
||||
{
|
||||
var tile = proto == null
|
||||
? Tile.Empty
|
||||
: new Tile(TileMan[proto].TileId);
|
||||
|
||||
var pos = SEntMan.GetCoordinates(coords ?? TargetCoords).ToMap(SEntMan, Transform);
|
||||
var pos = Transform.ToMapCoordinates(SEntMan.GetCoordinates(coords ?? TargetCoords));
|
||||
|
||||
EntityUid gridUid;
|
||||
MapGridComponent? gridComp;
|
||||
await Server.WaitPost(() =>
|
||||
{
|
||||
if (grid != null || MapMan.TryFindGridAt(pos, out var gridUid, out grid))
|
||||
if (grid is { } gridEnt)
|
||||
{
|
||||
grid.SetTile(SEntMan.GetCoordinates(coords ?? TargetCoords), tile);
|
||||
MapSystem.SetTile(gridEnt, SEntMan.GetCoordinates(coords ?? TargetCoords), tile);
|
||||
return;
|
||||
}
|
||||
else if (MapMan.TryFindGridAt(pos, out var gUid, out var gComp))
|
||||
{
|
||||
MapSystem.SetTile(gUid, gComp, SEntMan.GetCoordinates(coords ?? TargetCoords), tile);
|
||||
return;
|
||||
}
|
||||
|
||||
if (proto == null)
|
||||
return;
|
||||
|
||||
var gridEnt = MapMan.CreateGridEntity(MapData.MapId);
|
||||
gridEnt = MapMan.CreateGridEntity(MapData.MapId);
|
||||
grid = gridEnt;
|
||||
gridUid = gridEnt;
|
||||
gridComp = gridEnt.Comp;
|
||||
var gridXform = SEntMan.GetComponent<TransformComponent>(gridUid);
|
||||
Transform.SetWorldPosition(gridXform, pos.Position);
|
||||
grid.SetTile(SEntMan.GetCoordinates(coords ?? TargetCoords), tile);
|
||||
MapSystem.SetTile((gridUid, gridComp), SEntMan.GetCoordinates(coords ?? TargetCoords), tile);
|
||||
|
||||
if (!MapMan.TryFindGridAt(pos, out _, out grid))
|
||||
if (!MapMan.TryFindGridAt(pos, out _, out _))
|
||||
Assert.Fail("Failed to create grid?");
|
||||
});
|
||||
await AssertTile(proto, coords);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#nullable enable
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Client.Construction;
|
||||
@@ -108,6 +107,7 @@ public abstract partial class InteractionTest
|
||||
protected SharedItemToggleSystem ItemToggleSys = default!;
|
||||
protected InteractionTestSystem STestSystem = default!;
|
||||
protected SharedTransformSystem Transform = default!;
|
||||
protected SharedMapSystem MapSystem = default!;
|
||||
protected ISawmill SLogger = default!;
|
||||
protected SharedUserInterfaceSystem SUiSys = default!;
|
||||
|
||||
@@ -153,7 +153,7 @@ public abstract partial class InteractionTest
|
||||
[SetUp]
|
||||
public virtual async Task Setup()
|
||||
{
|
||||
Pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true, Dirty = true});
|
||||
Pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true, Dirty = true });
|
||||
|
||||
// server dependencies
|
||||
SEntMan = Server.ResolveDependency<IEntityManager>();
|
||||
@@ -168,6 +168,7 @@ public abstract partial class InteractionTest
|
||||
ItemToggleSys = SEntMan.System<SharedItemToggleSystem>();
|
||||
DoAfterSys = SEntMan.System<SharedDoAfterSystem>();
|
||||
Transform = SEntMan.System<SharedTransformSystem>();
|
||||
MapSystem = SEntMan.System<SharedMapSystem>();
|
||||
SConstruction = SEntMan.System<Server.Construction.ConstructionSystem>();
|
||||
STestSystem = SEntMan.System<InteractionTestSystem>();
|
||||
Stack = SEntMan.System<StackSystem>();
|
||||
@@ -188,9 +189,10 @@ public abstract partial class InteractionTest
|
||||
|
||||
// Setup map.
|
||||
await Pair.CreateTestMap();
|
||||
PlayerCoords = SEntMan.GetNetCoordinates(MapData.GridCoords.Offset(new Vector2(0.5f, 0.5f)).WithEntityId(MapData.MapUid, Transform, SEntMan));
|
||||
TargetCoords = SEntMan.GetNetCoordinates(MapData.GridCoords.Offset(new Vector2(1.5f, 0.5f)).WithEntityId(MapData.MapUid, Transform, SEntMan));
|
||||
await SetTile(Plating, grid: MapData.Grid.Comp);
|
||||
|
||||
PlayerCoords = SEntMan.GetNetCoordinates(Transform.WithEntityId(MapData.GridCoords.Offset(new Vector2(0.5f, 0.5f)), MapData.MapUid));
|
||||
TargetCoords = SEntMan.GetNetCoordinates(Transform.WithEntityId(MapData.GridCoords.Offset(new Vector2(1.5f, 0.5f)), MapData.MapUid));
|
||||
await SetTile(Plating, grid: MapData.Grid);
|
||||
|
||||
// Get player data
|
||||
var sPlayerMan = Server.ResolveDependency<Robust.Server.Player.IPlayerManager>();
|
||||
@@ -263,7 +265,8 @@ public abstract partial class InteractionTest
|
||||
await TearDown();
|
||||
}
|
||||
|
||||
protected virtual async Task TearDown()
|
||||
protected virtual Task TearDown()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,26 +26,26 @@ public sealed class StaticFieldValidationTest
|
||||
protos.Add(kind, ids);
|
||||
}
|
||||
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(StringValid), protos).Count, Is.Zero);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(StringArrayValid), protos).Count, Is.Zero);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdValid), protos).Count, Is.Zero);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdArrayValid), protos).Count, Is.Zero);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdTestValid), protos).Count, Is.Zero);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdArrayValid), protos).Count, Is.Zero);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdListValid), protos).Count, Is.Zero);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdSetValid), protos).Count, Is.Zero);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(PrivateProtoIdArrayValid), protos).Count, Is.Zero);
|
||||
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(StringInvalid), protos).Count, Is.EqualTo(1));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(StringArrayInvalid), protos).Count, Is.EqualTo(2));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdInvalid), protos).Count, Is.EqualTo(1));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdArrayInvalid), protos).Count, Is.EqualTo(2));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdTestInvalid), protos).Count, Is.EqualTo(1));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdArrayInvalid), protos).Count, Is.EqualTo(2));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdListInvalid), protos).Count, Is.EqualTo(2));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdSetInvalid), protos).Count, Is.EqualTo(2));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(PrivateProtoIdArrayInvalid), protos).Count, Is.EqualTo(2));
|
||||
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(StringValid), protos), Is.Empty);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(StringArrayValid), protos), Is.Empty);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdValid), protos), Is.Empty);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdArrayValid), protos), Is.Empty);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdTestValid), protos), Is.Empty);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdArrayValid), protos), Is.Empty);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdListValid), protos), Is.Empty);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdSetValid), protos), Is.Empty);
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(PrivateProtoIdArrayValid), protos), Is.Empty);
|
||||
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(StringInvalid), protos), Has.Count.EqualTo(1));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(StringArrayInvalid), protos), Has.Count.EqualTo(2));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdInvalid), protos), Has.Count.EqualTo(1));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdArrayInvalid), protos), Has.Count.EqualTo(2));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdTestInvalid), protos), Has.Count.EqualTo(1));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdArrayInvalid), protos), Has.Count.EqualTo(2));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdListInvalid), protos), Has.Count.EqualTo(2));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdSetInvalid), protos), Has.Count.EqualTo(2));
|
||||
Assert.That(protoMan.ValidateStaticFields(typeof(PrivateProtoIdArrayInvalid), protos), Has.Count.EqualTo(2));
|
||||
|
||||
await pair.CleanReturnAsync();
|
||||
}
|
||||
|
||||
@@ -58,93 +58,111 @@ public sealed class StaticFieldValidationTest
|
||||
id: StaticFieldTestTag
|
||||
";
|
||||
|
||||
[Reflect(false)] private sealed class StringValid
|
||||
[Reflect(false)]
|
||||
private sealed class StringValid
|
||||
{
|
||||
[ValidatePrototypeId<TagPrototype>] public static string Tag = "StaticFieldTestTag";
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class StringInvalid
|
||||
[Reflect(false)]
|
||||
private sealed class StringInvalid
|
||||
{
|
||||
[ValidatePrototypeId<TagPrototype>] public static string Tag = string.Empty;
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class StringArrayValid
|
||||
[Reflect(false)]
|
||||
private sealed class StringArrayValid
|
||||
{
|
||||
[ValidatePrototypeId<TagPrototype>] public static string[] Tag = {"StaticFieldTestTag", "StaticFieldTestTag"};
|
||||
[ValidatePrototypeId<TagPrototype>] public static string[] Tag = ["StaticFieldTestTag", "StaticFieldTestTag"];
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class StringArrayInvalid
|
||||
[Reflect(false)]
|
||||
private sealed class StringArrayInvalid
|
||||
{
|
||||
[ValidatePrototypeId<TagPrototype>] public static string[] Tag = {string.Empty, "StaticFieldTestTag", string.Empty};
|
||||
[ValidatePrototypeId<TagPrototype>] public static string[] Tag = [string.Empty, "StaticFieldTestTag", string.Empty];
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class EntProtoIdValid
|
||||
[Reflect(false)]
|
||||
private sealed class EntProtoIdValid
|
||||
{
|
||||
public static EntProtoId Tag = "StaticFieldTestEnt";
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class EntProtoIdInvalid
|
||||
[Reflect(false)]
|
||||
private sealed class EntProtoIdInvalid
|
||||
{
|
||||
public static EntProtoId Tag = string.Empty;
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class EntProtoIdArrayValid
|
||||
[Reflect(false)]
|
||||
private sealed class EntProtoIdArrayValid
|
||||
{
|
||||
public static EntProtoId[] Tag = {"StaticFieldTestEnt", "StaticFieldTestEnt"};
|
||||
public static EntProtoId[] Tag = ["StaticFieldTestEnt", "StaticFieldTestEnt"];
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class EntProtoIdArrayInvalid
|
||||
[Reflect(false)]
|
||||
private sealed class EntProtoIdArrayInvalid
|
||||
{
|
||||
public static EntProtoId[] Tag = {string.Empty, "StaticFieldTestEnt", string.Empty};
|
||||
public static EntProtoId[] Tag = [string.Empty, "StaticFieldTestEnt", string.Empty];
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class ProtoIdTestValid
|
||||
[Reflect(false)]
|
||||
private sealed class ProtoIdTestValid
|
||||
{
|
||||
public static ProtoId<TagPrototype> Tag = "StaticFieldTestTag";
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class ProtoIdTestInvalid
|
||||
[Reflect(false)]
|
||||
private sealed class ProtoIdTestInvalid
|
||||
{
|
||||
public static ProtoId<TagPrototype> Tag = string.Empty;
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class ProtoIdArrayValid
|
||||
[Reflect(false)]
|
||||
private sealed class ProtoIdArrayValid
|
||||
{
|
||||
public static ProtoId<TagPrototype>[] Tag = {"StaticFieldTestTag", "StaticFieldTestTag"};
|
||||
public static ProtoId<TagPrototype>[] Tag = ["StaticFieldTestTag", "StaticFieldTestTag"];
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class ProtoIdArrayInvalid
|
||||
[Reflect(false)]
|
||||
private sealed class ProtoIdArrayInvalid
|
||||
{
|
||||
public static ProtoId<TagPrototype>[] Tag = {string.Empty, "StaticFieldTestTag", string.Empty};
|
||||
public static ProtoId<TagPrototype>[] Tag = [string.Empty, "StaticFieldTestTag", string.Empty];
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class ProtoIdListValid
|
||||
[Reflect(false)]
|
||||
private sealed class ProtoIdListValid
|
||||
{
|
||||
public static List<ProtoId<TagPrototype>> Tag = new() {"StaticFieldTestTag", "StaticFieldTestTag"};
|
||||
public static List<ProtoId<TagPrototype>> Tag = ["StaticFieldTestTag", "StaticFieldTestTag"];
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class ProtoIdListInvalid
|
||||
[Reflect(false)]
|
||||
private sealed class ProtoIdListInvalid
|
||||
{
|
||||
public static List<ProtoId<TagPrototype>> Tag = new() {string.Empty, "StaticFieldTestTag", string.Empty};
|
||||
public static List<ProtoId<TagPrototype>> Tag = [string.Empty, "StaticFieldTestTag", string.Empty];
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class ProtoIdSetValid
|
||||
[Reflect(false)]
|
||||
private sealed class ProtoIdSetValid
|
||||
{
|
||||
public static HashSet<ProtoId<TagPrototype>> Tag = new() {"StaticFieldTestTag", "StaticFieldTestTag"};
|
||||
public static HashSet<ProtoId<TagPrototype>> Tag = ["StaticFieldTestTag", "StaticFieldTestTag"];
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class ProtoIdSetInvalid
|
||||
[Reflect(false)]
|
||||
private sealed class ProtoIdSetInvalid
|
||||
{
|
||||
public static HashSet<ProtoId<TagPrototype>> Tag = new() {string.Empty, "StaticFieldTestTag", string.Empty, " "};
|
||||
public static HashSet<ProtoId<TagPrototype>> Tag = [string.Empty, "StaticFieldTestTag", string.Empty, " "];
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class PrivateProtoIdArrayValid
|
||||
[Reflect(false)]
|
||||
private sealed class PrivateProtoIdArrayValid
|
||||
{
|
||||
private static ProtoId<TagPrototype>[] Tag = {"StaticFieldTestTag", "StaticFieldTestTag"};
|
||||
private static readonly ProtoId<TagPrototype>[] Tag = ["StaticFieldTestTag", "StaticFieldTestTag"];
|
||||
}
|
||||
|
||||
[Reflect(false)] private sealed class PrivateProtoIdArrayInvalid
|
||||
[Reflect(false)]
|
||||
private sealed class PrivateProtoIdArrayInvalid
|
||||
{
|
||||
private static ProtoId<TagPrototype>[] Tag = {string.Empty, "StaticFieldTestTag", string.Empty};
|
||||
private static readonly ProtoId<TagPrototype>[] Tag = [string.Empty, "StaticFieldTestTag", string.Empty];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Construction.Components;
|
||||
using Content.Shared.Construction.Components;
|
||||
using Content.Shared.Prototypes;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
@@ -37,6 +36,7 @@ public sealed class MachineBoardTest
|
||||
var server = pair.Server;
|
||||
|
||||
var protoMan = server.ResolveDependency<IPrototypeManager>();
|
||||
var compFact = server.ResolveDependency<IComponentFactory>();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
@@ -45,7 +45,7 @@ public sealed class MachineBoardTest
|
||||
.Where(p => !pair.IsTestPrototype(p))
|
||||
.Where(p => !_ignoredPrototypes.Contains(p.ID)))
|
||||
{
|
||||
if (!p.TryGetComponent<MachineBoardComponent>(out var mbc))
|
||||
if (!p.TryGetComponent<MachineBoardComponent>(out var mbc, compFact))
|
||||
continue;
|
||||
var mId = mbc.Prototype;
|
||||
|
||||
@@ -53,7 +53,7 @@ public sealed class MachineBoardTest
|
||||
{
|
||||
Assert.That(protoMan.TryIndex<EntityPrototype>(mId, out var mProto),
|
||||
$"Machine board {p.ID}'s corresponding machine has an invalid prototype.");
|
||||
Assert.That(mProto.TryGetComponent<MachineComponent>(out var mComp),
|
||||
Assert.That(mProto.TryGetComponent<MachineComponent>(out var mComp, compFact),
|
||||
$"Machine board {p.ID}'s corresponding machine {mId} does not have MachineComponent");
|
||||
Assert.That(mComp.Board, Is.EqualTo(p.ID),
|
||||
$"Machine {mId}'s BoardPrototype is not equal to it's corresponding machine board, {p.ID}");
|
||||
@@ -75,6 +75,7 @@ public sealed class MachineBoardTest
|
||||
var server = pair.Server;
|
||||
|
||||
var protoMan = server.ResolveDependency<IPrototypeManager>();
|
||||
var compFact = server.ResolveDependency<IComponentFactory>();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
@@ -83,7 +84,7 @@ public sealed class MachineBoardTest
|
||||
.Where(p => !pair.IsTestPrototype(p))
|
||||
.Where(p => !_ignoredPrototypes.Contains(p.ID)))
|
||||
{
|
||||
if (!p.TryGetComponent<ComputerBoardComponent>(out var cbc))
|
||||
if (!p.TryGetComponent<ComputerBoardComponent>(out var cbc, compFact))
|
||||
continue;
|
||||
var cId = cbc.Prototype;
|
||||
|
||||
@@ -92,7 +93,7 @@ public sealed class MachineBoardTest
|
||||
Assert.That(cId, Is.Not.Null, $"Computer board \"{p.ID}\" does not have a corresponding computer.");
|
||||
Assert.That(protoMan.TryIndex<EntityPrototype>(cId, out var cProto),
|
||||
$"Computer board \"{p.ID}\"'s corresponding computer has an invalid prototype.");
|
||||
Assert.That(cProto.TryGetComponent<ComputerComponent>(out var cComp),
|
||||
Assert.That(cProto.TryGetComponent<ComputerComponent>(out var cComp, compFact),
|
||||
$"Computer board {p.ID}'s corresponding computer \"{cId}\" does not have ComputerComponent");
|
||||
Assert.That(cComp.BoardPrototype, Is.EqualTo(p.ID),
|
||||
$"Computer \"{cId}\"'s BoardPrototype is not equal to it's corresponding computer board, \"{p.ID}\"");
|
||||
|
||||
@@ -13,7 +13,7 @@ public sealed class MappingTests
|
||||
[Test]
|
||||
public async Task MappingTest()
|
||||
{
|
||||
await using var pair = await PoolManager.GetServerClient(new PoolSettings {Dirty = true, Connected = true, DummyTicker = false});
|
||||
await using var pair = await PoolManager.GetServerClient(new PoolSettings { Dirty = true, Connected = true, DummyTicker = false });
|
||||
|
||||
var server = pair.Server;
|
||||
var entMan = server.EntMan;
|
||||
|
||||
@@ -38,15 +38,16 @@ public sealed class MaterialArbitrageTest
|
||||
await server.WaitIdleAsync();
|
||||
|
||||
var entManager = server.ResolveDependency<IEntityManager>();
|
||||
var sysManager = server.ResolveDependency<IEntitySystemManager>();
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
Assert.That(mapManager.IsMapInitialized(testMap.MapId));
|
||||
|
||||
var protoManager = server.ResolveDependency<IPrototypeManager>();
|
||||
var pricing = sysManager.GetEntitySystem<PricingSystem>();
|
||||
var stackSys = sysManager.GetEntitySystem<StackSystem>();
|
||||
|
||||
var pricing = entManager.System<PricingSystem>();
|
||||
var stackSys = entManager.System<StackSystem>();
|
||||
var mapSystem = server.System<SharedMapSystem>();
|
||||
var compFact = server.ResolveDependency<IComponentFactory>();
|
||||
|
||||
Assert.That(mapSystem.IsInitialized(testMap.MapId));
|
||||
|
||||
var constructionName = compFact.GetComponentName(typeof(ConstructionComponent));
|
||||
var compositionName = compFact.GetComponentName(typeof(PhysicalCompositionComponent));
|
||||
var materialName = compFact.GetComponentName(typeof(MaterialComponent));
|
||||
@@ -67,7 +68,7 @@ public sealed class MaterialArbitrageTest
|
||||
Dictionary<string, ConstructionComponent> constructionRecipes = new();
|
||||
foreach (var proto in protoManager.EnumeratePrototypes<EntityPrototype>())
|
||||
{
|
||||
if (proto.NoSpawn || proto.Abstract || pair.IsTestPrototype(proto))
|
||||
if (proto.HideSpawnMenu || proto.Abstract || pair.IsTestPrototype(proto))
|
||||
continue;
|
||||
|
||||
if (!proto.Components.TryGetValue(constructionName, out var destructible))
|
||||
@@ -127,7 +128,7 @@ public sealed class MaterialArbitrageTest
|
||||
// Here we get the set of entities/materials spawned when destroying an entity.
|
||||
foreach (var proto in protoManager.EnumeratePrototypes<EntityPrototype>())
|
||||
{
|
||||
if (proto.NoSpawn || proto.Abstract || pair.IsTestPrototype(proto))
|
||||
if (proto.HideSpawnMenu || proto.Abstract || pair.IsTestPrototype(proto))
|
||||
continue;
|
||||
|
||||
if (!proto.Components.TryGetValue(destructibleName, out var destructible))
|
||||
@@ -298,7 +299,7 @@ public sealed class MaterialArbitrageTest
|
||||
Dictionary<string, PhysicalCompositionComponent> physicalCompositions = new();
|
||||
foreach (var proto in protoManager.EnumeratePrototypes<EntityPrototype>())
|
||||
{
|
||||
if (proto.NoSpawn || proto.Abstract || pair.IsTestPrototype(proto))
|
||||
if (proto.HideSpawnMenu || proto.Abstract || pair.IsTestPrototype(proto))
|
||||
continue;
|
||||
|
||||
if (!proto.Components.TryGetValue(compositionName, out var composition))
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Content.IntegrationTests.Tests.Minds;
|
||||
[TestFixture]
|
||||
public sealed class GhostTests
|
||||
{
|
||||
struct GhostTestData
|
||||
private struct GhostTestData
|
||||
{
|
||||
public IEntityManager SEntMan;
|
||||
public Robust.Server.Player.IPlayerManager SPlayerMan;
|
||||
@@ -23,10 +23,10 @@ public sealed class GhostTests
|
||||
|
||||
public TestPair Pair = default!;
|
||||
|
||||
public TestMapData MapData => Pair.TestMap!;
|
||||
public readonly TestMapData MapData => Pair.TestMap!;
|
||||
|
||||
public RobustIntegrationTest.ServerIntegrationInstance Server => Pair.Server;
|
||||
public RobustIntegrationTest.ClientIntegrationInstance Client => Pair.Client;
|
||||
public readonly RobustIntegrationTest.ServerIntegrationInstance Server => Pair.Server;
|
||||
public readonly RobustIntegrationTest.ClientIntegrationInstance Client => Pair.Client;
|
||||
|
||||
/// <summary>
|
||||
/// Initial player coordinates. Note that this does not necessarily correspond to the position of the
|
||||
@@ -47,15 +47,16 @@ public sealed class GhostTests
|
||||
|
||||
private async Task<GhostTestData> SetupData()
|
||||
{
|
||||
var data = new GhostTestData();
|
||||
|
||||
// Client is needed to create a session for the ghost system. Creating a dummy session was too difficult.
|
||||
data.Pair = await PoolManager.GetServerClient(new PoolSettings
|
||||
var data = new GhostTestData
|
||||
{
|
||||
DummyTicker = false,
|
||||
Connected = true,
|
||||
Dirty = true
|
||||
});
|
||||
// Client is needed to create a session for the ghost system. Creating a dummy session was too difficult.
|
||||
Pair = await PoolManager.GetServerClient(new PoolSettings
|
||||
{
|
||||
DummyTicker = false,
|
||||
Connected = true,
|
||||
Dirty = true
|
||||
})
|
||||
};
|
||||
|
||||
data.SEntMan = data.Pair.Server.ResolveDependency<IServerEntityManager>();
|
||||
data.SPlayerMan = data.Pair.Server.ResolveDependency<Robust.Server.Player.IPlayerManager>();
|
||||
@@ -64,7 +65,8 @@ public sealed class GhostTests
|
||||
|
||||
// Setup map.
|
||||
await data.Pair.CreateTestMap();
|
||||
data.PlayerCoords = data.SEntMan.GetNetCoordinates(data.MapData.GridCoords.Offset(new Vector2(0.5f, 0.5f)).WithEntityId(data.MapData.MapUid, data.STransformSys, data.SEntMan));
|
||||
var test = data.MapData.GridCoords.Offset(new Vector2(0.5f, 0.5f));
|
||||
data.PlayerCoords = data.SEntMan.GetNetCoordinates(data.STransformSys.WithEntityId(data.MapData.GridCoords.Offset(new Vector2(0.5f, 0.5f)), data.MapData.MapUid));
|
||||
|
||||
if (data.Client.Session == null)
|
||||
Assert.Fail("No player");
|
||||
|
||||
@@ -169,7 +169,7 @@ public sealed partial class MindTests
|
||||
{
|
||||
var netManager = pair.Client.ResolveDependency<IClientNetManager>();
|
||||
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
|
||||
Assert.That(!playerMan.Sessions.Any());
|
||||
Assert.That(playerMan.Sessions, Is.Empty);
|
||||
|
||||
await Task.WhenAll(pair.Client.WaitIdleAsync(), pair.Client.WaitIdleAsync());
|
||||
pair.Client.SetConnectTarget(pair.Server);
|
||||
|
||||
@@ -34,7 +34,7 @@ public sealed class BuckleMovementTest : MovementTest
|
||||
Assert.That(Delta(), Is.InRange(-0.01f, 0.01f));
|
||||
Assert.That(buckle.Buckled, Is.True);
|
||||
Assert.That(buckle.BuckledTo, Is.EqualTo(STarget));
|
||||
Assert.That(strap.BuckledEntities, Is.EquivalentTo(new[]{SPlayer}));
|
||||
Assert.That(strap.BuckledEntities, Is.EquivalentTo(new[] { SPlayer }));
|
||||
Assert.That(cAlert.IsShowingAlert(CPlayer, strap.BuckledAlertType), Is.True);
|
||||
Assert.That(sAlert.IsShowingAlert(SPlayer, strap.BuckledAlertType), Is.True);
|
||||
|
||||
@@ -43,7 +43,7 @@ public sealed class BuckleMovementTest : MovementTest
|
||||
Assert.That(Delta(), Is.InRange(-0.01f, 0.01f));
|
||||
Assert.That(buckle.Buckled, Is.True);
|
||||
Assert.That(buckle.BuckledTo, Is.EqualTo(STarget));
|
||||
Assert.That(strap.BuckledEntities, Is.EquivalentTo(new[]{SPlayer}));
|
||||
Assert.That(strap.BuckledEntities, Is.EquivalentTo(new[] { SPlayer }));
|
||||
Assert.That(cAlert.IsShowingAlert(CPlayer, strap.BuckledAlertType), Is.True);
|
||||
Assert.That(sAlert.IsShowingAlert(SPlayer, strap.BuckledAlertType), Is.True);
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ public abstract class MovementTest : InteractionTest
|
||||
|
||||
for (var i = -Tiles; i <= Tiles; i++)
|
||||
{
|
||||
await SetTile(Plating, SEntMan.GetNetCoordinates(pCoords.Offset(new Vector2(i, 0))), MapData.Grid.Comp);
|
||||
await SetTile(Plating, SEntMan.GetNetCoordinates(pCoords.Offset(new Vector2(i, 0))), MapData.Grid);
|
||||
}
|
||||
AssertGridCount(1);
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@ namespace Content.IntegrationTests.Tests.Networking;
|
||||
[TestFixture]
|
||||
public sealed class PvsCommandTest
|
||||
{
|
||||
public static EntProtoId TestEnt = "MobHuman";
|
||||
private static readonly EntProtoId TestEnt = "MobHuman";
|
||||
|
||||
[Test]
|
||||
public async Task TestPvsCommands()
|
||||
{
|
||||
await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true, DummyTicker = false});
|
||||
await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true, DummyTicker = false });
|
||||
var (server, client) = pair;
|
||||
await pair.RunTicksSync(5);
|
||||
|
||||
|
||||
@@ -51,11 +51,12 @@ namespace Content.IntegrationTests.Tests.Networking
|
||||
PredictionTestComponent clientComponent = default!;
|
||||
var serverSystem = sEntityManager.System<PredictionTestEntitySystem>();
|
||||
var clientSystem = cEntityManager.System<PredictionTestEntitySystem>();
|
||||
var sMapSys = sEntityManager.System<SharedMapSystem>();
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
// Spawn dummy component entity.
|
||||
var map = sMapManager.CreateMap();
|
||||
sMapSys.CreateMap(out var map);
|
||||
serverEnt = sEntityManager.SpawnEntity(null, new MapCoordinates(new Vector2(0, 0), map));
|
||||
serverComponent = sEntityManager.AddComponent<PredictionTestComponent>(serverEnt);
|
||||
});
|
||||
@@ -67,7 +68,7 @@ namespace Content.IntegrationTests.Tests.Networking
|
||||
Assert.That(sGameTiming.TickTimingAdjustment, Is.EqualTo(0));
|
||||
|
||||
// Check client buffer is full
|
||||
Assert.That(cGameStateManager.CurrentBufferSize, Is.EqualTo(cGameStateManager.TargetBufferSize));
|
||||
Assert.That(cGameStateManager.GetApplicableStateCount(), Is.EqualTo(cGameStateManager.TargetBufferSize));
|
||||
Assert.That(cGameStateManager.TargetBufferSize, Is.EqualTo(2));
|
||||
|
||||
// This isn't required anymore, but the test had this for the sake of "technical things", and I cbf shifting
|
||||
@@ -99,7 +100,7 @@ namespace Content.IntegrationTests.Tests.Networking
|
||||
|
||||
// Client last ran tick 15 meaning it's ahead of the last server tick it processed (12)
|
||||
Assert.That(cGameTiming.CurTick, Is.EqualTo(expected));
|
||||
Assert.That(cGameTiming.LastProcessedTick, Is.EqualTo(new GameTick((uint)(baseTick - cGameStateManager.TargetBufferSize))));
|
||||
Assert.That(cGameTiming.LastProcessedTick, Is.EqualTo(new GameTick((uint) (baseTick - cGameStateManager.TargetBufferSize))));
|
||||
});
|
||||
|
||||
// *** I am using block scopes to visually distinguish these sections of the test to make it more readable.
|
||||
@@ -264,7 +265,7 @@ namespace Content.IntegrationTests.Tests.Networking
|
||||
// Assert timing is still correct.
|
||||
Assert.That(sGameTiming.CurTick, Is.EqualTo(new GameTick(baseTick + 8)));
|
||||
Assert.That(cGameTiming.CurTick, Is.EqualTo(new GameTick(baseTick + 8 + delta)));
|
||||
Assert.That(cGameTiming.LastProcessedTick, Is.EqualTo(new GameTick((uint)(baseTick + 8 - cGameStateManager.TargetBufferSize))));
|
||||
Assert.That(cGameTiming.LastProcessedTick, Is.EqualTo(new GameTick((uint) (baseTick + 8 - cGameStateManager.TargetBufferSize))));
|
||||
});
|
||||
|
||||
{
|
||||
|
||||
@@ -81,13 +81,14 @@ namespace Content.IntegrationTests.Tests
|
||||
|
||||
var entManager = server.ResolveDependency<IEntityManager>();
|
||||
var mapLoader = entManager.System<MapLoaderSystem>();
|
||||
var mapSystem = entManager.System<SharedMapSystem>();
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var cfg = server.ResolveDependency<IConfigurationManager>();
|
||||
Assert.That(cfg.GetCVar(CCVars.GridFill), Is.False);
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
var mapId = mapManager.CreateMap();
|
||||
mapSystem.CreateMap(out var mapId);
|
||||
try
|
||||
{
|
||||
#pragma warning disable NUnit2045
|
||||
@@ -168,6 +169,7 @@ namespace Content.IntegrationTests.Tests
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var entManager = server.ResolveDependency<IEntityManager>();
|
||||
var mapLoader = entManager.System<MapLoaderSystem>();
|
||||
var mapSystem = entManager.System<SharedMapSystem>();
|
||||
var protoManager = server.ResolveDependency<IPrototypeManager>();
|
||||
var ticker = entManager.EntitySysManager.GetEntitySystem<GameTicker>();
|
||||
var shuttleSystem = entManager.EntitySysManager.GetEntitySystem<ShuttleSystem>();
|
||||
@@ -177,7 +179,7 @@ namespace Content.IntegrationTests.Tests
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
var mapId = mapManager.CreateMap();
|
||||
mapSystem.CreateMap(out var mapId);
|
||||
try
|
||||
{
|
||||
ticker.LoadGameMap(protoManager.Index<GameMapPrototype>(mapProto), mapId, null);
|
||||
@@ -187,7 +189,7 @@ namespace Content.IntegrationTests.Tests
|
||||
throw new Exception($"Failed to load map {mapProto}", ex);
|
||||
}
|
||||
|
||||
var shuttleMap = mapManager.CreateMap();
|
||||
mapSystem.CreateMap(out var shuttleMap);
|
||||
var largest = 0f;
|
||||
EntityUid? targetGrid = null;
|
||||
var memberQuery = entManager.GetEntityQuery<StationMemberComponent>();
|
||||
@@ -256,7 +258,7 @@ namespace Content.IntegrationTests.Tests
|
||||
.Select(x => x.Job!.Value);
|
||||
|
||||
jobs.ExceptWith(spawnPoints);
|
||||
Assert.That(jobs, Is.Empty,$"There is no spawnpoints for {string.Join(", ", jobs)} on {mapProto}.");
|
||||
Assert.That(jobs, Is.Empty, $"There is no spawnpoints for {string.Join(", ", jobs)} on {mapProto}.");
|
||||
}
|
||||
|
||||
try
|
||||
@@ -329,6 +331,7 @@ namespace Content.IntegrationTests.Tests
|
||||
var resourceManager = server.ResolveDependency<IResourceManager>();
|
||||
var protoManager = server.ResolveDependency<IPrototypeManager>();
|
||||
var cfg = server.ResolveDependency<IConfigurationManager>();
|
||||
var mapSystem = server.System<SharedMapSystem>();
|
||||
Assert.That(cfg.GetCVar(CCVars.GridFill), Is.False);
|
||||
|
||||
var gameMaps = protoManager.EnumeratePrototypes<GameMapPrototype>().Select(o => o.MapPath).ToHashSet();
|
||||
@@ -359,7 +362,7 @@ namespace Content.IntegrationTests.Tests
|
||||
{
|
||||
foreach (var mapName in mapNames)
|
||||
{
|
||||
var mapId = mapManager.CreateMap();
|
||||
mapSystem.CreateMap(out var mapId);
|
||||
try
|
||||
{
|
||||
Assert.That(mapLoader.TryLoad(mapId, mapName, out _));
|
||||
|
||||
@@ -166,6 +166,7 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var server = pair.Server;
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
const float loadPower = 200;
|
||||
PowerSupplierComponent supplier = default!;
|
||||
PowerConsumerComponent consumer1 = default!;
|
||||
@@ -173,21 +174,19 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var map = mapManager.CreateMap();
|
||||
var grid = mapManager.CreateGrid(map);
|
||||
|
||||
var gridOwner = grid.Owner;
|
||||
var map = mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
|
||||
// Power only works when anchored
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
grid.SetTile(new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, i));
|
||||
mapSys.SetTile(grid, new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, i));
|
||||
}
|
||||
|
||||
var generatorEnt = entityManager.SpawnEntity("GeneratorDummy", gridOwner.ToCoordinates());
|
||||
var consumerEnt1 = entityManager.SpawnEntity("ConsumerDummy", gridOwner.ToCoordinates(0, 1));
|
||||
var consumerEnt2 = entityManager.SpawnEntity("ConsumerDummy", gridOwner.ToCoordinates(0, 2));
|
||||
var generatorEnt = entityManager.SpawnEntity("GeneratorDummy", grid.Owner.ToCoordinates());
|
||||
var consumerEnt1 = entityManager.SpawnEntity("ConsumerDummy", grid.Owner.ToCoordinates(0, 1));
|
||||
var consumerEnt2 = entityManager.SpawnEntity("ConsumerDummy", grid.Owner.ToCoordinates(0, 2));
|
||||
|
||||
supplier = entityManager.GetComponent<PowerSupplierComponent>(generatorEnt);
|
||||
consumer1 = entityManager.GetComponent<PowerConsumerComponent>(consumerEnt1);
|
||||
@@ -229,6 +228,7 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var server = pair.Server;
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
const float loadPower = 200;
|
||||
PowerSupplierComponent supplier = default!;
|
||||
PowerConsumerComponent consumer1 = default!;
|
||||
@@ -236,21 +236,19 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var map = mapManager.CreateMap();
|
||||
var grid = mapManager.CreateGrid(map);
|
||||
|
||||
var gridOwner = grid.Owner;
|
||||
var map = mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
|
||||
// Power only works when anchored
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
grid.SetTile(new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, i));
|
||||
mapSys.SetTile(grid, new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, i));
|
||||
}
|
||||
|
||||
var generatorEnt = entityManager.SpawnEntity("GeneratorDummy", gridOwner.ToCoordinates());
|
||||
var consumerEnt1 = entityManager.SpawnEntity("ConsumerDummy", gridOwner.ToCoordinates(0, 1));
|
||||
var consumerEnt2 = entityManager.SpawnEntity("ConsumerDummy", gridOwner.ToCoordinates(0, 2));
|
||||
var generatorEnt = entityManager.SpawnEntity("GeneratorDummy", grid.Owner.ToCoordinates());
|
||||
var consumerEnt1 = entityManager.SpawnEntity("ConsumerDummy", grid.Owner.ToCoordinates(0, 1));
|
||||
var consumerEnt2 = entityManager.SpawnEntity("ConsumerDummy", grid.Owner.ToCoordinates(0, 2));
|
||||
|
||||
supplier = entityManager.GetComponent<PowerSupplierComponent>(generatorEnt);
|
||||
consumer1 = entityManager.GetComponent<PowerConsumerComponent>(consumerEnt1);
|
||||
@@ -288,25 +286,25 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var server = pair.Server;
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
var gameTiming = server.ResolveDependency<IGameTiming>();
|
||||
PowerSupplierComponent supplier = default!;
|
||||
PowerConsumerComponent consumer = default!;
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var map = mapManager.CreateMap();
|
||||
var grid = mapManager.CreateGrid(map);
|
||||
var gridOwner = grid.Owner;
|
||||
var map = mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
|
||||
// Power only works when anchored
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
grid.SetTile(new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, i));
|
||||
mapSys.SetTile(grid, new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, i));
|
||||
}
|
||||
|
||||
var generatorEnt = entityManager.SpawnEntity("GeneratorDummy", gridOwner.ToCoordinates());
|
||||
var consumerEnt = entityManager.SpawnEntity("ConsumerDummy", gridOwner.ToCoordinates(0, 2));
|
||||
var generatorEnt = entityManager.SpawnEntity("GeneratorDummy", grid.Owner.ToCoordinates());
|
||||
var consumerEnt = entityManager.SpawnEntity("ConsumerDummy", grid.Owner.ToCoordinates(0, 2));
|
||||
|
||||
supplier = entityManager.GetComponent<PowerSupplierComponent>(generatorEnt);
|
||||
consumer = entityManager.GetComponent<PowerConsumerComponent>(consumerEnt);
|
||||
@@ -378,6 +376,7 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var gameTiming = server.ResolveDependency<IGameTiming>();
|
||||
var batterySys = entityManager.System<BatterySystem>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
const float startingCharge = 100_000;
|
||||
|
||||
PowerNetworkBatteryComponent netBattery = default!;
|
||||
@@ -386,19 +385,18 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var map = mapManager.CreateMap();
|
||||
var grid = mapManager.CreateGrid(map);
|
||||
var gridOwner = grid.Owner;
|
||||
var map = mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
|
||||
// Power only works when anchored
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
grid.SetTile(new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, i));
|
||||
mapSys.SetTile(grid, new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, i));
|
||||
}
|
||||
|
||||
var generatorEnt = entityManager.SpawnEntity("DischargingBatteryDummy", gridOwner.ToCoordinates());
|
||||
var consumerEnt = entityManager.SpawnEntity("ConsumerDummy", gridOwner.ToCoordinates(0, 2));
|
||||
var generatorEnt = entityManager.SpawnEntity("DischargingBatteryDummy", grid.Owner.ToCoordinates());
|
||||
var consumerEnt = entityManager.SpawnEntity("ConsumerDummy", grid.Owner.ToCoordinates(0, 2));
|
||||
|
||||
netBattery = entityManager.GetComponent<PowerNetworkBatteryComponent>(generatorEnt);
|
||||
battery = entityManager.GetComponent<BatteryComponent>(generatorEnt);
|
||||
@@ -479,6 +477,7 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var batterySys = entityManager.System<BatterySystem>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
PowerSupplierComponent supplier = default!;
|
||||
PowerNetworkBatteryComponent netBattery = default!;
|
||||
BatteryComponent battery = default!;
|
||||
@@ -490,20 +489,19 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var map = mapManager.CreateMap();
|
||||
var grid = mapManager.CreateGrid(map);
|
||||
var gridOwner = grid.Owner;
|
||||
var map = mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
|
||||
// Power only works when anchored
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
grid.SetTile(new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, i));
|
||||
mapSys.SetTile(grid, new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, i));
|
||||
}
|
||||
|
||||
var generatorEnt = entityManager.SpawnEntity("GeneratorDummy", gridOwner.ToCoordinates());
|
||||
var consumerEnt = entityManager.SpawnEntity("ConsumerDummy", gridOwner.ToCoordinates(0, 1));
|
||||
var batteryEnt = entityManager.SpawnEntity("DischargingBatteryDummy", gridOwner.ToCoordinates(0, 2));
|
||||
var generatorEnt = entityManager.SpawnEntity("GeneratorDummy", grid.Owner.ToCoordinates());
|
||||
var consumerEnt = entityManager.SpawnEntity("ConsumerDummy", grid.Owner.ToCoordinates(0, 1));
|
||||
var batteryEnt = entityManager.SpawnEntity("DischargingBatteryDummy", grid.Owner.ToCoordinates(0, 2));
|
||||
netBattery = entityManager.GetComponent<PowerNetworkBatteryComponent>(batteryEnt);
|
||||
battery = entityManager.GetComponent<BatteryComponent>(batteryEnt);
|
||||
supplier = entityManager.GetComponent<PowerSupplierComponent>(generatorEnt);
|
||||
@@ -577,24 +575,24 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var gameTiming = server.ResolveDependency<IGameTiming>();
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var batterySys = entityManager.System<BatterySystem>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
PowerSupplierComponent supplier = default!;
|
||||
BatteryComponent battery = default!;
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var map = mapManager.CreateMap();
|
||||
var grid = mapManager.CreateGrid(map);
|
||||
var gridOwner = grid.Owner;
|
||||
var map = mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
|
||||
// Power only works when anchored
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
grid.SetTile(new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, i));
|
||||
mapSys.SetTile(grid, new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, i));
|
||||
}
|
||||
|
||||
var generatorEnt = entityManager.SpawnEntity("GeneratorDummy", gridOwner.ToCoordinates());
|
||||
var batteryEnt = entityManager.SpawnEntity("ChargingBatteryDummy", gridOwner.ToCoordinates(0, 2));
|
||||
var generatorEnt = entityManager.SpawnEntity("GeneratorDummy", grid.Owner.ToCoordinates());
|
||||
var batteryEnt = entityManager.SpawnEntity("ChargingBatteryDummy", grid.Owner.ToCoordinates(0, 2));
|
||||
|
||||
supplier = entityManager.GetComponent<PowerSupplierComponent>(generatorEnt);
|
||||
var netBattery = entityManager.GetComponent<PowerNetworkBatteryComponent>(batteryEnt);
|
||||
@@ -634,6 +632,7 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var gameTiming = server.ResolveDependency<IGameTiming>();
|
||||
var batterySys = entityManager.System<BatterySystem>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
PowerConsumerComponent consumer = default!;
|
||||
PowerSupplierComponent supplier = default!;
|
||||
PowerNetworkBatteryComponent netBattery = default!;
|
||||
@@ -641,23 +640,22 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var map = mapManager.CreateMap();
|
||||
var grid = mapManager.CreateGrid(map);
|
||||
var gridOwner = grid.Owner;
|
||||
var map = mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
|
||||
// Power only works when anchored
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
grid.SetTile(new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, i));
|
||||
mapSys.SetTile(grid, new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, i));
|
||||
}
|
||||
|
||||
var terminal = entityManager.SpawnEntity("CableTerminal", gridOwner.ToCoordinates(0, 1));
|
||||
var terminal = entityManager.SpawnEntity("CableTerminal", grid.Owner.ToCoordinates(0, 1));
|
||||
entityManager.GetComponent<TransformComponent>(terminal).LocalRotation = Angle.FromDegrees(180);
|
||||
|
||||
var batteryEnt = entityManager.SpawnEntity("FullBatteryDummy", gridOwner.ToCoordinates(0, 2));
|
||||
var supplyEnt = entityManager.SpawnEntity("GeneratorDummy", gridOwner.ToCoordinates(0, 0));
|
||||
var consumerEnt = entityManager.SpawnEntity("ConsumerDummy", gridOwner.ToCoordinates(0, 3));
|
||||
var batteryEnt = entityManager.SpawnEntity("FullBatteryDummy", grid.Owner.ToCoordinates(0, 2));
|
||||
var supplyEnt = entityManager.SpawnEntity("GeneratorDummy", grid.Owner.ToCoordinates(0, 0));
|
||||
var consumerEnt = entityManager.SpawnEntity("ConsumerDummy", grid.Owner.ToCoordinates(0, 3));
|
||||
|
||||
consumer = entityManager.GetComponent<PowerConsumerComponent>(consumerEnt);
|
||||
supplier = entityManager.GetComponent<PowerSupplierComponent>(supplyEnt);
|
||||
@@ -712,6 +710,7 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var gameTiming = server.ResolveDependency<IGameTiming>();
|
||||
var batterySys = entityManager.System<BatterySystem>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
PowerConsumerComponent consumer = default!;
|
||||
PowerSupplierComponent supplier = default!;
|
||||
PowerNetworkBatteryComponent netBattery = default!;
|
||||
@@ -719,23 +718,22 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var map = mapManager.CreateMap();
|
||||
var grid = mapManager.CreateGrid(map);
|
||||
var gridOwner = grid.Owner;
|
||||
var map = mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
|
||||
// Power only works when anchored
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
grid.SetTile(new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, i));
|
||||
mapSys.SetTile(grid, new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, i));
|
||||
}
|
||||
|
||||
var terminal = entityManager.SpawnEntity("CableTerminal", gridOwner.ToCoordinates(0, 1));
|
||||
var terminal = entityManager.SpawnEntity("CableTerminal", grid.Owner.ToCoordinates(0, 1));
|
||||
entityManager.GetComponent<TransformComponent>(terminal).LocalRotation = Angle.FromDegrees(180);
|
||||
|
||||
var batteryEnt = entityManager.SpawnEntity("FullBatteryDummy", gridOwner.ToCoordinates(0, 2));
|
||||
var supplyEnt = entityManager.SpawnEntity("GeneratorDummy", gridOwner.ToCoordinates(0, 0));
|
||||
var consumerEnt = entityManager.SpawnEntity("ConsumerDummy", gridOwner.ToCoordinates(0, 3));
|
||||
var batteryEnt = entityManager.SpawnEntity("FullBatteryDummy", grid.Owner.ToCoordinates(0, 2));
|
||||
var supplyEnt = entityManager.SpawnEntity("GeneratorDummy", grid.Owner.ToCoordinates(0, 0));
|
||||
var consumerEnt = entityManager.SpawnEntity("ConsumerDummy", grid.Owner.ToCoordinates(0, 3));
|
||||
|
||||
consumer = entityManager.GetComponent<PowerConsumerComponent>(consumerEnt);
|
||||
supplier = entityManager.GetComponent<PowerSupplierComponent>(supplyEnt);
|
||||
@@ -789,15 +787,15 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var batterySys = entityManager.System<BatterySystem>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
PowerConsumerComponent consumer1 = default!;
|
||||
PowerConsumerComponent consumer2 = default!;
|
||||
PowerSupplierComponent supplier = default!;
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var map = mapManager.CreateMap();
|
||||
var grid = mapManager.CreateGrid(map);
|
||||
var gridOwner = grid.Owner;
|
||||
var map = mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
|
||||
// Map layout here is
|
||||
// C - consumer
|
||||
@@ -810,19 +808,19 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
// Power only works when anchored
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
grid.SetTile(new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, i));
|
||||
mapSys.SetTile(grid, new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, i));
|
||||
}
|
||||
|
||||
entityManager.SpawnEntity("CableTerminal", gridOwner.ToCoordinates(0, 2));
|
||||
var terminal = entityManager.SpawnEntity("CableTerminal", gridOwner.ToCoordinates(0, 2));
|
||||
entityManager.SpawnEntity("CableTerminal", grid.Owner.ToCoordinates(0, 2));
|
||||
var terminal = entityManager.SpawnEntity("CableTerminal", grid.Owner.ToCoordinates(0, 2));
|
||||
entityManager.GetComponent<TransformComponent>(terminal).LocalRotation = Angle.FromDegrees(180);
|
||||
|
||||
var batteryEnt1 = entityManager.SpawnEntity("FullBatteryDummy", gridOwner.ToCoordinates(0, 1));
|
||||
var batteryEnt2 = entityManager.SpawnEntity("FullBatteryDummy", gridOwner.ToCoordinates(0, 3));
|
||||
var supplyEnt = entityManager.SpawnEntity("GeneratorDummy", gridOwner.ToCoordinates(0, 2));
|
||||
var consumerEnt1 = entityManager.SpawnEntity("ConsumerDummy", gridOwner.ToCoordinates(0, 0));
|
||||
var consumerEnt2 = entityManager.SpawnEntity("ConsumerDummy", gridOwner.ToCoordinates(0, 4));
|
||||
var batteryEnt1 = entityManager.SpawnEntity("FullBatteryDummy", grid.Owner.ToCoordinates(0, 1));
|
||||
var batteryEnt2 = entityManager.SpawnEntity("FullBatteryDummy", grid.Owner.ToCoordinates(0, 3));
|
||||
var supplyEnt = entityManager.SpawnEntity("GeneratorDummy", grid.Owner.ToCoordinates(0, 2));
|
||||
var consumerEnt1 = entityManager.SpawnEntity("ConsumerDummy", grid.Owner.ToCoordinates(0, 0));
|
||||
var consumerEnt2 = entityManager.SpawnEntity("ConsumerDummy", grid.Owner.ToCoordinates(0, 4));
|
||||
|
||||
consumer1 = entityManager.GetComponent<PowerConsumerComponent>(consumerEnt1);
|
||||
consumer2 = entityManager.GetComponent<PowerConsumerComponent>(consumerEnt2);
|
||||
@@ -887,6 +885,7 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var gameTiming = server.ResolveDependency<IGameTiming>();
|
||||
var batterySys = entityManager.System<BatterySystem>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
PowerConsumerComponent consumer = default!;
|
||||
PowerSupplierComponent supplier1 = default!;
|
||||
PowerSupplierComponent supplier2 = default!;
|
||||
@@ -897,9 +896,8 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var map = mapManager.CreateMap();
|
||||
var grid = mapManager.CreateGrid(map);
|
||||
var gridOwner = grid.Owner;
|
||||
var map = mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
|
||||
// Layout is two generators, two batteries, and one load. As to why two: because previously this test
|
||||
// would fail ONLY if there were more than two batteries present, because each of them tries to supply
|
||||
@@ -911,17 +909,17 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
// Place cables
|
||||
for (var i = -2; i <= 2; i++)
|
||||
{
|
||||
grid.SetTile(new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, i));
|
||||
mapSys.SetTile(grid, new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, i));
|
||||
}
|
||||
|
||||
var batteryEnt1 = entityManager.SpawnEntity("FullBatteryDummy", gridOwner.ToCoordinates(0, 2));
|
||||
var batteryEnt2 = entityManager.SpawnEntity("FullBatteryDummy", gridOwner.ToCoordinates(0, -2));
|
||||
var batteryEnt1 = entityManager.SpawnEntity("FullBatteryDummy", grid.Owner.ToCoordinates(0, 2));
|
||||
var batteryEnt2 = entityManager.SpawnEntity("FullBatteryDummy", grid.Owner.ToCoordinates(0, -2));
|
||||
|
||||
var supplyEnt1 = entityManager.SpawnEntity("GeneratorDummy", gridOwner.ToCoordinates(0, 1));
|
||||
var supplyEnt2 = entityManager.SpawnEntity("GeneratorDummy", gridOwner.ToCoordinates(0, -1));
|
||||
var supplyEnt1 = entityManager.SpawnEntity("GeneratorDummy", grid.Owner.ToCoordinates(0, 1));
|
||||
var supplyEnt2 = entityManager.SpawnEntity("GeneratorDummy", grid.Owner.ToCoordinates(0, -1));
|
||||
|
||||
var consumerEnt = entityManager.SpawnEntity("ConsumerDummy", gridOwner.ToCoordinates(0, 0));
|
||||
var consumerEnt = entityManager.SpawnEntity("ConsumerDummy", grid.Owner.ToCoordinates(0, 0));
|
||||
|
||||
consumer = entityManager.GetComponent<PowerConsumerComponent>(consumerEnt);
|
||||
supplier1 = entityManager.GetComponent<PowerSupplierComponent>(supplyEnt1);
|
||||
@@ -985,15 +983,15 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var batterySys = entityManager.System<BatterySystem>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
PowerConsumerComponent consumer1 = default!;
|
||||
PowerConsumerComponent consumer2 = default!;
|
||||
PowerSupplierComponent supplier = default!;
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var map = mapManager.CreateMap();
|
||||
var grid = mapManager.CreateGrid(map);
|
||||
var gridOwner = grid.Owner;
|
||||
var map = mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
|
||||
// Map layout here is
|
||||
// C - consumer
|
||||
@@ -1006,19 +1004,19 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
// Power only works when anchored
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
grid.SetTile(new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, i));
|
||||
mapSys.SetTile(grid, new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, i));
|
||||
}
|
||||
|
||||
entityManager.SpawnEntity("CableTerminal", gridOwner.ToCoordinates(0, 2));
|
||||
var terminal = entityManager.SpawnEntity("CableTerminal", gridOwner.ToCoordinates(0, 2));
|
||||
entityManager.SpawnEntity("CableTerminal", grid.Owner.ToCoordinates(0, 2));
|
||||
var terminal = entityManager.SpawnEntity("CableTerminal", grid.Owner.ToCoordinates(0, 2));
|
||||
entityManager.GetComponent<TransformComponent>(terminal).LocalRotation = Angle.FromDegrees(180);
|
||||
|
||||
var batteryEnt1 = entityManager.SpawnEntity("FullBatteryDummy", gridOwner.ToCoordinates(0, 1));
|
||||
var batteryEnt2 = entityManager.SpawnEntity("FullBatteryDummy", gridOwner.ToCoordinates(0, 3));
|
||||
var supplyEnt = entityManager.SpawnEntity("GeneratorDummy", gridOwner.ToCoordinates(0, 2));
|
||||
var consumerEnt1 = entityManager.SpawnEntity("ConsumerDummy", gridOwner.ToCoordinates(0, 0));
|
||||
var consumerEnt2 = entityManager.SpawnEntity("ConsumerDummy", gridOwner.ToCoordinates(0, 4));
|
||||
var batteryEnt1 = entityManager.SpawnEntity("FullBatteryDummy", grid.Owner.ToCoordinates(0, 1));
|
||||
var batteryEnt2 = entityManager.SpawnEntity("FullBatteryDummy", grid.Owner.ToCoordinates(0, 3));
|
||||
var supplyEnt = entityManager.SpawnEntity("GeneratorDummy", grid.Owner.ToCoordinates(0, 2));
|
||||
var consumerEnt1 = entityManager.SpawnEntity("ConsumerDummy", grid.Owner.ToCoordinates(0, 0));
|
||||
var consumerEnt2 = entityManager.SpawnEntity("ConsumerDummy", grid.Owner.ToCoordinates(0, 4));
|
||||
|
||||
consumer1 = entityManager.GetComponent<PowerConsumerComponent>(consumerEnt1);
|
||||
consumer2 = entityManager.GetComponent<PowerConsumerComponent>(consumerEnt2);
|
||||
@@ -1073,29 +1071,29 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var batterySys = entityManager.System<BatterySystem>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
PowerConsumerComponent consumer = default!;
|
||||
PowerSupplierComponent supplier = default!;
|
||||
PowerNetworkBatteryComponent netBattery = default!;
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
var map = mapManager.CreateMap();
|
||||
var grid = mapManager.CreateGrid(map);
|
||||
var gridOwner = grid.Owner;
|
||||
var map = mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
|
||||
// Power only works when anchored
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
grid.SetTile(new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, i));
|
||||
mapSys.SetTile(grid, new Vector2i(0, i), new Tile(1));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, i));
|
||||
}
|
||||
|
||||
var terminal = entityManager.SpawnEntity("CableTerminal", gridOwner.ToCoordinates(0, 1));
|
||||
var terminal = entityManager.SpawnEntity("CableTerminal", grid.Owner.ToCoordinates(0, 1));
|
||||
entityManager.GetComponent<TransformComponent>(terminal).LocalRotation = Angle.FromDegrees(180);
|
||||
|
||||
var batteryEnt = entityManager.SpawnEntity("FullBatteryDummy", gridOwner.ToCoordinates(0, 2));
|
||||
var supplyEnt = entityManager.SpawnEntity("GeneratorDummy", gridOwner.ToCoordinates(0, 0));
|
||||
var consumerEnt = entityManager.SpawnEntity("ConsumerDummy", gridOwner.ToCoordinates(0, 3));
|
||||
var batteryEnt = entityManager.SpawnEntity("FullBatteryDummy", grid.Owner.ToCoordinates(0, 2));
|
||||
var supplyEnt = entityManager.SpawnEntity("GeneratorDummy", grid.Owner.ToCoordinates(0, 0));
|
||||
var consumerEnt = entityManager.SpawnEntity("ConsumerDummy", grid.Owner.ToCoordinates(0, 3));
|
||||
|
||||
consumer = entityManager.GetComponent<PowerConsumerComponent>(consumerEnt);
|
||||
supplier = entityManager.GetComponent<PowerSupplierComponent>(supplyEnt);
|
||||
@@ -1158,6 +1156,7 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var nodeContainer = entityManager.System<NodeContainerSystem>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
CableNode leftNode = default!;
|
||||
CableNode rightNode = default!;
|
||||
Node batteryInput = default!;
|
||||
@@ -1165,25 +1164,24 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var map = mapManager.CreateMap();
|
||||
var grid = mapManager.CreateGrid(map);
|
||||
var gridOwner = grid.Owner;
|
||||
var map = mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
|
||||
// Power only works when anchored
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
grid.SetTile(new Vector2i(0, i), new Tile(1));
|
||||
mapSys.SetTile(grid, new Vector2i(0, i), new Tile(1));
|
||||
}
|
||||
|
||||
var leftEnt = entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, 0));
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, 1));
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, 2));
|
||||
var rightEnt = entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, 3));
|
||||
var leftEnt = entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, 0));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, 1));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, 2));
|
||||
var rightEnt = entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, 3));
|
||||
|
||||
var terminal = entityManager.SpawnEntity("CableTerminal", gridOwner.ToCoordinates(0, 1));
|
||||
var terminal = entityManager.SpawnEntity("CableTerminal", grid.Owner.ToCoordinates(0, 1));
|
||||
entityManager.GetComponent<TransformComponent>(terminal).LocalRotation = Angle.FromDegrees(180);
|
||||
|
||||
var battery = entityManager.SpawnEntity("FullBatteryDummy", gridOwner.ToCoordinates(0, 2));
|
||||
var battery = entityManager.SpawnEntity("FullBatteryDummy", grid.Owner.ToCoordinates(0, 2));
|
||||
var batteryNodeContainer = entityManager.GetComponent<NodeContainerComponent>(battery);
|
||||
|
||||
if (nodeContainer.TryGetNode<CableNode>(entityManager.GetComponent<NodeContainerComponent>(leftEnt),
|
||||
@@ -1224,29 +1222,29 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var batterySys = entityManager.System<BatterySystem>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
PowerNetworkBatteryComponent substationNetBattery = default!;
|
||||
BatteryComponent apcBattery = default!;
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var map = mapManager.CreateMap();
|
||||
var grid = mapManager.CreateGrid(map);
|
||||
var gridOwner = grid.Owner;
|
||||
var map = mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
|
||||
// Power only works when anchored
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
grid.SetTile(new Vector2i(0, i), new Tile(1));
|
||||
mapSys.SetTile(grid, new Vector2i(0, i), new Tile(1));
|
||||
}
|
||||
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, 0));
|
||||
entityManager.SpawnEntity("CableHV", gridOwner.ToCoordinates(0, 1));
|
||||
entityManager.SpawnEntity("CableMV", gridOwner.ToCoordinates(0, 1));
|
||||
entityManager.SpawnEntity("CableMV", gridOwner.ToCoordinates(0, 2));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, 0));
|
||||
entityManager.SpawnEntity("CableHV", grid.Owner.ToCoordinates(0, 1));
|
||||
entityManager.SpawnEntity("CableMV", grid.Owner.ToCoordinates(0, 1));
|
||||
entityManager.SpawnEntity("CableMV", grid.Owner.ToCoordinates(0, 2));
|
||||
|
||||
var generatorEnt = entityManager.SpawnEntity("GeneratorDummy", gridOwner.ToCoordinates(0, 0));
|
||||
var substationEnt = entityManager.SpawnEntity("SubstationDummy", gridOwner.ToCoordinates(0, 1));
|
||||
var apcEnt = entityManager.SpawnEntity("ApcDummy", gridOwner.ToCoordinates(0, 2));
|
||||
var generatorEnt = entityManager.SpawnEntity("GeneratorDummy", grid.Owner.ToCoordinates(0, 0));
|
||||
var substationEnt = entityManager.SpawnEntity("SubstationDummy", grid.Owner.ToCoordinates(0, 1));
|
||||
var apcEnt = entityManager.SpawnEntity("ApcDummy", grid.Owner.ToCoordinates(0, 2));
|
||||
|
||||
var generatorSupplier = entityManager.GetComponent<PowerSupplierComponent>(generatorEnt);
|
||||
substationNetBattery = entityManager.GetComponent<PowerNetworkBatteryComponent>(substationEnt);
|
||||
@@ -1281,33 +1279,33 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var batterySys = entityManager.System<BatterySystem>();
|
||||
var extensionCableSystem = entityManager.System<ExtensionCableSystem>();
|
||||
var mapSys = entityManager.System<SharedMapSystem>();
|
||||
PowerNetworkBatteryComponent apcNetBattery = default!;
|
||||
ApcPowerReceiverComponent receiver = default!;
|
||||
ApcPowerReceiverComponent unpoweredReceiver = default!;
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var map = mapManager.CreateMap();
|
||||
var grid = mapManager.CreateGrid(map);
|
||||
var gridOwner = grid.Owner;
|
||||
var map = mapSys.CreateMap(out var mapId);
|
||||
var grid = mapManager.CreateGridEntity(mapId);
|
||||
|
||||
const int range = 5;
|
||||
|
||||
// Power only works when anchored
|
||||
for (var i = 0; i < range; i++)
|
||||
{
|
||||
grid.SetTile(new Vector2i(0, i), new Tile(1));
|
||||
mapSys.SetTile(grid, new Vector2i(0, i), new Tile(1));
|
||||
}
|
||||
|
||||
var apcEnt = entityManager.SpawnEntity("ApcDummy", gridOwner.ToCoordinates(0, 0));
|
||||
var apcExtensionEnt = entityManager.SpawnEntity("CableApcExtension", gridOwner.ToCoordinates(0, 0));
|
||||
var apcEnt = entityManager.SpawnEntity("ApcDummy", grid.Owner.ToCoordinates(0, 0));
|
||||
var apcExtensionEnt = entityManager.SpawnEntity("CableApcExtension", grid.Owner.ToCoordinates(0, 0));
|
||||
|
||||
// Create a powered receiver in range (range is 0 indexed)
|
||||
var powerReceiverEnt = entityManager.SpawnEntity("ApcPowerReceiverDummy", gridOwner.ToCoordinates(0, range - 1));
|
||||
var powerReceiverEnt = entityManager.SpawnEntity("ApcPowerReceiverDummy", grid.Owner.ToCoordinates(0, range - 1));
|
||||
receiver = entityManager.GetComponent<ApcPowerReceiverComponent>(powerReceiverEnt);
|
||||
|
||||
// Create an unpowered receiver outside range
|
||||
var unpoweredReceiverEnt = entityManager.SpawnEntity("ApcPowerReceiverDummy", gridOwner.ToCoordinates(0, range));
|
||||
var unpoweredReceiverEnt = entityManager.SpawnEntity("ApcPowerReceiverDummy", grid.Owner.ToCoordinates(0, range));
|
||||
unpoweredReceiver = entityManager.GetComponent<ApcPowerReceiverComponent>(unpoweredReceiverEnt);
|
||||
|
||||
var battery = entityManager.GetComponent<BatteryComponent>(apcEnt);
|
||||
|
||||
@@ -40,6 +40,7 @@ public sealed class PrototypeSaveTest
|
||||
var prototypeMan = server.ResolveDependency<IPrototypeManager>();
|
||||
var seriMan = server.ResolveDependency<ISerializationManager>();
|
||||
var compFact = server.ResolveDependency<IComponentFactory>();
|
||||
var mapSystem = server.System<SharedMapSystem>();
|
||||
|
||||
var prototypes = new List<EntityPrototype>();
|
||||
EntityUid uid;
|
||||
@@ -77,7 +78,7 @@ public sealed class PrototypeSaveTest
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
Assert.That(!mapManager.IsMapInitialized(mapId));
|
||||
Assert.That(!mapSystem.IsInitialized(mapId));
|
||||
var testLocation = grid.Owner.ToCoordinates();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
@@ -184,7 +185,7 @@ public sealed class PrototypeSaveTest
|
||||
IDependencyCollection dependencies, bool alwaysWrite = false,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
if (WritingComponent != "Transform" && (Prototype?.NoSpawn == false))
|
||||
if (WritingComponent != "Transform" && Prototype?.HideSpawnMenu == false)
|
||||
{
|
||||
// Maybe this will be necessary in the future, but at the moment it just indicates that there is some
|
||||
// issue, like a non-nullable entityUid data-field. If a component MUST have an entity uid to work with,
|
||||
|
||||
@@ -29,7 +29,7 @@ public sealed class PullerTest
|
||||
{
|
||||
foreach (var proto in protoManager.EnumeratePrototypes<EntityPrototype>())
|
||||
{
|
||||
if (!proto.TryGetComponent(out PullerComponent? puller))
|
||||
if (!proto.TryGetComponent(out PullerComponent? puller, compFactory))
|
||||
continue;
|
||||
|
||||
if (!puller.NeedsHands)
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Shared.Lathe;
|
||||
using Content.Shared.Research.Prototypes;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.IntegrationTests.Tests;
|
||||
@@ -52,6 +53,7 @@ public sealed class ResearchTest
|
||||
var server = pair.Server;
|
||||
|
||||
var protoManager = server.ResolveDependency<IPrototypeManager>();
|
||||
var compFact = server.ResolveDependency<IComponentFactory>();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
@@ -65,7 +67,7 @@ public sealed class ResearchTest
|
||||
if (pair.IsTestPrototype(proto))
|
||||
continue;
|
||||
|
||||
if (!proto.TryGetComponent<LatheComponent>(out var lathe))
|
||||
if (!proto.TryGetComponent<LatheComponent>(out var lathe, compFact))
|
||||
continue;
|
||||
allLathes.Add(lathe);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Salvage;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Salvage;
|
||||
using Robust.Server.GameObjects;
|
||||
@@ -28,6 +27,7 @@ public sealed class SalvageTest
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var prototypeManager = server.ResolveDependency<IPrototypeManager>();
|
||||
var cfg = server.ResolveDependency<IConfigurationManager>();
|
||||
var mapSystem = entManager.System<SharedMapSystem>();
|
||||
Assert.That(cfg.GetCVar(CCVars.GridFill), Is.False);
|
||||
|
||||
await server.WaitPost(() =>
|
||||
@@ -36,7 +36,7 @@ public sealed class SalvageTest
|
||||
{
|
||||
var mapFile = salvage.MapPath;
|
||||
|
||||
var mapId = mapManager.CreateMap();
|
||||
mapSystem.CreateMap(out var mapId);
|
||||
try
|
||||
{
|
||||
Assert.That(mapLoader.TryLoad(mapId, mapFile.ToString(), out var roots));
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace Content.IntegrationTests.Tests
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var sEntities = server.ResolveDependency<IEntityManager>();
|
||||
var mapLoader = sEntities.System<MapLoaderSystem>();
|
||||
var mapSystem = sEntities.System<SharedMapSystem>();
|
||||
var xformSystem = sEntities.EntitySysManager.GetEntitySystem<SharedTransformSystem>();
|
||||
var resManager = server.ResolveDependency<IResourceManager>();
|
||||
var cfg = server.ResolveDependency<IConfigurationManager>();
|
||||
@@ -33,19 +34,17 @@ namespace Content.IntegrationTests.Tests
|
||||
var dir = new ResPath(mapPath).Directory;
|
||||
resManager.UserData.CreateDir(dir);
|
||||
|
||||
var mapId = mapManager.CreateMap();
|
||||
mapSystem.CreateMap(out var mapId);
|
||||
|
||||
{
|
||||
var mapGrid = mapManager.CreateGrid(mapId);
|
||||
var mapGridEnt = mapGrid.Owner;
|
||||
xformSystem.SetWorldPosition(mapGridEnt, new Vector2(10, 10));
|
||||
mapGrid.SetTile(new Vector2i(0, 0), new Tile(1, (TileRenderFlag) 1, 255));
|
||||
var mapGrid = mapManager.CreateGridEntity(mapId);
|
||||
xformSystem.SetWorldPosition(mapGrid, new Vector2(10, 10));
|
||||
mapSystem.SetTile(mapGrid, new Vector2i(0, 0), new Tile(1, (TileRenderFlag) 1, 255));
|
||||
}
|
||||
{
|
||||
var mapGrid = mapManager.CreateGrid(mapId);
|
||||
var mapGridEnt = mapGrid.Owner;
|
||||
xformSystem.SetWorldPosition(mapGridEnt, new Vector2(-8, -8));
|
||||
mapGrid.SetTile(new Vector2i(0, 0), new Tile(2, (TileRenderFlag) 1, 254));
|
||||
var mapGrid = mapManager.CreateGridEntity(mapId);
|
||||
xformSystem.SetWorldPosition(mapGrid, new Vector2(-8, -8));
|
||||
mapSystem.SetTile(mapGrid, new Vector2i(0, 0), new Tile(2, (TileRenderFlag) 1, 254));
|
||||
}
|
||||
|
||||
Assert.Multiple(() => mapLoader.SaveMap(mapId, mapPath));
|
||||
@@ -74,7 +73,7 @@ namespace Content.IntegrationTests.Tests
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(xformSystem.GetWorldPosition(gridXform), Is.EqualTo(new Vector2(10, 10)));
|
||||
Assert.That(mapGrid.GetTileRef(new Vector2i(0, 0)).Tile, Is.EqualTo(new Tile(1, (TileRenderFlag) 1, 255)));
|
||||
Assert.That(mapSystem.GetTileRef(gridUid, mapGrid, new Vector2i(0, 0)).Tile, Is.EqualTo(new Tile(1, (TileRenderFlag) 1, 255)));
|
||||
});
|
||||
}
|
||||
{
|
||||
@@ -88,7 +87,7 @@ namespace Content.IntegrationTests.Tests
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(xformSystem.GetWorldPosition(gridXform), Is.EqualTo(new Vector2(-8, -8)));
|
||||
Assert.That(mapGrid.GetTileRef(new Vector2i(0, 0)).Tile, Is.EqualTo(new Tile(2, (TileRenderFlag) 1, 254)));
|
||||
Assert.That(mapSystem.GetTileRef(gridUid, mapGrid, new Vector2i(0, 0)).Tile, Is.EqualTo(new Tile(2, (TileRenderFlag) 1, 254)));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -25,17 +25,18 @@ namespace Content.IntegrationTests.Tests
|
||||
var server = pair.Server;
|
||||
var entManager = server.ResolveDependency<IEntityManager>();
|
||||
var mapLoader = entManager.System<MapLoaderSystem>();
|
||||
var mapSystem = entManager.System<SharedMapSystem>();
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var cfg = server.ResolveDependency<IConfigurationManager>();
|
||||
Assert.That(cfg.GetCVar(CCVars.GridFill), Is.False);
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
var mapId0 = mapManager.CreateMap();
|
||||
mapSystem.CreateMap(out var mapId0);
|
||||
// TODO: Properly find the "main" station grid.
|
||||
var grid0 = mapManager.CreateGrid(mapId0);
|
||||
var grid0 = mapManager.CreateGridEntity(mapId0);
|
||||
mapLoader.Save(grid0.Owner, "save load save 1.yml");
|
||||
var mapId1 = mapManager.CreateMap();
|
||||
mapSystem.CreateMap(out var mapId1);
|
||||
EntityUid grid1 = default!;
|
||||
#pragma warning disable NUnit2045
|
||||
Assert.That(mapLoader.TryLoad(mapId1, "save load save 1.yml", out var roots, new MapLoadOptions() { LoadMap = false }), $"Failed to load test map {TestMap}");
|
||||
@@ -101,6 +102,7 @@ namespace Content.IntegrationTests.Tests
|
||||
var server = pair.Server;
|
||||
var mapLoader = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<MapLoaderSystem>();
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var mapSystem = server.System<SharedMapSystem>();
|
||||
|
||||
MapId mapId = default;
|
||||
var cfg = server.ResolveDependency<IConfigurationManager>();
|
||||
@@ -109,8 +111,7 @@ namespace Content.IntegrationTests.Tests
|
||||
// Load bagel.yml as uninitialized map, and save it to ensure it's up to date.
|
||||
server.Post(() =>
|
||||
{
|
||||
mapId = mapManager.CreateMap();
|
||||
mapManager.AddUninitializedMap(mapId);
|
||||
mapSystem.CreateMap(out mapId, runMapInit: false);
|
||||
mapManager.SetMapPaused(mapId, true);
|
||||
Assert.That(mapLoader.TryLoad(mapId, TestMap, out _), $"Failed to load test map {TestMap}");
|
||||
mapLoader.SaveMap(mapId, "load save ticks save 1.yml");
|
||||
@@ -182,7 +183,8 @@ namespace Content.IntegrationTests.Tests
|
||||
await using var pair = await PoolManager.GetServerClient();
|
||||
var server = pair.Server;
|
||||
|
||||
var mapLoader = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<MapLoaderSystem>();
|
||||
var mapLoader = server.System<MapLoaderSystem>();
|
||||
var mapSystem = server.System<SharedMapSystem>();
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var userData = server.ResolveDependency<IResourceManager>().UserData;
|
||||
var cfg = server.ResolveDependency<IConfigurationManager>();
|
||||
@@ -197,8 +199,7 @@ namespace Content.IntegrationTests.Tests
|
||||
// Load & save the first map
|
||||
server.Post(() =>
|
||||
{
|
||||
mapId = mapManager.CreateMap();
|
||||
mapManager.AddUninitializedMap(mapId);
|
||||
mapSystem.CreateMap(out mapId, runMapInit: false);
|
||||
mapManager.SetMapPaused(mapId, true);
|
||||
Assert.That(mapLoader.TryLoad(mapId, TestMap, out _), $"Failed to load test map {TestMap}");
|
||||
mapLoader.SaveMap(mapId, fileA);
|
||||
@@ -217,8 +218,7 @@ namespace Content.IntegrationTests.Tests
|
||||
server.Post(() =>
|
||||
{
|
||||
mapManager.DeleteMap(mapId);
|
||||
mapManager.CreateMap(mapId);
|
||||
mapManager.AddUninitializedMap(mapId);
|
||||
mapSystem.CreateMap(out mapId, runMapInit: false);
|
||||
mapManager.SetMapPaused(mapId, true);
|
||||
Assert.That(mapLoader.TryLoad(mapId, TestMap, out _), $"Failed to load test map {TestMap}");
|
||||
mapLoader.SaveMap(mapId, fileB);
|
||||
|
||||
@@ -24,7 +24,7 @@ public sealed partial class SerializationTest
|
||||
|
||||
Enum value = TestEnum.Bb;
|
||||
|
||||
var node = seriMan.WriteValue(value, notNullableOverride:true);
|
||||
var node = seriMan.WriteValue(value, notNullableOverride: true);
|
||||
var valueNode = node as ValueDataNode;
|
||||
Assert.That(valueNode, Is.Not.Null);
|
||||
|
||||
@@ -34,22 +34,22 @@ public sealed partial class SerializationTest
|
||||
var errors = seriMan.ValidateNode<Enum>(valueNode).GetErrors();
|
||||
Assert.That(errors.Any(), Is.False);
|
||||
|
||||
var deserialized = seriMan.Read<Enum>(node, notNullableOverride:true);
|
||||
var deserialized = seriMan.Read<Enum>(node, notNullableOverride: true);
|
||||
Assert.That(deserialized, Is.EqualTo(value));
|
||||
|
||||
// Repeat test with enums in a data definitions.
|
||||
var data = new TestData
|
||||
{
|
||||
Value = TestEnum.Cc,
|
||||
Sequence = new() {TestEnum.Dd, TestEnum.Aa}
|
||||
Sequence = [TestEnum.Dd, TestEnum.Aa]
|
||||
};
|
||||
|
||||
node = seriMan.WriteValue(data, notNullableOverride:true);
|
||||
node = seriMan.WriteValue(data, notNullableOverride: true);
|
||||
|
||||
errors = seriMan.ValidateNode<TestData>(node).GetErrors();
|
||||
Assert.That(errors.Any(), Is.False);
|
||||
|
||||
var deserializedData = seriMan.Read<TestData>(node, notNullableOverride:false);
|
||||
var deserializedData = seriMan.Read<TestData>(node, notNullableOverride: false);
|
||||
|
||||
Assert.That(deserializedData.Value, Is.EqualTo(data.Value));
|
||||
Assert.That(deserializedData.Sequence.Count, Is.EqualTo(data.Sequence.Count));
|
||||
@@ -60,7 +60,7 @@ public sealed partial class SerializationTest
|
||||
Enum genericValue = TestEnum.Bb;
|
||||
TestEnum typedValue = TestEnum.Bb;
|
||||
|
||||
var genericNode = seriMan.WriteValue(genericValue, notNullableOverride:true);
|
||||
var genericNode = seriMan.WriteValue(genericValue, notNullableOverride: true);
|
||||
var typedNode = seriMan.WriteValue(typedValue);
|
||||
|
||||
Assert.That(seriMan.ValidateNode<Enum>(genericNode).GetErrors().Any(), Is.False);
|
||||
@@ -76,7 +76,7 @@ public sealed partial class SerializationTest
|
||||
[DataDefinition]
|
||||
private sealed partial class TestData
|
||||
{
|
||||
[DataField("value")] public Enum Value = default!;
|
||||
[DataField("sequence")] public List<Enum> Sequence = default!;
|
||||
[DataField] public Enum Value = default!;
|
||||
[DataField] public List<Enum> Sequence = default!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ using System.Numerics;
|
||||
using Content.Server.Shuttles.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
@@ -23,33 +22,33 @@ namespace Content.IntegrationTests.Tests
|
||||
var entManager = server.ResolveDependency<IEntityManager>();
|
||||
var physicsSystem = entManager.System<SharedPhysicsSystem>();
|
||||
|
||||
EntityUid gridEnt = default;
|
||||
PhysicsComponent gridPhys = null;
|
||||
|
||||
var map = await pair.CreateTestMap();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var mapId = mapMan.CreateMap();
|
||||
var grid = mapMan.CreateGridEntity(mapId);
|
||||
gridEnt = grid.Owner;
|
||||
var mapId = map.MapId;
|
||||
var grid = map.Grid;
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(entManager.HasComponent<ShuttleComponent>(gridEnt));
|
||||
Assert.That(entManager.TryGetComponent(gridEnt, out gridPhys));
|
||||
Assert.That(entManager.HasComponent<ShuttleComponent>(grid));
|
||||
Assert.That(entManager.TryGetComponent(grid, out gridPhys));
|
||||
});
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(gridPhys.BodyType, Is.EqualTo(BodyType.Dynamic));
|
||||
Assert.That(entManager.GetComponent<TransformComponent>(gridEnt).LocalPosition, Is.EqualTo(Vector2.Zero));
|
||||
Assert.That(entManager.GetComponent<TransformComponent>(grid).LocalPosition, Is.EqualTo(Vector2.Zero));
|
||||
});
|
||||
physicsSystem.ApplyLinearImpulse(gridEnt, Vector2.One, body: gridPhys);
|
||||
physicsSystem.ApplyLinearImpulse(grid, Vector2.One, body: gridPhys);
|
||||
});
|
||||
|
||||
await server.WaitRunTicks(1);
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
Assert.That(entManager.GetComponent<TransformComponent>(gridEnt).LocalPosition, Is.Not.EqualTo(Vector2.Zero));
|
||||
Assert.That(entManager.GetComponent<TransformComponent>(map.Grid).LocalPosition, Is.Not.EqualTo(Vector2.Zero));
|
||||
});
|
||||
await pair.CleanReturnAsync();
|
||||
}
|
||||
|
||||
@@ -19,12 +19,12 @@ namespace Content.IntegrationTests.Tests.Sprite;
|
||||
/// - Shouldn't have an item component
|
||||
/// - Is missing the required sprite information.
|
||||
/// If none of the abveo are true, it might need to be added to the list of ignored components, see
|
||||
/// <see cref="_ignored"/>
|
||||
/// <see cref="Ignored"/>
|
||||
/// </remarks>
|
||||
[TestFixture]
|
||||
public sealed class PrototypeSaveTest
|
||||
{
|
||||
private static HashSet<string> _ignored = new()
|
||||
private static readonly HashSet<string> Ignored = new()
|
||||
{
|
||||
// The only prototypes that should get ignored are those that REQUIRE setup to get a sprite. At that point it is
|
||||
// the responsibility of the spawner to ensure that a valid sprite is set.
|
||||
@@ -34,13 +34,13 @@ public sealed class PrototypeSaveTest
|
||||
[Test]
|
||||
public async Task AllItemsHaveSpritesTest()
|
||||
{
|
||||
var settings = new PoolSettings() {Connected = true}; // client needs to be in-game
|
||||
var settings = new PoolSettings() { Connected = true }; // client needs to be in-game
|
||||
await using var pair = await PoolManager.GetServerClient(settings);
|
||||
List<EntityPrototype> badPrototypes = new();
|
||||
List<EntityPrototype> badPrototypes = [];
|
||||
|
||||
await pair.Client.WaitPost(() =>
|
||||
{
|
||||
foreach (var proto in pair.GetPrototypesWithComponent<ItemComponent>(_ignored))
|
||||
foreach (var proto in pair.GetPrototypesWithComponent<ItemComponent>(Ignored))
|
||||
{
|
||||
var dummy = pair.Client.EntMan.Spawn(proto.ID);
|
||||
pair.Client.EntMan.RunMapInit(dummy, pair.Client.MetaData(dummy));
|
||||
|
||||
@@ -36,16 +36,18 @@ public abstract class ToolshedTest : IInvocationContext
|
||||
await TearDown();
|
||||
}
|
||||
|
||||
protected virtual async Task TearDown()
|
||||
protected virtual Task TearDown()
|
||||
{
|
||||
Assert.That(_expectedErrors, Is.Empty);
|
||||
ClearErrors();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public virtual async Task Setup()
|
||||
{
|
||||
Pair = await PoolManager.GetServerClient(new PoolSettings {Connected = Connected});
|
||||
Pair = await PoolManager.GetServerClient(new PoolSettings { Connected = Connected });
|
||||
Server = Pair.Server;
|
||||
|
||||
if (Connected)
|
||||
@@ -142,7 +144,7 @@ public abstract class ToolshedTest : IInvocationContext
|
||||
);
|
||||
}
|
||||
|
||||
done:
|
||||
done:
|
||||
_errors.Add(err);
|
||||
}
|
||||
|
||||
|
||||
@@ -111,6 +111,7 @@ namespace Content.IntegrationTests.Tests
|
||||
await server.WaitIdleAsync();
|
||||
|
||||
var prototypeManager = server.ResolveDependency<IPrototypeManager>();
|
||||
var compFact = server.ResolveDependency<IComponentFactory>();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
@@ -133,7 +134,7 @@ namespace Content.IntegrationTests.Tests
|
||||
// Collect all the prototypes with StorageFills referencing those entities.
|
||||
foreach (var proto in prototypeManager.EnumeratePrototypes<EntityPrototype>())
|
||||
{
|
||||
if (!proto.TryGetComponent<StorageFillComponent>(out var storage))
|
||||
if (!proto.TryGetComponent<StorageFillComponent>(out var storage, compFact))
|
||||
continue;
|
||||
|
||||
List<string> restockStore = new();
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
using System.Text.Json;
|
||||
using Content.Server.Administration.Managers;
|
||||
using Robust.Server.Player;
|
||||
|
||||
namespace Content.Server.Administration.Logs.Converters;
|
||||
|
||||
[AdminLogConverter]
|
||||
public sealed class EntityStringRepresentationConverter : AdminLogConverter<EntityStringRepresentation>
|
||||
{
|
||||
[Dependency] private readonly IAdminManager _adminManager = default!;
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, EntityStringRepresentation value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStartObject();
|
||||
@@ -19,6 +23,21 @@ public sealed class EntityStringRepresentationConverter : AdminLogConverter<Enti
|
||||
if (value.Session != null)
|
||||
{
|
||||
writer.WriteString("player", value.Session.UserId.UserId);
|
||||
|
||||
if (_adminManager.IsAdmin(value.Uid))
|
||||
{
|
||||
writer.WriteBoolean("admin", true);
|
||||
}
|
||||
}
|
||||
|
||||
if (value.Prototype != null)
|
||||
{
|
||||
writer.WriteString("prototype", value.Prototype);
|
||||
}
|
||||
|
||||
if (value.Deleted)
|
||||
{
|
||||
writer.WriteBoolean("deleted", true);
|
||||
}
|
||||
|
||||
writer.WriteEndObject();
|
||||
|
||||
@@ -270,6 +270,9 @@ public sealed class AmeControllerSystem : EntitySystem
|
||||
var humanReadableState = controller.Injecting ? "Inject" : "Not inject";
|
||||
_adminLogger.Add(LogType.Action, LogImpact.Extreme, $"{EntityManager.ToPrettyString(user.Value):player} has set the AME to inject {controller.InjectionAmount} while set to {humanReadableState}");
|
||||
|
||||
/* This needs to be information which an admin is very likely to want to be informed about in order to be an admin alert or have a sound notification.
|
||||
At the time of editing, players regularly "overclock" the AME and those cases require no admin attention.
|
||||
|
||||
// Admin alert
|
||||
var safeLimit = 0;
|
||||
if (TryGetAMENodeGroup(uid, out var group))
|
||||
@@ -285,6 +288,7 @@ public sealed class AmeControllerSystem : EntitySystem
|
||||
controller.EffectCooldown = _gameTiming.CurTime + controller.CooldownDuration;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public void AdjustInjectionAmount(EntityUid uid, int delta, int min = 0, int max = int.MaxValue, EntityUid? user = null, AmeControllerComponent? controller = null)
|
||||
|
||||
@@ -5,14 +5,22 @@ namespace Content.Server.Atmos.Piping.Other.Components
|
||||
[RegisterComponent]
|
||||
public sealed partial class GasMinerComponent : Component
|
||||
{
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
public bool Broken { get; set; } = false;
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public bool Idle { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// If the number of moles in the external environment exceeds this number, no gas will be mined.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("maxExternalAmount")]
|
||||
public float MaxExternalAmount { get; set; } = float.PositiveInfinity;
|
||||
|
||||
/// <summary>
|
||||
/// If the pressure (in kPA) of the external environment exceeds this number, no gas will be mined.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("maxExternalPressure")]
|
||||
public float MaxExternalPressure { get; set; } = Atmospherics.GasMinerDefaultMaxExternalPressure;
|
||||
|
||||
@@ -25,10 +25,17 @@ namespace Content.Server.Atmos.Piping.Other.EntitySystems
|
||||
{
|
||||
var miner = ent.Comp;
|
||||
|
||||
if (!GetValidEnvironment(ent, out var environment))
|
||||
{
|
||||
miner.Idle = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// SpawnAmount is declared in mol/s so to get the amount of gas we hope to mine, we have to multiply this by
|
||||
// how long we have been waiting to spawn it and further cap the number according to the miner's state.
|
||||
var toSpawn = CapSpawnAmount(ent, miner.SpawnAmount * args.dt, out var environment);
|
||||
if (toSpawn <= 0f || environment == null || !miner.Enabled || !miner.SpawnGas.HasValue)
|
||||
var toSpawn = CapSpawnAmount(ent, miner.SpawnAmount * args.dt, environment);
|
||||
miner.Idle = toSpawn == 0;
|
||||
if (miner.Idle || !miner.Enabled || !miner.SpawnGas.HasValue)
|
||||
return;
|
||||
|
||||
// Time to mine some gas.
|
||||
@@ -39,27 +46,26 @@ namespace Content.Server.Atmos.Piping.Other.EntitySystems
|
||||
_atmosphereSystem.Merge(environment, merger);
|
||||
}
|
||||
|
||||
private float CapSpawnAmount(Entity<GasMinerComponent> ent, float toSpawnTarget, [NotNullWhen(true)] out GasMixture? environment)
|
||||
private bool GetValidEnvironment(Entity<GasMinerComponent> ent, [NotNullWhen(true)] out GasMixture? environment)
|
||||
{
|
||||
var (uid, miner) = ent;
|
||||
var transform = Transform(uid);
|
||||
environment = _atmosphereSystem.GetContainingMixture((uid, transform), true, true);
|
||||
|
||||
var position = _transformSystem.GetGridOrMapTilePosition(uid, transform);
|
||||
|
||||
// Space.
|
||||
// Treat space as an invalid environment
|
||||
if (_atmosphereSystem.IsTileSpace(transform.GridUid, transform.MapUid, position))
|
||||
{
|
||||
miner.Broken = true;
|
||||
return 0f;
|
||||
environment = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Air-blocked location.
|
||||
if (environment == null)
|
||||
{
|
||||
miner.Broken = true;
|
||||
return 0f;
|
||||
}
|
||||
environment = _atmosphereSystem.GetContainingMixture((uid, transform), true, true);
|
||||
return environment != null;
|
||||
}
|
||||
|
||||
private float CapSpawnAmount(Entity<GasMinerComponent> ent, float toSpawnTarget, GasMixture environment)
|
||||
{
|
||||
var (uid, miner) = ent;
|
||||
|
||||
// How many moles could we theoretically spawn. Cap by pressure and amount.
|
||||
var allowableMoles = Math.Min(
|
||||
@@ -69,11 +75,9 @@ namespace Content.Server.Atmos.Piping.Other.EntitySystems
|
||||
var toSpawnReal = Math.Clamp(allowableMoles, 0f, toSpawnTarget);
|
||||
|
||||
if (toSpawnReal < Atmospherics.GasMinMoles) {
|
||||
miner.Broken = true;
|
||||
return 0f;
|
||||
}
|
||||
|
||||
miner.Broken = false;
|
||||
return toSpawnReal;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
using System.Linq;
|
||||
using Content.Shared.BarSign;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.BarSign.Systems
|
||||
{
|
||||
public sealed class BarSignSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<BarSignComponent, MapInitEvent>(OnMapInit);
|
||||
}
|
||||
|
||||
private void OnMapInit(EntityUid uid, BarSignComponent component, MapInitEvent args)
|
||||
{
|
||||
if (component.Current != null)
|
||||
return;
|
||||
|
||||
var prototypes = _prototypeManager
|
||||
.EnumeratePrototypes<BarSignPrototype>()
|
||||
.Where(p => !p.Hidden)
|
||||
.ToList();
|
||||
|
||||
var newPrototype = _random.Pick(prototypes);
|
||||
|
||||
var meta = Comp<MetaDataComponent>(uid);
|
||||
var name = newPrototype.Name != string.Empty ? newPrototype.Name : "barsign-component-name";
|
||||
_metaData.SetEntityName(uid, Loc.GetString(name), meta);
|
||||
_metaData.SetEntityDescription(uid, Loc.GetString(newPrototype.Description), meta);
|
||||
|
||||
component.Current = newPrototype.ID;
|
||||
Dirty(uid, component);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,10 +30,18 @@ public sealed class AntagLoadProfileRuleSystem : GameRuleSystem<AntagLoadProfile
|
||||
var profile = args.Session != null
|
||||
? _prefs.GetPreferences(args.Session.UserId).SelectedCharacter as HumanoidCharacterProfile
|
||||
: HumanoidCharacterProfile.RandomWithSpecies();
|
||||
if (profile?.Species is not {} speciesId || !_proto.TryIndex<SpeciesPrototype>(speciesId, out var species))
|
||||
|
||||
SpeciesPrototype? species;
|
||||
if (ent.Comp.SpeciesOverride != null)
|
||||
{
|
||||
species = _proto.Index(ent.Comp.SpeciesOverride.Value);
|
||||
}
|
||||
else if (profile?.Species is not { } speciesId || !_proto.TryIndex(speciesId, out species))
|
||||
{
|
||||
species = _proto.Index<SpeciesPrototype>(SharedHumanoidAppearanceSystem.DefaultSpecies);
|
||||
}
|
||||
|
||||
args.Entity = Spawn(species.Prototype);
|
||||
_humanoid.LoadProfile(args.Entity.Value, profile);
|
||||
_humanoid.LoadProfile(args.Entity.Value, profile?.WithSpecies(species.ID));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.GameTicking.Rules.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Makes this rules antags spawn a humanoid, either from the player's profile or a random one.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class AntagLoadProfileRuleComponent : Component;
|
||||
public sealed partial class AntagLoadProfileRuleComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// If specified, the profile loaded will be made into this species.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<SpeciesPrototype>? SpeciesOverride;
|
||||
}
|
||||
|
||||
@@ -57,13 +57,12 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
SubscribeLocalEvent<NukeOperativeComponent, MobStateChangedEvent>(OnMobStateChanged);
|
||||
SubscribeLocalEvent<NukeOperativeComponent, EntityZombifiedEvent>(OnOperativeZombified);
|
||||
|
||||
SubscribeLocalEvent<NukeOpsShuttleComponent, MapInitEvent>(OnMapInit);
|
||||
|
||||
SubscribeLocalEvent<ConsoleFTLAttemptEvent>(OnShuttleFTLAttempt);
|
||||
SubscribeLocalEvent<WarDeclaredEvent>(OnWarDeclared);
|
||||
SubscribeLocalEvent<CommunicationConsoleCallShuttleAttemptEvent>(OnShuttleCallAttempt);
|
||||
|
||||
SubscribeLocalEvent<NukeopsRuleComponent, AfterAntagEntitySelectedEvent>(OnAfterAntagEntSelected);
|
||||
SubscribeLocalEvent<NukeopsRuleComponent, RuleLoadedGridsEvent>(OnRuleLoadedGrids);
|
||||
}
|
||||
|
||||
protected override void Started(EntityUid uid, NukeopsRuleComponent component, GameRuleComponent gameRule,
|
||||
@@ -256,17 +255,18 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
RemCompDeferred(uid, component);
|
||||
}
|
||||
|
||||
private void OnMapInit(Entity<NukeOpsShuttleComponent> ent, ref MapInitEvent args)
|
||||
private void OnRuleLoadedGrids(Entity<NukeopsRuleComponent> ent, ref RuleLoadedGridsEvent args)
|
||||
{
|
||||
var map = Transform(ent).MapID;
|
||||
|
||||
var rules = EntityQueryEnumerator<NukeopsRuleComponent, RuleGridsComponent>();
|
||||
while (rules.MoveNext(out var uid, out _, out var grids))
|
||||
// Check each nukie shuttle
|
||||
var query = EntityQueryEnumerator<NukeOpsShuttleComponent>();
|
||||
while (query.MoveNext(out var uid, out var shuttle))
|
||||
{
|
||||
if (map != grids.Map)
|
||||
continue;
|
||||
ent.Comp.AssociatedRule = uid;
|
||||
break;
|
||||
// Check if the shuttle's mapID is the one that just got loaded for this rule
|
||||
if (Transform(uid).MapID == args.Map)
|
||||
{
|
||||
shuttle.AssociatedRule = ent;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,7 +376,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
if (Transform(uid).MapID != Transform(outpost).MapID) // Will receive bonus TC only on their start outpost
|
||||
continue;
|
||||
|
||||
_store.TryAddCurrency(new () { { TelecrystalCurrencyPrototype, nukieRule.Comp.WarTcAmountPerNukie } }, uid, component);
|
||||
_store.TryAddCurrency(new() { { TelecrystalCurrencyPrototype, nukieRule.Comp.WarTcAmountPerNukie } }, uid, component);
|
||||
|
||||
var msg = Loc.GetString("store-currency-war-boost-given", ("target", uid));
|
||||
_popupSystem.PopupEntity(msg, uid);
|
||||
|
||||
@@ -7,7 +7,7 @@ using Robust.Shared.Console;
|
||||
namespace Content.Server.Ghost
|
||||
{
|
||||
[AnyCommand]
|
||||
public sealed class Ghost : IConsoleCommand
|
||||
public sealed class GhostCommand : IConsoleCommand
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entities = default!;
|
||||
|
||||
7
Content.Server/IgnitionSource/IgnitionEvent.cs
Normal file
7
Content.Server/IgnitionSource/IgnitionEvent.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Content.Server.IgnitionSource;
|
||||
|
||||
/// <summary>
|
||||
/// Raised in order to toggle the ignitionSourceComponent on an entity on or off
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public readonly record struct IgnitionEvent(bool Ignite = false);
|
||||
@@ -19,18 +19,25 @@ public sealed class IgnitionSourceSystem : EntitySystem
|
||||
|
||||
SubscribeLocalEvent<IgnitionSourceComponent, IsHotEvent>(OnIsHot);
|
||||
SubscribeLocalEvent<ItemToggleHotComponent, ItemToggledEvent>(OnItemToggle);
|
||||
SubscribeLocalEvent<IgnitionSourceComponent, IgnitionEvent>(OnIgnitionEvent);
|
||||
}
|
||||
|
||||
private void OnIsHot(Entity<IgnitionSourceComponent> ent, ref IsHotEvent args)
|
||||
{
|
||||
SetIgnited((ent.Owner, ent.Comp), args.IsHot);
|
||||
args.IsHot = ent.Comp.Ignited;
|
||||
}
|
||||
|
||||
private void OnItemToggle(Entity<ItemToggleHotComponent> ent, ref ItemToggledEvent args)
|
||||
{
|
||||
if (TryComp<IgnitionSourceComponent>(ent, out var comp))
|
||||
SetIgnited((ent.Owner, comp), args.Activated);
|
||||
}
|
||||
|
||||
private void OnIgnitionEvent(Entity<IgnitionSourceComponent> ent, ref IgnitionEvent args)
|
||||
{
|
||||
SetIgnited((ent.Owner, ent.Comp), args.Ignite);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simply sets the ignited field to the ignited param.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Server.IgnitionSource;
|
||||
using Content.Server.Light.Components;
|
||||
using Content.Shared.Clothing.Components;
|
||||
using Content.Shared.Clothing.EntitySystems;
|
||||
@@ -99,8 +100,8 @@ namespace Content.Server.Light.EntitySystems
|
||||
_item.SetHeldPrefix(ent, "lit", component: item);
|
||||
}
|
||||
|
||||
var isHotEvent = new IsHotEvent() {IsHot = true};
|
||||
RaiseLocalEvent(ent, isHotEvent);
|
||||
var ignite = new IgnitionEvent(true);
|
||||
RaiseLocalEvent(ent, ref ignite);
|
||||
|
||||
component.CurrentState = ExpendableLightState.Lit;
|
||||
component.StateExpiryTime = component.GlowDuration;
|
||||
@@ -134,8 +135,8 @@ namespace Content.Server.Light.EntitySystems
|
||||
|
||||
case ExpendableLightState.Dead:
|
||||
_appearance.SetData(ent, ExpendableLightVisuals.Behavior, string.Empty, appearance);
|
||||
var isHotEvent = new IsHotEvent() {IsHot = true};
|
||||
RaiseLocalEvent(ent, isHotEvent);
|
||||
var ignite = new IgnitionEvent(false);
|
||||
RaiseLocalEvent(ent, ref ignite);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
123
Content.Server/NPC/Pathfinding/PathfindingSystem.Breadth.cs
Normal file
123
Content.Server/NPC/Pathfinding/PathfindingSystem.Breadth.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
namespace Content.Server.NPC.Pathfinding;
|
||||
|
||||
public sealed partial class PathfindingSystem
|
||||
{
|
||||
/*
|
||||
* Handle BFS searches from Start->End. Doesn't consider NPC pathfinding.
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Pathfinding args for a 1-many path.
|
||||
/// </summary>
|
||||
public record struct BreadthPathArgs()
|
||||
{
|
||||
public Vector2i Start;
|
||||
public List<Vector2i> Ends;
|
||||
|
||||
public bool Diagonals = false;
|
||||
|
||||
public Func<Vector2i, float>? TileCost;
|
||||
|
||||
public int Limit = 10000;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a BFS path from start to any end. Can also supply an optional tile-cost for tiles.
|
||||
/// </summary>
|
||||
public SimplePathResult GetBreadthPath(BreadthPathArgs args)
|
||||
{
|
||||
var cameFrom = new Dictionary<Vector2i, Vector2i>();
|
||||
var costSoFar = new Dictionary<Vector2i, float>();
|
||||
var frontier = new PriorityQueue<Vector2i, float>();
|
||||
|
||||
costSoFar[args.Start] = 0f;
|
||||
frontier.Enqueue(args.Start, 0f);
|
||||
var count = 0;
|
||||
|
||||
while (frontier.TryDequeue(out var node, out _) && count < args.Limit)
|
||||
{
|
||||
count++;
|
||||
|
||||
if (args.Ends.Contains(node))
|
||||
{
|
||||
// Found target
|
||||
var path = ReconstructPath(node, cameFrom);
|
||||
|
||||
return new SimplePathResult()
|
||||
{
|
||||
CameFrom = cameFrom,
|
||||
Path = path,
|
||||
};
|
||||
}
|
||||
|
||||
var gCost = costSoFar[node];
|
||||
|
||||
if (args.Diagonals)
|
||||
{
|
||||
for (var x = -1; x <= 1; x++)
|
||||
{
|
||||
for (var y = -1; y <= 1; y++)
|
||||
{
|
||||
var neighbor = node + new Vector2i(x, y);
|
||||
var neighborCost = OctileDistance(node, neighbor) * args.TileCost?.Invoke(neighbor) ?? 1f;
|
||||
|
||||
if (neighborCost.Equals(0f))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// f = g + h
|
||||
// gScore is distance to the start node
|
||||
// hScore is distance to the end node
|
||||
var gScore = gCost + neighborCost;
|
||||
|
||||
// Slower to get here so just ignore it.
|
||||
if (costSoFar.TryGetValue(neighbor, out var nextValue) && gScore >= nextValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cameFrom[neighbor] = node;
|
||||
costSoFar[neighbor] = gScore;
|
||||
// pFactor is tie-breaker where the fscore is otherwise equal.
|
||||
// See http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html#breaking-ties
|
||||
// There's other ways to do it but future consideration
|
||||
// The closer the fScore is to the actual distance then the better the pathfinder will be
|
||||
// (i.e. somewhere between 1 and infinite)
|
||||
// Can use hierarchical pathfinder or whatever to improve the heuristic but this is fine for now.
|
||||
frontier.Enqueue(neighbor, gScore);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var x = -1; x <= 1; x++)
|
||||
{
|
||||
for (var y = -1; y <= 1; y++)
|
||||
{
|
||||
if (x != 0 && y != 0)
|
||||
continue;
|
||||
|
||||
var neighbor = node + new Vector2i(x, y);
|
||||
var neighborCost = ManhattanDistance(node, neighbor) * args.TileCost?.Invoke(neighbor) ?? 1f;
|
||||
|
||||
if (neighborCost.Equals(0f))
|
||||
continue;
|
||||
|
||||
var gScore = gCost + neighborCost;
|
||||
|
||||
if (costSoFar.TryGetValue(neighbor, out var nextValue) && gScore >= nextValue)
|
||||
continue;
|
||||
|
||||
cameFrom[neighbor] = node;
|
||||
costSoFar[neighbor] = gScore;
|
||||
|
||||
frontier.Enqueue(neighbor, gScore);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SimplePathResult.NoPath;
|
||||
}
|
||||
}
|
||||
74
Content.Server/NPC/Pathfinding/PathfindingSystem.Line.cs
Normal file
74
Content.Server/NPC/Pathfinding/PathfindingSystem.Line.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
namespace Content.Server.NPC.Pathfinding;
|
||||
|
||||
public sealed partial class PathfindingSystem
|
||||
{
|
||||
public void GridCast(Vector2i start, Vector2i end, Vector2iCallback callback)
|
||||
{
|
||||
// https://gist.github.com/Pyr3z/46884d67641094d6cf353358566db566
|
||||
// declare all locals at the top so it's obvious how big the footprint is
|
||||
int dx, dy, xinc, yinc, side, i, error;
|
||||
|
||||
// starting cell is always returned
|
||||
if (!callback(start))
|
||||
return;
|
||||
|
||||
xinc = (end.X < start.X) ? -1 : 1;
|
||||
yinc = (end.Y < start.Y) ? -1 : 1;
|
||||
dx = xinc * (end.X - start.X);
|
||||
dy = yinc * (end.Y - start.Y);
|
||||
var ax = start.X;
|
||||
var ay = start.Y;
|
||||
|
||||
if (dx == dy) // Handle perfect diagonals
|
||||
{
|
||||
// I include this "optimization" for more aesthetic reasons, actually.
|
||||
// While Bresenham's Line can handle perfect diagonals just fine, it adds
|
||||
// additional cells to the line that make it not a perfect diagonal
|
||||
// anymore. So, while this branch is ~twice as fast as the next branch,
|
||||
// the real reason it is here is for style.
|
||||
|
||||
// Also, there *is* the reason of performance. If used for cell-based
|
||||
// raycasts, for example, then perfect diagonals will check half as many
|
||||
// cells.
|
||||
|
||||
while (dx --> 0)
|
||||
{
|
||||
ax += xinc;
|
||||
ay += yinc;
|
||||
if (!callback(new Vector2i(ax, ay)))
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle all other lines
|
||||
|
||||
side = -1 * ((dx == 0 ? yinc : xinc) - 1);
|
||||
|
||||
i = dx + dy;
|
||||
error = dx - dy;
|
||||
|
||||
dx *= 2;
|
||||
dy *= 2;
|
||||
|
||||
while (i --> 0)
|
||||
{
|
||||
if (error > 0 || error == side)
|
||||
{
|
||||
ax += xinc;
|
||||
error -= dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
ay += yinc;
|
||||
error += dx;
|
||||
}
|
||||
|
||||
if (!callback(new Vector2i(ax, ay)))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public delegate bool Vector2iCallback(Vector2i index);
|
||||
}
|
||||
154
Content.Server/NPC/Pathfinding/PathfindingSystem.Simple.cs
Normal file
154
Content.Server/NPC/Pathfinding/PathfindingSystem.Simple.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
namespace Content.Server.NPC.Pathfinding;
|
||||
|
||||
public sealed partial class PathfindingSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// Pathfinding args for a 1-1 path.
|
||||
/// </summary>
|
||||
public record struct SimplePathArgs()
|
||||
{
|
||||
public Vector2i Start;
|
||||
public Vector2i End;
|
||||
|
||||
public bool Diagonals = false;
|
||||
|
||||
public int Limit = 10000;
|
||||
|
||||
/// <summary>
|
||||
/// Custom tile-costs if applicable.
|
||||
/// </summary>
|
||||
public Func<Vector2i, float>? TileCost;
|
||||
}
|
||||
|
||||
public record struct SimplePathResult
|
||||
{
|
||||
public static SimplePathResult NoPath = new();
|
||||
|
||||
public List<Vector2i> Path;
|
||||
public Dictionary<Vector2i, Vector2i> CameFrom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets simple A* path from start to end. Can also supply an optional tile-cost for tiles.
|
||||
/// </summary>
|
||||
public SimplePathResult GetPath(SimplePathArgs args)
|
||||
{
|
||||
var cameFrom = new Dictionary<Vector2i, Vector2i>();
|
||||
var costSoFar = new Dictionary<Vector2i, float>();
|
||||
var frontier = new PriorityQueue<Vector2i, float>();
|
||||
|
||||
costSoFar[args.Start] = 0f;
|
||||
frontier.Enqueue(args.Start, 0f);
|
||||
var count = 0;
|
||||
|
||||
while (frontier.TryDequeue(out var node, out _) && count < args.Limit)
|
||||
{
|
||||
count++;
|
||||
|
||||
if (node == args.End)
|
||||
{
|
||||
// Found target
|
||||
var path = ReconstructPath(args.End, cameFrom);
|
||||
|
||||
return new SimplePathResult()
|
||||
{
|
||||
CameFrom = cameFrom,
|
||||
Path = path,
|
||||
};
|
||||
}
|
||||
|
||||
var gCost = costSoFar[node];
|
||||
|
||||
if (args.Diagonals)
|
||||
{
|
||||
for (var x = -1; x <= 1; x++)
|
||||
{
|
||||
for (var y = -1; y <= 1; y++)
|
||||
{
|
||||
var neighbor = node + new Vector2i(x, y);
|
||||
var neighborCost = OctileDistance(node, neighbor) * args.TileCost?.Invoke(neighbor) ?? 1f;
|
||||
|
||||
if (neighborCost.Equals(0f))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// f = g + h
|
||||
// gScore is distance to the start node
|
||||
// hScore is distance to the end node
|
||||
var gScore = gCost + neighborCost;
|
||||
|
||||
// Slower to get here so just ignore it.
|
||||
if (costSoFar.TryGetValue(neighbor, out var nextValue) && gScore >= nextValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cameFrom[neighbor] = node;
|
||||
costSoFar[neighbor] = gScore;
|
||||
// pFactor is tie-breaker where the fscore is otherwise equal.
|
||||
// See http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html#breaking-ties
|
||||
// There's other ways to do it but future consideration
|
||||
// The closer the fScore is to the actual distance then the better the pathfinder will be
|
||||
// (i.e. somewhere between 1 and infinite)
|
||||
// Can use hierarchical pathfinder or whatever to improve the heuristic but this is fine for now.
|
||||
var hScore = OctileDistance(args.End, neighbor) * (1.0f + 1.0f / 1000.0f);
|
||||
var fScore = gScore + hScore;
|
||||
frontier.Enqueue(neighbor, fScore);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var x = -1; x <= 1; x++)
|
||||
{
|
||||
for (var y = -1; y <= 1; y++)
|
||||
{
|
||||
if (x != 0 && y != 0)
|
||||
continue;
|
||||
|
||||
var neighbor = node + new Vector2i(x, y);
|
||||
var neighborCost = ManhattanDistance(node, neighbor) * args.TileCost?.Invoke(neighbor) ?? 1f;
|
||||
|
||||
if (neighborCost.Equals(0f))
|
||||
continue;
|
||||
|
||||
var gScore = gCost + neighborCost;
|
||||
|
||||
if (costSoFar.TryGetValue(neighbor, out var nextValue) && gScore >= nextValue)
|
||||
continue;
|
||||
|
||||
cameFrom[neighbor] = node;
|
||||
costSoFar[neighbor] = gScore;
|
||||
|
||||
// Still use octile even for manhattan distance.
|
||||
var hScore = OctileDistance(args.End, neighbor) * 1.001f;
|
||||
var fScore = gScore + hScore;
|
||||
frontier.Enqueue(neighbor, fScore);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SimplePathResult.NoPath;
|
||||
}
|
||||
|
||||
private List<Vector2i> ReconstructPath(Vector2i end, Dictionary<Vector2i, Vector2i> cameFrom)
|
||||
{
|
||||
var path = new List<Vector2i>()
|
||||
{
|
||||
end,
|
||||
};
|
||||
var node = end;
|
||||
|
||||
while (cameFrom.TryGetValue(node, out var source))
|
||||
{
|
||||
path.Add(source);
|
||||
node = source;
|
||||
}
|
||||
|
||||
path.Reverse();
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
||||
180
Content.Server/NPC/Pathfinding/PathfindingSystem.Splines.cs
Normal file
180
Content.Server/NPC/Pathfinding/PathfindingSystem.Splines.cs
Normal file
@@ -0,0 +1,180 @@
|
||||
using Robust.Shared.Collections;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.NPC.Pathfinding;
|
||||
|
||||
public sealed partial class PathfindingSystem
|
||||
{
|
||||
public record struct SimplifyPathArgs
|
||||
{
|
||||
public Vector2i Start;
|
||||
public Vector2i End;
|
||||
public List<Vector2i> Path;
|
||||
}
|
||||
|
||||
public record struct SplinePathResult()
|
||||
{
|
||||
public static SplinePathResult NoPath = new();
|
||||
|
||||
public List<Vector2i> Points = new();
|
||||
|
||||
public List<Vector2i> Path = new();
|
||||
public Dictionary<Vector2i, Vector2i> CameFrom;
|
||||
}
|
||||
|
||||
public record struct SplinePathArgs(SimplePathArgs Args)
|
||||
{
|
||||
public SimplePathArgs Args = Args;
|
||||
|
||||
public float MaxRatio = 0.25f;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum distance between subdivisions.
|
||||
/// </summary>
|
||||
public int Distance = 20;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a spline path from start to end.
|
||||
/// </summary>
|
||||
public SplinePathResult GetSplinePath(SplinePathArgs args, Random random)
|
||||
{
|
||||
var start = args.Args.Start;
|
||||
var end = args.Args.End;
|
||||
|
||||
var path = new List<Vector2i>();
|
||||
|
||||
var pairs = new ValueList<(Vector2i Start, Vector2i End)> { (start, end) };
|
||||
var subdivided = true;
|
||||
|
||||
// Sub-divide recursively
|
||||
while (subdivided)
|
||||
{
|
||||
// Sometimes we might inadvertantly get 2 nodes too close together so better to just check each one as it comes up instead.
|
||||
var i = 0;
|
||||
subdivided = false;
|
||||
|
||||
while (i < pairs.Count)
|
||||
{
|
||||
var pointA = pairs[i].Start;
|
||||
var pointB = pairs[i].End;
|
||||
var vector = pointB - pointA;
|
||||
|
||||
var halfway = vector / 2f;
|
||||
|
||||
// Finding the point
|
||||
var adj = halfway.Length();
|
||||
|
||||
// Should we even subdivide.
|
||||
if (adj <= args.Distance)
|
||||
{
|
||||
// Just check the next entry no double skip.
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
subdivided = true;
|
||||
var opposite = args.MaxRatio * adj;
|
||||
var hypotenuse = MathF.Sqrt(MathF.Pow(adj, 2) + MathF.Pow(opposite, 2));
|
||||
|
||||
// Okay so essentially we have 2 points and no poly
|
||||
// We add 2 other points to form a diamond and want some point halfway between randomly offset.
|
||||
var angle = new Angle(MathF.Atan(opposite / adj));
|
||||
var pointAPerp = pointA + angle.RotateVec(halfway).Normalized() * hypotenuse;
|
||||
var pointBPerp = pointA + (-angle).RotateVec(halfway).Normalized() * hypotenuse;
|
||||
|
||||
var perpLine = pointBPerp - pointAPerp;
|
||||
var perpHalfway = perpLine.Length() / 2f;
|
||||
|
||||
var splinePoint = (pointAPerp + perpLine.Normalized() * random.NextFloat(-args.MaxRatio, args.MaxRatio) * perpHalfway).Floored();
|
||||
|
||||
// We essentially take (A, B) and turn it into (A, C) & (C, B)
|
||||
pairs[i] = (pointA, splinePoint);
|
||||
pairs.Insert(i + 1, (splinePoint, pointB));
|
||||
|
||||
i+= 2;
|
||||
}
|
||||
}
|
||||
|
||||
var spline = new ValueList<Vector2i>(pairs.Count - 1)
|
||||
{
|
||||
start
|
||||
};
|
||||
|
||||
foreach (var pair in pairs)
|
||||
{
|
||||
spline.Add(pair.End);
|
||||
}
|
||||
|
||||
// Now we need to pathfind between each node on the spline.
|
||||
|
||||
// TODO: Add rotation version or straight-line version for pathfinder config
|
||||
// Move the worm pathfinder to here I think.
|
||||
var cameFrom = new Dictionary<Vector2i, Vector2i>();
|
||||
|
||||
// TODO: Need to get rid of the branch bullshit.
|
||||
var points = new List<Vector2i>();
|
||||
|
||||
for (var i = 0; i < spline.Count - 1; i++)
|
||||
{
|
||||
var point = spline[i];
|
||||
var target = spline[i + 1];
|
||||
points.Add(point);
|
||||
var aStarArgs = args.Args with { Start = point, End = target };
|
||||
|
||||
var aStarResult = GetPath(aStarArgs);
|
||||
|
||||
if (aStarResult == SimplePathResult.NoPath)
|
||||
return SplinePathResult.NoPath;
|
||||
|
||||
path.AddRange(aStarResult.Path[0..]);
|
||||
|
||||
foreach (var a in aStarResult.CameFrom)
|
||||
{
|
||||
cameFrom[a.Key] = a.Value;
|
||||
}
|
||||
}
|
||||
|
||||
points.Add(spline[^1]);
|
||||
|
||||
var simple = SimplifyPath(new SimplifyPathArgs()
|
||||
{
|
||||
Start = args.Args.Start,
|
||||
End = args.Args.End,
|
||||
Path = path,
|
||||
});
|
||||
|
||||
return new SplinePathResult()
|
||||
{
|
||||
Path = simple,
|
||||
CameFrom = cameFrom,
|
||||
Points = points,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does a simpler pathfinder over the nodes to prune unnecessary branches.
|
||||
/// </summary>
|
||||
public List<Vector2i> SimplifyPath(SimplifyPathArgs args)
|
||||
{
|
||||
var nodes = new HashSet<Vector2i>(args.Path);
|
||||
|
||||
var result = GetBreadthPath(new BreadthPathArgs()
|
||||
{
|
||||
Start = args.Start,
|
||||
Ends = new List<Vector2i>()
|
||||
{
|
||||
args.End,
|
||||
},
|
||||
TileCost = node =>
|
||||
{
|
||||
if (!nodes.Contains(node))
|
||||
return 0f;
|
||||
|
||||
return 1f;
|
||||
}
|
||||
});
|
||||
|
||||
return result.Path;
|
||||
}
|
||||
}
|
||||
89
Content.Server/NPC/Pathfinding/PathfindingSystem.Widen.cs
Normal file
89
Content.Server/NPC/Pathfinding/PathfindingSystem.Widen.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System.Numerics;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.NPC.Pathfinding;
|
||||
|
||||
public sealed partial class PathfindingSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// Widens the path by the specified amount.
|
||||
/// </summary>
|
||||
public HashSet<Vector2i> GetWiden(WidenArgs args, Random random)
|
||||
{
|
||||
var tiles = new HashSet<Vector2i>(args.Path.Count * 2);
|
||||
var variance = (args.MaxWiden - args.MinWiden) / 2f + args.MinWiden;
|
||||
var counter = 0;
|
||||
|
||||
foreach (var tile in args.Path)
|
||||
{
|
||||
counter++;
|
||||
|
||||
if (counter != args.TileSkip)
|
||||
continue;
|
||||
|
||||
counter = 0;
|
||||
|
||||
var center = new Vector2(tile.X + 0.5f, tile.Y + 0.5f);
|
||||
|
||||
if (args.Square)
|
||||
{
|
||||
for (var x = -variance; x <= variance; x++)
|
||||
{
|
||||
for (var y = -variance; y <= variance; y++)
|
||||
{
|
||||
var neighbor = center + new Vector2(x, y);
|
||||
|
||||
tiles.Add(neighbor.Floored());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var x = -variance; x <= variance; x++)
|
||||
{
|
||||
for (var y = -variance; y <= variance; y++)
|
||||
{
|
||||
var offset = new Vector2(x, y);
|
||||
|
||||
if (offset.Length() > variance)
|
||||
continue;
|
||||
|
||||
var neighbor = center + offset;
|
||||
|
||||
tiles.Add(neighbor.Floored());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variance += random.NextFloat(-args.Variance * args.TileSkip, args.Variance * args.TileSkip);
|
||||
variance = Math.Clamp(variance, args.MinWiden, args.MaxWiden);
|
||||
}
|
||||
|
||||
return tiles;
|
||||
}
|
||||
|
||||
public record struct WidenArgs()
|
||||
{
|
||||
public bool Square = false;
|
||||
|
||||
/// <summary>
|
||||
/// How many tiles to skip between iterations., 1-in-n
|
||||
/// </summary>
|
||||
public int TileSkip = 3;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum amount to vary per tile.
|
||||
/// </summary>
|
||||
public float Variance = 0.25f;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum width.
|
||||
/// </summary>
|
||||
public float MinWiden = 2f;
|
||||
|
||||
|
||||
public float MaxWiden = 7f;
|
||||
|
||||
public List<Vector2i> Path;
|
||||
}
|
||||
}
|
||||
@@ -142,6 +142,13 @@ public sealed partial class NPCSteeringSystem
|
||||
|
||||
// Grab the target position, either the next path node or our end goal..
|
||||
var targetCoordinates = GetTargetCoordinates(steering);
|
||||
|
||||
if (!targetCoordinates.IsValid(EntityManager))
|
||||
{
|
||||
steering.Status = SteeringStatus.NoPath;
|
||||
return false;
|
||||
}
|
||||
|
||||
var needsPath = false;
|
||||
|
||||
// If the next node is invalid then get new ones
|
||||
@@ -243,6 +250,14 @@ public sealed partial class NPCSteeringSystem
|
||||
// Alright just adjust slightly and grab the next node so we don't stop moving for a tick.
|
||||
// TODO: If it's the last node just grab the target instead.
|
||||
targetCoordinates = GetTargetCoordinates(steering);
|
||||
|
||||
if (!targetCoordinates.IsValid(EntityManager))
|
||||
{
|
||||
SetDirection(mover, steering, Vector2.Zero);
|
||||
steering.Status = SteeringStatus.NoPath;
|
||||
return false;
|
||||
}
|
||||
|
||||
targetMap = targetCoordinates.ToMap(EntityManager, _transform);
|
||||
|
||||
// Can't make it again.
|
||||
|
||||
@@ -810,7 +810,7 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
||||
// At least for now unless we do lookups or smth, only work with anchoring.
|
||||
if (_xformQuery.TryGetComponent(ent, out var xform) && !xform.Anchored)
|
||||
{
|
||||
_transform.AnchorEntity(ent, xform, gridUid, grid, indices);
|
||||
_transform.AnchorEntity((ent, xform), (gridUid, grid), indices);
|
||||
}
|
||||
|
||||
loadedEntities.Add(ent, indices);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,138 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
using Content.Server.Parallax;
|
||||
using Content.Shared.Parallax.Biomes;
|
||||
using Content.Shared.Parallax.Biomes.Markers;
|
||||
using Content.Shared.Procedural;
|
||||
using Content.Shared.Procedural.PostGeneration;
|
||||
using Content.Shared.Random.Helpers;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.Procedural;
|
||||
|
||||
public sealed partial class DungeonJob
|
||||
{
|
||||
/*
|
||||
* Handles PostGen code for marker layers + biomes.
|
||||
*/
|
||||
|
||||
private async Task PostGen(BiomePostGen postGen, Dungeon dungeon, EntityUid gridUid, MapGridComponent grid, Random random)
|
||||
{
|
||||
if (_entManager.TryGetComponent(gridUid, out BiomeComponent? biomeComp))
|
||||
return;
|
||||
|
||||
biomeComp = _entManager.AddComponent<BiomeComponent>(gridUid);
|
||||
var biomeSystem = _entManager.System<BiomeSystem>();
|
||||
biomeSystem.SetTemplate(gridUid, biomeComp, _prototype.Index(postGen.BiomeTemplate));
|
||||
var seed = random.Next();
|
||||
var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
|
||||
|
||||
foreach (var node in dungeon.RoomTiles)
|
||||
{
|
||||
// Need to set per-tile to override data.
|
||||
if (biomeSystem.TryGetTile(node, biomeComp.Layers, seed, grid, out var tile))
|
||||
{
|
||||
_maps.SetTile(gridUid, grid, node, tile.Value);
|
||||
}
|
||||
|
||||
if (biomeSystem.TryGetDecals(node, biomeComp.Layers, seed, grid, out var decals))
|
||||
{
|
||||
foreach (var decal in decals)
|
||||
{
|
||||
_decals.TryAddDecal(decal.ID, new EntityCoordinates(gridUid, decal.Position), out _);
|
||||
}
|
||||
}
|
||||
|
||||
if (biomeSystem.TryGetEntity(node, biomeComp, grid, out var entityProto))
|
||||
{
|
||||
var ent = _entManager.SpawnEntity(entityProto, new EntityCoordinates(gridUid, node + grid.TileSizeHalfVector));
|
||||
var xform = xformQuery.Get(ent);
|
||||
|
||||
if (!xform.Comp.Anchored)
|
||||
{
|
||||
_transform.AnchorEntity(ent, xform);
|
||||
}
|
||||
|
||||
// TODO: Engine bug with SpawnAtPosition
|
||||
DebugTools.Assert(xform.Comp.Anchored);
|
||||
}
|
||||
|
||||
await SuspendIfOutOfTime();
|
||||
ValidateResume();
|
||||
}
|
||||
|
||||
biomeComp.Enabled = false;
|
||||
}
|
||||
|
||||
private async Task PostGen(BiomeMarkerLayerPostGen postGen, Dungeon dungeon, EntityUid gridUid, MapGridComponent grid, Random random)
|
||||
{
|
||||
if (!_entManager.TryGetComponent(gridUid, out BiomeComponent? biomeComp))
|
||||
return;
|
||||
|
||||
var biomeSystem = _entManager.System<BiomeSystem>();
|
||||
var weightedRandom = _prototype.Index(postGen.MarkerTemplate);
|
||||
var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
|
||||
var templates = new Dictionary<string, int>();
|
||||
|
||||
for (var i = 0; i < postGen.Count; i++)
|
||||
{
|
||||
var template = weightedRandom.Pick(random);
|
||||
var count = templates.GetOrNew(template);
|
||||
count++;
|
||||
templates[template] = count;
|
||||
}
|
||||
|
||||
foreach (var (template, count) in templates)
|
||||
{
|
||||
var markerTemplate = _prototype.Index<BiomeMarkerLayerPrototype>(template);
|
||||
|
||||
var bounds = new Box2i();
|
||||
|
||||
foreach (var tile in dungeon.RoomTiles)
|
||||
{
|
||||
bounds = bounds.UnionTile(tile);
|
||||
}
|
||||
|
||||
await SuspendIfOutOfTime();
|
||||
ValidateResume();
|
||||
|
||||
biomeSystem.GetMarkerNodes(gridUid, biomeComp, grid, markerTemplate, true, bounds, count,
|
||||
random, out var spawnSet, out var existing, false);
|
||||
|
||||
await SuspendIfOutOfTime();
|
||||
ValidateResume();
|
||||
|
||||
foreach (var ent in existing)
|
||||
{
|
||||
_entManager.DeleteEntity(ent);
|
||||
}
|
||||
|
||||
await SuspendIfOutOfTime();
|
||||
ValidateResume();
|
||||
|
||||
foreach (var (node, mask) in spawnSet)
|
||||
{
|
||||
string? proto;
|
||||
|
||||
if (mask != null && markerTemplate.EntityMask.TryGetValue(mask, out var maskedProto))
|
||||
{
|
||||
proto = maskedProto;
|
||||
}
|
||||
else
|
||||
{
|
||||
proto = markerTemplate.Prototype;
|
||||
}
|
||||
|
||||
var ent = _entManager.SpawnAtPosition(proto, new EntityCoordinates(gridUid, node + grid.TileSizeHalfVector));
|
||||
var xform = xformQuery.Get(ent);
|
||||
|
||||
if (!xform.Comp.Anchored)
|
||||
_transform.AnchorEntity(ent, xform);
|
||||
|
||||
await SuspendIfOutOfTime();
|
||||
ValidateResume();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Content.Server.Construction;
|
||||
using Robust.Shared.CPUJob.JobQueues;
|
||||
using Content.Server.Decals;
|
||||
using Content.Shared.Construction.EntitySystems;
|
||||
using Content.Shared.Maps;
|
||||
using Content.Shared.Procedural;
|
||||
using Content.Shared.Procedural.DungeonGenerators;
|
||||
using Content.Shared.Procedural.PostGeneration;
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Server.Physics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.Procedural;
|
||||
|
||||
public sealed partial class DungeonJob : Job<Dungeon>
|
||||
{
|
||||
private readonly IEntityManager _entManager;
|
||||
private readonly IMapManager _mapManager;
|
||||
private readonly IPrototypeManager _prototype;
|
||||
private readonly ITileDefinitionManager _tileDefManager;
|
||||
|
||||
private readonly AnchorableSystem _anchorable;
|
||||
private readonly DecalSystem _decals;
|
||||
private readonly DungeonSystem _dungeon;
|
||||
private readonly EntityLookupSystem _lookup;
|
||||
private readonly TagSystem _tag;
|
||||
private readonly TileSystem _tile;
|
||||
private readonly SharedMapSystem _maps;
|
||||
private readonly SharedTransformSystem _transform;
|
||||
|
||||
private readonly DungeonConfigPrototype _gen;
|
||||
private readonly int _seed;
|
||||
private readonly Vector2i _position;
|
||||
|
||||
private readonly MapGridComponent _grid;
|
||||
private readonly EntityUid _gridUid;
|
||||
|
||||
private readonly ISawmill _sawmill;
|
||||
|
||||
public DungeonJob(
|
||||
ISawmill sawmill,
|
||||
double maxTime,
|
||||
IEntityManager entManager,
|
||||
IMapManager mapManager,
|
||||
IPrototypeManager prototype,
|
||||
ITileDefinitionManager tileDefManager,
|
||||
AnchorableSystem anchorable,
|
||||
DecalSystem decals,
|
||||
DungeonSystem dungeon,
|
||||
EntityLookupSystem lookup,
|
||||
TagSystem tag,
|
||||
TileSystem tile,
|
||||
SharedTransformSystem transform,
|
||||
DungeonConfigPrototype gen,
|
||||
MapGridComponent grid,
|
||||
EntityUid gridUid,
|
||||
int seed,
|
||||
Vector2i position,
|
||||
CancellationToken cancellation = default) : base(maxTime, cancellation)
|
||||
{
|
||||
_sawmill = sawmill;
|
||||
_entManager = entManager;
|
||||
_mapManager = mapManager;
|
||||
_prototype = prototype;
|
||||
_tileDefManager = tileDefManager;
|
||||
|
||||
_anchorable = anchorable;
|
||||
_decals = decals;
|
||||
_dungeon = dungeon;
|
||||
_lookup = lookup;
|
||||
_tag = tag;
|
||||
_tile = tile;
|
||||
_maps = _entManager.System<SharedMapSystem>();
|
||||
_transform = transform;
|
||||
|
||||
_gen = gen;
|
||||
_grid = grid;
|
||||
_gridUid = gridUid;
|
||||
_seed = seed;
|
||||
_position = position;
|
||||
}
|
||||
|
||||
protected override async Task<Dungeon?> Process()
|
||||
{
|
||||
Dungeon dungeon;
|
||||
_sawmill.Info($"Generating dungeon {_gen.ID} with seed {_seed} on {_entManager.ToPrettyString(_gridUid)}");
|
||||
_grid.CanSplit = false;
|
||||
|
||||
switch (_gen.Generator)
|
||||
{
|
||||
case NoiseDunGen noise:
|
||||
dungeon = await GenerateNoiseDungeon(noise, _gridUid, _grid, _seed);
|
||||
break;
|
||||
case PrefabDunGen prefab:
|
||||
dungeon = await GeneratePrefabDungeon(prefab, _gridUid, _grid, _seed);
|
||||
DebugTools.Assert(dungeon.RoomExteriorTiles.Count > 0);
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
DebugTools.Assert(dungeon.RoomTiles.Count > 0);
|
||||
|
||||
// To make it slightly more deterministic treat this RNG as separate ig.
|
||||
var random = new Random(_seed);
|
||||
|
||||
foreach (var post in _gen.PostGeneration)
|
||||
{
|
||||
_sawmill.Debug($"Doing postgen {post.GetType()} for {_gen.ID} with seed {_seed}");
|
||||
|
||||
switch (post)
|
||||
{
|
||||
case AutoCablingPostGen cabling:
|
||||
await PostGen(cabling, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case BiomePostGen biome:
|
||||
await PostGen(biome, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case BoundaryWallPostGen boundary:
|
||||
await PostGen(boundary, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case CornerClutterPostGen clutter:
|
||||
await PostGen(clutter, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case CorridorClutterPostGen corClutter:
|
||||
await PostGen(corClutter, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case CorridorPostGen cordor:
|
||||
await PostGen(cordor, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case CorridorDecalSkirtingPostGen decks:
|
||||
await PostGen(decks, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case EntranceFlankPostGen flank:
|
||||
await PostGen(flank, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case JunctionPostGen junc:
|
||||
await PostGen(junc, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case MiddleConnectionPostGen dordor:
|
||||
await PostGen(dordor, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case DungeonEntrancePostGen entrance:
|
||||
await PostGen(entrance, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case ExternalWindowPostGen externalWindow:
|
||||
await PostGen(externalWindow, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case InternalWindowPostGen internalWindow:
|
||||
await PostGen(internalWindow, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case BiomeMarkerLayerPostGen markerPost:
|
||||
await PostGen(markerPost, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case RoomEntrancePostGen rEntrance:
|
||||
await PostGen(rEntrance, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case WallMountPostGen wall:
|
||||
await PostGen(wall, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
case WormCorridorPostGen worm:
|
||||
await PostGen(worm, dungeon, _gridUid, _grid, random);
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
await SuspendIfOutOfTime();
|
||||
|
||||
if (!ValidateResume())
|
||||
break;
|
||||
}
|
||||
|
||||
// Defer splitting so they don't get spammed and so we don't have to worry about tracking the grid along the way.
|
||||
_grid.CanSplit = true;
|
||||
_entManager.System<GridFixtureSystem>().CheckSplits(_gridUid);
|
||||
return dungeon;
|
||||
}
|
||||
|
||||
private bool ValidateResume()
|
||||
{
|
||||
if (_entManager.Deleted(_gridUid))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System.Threading.Tasks;
|
||||
using Content.Server.NPC.Pathfinding;
|
||||
using Content.Shared.Maps;
|
||||
using Content.Shared.Procedural;
|
||||
using Content.Shared.Procedural.DungeonGenerators;
|
||||
using Robust.Shared.Collections;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.Procedural.DungeonJob;
|
||||
|
||||
public sealed partial class DungeonJob
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="ExteriorDunGen"/>
|
||||
/// </summary>
|
||||
private async Task<List<Dungeon>> GenerateExteriorDungen(Vector2i position, ExteriorDunGen dungen, HashSet<Vector2i> reservedTiles, Random random)
|
||||
{
|
||||
DebugTools.Assert(_grid.ChunkCount > 0);
|
||||
|
||||
var aabb = new Box2i(_grid.LocalAABB.BottomLeft.Floored(), _grid.LocalAABB.TopRight.Floored());
|
||||
var angle = random.NextAngle();
|
||||
|
||||
var distance = Math.Max(aabb.Width / 2f + 1f, aabb.Height / 2f + 1f);
|
||||
|
||||
var startTile = new Vector2i(0, (int) distance).Rotate(angle);
|
||||
|
||||
Vector2i? dungeonSpawn = null;
|
||||
var pathfinder = _entManager.System<PathfindingSystem>();
|
||||
|
||||
// Gridcast
|
||||
pathfinder.GridCast(startTile, position, tile =>
|
||||
{
|
||||
if (!_maps.TryGetTileRef(_gridUid, _grid, tile, out var tileRef) ||
|
||||
tileRef.Tile.IsSpace(_tileDefManager))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
dungeonSpawn = tile;
|
||||
return false;
|
||||
});
|
||||
|
||||
if (dungeonSpawn == null)
|
||||
{
|
||||
return new List<Dungeon>()
|
||||
{
|
||||
Dungeon.Empty
|
||||
};
|
||||
}
|
||||
|
||||
var config = _prototype.Index(dungen.Proto);
|
||||
var nextSeed = random.Next();
|
||||
var dungeons = await GetDungeons(dungeonSpawn.Value, config, config.Data, config.Layers, reservedTiles, nextSeed, new Random(nextSeed));
|
||||
|
||||
return dungeons;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user