diff --git a/Content.Server/Zombies/ZombieSystem.Transform.cs b/Content.Server/Zombies/ZombieSystem.Transform.cs index 0a4cd689cea..d8a8d626f7b 100644 --- a/Content.Server/Zombies/ZombieSystem.Transform.cs +++ b/Content.Server/Zombies/ZombieSystem.Transform.cs @@ -186,7 +186,7 @@ public void ZombifyEntity(EntityUid target, MobStateComponent? mobState = null) { { "Slash", 15 }, { "Piercing", 15 }, - { "Structural", 150 } // Sunrise-Edit + { "Structural", 15 } // Sunrise-Edit } }; melee.Damage = dspec; diff --git a/Content.Server/Zombies/ZombieSystem.cs b/Content.Server/Zombies/ZombieSystem.cs index 1f002c76b7a..c20b280c16e 100644 --- a/Content.Server/Zombies/ZombieSystem.cs +++ b/Content.Server/Zombies/ZombieSystem.cs @@ -1,9 +1,11 @@ using System.Linq; +using System.Text.RegularExpressions; // Sunrise using Content.Server.Actions; using Content.Server.Body.Systems; using Content.Server.Chat; using Content.Server.Chat.Systems; using Content.Server.Emoting.Systems; +using Content.Server.Pinpointer; // Sunrise using Content.Server.Speech.EntitySystems; using Content.Shared.Bed.Sleep; using Content.Shared.Cloning; @@ -20,6 +22,7 @@ using Content.Shared.Throwing; using Content.Shared.Weapons.Melee.Events; using Content.Shared.Zombies; +using Robust.Server.GameObjects; // Sunrise using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -44,6 +47,8 @@ public sealed partial class ZombieSystem : SharedZombieSystem [Dependency] private readonly ThrowingSystem _throwing = default!; [Dependency] private readonly ActionsSystem _action = default!; [Dependency] private readonly SharedStunSystem _stun = default!; + [Dependency] private readonly NavMapSystem _navMap = default!; // Sunrise-Zombies + [Dependency] private readonly TransformSystem _transform = default!; // Sunrise-Zombies public const SlotFlags ProtectiveSlots = SlotFlags.FEET | @@ -91,6 +96,9 @@ private void OnThrowDoHit(EntityUid uid, ZombieComponent component, ThrowDoHitEv return; if (!_mobState.IsAlive(args.Target)) return; + if (_timing.CurTime - component.LastThrowHit < component.ThrowHitDelay) + return; + component.LastThrowHit = _timing.CurTime; _stun.TryParalyze(args.Target, TimeSpan.FromSeconds(component.ParalyzeTime), false); _damageable.TryChangeDamage(args.Target, component.Damage, origin: args.Thrown); @@ -101,12 +109,54 @@ private void OnFlair(EntityUid uid, ZombieComponent component, ZombieFlairAction if (args.Handled) return; - _popup.PopupEntity("Мне было лень это делать, напишите админам, пускай скажут вам где выжившие.", - uid, uid, PopupType.LargeCaution); + var zombieXform = Transform(uid); + EntityUid? nearestUid = default!; + TransformComponent? nearestXform = default!; + float? minDistance = null; + var query = AllEntityQuery(); + while (query.MoveNext(out var targetUid, out var humanoidAppearanceComponent)) + { + // Зомби не должны чувствовать тех, у кого иммунитет к ним. + if (HasComp(targetUid) || HasComp(targetUid)) + continue; + var xform = Transform(targetUid); + + // Почему бы и нет, оптимизация наху + var distance = Math.Abs(zombieXform.Coordinates.X - xform.Coordinates.X) + + Math.Abs(zombieXform.Coordinates.Y - xform.Coordinates.Y); + + if (distance > component.MaxFlairDistance) + continue; + + if (minDistance == null || nearestUid == null || minDistance > distance) + { + nearestUid = targetUid; + minDistance = distance; + nearestXform = xform; + } + } + + if (nearestUid == null || nearestUid == default!) + { + _popup.PopupEntity($"Ближайших выживших не найдено.", uid, uid, PopupType.LargeCaution); + } + else + { + _popup.PopupEntity($"Ближайший выживший находится {RemoveColorTags(_navMap.GetNearestBeaconString(nearestUid.Value))}", uid, uid, PopupType.LargeCaution); + } args.Handled = true; } + private string RemoveColorTags(string input) + { + // Регулярное выражение для поиска тэгов [color=...] и [/color] + var pattern = @"\[\s*\/?\s*color(?:=[^\]]*)?\]"; + // Заменяем найденные тэги на пустую строку + var result = Regex.Replace(input, pattern, string.Empty, RegexOptions.IgnoreCase); + return result; + } + private void OnJump(EntityUid uid, ZombieComponent component, ZombieJumpActionEvent args) { if (args.Handled) @@ -125,6 +175,11 @@ private void OnJump(EntityUid uid, ZombieComponent component, ZombieJumpActionEv var mapCoords = args.Target.ToMap(EntityManager); var direction = mapCoords.Position - xform.MapPosition.Position; + if (direction.Length() > component.MaxThrow) + { + direction = direction.Normalized() * component.MaxThrow; + } + _throwing.TryThrow(uid, direction, 7F, uid, 10F); _chatSystem.TryEmoteWithChat(uid, "ZombieGroan"); } diff --git a/Content.Shared/Zombies/ZombieComponent.cs b/Content.Shared/Zombies/ZombieComponent.cs index 6414640574c..1f69f47a8d4 100644 --- a/Content.Shared/Zombies/ZombieComponent.cs +++ b/Content.Shared/Zombies/ZombieComponent.cs @@ -31,7 +31,7 @@ public sealed partial class ZombieComponent : Component public float MinZombieInfectionChance = 0.6f; // Sunrise-Edit [ViewVariables(VVAccess.ReadWrite)] - public float ZombieMovementSpeedBuff = 1.3f; // Sunrise-Edit + public float ZombieMovementSpeedBuff = 1f; // Sunrise-Edit /// /// The skin color of the zombie @@ -100,9 +100,9 @@ public sealed partial class ZombieComponent : Component { DamageDict = new () { - { "Blunt", -2.5 }, // Sunrise-Edit - { "Slash", -2.5 }, // Sunrise-Edit - { "Piercing", -2.5 }, // Sunrise-Edit + { "Blunt", -5 }, // Sunrise-Edit + { "Slash", -5 }, // Sunrise-Edit + { "Piercing", -5 }, // Sunrise-Edit { "Heat", -0.02 }, { "Shock", -0.02 } } @@ -112,7 +112,7 @@ public sealed partial class ZombieComponent : Component /// A multiplier applied to when the entity is in critical condition. /// [DataField("passiveHealingCritMultiplier")] - public float PassiveHealingCritMultiplier = 5f; // Sunrise-Edit + public float PassiveHealingCritMultiplier = 2f; // Sunrise-Edit /// /// Healing given when a zombie bites a living being. @@ -170,5 +170,23 @@ public sealed partial class ZombieComponent : Component { "Slash", 30 }, }, }; + + /// + /// Нельзя пролететь через толпу и всех переубивать + /// + [DataField] + public TimeSpan? LastThrowHit; + + [DataField] + public TimeSpan ThrowHitDelay = TimeSpan.Zero(); + + [DataField] + public float MaxThrow = 10f; + + /// + /// Зомби не должны чувствовать очень далеко. + /// + [DataField] + public float MaxFlairDistance = 500f; // Sunrise-End } diff --git a/Resources/Prototypes/Damage/modifier_sets.yml b/Resources/Prototypes/Damage/modifier_sets.yml index 6f22ea2de95..b6cb089935d 100644 --- a/Resources/Prototypes/Damage/modifier_sets.yml +++ b/Resources/Prototypes/Damage/modifier_sets.yml @@ -198,9 +198,9 @@ - type: damageModifierSet id: Zombie #Blunt resistant and immune to biological threats, but can be hacked apart and burned coefficients: - Blunt: 0.1 - Piercing: 0.1 - Cold: 0.1 + Blunt: 0.2 # Sunrise-edit + Piercing: 0.2 # Surnise-edit + Cold: 0.2 # Sunrise-edit Heat: 1.25 Poison: 0.0 Radiation: 0.0 diff --git a/Resources/Prototypes/Voice/auto_emotes.yml b/Resources/Prototypes/Voice/auto_emotes.yml index 5b136f480ab..bf6752ec209 100644 --- a/Resources/Prototypes/Voice/auto_emotes.yml +++ b/Resources/Prototypes/Voice/auto_emotes.yml @@ -3,7 +3,7 @@ id: ZombieGroan emote: Scream interval: 5.0 - chance: 0.8 # Sunrise-Edit + chance: 0.5 # Sunrise-Edit если ставить меньше, то от спама звуками голова болит withChat: false # Cluwne - type: autoEmote diff --git a/Resources/Prototypes/_Sunrise/Actions/zombie_actions.yml b/Resources/Prototypes/_Sunrise/Actions/zombie_actions.yml index 354a3364db8..3b28af5a0e6 100644 --- a/Resources/Prototypes/_Sunrise/Actions/zombie_actions.yml +++ b/Resources/Prototypes/_Sunrise/Actions/zombie_actions.yml @@ -4,7 +4,7 @@ components: - type: WorldTargetAction useDelay: 15 - icon: _Sunrise/Zombie/Actions/test.png # TODO: Спрайты + icon: _Sunrise/Zombie/Actions/jump.png itemIconStyle: NoItem checkCanAccess: false range: 200 @@ -16,6 +16,6 @@ components: - type: InstantAction useDelay: 15 - icon: _Sunrise/Zombie/Actions/test.png # TODO: Спрайты + icon: _Sunrise/Zombie/Actions/the_look.png itemIconStyle: NoItem event: !type:ZombieFlairActionEvent diff --git a/Resources/Textures/_Sunrise/Zombie/Actions/jump.png b/Resources/Textures/_Sunrise/Zombie/Actions/jump.png new file mode 100644 index 00000000000..500cabba859 Binary files /dev/null and b/Resources/Textures/_Sunrise/Zombie/Actions/jump.png differ diff --git a/Resources/Textures/_Sunrise/Zombie/Actions/the_look.png b/Resources/Textures/_Sunrise/Zombie/Actions/the_look.png new file mode 100644 index 00000000000..2e754462bef Binary files /dev/null and b/Resources/Textures/_Sunrise/Zombie/Actions/the_look.png differ