using System.Collections.Generic;
using UnityEngine;
namespace NecromancerTome
{
///
/// Нюх одержимой зомбособаки (указание 09.10: «добавь зомбособаке отображение противников, как в Тёмном чутье.
/// Типа у собаки нюх»; решено: только в одержимости, чует всех существ). Как Тёмное чутьё змеи
/// (SnakeControl.Sense): раз в секунду существа ближе SenseRange к собаке получают метку на компасе и карте,
/// дальше SenseDropRange, мёртвые и выгруженные её теряют. В отличие от чутья - не только нежить: звери,
/// бандиты, зомби. Не метятся: тело игрока и другие игроки, питомцы мода (призрачные), торговцы.
///
public static class DogSense
{
public const string DogClass = "necroZombieDog";
static readonly HashSet _sensed = new HashSet();
static float _check;
public static bool Is(EntityAlive _e)
{
return _e != null && EntityClass.list.TryGetValue(_e.entityClass, out EntityClass cls) && cls != null &&
cls.entityClassName == DogClass;
}
static bool Smells(EntityAlive _e, EntityAlive _dog)
{
return _e != null && _e != _dog && !_e.IsDead() && !(_e is EntityPlayer) && !(_e is EntityTrader) &&
!SnakeControl.IsNecroEntity(_e) && !GhostTraderPatch.ShouldBeGhost(_e);
}
public static void Tick(World _world, EntityAlive _dog, float _dt)
{
_check -= _dt;
if (_check > 0f)
{
return;
}
_check = 1f;
Vector3 at = _dog.position;
for (int i = 0; i < _world.EntityAlives.Count; i++)
{
EntityAlive e = _world.EntityAlives[i];
if (e == null)
{
continue;
}
float d2 = (e.position - at).sqrMagnitude;
bool smell = Smells(e, _dog);
if (smell && d2 < SnakeControl.SenseRange * SnakeControl.SenseRange)
{
if (_sensed.Add(e.entityId))
{
e.AddNavObject(SnakeControl.SenseNavObject, null, null);
}
}
else if (_sensed.Contains(e.entityId) && (!smell || d2 > SnakeControl.SenseDropRange * SnakeControl.SenseDropRange))
{
e.RemoveNavObject(SnakeControl.SenseNavObject);
_sensed.Remove(e.entityId);
}
}
_sensed.RemoveWhere(id => _world.GetEntity(id) == null);
}
/// Выход из собаки - снять все метки.
public static void Clear()
{
World world = GameManager.Instance?.World;
if (world != null)
{
foreach (int id in _sensed)
{
(world.GetEntity(id) as EntityAlive)?.RemoveNavObject(SnakeControl.SenseNavObject);
}
}
_sensed.Clear();
_check = 0f;
}
}
}