Одержимость питомцев, стервятник-разведчик, метки на карте, череп, глава письма

- Одержимость питомца: ПКМ с книгой - вселиться, E - отозвать (и изнутри питомца),
  пояс скрыт, надпись о враге у тела.
- Одержимый стервятник: полёт, рывок на ЛКМ с 10 м с прямым уроном, звуком и
  кровотечением, обычный прицел краснеет на цели; посадка в позу 0 и взлёт на пробел;
  ПКМ - клич-приманка (паникующая курица, откат 0.5 с); F - питаться трупами и
  блоками-падалью, доеденное исчезает.
- Дух змеи атакует только нежить; фиолетовая метка на карте у змеи и одержимого.
- Череп из красного трупа (этап 1 цинерария); глава книги «Письмо архимага» с видео.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AlexCube
2026-10-06 22:09:28 +03:00
co-authored by Claude Opus 5.5
parent a79bb085ab
commit beab1640b0
16 changed files with 1287 additions and 57 deletions
+21 -15
View File
@@ -116,8 +116,7 @@ namespace NecromancerTome
static readonly System.Collections.Generic.Queue<int> _fearQueue = new System.Collections.Generic.Queue<int>();
static readonly System.Collections.Generic.HashSet<int> _fearQueued = new System.Collections.Generic.HashSet<int>();
static float _fearCheck;
public const string SnakeMapNavObject = "necroSnakeSpirit";
static EntityAlive _mapSnake;
static NecroMapMarker.Marker _mapNav;
public const float FearInterval = 0.25f;
/// <summary>Убитые змеёй: с них не падает мешок с добычей (указание 28.09: «в режиме змеи
/// лут не выпадал вообще»). Снимается в патче dropItemOnDeath.</summary>
@@ -180,9 +179,10 @@ namespace NecromancerTome
_fearQueue.Clear();
_fearQueued.Clear();
_fearCheck = 0f;
// Фиолетовая змея на карте (nav_objects.xml, necroSnakeSpirit), указание 02.10.
_snake.AddNavObject(SnakeMapNavObject, null, null);
_mapSnake = _snake;
// Фиолетовая змея на карте (nav_objects.xml, necroSnakeSpirit), указание 02.10. С 06.10 - своя
// метка по Transform (NecroMapMarker): через AddNavObject она так и не показалась.
NecroMapMarker.Hide(ref _mapNav); // старая ссылка после закрытия мира - снимется, только если ещё наша
_mapNav = NecroMapMarker.Show(_snake, "ui_game_symbol_tracking_snake");
Target = null;
_radiationCheck = 0f;
BodyDanger = false;
@@ -248,11 +248,7 @@ namespace NecromancerTome
public static void End()
{
ClearSense();
if (_mapSnake != null)
{
_mapSnake.RemoveNavObject(SnakeMapNavObject);
_mapSnake = null;
}
NecroMapMarker.Hide(ref _mapNav);
_fearQueue.Clear();
_fearQueued.Clear();
Controlling = false;
@@ -432,7 +428,7 @@ namespace NecromancerTome
_fearQueued.Remove(id);
EntityAlive e = _world.GetEntity(id) as EntityAlive;
// Ушёл из чутья, умер, стал своим, началась луна - пропускаем и берём следующего.
if (e == null || bloodMoon || _world.IsRemote() || !IsFoe(e, _snake) ||
if (e == null || bloodMoon || _world.IsRemote() || !IsFoe(e, _snake) || !IsUndead(e) ||
(e.position - _pos).sqrMagnitude > SenseRange * SenseRange)
{
continue;
@@ -598,7 +594,8 @@ namespace NecromancerTome
continue;
}
float d2 = (e.position - _pos).sqrMagnitude;
bool foe = IsFoe(e, _snake);
// Чутьё и ужас - власть над мёртвыми (указание 06.10): только нежить, живых змея не чует и не пугает.
bool foe = IsFoe(e, _snake) && IsUndead(e);
if (foe && d2 < SenseRange * SenseRange)
{
// Только наземные: зомби и звери-зомби. Стервятникам пафайндер не нужен.
@@ -654,6 +651,13 @@ namespace NecromancerTome
!GhostTraderPatch.ShouldBeGhost(_e) && !NecroCharmSide.IsCharmed(_e);
}
/// <summary>Нежить - поднятые мертвецы: всё с меткой zombie (зомби-люди, зомби-собаки, -медведи,
/// -кабаны, стервятники, Стиратель). Живые звери, бандиты, игроки и торговцы - не нежить. Та же
/// метка, по которой считаются убийства в Некромантию (NecromancyKillCreditPatch.ZombieTag).</summary>
static readonly FastTags<TagGroup.Global> UndeadTag = FastTags<TagGroup.Global>.Parse("zombie");
public static bool IsUndead(EntityAlive _e) => _e != null && _e.HasAnyTags(UndeadTag);
/// <summary>Питомцы и змея мода - тоже EntityEnemy (зомби-основа), и без этой проверки
/// охрана выбирала целью самого питомца: он ближе всех к хозяину (тест 30.09, лог
/// «pet 3838 идёт на 3838»). Все наши классы сущностей начинаются с necro.</summary>
@@ -1002,7 +1006,8 @@ namespace NecromancerTome
for (int i = 0; i < _world.EntityAlives.Count; i++)
{
EntityAlive e = _world.EntityAlives[i];
if (!IsFoe(e, _snake))
// Атака духа змеи - только по нежити (указание 06.10): живые звери и люди ей не подвластны.
if (!IsFoe(e, _snake) || !IsUndead(e))
{
continue;
}
@@ -1340,7 +1345,8 @@ namespace NecromancerTome
}
}
/// <summary>Пояс в режиме змеи скрыт (указание 28.09: «прятать оверлей с поясом»). Игра каждый
/// <summary>Пояс в режиме змеи скрыт (указание 28.09: «прятать оверлей с поясом»), так же в
/// чертогах и у одержимого питомца (06.10). Игра каждый
/// кадр в EntityPlayerLocal.OnHUD открывает окно "toolbelt", если оно закрыто, - поэтому не
/// закрываем его раз за разом, а не даём открыться: все Open сходятся в openInternal.</summary>
[HarmonyPatch(typeof(GUIWindowManager), "openInternal")]
@@ -1348,7 +1354,7 @@ namespace NecromancerTome
{
public static bool Prefix(GUIWindow _w)
{
return !((SnakeControl.Controlling || MindControl.Controlling) && _w != null && _w.Id == SnakeControl.ToolbeltWindow);
return !((SnakeControl.Controlling || MindControl.Controlling || (Possession.Active && Possession.IsPet)) && _w != null && _w.Id == SnakeControl.ToolbeltWindow);
}
}