Zombie cloning fix (#12520)
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
using Content.Server.Administration.Logs;
|
||||||
using Content.Server.Medical.Components;
|
using Content.Server.Medical.Components;
|
||||||
using Content.Server.Cloning.Components;
|
using Content.Server.Cloning.Components;
|
||||||
using Content.Server.MachineLinking.Components;
|
using Content.Server.MachineLinking.Components;
|
||||||
@@ -13,6 +15,7 @@ using Robust.Server.GameObjects;
|
|||||||
using Robust.Server.Player;
|
using Robust.Server.Player;
|
||||||
using Content.Shared.Cloning.CloningConsole;
|
using Content.Shared.Cloning.CloningConsole;
|
||||||
using Content.Shared.Cloning;
|
using Content.Shared.Cloning;
|
||||||
|
using Content.Shared.Database;
|
||||||
using Content.Shared.MachineLinking.Events;
|
using Content.Shared.MachineLinking.Events;
|
||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
using Content.Shared.Mobs.Components;
|
using Content.Shared.Mobs.Components;
|
||||||
@@ -24,6 +27,7 @@ namespace Content.Server.Cloning
|
|||||||
public sealed class CloningConsoleSystem : EntitySystem
|
public sealed class CloningConsoleSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly SignalLinkerSystem _signalSystem = default!;
|
[Dependency] private readonly SignalLinkerSystem _signalSystem = default!;
|
||||||
|
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||||
[Dependency] private readonly CloningSystem _cloningSystem = default!;
|
[Dependency] private readonly CloningSystem _cloningSystem = default!;
|
||||||
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
||||||
@@ -168,7 +172,8 @@ namespace Content.Server.Cloning
|
|||||||
if (mind == null || mind.UserId.HasValue == false || mind.Session == null)
|
if (mind == null || mind.UserId.HasValue == false || mind.Session == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_cloningSystem.TryCloning(cloningPodUid, body.Value, mind, cloningPod, scannerComp.CloningFailChanceMultiplier);
|
if (_cloningSystem.TryCloning(cloningPodUid, body.Value, mind, cloningPod, scannerComp.CloningFailChanceMultiplier))
|
||||||
|
_adminLogger.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(uid)} successfully cloned {ToPrettyString(body.Value)}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RecheckConnections(EntityUid console, EntityUid? cloningPod, EntityUid? scanner, CloningConsoleComponent? consoleComp = null)
|
public void RecheckConnections(EntityUid console, EntityUid? cloningPod, EntityUid? scanner, CloningConsoleComponent? consoleComp = null)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ using Content.Server.Stack;
|
|||||||
using Content.Server.Jobs;
|
using Content.Server.Jobs;
|
||||||
using Content.Shared.Humanoid;
|
using Content.Shared.Humanoid;
|
||||||
using Content.Shared.Humanoid.Prototypes;
|
using Content.Shared.Humanoid.Prototypes;
|
||||||
|
using Content.Shared.Zombies;
|
||||||
using Content.Shared.Mobs.Systems;
|
using Content.Shared.Mobs.Systems;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.Containers;
|
using Robust.Server.Containers;
|
||||||
@@ -220,6 +221,10 @@ namespace Content.Server.Cloning
|
|||||||
var mob = Spawn(speciesPrototype.Prototype, Transform(clonePod.Owner).MapPosition);
|
var mob = Spawn(speciesPrototype.Prototype, Transform(clonePod.Owner).MapPosition);
|
||||||
_humanoidSystem.CloneAppearance(bodyToClone, mob);
|
_humanoidSystem.CloneAppearance(bodyToClone, mob);
|
||||||
|
|
||||||
|
var ev = new CloningEvent(bodyToClone, mob);
|
||||||
|
RaiseLocalEvent(bodyToClone, ref ev);
|
||||||
|
|
||||||
|
if (!ev.NameHandled)
|
||||||
MetaData(mob).EntityName = MetaData(bodyToClone).EntityName;
|
MetaData(mob).EntityName = MetaData(bodyToClone).EntityName;
|
||||||
|
|
||||||
var cloneMindReturn = EntityManager.AddComponent<BeingClonedComponent>(mob);
|
var cloneMindReturn = EntityManager.AddComponent<BeingClonedComponent>(mob);
|
||||||
@@ -323,4 +328,21 @@ namespace Content.Server.Cloning
|
|||||||
ClonesWaitingForMind.Clear();
|
ClonesWaitingForMind.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised after a new mob got spawned when cloning a humanoid
|
||||||
|
/// </summary>
|
||||||
|
[ByRefEvent]
|
||||||
|
public struct CloningEvent
|
||||||
|
{
|
||||||
|
public bool NameHandled = false;
|
||||||
|
|
||||||
|
public readonly EntityUid Source;
|
||||||
|
public readonly EntityUid Target;
|
||||||
|
|
||||||
|
public CloningEvent(EntityUid source, EntityUid target) {
|
||||||
|
Source = source;
|
||||||
|
Target = target;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.Body.Systems;
|
using Content.Server.Body.Systems;
|
||||||
using Content.Server.Chat.Systems;
|
using Content.Server.Chat.Systems;
|
||||||
|
using Content.Server.Cloning;
|
||||||
using Content.Server.Disease;
|
using Content.Server.Disease;
|
||||||
using Content.Server.Disease.Components;
|
using Content.Server.Disease.Components;
|
||||||
using Content.Server.Drone.Components;
|
using Content.Server.Drone.Components;
|
||||||
|
using Content.Server.Humanoid;
|
||||||
using Content.Server.Inventory;
|
using Content.Server.Inventory;
|
||||||
using Content.Server.Speech;
|
using Content.Server.Speech;
|
||||||
using Content.Shared.Bed.Sleep;
|
using Content.Shared.Bed.Sleep;
|
||||||
@@ -32,6 +34,7 @@ namespace Content.Server.Zombies
|
|||||||
[Dependency] private readonly ChatSystem _chat = default!;
|
[Dependency] private readonly ChatSystem _chat = default!;
|
||||||
[Dependency] private readonly IPrototypeManager _protoManager = default!;
|
[Dependency] private readonly IPrototypeManager _protoManager = default!;
|
||||||
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
||||||
|
[Dependency] private readonly HumanoidSystem _humanoidSystem = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -39,6 +42,7 @@ namespace Content.Server.Zombies
|
|||||||
|
|
||||||
SubscribeLocalEvent<ZombieComponent, MeleeHitEvent>(OnMeleeHit);
|
SubscribeLocalEvent<ZombieComponent, MeleeHitEvent>(OnMeleeHit);
|
||||||
SubscribeLocalEvent<ZombieComponent, MobStateChangedEvent>(OnMobState);
|
SubscribeLocalEvent<ZombieComponent, MobStateChangedEvent>(OnMobState);
|
||||||
|
SubscribeLocalEvent<ZombieComponent, CloningEvent>(OnZombieCloning);
|
||||||
SubscribeLocalEvent<ActiveZombieComponent, DamageChangedEvent>(OnDamage);
|
SubscribeLocalEvent<ActiveZombieComponent, DamageChangedEvent>(OnDamage);
|
||||||
SubscribeLocalEvent<ActiveZombieComponent, AttemptSneezeCoughEvent>(OnSneeze);
|
SubscribeLocalEvent<ActiveZombieComponent, AttemptSneezeCoughEvent>(OnSneeze);
|
||||||
SubscribeLocalEvent<ActiveZombieComponent, TryingToSleepEvent>(OnSleepAttempt);
|
SubscribeLocalEvent<ActiveZombieComponent, TryingToSleepEvent>(OnSleepAttempt);
|
||||||
@@ -176,5 +180,36 @@ namespace Content.Server.Zombies
|
|||||||
DoGroan(zombiecomp.Owner, zombiecomp);
|
DoGroan(zombiecomp.Owner, zombiecomp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is the function to call if you want to unzombify an entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source">the entity having the ZombieComponent</param>
|
||||||
|
/// <param name="target">the entity you want to unzombify (different from source in case of cloning, for example)</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// this currently only restore the name and skin/eye color from before zombified
|
||||||
|
/// TODO: reverse everything else done in ZombifyEntity
|
||||||
|
/// </remarks>
|
||||||
|
public bool UnZombify(EntityUid source, EntityUid target, ZombieComponent? zombiecomp)
|
||||||
|
{
|
||||||
|
if (!Resolve(source, ref zombiecomp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach (var (layer, info) in zombiecomp.BeforeZombifiedCustomBaseLayers)
|
||||||
|
{
|
||||||
|
_humanoidSystem.SetBaseLayerColor(target, layer, info.Color);
|
||||||
|
_humanoidSystem.SetBaseLayerId(target, layer, info.ID);
|
||||||
|
}
|
||||||
|
_humanoidSystem.SetSkinColor(target, zombiecomp.BeforeZombifiedSkinColor);
|
||||||
|
|
||||||
|
MetaData(target).EntityName = zombiecomp.BeforeZombifiedEntityName;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnZombieCloning(EntityUid uid, ZombieComponent zombiecomp, ref CloningEvent args)
|
||||||
|
{
|
||||||
|
if (UnZombify(args.Source, args.Target, zombiecomp))
|
||||||
|
args.NameHandled = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,6 +127,10 @@ namespace Content.Server.Zombies
|
|||||||
//We have specific stuff for humanoid zombies because they matter more
|
//We have specific stuff for humanoid zombies because they matter more
|
||||||
if (TryComp<HumanoidComponent>(target, out var huApComp)) //huapcomp
|
if (TryComp<HumanoidComponent>(target, out var huApComp)) //huapcomp
|
||||||
{
|
{
|
||||||
|
//store some values before changing them in case the humanoid get cloned later
|
||||||
|
zombiecomp.BeforeZombifiedSkinColor = huApComp.SkinColor;
|
||||||
|
zombiecomp.BeforeZombifiedCustomBaseLayers = new(huApComp.CustomBaseLayers);
|
||||||
|
|
||||||
_sharedHuApp.SetSkinColor(target, zombiecomp.SkinColor, humanoid: huApComp);
|
_sharedHuApp.SetSkinColor(target, zombiecomp.SkinColor, humanoid: huApComp);
|
||||||
_sharedHuApp.SetBaseLayerColor(target, HumanoidVisualLayers.Eyes, zombiecomp.EyeColor, humanoid: huApComp);
|
_sharedHuApp.SetBaseLayerColor(target, HumanoidVisualLayers.Eyes, zombiecomp.EyeColor, humanoid: huApComp);
|
||||||
|
|
||||||
@@ -172,6 +176,7 @@ namespace Content.Server.Zombies
|
|||||||
|
|
||||||
//gives it the funny "Zombie ___" name.
|
//gives it the funny "Zombie ___" name.
|
||||||
var meta = MetaData(target);
|
var meta = MetaData(target);
|
||||||
|
zombiecomp.BeforeZombifiedEntityName = meta.EntityName;
|
||||||
meta.EntityName = Loc.GetString("zombie-name-prefix", ("target", meta.EntityName));
|
meta.EntityName = Loc.GetString("zombie-name-prefix", ("target", meta.EntityName));
|
||||||
|
|
||||||
_identity.QueueIdentityUpdate(target);
|
_identity.QueueIdentityUpdate(target);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Shared.Roles;
|
using Content.Shared.Roles;
|
||||||
|
using Content.Shared.Humanoid;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
@@ -60,5 +61,23 @@ namespace Content.Shared.Zombies
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("zombieRoleId", customTypeSerializer: typeof(PrototypeIdSerializer<AntagPrototype>))]
|
[DataField("zombieRoleId", customTypeSerializer: typeof(PrototypeIdSerializer<AntagPrototype>))]
|
||||||
public readonly string ZombieRoleId = "Zombie";
|
public readonly string ZombieRoleId = "Zombie";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The EntityName of the humanoid to restore in case of cloning
|
||||||
|
/// </summary>
|
||||||
|
[DataField("beforeZombifiedEntityName"), ViewVariables(VVAccess.ReadOnly)]
|
||||||
|
public string BeforeZombifiedEntityName = String.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The CustomBaseLayers of the humanoid to restore in case of cloning
|
||||||
|
/// </summary>
|
||||||
|
[DataField("beforeZombifiedCustomBaseLayers")]
|
||||||
|
public Dictionary<HumanoidVisualLayers, CustomBaseLayerInfo> BeforeZombifiedCustomBaseLayers = new ();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The skin color of the humanoid to restore in case of cloning
|
||||||
|
/// </summary>
|
||||||
|
[DataField("beforeZombifiedSkinColor")]
|
||||||
|
public Color BeforeZombifiedSkinColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user