Урна: дух встаёт у края станции в свободной клетке со стороны урны и смотрит на неё, а не влетает в центр

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AlexCube
2026-10-16 20:11:52 +03:00
co-authored by Claude Opus 5.5
parent d7c80341d2
commit fad57a3756
2 changed files with 52 additions and 6 deletions
+38 -1
View File
@@ -198,10 +198,47 @@ namespace NecromancerTome
{
_pending = true;
_actAt = Time.time + (motion != null ? CinerariumGenieMotion.ActDelay : 0f);
motion?.Visit(World.blockToTransformPos(at.Value) - Origin.position);
if (motion != null)
{
Vector3 look = World.blockToTransformPos(at.Value) - Origin.position;
motion.Visit(Stand(_world, at.Value, out bool beside) - Origin.position, look, beside);
}
}
}
/// <summary>Где духу встать у места работы (16.10: «влетает в станцию в самый центр... логичнее к краю станции с
/// доступной стороны»): из четырёх соседних клеток - свободная (воздух или растение), ближайшая к урне; дух встаёт у
/// её края со стороны места. Свободной нет - над местом. Возвращает низ точки в координатах мира (blockToTransformPos).</summary>
Vector3 Stand(World _world, Vector3i _at, out bool _beside)
{
Vector3i urn = ToWorldPos();
Vector3i best = _at;
int bestD = int.MaxValue;
foreach (Vector3i dir in new[] { Vector3i.forward, Vector3i.back, Vector3i.left, Vector3i.right })
{
Vector3i n = _at + dir;
BlockValue bv = _world.GetBlock(n);
if (!bv.isair && !(bv.Block is BlockPlant))
{
continue;
}
int d = (n.x - urn.x) * (n.x - urn.x) + (n.z - urn.z) * (n.z - urn.z);
if (d < bestD)
{
bestD = d;
best = n;
}
}
_beside = best != _at;
Vector3 at = World.blockToTransformPos(_at);
if (!_beside)
{
return at;
}
Vector3 n0 = World.blockToTransformPos(best);
return Vector3.Lerp(n0, at, 0.2f); // чуть ближе к месту - у самого края
}
// ------------------------------------------------------------------
// Череп.
// ------------------------------------------------------------------