diff --git a/HarmonySrc/Cinerarium.cs b/HarmonySrc/Cinerarium.cs
index d2de829..3da4ed5 100644
--- a/HarmonySrc/Cinerarium.cs
+++ b/HarmonySrc/Cinerarium.cs
@@ -741,6 +741,15 @@ namespace NecromancerTome
bool _pending;
float _actAt;
+ /// Состояние работы для necrourn info (23.10: «стою в 19 м - не работают», проба находит урожай, дела нет).
+ public string WorkState()
+ {
+ float now = Time.time;
+ return "дело ждёт " + _pending + (_pending ? " (через " + (_actAt - now).ToString("0.0") + " с)" : "") +
+ ", следующий шаг через " + (_nextWork - now).ToString("0.0") + " с, прилив " + CinerariumLoad.Tide +
+ ", дух " + (_genie != null);
+ }
+
/// Работа духа (CinerariumWork): раз в StepSeconds одно дело, только с черепом и только на сервере.
/// Сначала пробный шаг (ничего не меняет) - куда лететь; само дело - когда дух долетел и машет руками. Если за это
/// время что-то поменялось, настоящий шаг сделает то, что нужно на тот момент.
@@ -773,7 +782,7 @@ namespace NecromancerTome
_nextWork = Time.time + CinerariumWork.StepSeconds;
return;
}
- if (Time.time < _nextWork || !CinerariumLoad.TryTakeStep())
+ if (Time.time < _nextWork || !CinerariumLoad.TryTakeStep(ToWorldPos()))
{
return; // не время или бюджет кадра на дела духов выбран - в следующем кадре
}
diff --git a/HarmonySrc/CinerariumLoad.cs b/HarmonySrc/CinerariumLoad.cs
index b57cf8e..acdccc4 100644
--- a/HarmonySrc/CinerariumLoad.cs
+++ b/HarmonySrc/CinerariumLoad.cs
@@ -34,18 +34,54 @@ namespace NecromancerTome
}
}
- /// Взять одно дело из бюджета кадра.
- public static bool TryTakeStep()
+ /// Взять одно дело из бюджета кадра. _who - урна (учёт для necrourn budget).
+ public static bool TryTakeStep(Vector3i _who)
{
NewFrame();
if (_used >= StepsPerFrame)
{
+ Count(_denied, _who);
return false;
}
_used++;
+ Count(_granted, _who);
return true;
}
+ // Учёт бюджета (23.10: сборщики 600 с не получили ни одного шага, логист рядом - получал): кому дали, кому отказали.
+ static readonly Dictionary _granted = new Dictionary();
+ static readonly Dictionary _denied = new Dictionary();
+ static float _countSince;
+ static int _frames0;
+
+ static void Count(Dictionary _d, Vector3i _who)
+ {
+ _d.TryGetValue(_who, out int n);
+ _d[_who] = n + 1;
+ }
+
+ /// Сводка с прошлого вызова и сброс (команда necrourn budget).
+ public static string Budget()
+ {
+ float sec = Time.time - _countSince;
+ int frames = Time.frameCount - _frames0;
+ string s = "за " + sec.ToString("0") + " с, кадров " + frames + ", лимит " + StepsPerFrame + "/кадр; дано:";
+ foreach (KeyValuePair kv in _granted)
+ {
+ s += " " + kv.Key + "=" + kv.Value;
+ }
+ s += "; отказано:";
+ foreach (KeyValuePair kv in _denied)
+ {
+ s += " " + kv.Key + "=" + kv.Value;
+ }
+ _granted.Clear();
+ _denied.Clear();
+ _countSince = Time.time;
+ _frames0 = Time.frameCount;
+ return s;
+ }
+
/// Идёт ли кровавый прилив (раз за кадр).
public static bool Tide
{
diff --git a/HarmonySrc/CinerariumZone.cs b/HarmonySrc/CinerariumZone.cs
index 7bfc71b..e295f44 100644
--- a/HarmonySrc/CinerariumZone.cs
+++ b/HarmonySrc/CinerariumZone.cs
@@ -246,7 +246,7 @@ namespace NecromancerTome
{
ScanColumns(_world);
}
- if (Time.time < _zoneNext || !CinerariumLoad.TryTakeStep())
+ if (Time.time < _zoneNext || !CinerariumLoad.TryTakeStep(ToWorldPos()))
{
return;
}
diff --git a/HarmonySrc/NecroDevCommands.cs b/HarmonySrc/NecroDevCommands.cs
index 299dedf..12464ca 100644
--- a/HarmonySrc/NecroDevCommands.cs
+++ b/HarmonySrc/NecroDevCommands.cs
@@ -459,6 +459,16 @@ namespace NecromancerTome
static void Urn(World _w, List _p)
{
+ if (_p.Count > 0 && _p[0] == "budget")
+ {
+ // necrourn budget [N] - кому из урн дали шаг и кому отказали с прошлого вызова; N - лимит дел на кадр (по умолчанию 3)
+ if (_p.Count > 1)
+ {
+ CinerariumLoad.StepsPerFrame = int.Parse(_p[1]);
+ }
+ Out("necrourn budget: " + CinerariumLoad.Budget());
+ return;
+ }
Vector3i pos = P(_p, 0);
TEFeatureCinerarium u = CinerariumThreads.UrnAt(_w, pos);
if (u == null)
@@ -497,7 +507,7 @@ namespace NecromancerTome
}
Out("necrourn: " + pos + " " + _w.GetBlock(pos).Block?.GetBlockName() + ", череп " + u.HasSkull + ", застрял " + u.Stuck + ", мигание " + blink +
", откуда " + u.ThreadFrom.Count + ", куда " + (u.HasThreadTo ? u.ThreadTo.ToString() : "нет") + ", от урны " + u.ThreadOut.Count +
- ", зона " + (u.IsBigZone ? u.ZoneSideNow + (u.ZoneRunning ? " идёт" : " ждёт") + (u.ZoneLacking ? " нехватка" : "") + " курсор " + u.ZoneCursor : "-") + ", образец " + (u.Sample == null || u.Sample.IsEmpty() ? "нет" : u.Sample.itemValue.ItemClass?.GetItemName() + "x" + u.Sample.count));
+ ", зона " + (u.IsBigZone ? u.ZoneSideNow + (u.ZoneRunning ? " идёт" : " ждёт") + (u.ZoneLacking ? " нехватка" : "") + " курсор " + u.ZoneCursor : "-") + ", образец " + (u.Sample == null || u.Sample.IsEmpty() ? "нет" : u.Sample.itemValue.ItemClass?.GetItemName() + "x" + u.Sample.count) + "; " + u.WorkState());
}
}