public override bool Add(IMyInventoryItem item, MyFixedPoint amount) { using (List <MyComponentBase> .Enumerator enumerator = this.m_children.Reader.GetEnumerator()) { while (true) { if (!enumerator.MoveNext()) { break; } MyInventoryBase current = (MyInventoryBase)enumerator.Current; if (current.ItemsCanBeAdded(amount, item) && current.Add(item, amount)) { return(true); } } } return(false); }
/// <summary> /// Transfers safely given item from inventory given as parameter to this instance. /// </summary> /// <returns>true if items were succesfully transfered, otherwise, false</returns> public override bool TransferItemsFrom(MyInventoryBase sourceInventory, IMyInventoryItem item, MyFixedPoint amount) { if (sourceInventory == null) { System.Diagnostics.Debug.Fail("Source inventory is null!"); return(false); } MyInventoryBase destinationInventory = this; if (destinationInventory == null) { System.Diagnostics.Debug.Fail("Destionation inventory is null!"); return(false); } if (item == null) { System.Diagnostics.Debug.Fail("Item is null!"); return(false); } if (amount == 0) { return(true); } bool transfered = false; if ((destinationInventory.ItemsCanBeAdded(amount, item) || destinationInventory == sourceInventory) && sourceInventory.ItemsCanBeRemoved(amount, item)) { if (Sync.IsServer) { if (destinationInventory != sourceInventory) { // try to add first and then remove to ensure this items don't disappear if (destinationInventory.Add(item, amount)) { if (sourceInventory.Remove(item, amount)) { // successfull transaction return(true); } else { // This can happend, that it can't be removed due to some lock, then we need to revert the add. destinationInventory.Remove(item, amount); } } } else { // same inventory transfer = splitting amount, need to remove first and add second if (sourceInventory.Remove(item, amount) && destinationInventory.Add(item, amount)) { return(true); } else { System.Diagnostics.Debug.Fail("Error! Unsuccesfull splitting!"); } } } else { Debug.Assert(sourceInventory != null); MyInventoryTransferEventContent eventParams = new MyInventoryTransferEventContent(); eventParams.Amount = amount; eventParams.ItemId = item.ItemId; eventParams.SourceOwnerId = sourceInventory.Entity.EntityId; eventParams.SourceInventoryId = sourceInventory.InventoryId; eventParams.DestinationOwnerId = destinationInventory.Entity.EntityId; eventParams.DestinationInventoryId = destinationInventory.InventoryId; MyMultiplayer.RaiseStaticEvent(s => InventoryBaseTransferItem_Implementation, eventParams); } } return(transfered); }
public static bool Apply <TInstance>(MyInventoryBase items, ListReader <ImmutableInventoryAction> actions, LuckyLoot.LootContext?luckContext = null, ActionWithArg <TInstance, ImmutableInventoryAction>?errorReporter = null) { var luck = luckContext ?? LuckyLoot.DefaultLoot; var success = true; foreach (var action in actions) { switch (action.Mode) { case ImmutableInventoryAction.InventoryActionMode.GiveTakeItem: { if (action.Amount > 0) { success = action.TargetId.TypeId == typeof(MyObjectBuilder_ItemTagDefinition) ? items.AddItemsWithTag(action.TargetId.SubtypeId, action.Amount) : items.AddItems(action.TargetId, action.Amount); } else { success = action.TargetId.TypeId == typeof(MyObjectBuilder_ItemTagDefinition) ? items.RemoveItemsWithTag(action.TargetId.SubtypeId, -action.Amount) : items.RemoveItems(action.TargetId, -action.Amount); } break; } case ImmutableInventoryAction.InventoryActionMode.RepairDamageItem: { var remaining = action.Amount; if (action.TargetId.TypeId == typeof(MyObjectBuilder_ItemTagDefinition)) { foreach (var item in items.Items) { if (item is MyDurableItem durable && item.HasTag(action.TargetId.SubtypeId)) { ApplyDurability(durable, ref remaining); if (durable.Durability == 0) { var broken = durable.GetDefinition().BrokenItem; var amount = item.Amount; if (!items.Remove(item)) { break; } if (broken.HasValue && !items.AddItems(broken.Value, amount)) { break; } } if (remaining == 0) { break; } } } } else { foreach (var item in items.Items) { if (item is MyDurableItem durable && item.DefinitionId == action.TargetId) { ApplyDurability(durable, ref remaining); if (durable.Durability == 0) { var broken = durable.GetDefinition().BrokenItem; var amount = item.Amount; if (!items.Remove(item)) { break; } if (broken.HasValue && !items.AddItems(broken.Value, amount)) { break; } } if (remaining == 0) { break; } } } } success = remaining == 0; break; } case ImmutableInventoryAction.InventoryActionMode.GiveTakeLootTable: { using (ItemCollection.Borrow(out var tmp)) { using (PoolManager.Get(out HashSet <MyStringHash> tmpSet)) { var table = MyDefinitionManager.Get <MyLootTableDefinition>(action.TargetId); for (var pass = 0; pass < Math.Abs(action.Amount); pass++) { tmpSet.Clear(); tmp.GenerateLuckyContent(table, luck, tmpSet); } } if (action.Amount > 0) { foreach (var item in tmp.Items) { success &= items.Add(item); } } else { foreach (var item in tmp.Items) { success &= items.RemoveItems(item.DefinitionId, item.Amount); } } } break; } default: throw new Exception("Bad mode"); } if (!success) { errorReporter?.Invoke(action); return(false); } } return(success); }