Одержимость: прицел-перекрестие с покраснением, кнопки E/F, лут мешков и багажник волка, медведь на дыбы

- Прицел всех одержимых - всегда перекрестие (свой guiDrawCrosshair: точка бралась из проверки
  камеры от 3-го лица у тела); краснеет на враге: у стервятника - цель рывка, у наземных - враг
  на луче прицела до 30 м, не за стеной
- Падаль: отхил вдвое меньше (EatHealFrac 0.125); ест на F стервятник, медведь, собака, волк и
  одержимые зомби
- E - действие: стервятник - клич (был F), крыса/волк - обыск, медведь - на дыбы (враги до 3.5 м
  сбиты с ног и отброшены, откат 6 с)
- Рёв медведя: надписи «на медведя идут N» и откат, мимо очереди подсказок
- Крыса и волк обыскивают мешки с зомби (EntityLootContainer), волк берёт в сумку
- Багажник волка: окно сумки как у браслета, без рюкзака; выброс - у волка
- Отзыв волка: мешок на месте и метка «Сумка волка» на карте, снимается с мешком
- Тексты на 13 языках

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AlexCube
2026-10-09 13:31:55 +03:00
co-authored by Claude Opus 5.5
parent 31aa99860c
commit e94e967b8e
7 changed files with 572 additions and 55 deletions
+59 -1
View File
@@ -10,7 +10,9 @@ namespace NecromancerTome
/// увести толпу от тела или базы. Та же провокация, что каждую секунду делает одержимость
/// (Possession.Taunt), только шире, без «видит ли» и на 20 с;
/// - удар лапой по блоку: ЛКМ по блоку под прицелом бьёт его на SmashDamage (дерево и двери за 2-3
/// удара, бетон дольше).
/// удара, бетон дольше);
/// - на дыбы на E (указание 09.10: «на E - действие»): враги ближе RearRange сбиты с ног на RearStun с
/// и отброшены от медведя - передышка в толпе. Откат RearCooldown.
/// </summary>
public static class BearControl
{
@@ -25,6 +27,13 @@ namespace NecromancerTome
public const float SmashReach = 2.6f;
public const float SkinFactor = 0.5f;
static float _nextRoar;
public const float RearRange = 3.5f;
public const float RearStun = 2f;
public const float RearCooldown = 6f;
/// <summary>Толчок от медведя, м за тик (как motion существ; гаснет сам).</summary>
public const float RearPush = 0.5f;
public const string RearSound = "bearattack";
static float _nextRear;
public static bool Is(EntityAlive _e)
{
@@ -36,6 +45,8 @@ namespace NecromancerTome
{
if (Time.time < _nextRoar)
{
// Рёв в толпе не отличить от удара (тест 09.10) - пишем, сколько ждать и сколько пошло на медведя.
Tip(string.Format(Localization.Get("necroBearRoarCooldown"), Mathf.CeilToInt(_nextRoar - Time.time)));
return;
}
_nextRoar = Time.time + RoarCooldown;
@@ -59,6 +70,53 @@ namespace NecromancerTome
n++;
}
Debug.Log("[NecromancerTome] BearControl: рёв - на медведя идут " + n);
Tip(string.Format(Localization.Get("necroBearRoarResult"), n));
}
/// <summary>Сразу, мимо очереди подсказок: очередь игры (XUiC_PopupToolTip) отсеивает только одинаковый текст,
/// и «через 7 с», «через 6 с»... при частых ПКМ копились бы и всплывали с опозданием.</summary>
static void Tip(string _text)
{
if (Possession.Player != null)
{
GameManager.ShowTooltip(Possession.Player, _text, true);
}
}
/// <summary>E: на дыбы - враги рядом падают (тот же приём, что у броска волка: BeginStun Prone) и
/// отлетают от медведя.</summary>
public static void RearUp(World _world, EntityAlive _bear)
{
if (Time.time < _nextRear)
{
Tip(string.Format(Localization.Get("necroBearRearCooldown"), Mathf.CeilToInt(_nextRear - Time.time)));
return;
}
_nextRear = Time.time + RearCooldown;
_bear.PlayOneShot(RearSound);
_bear.emodel?.avatarController?.StartAnimationAttack();
int n = 0;
for (int i = 0; i < _world.EntityAlives.Count; i++)
{
EntityAlive e = _world.EntityAlives[i];
if (!SnakeControl.IsFoe(e, _bear) || (e.position - _bear.position).sqrMagnitude > RearRange * RearRange)
{
continue;
}
Vector3 away = e.position - _bear.position;
away.y = 0f;
away = away.sqrMagnitude > 0.01f ? away.normalized : _bear.GetForwardVector();
e.motion += away * RearPush + Vector3.up * 0.15f;
if (e.bodyDamage.CurrentStun == EnumEntityStunType.None && e.emodel?.avatarController != null)
{
e.emodel.avatarController.BeginStun(EnumEntityStunType.Prone, EnumBodyPartHit.Torso, Utils.EnumHitDirection.Back, false, 0.5f);
e.SetStun(EnumEntityStunType.Prone);
e.bodyDamage.StunDuration = RearStun;
}
n++;
}
Tip(string.Format(Localization.Get("necroBearRearResult"), n));
Debug.Log("[NecromancerTome] BearControl: на дыбы - сбиты с ног " + n);
}
/// <summary>ЛКМ: блок под прицелом в досягаемости лапы (не существо) - урон SmashDamage.</summary>