2023-08-28 16:53:24 -07:00
|
|
|
using Content.Server.Humanoid;
|
2025-03-02 16:50:12 +01:00
|
|
|
using Content.Shared.Administration.Logs;
|
2023-08-28 16:53:24 -07:00
|
|
|
using Content.Shared.Cloning;
|
2025-03-02 16:50:12 +01:00
|
|
|
using Content.Shared.Cloning.Events;
|
|
|
|
|
using Content.Shared.Database;
|
2022-12-24 23:28:21 -05:00
|
|
|
using Content.Shared.Humanoid;
|
2025-03-02 16:50:12 +01:00
|
|
|
using Content.Shared.Inventory;
|
2025-03-18 06:21:56 +01:00
|
|
|
using Content.Shared.Implants;
|
|
|
|
|
using Content.Shared.Implants.Components;
|
2025-05-06 14:22:32 -03:00
|
|
|
using Content.Shared.NameModifier.EntitySystems;
|
2025-03-02 16:50:12 +01:00
|
|
|
using Content.Shared.StatusEffect;
|
2025-03-16 23:02:19 +01:00
|
|
|
using Content.Shared.Storage;
|
|
|
|
|
using Content.Shared.Storage.EntitySystems;
|
2025-03-02 16:50:12 +01:00
|
|
|
using Content.Shared.Whitelist;
|
2025-03-16 23:02:19 +01:00
|
|
|
using Robust.Shared.Containers;
|
2025-03-02 16:50:12 +01:00
|
|
|
using Robust.Shared.Map;
|
2023-08-28 16:53:24 -07:00
|
|
|
using Robust.Shared.Prototypes;
|
2025-03-02 16:50:12 +01:00
|
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
|
|
using System.Linq;
|
2022-08-29 22:31:27 -04:00
|
|
|
|
2025-03-02 16:50:12 +01:00
|
|
|
namespace Content.Server.Cloning;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// System responsible for making a copy of a humanoid's body.
|
|
|
|
|
/// For the cloning machines themselves look at CloningPodSystem, CloningConsoleSystem and MedicalScannerSystem instead.
|
|
|
|
|
/// </summary>
|
Changeling devour and transform (#34002)
* Initial:
Create Devour componentry, preliminary identity storage and the systems
for Devouring
* I have genuinely no idea what i'm doing
- added the radial menu, it has nothing in it.
- trying to get it to populate. the event under the event is broken,
i don't know why, but apparently it's not typed right
- Added a placeholder transform
- oh also fixed up some devour stuff and moved some things around.
* Holey moley, Transform, better devour, oh my!
- Move DnaComponent into Shared because we need it for the DNA cloning
- Make Transform MOSTLY work on the LAST identity devoured.
- Fix some issues on devour that involved prediction, canceling and
Damage exeucting (Thanks Plykiya for pointing out AttemptFrequency!)
* Proper tail stealing and Damage modifier attempt
Add check to add a wagging component on the Changeling if the victim's
species Prototype had one.
attempt to add the Damage mitigation check
* MAJOR CLEANUP AND FIXES AUGH 3 DAYS!!!
- Nullspaced a clone of a victim
- fix audio using server virtualized Pvs (i hate this)
- fix the mispredicted doafters
- Clean up a wholelotta code
- utilize clone systems to clone appearances
- Move CloneAppearance from server to shared So we can actually access
it
* Examine stuff, more cleanup, Jumpsuit ripping
- make rotting prevent the action
- Add ripping of clothing (guh why is it also server)
- add some System stuff for pushing husked corpse inspection
- clean up more badcode
* Doing things properly, UI sorta kinda works.
- Utilize Relayed events for Devour checking
- Get a UI that partially works, Says the name of identities, doesn't
show their looks
- Make use of the New Dynamic BUI assignment
- commit the sin of no client prediction cause nullspace entities aren't
networked
* Got an entity for the Frontend transform
Issue with the looks
* Stick a camera into a fake mobs forehead
- Get the UI to see the net entity in pause space by using a
ViewSubscriber to get the Pvs from the initially stored identity entity
- Remove all the other parts used to try to get this to work before hand
* Raaaaadiallllllls also fix protection coefficents
- Change FancyWindow to Radial
- Fix Issue where coeffeient checking was the wrong way round
* absolutely massive cleanup, no more camera in mobs
- cleaned up event variables that are not needed
- Removed the use of a Pause space and go back to Nullspace usage
- use a PvsOverride rather than ViewSharing
- Remove old commented out code and Lots of unused code
* Fix "Ui elements" dying on the screen
- some minor cleanup
- don't start the entities that get cloned
* ftl, cleanup, and fixing missing transform details
- add replace functionality to TypingIndicatorSystem and
BodyEmotesSystem
- add placeholder sounds and functions to TransformBodyEmotes
- add extra Pvs handling for later use
- attributions for the funny straw sound
- Sound collections for all of the sounds
- various cleanups
* Some extra cleanup
* Fix some false assumptions about TypingIndicator
- Bubbles now transfer on spawned humans rather than used humans
- Clean up YET MORE CODE
- make it so you can't eat yourself
* Oooprs, forgot to add a Husked Corpse Loc
* Missing period in the husked corpse loc
* bad devour windup placeholder
* Husking and WIP Lungs
- Husking now will be prevented from Revival fully and will change
the appearance of players
* Add finalized Sprites for actions and final meta
- add devour on and off sprites
- add transform action sprite
- Add Armblade sprite for future use
- Credit obscenelytinyshark for the sprites <3
* Remove ling lungs, Entity<> everything
- Remove the ling lungs stuff for now... body system is overly
complicated, makes my head hurt
- Switch every method to use Entity<> from Uid, Comp format
* cleanup, admin logging, WIP Roles
* Admin verb, Roundstart, gamerule stuff
- add a Admin verb to make Changelingification easy!
- Add game rule stuff for admin verb and to tell the hapless
goober how to be a changeling... sorta
- clean up parts to make VV easy... USE THE VERB!!
* Armor Coefficent Check
- Remove bespoke changeling armor check and replace it
with a generic armor coefficient query.
* move to UnrevivableComponent instead of husked
- Move UnrevivableComponent to shared
- add Analyzable and ReasonMessage to UnrevivableComponent
to give granular control of the message and whether or not it shows up
in the analyzer
- remove the check for HuskedComponent in DefibrillatorSystem
* aaaaaaa CopyComp
- Some cleanup
- make Vocal system shared
- make VocalSystem Not make more Actions than it needs
- Use some code from ChameleonProjector so we can copy components
- partially ungod method the Transform system
* Cleanup, Moving more things to CopyComp
- TransformBodyEmotes now uses CopyComp (it's a server component so i
need to tell the server to deal with it
- TypingIndicatorComponent also now uses CopyComp
- cleaned up old, now unused "replace" methods in favor of CopyComp
- BodyEmotesSystem now has a publically accessable LoadSounds to deal
with the same problem Screaming had
* WIP
* Devour Windup noise, ForensicsSystem cleanup
* Revert VocalSystem Changes
- Reverted Moving VocalSystem to shared, copy comp acomplishes it
- added component.ScreamActionEntity = null; for copy comp
* cleanup unneeded comments
* revert an accidental line removal
* Remove duplicate SharedHumanoidAppearanceSystem
* Cleanup Typo's and import Forensics components for Dna
* Some more forensics calls
* cleanup use CopyComp for now until CopyComps
* CR cleanup
* Undo some SharedHumanoidAppearanceSystem changes
* Confound these spaces
* Some Copycomp stuff and fixing some PVS override
* use the proper TryCopyComps that are merged
* Change TransformMenu with RadialWithSector
* All sounds done, Fix lack of typing indicator issue
* Updated attributions to include used sound authors
* some ftl typos and mind_role text issue
* DNA, Screaming, appearance, grammar, wagging
- reduced all of the above using ApplyComponentChanges
- Issue still remains with bodyEmotes sticking around in the UI
* Fix UI stuff, partials, entprotoid, good practices
- bunch of partials added
- UI now has a predicted message
- EntProtoID in the admin verb
- RipClothing now uses Entity<ButcherableComponent>
- husking is now optional (off by default) for testing/till we have
hivemind/when we figure out what were doing with devour
- remove TransformGrammarSet
* More CR stuff and documentation
- Make TargetIsProtected less of a meme, with a prototype
set of DamageTypes to check
- Documenation everywhere
- Move DevourEvents into its own file
* Predicted sounds and fix the comp clone list
- Made all start and stop sounds shared
- Split out the rest of the events and UI stuff into subfiles
- Fixed some Clone comp list issues where comments had -'s causing them
to be read incorrectly
* Damage cap check, Identity Shutdown cleanup, cleanup
* Sound stuff (but actually this time)
* Missed documentation
* Missed Documentation and a EntProtoId
* Remove unused dependency
* Remove a nullcheck
* Some dummy minplayers
* CR - Husked now uses a rem/ensure
* Update Actions in the Prototype
* Fixup mindswap handover
- cleanup and handover PVS on mindswap
* Fixup Missing meta from accidental "Take-theirs"
* Add the Armblade to the roundstart-role
* Cleanup, CR (everything but the UI and renames)
* missed a spot
* missed some more whitespace
* Renames
* Primary constructor and a space in these trying times
* User interface stuff for Slime transformation
* popup prediction
* Ling devour no longer makes duplicate identities
- added a key to identities to the original victim
- Add some extra clone settings
* add guard statements to OnClones
* SentOnlyToOwner additions
* fix for sound stoppage error
* Move Organ deleter into soon to be atomized husk
* clone event inventory
* mono sounds
* lower sound volume
* Fix networked sound warning
* Clone comps thing
* review
* attributions
* Fix clobbered changes
* I'm gonna weh out
- whole bunch of CR changes
* fix some very buggy git
* okay its fixed
* address most review points
* fix inventory
* we hate entityuids
* fix test and more cleanup
* move this
* fix more stuff
* fix validation and rootable
* Remove Quickswitch due to some UI quirks
* oops left out some better explanation
* remove dangling LastConsumed component fields
* fix test fail
* try this
* cleanup cloning subscriptions, add movement speed modifier
* fix slime storage
* fix cloning setting inheritance
* Add session information to transform admin logs
* slay the integration test hydra
* dwarf size
* more volume tweaks
* comments
* improve comments and unpredict deletion due to errors when shutting down the server
* fix displancement cloning
---------
Co-authored-by: ScarKy0 <scarky0@onet.eu>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
2025-08-06 16:55:49 -03:00
|
|
|
public sealed partial class CloningSystem : SharedCloningSystem
|
2020-08-19 10:23:20 -04:00
|
|
|
{
|
2025-03-02 16:50:12 +01:00
|
|
|
[Dependency] private readonly HumanoidAppearanceSystem _humanoidSystem = default!;
|
|
|
|
|
[Dependency] private readonly InventorySystem _inventory = default!;
|
|
|
|
|
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
|
|
|
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
|
|
|
|
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
|
|
|
|
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
2025-03-16 23:02:19 +01:00
|
|
|
[Dependency] private readonly SharedContainerSystem _container = default!;
|
|
|
|
|
[Dependency] private readonly SharedStorageSystem _storage = default!;
|
2025-03-18 06:21:56 +01:00
|
|
|
[Dependency] private readonly SharedSubdermalImplantSystem _subdermalImplant = default!;
|
2025-05-06 14:22:32 -03:00
|
|
|
[Dependency] private readonly NameModifierSystem _nameMod = default!;
|
2025-03-02 16:50:12 +01:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Spawns a clone of the given humanoid mob at the specified location or in nullspace.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool TryCloning(EntityUid original, MapCoordinates? coords, ProtoId<CloningSettingsPrototype> settingsId, [NotNullWhen(true)] out EntityUid? clone)
|
2020-08-19 10:23:20 -04:00
|
|
|
{
|
2025-03-02 16:50:12 +01:00
|
|
|
clone = null;
|
2025-09-09 18:17:56 +02:00
|
|
|
if (!_prototype.Resolve(settingsId, out var settings))
|
2025-03-02 16:50:12 +01:00
|
|
|
return false; // invalid settings
|
2022-08-29 22:31:27 -04:00
|
|
|
|
2025-03-02 16:50:12 +01:00
|
|
|
if (!TryComp<HumanoidAppearanceComponent>(original, out var humanoid))
|
|
|
|
|
return false; // whatever body was to be cloned, was not a humanoid
|
2021-05-11 16:16:08 -07:00
|
|
|
|
2025-09-09 18:17:56 +02:00
|
|
|
if (!_prototype.Resolve(humanoid.Species, out var speciesPrototype))
|
2025-03-02 16:50:12 +01:00
|
|
|
return false; // invalid species
|
2021-05-11 16:16:08 -07:00
|
|
|
|
2025-03-02 16:50:12 +01:00
|
|
|
var attemptEv = new CloningAttemptEvent(settings);
|
|
|
|
|
RaiseLocalEvent(original, ref attemptEv);
|
|
|
|
|
if (attemptEv.Cancelled && !settings.ForceCloning)
|
|
|
|
|
return false; // cannot clone, for example due to the unrevivable trait
|
2022-08-04 00:05:17 -04:00
|
|
|
|
2025-03-02 16:50:12 +01:00
|
|
|
clone = coords == null ? Spawn(speciesPrototype.Prototype) : Spawn(speciesPrototype.Prototype, coords.Value);
|
|
|
|
|
_humanoidSystem.CloneAppearance(original, clone.Value);
|
2022-08-04 00:05:17 -04:00
|
|
|
|
2025-05-06 14:22:32 -03:00
|
|
|
CloneComponents(original, clone.Value, settings);
|
|
|
|
|
|
|
|
|
|
// Add equipment first so that SetEntityName also renames the ID card.
|
|
|
|
|
if (settings.CopyEquipment != null)
|
|
|
|
|
CopyEquipment(original, clone.Value, settings.CopyEquipment.Value, settings.Whitelist, settings.Blacklist);
|
|
|
|
|
|
|
|
|
|
// Copy storage on the mob itself as well.
|
|
|
|
|
// This is needed for slime storage.
|
|
|
|
|
if (settings.CopyInternalStorage)
|
|
|
|
|
CopyStorage(original, clone.Value, settings.Whitelist, settings.Blacklist);
|
|
|
|
|
|
|
|
|
|
// copy implants and their storage contents
|
|
|
|
|
if (settings.CopyImplants)
|
|
|
|
|
CopyImplants(original, clone.Value, settings.CopyInternalStorage, settings.Whitelist, settings.Blacklist);
|
|
|
|
|
|
|
|
|
|
var originalName = _nameMod.GetBaseName(original);
|
|
|
|
|
|
|
|
|
|
// Set the clone's name. The raised events will also adjust their PDA and ID card names.
|
|
|
|
|
_metaData.SetEntityName(clone.Value, originalName);
|
|
|
|
|
|
|
|
|
|
_adminLogger.Add(LogType.Chat, LogImpact.Medium, $"The body of {original:player} was cloned as {clone.Value:player}");
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
Changeling devour and transform (#34002)
* Initial:
Create Devour componentry, preliminary identity storage and the systems
for Devouring
* I have genuinely no idea what i'm doing
- added the radial menu, it has nothing in it.
- trying to get it to populate. the event under the event is broken,
i don't know why, but apparently it's not typed right
- Added a placeholder transform
- oh also fixed up some devour stuff and moved some things around.
* Holey moley, Transform, better devour, oh my!
- Move DnaComponent into Shared because we need it for the DNA cloning
- Make Transform MOSTLY work on the LAST identity devoured.
- Fix some issues on devour that involved prediction, canceling and
Damage exeucting (Thanks Plykiya for pointing out AttemptFrequency!)
* Proper tail stealing and Damage modifier attempt
Add check to add a wagging component on the Changeling if the victim's
species Prototype had one.
attempt to add the Damage mitigation check
* MAJOR CLEANUP AND FIXES AUGH 3 DAYS!!!
- Nullspaced a clone of a victim
- fix audio using server virtualized Pvs (i hate this)
- fix the mispredicted doafters
- Clean up a wholelotta code
- utilize clone systems to clone appearances
- Move CloneAppearance from server to shared So we can actually access
it
* Examine stuff, more cleanup, Jumpsuit ripping
- make rotting prevent the action
- Add ripping of clothing (guh why is it also server)
- add some System stuff for pushing husked corpse inspection
- clean up more badcode
* Doing things properly, UI sorta kinda works.
- Utilize Relayed events for Devour checking
- Get a UI that partially works, Says the name of identities, doesn't
show their looks
- Make use of the New Dynamic BUI assignment
- commit the sin of no client prediction cause nullspace entities aren't
networked
* Got an entity for the Frontend transform
Issue with the looks
* Stick a camera into a fake mobs forehead
- Get the UI to see the net entity in pause space by using a
ViewSubscriber to get the Pvs from the initially stored identity entity
- Remove all the other parts used to try to get this to work before hand
* Raaaaadiallllllls also fix protection coefficents
- Change FancyWindow to Radial
- Fix Issue where coeffeient checking was the wrong way round
* absolutely massive cleanup, no more camera in mobs
- cleaned up event variables that are not needed
- Removed the use of a Pause space and go back to Nullspace usage
- use a PvsOverride rather than ViewSharing
- Remove old commented out code and Lots of unused code
* Fix "Ui elements" dying on the screen
- some minor cleanup
- don't start the entities that get cloned
* ftl, cleanup, and fixing missing transform details
- add replace functionality to TypingIndicatorSystem and
BodyEmotesSystem
- add placeholder sounds and functions to TransformBodyEmotes
- add extra Pvs handling for later use
- attributions for the funny straw sound
- Sound collections for all of the sounds
- various cleanups
* Some extra cleanup
* Fix some false assumptions about TypingIndicator
- Bubbles now transfer on spawned humans rather than used humans
- Clean up YET MORE CODE
- make it so you can't eat yourself
* Oooprs, forgot to add a Husked Corpse Loc
* Missing period in the husked corpse loc
* bad devour windup placeholder
* Husking and WIP Lungs
- Husking now will be prevented from Revival fully and will change
the appearance of players
* Add finalized Sprites for actions and final meta
- add devour on and off sprites
- add transform action sprite
- Add Armblade sprite for future use
- Credit obscenelytinyshark for the sprites <3
* Remove ling lungs, Entity<> everything
- Remove the ling lungs stuff for now... body system is overly
complicated, makes my head hurt
- Switch every method to use Entity<> from Uid, Comp format
* cleanup, admin logging, WIP Roles
* Admin verb, Roundstart, gamerule stuff
- add a Admin verb to make Changelingification easy!
- Add game rule stuff for admin verb and to tell the hapless
goober how to be a changeling... sorta
- clean up parts to make VV easy... USE THE VERB!!
* Armor Coefficent Check
- Remove bespoke changeling armor check and replace it
with a generic armor coefficient query.
* move to UnrevivableComponent instead of husked
- Move UnrevivableComponent to shared
- add Analyzable and ReasonMessage to UnrevivableComponent
to give granular control of the message and whether or not it shows up
in the analyzer
- remove the check for HuskedComponent in DefibrillatorSystem
* aaaaaaa CopyComp
- Some cleanup
- make Vocal system shared
- make VocalSystem Not make more Actions than it needs
- Use some code from ChameleonProjector so we can copy components
- partially ungod method the Transform system
* Cleanup, Moving more things to CopyComp
- TransformBodyEmotes now uses CopyComp (it's a server component so i
need to tell the server to deal with it
- TypingIndicatorComponent also now uses CopyComp
- cleaned up old, now unused "replace" methods in favor of CopyComp
- BodyEmotesSystem now has a publically accessable LoadSounds to deal
with the same problem Screaming had
* WIP
* Devour Windup noise, ForensicsSystem cleanup
* Revert VocalSystem Changes
- Reverted Moving VocalSystem to shared, copy comp acomplishes it
- added component.ScreamActionEntity = null; for copy comp
* cleanup unneeded comments
* revert an accidental line removal
* Remove duplicate SharedHumanoidAppearanceSystem
* Cleanup Typo's and import Forensics components for Dna
* Some more forensics calls
* cleanup use CopyComp for now until CopyComps
* CR cleanup
* Undo some SharedHumanoidAppearanceSystem changes
* Confound these spaces
* Some Copycomp stuff and fixing some PVS override
* use the proper TryCopyComps that are merged
* Change TransformMenu with RadialWithSector
* All sounds done, Fix lack of typing indicator issue
* Updated attributions to include used sound authors
* some ftl typos and mind_role text issue
* DNA, Screaming, appearance, grammar, wagging
- reduced all of the above using ApplyComponentChanges
- Issue still remains with bodyEmotes sticking around in the UI
* Fix UI stuff, partials, entprotoid, good practices
- bunch of partials added
- UI now has a predicted message
- EntProtoID in the admin verb
- RipClothing now uses Entity<ButcherableComponent>
- husking is now optional (off by default) for testing/till we have
hivemind/when we figure out what were doing with devour
- remove TransformGrammarSet
* More CR stuff and documentation
- Make TargetIsProtected less of a meme, with a prototype
set of DamageTypes to check
- Documenation everywhere
- Move DevourEvents into its own file
* Predicted sounds and fix the comp clone list
- Made all start and stop sounds shared
- Split out the rest of the events and UI stuff into subfiles
- Fixed some Clone comp list issues where comments had -'s causing them
to be read incorrectly
* Damage cap check, Identity Shutdown cleanup, cleanup
* Sound stuff (but actually this time)
* Missed documentation
* Missed Documentation and a EntProtoId
* Remove unused dependency
* Remove a nullcheck
* Some dummy minplayers
* CR - Husked now uses a rem/ensure
* Update Actions in the Prototype
* Fixup mindswap handover
- cleanup and handover PVS on mindswap
* Fixup Missing meta from accidental "Take-theirs"
* Add the Armblade to the roundstart-role
* Cleanup, CR (everything but the UI and renames)
* missed a spot
* missed some more whitespace
* Renames
* Primary constructor and a space in these trying times
* User interface stuff for Slime transformation
* popup prediction
* Ling devour no longer makes duplicate identities
- added a key to identities to the original victim
- Add some extra clone settings
* add guard statements to OnClones
* SentOnlyToOwner additions
* fix for sound stoppage error
* Move Organ deleter into soon to be atomized husk
* clone event inventory
* mono sounds
* lower sound volume
* Fix networked sound warning
* Clone comps thing
* review
* attributions
* Fix clobbered changes
* I'm gonna weh out
- whole bunch of CR changes
* fix some very buggy git
* okay its fixed
* address most review points
* fix inventory
* we hate entityuids
* fix test and more cleanup
* move this
* fix more stuff
* fix validation and rootable
* Remove Quickswitch due to some UI quirks
* oops left out some better explanation
* remove dangling LastConsumed component fields
* fix test fail
* try this
* cleanup cloning subscriptions, add movement speed modifier
* fix slime storage
* fix cloning setting inheritance
* Add session information to transform admin logs
* slay the integration test hydra
* dwarf size
* more volume tweaks
* comments
* improve comments and unpredict deletion due to errors when shutting down the server
* fix displancement cloning
---------
Co-authored-by: ScarKy0 <scarky0@onet.eu>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
2025-08-06 16:55:49 -03:00
|
|
|
public override void CloneComponents(EntityUid original, EntityUid clone, CloningSettingsPrototype settings)
|
2025-05-06 14:22:32 -03:00
|
|
|
{
|
2025-03-02 16:50:12 +01:00
|
|
|
var componentsToCopy = settings.Components;
|
2025-05-06 14:22:32 -03:00
|
|
|
var componentsToEvent = settings.EventComponents;
|
2021-05-11 16:16:08 -07:00
|
|
|
|
2025-03-02 16:50:12 +01:00
|
|
|
// don't make status effects permanent
|
|
|
|
|
if (TryComp<StatusEffectsComponent>(original, out var statusComp))
|
2025-05-06 14:22:32 -03:00
|
|
|
{
|
|
|
|
|
var statusComps = statusComp.ActiveEffects.Values.Select(s => s.RelevantComponent).Where(s => s != null).ToList();
|
|
|
|
|
componentsToCopy.ExceptWith(statusComps!);
|
|
|
|
|
componentsToEvent.ExceptWith(statusComps!);
|
|
|
|
|
}
|
2022-08-04 00:05:17 -04:00
|
|
|
|
2025-03-02 16:50:12 +01:00
|
|
|
foreach (var componentName in componentsToCopy)
|
2022-08-29 22:31:27 -04:00
|
|
|
{
|
2025-05-20 15:08:55 +10:00
|
|
|
if (!Factory.TryGetRegistration(componentName, out var componentRegistration))
|
2022-08-29 22:31:27 -04:00
|
|
|
{
|
2025-03-02 16:50:12 +01:00
|
|
|
Log.Error($"Tried to use invalid component registration for cloning: {componentName}");
|
|
|
|
|
continue;
|
2022-08-29 22:31:27 -04:00
|
|
|
}
|
2023-01-23 00:36:03 +01:00
|
|
|
|
2025-05-06 14:22:32 -03:00
|
|
|
// If the original does not have the component, then the clone shouldn't have it either.
|
|
|
|
|
RemComp(clone, componentRegistration.Type);
|
2025-03-02 16:50:12 +01:00
|
|
|
if (EntityManager.TryGetComponent(original, componentRegistration.Type, out var sourceComp)) // Does the original have this component?
|
2022-09-05 22:29:40 -04:00
|
|
|
{
|
2025-05-06 14:22:32 -03:00
|
|
|
CopyComp(original, clone, sourceComp);
|
2022-09-05 22:29:40 -04:00
|
|
|
}
|
2022-08-04 00:05:17 -04:00
|
|
|
}
|
|
|
|
|
|
2025-05-06 14:22:32 -03:00
|
|
|
foreach (var componentName in componentsToEvent)
|
|
|
|
|
{
|
2025-05-20 15:08:55 +10:00
|
|
|
if (!Factory.TryGetRegistration(componentName, out var componentRegistration))
|
2025-05-06 14:22:32 -03:00
|
|
|
{
|
|
|
|
|
Log.Error($"Tried to use invalid component registration for cloning: {componentName}");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2025-01-30 05:05:47 +01:00
|
|
|
|
2025-05-06 14:22:32 -03:00
|
|
|
// If the original does not have the component, then the clone shouldn't have it either.
|
Changeling devour and transform (#34002)
* Initial:
Create Devour componentry, preliminary identity storage and the systems
for Devouring
* I have genuinely no idea what i'm doing
- added the radial menu, it has nothing in it.
- trying to get it to populate. the event under the event is broken,
i don't know why, but apparently it's not typed right
- Added a placeholder transform
- oh also fixed up some devour stuff and moved some things around.
* Holey moley, Transform, better devour, oh my!
- Move DnaComponent into Shared because we need it for the DNA cloning
- Make Transform MOSTLY work on the LAST identity devoured.
- Fix some issues on devour that involved prediction, canceling and
Damage exeucting (Thanks Plykiya for pointing out AttemptFrequency!)
* Proper tail stealing and Damage modifier attempt
Add check to add a wagging component on the Changeling if the victim's
species Prototype had one.
attempt to add the Damage mitigation check
* MAJOR CLEANUP AND FIXES AUGH 3 DAYS!!!
- Nullspaced a clone of a victim
- fix audio using server virtualized Pvs (i hate this)
- fix the mispredicted doafters
- Clean up a wholelotta code
- utilize clone systems to clone appearances
- Move CloneAppearance from server to shared So we can actually access
it
* Examine stuff, more cleanup, Jumpsuit ripping
- make rotting prevent the action
- Add ripping of clothing (guh why is it also server)
- add some System stuff for pushing husked corpse inspection
- clean up more badcode
* Doing things properly, UI sorta kinda works.
- Utilize Relayed events for Devour checking
- Get a UI that partially works, Says the name of identities, doesn't
show their looks
- Make use of the New Dynamic BUI assignment
- commit the sin of no client prediction cause nullspace entities aren't
networked
* Got an entity for the Frontend transform
Issue with the looks
* Stick a camera into a fake mobs forehead
- Get the UI to see the net entity in pause space by using a
ViewSubscriber to get the Pvs from the initially stored identity entity
- Remove all the other parts used to try to get this to work before hand
* Raaaaadiallllllls also fix protection coefficents
- Change FancyWindow to Radial
- Fix Issue where coeffeient checking was the wrong way round
* absolutely massive cleanup, no more camera in mobs
- cleaned up event variables that are not needed
- Removed the use of a Pause space and go back to Nullspace usage
- use a PvsOverride rather than ViewSharing
- Remove old commented out code and Lots of unused code
* Fix "Ui elements" dying on the screen
- some minor cleanup
- don't start the entities that get cloned
* ftl, cleanup, and fixing missing transform details
- add replace functionality to TypingIndicatorSystem and
BodyEmotesSystem
- add placeholder sounds and functions to TransformBodyEmotes
- add extra Pvs handling for later use
- attributions for the funny straw sound
- Sound collections for all of the sounds
- various cleanups
* Some extra cleanup
* Fix some false assumptions about TypingIndicator
- Bubbles now transfer on spawned humans rather than used humans
- Clean up YET MORE CODE
- make it so you can't eat yourself
* Oooprs, forgot to add a Husked Corpse Loc
* Missing period in the husked corpse loc
* bad devour windup placeholder
* Husking and WIP Lungs
- Husking now will be prevented from Revival fully and will change
the appearance of players
* Add finalized Sprites for actions and final meta
- add devour on and off sprites
- add transform action sprite
- Add Armblade sprite for future use
- Credit obscenelytinyshark for the sprites <3
* Remove ling lungs, Entity<> everything
- Remove the ling lungs stuff for now... body system is overly
complicated, makes my head hurt
- Switch every method to use Entity<> from Uid, Comp format
* cleanup, admin logging, WIP Roles
* Admin verb, Roundstart, gamerule stuff
- add a Admin verb to make Changelingification easy!
- Add game rule stuff for admin verb and to tell the hapless
goober how to be a changeling... sorta
- clean up parts to make VV easy... USE THE VERB!!
* Armor Coefficent Check
- Remove bespoke changeling armor check and replace it
with a generic armor coefficient query.
* move to UnrevivableComponent instead of husked
- Move UnrevivableComponent to shared
- add Analyzable and ReasonMessage to UnrevivableComponent
to give granular control of the message and whether or not it shows up
in the analyzer
- remove the check for HuskedComponent in DefibrillatorSystem
* aaaaaaa CopyComp
- Some cleanup
- make Vocal system shared
- make VocalSystem Not make more Actions than it needs
- Use some code from ChameleonProjector so we can copy components
- partially ungod method the Transform system
* Cleanup, Moving more things to CopyComp
- TransformBodyEmotes now uses CopyComp (it's a server component so i
need to tell the server to deal with it
- TypingIndicatorComponent also now uses CopyComp
- cleaned up old, now unused "replace" methods in favor of CopyComp
- BodyEmotesSystem now has a publically accessable LoadSounds to deal
with the same problem Screaming had
* WIP
* Devour Windup noise, ForensicsSystem cleanup
* Revert VocalSystem Changes
- Reverted Moving VocalSystem to shared, copy comp acomplishes it
- added component.ScreamActionEntity = null; for copy comp
* cleanup unneeded comments
* revert an accidental line removal
* Remove duplicate SharedHumanoidAppearanceSystem
* Cleanup Typo's and import Forensics components for Dna
* Some more forensics calls
* cleanup use CopyComp for now until CopyComps
* CR cleanup
* Undo some SharedHumanoidAppearanceSystem changes
* Confound these spaces
* Some Copycomp stuff and fixing some PVS override
* use the proper TryCopyComps that are merged
* Change TransformMenu with RadialWithSector
* All sounds done, Fix lack of typing indicator issue
* Updated attributions to include used sound authors
* some ftl typos and mind_role text issue
* DNA, Screaming, appearance, grammar, wagging
- reduced all of the above using ApplyComponentChanges
- Issue still remains with bodyEmotes sticking around in the UI
* Fix UI stuff, partials, entprotoid, good practices
- bunch of partials added
- UI now has a predicted message
- EntProtoID in the admin verb
- RipClothing now uses Entity<ButcherableComponent>
- husking is now optional (off by default) for testing/till we have
hivemind/when we figure out what were doing with devour
- remove TransformGrammarSet
* More CR stuff and documentation
- Make TargetIsProtected less of a meme, with a prototype
set of DamageTypes to check
- Documenation everywhere
- Move DevourEvents into its own file
* Predicted sounds and fix the comp clone list
- Made all start and stop sounds shared
- Split out the rest of the events and UI stuff into subfiles
- Fixed some Clone comp list issues where comments had -'s causing them
to be read incorrectly
* Damage cap check, Identity Shutdown cleanup, cleanup
* Sound stuff (but actually this time)
* Missed documentation
* Missed Documentation and a EntProtoId
* Remove unused dependency
* Remove a nullcheck
* Some dummy minplayers
* CR - Husked now uses a rem/ensure
* Update Actions in the Prototype
* Fixup mindswap handover
- cleanup and handover PVS on mindswap
* Fixup Missing meta from accidental "Take-theirs"
* Add the Armblade to the roundstart-role
* Cleanup, CR (everything but the UI and renames)
* missed a spot
* missed some more whitespace
* Renames
* Primary constructor and a space in these trying times
* User interface stuff for Slime transformation
* popup prediction
* Ling devour no longer makes duplicate identities
- added a key to identities to the original victim
- Add some extra clone settings
* add guard statements to OnClones
* SentOnlyToOwner additions
* fix for sound stoppage error
* Move Organ deleter into soon to be atomized husk
* clone event inventory
* mono sounds
* lower sound volume
* Fix networked sound warning
* Clone comps thing
* review
* attributions
* Fix clobbered changes
* I'm gonna weh out
- whole bunch of CR changes
* fix some very buggy git
* okay its fixed
* address most review points
* fix inventory
* we hate entityuids
* fix test and more cleanup
* move this
* fix more stuff
* fix validation and rootable
* Remove Quickswitch due to some UI quirks
* oops left out some better explanation
* remove dangling LastConsumed component fields
* fix test fail
* try this
* cleanup cloning subscriptions, add movement speed modifier
* fix slime storage
* fix cloning setting inheritance
* Add session information to transform admin logs
* slay the integration test hydra
* dwarf size
* more volume tweaks
* comments
* improve comments and unpredict deletion due to errors when shutting down the server
* fix displancement cloning
---------
Co-authored-by: ScarKy0 <scarky0@onet.eu>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
2025-08-06 16:55:49 -03:00
|
|
|
if (!HasComp(original, componentRegistration.Type))
|
|
|
|
|
RemComp(clone, componentRegistration.Type);
|
2025-05-06 14:22:32 -03:00
|
|
|
}
|
2023-04-29 10:50:10 +01:00
|
|
|
|
2025-05-06 14:22:32 -03:00
|
|
|
var cloningEv = new CloningEvent(settings, clone);
|
|
|
|
|
RaiseLocalEvent(original, ref cloningEv); // used for datafields that cannot be directly copied using CopyComp
|
2025-03-02 16:50:12 +01:00
|
|
|
}
|
2020-10-30 01:05:18 +01:00
|
|
|
|
2025-03-02 16:50:12 +01:00
|
|
|
/// <summary>
|
|
|
|
|
/// Copies the equipment the original has to the clone.
|
|
|
|
|
/// This uses the original prototype of the items, so any changes to components that are done after spawning are lost!
|
|
|
|
|
/// </summary>
|
2025-03-16 23:02:19 +01:00
|
|
|
public void CopyEquipment(Entity<InventoryComponent?> original, Entity<InventoryComponent?> clone, SlotFlags slotFlags, EntityWhitelist? whitelist = null, EntityWhitelist? blacklist = null)
|
2025-03-02 16:50:12 +01:00
|
|
|
{
|
2025-03-16 23:02:19 +01:00
|
|
|
if (!Resolve(original, ref original.Comp) || !Resolve(clone, ref clone.Comp))
|
2025-03-02 16:50:12 +01:00
|
|
|
return;
|
2025-03-16 23:02:19 +01:00
|
|
|
|
|
|
|
|
var coords = Transform(clone).Coordinates;
|
|
|
|
|
|
2025-03-02 16:50:12 +01:00
|
|
|
// Iterate over all inventory slots
|
2025-03-16 23:02:19 +01:00
|
|
|
var slotEnumerator = _inventory.GetSlotEnumerator(original, slotFlags);
|
2025-03-02 16:50:12 +01:00
|
|
|
while (slotEnumerator.NextItem(out var item, out var slot))
|
2022-08-29 22:31:27 -04:00
|
|
|
{
|
2025-03-16 23:02:19 +01:00
|
|
|
var cloneItem = CopyItem(item, coords, whitelist, blacklist);
|
2022-08-29 22:31:27 -04:00
|
|
|
|
2025-03-16 23:02:19 +01:00
|
|
|
if (cloneItem != null && !_inventory.TryEquip(clone, cloneItem.Value, slot.Name, silent: true, inventory: clone.Comp))
|
|
|
|
|
Del(cloneItem); // delete it again if the clone cannot equip it
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Copies an item and its storage recursively, placing all items at the same position in grid storage.
|
|
|
|
|
/// This uses the original prototype of the items, so any changes to components that are done after spawning are lost!
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// This is not perfect and only considers item in storage containers.
|
|
|
|
|
/// Some components have their own additional spawn logic on map init, so we cannot just copy all containers.
|
|
|
|
|
/// </remarks>
|
|
|
|
|
public EntityUid? CopyItem(EntityUid original, EntityCoordinates coords, EntityWhitelist? whitelist = null, EntityWhitelist? blacklist = null)
|
|
|
|
|
{
|
|
|
|
|
// we use a whitelist and blacklist to be sure to exclude any problematic entities
|
|
|
|
|
if (!_whitelist.CheckBoth(original, blacklist, whitelist))
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
var prototype = MetaData(original).EntityPrototype?.ID;
|
|
|
|
|
if (prototype == null)
|
|
|
|
|
return null;
|
|
|
|
|
|
2025-06-26 19:50:49 -04:00
|
|
|
var spawned = SpawnAtPosition(prototype, coords);
|
2025-03-16 23:02:19 +01:00
|
|
|
|
2025-03-26 17:13:02 +01:00
|
|
|
// copy over important component data
|
|
|
|
|
var ev = new CloningItemEvent(spawned);
|
|
|
|
|
RaiseLocalEvent(original, ref ev);
|
2025-03-16 23:02:19 +01:00
|
|
|
|
|
|
|
|
// if the original has items inside its storage, copy those as well
|
|
|
|
|
if (TryComp<StorageComponent>(original, out var originalStorage) && TryComp<StorageComponent>(spawned, out var spawnedStorage))
|
|
|
|
|
{
|
|
|
|
|
// remove all items that spawned with the entity inside its storage
|
|
|
|
|
// this ignores other containers, but this should be good enough for our purposes
|
|
|
|
|
_container.CleanContainer(spawnedStorage.Container);
|
|
|
|
|
|
|
|
|
|
// recursively replace them
|
|
|
|
|
// surely no one will ever create two items that contain each other causing an infinite loop, right?
|
|
|
|
|
foreach ((var itemUid, var itemLocation) in originalStorage.StoredItems)
|
|
|
|
|
{
|
|
|
|
|
var copy = CopyItem(itemUid, coords, whitelist, blacklist);
|
|
|
|
|
if (copy != null)
|
|
|
|
|
_storage.InsertAt((spawned, spawnedStorage), copy.Value, itemLocation, out _, playSound: false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return spawned;
|
|
|
|
|
}
|
2022-08-29 22:31:27 -04:00
|
|
|
|
2025-03-16 23:02:19 +01:00
|
|
|
/// <summary>
|
|
|
|
|
/// Copies an item's storage recursively to another storage.
|
|
|
|
|
/// The storage grids should have the same shape or it will drop on the floor.
|
|
|
|
|
/// Basically the same as CopyItem, but we don't copy the outermost container.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void CopyStorage(Entity<StorageComponent?> original, Entity<StorageComponent?> target, EntityWhitelist? whitelist = null, EntityWhitelist? blacklist = null)
|
|
|
|
|
{
|
|
|
|
|
if (!Resolve(original, ref original.Comp, false) || !Resolve(target, ref target.Comp, false))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var coords = Transform(target).Coordinates;
|
|
|
|
|
|
|
|
|
|
// delete all items in the target storage
|
|
|
|
|
_container.CleanContainer(target.Comp.Container);
|
|
|
|
|
|
|
|
|
|
// recursively replace them
|
|
|
|
|
foreach ((var itemUid, var itemLocation) in original.Comp.StoredItems)
|
|
|
|
|
{
|
|
|
|
|
var copy = CopyItem(itemUid, coords, whitelist, blacklist);
|
|
|
|
|
if (copy != null)
|
|
|
|
|
_storage.InsertAt(target, copy.Value, itemLocation, out _, playSound: false);
|
2020-10-30 01:05:18 +01:00
|
|
|
}
|
2020-08-19 10:23:20 -04:00
|
|
|
}
|
2025-03-18 06:21:56 +01:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Copies all implants from one mob to another.
|
|
|
|
|
/// Might result in duplicates if the target already has them.
|
|
|
|
|
/// Can copy the storage inside a storage implant according to a whitelist and blacklist.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="original">Entity to copy implants from.</param>
|
|
|
|
|
/// <param name="target">Entity to copy implants to.</param>
|
|
|
|
|
/// <param name="copyStorage">If true will copy storage of the implants (E.g storage implant)</param>
|
|
|
|
|
/// <param name="whitelist">Whitelist for the storage copy (If copyStorage is true)</param>
|
|
|
|
|
/// <param name="blacklist">Blacklist for the storage copy (If copyStorage is true)</param>
|
|
|
|
|
public void CopyImplants(Entity<ImplantedComponent?> original, EntityUid target, bool copyStorage = false, EntityWhitelist? whitelist = null, EntityWhitelist? blacklist = null)
|
|
|
|
|
{
|
|
|
|
|
if (!Resolve(original, ref original.Comp, false))
|
|
|
|
|
return; // they don't have any implants to copy!
|
|
|
|
|
|
|
|
|
|
foreach (var originalImplant in original.Comp.ImplantContainer.ContainedEntities)
|
|
|
|
|
{
|
|
|
|
|
if (!HasComp<SubdermalImplantComponent>(originalImplant))
|
|
|
|
|
continue; // not an implant (should only happen with admin shenanigans)
|
|
|
|
|
|
|
|
|
|
var implantId = MetaData(originalImplant).EntityPrototype?.ID;
|
|
|
|
|
|
|
|
|
|
if (implantId == null)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
var targetImplant = _subdermalImplant.AddImplant(target, implantId);
|
|
|
|
|
|
2025-03-26 17:13:02 +01:00
|
|
|
if (targetImplant == null)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// copy over important component data
|
|
|
|
|
var ev = new CloningItemEvent(targetImplant.Value);
|
|
|
|
|
RaiseLocalEvent(originalImplant, ref ev);
|
|
|
|
|
|
|
|
|
|
if (copyStorage)
|
2025-03-18 06:21:56 +01:00
|
|
|
CopyStorage(originalImplant, targetImplant.Value, whitelist, blacklist); // only needed for storage implants
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2020-08-19 10:23:20 -04:00
|
|
|
}
|