diff --git a/HarmonySrc/CinerariumCraft.cs b/HarmonySrc/CinerariumCraft.cs index 98e7bd3..0cdc1ab 100644 --- a/HarmonySrc/CinerariumCraft.cs +++ b/HarmonySrc/CinerariumCraft.cs @@ -133,13 +133,17 @@ namespace NecromancerTome { continue; // выход полон и ящики «куда» полны (или их нет) - ниже станция погаснет } + if (InQueue(st.Te, sample.itemValue.type)) + { + continue; // партия этого предмета уже в очереди - следующая, когда она кончится + } foreach (Recipe r in CraftingManager.GetRecipes(name)) { if (r.IsScrap || !AreaFits(r, st.Areas) || !ToolFits(r, st.Te) || owner != null && !r.IsUnlocked(owner)) { continue; } - if (!Ingredients(r, st.Te, src, out Vector3i? srcAt, out string shortUnit)) + if (!Ingredients(r, st.Te, src, out Vector3i? srcAt, out string shortUnit, out int batches)) { // Кузня: не хватает переплавленного материала - положить сырьё во вход (плавит сама, с огнём). if (shortUnit != null && FeedMaterial(st, shortUnit, src, _dry, out Vector3i? rawAt)) @@ -158,10 +162,10 @@ namespace NecromancerTome { return st.Pos; } - TakeIngredients(r, st.Te, src); - Enqueue(st.Te, slot, r); + TakeIngredients(r, st.Te, src, batches); + Enqueue(st.Te, slot, r, batches); Ignite(st.Te, src, false); - Debug.Log("[NecromancerTome] Cinerarium: рабочий поставил " + name + " на станцию " + st.Pos); + Debug.Log("[NecromancerTome] Cinerarium: рабочий поставил " + name + " x" + batches + " на станцию " + st.Pos); return st.Pos; } } @@ -289,6 +293,21 @@ namespace NecromancerTome return -1; } + /// Есть ли в очереди станции рецепт этого предмета. 24.10, пользователь: партия - до стака, и «если бы их было + /// двое, то тут нужно занимать очередь на ячейку»: один предмет держит в очереди одну ячейку, прочие - другим урнам на + /// той же станции (иначе одна урна забила бы очередь стаками на часы вперёд). + static bool InQueue(TileEntityWorkstation _te, int _itemType) + { + foreach (RecipeQueueItem q in _te.Queue) + { + if (q != null && q.Recipe != null && q.Multiplier > 0 && q.Recipe.itemValueType == _itemType) + { + return true; + } + } + return false; + } + static bool OutputHasRoom(TileEntityWorkstation _te, ItemStack _sample) { foreach (ItemStack s in _te.Output) @@ -325,11 +344,17 @@ namespace NecromancerTome } /// Хватает ли всего: переплавленное - в кузне, прочее - в ящиках «откуда». _srcAt - ящик, откуда первое; - /// _shortUnit - какого переплавленного не хватило (кузне можно подложить сырья). - static bool Ingredients(Recipe _r, TileEntityWorkstation _te, List<(Vector3i p, TEFeatureStorage box)> _src, out Vector3i? _srcAt, out string _shortUnit) + /// _shortUnit - какого переплавленного не хватило (кузне можно подложить сырья). _batches - сколько раз рецепт ставится + /// в очередь за одно дело (24.10, пользователь: «в бетономешалку кладётся по одному камушку... ожидается, что он будет + /// класть хотя бы по целому стаку, а если на стак не хватает, то сколько найдёт»): на сколько хватает каждого + /// ингредиента, но не больше стака ни одного ингредиента и не больше стака готового. + static bool Ingredients(Recipe _r, TileEntityWorkstation _te, List<(Vector3i p, TEFeatureStorage box)> _src, out Vector3i? _srcAt, out string _shortUnit, out int _batches) { _srcAt = null; _shortUnit = null; + ItemClass outClass = ItemClass.GetForId(_r.itemValueType); + _batches = outClass != null && _r.count > 0 ? Mathf.Max(1, outClass.MaxCount / _r.count) : 1; + _batches = Mathf.Min(_batches, short.MaxValue); foreach (ItemStack ing in _r.ingredients) { if (ing == null || ing.IsEmpty() || ing.count <= 0) @@ -345,6 +370,7 @@ namespace NecromancerTome _shortUnit = iname; return false; } + _batches = Mathf.Min(_batches, _te.Input[us].count / ing.count); continue; } int have = 0; @@ -367,11 +393,14 @@ namespace NecromancerTome { return false; } + int stack = ing.itemValue.ItemClass != null ? ing.itemValue.ItemClass.MaxCount : ing.count; + _batches = Mathf.Min(_batches, Mathf.Max(1, stack / ing.count), have / ing.count); } + _batches = Mathf.Max(1, _batches); return true; } - static void TakeIngredients(Recipe _r, TileEntityWorkstation _te, List<(Vector3i p, TEFeatureStorage box)> _src) + static void TakeIngredients(Recipe _r, TileEntityWorkstation _te, List<(Vector3i p, TEFeatureStorage box)> _src, int _batches) { ItemStack[] input = _te.Input; bool inputChanged = false; @@ -384,11 +413,11 @@ namespace NecromancerTome int us = UnitSlot(_te, ing.itemValue.ItemClass?.GetItemName() ?? ""); if (us >= 0) { - input[us].count -= ing.count; + input[us].count -= ing.count * _batches; inputChanged = true; continue; } - int need = ing.count; + int need = ing.count * _batches; foreach ((Vector3i p, TEFeatureStorage box) s in _src) { ItemStack[] grid = s.box.ItemGrid.items; @@ -413,7 +442,7 @@ namespace NecromancerTome } } - static void Enqueue(TileEntityWorkstation _te, int _slot, Recipe _r) + static void Enqueue(TileEntityWorkstation _te, int _slot, Recipe _r, int _batches) { RecipeQueueItem[] q = _te.Queue; float t = _r.craftingTime > 0f ? _r.craftingTime : 1f; @@ -421,7 +450,7 @@ namespace NecromancerTome q[_slot] = new RecipeQueueItem { Recipe = _r, - Multiplier = 1, + Multiplier = (short)_batches, CraftingTimeLeft = t, OneItemCraftTime = t, IsCrafting = _slot == q.Length - 1, @@ -455,11 +484,13 @@ namespace NecromancerTome ItemStack[] input = _st.Te.Input; // 23.10 («вместо камней вплавляет булыжник»): сначала сырьё, у которого нет рецепта (камни, лом), сделанное руками // (булыжник) - только если сырья нет. Раньше - первое подходящее по порядку ячеек. + // 24.10 («работник положил сланец в переплавку в печку»): горючее (нефтяной сланец - сырьё для бензина) не плавится + // вовсе - рецепта у него нет, и раньше оно шло наравне с камнями. foreach ((Vector3i p, TEFeatureStorage box, int k) s in Ordered(_src, g => { ItemClass c = g.itemValue.ItemClass; if (c?.MadeOfMaterial?.ForgeCategory == null || !c.MadeOfMaterial.ForgeCategory.EqualsCaseInsensitive(mat) || - c.GetItemName().StartsWith("unit_")) + c.GetItemName().StartsWith("unit_") || ItemClass.GetFuelValue(g.itemValue) > 0) { return -1; } diff --git a/NecromancerHarmony.dll b/NecromancerHarmony.dll index afc92ba..94a3a40 100644 Binary files a/NecromancerHarmony.dll and b/NecromancerHarmony.dll differ diff --git a/NecromancerHarmony.pdb b/NecromancerHarmony.pdb index 516eb61..3ce8e08 100644 Binary files a/NecromancerHarmony.pdb and b/NecromancerHarmony.pdb differ