Ремонтник и лутер: зона из 3x3 квадратов, лишние выключаются (#84)
Сетка «Где работать» в «Содержимом» урны, квадраты очерчены линиями при показе границ; выключенные квадраты обход пропускает. Сохраняется пятым числом v6 (старая DLL его пропустит). Консоль: necrourn x y z sectors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
9a567b6ac0
commit
96d930e5bb
@@ -8,7 +8,8 @@ namespace NecromancerTome
|
||||
/// Урны с большой зоной - ремонтник и лутер (решения 17.10 и 18.10, BACKLOG «Урна ремонтника», «Урна лутера»).
|
||||
///
|
||||
/// Общее. Зона - квадрат со стороной блока притязания (LandClaimSize сервера, по умолчанию 41) или меньше (31/21/11, пункт
|
||||
/// меню «Размер зоны»), по высоте - весь столб мира; зоны таких урн могут пересекаться. Работа - только по кнопке (17.10: «А
|
||||
/// меню «Размер зоны»), по высоте - весь столб мира; делится на 3x3 квадрата, любой можно выключить (#84, ZoneOff); зоны
|
||||
/// таких урн могут пересекаться. Работа - только по кнопке (17.10: «А
|
||||
/// если сделать рубильник или кнопку. Включил, ремонтник начал работу»): «Запустить» - один проход по зоне, конец прохода -
|
||||
/// снова ожидание; до нажатия урна ничего не считает. Кнопки - на самой урне с четырёх сторон («как у дверного звонка, но с
|
||||
/// черепом»), их цвет - состояние (CinerariumButtons): не горят - нет черепа; жёлтая ровно - ожидание; жёлтая мигает - не
|
||||
@@ -123,6 +124,88 @@ namespace NecromancerTome
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Квадраты зоны (28.10, #84, пользователь: «разделить уже имеющуюся зону на 9 квадратов, с цинерарием посередине...
|
||||
/// по умолчанию все 9 были выбраны, но можно было какой-нибудь отключить. Иначе он начинает ремонтировать близстоящие
|
||||
/// здания»): сетка ZoneGrid x ZoneGrid, урна в среднем квадрате. Номер квадрата - столбец + строка * ZoneGrid, столбец 0 -
|
||||
/// запад (меньший x), строка 0 - юг (меньший z). Бит в ZoneOff - квадрат выключен; 0 - все включены. Сохраняется (v6,
|
||||
/// пятое число). Выключать - в «Содержимом» (XUiC_NecroUrnZone) или «necrourn x y z sectors».</summary>
|
||||
public int ZoneOff;
|
||||
public const int ZoneGrid = 3;
|
||||
public const int ZoneSectors = ZoneGrid * ZoneGrid;
|
||||
|
||||
public bool SectorOn(int _s) => (ZoneOff & (1 << _s)) == 0;
|
||||
|
||||
/// <summary>Полоса сетки клетки _i (0..side-1, от западного/южного края зоны).</summary>
|
||||
static int Band(int _i, int _side) => _i * ZoneGrid / _side;
|
||||
|
||||
/// <summary>Первая клетка полосы _k от края зоны; _k = ZoneGrid - сторона зоны.</summary>
|
||||
public static int BandStart(int _k, int _side) => (_k * _side + ZoneGrid - 1) / ZoneGrid;
|
||||
|
||||
/// <summary>Работает ли урна в столбе мира (x, z): в зоне и квадрат включён.</summary>
|
||||
public bool InZone(int _x, int _z)
|
||||
{
|
||||
int side = ZoneSideNow, half = side / 2;
|
||||
Vector3i c = ToWorldPos();
|
||||
int ix = _x - c.x + half, iz = _z - c.z + half;
|
||||
if (ix < 0 || iz < 0 || ix >= side || iz >= side)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return SectorOn(Band(ix, side) + Band(iz, side) * ZoneGrid);
|
||||
}
|
||||
|
||||
/// <summary>Включить/выключить квадрат. Блоки выключенного квадрата, уже взятые в очередь, отпускаются; линии перерисовать.</summary>
|
||||
public void SetZoneOff(int _mask)
|
||||
{
|
||||
ZoneOff = _mask & ((1 << ZoneSectors) - 1);
|
||||
DropOutside(_queue);
|
||||
DropOutside(_lacking);
|
||||
if (_zonePending && IsRepairer && !InZone(_zoneTarget.x, _zoneTarget.z))
|
||||
{
|
||||
_zonePending = false;
|
||||
Claimed.Remove(_zoneTarget);
|
||||
}
|
||||
if (ZoneShown)
|
||||
{
|
||||
RemoveBounds();
|
||||
SpawnBounds();
|
||||
}
|
||||
SetModified();
|
||||
Debug.Log("[NecromancerTome] Cinerarium: урна " + ToWorldPos() + " - квадраты зоны " + SectorsText());
|
||||
}
|
||||
|
||||
public void ToggleSector(int _s) => SetZoneOff(ZoneOff ^ (1 << _s));
|
||||
|
||||
/// <summary>Квадраты строками с севера: «+» включён, «-» выключен (для лога и консоли).</summary>
|
||||
public string SectorsText()
|
||||
{
|
||||
System.Text.StringBuilder sb = new System.Text.StringBuilder();
|
||||
for (int r = ZoneGrid - 1; r >= 0; r--)
|
||||
{
|
||||
for (int col = 0; col < ZoneGrid; col++)
|
||||
{
|
||||
sb.Append(SectorOn(col + r * ZoneGrid) ? '+' : '-');
|
||||
}
|
||||
if (r > 0)
|
||||
{
|
||||
sb.Append('/');
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
void DropOutside(List<Vector3i> _l)
|
||||
{
|
||||
for (int i = _l.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (!InZone(_l[i].x, _l[i].z))
|
||||
{
|
||||
Claimed.Remove(_l[i]);
|
||||
_l.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ButtonState
|
||||
{
|
||||
Off,
|
||||
@@ -317,6 +400,10 @@ namespace NecromancerTome
|
||||
{
|
||||
int x = c.x - half + ZoneCursor % side, z = c.z - half + ZoneCursor / side;
|
||||
ZoneCursor++;
|
||||
if (ZoneOff != 0 && !InZone(x, z))
|
||||
{
|
||||
continue; // квадрат выключен (#84)
|
||||
}
|
||||
if (!(_world.GetChunkFromWorldPos(x, 0, z) is Chunk ch))
|
||||
{
|
||||
continue; // не загружен - пропустить столб
|
||||
@@ -585,7 +672,16 @@ namespace NecromancerTome
|
||||
foreach (Entity e in _ents)
|
||||
{
|
||||
int rank = LootRank(e);
|
||||
if (rank < bestRank && !_lootDone.Contains(e.entityId) && !LockManager.Instance.IsLockedServer(e, 0))
|
||||
if (rank >= bestRank)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Vector3i ep = World.worldToBlockPos(e.GetPosition());
|
||||
if (ZoneOff != 0 && !InZone(ep.x, ep.z))
|
||||
{
|
||||
continue; // квадрат выключен (#84)
|
||||
}
|
||||
if (!_lootDone.Contains(e.entityId) && !LockManager.Instance.IsLockedServer(e, 0))
|
||||
{
|
||||
best = e;
|
||||
bestRank = rank;
|
||||
|
||||
Reference in New Issue
Block a user