Ремонтник: сначала то, на что есть материал; ячейка нехватки видна всегда
- Блоки без материалов откладываются (_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)
|
/// было понятно что именно это требуется»). Ячейка дописана в окно игры windowBagStorage (Config/XUi_InGame/windows.xml)
|
||||||
/// под блоком лимита урн: иконка материала, сколько доложить в ящики с нитями, красный «!». Только показ - не ячейка
|
/// под блоком лимита урн: иконка материала, сколько доложить в ящики с нитями, красный «!». Только показ - не ячейка
|
||||||
/// сумки, взять из неё нечего. Видна у ремонтника, пока он ждёт материал (TEFeatureCinerarium.LackType/LackCount).
|
/// сумки, взять из неё нечего. Видна у ремонтника, пока хоть один блок ждёт материал (TEFeatureCinerarium.LackType/LackCount) - и когда он чинит
|
||||||
|
/// остальное.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Preserve]
|
[Preserve]
|
||||||
public class XUiC_NecroRepairNeed : XUiController
|
public class XUiC_NecroRepairNeed : XUiController
|
||||||
@@ -44,7 +45,7 @@ namespace NecromancerTome
|
|||||||
{
|
{
|
||||||
_nextRefresh = Time.time + 0.5f;
|
_nextRefresh = Time.time + 0.5f;
|
||||||
TEFeatureCinerarium urn = CinerariumContents.Urn;
|
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;
|
ViewComponent.IsVisible = ic != null;
|
||||||
if (ic == null)
|
if (ic == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ namespace NecromancerTome
|
|||||||
static readonly HashSet<Vector3i> Claimed = new HashSet<Vector3i>();
|
static readonly HashSet<Vector3i> Claimed = new HashSet<Vector3i>();
|
||||||
|
|
||||||
readonly List<Vector3i> _queue = new List<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;
|
float _zoneNext;
|
||||||
bool _zonePending;
|
bool _zonePending;
|
||||||
float _zoneActAt;
|
float _zoneActAt;
|
||||||
@@ -175,7 +179,7 @@ namespace NecromancerTome
|
|||||||
ZoneCursor = 0;
|
ZoneCursor = 0;
|
||||||
ZoneLacking = false;
|
ZoneLacking = false;
|
||||||
ZonePressedBy = _player != null ? _player.entityId : -1;
|
ZonePressedBy = _player != null ? _player.entityId : -1;
|
||||||
_queue.Clear();
|
ReleaseClaims();
|
||||||
_lootDone.Clear();
|
_lootDone.Clear();
|
||||||
Audio.Manager.BroadcastPlay(World.blockToTransformPos(ToWorldPos()), "button4");
|
Audio.Manager.BroadcastPlay(World.blockToTransformPos(ToWorldPos()), "button4");
|
||||||
Debug.Log("[NecromancerTome] Cinerarium: " + (IsLooter ? "лутер" : "ремонтник") + " " + ToWorldPos() + " запущен, зона " + ZoneSideNow);
|
Debug.Log("[NecromancerTome] Cinerarium: " + (IsLooter ? "лутер" : "ремонтник") + " " + ToWorldPos() + " запущен, зона " + ZoneSideNow);
|
||||||
@@ -206,11 +210,7 @@ namespace NecromancerTome
|
|||||||
/// <summary>Остановить проход (кнопка, урна убрана): очередь и взятые блоки отпускаются.</summary>
|
/// <summary>Остановить проход (кнопка, урна убрана): очередь и взятые блоки отпускаются.</summary>
|
||||||
public void ZoneStop(bool _log)
|
public void ZoneStop(bool _log)
|
||||||
{
|
{
|
||||||
foreach (Vector3i p in _queue)
|
ReleaseClaims();
|
||||||
{
|
|
||||||
Claimed.Remove(p);
|
|
||||||
}
|
|
||||||
_queue.Clear();
|
|
||||||
_zonePending = false;
|
_zonePending = false;
|
||||||
if (ZoneRunning && _log)
|
if (ZoneRunning && _log)
|
||||||
{
|
{
|
||||||
@@ -220,6 +220,23 @@ namespace NecromancerTome
|
|||||||
ZoneLacking = false;
|
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)
|
void ZoneWork(World _world)
|
||||||
{
|
{
|
||||||
SyncButtons();
|
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 + " обошёл зону - ожидание");
|
Debug.Log("[NecromancerTome] Cinerarium: ремонтник " + c + " обошёл зону - ожидание");
|
||||||
ZoneStop(false);
|
ZoneStop(false);
|
||||||
@@ -334,32 +351,78 @@ namespace NecromancerTome
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Следующий блок: сначала из очереди обхода, на что есть материалы (на что нет - в _lacking), потом из _lacking,
|
||||||
|
/// если материал появился. Нечего чинить, кроме ждущих материала, - кнопка жёлтая. Ячейка «не хватает» в «Содержимом» -
|
||||||
|
/// первый блок из _lacking (LackType/LackCount), пока он есть.</summary>
|
||||||
void RepairPick(World _world, CinerariumGenieMotion _motion)
|
void RepairPick(World _world, CinerariumGenieMotion _motion)
|
||||||
{
|
{
|
||||||
while (_queue.Count > 0)
|
while (_queue.Count > 0)
|
||||||
{
|
{
|
||||||
Vector3i p = _queue[0];
|
Vector3i p = _queue[0];
|
||||||
|
_queue.RemoveAt(0);
|
||||||
BlockValue bv = _world.GetBlock(p);
|
BlockValue bv = _world.GetBlock(p);
|
||||||
if (bv.isair || bv.damage <= 0 || bv.Block?.RepairItems == null)
|
if (bv.isair || bv.damage <= 0 || bv.Block?.RepairItems == null)
|
||||||
{
|
{
|
||||||
_queue.RemoveAt(0);
|
|
||||||
Claimed.Remove(p);
|
Claimed.Remove(p);
|
||||||
continue; // починили до нас или блок убран
|
continue; // починили до нас или блок убран
|
||||||
}
|
}
|
||||||
if (!HasMaterials(_world, bv, false))
|
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;
|
else
|
||||||
return; // ждём: положат в ящик - продолжим с того же блока
|
{
|
||||||
|
Claimed.Remove(p); // найдётся при следующем обходе
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
ZoneLacking = false;
|
Go(_world, _motion, p);
|
||||||
_zoneTarget = p;
|
|
||||||
FlyThenAct(_world, _motion, p);
|
|
||||||
return;
|
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)
|
void RepairNow(World _world, Vector3i _p)
|
||||||
@@ -373,8 +436,7 @@ namespace NecromancerTome
|
|||||||
}
|
}
|
||||||
if (!HasMaterials(_world, bv, true))
|
if (!HasMaterials(_world, bv, true))
|
||||||
{
|
{
|
||||||
ZoneLacking = true;
|
_lacking.Add(_p); // материал забрали, пока дух летел
|
||||||
_queue.Insert(0, _p);
|
|
||||||
Claimed.Add(_p);
|
Claimed.Add(_p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user