Merge remote-tracking branch 'upstream/stable' into ed-25-08-2025-upstream-sync

# Conflicts:
#	.github/CODEOWNERS
#	Content.Client/UserInterface/Systems/Actions/Controls/ActionButton.cs
#	Content.Server/Administration/Systems/AdminVerbSystem.Antags.cs
#	Content.Server/Chat/Systems/ChatSystem.cs
#	Content.Server/Explosion/EntitySystems/TriggerSystem.cs
#	Content.Server/Nutrition/EntitySystems/SliceableFoodSystem.cs
#	Content.Shared/Lock/LockSystem.cs
#	Content.Shared/Nutrition/Components/FoodComponent.cs
#	Content.Shared/Speech/ListenEvent.cs
#	Resources/Prototypes/Entities/Effects/admin_triggers.yml
This commit is contained in:
Ed
2025-08-25 16:22:32 +03:00
1069 changed files with 42396 additions and 29527 deletions

View File

@@ -5,4 +5,4 @@
// https://github.com/dotnet/runtime/issues/107197
// So we can't really parallelize integration tests harder either until the runtime fixes that,
// *or* we fix serv3 to not spam expression trees.
[assembly: LevelOfParallelism(3)]
[assembly: LevelOfParallelism(2)]

View File

@@ -0,0 +1,29 @@
using Content.Shared.Damage.Components;
namespace Content.IntegrationTests.Tests.Damageable;
public sealed class StaminaComponentTest
{
[Test]
public async Task ValidatePrototypes()
{
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;
var protos = pair.GetPrototypesWithComponent<StaminaComponent>();
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
foreach (var (proto, comp) in protos)
{
Assert.That(comp.AnimationThreshold, Is.LessThan(comp.CritThreshold),
$"Animation threshold on {proto.ID} must be less than its crit threshold.");
}
});
});
await pair.CleanReturnAsync();
}
}

View File

@@ -1,11 +1,9 @@
#nullable enable
using Content.Server.Cuffs;
using Content.Shared.Body.Components;
using Content.Shared.Cuffs.Components;
using Content.Shared.Hands.Components;
using Robust.Server.Console;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
namespace Content.IntegrationTests.Tests.GameObjects.Components.ActionBlocking
{
@@ -22,9 +20,15 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.ActionBlocking
components:
- type: Cuffable
- type: Hands
hands:
hand_right:
location: Right
hand_left:
location: Left
sortedHands:
- hand_right
- hand_left
- type: ComplexInteraction
- type: Body
prototype: Human
- type: entity
name: HandcuffsDummy
@@ -47,7 +51,6 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.ActionBlocking
HandsComponent hands = default!;
var entityManager = server.ResolveDependency<IEntityManager>();
var mapManager = server.ResolveDependency<IMapManager>();
var host = server.ResolveDependency<IServerConsoleHost>();
var map = await pair.CreateTestMap();
@@ -73,7 +76,6 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.ActionBlocking
{
Assert.That(entityManager.TryGetComponent(human, out cuffed!), $"Human has no {nameof(CuffableComponent)}");
Assert.That(entityManager.TryGetComponent(human, out hands!), $"Human has no {nameof(HandsComponent)}");
Assert.That(entityManager.TryGetComponent(human, out BodyComponent? _), $"Human has no {nameof(BodyComponent)}");
Assert.That(entityManager.TryGetComponent(cuffs, out HandcuffComponent? _), $"Handcuff has no {nameof(HandcuffComponent)}");
Assert.That(entityManager.TryGetComponent(secondCuffs, out HandcuffComponent? _), $"Second handcuffs has no {nameof(HandcuffComponent)}");
});

View File

@@ -9,7 +9,6 @@ using Content.Server.Mind;
using Content.Server.Roles;
using Content.Server.RoundEnd;
using Content.Server.Shuttles.Components;
using Content.Server.Station.Components;
using Content.Shared.CCVar;
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
@@ -20,6 +19,7 @@ using Content.Shared.NPC.Prototypes;
using Content.Shared.NPC.Systems;
using Content.Shared.NukeOps;
using Content.Shared.Pinpointer;
using Content.Shared.Roles.Components;
using Content.Shared.Station.Components;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;

View File

@@ -3,7 +3,6 @@ using System.Linq;
using Content.Server.Ghost.Roles;
using Content.Server.Ghost.Roles.Components;
using Content.Server.Mind;
using Content.Server.Roles;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.FixedPoint;
@@ -11,7 +10,7 @@ using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Players;
using Content.Shared.Roles;
using Content.Shared.Roles.Jobs;
using Content.Shared.Roles.Components;
using Robust.Server.Console;
using Robust.Server.GameObjects;
using Robust.Server.Player;

View File

@@ -1,7 +1,5 @@
using System.Linq;
using Content.Server.Roles;
using Content.Shared.Roles;
using Content.Shared.Roles.Jobs;
using Content.Shared.Roles.Components;
using Robust.Shared.GameObjects;
using Robust.Shared.Reflection;

View File

@@ -1,6 +1,6 @@
using Content.IntegrationTests.Tests.Interaction;
using Content.Server.Explosion.Components;
using Content.Shared.Explosion.Components;
using Content.Shared.Trigger.Components;
using Content.Shared.Trigger.Systems;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
@@ -25,19 +25,19 @@ public sealed class ModularGrenadeTests : InteractionTest
await InteractUsing(Cable);
// Insert & remove trigger
AssertComp<OnUseTimerTriggerComponent>(false);
AssertComp<TimerTriggerComponent>(false);
await InteractUsing(Trigger);
AssertComp<OnUseTimerTriggerComponent>();
AssertComp<TimerTriggerComponent>();
await FindEntity(Trigger, LookupFlags.Uncontained, shouldSucceed: false);
await InteractUsing(Pry);
AssertComp<OnUseTimerTriggerComponent>(false);
AssertComp<TimerTriggerComponent>(false);
// Trigger was dropped to floor, not deleted.
await FindEntity(Trigger, LookupFlags.Uncontained);
// Re-insert
await InteractUsing(Trigger);
AssertComp<OnUseTimerTriggerComponent>();
AssertComp<TimerTriggerComponent>();
// Insert & remove payload.
await InteractUsing(Payload);
@@ -56,13 +56,14 @@ public sealed class ModularGrenadeTests : InteractionTest
await Pickup();
AssertComp<ActiveTimerTriggerComponent>(false);
await UseInHand();
AssertComp<ActiveTimerTriggerComponent>(true);
// So uhhh grenades in hands don't destroy themselves when exploding. Maybe that will be fixed eventually.
await Drop();
// Wait until grenade explodes
var timer = Comp<ActiveTimerTriggerComponent>();
while (timer.TimeRemaining >= 0)
var triggerSys = SEntMan.System<TriggerSystem>();
while (Target != null && triggerSys.GetRemainingTime(SEntMan.GetEntity(Target.Value))?.TotalSeconds >= 0.0)
{
await RunTicks(10);
}

View File

@@ -2,9 +2,9 @@ using System.Linq;
using Content.Server.GameTicking;
using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Systems;
using Content.Server.Station.Components;
using Content.Shared.CCVar;
using Content.Shared.Shuttles.Components;
using Content.Shared.Station.Components;
using Robust.Shared.GameObjects;
using Robust.Shared.Map.Components;

View File

@@ -128,7 +128,7 @@ public sealed class StoreTests
var buyMsg = new StoreBuyListingMessage(discountedListingItem.ID){Actor = human};
server.EntMan.EventBus.RaiseComponentEvent(pda, storeComponent, buyMsg);
server.EntMan.EventBus.RaiseLocalEvent(pda, buyMsg);
var newBalance = storeComponent.Balance[UplinkSystem.TelecrystalCurrencyPrototype];
Assert.That(newBalance.Value, Is.EqualTo((originalBalance - plainDiscountedCost).Value), "Expected to have balance reduced by discounted cost");
@@ -141,7 +141,7 @@ public sealed class StoreTests
Assert.That(costAfterBuy.Value, Is.EqualTo(prototypeCost.Value), "Expected cost after discount refund to be equal to prototype cost.");
var refundMsg = new StoreRequestRefundMessage { Actor = human };
server.EntMan.EventBus.RaiseComponentEvent(pda, storeComponent, refundMsg);
server.EntMan.EventBus.RaiseLocalEvent(pda, refundMsg);
// get refreshed item after refund re-generated items
discountedListingItem = storeComponent.FullListingsCatalog.First(x => x.ID == itemId);