Fix not dropping your items when dying while buckled (#1856)
* Fix not dropping your items when dying while buckled * Add test for dropping items while buckled and dead
This commit is contained in:
@@ -1,7 +1,11 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Content.Server.GameObjects.Components.Buckle;
|
using Content.Server.GameObjects.Components.Buckle;
|
||||||
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
using Content.Server.GameObjects.Components.Strap;
|
using Content.Server.GameObjects.Components.Strap;
|
||||||
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.GameObjects.Components.Buckle;
|
using Content.Shared.GameObjects.Components.Buckle;
|
||||||
|
using Content.Shared.GameObjects.Components.Damage;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
@@ -166,5 +170,93 @@ namespace Content.IntegrationTests.Tests
|
|||||||
|
|
||||||
await server.WaitIdleAsync();
|
await server.WaitIdleAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task BuckledDyingDropItemsTest()
|
||||||
|
{
|
||||||
|
var server = StartServer();
|
||||||
|
|
||||||
|
IEntity human = null;
|
||||||
|
IEntity chair = null;
|
||||||
|
BuckleComponent buckle = null;
|
||||||
|
StrapComponent strap = null;
|
||||||
|
HandsComponent hands = null;
|
||||||
|
IDamageableComponent humanDamageable = null;
|
||||||
|
|
||||||
|
server.Assert(() =>
|
||||||
|
{
|
||||||
|
var mapManager = IoCManager.Resolve<IMapManager>();
|
||||||
|
|
||||||
|
var mapId = new MapId(1);
|
||||||
|
mapManager.CreateNewMapEntity(mapId);
|
||||||
|
|
||||||
|
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||||
|
var gridId = new GridId(1);
|
||||||
|
var grid = mapManager.CreateGrid(mapId, gridId);
|
||||||
|
var coordinates = new GridCoordinates((0, 0), gridId);
|
||||||
|
var tileManager = IoCManager.Resolve<ITileDefinitionManager>();
|
||||||
|
var tileId = tileManager["underplating"].TileId;
|
||||||
|
var tile = new Tile(tileId);
|
||||||
|
|
||||||
|
grid.SetTile(coordinates, tile);
|
||||||
|
|
||||||
|
human = entityManager.SpawnEntity("HumanMob_Content", coordinates);
|
||||||
|
chair = entityManager.SpawnEntity("ChairWood", coordinates);
|
||||||
|
|
||||||
|
// Component sanity check
|
||||||
|
Assert.True(human.TryGetComponent(out buckle));
|
||||||
|
Assert.True(chair.TryGetComponent(out strap));
|
||||||
|
Assert.True(human.TryGetComponent(out hands));
|
||||||
|
Assert.True(human.TryGetComponent(out humanDamageable));
|
||||||
|
|
||||||
|
// Buckle
|
||||||
|
Assert.True(buckle.TryBuckle(human, chair));
|
||||||
|
Assert.NotNull(buckle.BuckledTo);
|
||||||
|
Assert.True(buckle.Buckled);
|
||||||
|
|
||||||
|
// Put an item into every hand
|
||||||
|
for (var i = 0; i < hands.Count; i++)
|
||||||
|
{
|
||||||
|
var akms = entityManager.SpawnEntity("RifleAk", coordinates);
|
||||||
|
|
||||||
|
// Equip items
|
||||||
|
Assert.True(akms.TryGetComponent(out ItemComponent item));
|
||||||
|
Assert.True(hands.PutInHand(item));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.RunTicks(10);
|
||||||
|
|
||||||
|
server.Assert(() =>
|
||||||
|
{
|
||||||
|
// Still buckled
|
||||||
|
Assert.True(buckle.Buckled);
|
||||||
|
|
||||||
|
// With items in all hands
|
||||||
|
foreach (var slot in hands.Hands)
|
||||||
|
{
|
||||||
|
Assert.NotNull(hands.GetItem(slot));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Banish our guy into the shadow realm
|
||||||
|
humanDamageable.ChangeDamage(DamageClass.Brute, 1000000, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.RunTicks(10);
|
||||||
|
|
||||||
|
server.Assert(() =>
|
||||||
|
{
|
||||||
|
// Still buckled
|
||||||
|
Assert.True(buckle.Buckled);
|
||||||
|
|
||||||
|
// Now with no item in any hand
|
||||||
|
foreach (var slot in hands.Hands)
|
||||||
|
{
|
||||||
|
Assert.Null(hands.GetItem(slot));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await server.WaitIdleAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ namespace Content.Server.Mobs
|
|||||||
/// <returns>False if the mob was already downed or couldn't set the state</returns>
|
/// <returns>False if the mob was already downed or couldn't set the state</returns>
|
||||||
public static bool Down(IEntity entity, bool playSound = true, bool dropItems = true, bool force = false)
|
public static bool Down(IEntity entity, bool playSound = true, bool dropItems = true, bool force = false)
|
||||||
{
|
{
|
||||||
|
if (dropItems)
|
||||||
|
{
|
||||||
|
DropAllItemsInHands(entity, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (!force && !EffectBlockerSystem.CanFall(entity))
|
if (!force && !EffectBlockerSystem.CanFall(entity))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -45,11 +50,6 @@ namespace Content.Server.Mobs
|
|||||||
.PlayFromEntity(AudioHelpers.GetRandomFileFromSoundCollection("bodyfall"), entity, AudioHelpers.WithVariation(0.25f));
|
.PlayFromEntity(AudioHelpers.GetRandomFileFromSoundCollection("bodyfall"), entity, AudioHelpers.WithVariation(0.25f));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dropItems)
|
|
||||||
{
|
|
||||||
DropAllItemsInHands(entity, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:String x:Key="/Default/FilterSettingsManager/AttributeFilterXml/@EntryValue"><data /></s:String>
|
<s:String x:Key="/Default/FilterSettingsManager/AttributeFilterXml/@EntryValue"><data /></s:String>
|
||||||
<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue"><data><IncludeFilters /><ExcludeFilters><Filter ModuleMask="*.UnitTesting" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /></ExcludeFilters></data></s:String>
|
<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue"><data><IncludeFilters /><ExcludeFilters><Filter ModuleMask="*.UnitTesting" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /></ExcludeFilters></data></s:String>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=akms/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Atmos/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Atmos/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=autoconnect/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=autoconnect/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Barotrauma/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Barotrauma/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|||||||
Reference in New Issue
Block a user