Inventory slot enumerator rejig (#21788)
This commit is contained in:
@@ -92,9 +92,9 @@ namespace Content.Server.Administration.Commands
|
||||
}
|
||||
|
||||
var invSystem = entityManager.System<InventorySystem>();
|
||||
if (invSystem.TryGetSlots(target, out var slotDefinitions, inventoryComponent))
|
||||
if (invSystem.TryGetSlots(target, out var slots))
|
||||
{
|
||||
foreach (var slot in slotDefinitions)
|
||||
foreach (var slot in slots)
|
||||
{
|
||||
invSystem.TryUnequip(target, slot.Name, true, true, false, inventoryComponent);
|
||||
var gearStr = startingGear.GetGear(slot.Name, profile);
|
||||
|
||||
@@ -368,15 +368,12 @@ namespace Content.Server.Administration.Systems
|
||||
}
|
||||
}
|
||||
|
||||
if (TryComp(entity.Value, out InventoryComponent? inventory) &&
|
||||
_inventory.TryGetSlots(entity.Value, out var slots, inventory))
|
||||
if (_inventory.TryGetContainerSlotEnumerator(entity.Value, out var enumerator))
|
||||
{
|
||||
foreach (var slot in slots)
|
||||
while (enumerator.NextItem(out var item, out var slot))
|
||||
{
|
||||
if (_inventory.TryUnequip(entity.Value, entity.Value, slot.Name, out var item, true, true))
|
||||
{
|
||||
_physics.ApplyAngularImpulse(item.Value, ThrowingSystem.ThrowAngularImpulse);
|
||||
}
|
||||
if (_inventory.TryUnequip(entity.Value, entity.Value, slot.Name, true, true))
|
||||
_physics.ApplyAngularImpulse(item, ThrowingSystem.ThrowAngularImpulse);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -285,27 +285,7 @@ public sealed partial class AdminVerbSystem
|
||||
Text = "Refill Internals Oxygen",
|
||||
Category = VerbCategory.Tricks,
|
||||
Icon = new SpriteSpecifier.Rsi(new("/Textures/Objects/Tanks/oxygen.rsi"), "icon"),
|
||||
Act = () =>
|
||||
{
|
||||
foreach (var slot in _inventorySystem.GetSlots(args.Target))
|
||||
{
|
||||
if (!_inventorySystem.TryGetSlotEntity(args.Target, slot.Name, out var entity))
|
||||
continue;
|
||||
|
||||
if (!TryComp(entity, out tank))
|
||||
continue;
|
||||
|
||||
RefillGasTank(entity.Value, Gas.Oxygen, tank);
|
||||
}
|
||||
|
||||
foreach (var held in _handsSystem.EnumerateHeld(args.Target))
|
||||
{
|
||||
if (!TryComp(held, out tank))
|
||||
continue;
|
||||
|
||||
RefillGasTank(held, Gas.Oxygen, tank);
|
||||
}
|
||||
},
|
||||
Act = () => RefillEquippedTanks(args.User, Gas.Oxygen),
|
||||
Impact = LogImpact.Extreme,
|
||||
Message = Loc.GetString("admin-trick-internals-refill-oxygen-description"),
|
||||
Priority = (int) TricksVerbPriorities.RefillOxygen,
|
||||
@@ -317,27 +297,7 @@ public sealed partial class AdminVerbSystem
|
||||
Text = "Refill Internals Nitrogen",
|
||||
Category = VerbCategory.Tricks,
|
||||
Icon = new SpriteSpecifier.Rsi(new("/Textures/Objects/Tanks/red.rsi"), "icon"),
|
||||
Act = () =>
|
||||
{
|
||||
foreach (var slot in _inventorySystem.GetSlots(args.Target))
|
||||
{
|
||||
if (!_inventorySystem.TryGetSlotEntity(args.Target, slot.Name, out var entity))
|
||||
continue;
|
||||
|
||||
if (!TryComp(entity, out tank))
|
||||
continue;
|
||||
|
||||
RefillGasTank(entity.Value, Gas.Nitrogen, tank);
|
||||
}
|
||||
|
||||
foreach (var held in _handsSystem.EnumerateHeld(args.Target))
|
||||
{
|
||||
if (!TryComp(held, out tank))
|
||||
continue;
|
||||
|
||||
RefillGasTank(held, Gas.Nitrogen, tank);
|
||||
}
|
||||
},
|
||||
Act = () =>RefillEquippedTanks(args.User, Gas.Nitrogen),
|
||||
Impact = LogImpact.Extreme,
|
||||
Message = Loc.GetString("admin-trick-internals-refill-nitrogen-description"),
|
||||
Priority = (int) TricksVerbPriorities.RefillNitrogen,
|
||||
@@ -349,27 +309,7 @@ public sealed partial class AdminVerbSystem
|
||||
Text = "Refill Internals Plasma",
|
||||
Category = VerbCategory.Tricks,
|
||||
Icon = new SpriteSpecifier.Rsi(new("/Textures/Objects/Tanks/plasma.rsi"), "icon"),
|
||||
Act = () =>
|
||||
{
|
||||
foreach (var slot in _inventorySystem.GetSlots(args.Target))
|
||||
{
|
||||
if (!_inventorySystem.TryGetSlotEntity(args.Target, slot.Name, out var entity))
|
||||
continue;
|
||||
|
||||
if (!TryComp(entity, out tank))
|
||||
continue;
|
||||
|
||||
RefillGasTank(entity.Value, Gas.Plasma, tank);
|
||||
}
|
||||
|
||||
foreach (var held in _handsSystem.EnumerateHeld(args.Target))
|
||||
{
|
||||
if (!TryComp(held, out tank))
|
||||
continue;
|
||||
|
||||
RefillGasTank(held, Gas.Plasma, tank);
|
||||
}
|
||||
},
|
||||
Act = () => RefillEquippedTanks(args.User, Gas.Plasma),
|
||||
Impact = LogImpact.Extreme,
|
||||
Message = Loc.GetString("admin-trick-internals-refill-plasma-description"),
|
||||
Priority = (int) TricksVerbPriorities.RefillPlasma,
|
||||
@@ -792,9 +732,17 @@ public sealed partial class AdminVerbSystem
|
||||
}
|
||||
}
|
||||
|
||||
private void RefillGasTank(EntityUid tank, Gas gasType, GasTankComponent? tankComponent)
|
||||
private void RefillEquippedTanks(EntityUid target, Gas plasma)
|
||||
{
|
||||
if (!Resolve(tank, ref tankComponent))
|
||||
foreach (var held in _inventorySystem.GetHandOrInventoryEntities(target))
|
||||
{
|
||||
RefillGasTank(held, Gas.Plasma);
|
||||
}
|
||||
}
|
||||
|
||||
private void RefillGasTank(EntityUid tank, Gas gasType, GasTankComponent? tankComponent = null)
|
||||
{
|
||||
if (!Resolve(tank, ref tankComponent, false))
|
||||
return;
|
||||
|
||||
var mixSize = tankComponent.Air.Volume;
|
||||
|
||||
@@ -6,6 +6,7 @@ using Content.Server.Popups;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Internals;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Verbs;
|
||||
@@ -26,6 +27,8 @@ public sealed class InternalsSystem : EntitySystem
|
||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
|
||||
public const SlotFlags InventorySlots = SlotFlags.POCKET | SlotFlags.BELT;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -81,7 +84,7 @@ public sealed class InternalsSystem : EntitySystem
|
||||
return;
|
||||
}
|
||||
|
||||
var tank = FindBestGasTank(uid, internals);
|
||||
var tank = FindBestGasTank(uid);
|
||||
|
||||
if (tank == null)
|
||||
{
|
||||
@@ -224,59 +227,35 @@ public sealed class InternalsSystem : EntitySystem
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Entity<GasTankComponent>? FindBestGasTank(EntityUid internalsOwner, InternalsComponent component)
|
||||
public Entity<GasTankComponent>? FindBestGasTank(Entity<HandsComponent?, InventoryComponent?, ContainerManagerComponent?> user)
|
||||
{
|
||||
// Prioritise
|
||||
// 1. back equipped tanks
|
||||
// 2. exo-slot tanks
|
||||
// 3. in-hand tanks
|
||||
// 4. pocket/belt tanks
|
||||
InventoryComponent? inventory = null;
|
||||
ContainerManagerComponent? containerManager = null;
|
||||
|
||||
if (_inventory.TryGetSlotEntity(internalsOwner, "back", out var backEntity, inventory, containerManager) &&
|
||||
if (!Resolve(user.Owner, ref user.Comp1, ref user.Comp2, ref user.Comp3))
|
||||
return null;
|
||||
|
||||
if (_inventory.TryGetSlotEntity(user.Owner, "back", out var backEntity, user.Comp2, user.Comp3) &&
|
||||
TryComp<GasTankComponent>(backEntity, out var backGasTank) &&
|
||||
_gasTank.CanConnectToInternals(backGasTank))
|
||||
{
|
||||
return (backEntity.Value, backGasTank);
|
||||
}
|
||||
|
||||
if (_inventory.TryGetSlotEntity(internalsOwner, "suitstorage", out var entity, inventory, containerManager) &&
|
||||
if (_inventory.TryGetSlotEntity(user.Owner, "suitstorage", out var entity, user.Comp2, user.Comp3) &&
|
||||
TryComp<GasTankComponent>(entity, out var gasTank) &&
|
||||
_gasTank.CanConnectToInternals(gasTank))
|
||||
{
|
||||
return (entity.Value, gasTank);
|
||||
}
|
||||
|
||||
var tanks = new List<Entity<GasTankComponent>>();
|
||||
|
||||
foreach (var hand in _hands.EnumerateHands(internalsOwner))
|
||||
foreach (var item in _inventory.GetHandOrInventoryEntities((user.Owner, user.Comp1, user.Comp2)))
|
||||
{
|
||||
if (TryComp(hand.HeldEntity, out gasTank) && _gasTank.CanConnectToInternals(gasTank))
|
||||
tanks.Add((hand.HeldEntity.Value, gasTank));
|
||||
}
|
||||
|
||||
if (tanks.Count > 0)
|
||||
{
|
||||
tanks.Sort((x, y) => y.Comp.Air.TotalMoles.CompareTo(x.Comp.Air.TotalMoles));
|
||||
return tanks[0];
|
||||
}
|
||||
|
||||
if (Resolve(internalsOwner, ref inventory, false))
|
||||
{
|
||||
var enumerator = new InventorySystem.ContainerSlotEnumerator(internalsOwner, inventory.TemplateId, _protoManager, _inventory, SlotFlags.POCKET | SlotFlags.BELT);
|
||||
|
||||
while (enumerator.MoveNext(out var container))
|
||||
{
|
||||
if (TryComp(container.ContainedEntity, out gasTank) && _gasTank.CanConnectToInternals(gasTank))
|
||||
tanks.Add((container.ContainedEntity.Value, gasTank));
|
||||
}
|
||||
|
||||
if (tanks.Count > 0)
|
||||
{
|
||||
tanks.Sort((x, y) => y.Comp.Air.TotalMoles.CompareTo(x.Comp.Air.TotalMoles));
|
||||
return tanks[0];
|
||||
}
|
||||
if (TryComp(item, out gasTank) && _gasTank.CanConnectToInternals(gasTank))
|
||||
return (item, gasTank);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -35,15 +35,13 @@ namespace Content.Server.Chemistry.EntitySystems
|
||||
return;
|
||||
}
|
||||
|
||||
if (component.BlockSlots != 0x0 && TryComp<InventoryComponent>(target, out var inventory))
|
||||
if (component.BlockSlots != 0x0)
|
||||
{
|
||||
var containerEnumerator = new InventorySystem.ContainerSlotEnumerator(target, inventory.TemplateId, _protoManager, _inventorySystem, component.BlockSlots);
|
||||
var containerEnumerator = _inventorySystem.GetSlotEnumerator(target, component.BlockSlots);
|
||||
|
||||
while (containerEnumerator.MoveNext(out var container))
|
||||
{
|
||||
if (!container.ContainedEntity.HasValue) continue;
|
||||
// TODO add a helper method for this?
|
||||
if (containerEnumerator.MoveNext(out _))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var solRemoved = solution.SplitSolution(component.TransferAmount);
|
||||
|
||||
@@ -25,10 +25,8 @@ namespace Content.Server.Inventory
|
||||
|
||||
private void OnExploded(Entity<InventoryComponent> ent, ref BeforeExplodeEvent args)
|
||||
{
|
||||
if (!TryGetContainerSlotEnumerator(ent, out var slots, ent.Comp))
|
||||
return;
|
||||
|
||||
// explode each item in their inventory too
|
||||
var slots = new InventorySlotEnumerator(ent);
|
||||
while (slots.MoveNext(out var slot))
|
||||
{
|
||||
if (slot.ContainedEntity != null)
|
||||
@@ -55,33 +53,16 @@ namespace Content.Server.Inventory
|
||||
}
|
||||
}
|
||||
|
||||
public void TransferEntityInventories(EntityUid uid, EntityUid target)
|
||||
public void TransferEntityInventories(Entity<InventoryComponent?> source, Entity<InventoryComponent?> target)
|
||||
{
|
||||
if (!TryGetContainerSlotEnumerator(uid, out var enumerator))
|
||||
if (!Resolve(source.Owner, ref source.Comp) || !Resolve(target.Owner, ref target.Comp))
|
||||
return;
|
||||
|
||||
Dictionary<string, EntityUid> inventoryEntities = new();
|
||||
var slots = GetSlots(uid);
|
||||
while (enumerator.MoveNext(out var containerSlot))
|
||||
var enumerator = new InventorySlotEnumerator(source.Comp);
|
||||
while (enumerator.NextItem(out var item, out var slot))
|
||||
{
|
||||
//records all the entities stored in each of the target's slots
|
||||
foreach (var slot in slots)
|
||||
{
|
||||
if (TryGetSlotContainer(target, slot.Name, out var conslot, out _) &&
|
||||
conslot.ID == containerSlot.ID &&
|
||||
containerSlot.ContainedEntity is { } containedEntity)
|
||||
{
|
||||
inventoryEntities.Add(slot.Name, containedEntity);
|
||||
}
|
||||
}
|
||||
//drops everything in the target's inventory on the ground
|
||||
TryUnequip(uid, containerSlot.ID, true, true);
|
||||
}
|
||||
// This takes the objects we removed and stored earlier
|
||||
// and actually equips all of it to the new entity
|
||||
foreach (var (slot, item) in inventoryEntities)
|
||||
{
|
||||
TryEquip(target, item, slot , true, true);
|
||||
if (TryUnequip(source, slot.Name, true, true, inventory: source.Comp))
|
||||
TryEquip(target, item, slot.Name , true, true, inventory: target.Comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@ public sealed class StressTestMovementSystem : EntitySystem
|
||||
|
||||
while (query.MoveNext(out var uid, out var stressTest, out var transform))
|
||||
{
|
||||
if (!transform.ParentUid.IsValid())
|
||||
continue;
|
||||
|
||||
stressTest.Progress += frameTime;
|
||||
|
||||
if (stressTest.Progress > 1)
|
||||
|
||||
@@ -40,6 +40,16 @@ namespace Content.Server.Zombies
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
|
||||
public const SlotFlags ProtectiveSlots =
|
||||
SlotFlags.FEET |
|
||||
SlotFlags.HEAD |
|
||||
SlotFlags.EYES |
|
||||
SlotFlags.GLOVES |
|
||||
SlotFlags.MASK |
|
||||
SlotFlags.NECK |
|
||||
SlotFlags.INNERCLOTHING |
|
||||
SlotFlags.OUTERCLOTHING;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -164,33 +174,27 @@ namespace Content.Server.Zombies
|
||||
|
||||
private float GetZombieInfectionChance(EntityUid uid, ZombieComponent component)
|
||||
{
|
||||
var baseChance = component.MaxZombieInfectionChance;
|
||||
var max = component.MaxZombieInfectionChance;
|
||||
|
||||
if (!TryComp<InventoryComponent>(uid, out var inventoryComponent))
|
||||
return baseChance;
|
||||
|
||||
var enumerator =
|
||||
new InventorySystem.ContainerSlotEnumerator(uid, inventoryComponent.TemplateId, _protoManager, _inv,
|
||||
SlotFlags.FEET |
|
||||
SlotFlags.HEAD |
|
||||
SlotFlags.EYES |
|
||||
SlotFlags.GLOVES |
|
||||
SlotFlags.MASK |
|
||||
SlotFlags.NECK |
|
||||
SlotFlags.INNERCLOTHING |
|
||||
SlotFlags.OUTERCLOTHING);
|
||||
if (!_inventory.TryGetContainerSlotEnumerator(uid, out var enumerator, ProtectiveSlots))
|
||||
return max;
|
||||
|
||||
var items = 0f;
|
||||
var total = 0f;
|
||||
while (enumerator.MoveNext(out var con))
|
||||
{
|
||||
total++;
|
||||
|
||||
if (con.ContainedEntity != null)
|
||||
items++;
|
||||
}
|
||||
|
||||
var max = component.MaxZombieInfectionChance;
|
||||
if (total == 0)
|
||||
return max;
|
||||
|
||||
// Everyone knows that when it comes to zombies, socks & sandals provide just as much protection as an
|
||||
// armored vest. Maybe these should be weighted per-item. I.e. some kind of coverage/protection component.
|
||||
// Or at the very least different weights per slot.
|
||||
|
||||
var min = component.MinZombieInfectionChance;
|
||||
//gets a value between the max and min based on how many items the entity is wearing
|
||||
var chance = (max-min) * ((total - items)/total) + min;
|
||||
|
||||
Reference in New Issue
Block a user