Ремонтник: сначала то, на что есть материал; ячейка нехватки видна всегда
- Блоки без материалов откладываются (_lacking) и не держат очередь; к ним ремонтник возвращается, когда чинить больше нечего, и чинит, как только материал появился. Зона не останавливается, пока они есть. - Кнопка жёлтая, только когда кроме ждущих чинить нечего; ячейка «не хватает» видна, пока хоть один блок ждёт. - «Запустить» повторно отпускает старые взятые блоки (Claimed) - раньше они не попадали в обход заново. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3d08511e5b
commit
5ebd09dacd
@@ -8,7 +8,8 @@ namespace NecromancerTome
|
||||
/// нужен в данный момент? А то не угадать», «Пусть показывает в виде ячейки с материалом», «И восклицательный знак. Чтобы
|
||||
/// было понятно что именно это требуется»). Ячейка дописана в окно игры windowBagStorage (Config/XUi_InGame/windows.xml)
|
||||
/// под блоком лимита урн: иконка материала, сколько доложить в ящики с нитями, красный «!». Только показ - не ячейка
|
||||
/// сумки, взять из неё нечего. Видна у ремонтника, пока он ждёт материал (TEFeatureCinerarium.LackType/LackCount).
|
||||
/// сумки, взять из неё нечего. Видна у ремонтника, пока хоть один блок ждёт материал (TEFeatureCinerarium.LackType/LackCount) - и когда он чинит
|
||||
/// остальное.
|
||||
/// </summary>
|
||||
[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)
|
||||
{
|
||||
|
||||
@@ -89,6 +89,10 @@ namespace NecromancerTome
|
||||
static readonly HashSet<Vector3i> Claimed = new HashSet<Vector3i>();
|
||||
|
||||
readonly List<Vector3i> _queue = new List<Vector3i>();
|
||||
/// <summary>Ремонтник: блоки, на которые нет материалов (24.10, пользователь: «Если не может починить что-то для чего
|
||||
/// нет ресурсов, пусть сначала чинит то, для чего они есть»). Не держат очередь обхода; к ним - когда больше нечего.</summary>
|
||||
readonly List<Vector3i> _lacking = new List<Vector3i>();
|
||||
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
|
||||
/// <summary>Остановить проход (кнопка, урна убрана): очередь и взятые блоки отпускаются.</summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Очередь и отложенные блоки - отпустить (Claimed) и забыть.</summary>
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Следующий блок: сначала из очереди обхода, на что есть материалы (на что нет - в _lacking), потом из _lacking,
|
||||
/// если материал появился. Нечего чинить, кроме ждущих материала, - кнопка жёлтая. Ячейка «не хватает» в «Содержимом» -
|
||||
/// первый блок из _lacking (LackType/LackCount), пока он есть.</summary>
|
||||
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); // найдётся при следующем обходе
|
||||
}
|
||||
ZoneLacking = false;
|
||||
_zoneTarget = p;
|
||||
FlyThenAct(_world, _motion, p);
|
||||
continue;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user