Одержимые зомби открывают двери и щёлкают выключателями по E (питомцы - нет)
Прицел на блок до 3 м от головы - первая доступная команда open/close/light/activate, как E у персонажа; замок двери проверяет сама дверь. Иначе E - как раньше (лут, приёмы). Подсказка - 13 языков. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
a8ee6eb5cf
commit
b50cd6d008
@@ -595,6 +595,12 @@ namespace NecromancerTome
|
||||
// кнопка геймпада (тест 03.10: «подрыва нету»).
|
||||
detonate = input.Activate.WasPressed || input.PermanentActions.Activate.WasPressed;
|
||||
}
|
||||
// E на дверь или выключатель - как у персонажа (указание 13.10: одержимым управляет ГГ - «ему хватает ума не
|
||||
// ломать дверь, которую можно открыть»); у волка и крысы - нет. Прицел не на двери - E как раньше.
|
||||
if (detonate && !IsPet && UseDoorOrSwitch(world, z))
|
||||
{
|
||||
detonate = false;
|
||||
}
|
||||
// Только гуманоиды обычной комплекции (указание 13.10, FpArms.Allows) - у остальных ~/ё ничего не делает.
|
||||
if (input != null && !gui && FpArms.Allows(z) &&
|
||||
(input.CameraChange.WasPressed || input.QuickMenu.WasPressed || input.PermanentActions.QuickMenu.WasPressed))
|
||||
@@ -1592,6 +1598,10 @@ namespace NecromancerTome
|
||||
{
|
||||
text += ", " + Localization.Get("necroPossessHintZombieBag");
|
||||
}
|
||||
if (!IsPet)
|
||||
{
|
||||
text += ", " + Localization.Get("necroPossessHintDoor"); // двери и выключатели (13.10)
|
||||
}
|
||||
if (Flying)
|
||||
{
|
||||
text += ", " + Localization.Get("necroPossessHintFly");
|
||||
@@ -2145,6 +2155,73 @@ namespace NecromancerTome
|
||||
_flyZoomHeld = false;
|
||||
}
|
||||
|
||||
/// <summary>Команды блока, которые одержимый выполняет по E (как первая доступная команда у персонажа): двери
|
||||
/// (TEFeatureDoor - open/close), выключатели и лампы (light), рычаги квестов (activate). Без take, lock, edit,
|
||||
/// trigger. Запертую чужую дверь не откроет - замок проверяет сама дверь.</summary>
|
||||
static readonly string[] UseCommands = { "open", "close", "light", "activate" };
|
||||
public const float UseReach = 3f;
|
||||
|
||||
static bool UseDoorOrSwitch(World _world, EntityAlive _z)
|
||||
{
|
||||
Transform cam = _player?.cameraTransform;
|
||||
if (cam == null || _world == null)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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;
|
||||
bv = _world.GetBlock(pos);
|
||||
}
|
||||
Block b = bv.Block;
|
||||
if (bv.isair || b == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
BlockActivationCommand[] cmds = b.GetBlockActivationCommands(_world, bv, pos, _player);
|
||||
for (int i = 0; cmds != null && i < cmds.Length; i++)
|
||||
{
|
||||
if (!cmds[i].enabled || System.Array.IndexOf(UseCommands, cmds[i].text) < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
b.OnBlockActivated(cmds[i].text, _world, pos, bv, _player);
|
||||
Debug.Log("[NecromancerTome] Possession: " + _z.EntityName + " - " + cmds[i].text + " " + b.GetBlockName() + " " + pos);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>Миг удара рук от первого лица (FpArms): зомби бьёт сразу - его удар начат и сразу «дошёл до точки
|
||||
/// удара» (ForceImpact в EntityAlive.IsAttackImpact, задержка луча ItemActionMelee снята). Урон, дальность,
|
||||
/// цель - его, взгляд - на прицел (MeleeAim).</summary>
|
||||
|
||||
Reference in New Issue
Block a user