Двери одержимого: блок под прицелом - Voxel.Raycast, как у персонажа (физический луч дверь не видел); только двери, выключатели, лампы, рычаги; лог, если делать нечего

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AlexCube
2026-10-13 17:40:46 +03:00
co-authored by Claude Opus 5.5
parent 9baca33c6f
commit a726b719df
+20 -26
View File
@@ -2168,36 +2168,18 @@ namespace NecromancerTome
{
return false;
}
int n = Physics.RaycastNonAlloc(cam.position, cam.forward, _aimHits, 50f, -5, QueryTriggerInteraction.Ignore);
Transform self = _z.transform;
float best = float.MaxValue;
RaycastHit hit = default;
for (int i = 0; i < n; i++)
{
RaycastHit h = _aimHits[i];
if (h.distance >= best || h.transform == self || h.transform.IsChildOf(self))
{
continue;
}
best = h.distance;
hit = h;
}
if (best == float.MaxValue)
// Блок под прицелом - лучом по сетке блоков, как ищет персонаж (PlayerMoveController: Voxel.Raycast, те же
// маски). Физический луч дверь не видел (тест 13.10: «двери не открываются, даже подсказки нет») - коллайдеры
// дверей не на тех слоях. Луч - с уровня головы зомби по взгляду: от третьего лица камера за спиной.
Vector3 fwd = cam.forward;
Vector3 head = _z.getHeadPosition() - Origin.position;
Vector3 from = cam.position + fwd * Mathf.Max(0f, Vector3.Dot(head - cam.position, fwd));
if (!Voxel.Raycast(_world, new Ray(from, fwd), UseReach, -555266077, 69, 0f))
{
return false;
}
Vector3 at = hit.point + Origin.position;
if ((at - _z.getHeadPosition()).sqrMagnitude > UseReach * UseReach)
{
return false;
}
Vector3i pos = World.worldToBlockPos(at + cam.forward * 0.05f);
Vector3i pos = Voxel.voxelRayHitInfo.hit.blockPos;
BlockValue bv = _world.GetBlock(pos);
if (bv.isair)
{
pos = World.worldToBlockPos(at - cam.forward * 0.05f);
bv = _world.GetBlock(pos);
}
if (bv.ischild)
{
pos += bv.parent;
@@ -2208,6 +2190,12 @@ namespace NecromancerTome
{
return false;
}
// Только двери (функция двери у составного блока) и выключатели, лампы, рычаги - E по ящику остаётся лутом.
bool door = _world.GetTileEntity(pos) is TileEntityComposite tec && tec.GetFeature<TEFeatureDoor>() != null;
if (!door && !(b is BlockSwitch) && !(b is BlockLight) && !(b is BlockActivateSwitch))
{
return false;
}
BlockActivationCommand[] cmds = b.GetBlockActivationCommands(_world, bv, pos, _player);
for (int i = 0; cmds != null && i < cmds.Length; i++)
{
@@ -2219,6 +2207,12 @@ namespace NecromancerTome
Debug.Log("[NecromancerTome] Possession: " + _z.EntityName + " - " + cmds[i].text + " " + b.GetBlockName() + " " + pos);
return true;
}
string list = "";
for (int i = 0; cmds != null && i < cmds.Length; i++)
{
list += " " + cmds[i].text + (cmds[i].enabled ? "" : "(-)");
}
Debug.Log("[NecromancerTome] Possession: E по " + b.GetBlockName() + " " + pos + " - нечего делать, команды:" + list);
return false;
}