diff --git a/Subsurface/Source/Items/Components/ItemContainer.cs b/Subsurface/Source/Items/Components/ItemContainer.cs index d2ff56cfd..d9d4c4c68 100644 --- a/Subsurface/Source/Items/Components/ItemContainer.cs +++ b/Subsurface/Source/Items/Components/ItemContainer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Xml.Linq; using FarseerPhysics; using Microsoft.Xna.Framework; @@ -14,7 +15,7 @@ namespace Barotrauma.Items.Components List containableItems; public ItemInventory Inventory; - private bool hasStatusEffects; + private List> itemsWithStatusEffects; //how many items can be contained [HasDefaultValue(5, false)] @@ -110,24 +111,39 @@ namespace Barotrauma.Items.Components case "containable": RelatedItem containable = RelatedItem.Load(subElement); if (containable == null) continue; - - foreach (StatusEffect effect in containable.statusEffects) - { - if (effect.type == ActionType.OnContaining) hasStatusEffects = true; - } - + containableItems.Add(containable); break; } } - IsActive = true; + itemsWithStatusEffects = new List>(); } - public void RemoveContained(Item item) + public void OnItemContained(Item item) { - Inventory.RemoveItem(item); + item.SetContainedItemPositions(); + + RelatedItem ri = containableItems.Find(x => x.MatchesItem(item)); + if (ri != null) + { + foreach (StatusEffect effect in ri.statusEffects) + { + itemsWithStatusEffects.Add(Pair.Create(item, effect)); + } + } + + //no need to Update() if this item has no statuseffects and no physics body + IsActive = itemsWithStatusEffects.Count > 0 || item.body != null; + } + + public void OnItemRemoved(Item item) + { + itemsWithStatusEffects.RemoveAll(i => i.First == item); + + //deactivate if the inventory is empty + IsActive = itemsWithStatusEffects.Count > 0 || item.body != null; } public bool CanBeContained(Item item) @@ -138,31 +154,24 @@ namespace Barotrauma.Items.Components public override void Update(float deltaTime, Camera cam) { - if (item.body != null && item.body.FarseerBody.Awake) + if (item.body != null && + item.body.Enabled && + item.body.FarseerBody.Awake) { - foreach (Item contained in Inventory.Items) - { - if (contained == null) continue; - contained.SetTransform(item.SimPosition, 0.0f); - } + item.SetContainedItemPositions(); } - if (!hasStatusEffects) return; - - foreach (Item contained in Inventory.Items) + foreach (Pair itemAndEffect in itemsWithStatusEffects) { - if (contained == null || contained.Condition <= 0.0f) continue; + Item contained = itemAndEffect.First; + if (contained.Condition < 0.0f) continue; - RelatedItem ri = containableItems.Find(x => x.MatchesItem(contained)); - if (ri == null) continue; + StatusEffect effect = itemAndEffect.Second; - foreach (StatusEffect effect in ri.statusEffects) - { - if (effect.Targets.HasFlag(StatusEffect.TargetType.This)) effect.Apply(ActionType.OnContaining, deltaTime, item, item.AllPropertyObjects); - if (effect.Targets.HasFlag(StatusEffect.TargetType.Contained)) effect.Apply(ActionType.OnContaining, deltaTime, item, contained.AllPropertyObjects); - } - - //contained.ApplyStatusEffects(ActionType.OnContained, deltaTime); + if (effect.Targets.HasFlag(StatusEffect.TargetType.This)) + effect.Apply(ActionType.OnContaining, deltaTime, item, item.AllPropertyObjects); + if (effect.Targets.HasFlag(StatusEffect.TargetType.Contained)) + effect.Apply(ActionType.OnContaining, deltaTime, item, contained.AllPropertyObjects); } } @@ -232,15 +241,13 @@ namespace Barotrauma.Items.Components public override bool Combine(Item item) { - if (containableItems.Find(x => x.MatchesItem(item)) == null) return false; + if (!containableItems.Any(x => x.MatchesItem(item))) return false; if (Inventory.TryPutItem(item)) { IsActive = true; - if (hideItems || (item.body!=null && !item.body.Enabled)) item.body.Enabled = false; - - //item.Container = this.item; - + if (hideItems && item.body != null) item.body.Enabled = false; + return true; } diff --git a/Subsurface/Source/Items/Components/Wearable.cs b/Subsurface/Source/Items/Components/Wearable.cs index adb195e10..0c828a61c 100644 --- a/Subsurface/Source/Items/Components/Wearable.cs +++ b/Subsurface/Source/Items/Components/Wearable.cs @@ -168,9 +168,8 @@ namespace Barotrauma.Items.Components public override void Update(float deltaTime, Camera cam) { - base.Update(deltaTime, cam); - item.SetTransform(picker.SimPosition, 0.0f); + item.SetContainedItemPositions(); ApplyStatusEffects(ActionType.OnWearing, deltaTime, picker); diff --git a/Subsurface/Source/Items/ItemInventory.cs b/Subsurface/Source/Items/ItemInventory.cs index fe714d58e..27660144d 100644 --- a/Subsurface/Source/Items/ItemInventory.cs +++ b/Subsurface/Source/Items/ItemInventory.cs @@ -44,6 +44,27 @@ namespace Barotrauma return (item!=null && Items[i]==null && container.CanBeContained(item)); } + public override bool TryPutItem(Item item, System.Collections.Generic.List allowedSlots = null, bool createNetworkEvent = true) + { + bool wasPut = base.TryPutItem(item, allowedSlots, createNetworkEvent); + + if (wasPut) + { + foreach (Character c in Character.CharacterList) + { + if (!c.HasSelectedItem(item)) continue; + + item.Unequip(c); + break; + } + + container.IsActive = true; + container.OnItemContained(item); + } + + return wasPut; + } + public override bool TryPutItem(Item item, int i, bool allowSwapping, bool createNetworkEvent) { bool wasPut = base.TryPutItem(item, i, allowSwapping, createNetworkEvent); @@ -57,11 +78,18 @@ namespace Barotrauma item.Unequip(c); break; } - //item.Container = container.Item; + container.IsActive = true; + container.OnItemContained(item); } + return wasPut; } + public override void RemoveItem(Item item) + { + base.RemoveItem(item); + container.OnItemRemoved(item); + } } }