Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upstream sync #12

Merged
merged 36 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
81e4668
Revert "Make power grid check event force APCs off (#17935)" (#18731)
moonheart08 Aug 6, 2023
30de99e
Automatic changelog update
PJBot Aug 6, 2023
d571cde
Explicitly set float.Parse culture (#18778)
Morb0 Aug 6, 2023
782ef69
Make Shovel Item size 90 (#18779)
Vordenburg Aug 6, 2023
9af3c88
SandboxTest changes (#18595)
ElectroJr Aug 6, 2023
b26e60d
de-mixels the bleeding alert (#18787)
Flareguy Aug 6, 2023
56fa974
Automatic changelog update
PJBot Aug 6, 2023
91658a0
Update engine to v145.0.0 (#18794)
ElectroJr Aug 7, 2023
6a45d36
Fix mind test issues (#18793)
ElectroJr Aug 7, 2023
5c6013a
Make chemical analysis goggles cheaper to print (#18791)
EmoGarbage404 Aug 7, 2023
5cc5a8c
Validate that client prototypes are serializable (#18780)
ElectroJr Aug 7, 2023
f434975
Automatic changelog update
PJBot Aug 7, 2023
fff7fda
Cull remaining Sprite netsync (#18770)
Vordenburg Aug 7, 2023
afead24
Rename spacebucks to spesos (#18805)
mirrorcult Aug 7, 2023
6183640
Automatic changelog update
PJBot Aug 7, 2023
88b3417
Fix setmind command (#18799)
ElectroJr Aug 7, 2023
53db6bc
Examine throwable damage (#18580)
Slava0135 Aug 7, 2023
860ce0c
Automatic changelog update
PJBot Aug 7, 2023
c9ba039
bagel update (#18809)
Emisse Aug 7, 2023
7ee8763
marathon update (#18814)
Emisse Aug 7, 2023
a9e7f41
box update (#18816)
Emisse Aug 7, 2023
61b4ee0
omega update (#18817)
Emisse Aug 7, 2023
649295d
Call goat protective services (#18812)
metalgearsloth Aug 7, 2023
fd1c131
Automatic changelog update
PJBot Aug 7, 2023
3e64676
meat rotting hotfix (#18760)
deltanedas Aug 7, 2023
c3d2d48
lava brig (#18818)
Emisse Aug 7, 2023
1c47673
add destructible logs (#18788)
Chief-Engineer Aug 7, 2023
e203423
Emaggable protolathe (#18456)
ubis1 Aug 7, 2023
329d758
Automatic changelog update
PJBot Aug 7, 2023
51d7f18
Fix LoadPrototype admin button (#18802)
metalgearsloth Aug 7, 2023
a7b302b
Fix crusher altfire (#18826)
metalgearsloth Aug 7, 2023
bd172aa
Automatic changelog update
PJBot Aug 7, 2023
c4fb166
Particle Accelerator power changed admin chat warning (#18806)
ShadowCommander Aug 7, 2023
924a687
New moth markings for customization (#18768)
MilenVolf Aug 7, 2023
07f6886
Automatic changelog update
PJBot Aug 7, 2023
0b4242e
Merge remote-tracking branch 'upstream/master' into upstream-sync
temporaldarkness Aug 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,23 @@ public AdminbusTab()
_decalPlacerController = UserInterfaceManager.GetUIController<DecalPlacerUIController>();

var adminManager = IoCManager.Resolve<IClientAdminManager>();
adminManager.AdminStatusUpdated += OnStatusUpdate;

// For the SpawnEntitiesButton and SpawnTilesButton we need to do the press manually
// TODO: This will probably need some command check at some point
SpawnEntitiesButton.OnPressed += SpawnEntitiesButtonOnPressed;
SpawnTilesButton.OnPressed += SpawnTilesButtonOnOnPressed;
SpawnDecalsButton.OnPressed += SpawnDecalsButtonOnPressed;
LoadGamePrototypeButton.OnPressed += LoadGamePrototypeButtonOnPressed;
LoadGamePrototypeButton.Disabled = !adminManager.HasFlag(AdminFlags.Query);
LoadBlueprintsButton.Disabled = !adminManager.HasFlag(AdminFlags.Mapping);
LoadGamePrototypeButton.Disabled = !adminManager.CanCommand("loadprototype");
LoadBlueprintsButton.Disabled = !adminManager.CanCommand("loadgrid");
}

private void OnStatusUpdate()
{
var adminManager = IoCManager.Resolve<IClientAdminManager>();
LoadGamePrototypeButton.Disabled = !adminManager.CanCommand("loadprototype");
LoadBlueprintsButton.Disabled = !adminManager.CanCommand("loadgrid");
}

private void LoadGamePrototypeButtonOnPressed(BaseButton.ButtonEventArgs obj)
Expand Down
11 changes: 2 additions & 9 deletions Content.Client/Atmos/EntitySystems/AtmosPipeAppearanceSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,12 @@ private void OnInit(EntityUid uid, PipeAppearanceComponent component, ComponentI
if (!TryComp(uid, out SpriteComponent? sprite))
return;

if (!_resCache.TryGetResource(SpriteSpecifierSerializer.TextureRoot / component.RsiPath, out RSIResource? rsi))
{
Logger.Error($"{nameof(AtmosPipeAppearanceSystem)} could not load to load RSI {component.RsiPath}.");
return;
}

foreach (PipeConnectionLayer layerKey in Enum.GetValues(typeof(PipeConnectionLayer)))
{
sprite.LayerMapReserveBlank(layerKey);
var layer = sprite.LayerMapGet(layerKey);
sprite.LayerSetRSI(layer, rsi.RSI);
var layerState = component.State;
sprite.LayerSetState(layer, layerState);
sprite.LayerSetRSI(layer, component.Sprite.RsiPath);
sprite.LayerSetState(layer, component.Sprite.RsiState);
sprite.LayerSetDirOffset(layer, ToOffset(layerKey));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public sealed class SolutionContainerVisualsComponent : Component
[DataField("metamorphic")]
public bool Metamorphic = false;
[DataField("metamorphicDefaultSprite")]
public SpriteSpecifier MetamorphicDefaultSprite = SpriteSpecifier.Invalid;
public SpriteSpecifier? MetamorphicDefaultSprite;
[DataField("metamorphicNameFull")]
public string MetamorphicNameFull = "transformable-container-component-glass";

Expand All @@ -41,9 +41,12 @@ public sealed class SolutionContainerVisualsComponent : Component
/// If not set, will work as default.
/// </summary>
[DataField("solutionName")]
public string SolutionName = "";
public string? SolutionName;

[DataField("initialName")]
public string InitialName = string.Empty;

[DataField("initialDescription")]
public string InitialDescription = string.Empty;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ protected override void OnAppearanceChange(EntityUid uid, SolutionContainerVisua
{
if (hasOverlay)
args.Sprite.LayerSetVisible(overlayLayer, true);
args.Sprite.LayerSetSprite(baseLayer, component.MetamorphicDefaultSprite);
if (component.MetamorphicDefaultSprite != null)
args.Sprite.LayerSetSprite(baseLayer, component.MetamorphicDefaultSprite);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion Content.Client/Guidebook/Controls/GuideEntityEmbed.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Numerics;
using Content.Client.ContextMenu.UI;
using Content.Client.Examine;
Expand Down Expand Up @@ -155,7 +156,7 @@ public bool TryParseTag(Dictionary<string, string> args, [NotNullWhen(true)] out

if (args.TryGetValue("Scale", out var scaleStr))
{
var scale = float.Parse(scaleStr);
var scale = float.Parse(scaleStr, CultureInfo.InvariantCulture);
Scale = new Vector2(scale, scale);
}
else
Expand Down
2 changes: 1 addition & 1 deletion Content.Client/Weapons/Melee/MeleeWeaponSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public override void Update(float frameTime)
// it's kinda tricky.
// I think as long as we make secondaries their own component it's probably fine
// as long as guncomp has an alt-use key then it shouldn't be too much of a PITA to deal with.
if (HasComp<GunComponent>(weaponUid))
if (TryComp<GunComponent>(weaponUid, out var gun) && gun.UseKey)
{
return;
}
Expand Down
30 changes: 24 additions & 6 deletions Content.IntegrationTests/PoolManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Content.IntegrationTests.Tests.DeviceNetwork;
using Content.IntegrationTests.Tests.Interaction.Click;
using Content.Server.GameTicking;
using Content.Server.Mind.Components;
using Content.Shared.CCVar;
using Content.Shared.GameTicking;
using Robust.Client;
Expand Down Expand Up @@ -298,7 +299,7 @@ await testOut.WriteLineAsync(
// Newly created pairs should always be in a valid state.
await RunTicksSync(pair, 5);
await SyncTicks(pair, targetDelta: 1);
ValidateFastRecycle(pair, poolSettings);
ValidatePair(pair, poolSettings);
}
else
{
Expand Down Expand Up @@ -326,7 +327,7 @@ await testOut.WriteLineAsync(

await RunTicksSync(pair, 5);
await SyncTicks(pair, targetDelta: 1);
ValidateFastRecycle(pair, poolSettings);
ValidatePair(pair, poolSettings);
}
else
{
Expand Down Expand Up @@ -365,14 +366,15 @@ await testOut.WriteLineAsync(
};
}

private static void ValidateFastRecycle(Pair pair, PoolSettings settings)
private static void ValidatePair(Pair pair, PoolSettings settings)
{
var cfg = pair.Server.ResolveDependency<IConfigurationManager>();
Assert.That(cfg.GetCVar(CCVars.AdminLogsEnabled), Is.EqualTo(settings.AdminLogsEnabled));
Assert.That(cfg.GetCVar(CCVars.GameLobbyEnabled), Is.EqualTo(settings.InLobby));
Assert.That(cfg.GetCVar(CCVars.GameDummyTicker), Is.EqualTo(settings.UseDummyTicker));

var ticker = pair.Server.ResolveDependency<EntityManager>().System<GameTicker>();
var entMan = pair.Server.ResolveDependency<EntityManager>();
var ticker = entMan.System<GameTicker>();
Assert.That(ticker.DummyTicker, Is.EqualTo(settings.UseDummyTicker));

var expectPreRound = settings.InLobby | settings.DummyTicker;
Expand All @@ -390,17 +392,33 @@ private static void ValidateFastRecycle(Pair pair, PoolSettings settings)
var cPlayer = pair.Client.ResolveDependency<Robust.Client.Player.IPlayerManager>();
var sPlayer = pair.Server.ResolveDependency<IPlayerManager>();
Assert.That(sPlayer.Sessions.Count(), Is.EqualTo(1));
Assert.That(cPlayer.LocalPlayer?.Session.UserId, Is.EqualTo(sPlayer.Sessions.Single().UserId));
var session = sPlayer.Sessions.Single();
Assert.That(cPlayer.LocalPlayer?.Session.UserId, Is.EqualTo(session.UserId));

if (ticker.DummyTicker)
return;

var status = ticker.PlayerGameStatuses[sPlayer.Sessions.Single().UserId];
var status = ticker.PlayerGameStatuses[session.UserId];
var expected = settings.InLobby
? PlayerGameStatus.NotReadyToPlay
: PlayerGameStatus.JoinedGame;

Assert.That(status, Is.EqualTo(expected));

if (settings.InLobby)
{
Assert.Null(session.AttachedEntity);
return;
}

Assert.NotNull(session.AttachedEntity);
Assert.That(entMan.EntityExists(session.AttachedEntity));
Assert.That(entMan.HasComponent<MindContainerComponent>(session.AttachedEntity));
var mindCont = entMan.GetComponent<MindContainerComponent>(session.AttachedEntity!.Value);
Assert.NotNull(mindCont.Mind);
Assert.Null(mindCont.Mind?.VisitingEntity);
Assert.That(mindCont.Mind!.OwnedEntity, Is.EqualTo(session.AttachedEntity!.Value));
Assert.That(mindCont.Mind.UserId, Is.EqualTo(session.UserId));
}

private static Pair? GrabOptimalPair(PoolSettings poolSettings)
Expand Down
43 changes: 35 additions & 8 deletions Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#nullable enable
using System.Linq;
using Content.Server.Ghost.Components;
using Content.Server.Ghost.Roles;
using Content.Server.Ghost.Roles.Components;
using Content.Server.Mind;
Expand Down Expand Up @@ -43,23 +44,31 @@ public async Task TakeRoleAndReturn()
var conHost = client.ResolveDependency<IConsoleHost>();
var mindSystem = entMan.System<MindSystem>();
var session = sPlayerMan.ServerSessions.Single();
var originalMind = session.ContentData()!.Mind!;

// Spawn player entity & attach
EntityUid originalMob = default;
await server.WaitPost(() =>
{
originalMob = entMan.SpawnEntity(null, MapCoordinates.Nullspace);
mindSystem.TransferTo(session.ContentData()!.Mind!, originalMob, true);
mindSystem.TransferTo(originalMind, originalMob, true);
});

// Check player got attached.
await PoolManager.RunTicksSync(pairTracker.Pair, 10);
Assert.That(session.AttachedEntity, Is.EqualTo(originalMob));
Assert.That(originalMind.OwnedEntity, Is.EqualTo(originalMob));
Assert.Null(originalMind.VisitingEntity);

// Use the ghost command
conHost.ExecuteCommand("ghost");
await PoolManager.RunTicksSync(pairTracker.Pair, 10);
Assert.That(session.AttachedEntity, Is.Not.EqualTo(originalMob));
var ghost = session.AttachedEntity;
Assert.That(entMan.HasComponent<GhostComponent>(ghost));
Assert.That(ghost, Is.Not.EqualTo(originalMob));
Assert.That(session.ContentData()?.Mind, Is.EqualTo(originalMind));
Assert.That(originalMind.OwnedEntity, Is.EqualTo(originalMob));
Assert.That(originalMind.VisitingEntity, Is.EqualTo(ghost));

// Spawn ghost takeover entity.
EntityUid ghostRole = default;
Expand All @@ -74,21 +83,39 @@ await server.WaitPost(() =>

// Check player got attached to ghost role.
await PoolManager.RunTicksSync(pairTracker.Pair, 10);
var newMind = session.ContentData()!.Mind!;
Assert.That(newMind, Is.Not.EqualTo(originalMind));
Assert.That(session.AttachedEntity, Is.EqualTo(ghostRole));
Assert.That(newMind.OwnedEntity, Is.EqualTo(ghostRole));
Assert.Null(newMind.VisitingEntity);

// Original mind should be unaffected, but the ghost will have deleted itself.
Assert.That(originalMind.OwnedEntity, Is.EqualTo(originalMob));
Assert.Null(originalMind.VisitingEntity);
Assert.That(entMan.Deleted(ghost));

// Ghost again.
conHost.ExecuteCommand("ghost");
await PoolManager.RunTicksSync(pairTracker.Pair, 10);
Assert.That(session.AttachedEntity, Is.Not.EqualTo(originalMob));
Assert.That(session.AttachedEntity, Is.Not.EqualTo(ghostRole));
var otherGhost = session.AttachedEntity;
Assert.That(entMan.HasComponent<GhostComponent>(otherGhost));
Assert.That(otherGhost, Is.Not.EqualTo(originalMob));
Assert.That(otherGhost, Is.Not.EqualTo(ghostRole));
Assert.That(session.ContentData()?.Mind, Is.EqualTo(newMind));
Assert.That(newMind.OwnedEntity, Is.EqualTo(ghostRole));
Assert.That(newMind.VisitingEntity, Is.EqualTo(session.AttachedEntity));

// Next, control the original entity again:
await server.WaitPost(() =>
{
mindSystem.TransferTo(session.ContentData()!.Mind!, originalMob, true);
});
await server.WaitPost(() => mindSystem.SetUserId(originalMind, session.UserId));
await PoolManager.RunTicksSync(pairTracker.Pair, 10);
Assert.That(session.AttachedEntity, Is.EqualTo(originalMob));
Assert.That(originalMind.OwnedEntity, Is.EqualTo(originalMob));
Assert.Null(originalMind.VisitingEntity);

// the ghost-role mind is unaffected, though the ghost will have deleted itself
Assert.That(newMind.OwnedEntity, Is.EqualTo(ghostRole));
Assert.Null(newMind.VisitingEntity);
Assert.That(entMan.Deleted(otherGhost));

await pairTracker.CleanReturnAsync();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ await server.WaitAssertion(() =>
public async Task TestGhostOnDelete()
{
// Client is needed to spawn session
await using var pairTracker = await SetupPair();
await using var pairTracker = await SetupPair(dirty: true);
var server = pairTracker.Pair.Server;

var entMan = server.ResolveDependency<IServerEntityManager>();
Expand Down
5 changes: 3 additions & 2 deletions Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ public sealed partial class MindTests
/// the player's mind's current entity, likely because some previous test directly changed the players attached
/// entity.
/// </remarks>
private static async Task<PairTracker> SetupPair()
private static async Task<PairTracker> SetupPair(bool dirty = false)
{
var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
DummyTicker = false,
Connected = true
Connected = true,
Dirty = dirty
});
var pair = pairTracker.Pair;

Expand Down
21 changes: 12 additions & 9 deletions Content.IntegrationTests/Tests/Minds/MindTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using Content.Server.Ghost;
using Content.Server.Ghost.Roles;
using Content.Server.Ghost.Roles.Components;
using Content.Server.Mind;
using Content.Server.Mind.Commands;
using Content.Server.Mind.Components;
Expand Down Expand Up @@ -403,7 +404,8 @@ public async Task TestGhostDoesNotInfiniteLoop()
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
DummyTicker = false,
Connected = true
Connected = true,
Dirty = true
});
var server = pairTracker.Pair.Server;

Expand All @@ -412,7 +414,7 @@ public async Task TestGhostDoesNotInfiniteLoop()
var serverConsole = server.ResolveDependency<IServerConsoleHost>();

//EntityUid entity = default!;
EntityUid mouse = default!;
EntityUid ghostRole = default!;
EntityUid ghost = default!;
Mind mind = default!;
var player = playerMan.ServerSessions.Single();
Expand All @@ -436,36 +438,37 @@ await server.WaitAssertion(() =>

Assert.That(mind.OwnedEntity, Is.Not.Null);

mouse = entMan.SpawnEntity("MobMouse", new MapCoordinates());
ghostRole = entMan.SpawnEntity("GhostRoleTestEntity", MapCoordinates.Nullspace);
});

await PoolManager.RunTicksSync(pairTracker.Pair, 120);
await PoolManager.RunTicksSync(pairTracker.Pair, 20);

await server.WaitAssertion(() =>
{
serverConsole.ExecuteCommand(player, "aghost");
});

await PoolManager.RunTicksSync(pairTracker.Pair, 120);
await PoolManager.RunTicksSync(pairTracker.Pair, 20);

await server.WaitAssertion(() =>
{
entMan.EntitySysManager.GetEntitySystem<GhostRoleSystem>().Takeover(player, 0);
var id = entMan.GetComponent<GhostRoleComponent>(ghostRole).Identifier;
entMan.EntitySysManager.GetEntitySystem<GhostRoleSystem>().Takeover(player, id);
});

await PoolManager.RunTicksSync(pairTracker.Pair, 120);
await PoolManager.RunTicksSync(pairTracker.Pair, 20);

await server.WaitAssertion(() =>
{
var data = player.ContentData()!;
Assert.That(data.Mind!.OwnedEntity, Is.EqualTo(mouse));
Assert.That(data.Mind!.OwnedEntity, Is.EqualTo(ghostRole));

serverConsole.ExecuteCommand(player, "aghost");
Assert.That(player.AttachedEntity, Is.Not.Null);
ghost = player.AttachedEntity!.Value;
});

await PoolManager.RunTicksSync(pairTracker.Pair, 60);
await PoolManager.RunTicksSync(pairTracker.Pair, 20);

await server.WaitAssertion(() =>
{
Expand Down
Loading
Loading