Zombie Rework & Polymorph Expansion (#8413)
Co-authored-by: Kara <lunarautomaton6@gmail.com> Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
12
Content.Server/Zombies/ZombieComponent.cs
Normal file
12
Content.Server/Zombies/ZombieComponent.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Content.Server.Zombies
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed class ZombieComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The coefficient of the damage reduction applied when a zombie
|
||||
/// attacks another zombie. longe name
|
||||
/// </summary>
|
||||
public float OtherZombieDamageCoefficient = 0.75f;
|
||||
}
|
||||
}
|
||||
62
Content.Server/Zombies/ZombieSystem.cs
Normal file
62
Content.Server/Zombies/ZombieSystem.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using System.Linq;
|
||||
using Robust.Shared.Random;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Server.Disease.Components;
|
||||
using Content.Server.Drone.Components;
|
||||
using Content.Server.Weapon.Melee;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.MobState.Components;
|
||||
using Content.Server.Disease;
|
||||
|
||||
namespace Content.Server.Zombies
|
||||
{
|
||||
public sealed class ZombieSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly DiseaseSystem _disease = default!;
|
||||
[Dependency] private readonly BloodstreamSystem _bloodstream = default!;
|
||||
[Dependency] private readonly ZombifyOnDeathSystem _zombify = default!;
|
||||
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<ZombieComponent, MeleeHitEvent>(OnMeleeHit);
|
||||
}
|
||||
|
||||
private void OnMeleeHit(EntityUid uid, ZombieComponent component, MeleeHitEvent args)
|
||||
{
|
||||
if (!EntityManager.TryGetComponent<ZombieComponent>(args.User, out var zombieComp))
|
||||
return;
|
||||
|
||||
if (!args.HitEntities.Any())
|
||||
return;
|
||||
|
||||
foreach (EntityUid entity in args.HitEntities)
|
||||
{
|
||||
if (args.User == entity)
|
||||
continue;
|
||||
|
||||
if (!TryComp<MobStateComponent>(entity, out var mobState) || HasComp<DroneComponent>(entity))
|
||||
continue;
|
||||
|
||||
if (_robustRandom.Prob(0.5f) && HasComp<DiseaseCarrierComponent>(entity))
|
||||
_disease.TryAddDisease(entity, "ActiveZombieVirus");
|
||||
|
||||
if (HasComp<ZombieComponent>(entity))
|
||||
args.BonusDamage = args.BaseDamage * zombieComp.OtherZombieDamageCoefficient;
|
||||
|
||||
if ((mobState.IsDead() || mobState.IsCritical())
|
||||
&& !HasComp<ZombieComponent>(entity))
|
||||
{
|
||||
_zombify.ZombifyEntity(entity);
|
||||
args.BonusDamage = -args.BaseDamage;
|
||||
}
|
||||
else if (mobState.IsAlive()) //heals when zombies bite live entities
|
||||
{
|
||||
var healingSolution = new Solution();
|
||||
healingSolution.AddReagent("Bicaridine", 1.00); //if OP, reduce/change chem
|
||||
_bloodstream.TryAddToChemicals(args.User, healingSolution);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
15
Content.Server/Zombies/ZombifyOnDeathComponent.cs
Normal file
15
Content.Server/Zombies/ZombifyOnDeathComponent.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Content.Shared.Weapons.Melee;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
namespace Content.Server.Zombies
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed class ZombifyOnDeathComponent : Component
|
||||
{
|
||||
[DataField("skinColor")]
|
||||
public Color SkinColor = new Color(0.70f, 0.72f, 0.48f, 1);
|
||||
|
||||
[DataField("attackArc", customTypeSerializer: typeof(PrototypeIdSerializer<MeleeWeaponAnimationPrototype>))]
|
||||
public string AttackArc = "claw";
|
||||
}
|
||||
}
|
||||
147
Content.Server/Zombies/ZombifyOnDeathSystem.cs
Normal file
147
Content.Server/Zombies/ZombifyOnDeathSystem.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.MobState.Components;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.CharacterAppearance.Components;
|
||||
using Content.Shared.CharacterAppearance.Systems;
|
||||
using Content.Server.Disease.Components;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Server.Nutrition.Components;
|
||||
using Robust.Shared.Player;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Speech.Components;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Server.CombatMode;
|
||||
using Content.Server.Inventory;
|
||||
using Content.Server.Mind.Components;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Ghost.Roles.Components;
|
||||
using Content.Server.Hands.Components;
|
||||
using Content.Server.Mind.Commands;
|
||||
using Content.Server.Temperature.Components;
|
||||
using Content.Server.Weapon.Melee.Components;
|
||||
using Content.Server.Disease;
|
||||
using Robust.Shared.Containers;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.MobState;
|
||||
|
||||
namespace Content.Server.Zombies
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles zombie propagation and inherent zombie traits
|
||||
/// </summary>
|
||||
public sealed class ZombifyOnDeathSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedHandsSystem _sharedHands = default!;
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly BloodstreamSystem _bloodstream = default!;
|
||||
[Dependency] private readonly ServerInventorySystem _serverInventory = default!;
|
||||
[Dependency] private readonly DamageableSystem _damageable = default!;
|
||||
[Dependency] private readonly DiseaseSystem _disease = default!;
|
||||
[Dependency] private readonly SharedHumanoidAppearanceSystem _sharedHuApp = default!;
|
||||
[Dependency] private readonly IChatManager _chatMan = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ZombifyOnDeathComponent, MobStateChangedEvent>(OnDamageChanged);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles an entity turning into a zombie when they die or go into crit
|
||||
/// </summary>
|
||||
private void OnDamageChanged(EntityUid uid, ZombifyOnDeathComponent component, MobStateChangedEvent args)
|
||||
{
|
||||
if (!TryComp<MobStateComponent>(uid, out var mobstate))
|
||||
return;
|
||||
|
||||
if (mobstate.IsDead() ||
|
||||
mobstate.IsCritical())
|
||||
{
|
||||
ZombifyEntity(uid);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the general purpose function to call if you want to zombify an entity.
|
||||
/// It handles both humanoid and nonhumanoid transformation.
|
||||
/// </summary>
|
||||
/// <param name="target">the entity being zombified</param>
|
||||
public void ZombifyEntity(EntityUid target)
|
||||
{
|
||||
if (HasComp<ZombieComponent>(target))
|
||||
return;
|
||||
|
||||
_disease.CureAllDiseases(target);
|
||||
RemComp<DiseaseCarrierComponent>(target);
|
||||
RemComp<RespiratorComponent>(target);
|
||||
RemComp<BarotraumaComponent>(target);
|
||||
RemComp<HungerComponent>(target);
|
||||
RemComp<ThirstComponent>(target);
|
||||
|
||||
var zombiecomp = EnsureComp<ZombifyOnDeathComponent>(target);
|
||||
if (TryComp<HumanoidAppearanceComponent>(target, out var huApComp))
|
||||
{
|
||||
var appearance = huApComp.Appearance;
|
||||
_sharedHuApp.UpdateAppearance(target, appearance.WithSkinColor(zombiecomp.SkinColor), huApComp);
|
||||
_sharedHuApp.ForceAppearanceUpdate(target, huApComp);
|
||||
}
|
||||
|
||||
if (!HasComp<SharedDummyInputMoverComponent>(target))
|
||||
MakeSentientCommand.MakeSentient(target, EntityManager);
|
||||
|
||||
EnsureComp<ReplacementAccentComponent>(target).Accent = "zombie";
|
||||
|
||||
//funny add delet go brrr
|
||||
RemComp<CombatModeComponent>(target);
|
||||
AddComp<CombatModeComponent>(target);
|
||||
|
||||
var melee = EnsureComp<MeleeWeaponComponent>(target);
|
||||
melee.Arc = zombiecomp.AttackArc;
|
||||
melee.ClickArc = zombiecomp.AttackArc;
|
||||
//lord forgive me for the hardcoded damage
|
||||
DamageSpecifier dspec = new();
|
||||
dspec.DamageDict.Add("Slash", 13);
|
||||
dspec.DamageDict.Add("Piercing", 7);
|
||||
melee.Damage = dspec;
|
||||
|
||||
_damageable.SetDamageModifierSetId(target, "Zombie");
|
||||
_bloodstream.SetBloodLossThreshold(target, 0f);
|
||||
|
||||
_popupSystem.PopupEntity(Loc.GetString("zombie-transform", ("target", target)), target, Filter.Pvs(target));
|
||||
_serverInventory.TryUnequip(target, "gloves", true, true);
|
||||
|
||||
if (TryComp<TemperatureComponent>(target, out var tempComp))
|
||||
tempComp.ColdDamage.ClampMax(0);
|
||||
|
||||
if (TryComp<DamageableComponent>(target, out var damageablecomp))
|
||||
_damageable.SetAllDamage(damageablecomp, 0);
|
||||
|
||||
if (TryComp<MetaDataComponent>(target, out var meta))
|
||||
meta.EntityName = Loc.GetString("zombie-name-prefix", ("target", meta.EntityName));
|
||||
|
||||
var mindcomp = EnsureComp<MindComponent>(target);
|
||||
if (mindcomp.Mind != null && mindcomp.Mind.TryGetSession(out var session))
|
||||
_chatMan.DispatchServerMessage(session, Loc.GetString("zombie-infection-greeting"));
|
||||
|
||||
if (!HasComp<GhostRoleMobSpawnerComponent>(target) && !mindcomp.HasMind) //this specific component gives build test trouble so pop off, ig
|
||||
{
|
||||
EntityManager.EnsureComponent<GhostTakeoverAvailableComponent>(target, out var ghostcomp);
|
||||
ghostcomp.RoleName = Loc.GetString("zombie-generic");
|
||||
ghostcomp.RoleDescription = Loc.GetString("zombie-role-desc");
|
||||
ghostcomp.RoleRules = Loc.GetString("zombie-role-rules");
|
||||
}
|
||||
|
||||
foreach (var hand in _sharedHands.EnumerateHands(target))
|
||||
{
|
||||
_sharedHands.SetActiveHand(target, hand);
|
||||
hand.Container?.EmptyContainer();
|
||||
_sharedHands.RemoveHand(target, hand.Name);
|
||||
}
|
||||
RemComp<HandsComponent>(target);
|
||||
|
||||
EnsureComp<ZombieComponent>(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user