diff --git a/HarmonySrc/CinerariumRepairNeed.cs b/HarmonySrc/CinerariumRepairNeed.cs index ba1977b..7da45c4 100644 --- a/HarmonySrc/CinerariumRepairNeed.cs +++ b/HarmonySrc/CinerariumRepairNeed.cs @@ -8,7 +8,8 @@ namespace NecromancerTome /// нужен в данный момент? А то не угадать», «Пусть показывает в виде ячейки с материалом», «И восклицательный знак. Чтобы /// было понятно что именно это требуется»). Ячейка дописана в окно игры windowBagStorage (Config/XUi_InGame/windows.xml) /// под блоком лимита урн: иконка материала, сколько доложить в ящики с нитями, красный «!». Только показ - не ячейка - /// сумки, взять из неё нечего. Видна у ремонтника, пока он ждёт материал (TEFeatureCinerarium.LackType/LackCount). + /// сумки, взять из неё нечего. Видна у ремонтника, пока хоть один блок ждёт материал (TEFeatureCinerarium.LackType/LackCount) - и когда он чинит + /// остальное. /// [Preserve] public class XUiC_NecroRepairNeed : XUiController @@ -44,7 +45,7 @@ namespace NecromancerTome { _nextRefresh = Time.time + 0.5f; TEFeatureCinerarium urn = CinerariumContents.Urn; - ItemClass ic = urn != null && urn.IsRepairer && urn.ZoneLacking && urn.LackType > 0 ? ItemClass.GetForId(urn.LackType) : null; + ItemClass ic = urn != null && urn.IsRepairer && urn.LackType > 0 ? ItemClass.GetForId(urn.LackType) : null; ViewComponent.IsVisible = ic != null; if (ic == null) { diff --git a/HarmonySrc/CinerariumZone.cs b/HarmonySrc/CinerariumZone.cs index 36fa1e7..092665a 100644 --- a/HarmonySrc/CinerariumZone.cs +++ b/HarmonySrc/CinerariumZone.cs @@ -89,6 +89,10 @@ namespace NecromancerTome static readonly HashSet Claimed = new HashSet(); readonly List _queue = new List(); + /// Ремонтник: блоки, на которые нет материалов (24.10, пользователь: «Если не может починить что-то для чего + /// нет ресурсов, пусть сначала чинит то, для чего они есть»). Не держат очередь обхода; к ним - когда больше нечего. + readonly List _lacking = new List(); + const int LackingMax = 256; float _zoneNext; bool _zonePending; float _zoneActAt; @@ -175,7 +179,7 @@ namespace NecromancerTome ZoneCursor = 0; ZoneLacking = false; ZonePressedBy = _player != null ? _player.entityId : -1; - _queue.Clear(); + ReleaseClaims(); _lootDone.Clear(); Audio.Manager.BroadcastPlay(World.blockToTransformPos(ToWorldPos()), "button4"); Debug.Log("[NecromancerTome] Cinerarium: " + (IsLooter ? "лутер" : "ремонтник") + " " + ToWorldPos() + " запущен, зона " + ZoneSideNow); @@ -206,11 +210,7 @@ namespace NecromancerTome /// Остановить проход (кнопка, урна убрана): очередь и взятые блоки отпускаются. public void ZoneStop(bool _log) { - foreach (Vector3i p in _queue) - { - Claimed.Remove(p); - } - _queue.Clear(); + ReleaseClaims(); _zonePending = false; if (ZoneRunning && _log) { @@ -220,6 +220,23 @@ namespace NecromancerTome ZoneLacking = false; } + /// Очередь и отложенные блоки - отпустить (Claimed) и забыть. + void ReleaseClaims() + { + foreach (Vector3i p in _queue) + { + Claimed.Remove(p); + } + foreach (Vector3i p in _lacking) + { + Claimed.Remove(p); + } + _queue.Clear(); + _lacking.Clear(); + LackType = 0; + LackCount = 0; + } + void ZoneWork(World _world) { SyncButtons(); @@ -326,7 +343,7 @@ namespace NecromancerTome } } } - if (ZoneCursor >= total && _queue.Count == 0 && !_zonePending) + if (ZoneCursor >= total && _queue.Count == 0 && _lacking.Count == 0 && !_zonePending) { Debug.Log("[NecromancerTome] Cinerarium: ремонтник " + c + " обошёл зону - ожидание"); ZoneStop(false); @@ -334,32 +351,78 @@ namespace NecromancerTome } } + /// Следующий блок: сначала из очереди обхода, на что есть материалы (на что нет - в _lacking), потом из _lacking, + /// если материал появился. Нечего чинить, кроме ждущих материала, - кнопка жёлтая. Ячейка «не хватает» в «Содержимом» - + /// первый блок из _lacking (LackType/LackCount), пока он есть. void RepairPick(World _world, CinerariumGenieMotion _motion) { while (_queue.Count > 0) { Vector3i p = _queue[0]; + _queue.RemoveAt(0); BlockValue bv = _world.GetBlock(p); if (bv.isair || bv.damage <= 0 || bv.Block?.RepairItems == null) { - _queue.RemoveAt(0); Claimed.Remove(p); continue; // починили до нас или блок убран } if (!HasMaterials(_world, bv, false)) { - if (!ZoneLacking) + if (_lacking.Count < LackingMax) { - Debug.Log("[NecromancerTome] Cinerarium: ремонтнику " + ToWorldPos() + " не хватает материалов для " + bv.Block.GetBlockName() + " в " + p); + _lacking.Add(p); } - ZoneLacking = true; - return; // ждём: положат в ящик - продолжим с того же блока + else + { + Claimed.Remove(p); // найдётся при следующем обходе + } + continue; } - ZoneLacking = false; - _zoneTarget = p; - FlyThenAct(_world, _motion, p); + Go(_world, _motion, p); return; } + int lackType = 0, lackCount = 0; + for (int i = 0; i < _lacking.Count; i++) + { + Vector3i p = _lacking[i]; + BlockValue bv = _world.GetBlock(p); + if (bv.isair || bv.damage <= 0 || bv.Block?.RepairItems == null) + { + _lacking.RemoveAt(i--); + Claimed.Remove(p); + continue; + } + if (HasMaterials(_world, bv, false)) + { + _lacking.RemoveAt(i); + Go(_world, _motion, p); + LackType = lackType; + LackCount = lackCount; + return; + } + if (lackType == 0) + { + lackType = LackType; + lackCount = LackCount; + } + } + LackType = lackType; + LackCount = lackCount; + bool stuck = _lacking.Count > 0; + if (stuck && !ZoneLacking) + { + ItemClass ic = ItemClass.GetForId(LackType); + Debug.Log("[NecromancerTome] Cinerarium: ремонтнику " + ToWorldPos() + " нечего чинить без материалов: ждут " + _lacking.Count + + " блок(ов), первым не хватает " + LackCount + " " + ic?.GetItemName()); + } + ZoneLacking = stuck; + } + + void Go(World _world, CinerariumGenieMotion _motion, Vector3i _p) + { + ZoneLacking = false; + _zoneTarget = _p; + FlyThenAct(_world, _motion, _p); } void RepairNow(World _world, Vector3i _p) @@ -373,8 +436,7 @@ namespace NecromancerTome } if (!HasMaterials(_world, bv, true)) { - ZoneLacking = true; - _queue.Insert(0, _p); + _lacking.Add(_p); // материал забрали, пока дух летел Claimed.Add(_p); return; } diff --git a/NecromancerHarmony.dll b/NecromancerHarmony.dll index 8164cba..fc8e4ad 100644 Binary files a/NecromancerHarmony.dll and b/NecromancerHarmony.dll differ diff --git a/NecromancerHarmony.pdb b/NecromancerHarmony.pdb index 1f00886..d6dc41c 100644 Binary files a/NecromancerHarmony.pdb and b/NecromancerHarmony.pdb differ