necrourn budget [N]: учёт и лимит общего бюджета шагов урн; necrourn info - состояние работы урны

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AlexCube
2026-10-23 16:42:44 +03:00
co-authored by Claude Opus 5.5
parent ecae8eb6a7
commit 054897eb78
4 changed files with 60 additions and 5 deletions
+10 -1
View File
@@ -741,6 +741,15 @@ namespace NecromancerTome
bool _pending;
float _actAt;
/// <summary>Состояние работы для necrourn info (23.10: «стою в 19 м - не работают», проба находит урожай, дела нет).</summary>
public string WorkState()
{
float now = Time.time;
return "дело ждёт " + _pending + (_pending ? " (через " + (_actAt - now).ToString("0.0") + " с)" : "") +
", следующий шаг через " + (_nextWork - now).ToString("0.0") + " с, прилив " + CinerariumLoad.Tide +
", дух " + (_genie != null);
}
/// <summary>Работа духа (CinerariumWork): раз в StepSeconds одно дело, только с черепом и только на сервере.
/// Сначала пробный шаг (ничего не меняет) - куда лететь; само дело - когда дух долетел и машет руками. Если за это
/// время что-то поменялось, настоящий шаг сделает то, что нужно на тот момент.</summary>
@@ -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; // не время или бюджет кадра на дела духов выбран - в следующем кадре
}
+38 -2
View File
@@ -34,18 +34,54 @@ namespace NecromancerTome
}
}
/// <summary>Взять одно дело из бюджета кадра.</summary>
public static bool TryTakeStep()
/// <summary>Взять одно дело из бюджета кадра. _who - урна (учёт для necrourn budget).</summary>
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<Vector3i, int> _granted = new Dictionary<Vector3i, int>();
static readonly Dictionary<Vector3i, int> _denied = new Dictionary<Vector3i, int>();
static float _countSince;
static int _frames0;
static void Count(Dictionary<Vector3i, int> _d, Vector3i _who)
{
_d.TryGetValue(_who, out int n);
_d[_who] = n + 1;
}
/// <summary>Сводка с прошлого вызова и сброс (команда necrourn budget).</summary>
public static string Budget()
{
float sec = Time.time - _countSince;
int frames = Time.frameCount - _frames0;
string s = "за " + sec.ToString("0") + " с, кадров " + frames + ", лимит " + StepsPerFrame + "/кадр; дано:";
foreach (KeyValuePair<Vector3i, int> kv in _granted)
{
s += " " + kv.Key + "=" + kv.Value;
}
s += "; отказано:";
foreach (KeyValuePair<Vector3i, int> kv in _denied)
{
s += " " + kv.Key + "=" + kv.Value;
}
_granted.Clear();
_denied.Clear();
_countSince = Time.time;
_frames0 = Time.frameCount;
return s;
}
/// <summary>Идёт ли кровавый прилив (раз за кадр).</summary>
public static bool Tide
{
+1 -1
View File
@@ -246,7 +246,7 @@ namespace NecromancerTome
{
ScanColumns(_world);
}
if (Time.time < _zoneNext || !CinerariumLoad.TryTakeStep())
if (Time.time < _zoneNext || !CinerariumLoad.TryTakeStep(ToWorldPos()))
{
return;
}
+11 -1
View File
@@ -459,6 +459,16 @@ namespace NecromancerTome
static void Urn(World _w, List<string> _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());
}
}