Цинерарий-старатель (#64): дух добывает ископаемые

Урна necroCinerariumProspector (и ...Skull): в «Содержимом» череп и образец - один из девяти ресурсов (камень, глина,
песок, древесина, железо, свинец, уголь, селитра, сланец), нить к ящику. Дух отлетает на соседнюю свободную клетку и
уходит на 5 блоков под землю, растворяясь; раз в игровой час поднимается так же, кладёт добычу в ящик и уходит снова.
За сутки: камень/глина/песок/древесина 30000, руды 18000, ходка ±20%. Из руды - шанс на алмаз, серебро, золото по
шансам игры на каждый «блок» руды. Ящик полон - дух ждёт с добычей. Без зоны и вне лимита урн.

Рецепт - кузня: латунь 40, прах 100, кости 10, кровь/сок, железная кирка; открывается с остальными урнами.
Консоль necroprospector: on/off, trip, yield, spread, depth, состояние. Тексты - 13 языков; глава книги
«Цинерарии» - лист Fig. VIII с шестой урной и фраза про prospektisto.

Проверено в игре (test8): ходка железа 625 в ящике, спуск и подъём духа, лист и страница книги помещаются.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AlexCube
2026-10-22 11:09:12 +03:00
co-authored by Claude Opus 5.5
parent f1010f98b7
commit 0999fd3afc
12 changed files with 760 additions and 17 deletions
+20 -8
View File
@@ -64,7 +64,7 @@ namespace NecromancerTome
/// <summary>Урна без зоны 5x5 (логист, рабочий, ремонтник, лутер): ставится вплотную к любым урнам, в лимит не входит,
/// работает по нитям. У ремонтника и лутера своя большая зона (CinerariumZone.cs) - зоны таких урн могут пересекаться.</summary>
public static bool IsZonelessBlock(Block _b) => IsLogistBlock(_b) || IsWorkerBlock(_b) || IsRepairBlock(_b) || IsLootBlock(_b);
public static bool IsZonelessBlock(Block _b) => IsLogistBlock(_b) || IsWorkerBlock(_b) || IsRepairBlock(_b) || IsLootBlock(_b) || IsProspectorBlock(_b);
public const string SkullItemName = "necroSkull";
public const int HalfWidth = 2;
public const int Below = 1;
@@ -103,7 +103,7 @@ namespace NecromancerTome
}
}
bool _worker;
public bool IsZoneless => IsLogist || IsWorker || IsBigZone;
public bool IsZoneless => IsLogist || IsWorker || IsBigZone || IsProspector;
/// <summary>Урна-логист - по блоку (necroCinerariumLogist / ...Skull); узнаётся при постановке или по миру.</summary>
public bool IsLogist
{
@@ -119,6 +119,7 @@ namespace NecromancerTome
_worker = IsWorkerBlock(bv.Block);
_repair = IsRepairBlock(bv.Block);
_loot = IsLootBlock(bv.Block);
_prospector = IsProspectorBlock(bv.Block);
_logistKnown = true;
}
}
@@ -168,16 +169,17 @@ namespace NecromancerTome
_worker = IsWorkerBlock(_blockValue.Block);
_repair = IsRepairBlock(_blockValue.Block);
_loot = IsLootBlock(_blockValue.Block);
_prospector = IsProspectorBlock(_blockValue.Block);
_logistKnown = true;
string placed = _blockValue.Block?.GetBlockName();
if (placed == SkullBlockName || placed == LogistSkullBlockName || placed == LogistWallSkullBlockName || placed == WorkerSkullBlockName ||
placed == RepairSkullBlockName || placed == LootSkullBlockName)
placed == RepairSkullBlockName || placed == LootSkullBlockName || placed == ProspectorSkullBlockName)
{
HasSkull = true; // поставили урну, поднятую с черепом
}
if (ConnectionManager.Instance.IsServer)
{
CinerariumRegistry.Add(_blockPos, Parent?.Owner, _logist || _worker || _repair || _loot);
CinerariumRegistry.Add(_blockPos, Parent?.Owner, _logist || _worker || _repair || _loot || _prospector);
}
}
@@ -190,6 +192,7 @@ namespace NecromancerTome
RemoveGenie(false);
CinerariumContents.CloseIfShowing(this);
ZoneStop(false);
ProspectorReset();
if (!ConnectionManager.Instance.IsServer)
{
return;
@@ -224,6 +227,7 @@ namespace NecromancerTome
_threadsDirty = true; // чанк вернётся - нити построить заново
RemoveGenie(false);
CinerariumContents.CloseIfShowing(this);
ProspectorReset();
}
public override void Write(PooledBinaryWriter _bw, StreamModeWrite _eStreamMode)
@@ -447,7 +451,7 @@ namespace NecromancerTome
base.GetActivationText(_world, _blockPos, _blockValue, _entityFocusing, _activateHotkeyMarkup, _focusedTileEntityName);
string s = _activateHotkeyMarkup + " " + _blockValue.Block.GetLocalizedBlockName() + " - " +
Localization.Get(HasSkull ? "necroCinerariumStateSkull" : "necroCinerariumStateEmpty");
return IsBigZone ? s + ZoneStateText() : s;
return IsBigZone ? s + ZoneStateText() : IsProspector ? s + ProspectorStateText(_world as World) : s;
}
public override void UpdateTick(World _world)
@@ -752,6 +756,11 @@ namespace NecromancerTome
ZoneWork(_world); // ремонтник, лутер - CinerariumZone.cs
return;
}
if (IsProspector)
{
ProspectorWork(_world); // старатель - CinerariumProspector.cs
return;
}
CinerariumGenieMotion motion = _genie != null ? _genie.GetComponent<CinerariumGenieMotion>() : null;
if (_pending)
{
@@ -929,7 +938,7 @@ namespace NecromancerTome
logist = w != null && IsLogistWallBlock(w.GetBlock(ToWorldPos()).Block) ? 2 : 1;
}
_genie = CinerariumGenie.Spawn(ModelTransform(), IsWorker ? CinerariumGenie.WorkerDrop : 0f, logist);
if (_genie != null && IsLooter)
if (_genie != null && (IsLooter || IsProspector)) // старатель - на банке лутера
{
_genie.GetComponent<CinerariumGenieMotion>().ForwardOverride = CinerariumGenie.LootForward;
}
@@ -1089,7 +1098,7 @@ namespace NecromancerTome
string n = _b?.GetBlockName();
return n == BlockName || n == SkullBlockName || n == LogistBlockName || n == LogistSkullBlockName ||
n == LogistWallBlockName || n == LogistWallSkullBlockName || n == WorkerBlockName || n == WorkerSkullBlockName ||
IsRepairBlock(_b) || IsLootBlock(_b);
IsRepairBlock(_b) || IsLootBlock(_b) || IsProspectorBlock(_b);
}
public static int UrnLimit(EntityPlayer _player)
@@ -1486,7 +1495,10 @@ namespace NecromancerTome
bool worker = TEFeatureCinerarium.IsWorkerBlock(bv.Block);
bool repairUrn = TEFeatureCinerarium.IsRepairBlock(bv.Block);
bool lootUrn = TEFeatureCinerarium.IsLootBlock(bv.Block);
ItemValue iv = ItemClass.GetItem(repairUrn
bool prospector = TEFeatureCinerarium.IsProspectorBlock(bv.Block);
ItemValue iv = ItemClass.GetItem(prospector
? (urn.HasSkull ? TEFeatureCinerarium.ProspectorSkullBlockName : TEFeatureCinerarium.ProspectorBlockName)
: repairUrn
? (urn.HasSkull ? TEFeatureCinerarium.RepairSkullBlockName : TEFeatureCinerarium.RepairBlockName)
: lootUrn
? (urn.HasSkull ? TEFeatureCinerarium.LootSkullBlockName : TEFeatureCinerarium.LootBlockName)