Стиратель снят из кода (наработки отложены для дронов магов)

Подмешивание в орду было выключено 10.10: в кровавый прилив змеи нет, античит
не нужен. Убраны EraserPatch.cs, сущность zombieEraser, бафф свечения, строка
локализации, отброс змеи взрывом и текстуры Resources/Eraser. В выпущенных
версиях Стирателя не было - сейвы игроков не затронуты.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AlexCube
2026-10-12 11:26:04 +03:00
co-authored by Claude Opus 5.5
parent 8b8d1d0feb
commit 47a4b345af
11 changed files with 2 additions and 373 deletions
-1
View File
@@ -323,7 +323,6 @@ Dört modifikasyon yuvasına takılan kan küreleriyle çalışır: küreler sı
以放入四個改裝槽的血之球為燃料:血之球依次消耗,一顆相當於一滿箱。無法用油桶加油。用骨頭修理(每次50根)。 任一槽中放入血石即可永遠滿箱。" 以放入四個改裝槽的血之球為燃料:血之球依次消耗,一顆相當於一滿箱。無法用油桶加油。用骨頭修理(每次50根)。 任一槽中放入血石即可永遠滿箱。"
necroBoneSteedNeedBones,UI,Tooltip,,,,You need {0} bones to repair the Bone Steed.,,"Du brauchst {0} Knochen, um das Knochenross zu reparieren.",Necesitas {0} huesos para reparar el Corcel de hueso.,Il te faut {0} os pour réparer le Destrier d'os.,Servono {0} ossa per riparare il Destriero d'ossa.,骨の駿馬の修理には骨が{0}個必要だ。,뼈 군마를 수리하려면 뼈 {0}개가 필요하다.,Do naprawy Kościanego rumaka potrzeba {0} kości.,Você precisa de {0} ossos para reparar o Corcel de osso.,Для ремонта Костяного скакуна нужно {0} костей.,Kemik Atı onarmak için {0} kemik gerekir.,修理骨骸坐骑需要{0}根骨头。,修理骨骸坐騎需要{0}根骨頭。 necroBoneSteedNeedBones,UI,Tooltip,,,,You need {0} bones to repair the Bone Steed.,,"Du brauchst {0} Knochen, um das Knochenross zu reparieren.",Necesitas {0} huesos para reparar el Corcel de hueso.,Il te faut {0} os pour réparer le Destrier d'os.,Servono {0} ossa per riparare il Destriero d'ossa.,骨の駿馬の修理には骨が{0}個必要だ。,뼈 군마를 수리하려면 뼈 {0}개가 필요하다.,Do naprawy Kościanego rumaka potrzeba {0} kości.,Você precisa de {0} ossos para reparar o Corcel de osso.,Для ремонта Костяного скакуна нужно {0} костей.,Kemik Atı onarmak için {0} kemik gerekir.,修理骨骸坐骑需要{0}根骨头。,修理骨骸坐騎需要{0}根骨頭。
necroBoneSteed,entityclasses,Entity,,,,Bone Steed,,Knochenross,Corcel de hueso,Destrier d'os,Destriero d'ossa,骨の駿馬,뼈 군마,Kościany rumak,Corcel de osso,Костяной скакун,Kemik At,骨骸坐骑,骨骸坐騎 necroBoneSteed,entityclasses,Entity,,,,Bone Steed,,Knochenross,Corcel de hueso,Destrier d'os,Destriero d'ossa,骨の駿馬,뼈 군마,Kościany rumak,Corcel de osso,Костяной скакун,Kemik At,骨骸坐骑,骨骸坐騎
zombieEraser,entityclasses,Entity,,,,Eraser,,Radierer,Borrador,Effaceur,Cancellatore,イレイサー,이레이저,Wymazywacz,Apagador,Стиратель,Silici,抹除者,抹除者
necroRemains,entityclasses,Entity,,,,Remains,,Überreste,Restos,Restes,Resti,遺骸,유해,Szczątki,Restos,Останки,Kalıntılar,遗骸,遺骸 necroRemains,entityclasses,Entity,,,,Remains,,Überreste,Restos,Restes,Resti,遺骸,유해,Szczątki,Restos,Останки,Kalıntılar,遗骸,遺骸
necroMemoryBook,blocks,Block,,,,Book of Memory,,Buch der Erinnerung,Libro de la memoria,Livre de la mémoire,Libro della memoria,記憶の書,기억의 책,Księga pamięci,Livro da memória,Книга памяти,Hafıza Kitabı,记忆之书,記憶之書 necroMemoryBook,blocks,Block,,,,Book of Memory,,Buch der Erinnerung,Libro de la memoria,Livre de la mémoire,Libro della memoria,記憶の書,기억의 책,Księga pamięci,Livro da memória,Книга памяти,Hafıza Kitabı,记忆之书,記憶之書
necroMemoryBookPrompt,blocks,Block,,,,Press {0} to read,,Drücke {0} zum Lesen,Pulsa {0} para leer,Appuyez sur {0} pour lire,Premi {0} per leggere,{0} で読む,{0} 키를 눌러 읽기,"Naciśnij {0}, aby przeczytać",Pressione {0} para ler,"Нажмите {0}, чтобы прочитать",Okumak için {0} tuşuna basın,按 {0} 阅读,按 {0} 閱讀 necroMemoryBookPrompt,blocks,Block,,,,Press {0} to read,,Drücke {0} zum Lesen,Pulsa {0} para leer,Appuyez sur {0} pour lire,Premi {0} per leggere,{0} で読む,{0} 키를 눌러 읽기,"Naciśnij {0}, aby przeczytać",Pressione {0} para ler,"Нажмите {0}, чтобы прочитать",Okumak için {0} tuşuna basın,按 {0} 阅读,按 {0} 閱讀
1 Key File Type UsedInMainMenu NoTranslate KeepLoaded english Context / Alternate Text german spanish french italian japanese koreana polish brazilian russian turkish schinese tchinese
323
324
325
326
327
328
-14
View File
@@ -359,18 +359,4 @@
</append> </append>
<!-- «Стиратель» (02.10.2026): свечение маджента - свободный цвет (у игры зелёный/голубой/огонь,
у мода зелёный, фиолетовый, жёлто-зелёный, бирюзовый). Цвет даёт ParticlePatch.cs (EraserGlow).
Вешается свойством Buffs сущности zombieEraser. -->
<append xpath="/buffs">
<buff name="buffNecroEraser" hidden="true" remove_on_death="false">
<stack_type value="ignore"/>
<duration value="0"/>
<effect_group>
<triggered_effect trigger="onSelfBuffStart" action="AttachParticleEffectToEntity" particle="RadiatedParticlesOnMesh" local_offset="0,0.75,0"/>
<triggered_effect trigger="onSelfBuffRemove" action="RemoveParticleEffectFromEntity" particle="RadiatedParticlesOnMesh"/>
<triggered_effect trigger="onSelfDied" action="RemoveParticleEffectFromEntity" particle="RadiatedParticlesOnMesh"/>
</effect_group>
</buff>
</append>
</config> </config>
+1 -31
View File
@@ -451,38 +451,8 @@
</entity_class> </entity_class>
</append> </append>
<!-- «Стиратель» (02.10.2026, HarmonySrc/EraserPatch.cs): античит к режиму змеи - приходит в орду
кровавой луны игрока-змеи. Маленький, быстрый; взрывается, когда пытается сломать блок или
когда его разрывает змея. Имя НЕ на necro (IsNecroEntity - иначе змея не считает врагом).
Временный вид: тело толстого гавайца по ссылке игры + свечение маджента (buffNecroEraser);
свои вздутия и морда спайдера - потом. -->
<append xpath="/entity_classes"> <append xpath="/entity_classes">
<entity_class name="zombieEraser" extends="zombieFatHawaiian"> <!-- Останки красного трупа (10.10.2026): через 2 минуты (раньше - если игрок ушёл далеко или трупов больше
<property name="UserSpawnType" value="Menu"/>
<property name="Tags" value="entity,zombie,walker,eraser"/>
<property name="SizeScale" value="0.75"/>
<property name="MoveSpeedAggro" value="1.0, 1.6"/>
<!-- Звуки спайдера (указание 02.10) -->
<property name="SoundRandom" value="spiderroam"/>
<property name="SoundAlert" value="spideralert"/>
<property name="SoundAttack" value="spiderattack"/>
<property name="SoundDeath" value="spiderdeath"/>
<property name="SoundHurt" value="spiderpain"/>
<property name="SoundSense" value="spidersense"/>
<property name="SoundStepType" value="barestep"/>
<property name="Buffs" value="zombieBuffStatusCheck01,buffNecroEraser"/>
<property class="Explosion">
<property name="ParticleIndex" value="2"/>
<property name="RadiusBlocks" value="4"/>
<property name="RadiusEntities" value="5"/>
<property name="BlockDamage" value="2500"/>
<property name="EntityDamage" value="300"/>
<property class="DamageBonus">
<property name="earth" value=".1"/>
</property>
</property>
</entity_class>
<!-- Останки красного трупа (10.10.2026): через 2 минуты (раньше - если игрок ушёл далеко или трупов больше
предела) красный труп «Жертвы» истлевает в лёгкий контейнер со своей моделью - остов, обтянутый обугленной предела) красный труп «Жертвы» истлевает в лёгкий контейнер со своей моделью - остов, обтянутый обугленной
плёнкой (бандл necroremains). Лут и остаток срока переходят от трупа (RemainsDecay.cs). Сохраняется с плёнкой (бандл necroremains). Лут и остаток срока переходят от трупа (RemainsDecay.cs). Сохраняется с
участком силами игры, как мешок. TimeStayAfterDeath ставит код (остаток срока трупа). --> участком силами игры, как мешок. TimeStayAfterDeath ставит код (остаток срока трупа). -->
-287
View File
@@ -1,287 +0,0 @@
using HarmonyLib;
using UnityEngine;
namespace NecromancerTome
{
/// <summary>
/// «Стиратель» (указание 02.10) - античит к режиму змеи: если игрок в кровавую луну стал змеёй,
/// в его орде с большой вероятностью приходят Стиратели - маленькие быстрые зомби с
/// нитроглицериновыми вздутиями. Взрываются, когда пытаются сломать блок и когда их разрывает
/// змея; взрыв ломает блоки, ранит тело игрока и соседних зомби, змею не ранит (она бессмертна),
/// а отбрасывает.
///
/// Сущность - zombieEraser (entityclasses.xml): имя НЕ на necro, иначе IsNecroEntity сочтёт её
/// своей и змея перестанет видеть в ней врага. Параметры взрыва - блок Explosion там же,
/// подрыв - как у ванильного EntityZombieCop: ExplosionServer + SetDead.
/// </summary>
public static class EraserPatch
{
public const string EntityClassName = "zombieEraser";
/// <summary>Доля Стирателей в орде игрока-змеи («с большой вероятностью»).</summary>
public const float HordeChance = 0.5f;
/// <summary>Отброс змеи: дальше этого от взрыва змею не задевает.</summary>
public const float KnockRange = 8f;
static int _classId = -1;
public static bool IsEraser(Entity _e)
{
if (_e == null)
{
return false;
}
if (_classId == -1)
{
_classId = EntityClass.FromString(EntityClassName);
}
return _e.entityClass == _classId;
}
static System.Collections.IEnumerator BurstNextFrame(EntityAlive _e)
{
yield return null;
if (_e != null && _e.world != null && _e.world.GetEntity(_e.entityId) != null)
{
NecroBurst.Burst(_e, _e);
}
}
/// <summary>Подрыв на сервере. Возвращает false, если подрывать нечего или не здесь.</summary>
public static bool Explode(EntityAlive _e)
{
if (_e == null || _e.IsDead() || _e.world == null || _e.world.IsRemote())
{
return false;
}
Vector3 pos = _e.GetPosition();
_e.NotifySleeperDeath();
_e.SetModelLayer(2);
GameManager.Instance.ExplosionServer(pos, World.worldToBlockPos(pos), _e.transform.rotation,
EntityClass.list[_e.entityClass].explosionData, _e.entityId, 0f, false);
_e.timeStayAfterDeath = 0;
_e.SetDead();
SnakeControl.Knockback(pos, KnockRange);
// Тела не остаётся (указание 02.10: «после взрыва остаются трупы туристов»): чёрный
// разрыв, как от змеи. Не сразу, а в следующем кадре: подрыв идёт изнутри хода ИИ
// (Attack из задачи), и удаление посреди него роняло EntityAlive.updateTasks (NRE, тест 02.10).
GameManager.Instance.StartCoroutine(BurstNextFrame(_e));
Debug.Log("[NecromancerTome] EraserPatch: Стиратель " + _e.entityId + " взорвался в " + pos);
return true;
}
}
/// <summary>Стиратель упёрся и начинает ломать блок - вместо удара взрыв.</summary>
[HarmonyPatch(typeof(EAIBreakBlock), nameof(EAIBreakBlock.Start))]
public static class Patch_EAIBreakBlock_Start_Eraser
{
public static bool Prefix(EAIBreakBlock __instance)
{
return !(EraserPatch.IsEraser(__instance.theEntity) && EraserPatch.Explode(__instance.theEntity));
}
}
/// <summary>Любая атака Стирателя - по блоку (BreakBlock, DestroyArea) или по цели
/// (ApproachAndAttackTarget) - идёт через EntityAlive.Attack: взрыв вместо удара (тест 02.10:
/// «взрываются не всегда, хотя атакуют»).</summary>
[HarmonyPatch(typeof(EntityAlive), nameof(EntityAlive.Attack))]
public static class Patch_EntityAlive_Attack_Eraser
{
public static bool Prefix(EntityAlive __instance, ref bool __result)
{
if (EraserPatch.IsEraser(__instance) && EraserPatch.Explode(__instance))
{
__result = false;
return false;
}
return true;
}
}
// ОТКЛЮЧЕНО 10.10 (новая концепция кровавой луны - «кровавый прилив», SnakeMode.IsBloodTide): в эту ночь
// дух не выходит из тела, а кто был змеёй - выброшен в тело. Игрока-змеи в орде больше не бывает, и
// античит не нужен. Сущность и её вид (выше и ниже) оставлены - вернуть подмешивание можно, сняв комментарий.
/*
/// <summary>
/// Подмешивание в орду. Ванильный образец - AIDirectorBloodMoonParty.SpawnZombie: игрок в
/// транспорте получает в орду стервятников с шансом 0.5. Класс зомби там берётся из
/// EntityGroups.GetRandomEntityFromGroupMaxTier; на время SpawnZombie запоминаем цель и, если
/// это игрок в режиме змеи, с шансом подменяем результат на Стирателя.
/// Режим змеи - состояние локального игрока (SnakeControl.Controlling), поэтому работает в
/// одиночной игре и у хоста; змея подключённого клиента орду не меняет.
/// </summary>
[HarmonyPatch(typeof(AIDirectorBloodMoonParty), "SpawnZombie")]
public static class Patch_BloodMoonParty_SpawnZombie_Eraser
{
[System.ThreadStatic] public static EntityPlayer Target;
public static void Prefix(EntityPlayer _target)
{
Target = _target;
}
public static void Finalizer()
{
Target = null;
}
}
[HarmonyPatch(typeof(EntityGroups), nameof(EntityGroups.GetRandomEntityFromGroupMaxTier))]
public static class Patch_EntityGroups_GetRandom_Eraser
{
public static void Postfix(ref int __result)
{
EntityPlayer target = Patch_BloodMoonParty_SpawnZombie_Eraser.Target;
if (target == null || __result == -1 || !SnakeControl.Controlling ||
!(target is EntityPlayerLocal) || Random.value >= EraserPatch.HordeChance)
{
return;
}
int id = EntityClass.FromString(EraserPatch.EntityClassName);
if (id != -1 && EntityClass.list.ContainsKey(id))
{
__result = id;
}
}
}
*/
/// <summary>
/// Вид Стирателя (02.10): тело - ванильная модель толстого гавайца (скелет, физика, теги,
/// анимации игры), а раскраска своя. Игра в EModelBase.createModel сама копирует материал тела
/// (ветка MatColor/AltMats); после неё подставляем в материал LOD-рендереров свои текстуры
/// (Resources/Eraser/*.png, нарисованы скриптом по развёртке гавайца): _Albedo, _Normal и _RMOE
/// (шероховатость, металл, затенение, в альфе - маска свечения), свечение - _EmissiveColor.
/// Глаза - отдельные рендереры *Eye* - прячем: на их месте в текстуре чёрные провалы.
/// Ступни босые - пальцы и ногти нарисованы в текстуре (слоновья нога масштабом костей не
/// получилась, 02.10).
/// </summary>
[HarmonyPatch(typeof(EModelBase), nameof(EModelBase.createModel))]
public static class Patch_EModelBase_createModel_EraserLook
{
public static readonly Color Emission = new Color(1f, 0.1f, 0.65f) * 2.5f;
static Texture2D _albedo, _normal, _rmoe;
/// <summary>Своя раскраска на материал тела (только у материалов с _Albedo - тело и куски).</summary>
public static void Paint(Renderer _r)
{
// Сначала смотрим общий материал: обращение к .material создаёт копию, и делать её
// у глаз, огня и прочих рендереров без _Albedo незачем. Если копия уже наша - .material
// вернёт её же, повторной копии не будет. Брошенные копии убирает сама игра
// (GameManager: Resources.UnloadUnusedAssets по таймеру).
Material sm = _r.sharedMaterial;
if (sm == null || !sm.HasProperty("_Albedo") || sm.GetTexture("_Albedo") == _albedo && sm.GetColor("_EmissiveColor") == Emission)
{
return;
}
Material m = _r.material;
if (_albedo != null) m.SetTexture("_Albedo", _albedo);
if (_normal != null) m.SetTexture("_Normal", _normal);
if (_rmoe != null) m.SetTexture("_RMOE", _rmoe);
m.SetColor("_EmissiveColor", Emission);
}
static bool _loaded;
static Texture2D Load(string _file, bool _linear)
{
string path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(typeof(EraserPatch).Assembly.Location), "Resources", "Eraser", _file);
if (!System.IO.File.Exists(path))
{
Debug.LogWarning("[NecromancerTome] EraserLook: нет файла " + path);
return null;
}
Texture2D t = new Texture2D(2, 2, TextureFormat.RGBA32, true, _linear);
if (!ImageConversion.LoadImage(t, System.IO.File.ReadAllBytes(path)))
{
return null;
}
t.name = "Eraser_" + _file;
t.Apply(true, true);
return t;
}
public static void Postfix(EModelBase __instance)
{
Entity e = __instance.entity;
if (!EraserPatch.IsEraser(e))
{
return;
}
if (!_loaded)
{
_loaded = true;
_albedo = Load("eraser_albedo.png", false);
_normal = Load("eraser_normal.png", true);
_rmoe = Load("eraser_rmoe.png", true);
}
foreach (SkinnedMeshRenderer r in __instance.GetComponentsInChildren<SkinnedMeshRenderer>(true))
{
if (r.name.IndexOf("Eye", System.StringComparison.OrdinalIgnoreCase) >= 0)
{
r.enabled = false;
continue;
}
if (!r.CompareTag("LOD"))
{
continue;
}
Paint(r);
}
Debug.Log("[NecromancerTome] EraserLook: вид Стирателя на " + e.entityId);
}
}
/// <summary>
/// Отрубленная конечность (тест 02.10: «если у трупа отрубить руку, он становится туристом»):
/// игра при расчленении подменяет материалы тела и создаёт отлетающий кусок с ванильным
/// материалом гавайца. После RemoveLimb заново красим тело и новые куски.
/// </summary>
[HarmonyPatch(typeof(AvatarZombieController), nameof(AvatarZombieController.RemoveLimb))]
public static class Patch_AvatarZombieController_RemoveLimb_EraserLook
{
public static void Prefix(out int __state)
{
__state = DismembermentManager.Instance?.parts.Count ?? 0;
}
public static void Postfix(AvatarZombieController __instance, int __state)
{
EntityAlive e = Traverse.Create(__instance).Field("entity").GetValue<EntityAlive>();
if (!EraserPatch.IsEraser(e) || e.emodel == null)
{
return;
}
foreach (Renderer r in e.emodel.GetComponentsInChildren<Renderer>(true))
{
Patch_EModelBase_createModel_EraserLook.Paint(r);
}
var parts = DismembermentManager.Instance?.parts;
for (int i = __state; parts != null && i < parts.Count; i++)
{
foreach (Transform t in new[] { parts[i].prefabT, parts[i].detachT })
{
if (t == null) continue;
foreach (Renderer r in t.GetComponentsInChildren<Renderer>(true))
{
Patch_EModelBase_createModel_EraserLook.Paint(r);
}
}
}
}
}
/// <summary>Стиратель убит чем угодно (игроком, взрывом соседа, под бафом жертвы) - чёрный
/// разрыв, трупа не остаётся (указание 02.10). Тот же путь, что у змеи: постфикс ClientKill.</summary>
[HarmonyPatch(typeof(EntityAlive), nameof(EntityAlive.ClientKill))]
public static class Patch_EntityAlive_ClientKill_EraserBurst
{
public static void Postfix(EntityAlive __instance)
{
if (EraserPatch.IsEraser(__instance) && __instance.IsDead() && __instance.world != null &&
__instance.world.GetEntity(__instance.entityId) != null)
{
NecroBurst.Burst(__instance, __instance.entityThatKilledMe != null ? (Entity)__instance.entityThatKilledMe : __instance);
}
}
}
}
+1 -9
View File
@@ -77,9 +77,6 @@ namespace NecromancerTome
/// светятся сильнее обычного; плотнее и крупнее, чем у девиантов.</summary> /// светятся сильнее обычного; плотнее и крупнее, чем у девиантов.</summary>
public static readonly GlowConfig SnakeSightGlow = new GlowConfig { Tint = new Color(1.1f, 1.5f, 0.15f), SizeFactor = 0.4f, AlphaFactor = 1f, DensityFactor = 3f }; public static readonly GlowConfig SnakeSightGlow = new GlowConfig { Tint = new Color(1.1f, 1.5f, 0.15f), SizeFactor = 0.4f, AlphaFactor = 1f, DensityFactor = 3f };
public const string SnakeSightBuffName = "buffNecroSnakeSight"; public const string SnakeSightBuffName = "buffNecroSnakeSight";
/// <summary>«Стиратель» (02.10): маджента - этим цветом зомби больше никто не светится.</summary>
public static readonly GlowConfig EraserGlow = new GlowConfig { Tint = new Color(1f, 0.1f, 0.65f), SizeFactor = 0.4f, AlphaFactor = 1f, DensityFactor = 3f };
public const string EraserBuffName = "buffNecroEraser";
public static readonly GlowConfig PortalChannelGlow = new GlowConfig { Tint = new Color(0.1f, 0.85f, 0.8f), SizeFactor = 0.9f, AlphaFactor = 0.9f, DensityFactor = 5f }; public static readonly GlowConfig PortalChannelGlow = new GlowConfig { Tint = new Color(0.1f, 0.85f, 0.8f), SizeFactor = 0.9f, AlphaFactor = 0.9f, DensityFactor = 5f };
public static void Postfix(MinEventActionAttachParticleEffectToEntity __instance, MinEventParams _params) public static void Postfix(MinEventActionAttachParticleEffectToEntity __instance, MinEventParams _params)
@@ -100,8 +97,7 @@ namespace NecromancerTome
bool isVictim = entity.Buffs.HasBuff(Patch_EntityAlive_dropItemOnDeath_VictimBag.VictimBuffName); bool isVictim = entity.Buffs.HasBuff(Patch_EntityAlive_dropItemOnDeath_VictimBag.VictimBuffName);
bool isCharm = entity.Buffs.HasBuff(Patch_EntityBuffs_AddBuff_DeviatorCharm.CharmBuffName); bool isCharm = entity.Buffs.HasBuff(Patch_EntityBuffs_AddBuff_DeviatorCharm.CharmBuffName);
bool isSnakeSight = entity.Buffs.HasBuff(SnakeSightBuffName); bool isSnakeSight = entity.Buffs.HasBuff(SnakeSightBuffName);
bool isEraser = entity.Buffs.HasBuff(EraserBuffName); if (!isPortalChannel && !isVictim && !isCharm && !isSnakeSight)
if (!isPortalChannel && !isVictim && !isCharm && !isSnakeSight && !isEraser)
{ {
return; return;
} }
@@ -113,10 +109,6 @@ namespace NecromancerTome
{ {
config = PortalChannelGlow; config = PortalChannelGlow;
} }
else if (isEraser)
{
config = EraserGlow;
}
else if (isSnakeSight) else if (isSnakeSight)
{ {
config = SnakeSightGlow; config = SnakeSightGlow;
-31
View File
@@ -464,11 +464,6 @@ namespace NecromancerTome
} }
_pos = target.position - (flat.sqrMagnitude > 0.0001f ? flat.normalized * DashStop : Vector3.zero); _pos = target.position - (flat.sqrMagnitude > 0.0001f ? flat.normalized * DashStop : Vector3.zero);
_dashTarget = null; _dashTarget = null;
// Стиратель от разрыва взрывается; отброс змеи - из EraserPatch.Explode.
if (EraserPatch.IsEraser(target) && EraserPatch.Explode(target))
{
return;
}
_freeze = KillFreeze; _freeze = KillFreeze;
_killId = target.entityId; _killId = target.entityId;
NoLoot.Add(target.entityId); NoLoot.Add(target.entityId);
@@ -485,32 +480,6 @@ namespace NecromancerTome
Debug.Log("[NecromancerTome] SnakeControl: удар по " + target.EntityName + ", " + (target.IsDead() ? "убит" : "ВЫЖИЛ")); Debug.Log("[NecromancerTome] SnakeControl: удар по " + target.EntityName + ", " + (target.IsDead() ? "убит" : "ВЫЖИЛ"));
} }
/// <summary>Из EraserPatch.Explode: змею ближе _range от взрыва отбрасывает прочь и вверх.
/// Не ранит - змея бессмертна.</summary>
public static void Knockback(Vector3 _from, float _range)
{
if (!Controlling)
{
return;
}
Vector3 away = _pos - _from;
if (away.sqrMagnitude > _range * _range)
{
return;
}
away.y = 0f;
if (away.sqrMagnitude < 0.01f)
{
away = Quaternion.Euler(0f, _yaw, 0f) * Vector3.back;
}
_dashTarget = null;
_kick = away.normalized * KickSpeed;
_vy = KickUp;
_airborne = true;
_freeze = 0.6f;
Debug.Log("[NecromancerTome] SnakeControl: отброшена взрывом Стирателя");
}
/// <summary>Из NecroBurst.OnBurst: наш разрыв - запоминаем частицы, чтобы вести их за змеёй.</summary> /// <summary>Из NecroBurst.OnBurst: наш разрыв - запоминаем частицы, чтобы вести их за змеёй.</summary>
public static void OnBurst(EntityAlive _victim, Transform _effect) public static void OnBurst(EntityAlive _victim, Transform _effect)
{ {
Binary file not shown.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 896 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 539 KiB