Skip to content

Commit

Permalink
Metempsychosis Returns (#685)
Browse files Browse the repository at this point in the history
* Metempsychosis Returns

* Last updates

* Fixin the linter

* Update lathe.yml

* Update CloningSystem.cs

* Fixing the random name bug

* Fugitive, rough but functional

* Update fugitive.yml

* Update humanoid.yml

* Checking if its the floortile

* Guh

* Update EntityTest.cs

* Revert "Update EntityTest.cs"

This reverts commit 82375ac.

* Revert "Guh"

This reverts commit bc98f0f.

* Revert "Checking if its the floortile"

This reverts commit 51d3355.

* Revert "Update humanoid.yml"

This reverts commit 5af8fbd.

* Revert "Update fugitive.yml"

This reverts commit 13124db.

* Revert "Fugitive, rough but functional"

This reverts commit 47586c3.

* Update Content.Server/Medical/Components/MedicalScannerComponent.cs

Co-authored-by: DEATHB4DEFEAT <[email protected]>
Signed-off-by: VMSolidus <[email protected]>

* Update Content.Server/Nyanotrasen/Cloning/MetempsychosisKarmaComponent.cs

Co-authored-by: DEATHB4DEFEAT <[email protected]>
Signed-off-by: VMSolidus <[email protected]>

* Update Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineComponent.cs

Co-authored-by: DEATHB4DEFEAT <[email protected]>
Signed-off-by: VMSolidus <[email protected]>

* Update Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineSystem.cs

Co-authored-by: DEATHB4DEFEAT <[email protected]>
Signed-off-by: VMSolidus <[email protected]>

* Update Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineSystem.cs

Co-authored-by: DEATHB4DEFEAT <[email protected]>
Signed-off-by: VMSolidus <[email protected]>

* Update Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineSystem.cs

Co-authored-by: DEATHB4DEFEAT <[email protected]>
Signed-off-by: VMSolidus <[email protected]>

* Update Resources/Prototypes/Nyanotrasen/Entities/Structures/Machines/metempsychoticMachine.yml

Co-authored-by: DEATHB4DEFEAT <[email protected]>
Signed-off-by: VMSolidus <[email protected]>

* Update Resources/Prototypes/Nyanotrasen/Research/biochemical.yml.yml

Co-authored-by: DEATHB4DEFEAT <[email protected]>
Signed-off-by: VMSolidus <[email protected]>

* Update Resources/Textures/Nyanotrasen/Structures/Machines/metempsychotic.rsi/meta.json

Co-authored-by: DEATHB4DEFEAT <[email protected]>
Signed-off-by: VMSolidus <[email protected]>

* Update CloningSystem.cs

Signed-off-by: VMSolidus <[email protected]>

* Update CloningSystem.cs

* Update Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineSystem.cs

Co-authored-by: DEATHB4DEFEAT <[email protected]>
Signed-off-by: VMSolidus <[email protected]>

* Update MetempsychoticMachineSystem.cs

* Cleaning up some of the Metem code

* Update CloningConsoleSystem.cs

reordering for less merge conflict

Signed-off-by: VMSolidus <[email protected]>

* Reordering usings for less merge conflicts

Signed-off-by: VMSolidus <[email protected]>

* Update HumanoidAppearanceComponent.cs

Signed-off-by: VMSolidus <[email protected]>

* Update CloningSystem.cs

Signed-off-by: VMSolidus <[email protected]>

* Apply suggestions from code review

Co-authored-by: DEATHB4DEFEAT <[email protected]>
Signed-off-by: VMSolidus <[email protected]>

* Update CloningConsoleSystem.cs

Somehow this got removed during cleanup

Signed-off-by: VMSolidus <[email protected]>

* Update CloningConsoleSystem.cs

Signed-off-by: VMSolidus <[email protected]>

* Update CloningSystem.cs

I put it back in the wrong file...

Signed-off-by: VMSolidus <[email protected]>

* Update CloningConsoleSystem.cs

Signed-off-by: VMSolidus <[email protected]>

* Apply suggestions from code review

Co-authored-by: DEATHB4DEFEAT <[email protected]>
Signed-off-by: VMSolidus <[email protected]>

* Requested changes but need assistance with test fail

* biochem is gone apparently

* Update experimental.yml

Signed-off-by: VMSolidus <[email protected]>

* Update MetempsychosisTest.cs

* Update CloningSystem.cs

---------

Signed-off-by: VMSolidus <[email protected]>
Co-authored-by: DEATHB4DEFEAT <[email protected]>
  • Loading branch information
VMSolidus and DEATHB4DEFEAT authored Feb 18, 2024
1 parent 1e83a0e commit 8df7cc3
Show file tree
Hide file tree
Showing 19 changed files with 359 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using Content.Server.Nyanotrasen.Cloning;
using Content.Shared.Humanoid.Prototypes;
using Content.Shared.Random;
using Robust.Shared.Prototypes;

namespace Content.IntegrationTests.Tests.DeltaV;

[TestFixture]
[TestOf(typeof(MetempsychoticMachineSystem))]
public sealed class MetempsychosisTest
{
[Test]
public async Task AllHumanoidPoolSpeciesExist()
{
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;
// Per RobustIntegrationTest.cs, wait until state is settled to access it.
await server.WaitIdleAsync();

var prototypeManager = server.ResolveDependency<IPrototypeManager>();

var metemComponent = new MetempsychoticMachineComponent();

await server.WaitAssertion(() =>
{
prototypeManager.TryIndex<WeightedRandomPrototype>(metemComponent.MetempsychoticHumanoidPool,
out var humanoidPool);
prototypeManager.TryIndex<WeightedRandomPrototype>(metemComponent.MetempsychoticNonHumanoidPool,
out var nonHumanoidPool);

Assert.That(humanoidPool, Is.Not.Null, "MetempsychoticHumanoidPool is null!");
Assert.That(nonHumanoidPool, Is.Not.Null, "MetempsychoticNonHumanoidPool is null!");

Assert.That(humanoidPool.Weights, Is.Not.Empty,
"MetempsychoticHumanoidPool has no valid prototypes!");
Assert.That(nonHumanoidPool.Weights, Is.Not.Empty,
"MetempsychoticNonHumanoidPool has no valid prototypes!");

foreach (var key in humanoidPool.Weights.Keys)
{
Assert.That(prototypeManager.TryIndex<SpeciesPrototype>(key, out _),
$"MetempsychoticHumanoidPool has invalid prototype {key}!");
}

foreach (var key in nonHumanoidPool.Weights.Keys)
{
Assert.That(prototypeManager.TryIndex<EntityPrototype>(key, out _),
$"MetempsychoticNonHumanoidPool has invalid prototype {key}!");
}
});
await pair.CleanReturnAsync();
}
}
6 changes: 3 additions & 3 deletions Content.Server/Cloning/CloningConsoleSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public sealed class CloningConsoleSystem : EntitySystem
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
[Dependency] private readonly PowerReceiverSystem _powerReceiverSystem = default!;
[Dependency] private readonly SharedMindSystem _mindSystem = default!;

public override void Initialize()
{
base.Initialize();
Expand Down Expand Up @@ -169,8 +169,8 @@ public void TryClone(EntityUid uid, EntityUid cloningPodUid, EntityUid scannerUi

if (mind.UserId.HasValue == false || mind.Session == null)
return;

if (_cloningSystem.TryCloning(cloningPodUid, body.Value, (mindId, mind), cloningPod, scannerComp.CloningFailChanceMultiplier))
// Nyano: Adds scannerComp.MetemKarmaBonus
if (_cloningSystem.TryCloning(cloningPodUid, body.Value, (mindId, mind), cloningPod, scannerComp.CloningFailChanceMultiplier, scannerComp.MetemKarmaBonus))
_adminLogger.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(uid)} successfully cloned {ToPrettyString(body.Value)}.");
}

Expand Down
111 changes: 105 additions & 6 deletions Content.Server/Cloning/CloningSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,22 @@
using Robust.Shared.Physics.Components;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Content.Server.Psionics;
using Content.Server.Traits.Assorted; //Nyano - Summary: allows the potential psionic ability to be written to the character.
using Content.Server.Psionics; //DeltaV needed for Psionic Systems
using Content.Shared.Speech; //DeltaV Start Metem Usings
using Content.Shared.Tag;
using Content.Shared.Preferences;
using Content.Shared.Emoting;
using Content.Server.Speech.Components;
using Content.Server.StationEvents.Components;
using Content.Server.Ghost.Roles.Components;
using Content.Server.Nyanotrasen.Cloning;
using Content.Shared.Humanoid.Prototypes;
using Robust.Shared.GameObjects.Components.Localization; //DeltaV End Metem Usings
using Content.Server.EntityList;
using Content.Shared.SSDIndicator;
using Content.Shared.Damage.ForceSay;
using Content.Server.Polymorph.Components;

namespace Content.Server.Cloning
{
Expand Down Expand Up @@ -62,6 +76,8 @@ public sealed class CloningSystem : EntitySystem
[Dependency] private readonly SharedMindSystem _mindSystem = default!;
[Dependency] private readonly MetaDataSystem _metaSystem = default!;
[Dependency] private readonly SharedJobSystem _jobs = default!;
[Dependency] private readonly MetempsychoticMachineSystem _metem = default!; //DeltaV
[Dependency] private readonly TagSystem _tag = default!; //DeltaV

public readonly Dictionary<MindComponent, EntityUid> ClonesWaitingForMind = new();
public const float EasyModeCloningCost = 0.7f;
Expand Down Expand Up @@ -136,8 +152,8 @@ private void OnExamined(EntityUid uid, CloningPodComponent component, ExaminedEv

args.PushMarkup(Loc.GetString("cloning-pod-biomass", ("number", _material.GetMaterialAmount(uid, component.RequiredMaterial))));
}

public bool TryCloning(EntityUid uid, EntityUid bodyToClone, Entity<MindComponent> mindEnt, CloningPodComponent? clonePod, float failChanceModifier = 1)
// Nyano: Adds float karmaBonus
public bool TryCloning(EntityUid uid, EntityUid bodyToClone, Entity<MindComponent> mindEnt, CloningPodComponent? clonePod, float failChanceModifier = 1, float karmaBonus = 0.25f)
{
if (!Resolve(uid, ref clonePod))
return false;
Expand Down Expand Up @@ -167,6 +183,12 @@ public bool TryCloning(EntityUid uid, EntityUid bodyToClone, Entity<MindComponen
if (!TryComp<HumanoidAppearanceComponent>(bodyToClone, out var humanoid))
return false; // whatever body was to be cloned, was not a humanoid

// Begin Nyano-code: allow paradox anomalies to be cloned.
var pref = humanoid.LastProfileLoaded;

if (pref == null)
return false;
// End Nyano-code
if (!_prototype.TryIndex(humanoid.Species, out var speciesPrototype))
return false;

Expand Down Expand Up @@ -222,11 +244,11 @@ public bool TryCloning(EntityUid uid, EntityUid bodyToClone, Entity<MindComponen
AddComp<ActiveCloningPodComponent>(uid);
return true;
}
// End Nyano-code.
}
// end of genetic damage checks

var mob = Spawn(speciesPrototype.Prototype, Transform(uid).MapPosition);
_humanoidSystem.CloneAppearance(bodyToClone, mob);
var mob = FetchAndSpawnMob(clonePod, pref, speciesPrototype, humanoid, bodyToClone, karmaBonus); //DeltaV Replaces CloneAppearance with Metem/Clone via FetchAndSpawnMob

///Nyano - Summary: adds the potential psionic trait to the reanimated mob.
EnsureComp<PotentialPsionicComponent>(mob);
Expand Down Expand Up @@ -326,7 +348,6 @@ private void EndFailedCloning(EntityUid uid, CloningPodComponent clonePod)
var transform = Transform(uid);
var indices = _transformSystem.GetGridTilePositionOrDefault((uid, transform));
var tileMix = _atmosphereSystem.GetTileMixture(transform.GridUid, null, indices, true);

if (HasComp<EmaggedComponent>(uid))
{
_audio.PlayPvs(clonePod.ScreamSound, uid);
Expand Down Expand Up @@ -354,6 +375,84 @@ private void EndFailedCloning(EntityUid uid, CloningPodComponent clonePod)
RemCompDeferred<ActiveCloningPodComponent>(uid);
}

/// <summary>
/// Start Nyano Code: Handles fetching the mob and any appearance stuff...
/// </summary>
private EntityUid FetchAndSpawnMob(CloningPodComponent clonePod, HumanoidCharacterProfile pref, SpeciesPrototype speciesPrototype, HumanoidAppearanceComponent humanoid, EntityUid bodyToClone, float karmaBonus)
{
List<Sex> sexes = new();
bool switchingSpecies = false;
bool applyKarma = false;
var toSpawn = speciesPrototype.Prototype;
TryComp<MetempsychosisKarmaComponent>(bodyToClone, out var oldKarma);

if (TryComp<MetempsychoticMachineComponent>(clonePod.Owner, out var metem))
{
toSpawn = _metem.GetSpawnEntity(clonePod.Owner, karmaBonus, metem, speciesPrototype, out var newSpecies, oldKarma?.Score);
applyKarma = true;

if (newSpecies != null)
{
sexes = newSpecies.Sexes;

if (speciesPrototype.ID != newSpecies.ID)
switchingSpecies = true;

speciesPrototype = newSpecies;
}
}

var mob = Spawn(toSpawn, Transform(clonePod.Owner).MapPosition);
if (TryComp<HumanoidAppearanceComponent>(mob, out var newHumanoid))
{
if (switchingSpecies || HasComp<MetempsychosisKarmaComponent>(bodyToClone))
{
pref = HumanoidCharacterProfile.RandomWithSpecies(newHumanoid.Species);
if (sexes.Contains(humanoid.Sex))
pref = pref.WithSex(humanoid.Sex);

pref = pref.WithGender(humanoid.Gender);
pref = pref.WithAge(humanoid.Age);

}
_humanoidSystem.LoadProfile(mob, pref);
}

if (applyKarma)
{
var karma = EnsureComp<MetempsychosisKarmaComponent>(mob);
karma.Score++;
if (oldKarma != null)
karma.Score += oldKarma.Score;
}

var ev = new CloningEvent(bodyToClone, mob);
RaiseLocalEvent(bodyToClone, ref ev);

if (!ev.NameHandled)
_metaSystem.SetEntityName(mob, MetaData(bodyToClone).EntityName);

var grammar = EnsureComp<GrammarComponent>(mob);
grammar.ProperNoun = true;
grammar.Gender = humanoid.Gender;
Dirty(grammar);

EnsureComp<PotentialPsionicComponent>(mob);
EnsureComp<SpeechComponent>(mob);
EnsureComp<DamageForceSayComponent>(mob);
EnsureComp<EmotingComponent>(mob);
EnsureComp<MindContainerComponent>(mob);
EnsureComp<SSDIndicatorComponent>(mob);
RemComp<ReplacementAccentComponent>(mob);
RemComp<MonkeyAccentComponent>(mob);
RemComp<SentienceTargetComponent>(mob);
RemComp<GhostTakeoverAvailableComponent>(mob);

_tag.AddTag(mob, "DoorBumpOpener");

return mob;
}
//End Nyano Code
public void Reset(RoundRestartCleanupEvent ev)
{
ClonesWaitingForMind.Clear();
Expand Down
3 changes: 3 additions & 0 deletions Content.Server/Medical/Components/MedicalScannerComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,8 @@ public sealed partial class MedicalScannerComponent : SharedMedicalScannerCompon

[DataField, ViewVariables(VVAccess.ReadWrite)]
public float CloningFailChanceMultiplier = 1f;

// Nyano, needed for Metem Machine.
public float MetemKarmaBonus = 0.25f;
}
}
12 changes: 12 additions & 0 deletions Content.Server/Nyanotrasen/Cloning/MetempsychosisKarmaComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Content.Server.Nyanotrasen.Cloning
{
/// <summary>
/// This tracks how many times you have already been cloned and lowers your chance of getting a humanoid each time.
/// </summary>
[RegisterComponent]
public sealed partial class MetempsychosisKarmaComponent : Component
{
[DataField("score")]
public int Score = 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Content.Shared.Random;

namespace Content.Server.Nyanotrasen.Cloning
{
[RegisterComponent]
public sealed partial class MetempsychoticMachineComponent : Component
{
/// <summary>
/// Chance you will spawn as a humanoid instead of a non humanoid.
/// </summary>
[DataField("humanoidBaseChance")]
public float HumanoidBaseChance = 0.75f;

[ValidatePrototypeId<WeightedRandomPrototype>]
[DataField("metempsychoticHumanoidPool")]
public string MetempsychoticHumanoidPool = "MetempsychoticHumanoidPool";

[ValidatePrototypeId<WeightedRandomPrototype>]
[DataField("metempsychoticNonHumanoidPool")]
public string MetempsychoticNonHumanoidPool = "MetempsychoticNonhumanoidPool";
}
}
47 changes: 47 additions & 0 deletions Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Content.Shared.Humanoid.Prototypes;
using Content.Shared.Random;
using Content.Shared.Random.Helpers;
using Robust.Shared.Random;
using Robust.Shared.Prototypes;

namespace Content.Server.Nyanotrasen.Cloning
{
public sealed class MetempsychoticMachineSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;

private ISawmill _sawmill = default!;

public string GetSpawnEntity(EntityUid uid, float karmaBonus, MetempsychoticMachineComponent component, SpeciesPrototype oldSpecies, out SpeciesPrototype? species, int? karma = null)
{
var chance = component.HumanoidBaseChance + karmaBonus;

if (karma != null)
chance -= ((1 - component.HumanoidBaseChance) * (float) karma);

if (chance > 1 && _random.Prob(chance - 1))
{
species = oldSpecies;
return oldSpecies.Prototype;
}
else
chance = 1;

chance = Math.Clamp(chance, 0, 1);
if (_random.Prob(chance) &&
_prototypeManager.TryIndex<WeightedRandomPrototype>(component.MetempsychoticHumanoidPool, out var humanoidPool) &&
_prototypeManager.TryIndex<SpeciesPrototype>(humanoidPool.Pick(), out var speciesPrototype))
{
species = speciesPrototype;
return speciesPrototype.Prototype;
}
else
{
species = null;
_sawmill.Error("Could not index species for metempsychotic machine...");
return "MobHuman";
}
}
}
}
1 change: 1 addition & 0 deletions Content.Shared/Humanoid/HumanoidAppearanceComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
using Content.Shared.Preferences; //DeltaV, used for Metempsychosis, Fugitive, and Paradox Anomaly

namespace Content.Shared.Humanoid;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
research-technology-psionic-countermeasures = Psionic Countermeasures
research-technology-teleportation = Teleportation
research-technology-metempsychosis = Metempsychosis
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@
- MailingUnitElectronics
- SalvageMagnetMachineCircuitboard
- StationMapElectronics
# - MetempsychoticMachineCircuitboard
- MetempsychoticMachineCircuitboard
- DeepFryerMachineCircuitboard
# End Nyano additions
- SalvageExpeditionsComputerCircuitboard # DeltaV
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
- type: entity
id: MetempsychoticMachineCircuitboard
parent: BaseMachineCircuitboard
name: metempsychotic machine machine board
description: A machine printed circuit board for a cloning pod
components:
- type: Sprite
state: medical
- type: MachineBoard
prototype: MetempsychoticMachine
requirements:
Capacitor: 2
Manipulator: 2
materialRequirements:
Glass: 1
Cable: 1
- type: ReverseEngineering
difficulty: 3
recipes:
- MetempsychoticMachineCircuitboard

- type: entity
id: ReverseEngineeringMachineCircuitboard
parent: BaseMachineCircuitboard
Expand Down
Loading

0 comments on commit 8df7cc3

Please sign in to comment.