diff --git a/Content.Server/Changeling/ChangelingSystem.Abilities.cs b/Content.Server/Changeling/ChangelingSystem.Abilities.cs index 55d5eca3f6..1855d8cb99 100644 --- a/Content.Server/Changeling/ChangelingSystem.Abilities.cs +++ b/Content.Server/Changeling/ChangelingSystem.Abilities.cs @@ -1,10 +1,14 @@ using System.Linq; +using Content.Server._White.Cult; +using Content.Server._White.Cult.GameRule; using Content.Server.Administration.Systems; +using Content.Server.Bible.Components; using Content.Server.Body.Components; using Content.Server.Body.Systems; using Content.Server.Cuffs; using Content.Server.DoAfter; using Content.Server.Forensics; +using Content.Server.GameTicking.Rules; using Content.Server.Humanoid; using Content.Server.IdentityManagement; using Content.Server.Mind; @@ -13,6 +17,8 @@ using Content.Server.Popups; using Content.Server.Store.Components; using Content.Server.Temperature.Components; using Content.Server.Temperature.Systems; +using Content.Shared._White.Chaplain; +using Content.Shared._White.Cult.Components; using Content.Shared.Actions; using Content.Shared.Changeling; using Content.Shared.Chemistry.EntitySystems; @@ -66,6 +72,8 @@ public sealed partial class ChangelingSystem [Dependency] private readonly MindSystem _mindSystem = default!; [Dependency] private readonly BloodstreamSystem _blood = default!; [Dependency] private readonly CuffableSystem _cuffable = default!; + [Dependency] private readonly NukeopsRuleSystem _nukeOps = default!; + [Dependency] private readonly CultRuleSystem _cult = default!; private void InitializeAbilities() { @@ -815,6 +823,34 @@ public sealed partial class ChangelingSystem _identity.QueueIdentityUpdate(polymorphEntity.Value); + if (HasComp(target)) + EnsureComp(polymorphEntity.Value); + + if (HasComp(target)) + EnsureComp(polymorphEntity.Value); + + if (TryComp(target, out ChangelingComponent? lingComp)) + { + var toAdd = new ChangelingComponent + { + HiveName = lingComp.HiveName, + ChemicalsBalance = lingComp.ChemicalsBalance, + AbsorbedEntities = lingComp.AbsorbedEntities, + IsInited = lingComp.IsInited + }; + + EntityManager.AddComponent(polymorphEntity.Value, toAdd); + _chemicalsSystem.UpdateAlert(polymorphEntity.Value, toAdd); + } + + _nukeOps.TransferRole(target, polymorphEntity.Value); + + _cult.TransferRole(target, polymorphEntity.Value); + + _implantSystem.TransferImplants(target, polymorphEntity.Value); + _actionContainerSystem.TransferAllActionsFiltered(target, polymorphEntity.Value, polymorphEntity.Value); + _action.GrantContainedActions(polymorphEntity.Value, polymorphEntity.Value); + return polymorphEntity; } @@ -840,28 +876,12 @@ public sealed partial class ChangelingSystem if (reverted == null) return; - var toAdd = new ChangelingComponent - { - HiveName = component.HiveName, - ChemicalsBalance = component.ChemicalsBalance, - AbsorbedEntities = component.AbsorbedEntities, - IsInited = component.IsInited - }; - - EntityManager.AddComponent(reverted.Value, toAdd); - - _implantSystem.TransferImplants(uid, reverted.Value); - _actionContainerSystem.TransferAllActionsFiltered(uid, reverted.Value, reverted.Value); - _action.GrantContainedActions(reverted.Value, reverted.Value); - if (component.IsLesserForm) { //Don't copy IsLesserForm bool, because transferred component, in fact, new. Bool default value if false. StartUseDelayById(reverted.Value, ChangelingLesserForm); } - _chemicalsSystem.UpdateAlert(reverted.Value, component); - StartUseDelayById(reverted.Value, ChangelingTransform); } diff --git a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs index a156c159c1..f0175cc141 100644 --- a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs @@ -1191,4 +1191,18 @@ public sealed class NukeopsRuleSystem : GameRuleSystem if (GameTicker.RunLevel == GameRunLevel.InRound) SpawnOperativesForGhostRoles(uid, component); } + + public void TransferRole(EntityUid transferFrom, EntityUid transferTo) + { + if (!HasComp(transferFrom)) + return; + + var query = EntityQuery(); + foreach (var nukeOpsRule in query) + { + nukeOpsRule.OperativePlayers.Remove(Name(transferFrom)); + } + EnsureComp(transferTo); + RemComp(transferFrom); + } } diff --git a/Content.Server/_White/Cult/GameRule/CultRuleSystem.cs b/Content.Server/_White/Cult/GameRule/CultRuleSystem.cs index 056c48e57d..2736fc7f54 100644 --- a/Content.Server/_White/Cult/GameRule/CultRuleSystem.cs +++ b/Content.Server/_White/Cult/GameRule/CultRuleSystem.cs @@ -493,4 +493,21 @@ public sealed class CultRuleSystem : GameRuleSystem _bodySystem.GibBody(uid); } } + + public void TransferRole(EntityUid transferFrom, EntityUid transferTo) + { + if (HasComp(transferFrom)) + EnsureComp(transferTo); + + if (!HasComp(transferFrom)) + return; + + var query = EntityQuery(); + foreach (var cultRule in query) + { + cultRule.CultistsCache.Remove(Name(transferFrom)); + } + EnsureComp(transferTo); + RemComp(transferFrom); + } } diff --git a/Resources/Prototypes/Polymorphs/polymorph.yml b/Resources/Prototypes/Polymorphs/polymorph.yml index 68263832c8..6e35690bf3 100644 --- a/Resources/Prototypes/Polymorphs/polymorph.yml +++ b/Resources/Prototypes/Polymorphs/polymorph.yml @@ -285,6 +285,94 @@ allowRepeatedMorphs: true inventory: Transfer +- type: polymorph + id: MobHumanSyndicateAgent + configuration: + entity: MobHumanSyndicateAgent + forced: true + revertOnCrit: false + revertOnDeath: false + transferDamage: true + allowRepeatedMorphs: true + inventory: Transfer + +- type: polymorph + id: MobHumanSyndicateAgentNukeops + configuration: + entity: MobHumanSyndicateAgentNukeops + forced: true + revertOnCrit: false + revertOnDeath: false + transferDamage: true + allowRepeatedMorphs: true + inventory: Transfer + +- type: polymorph + id: MobHumanNukeOp + configuration: + entity: MobHumanNukeOp + forced: true + revertOnCrit: false + revertOnDeath: false + transferDamage: true + allowRepeatedMorphs: true + inventory: Transfer + +- type: polymorph + id: MobHumanLoneNuclearOperative + configuration: + entity: MobHumanLoneNuclearOperative + forced: true + revertOnCrit: false + revertOnDeath: false + transferDamage: true + allowRepeatedMorphs: true + inventory: Transfer + +- type: polymorph + id: MobHumanSpaceNinja + configuration: + entity: MobHumanSpaceNinja + forced: true + revertOnCrit: false + revertOnDeath: false + transferDamage: true + allowRepeatedMorphs: true + inventory: Transfer + +- type: polymorph + id: MobGingerbread + configuration: + entity: MobGingerbread + forced: true + revertOnCrit: false + revertOnDeath: false + transferDamage: true + allowRepeatedMorphs: true + inventory: Transfer + +- type: polymorph + id: MobHumanTerminator + configuration: + entity: MobHumanTerminator + forced: true + revertOnCrit: false + revertOnDeath: false + transferDamage: true + allowRepeatedMorphs: true + inventory: Transfer + +- type: polymorph + id: MobTerminatorEndoskeleton + configuration: + entity: MobTerminatorEndoskeleton + forced: true + revertOnCrit: false + revertOnDeath: false + transferDamage: true + allowRepeatedMorphs: true + inventory: Transfer + - type: polymorph id: ArtifactLuminous configuration: