-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
AWF
committed
Mar 23, 2024
1 parent
09838e9
commit 15da7f7
Showing
3 changed files
with
230 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
using Content.Shared.GameTicking; | ||
using Content.Shared.Damage; | ||
using Content.Shared.Examine; | ||
using Content.Shared.Cloning; | ||
using Content.Shared.Atmos; | ||
using Content.Shared.CCVar; | ||
using Content.Server.Cloning.Components; | ||
using Content.Server.Mind.Components; | ||
using Content.Server.Power.EntitySystems; | ||
using Content.Server.Atmos.EntitySystems; | ||
using Content.Server.EUI; | ||
using Content.Server.Humanoid; | ||
using Content.Server.MachineLinking.System; | ||
using Content.Server.MachineLinking.Events; | ||
using Content.Shared.Chemistry.Components; | ||
using Content.Server.Fluids.EntitySystems; | ||
using Content.Server.Chat.Systems; | ||
using Content.Server.Construction; | ||
using Content.Server.Materials; | ||
using Content.Server.Stack; | ||
using Content.Server.Jobs; | ||
using Content.Shared.Humanoid; | ||
using Content.Shared.Humanoid.Prototypes; | ||
using Content.Shared.Zombies; | ||
using Content.Shared.Mobs.Systems; | ||
using Robust.Server.GameObjects; | ||
using Robust.Server.Containers; | ||
using Robust.Server.Player; | ||
using Robust.Shared.Prototypes; | ||
using Robust.Shared.Random; | ||
using Robust.Shared.Configuration; | ||
using Robust.Shared.Containers; | ||
using Robust.Shared.Physics.Components; | ||
using Content.Shared.Humanoid; | ||
using Content.Shared.Preferences; | ||
using Content.Server.Preferences.Managers; | ||
using Robust.Shared.Prototypes; | ||
using Content.Server.DetailExaminable; | ||
using Robust.Shared.Configuration; | ||
|
||
namespace Content.Server.Cloning | ||
{ | ||
public sealed class AutoCloningSystem : EntitySystem | ||
{ | ||
[Dependency] private readonly IPlayerManager _playerManager = null!; | ||
[Dependency] private readonly IPrototypeManager _prototype = default!; | ||
[Dependency] private readonly HumanoidAppearanceSystem _humanoidSystem = default!; | ||
[Dependency] private readonly ContainerSystem _containerSystem = default!; | ||
[Dependency] private readonly MobStateSystem _mobStateSystem = default!; | ||
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!; | ||
[Dependency] private readonly TransformSystem _transformSystem = default!; | ||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!; | ||
[Dependency] private readonly SpillableSystem _spillableSystem = default!; | ||
[Dependency] private readonly ChatSystem _chatSystem = default!; | ||
[Dependency] private readonly IConfigurationManager _configManager = default!; | ||
[Dependency] private readonly IServerPreferencesManager _prefsManager = default!; | ||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!; | ||
[Dependency] private readonly IConfigurationManager _configurationManager = default!; | ||
|
||
public override void Initialize() | ||
{ | ||
base.Initialize(); | ||
|
||
SubscribeLocalEvent<AutoCloningPodComponent, ComponentInit>(OnComponentInit); | ||
} | ||
|
||
private void OnComponentInit(EntityUid uid, AutoCloningPodComponent clonePod, ComponentInit args) | ||
{ | ||
clonePod.BodyContainer = _containerSystem.EnsureContainer<ContainerSlot>(clonePod.Owner, "clonepod-bodyContainer"); | ||
} | ||
|
||
internal void TransferMindToClone(EntityUid entity, Mind.Mind mind) | ||
{ | ||
mind.TransferTo(entity, ghostCheckOverride: true); | ||
mind.UnVisit(); | ||
} | ||
|
||
private void HandleMindAdded(EntityUid uid, BeingClonedComponent clonedComponent, MindAddedMessage message) | ||
{ | ||
if (clonedComponent.Parent == EntityUid.Invalid || | ||
!EntityManager.EntityExists(clonedComponent.Parent) || | ||
!TryComp<AutoCloningPodComponent>(clonedComponent.Parent, out var AutoCloningPodComponent) || | ||
clonedComponent.Owner != AutoCloningPodComponent.BodyContainer.ContainedEntity) | ||
{ | ||
EntityManager.RemoveComponent<BeingClonedComponent>(clonedComponent.Owner); | ||
return; | ||
} | ||
UpdateStatus(CloningPodStatus.Cloning, AutoCloningPodComponent); | ||
} | ||
|
||
private HumanoidCharacterProfile GetPlayerProfile(IPlayerSession p) | ||
{ | ||
return (HumanoidCharacterProfile) _prefsManager.GetPreferences(p.UserId).SelectedCharacter; | ||
} | ||
|
||
private EntityUid SpawnAutoClonedPlayer(AutoCloningPodComponent clonePod, IPlayerSession player) | ||
{ | ||
var profile = GetPlayerProfile(player); | ||
|
||
var entity = EntityManager.SpawnEntity( | ||
_prototypeManager.Index<SpeciesPrototype>(profile?.Species ?? HumanoidAppearanceSystem.DefaultSpecies).Prototype, | ||
Transform(clonePod.Owner).MapPosition); | ||
|
||
if (profile != null) | ||
{ | ||
_humanoidSystem.LoadProfile(entity, profile); | ||
EntityManager.GetComponent<MetaDataComponent>(entity).EntityName = profile.Name; | ||
if (profile.FlavorText != "" && _configurationManager.GetCVar(CCVars.FlavorText)) | ||
{ | ||
EntityManager.AddComponent<DetailExaminableComponent>(entity).Content = profile.FlavorText; | ||
} | ||
} | ||
|
||
return entity; | ||
} | ||
|
||
public bool TryCloning(EntityUid uid, IPlayerSession player, Mind.Mind mind, AutoCloningPodComponent? clonePod) | ||
{ | ||
|
||
if (!Resolve(uid, ref clonePod)) | ||
return false; | ||
|
||
if (HasComp<ActiveCloningPodComponent>(uid)) | ||
return false; | ||
|
||
if (mind.OwnedEntity != null && !_mobStateSystem.IsDead(mind.OwnedEntity.Value)) | ||
return false; // Body controlled by mind is not dead | ||
|
||
var mob = SpawnAutoClonedPlayer(clonePod, player); | ||
|
||
var cloneMindReturn = EntityManager.AddComponent<BeingClonedComponent>(mob); | ||
cloneMindReturn.Mind = mind; | ||
cloneMindReturn.Parent = clonePod.Owner; | ||
clonePod.BodyContainer.Insert(mob); | ||
|
||
UpdateStatus(CloningPodStatus.NoMind, clonePod); | ||
TransferMindToClone(mob,mind); | ||
|
||
AddComp<ActiveCloningPodComponent>(uid); | ||
|
||
// TODO: Ideally, components like this should be on a mind entity so this isn't neccesary. | ||
// Remove this when 'mind entities' are added. | ||
// Add on special job components to the mob. | ||
if (mind.CurrentJob != null) | ||
{ | ||
foreach (var special in mind.CurrentJob.Prototype.Special) | ||
{ | ||
if (special is AddComponentSpecial) | ||
special.AfterEquip(mob); | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
public void UpdateStatus(CloningPodStatus status, AutoCloningPodComponent cloningPod) | ||
{ | ||
cloningPod.Status = status; | ||
_appearance.SetData(cloningPod.Owner, CloningPodVisuals.Status, cloningPod.Status); | ||
} | ||
|
||
public override void Update(float frameTime) | ||
{ | ||
foreach (var (_, cloning) in EntityManager.EntityQuery<ActiveCloningPodComponent, AutoCloningPodComponent>()) | ||
{ | ||
if (cloning.BodyContainer.ContainedEntity == null) | ||
continue; | ||
|
||
cloning.CloningProgress += frameTime; | ||
if (cloning.CloningProgress < cloning.CloningTime) | ||
continue; | ||
|
||
Eject(cloning.Owner, cloning); | ||
} | ||
} | ||
|
||
public void Eject(EntityUid uid, AutoCloningPodComponent? clonePod) | ||
{ | ||
if (!Resolve(uid, ref clonePod)) | ||
return; | ||
|
||
if (clonePod.BodyContainer.ContainedEntity is not {Valid: true} entity || clonePod.CloningProgress < clonePod.CloningTime) | ||
return; | ||
|
||
EntityManager.RemoveComponent<BeingClonedComponent>(entity); | ||
clonePod.BodyContainer.Remove(entity); | ||
clonePod.CloningProgress = 0f; | ||
UpdateStatus(CloningPodStatus.Idle, clonePod); | ||
RemCompDeferred<ActiveCloningPodComponent>(uid); | ||
} | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
Content.Server/Cloning/Components/AutoCloningPodComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
using Content.Shared.Cloning; | ||
using Content.Shared.Construction.Prototypes; | ||
using Content.Shared.Materials; | ||
using Robust.Shared.Containers; | ||
using Robust.Shared.Prototypes; | ||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; | ||
|
||
namespace Content.Server.Cloning.Components | ||
{ | ||
[RegisterComponent] | ||
public sealed class AutoCloningPodComponent : Component | ||
{ | ||
[ViewVariables] | ||
public ContainerSlot BodyContainer = default!; | ||
|
||
/// <summary> | ||
/// How long the cloning has been going on for. | ||
/// </summary> | ||
[ViewVariables] | ||
public float CloningProgress = 0; | ||
|
||
/// <summary> | ||
/// The base amount of time it takes to clone a body | ||
/// </summary> | ||
[DataField("baseCloningTime")] | ||
public float BaseCloningTime = 30f; | ||
|
||
/// <summary> | ||
/// The current amount of time it takes to clone a body | ||
/// </summary> | ||
[ViewVariables(VVAccess.ReadWrite)] | ||
public float CloningTime = 30f; | ||
|
||
[ViewVariables(VVAccess.ReadWrite)] | ||
public CloningPodStatus Status; | ||
} | ||
} |
Submodule RobustToolbox
updated
4 files
+1 −1 | MSBuild/Robust.Engine.Version.props | |
+0 −3 | RELEASE-NOTES.md | |
+1 −1 | Robust.Client/Robust.Client.csproj | |
+1 −1 | Robust.Shared/Robust.Shared.csproj |