diff --git a/HarmonySrc/CinerariumCraft.cs b/HarmonySrc/CinerariumCraft.cs index 44d24b4..e9fade0 100644 --- a/HarmonySrc/CinerariumCraft.cs +++ b/HarmonySrc/CinerariumCraft.cs @@ -478,18 +478,23 @@ namespace NecromancerTome _at = null; string mat = _unit.Substring(5); ItemStack[] input = _st.Te.Input; - foreach ((Vector3i p, TEFeatureStorage box) s in _src) + // 23.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_")) + { + return -1; + } + return CraftingManager.GetRecipe(c.GetItemName()) == null ? 0 : 1; + })) { - ItemStack[] grid = s.box.ItemGrid.items; - for (int k = 0; k < grid.Length; k++) { - ItemStack g = grid[k]; - ItemClass ic = g != null && !g.IsEmpty() ? g.itemValue.ItemClass : null; - if (ic == null || ic.MadeOfMaterial?.ForgeCategory == null || !ic.MadeOfMaterial.ForgeCategory.EqualsCaseInsensitive(mat) || - ic.GetItemName().StartsWith("unit_") || CinerariumWork.Locked(s.box, k)) - { - continue; - } + int k = s.k; + ItemStack g = s.box.ItemGrid.items[k]; + ItemClass ic = g.itemValue.ItemClass; for (int i = 0; i < 3 && i < input.Length; i++) { bool empty = input[i] == null || input[i].IsEmpty(); @@ -524,18 +529,53 @@ namespace NecromancerTome static Vector3i? FuelSource(List<(Vector3i p, TEFeatureStorage box)> _src) { + foreach ((Vector3i p, TEFeatureStorage box, int k) s in Ordered(_src, FuelRank)) + { + return s.p; + } + return null; + } + + /// Порядок топлива (23.10: «вместо камней жжёт в печке сланец»): древесина, потом уголь, потом прочее горючее + /// (сланец, бензин - ценное сырьё, только если больше нечего). -1 - не горит. + static int FuelRank(ItemStack _g) + { + if (ItemClass.GetFuelValue(_g.itemValue) <= 0) + { + return -1; + } + string n = _g.itemValue.ItemClass?.GetItemName() ?? ""; + return n.StartsWith("resourceWood") ? 0 : n.StartsWith("resourceCoal") ? 1 : 2; + } + + /// Незакреплённые непустые ячейки ящиков «откуда», у которых _rank >= 0, по возрастанию ранга (при равном - + /// в прежнем порядке ящиков и ячеек). + static List<(Vector3i p, TEFeatureStorage box, int k)> Ordered(List<(Vector3i p, TEFeatureStorage box)> _src, System.Func _rank) + { + List<(Vector3i p, TEFeatureStorage box, int k, int r, int i)> all = new List<(Vector3i, TEFeatureStorage, int, int, int)>(); foreach ((Vector3i p, TEFeatureStorage box) s in _src) { ItemStack[] grid = s.box.ItemGrid.items; for (int k = 0; k < grid.Length; k++) { - if (grid[k] != null && !grid[k].IsEmpty() && ItemClass.GetFuelValue(grid[k].itemValue) > 0 && !CinerariumWork.Locked(s.box, k)) + if (grid[k] == null || grid[k].IsEmpty() || CinerariumWork.Locked(s.box, k)) { - return s.p; + continue; + } + int r = _rank(grid[k]); + if (r >= 0) + { + all.Add((s.p, s.box, k, r, all.Count)); } } } - return null; + all.Sort((a, b) => a.r != b.r ? a.r.CompareTo(b.r) : a.i.CompareTo(b.i)); + List<(Vector3i p, TEFeatureStorage box, int k)> res = new List<(Vector3i, TEFeatureStorage, int)>(all.Count); + foreach (var a in all) + { + res.Add((a.p, a.box, a.k)); + } + return res; } /// Огонь станции с топливом: нет топлива - стопку горючего из ящиков «откуда» (_addFuel), затем зажечь. @@ -548,16 +588,11 @@ namespace NecromancerTome if (_addFuel || _te.BurnTotalTimeLeft <= 0f) { ItemStack[] fuel = _te.Fuel; - foreach ((Vector3i p, TEFeatureStorage box) s in _src) + foreach ((Vector3i p, TEFeatureStorage box, int k) s in Ordered(_src, FuelRank)) { - ItemStack[] grid = s.box.ItemGrid.items; - for (int k = 0; k < grid.Length; k++) { - ItemStack g = grid[k]; - if (g == null || g.IsEmpty() || ItemClass.GetFuelValue(g.itemValue) <= 0 || CinerariumWork.Locked(s.box, k)) - { - continue; - } + int k = s.k; + ItemStack g = s.box.ItemGrid.items[k]; for (int i = 0; i < fuel.Length; i++) { bool empty = fuel[i] == null || fuel[i].IsEmpty();