diff --git a/Core/Resources/Archives/Collection/ArchiveCollection.cs b/Core/Resources/Archives/Collection/ArchiveCollection.cs index 334c4732b..f0cdc42e8 100644 --- a/Core/Resources/Archives/Collection/ArchiveCollection.cs +++ b/Core/Resources/Archives/Collection/ArchiveCollection.cs @@ -562,6 +562,12 @@ public void ApplyDehackedPatch() Definitions.DehackedDefinition.LoadActorDefinitions(EntityDefinitionComposer); var dehackedApplier = new DehackedApplier(Definitions, Definitions.DehackedDefinition); dehackedApplier.Apply(Definitions.DehackedDefinition, Definitions, EntityDefinitionComposer); + + foreach (var ammo in Definitions.DehackedDefinition.AmmoNames) + EntityDefinitionComposer.GetByName(ammo)?.Properties.Inventory.IgnoreAmmoDroppedModifier = true; + foreach (var ammo in Definitions.DehackedDefinition.AmmoDoubleNames) + EntityDefinitionComposer.GetByName(ammo)?.Properties.Inventory.IgnoreAmmoDroppedModifier = true; + Definitions.DehackedDefinition.FinalizeData(); } diff --git a/Core/World/Entities/Definition/Properties/Components/InventoryProperty.cs b/Core/World/Entities/Definition/Properties/Components/InventoryProperty.cs index 3524bfb1d..570fbe3a9 100644 --- a/Core/World/Entities/Definition/Properties/Components/InventoryProperty.cs +++ b/Core/World/Entities/Definition/Properties/Components/InventoryProperty.cs @@ -29,5 +29,6 @@ public class InventoryProperty public int PickupBonusCount = 6; public bool MessageOnly; public bool NoItem; + public bool IgnoreAmmoDroppedModifier; public AmountModifier AmountModifier; } diff --git a/Core/World/Entities/Inventories/Inventory.cs b/Core/World/Entities/Inventories/Inventory.cs index 7b0808090..fcc668f6c 100644 --- a/Core/World/Entities/Inventories/Inventory.cs +++ b/Core/World/Entities/Inventories/Inventory.cs @@ -410,7 +410,12 @@ public static int GetAmmoGiveAmount(EntityDefinition ammoDef, EntityDefinition b if (multiplier.HasValue) giveAmount = (int)(giveAmount * multiplier); else + { + // Don't apply 0.5 skill dropped multiplier for ammo drops set by dehacked. Only weapons were hard coded to give half when dropped. + if (weaponDef == null && ammoDef.Properties.Inventory.IgnoreAmmoDroppedModifier) + flags = null; giveAmount = WorldStatic.World.SkillDefinition.GetAmmoAmount(giveAmount, 1, flags); + } return giveAmount; } diff --git a/Core/World/Entities/Players/Player.cs b/Core/World/Entities/Players/Player.cs index d2729939f..db9b824b2 100644 --- a/Core/World/Entities/Players/Player.cs +++ b/Core/World/Entities/Players/Player.cs @@ -1210,6 +1210,9 @@ private bool AddAmmo(EntityDefinition ammoDef, EntityDefinition? weaponDef, int var baseAmmoDef = Inventory.GetBaseAmmoDef(ammoDef); int giveAmount = Inventory.GetAmmoGiveAmount(ammoDef, baseAmmoDef, weaponDef, amount, flags); + if (giveAmount == 0) + return true; + int oldCount = Inventory.Amount(baseAmmoDef); bool success = Inventory.Add(baseAmmoDef, giveAmount, flags); if (success && autoSwitchWeapon && ShouldSwitch(weaponDef)) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index d778057e2..c667d080b 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -34,6 +34,7 @@ - Fix tracer lines drawing over sprites with software emulation. - Fix to match boom behavior to parsing dehacked integers with failures defaulting to zero. - Fix SBARDEF crash when children element was explicity set to null. +- Fix dehacked dropped ammo types only giving half ammo. ## Misc: - Refactor of old Status Bar renderer to data-driven SBARDEF format. diff --git a/Tests/Unit/GameAction/DehackedPickup.cs b/Tests/Unit/GameAction/DehackedPickup.cs index 904d010b7..a325ce224 100644 --- a/Tests/Unit/GameAction/DehackedPickup.cs +++ b/Tests/Unit/GameAction/DehackedPickup.cs @@ -1,13 +1,12 @@ -using Helion.Dehacked; -using Helion.Geometry.Vectors; +using Helion.Geometry.Vectors; using Helion.Resources.IWad; -using Helion.Tests.Unit.GameAction; using Helion.Tests.Unit.GameAction.Util; using Helion.Util; using Helion.World.Entities.Definition.Composer; using Helion.World.Entities.Players; using Helion.World.Impl.SinglePlayer; using System; +using System.Linq; using Xunit; namespace Helion.Tests.Unit.GameAction; @@ -22,15 +21,11 @@ public class DehackedPickup : IDisposable public DehackedPickup() { - World = WorldAllocator.LoadMap("Resources/box.zip", "box.WAD", "MAP01", GetType().Name, WorldInit, IWadType.Doom2); + World = WorldAllocator.LoadMap("Resources/box.zip", "box.WAD", "MAP01", GetType().Name, WorldInit, IWadType.Doom2, dehackedPatch: ""); } private void WorldInit(SinglePlayerWorld world) { - world.ArchiveCollection.Definitions.DehackedDefinition = new(); - DehackedApplier applier = new(world.ArchiveCollection.Definitions, world.ArchiveCollection.Definitions.DehackedDefinition); - applier.Apply(world.ArchiveCollection.Definitions.DehackedDefinition, world.ArchiveCollection.Definitions, world.EntityManager.DefinitionComposer); - // Modify shotgun sprite to blue key. // This should cause the player to pickup a blue key instead of the shotgun var def = GameActions.GetEntityDefinition(world, Chaingun); @@ -51,6 +46,7 @@ public void PickupItemWithModifiedSprite() [Fact(DisplayName = "Modified dehacked pickup carries over dropped")] public void ModifiedDehackedPickupCarriesOverDropped() { + Player.Inventory.Clear(); InventoryUtil.AssertAmount(Player, "Shell", 0); var shotgun = GameActions.CreateEntity(World, "Shotgun", Vec3D.Zero); World.PerformItemPickup(Player, shotgun); @@ -63,6 +59,22 @@ public void ModifiedDehackedPickupCarriesOverDropped() InventoryUtil.AssertAmount(Player, "Shell", 12); } + [Fact(DisplayName = "Dropped ammo is not modified by skill multiplier")] + public void DroppedAmmo() + { + var ammoNames = World.ArchiveCollection.Dehacked!.AmmoNames.Union(World.ArchiveCollection.Dehacked.AmmoDoubleNames); + foreach (var ammo in ammoNames) + { + Player.Inventory.Clear(); + var droppedAmmo = GameActions.CreateEntity(World, ammo, Vec3D.Zero); + var droppedAmmoDef = droppedAmmo.Definition; + droppedAmmo.Flags.SetDropped(); + World.PerformItemPickup(Player, droppedAmmo); + var baseDef = Helion.World.Entities.Inventories.Inventory.GetBaseAmmoDef(droppedAmmoDef); + InventoryUtil.AssertAmount(Player, baseDef.Name, droppedAmmoDef.Properties.Inventory.Amount); + } + } + public void Dispose() { GameActions.DestroyCreatedEntities(World);