public static bool CanApply <TInstance>(MyInventoryBase items, ListReader <ImmutableInventoryAction> actions, LuckyLoot.LootContext?luckContext = null, ActionWithArg <TInstance, ImmutableInventoryAction>?errorReporter = null) { using (ItemCollection.Borrow(out var collection)) { collection.OverwriteFrom(items); return(Apply(collection, actions, luckContext, errorReporter)); } }
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); }