From 8df7cc309e89d4bb6614eb404b8e3361348279b2 Mon Sep 17 00:00:00 2001 From: VMSolidus Date: Sat, 17 Feb 2024 21:36:16 -0500 Subject: [PATCH] Metempsychosis Returns (#685) * 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 82375acd67cc44e740ba803a4329b4c2493cd273. * Revert "Guh" This reverts commit bc98f0f858e0f78e846f237bad384f7e00c4e3a7. * Revert "Checking if its the floortile" This reverts commit 51d3355cc11fffd7333d67235ffbe47665c783eb. * Revert "Update humanoid.yml" This reverts commit 5af8fbdabe576b8bfade1cc23025c525b455aee6. * Revert "Update fugitive.yml" This reverts commit 13124dbc77be3afdea047ac4dc533b3bafc1ed9f. * Revert "Fugitive, rough but functional" This reverts commit 47586c3b15595cb72c8e26e980e7f0ae79318d07. * Update Content.Server/Medical/Components/MedicalScannerComponent.cs Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> Signed-off-by: VMSolidus * Update Content.Server/Nyanotrasen/Cloning/MetempsychosisKarmaComponent.cs Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> Signed-off-by: VMSolidus * Update Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineComponent.cs Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> Signed-off-by: VMSolidus * Update Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineSystem.cs Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> Signed-off-by: VMSolidus * Update Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineSystem.cs Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> Signed-off-by: VMSolidus * Update Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineSystem.cs Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> Signed-off-by: VMSolidus * Update Resources/Prototypes/Nyanotrasen/Entities/Structures/Machines/metempsychoticMachine.yml Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> Signed-off-by: VMSolidus * Update Resources/Prototypes/Nyanotrasen/Research/biochemical.yml.yml Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> Signed-off-by: VMSolidus * Update Resources/Textures/Nyanotrasen/Structures/Machines/metempsychotic.rsi/meta.json Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> Signed-off-by: VMSolidus * Update CloningSystem.cs Signed-off-by: VMSolidus * Update CloningSystem.cs * Update Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineSystem.cs Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> Signed-off-by: VMSolidus * Update MetempsychoticMachineSystem.cs * Cleaning up some of the Metem code * Update CloningConsoleSystem.cs reordering for less merge conflict Signed-off-by: VMSolidus * Reordering usings for less merge conflicts Signed-off-by: VMSolidus * Update HumanoidAppearanceComponent.cs Signed-off-by: VMSolidus * Update CloningSystem.cs Signed-off-by: VMSolidus * Apply suggestions from code review Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> Signed-off-by: VMSolidus * Update CloningConsoleSystem.cs Somehow this got removed during cleanup Signed-off-by: VMSolidus * Update CloningConsoleSystem.cs Signed-off-by: VMSolidus * Update CloningSystem.cs I put it back in the wrong file... Signed-off-by: VMSolidus * Update CloningConsoleSystem.cs Signed-off-by: VMSolidus * Apply suggestions from code review Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> Signed-off-by: VMSolidus * Requested changes but need assistance with test fail * biochem is gone apparently * Update experimental.yml Signed-off-by: VMSolidus * Update MetempsychosisTest.cs * Update CloningSystem.cs --------- Signed-off-by: VMSolidus Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> --- .../Metempsychosis/MetempsychosisTest.cs | 53 +++++++++ .../Cloning/CloningConsoleSystem.cs | 6 +- Content.Server/Cloning/CloningSystem.cs | 111 +++++++++++++++++- .../Components/MedicalScannerComponent.cs | 3 + .../Cloning/MetempsychosisKarmaComponent.cs | 12 ++ .../Cloning/MetempsychoticMachineComponent.cs | 22 ++++ .../Cloning/MetempsychoticMachineSystem.cs | 47 ++++++++ .../Humanoid/HumanoidAppearanceComponent.cs | 1 + .../nyanotrasen/research/technologies.ftl | 1 + .../Entities/Structures/Machines/lathe.yml | 2 +- .../Devices/CircuitBoards/production.yml | 21 ++++ .../Machines/metempsychoticMachine.yml | 25 ++++ .../Recipes/Lathes/electronics.yml | 18 +-- .../Nyanotrasen/Research/experimental.yml | 16 +++ .../Nyanotrasen/metempsychoticHumanoids.yml | 13 ++ .../metempsychoticNonHumanoids.yml | 9 ++ .../Machines/metempsychotic.rsi/meta.json | 18 +++ .../Machines/metempsychotic.rsi/pod_0.png | Bin 0 -> 6842 bytes .../Machines/metempsychotic.rsi/pod_1.png | Bin 0 -> 16026 bytes 19 files changed, 359 insertions(+), 19 deletions(-) create mode 100644 Content.IntegrationTests/Tests/Nyanotrasen/Metempsychosis/MetempsychosisTest.cs create mode 100644 Content.Server/Nyanotrasen/Cloning/MetempsychosisKarmaComponent.cs create mode 100644 Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineComponent.cs create mode 100644 Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineSystem.cs create mode 100644 Resources/Prototypes/Nyanotrasen/Entities/Structures/Machines/metempsychoticMachine.yml create mode 100644 Resources/Prototypes/Nyanotrasen/metempsychoticHumanoids.yml create mode 100644 Resources/Prototypes/Nyanotrasen/metempsychoticNonHumanoids.yml create mode 100644 Resources/Textures/Nyanotrasen/Structures/Machines/metempsychotic.rsi/meta.json create mode 100644 Resources/Textures/Nyanotrasen/Structures/Machines/metempsychotic.rsi/pod_0.png create mode 100644 Resources/Textures/Nyanotrasen/Structures/Machines/metempsychotic.rsi/pod_1.png diff --git a/Content.IntegrationTests/Tests/Nyanotrasen/Metempsychosis/MetempsychosisTest.cs b/Content.IntegrationTests/Tests/Nyanotrasen/Metempsychosis/MetempsychosisTest.cs new file mode 100644 index 0000000000..cd6a4b4c2b --- /dev/null +++ b/Content.IntegrationTests/Tests/Nyanotrasen/Metempsychosis/MetempsychosisTest.cs @@ -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(); + + var metemComponent = new MetempsychoticMachineComponent(); + + await server.WaitAssertion(() => + { + prototypeManager.TryIndex(metemComponent.MetempsychoticHumanoidPool, + out var humanoidPool); + prototypeManager.TryIndex(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(key, out _), + $"MetempsychoticHumanoidPool has invalid prototype {key}!"); + } + + foreach (var key in nonHumanoidPool.Weights.Keys) + { + Assert.That(prototypeManager.TryIndex(key, out _), + $"MetempsychoticNonHumanoidPool has invalid prototype {key}!"); + } + }); + await pair.CleanReturnAsync(); + } +} diff --git a/Content.Server/Cloning/CloningConsoleSystem.cs b/Content.Server/Cloning/CloningConsoleSystem.cs index 4176806639..c95c37312e 100644 --- a/Content.Server/Cloning/CloningConsoleSystem.cs +++ b/Content.Server/Cloning/CloningConsoleSystem.cs @@ -32,7 +32,7 @@ namespace Content.Server.Cloning [Dependency] private readonly MobStateSystem _mobStateSystem = default!; [Dependency] private readonly PowerReceiverSystem _powerReceiverSystem = default!; [Dependency] private readonly SharedMindSystem _mindSystem = default!; - + public override void Initialize() { base.Initialize(); @@ -169,8 +169,8 @@ namespace Content.Server.Cloning 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)}."); } diff --git a/Content.Server/Cloning/CloningSystem.cs b/Content.Server/Cloning/CloningSystem.cs index eabf10013d..0061283367 100644 --- a/Content.Server/Cloning/CloningSystem.cs +++ b/Content.Server/Cloning/CloningSystem.cs @@ -33,8 +33,22 @@ using Robust.Shared.Containers; 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 { @@ -62,6 +76,8 @@ namespace Content.Server.Cloning [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 ClonesWaitingForMind = new(); public const float EasyModeCloningCost = 0.7f; @@ -136,8 +152,8 @@ namespace Content.Server.Cloning args.PushMarkup(Loc.GetString("cloning-pod-biomass", ("number", _material.GetMaterialAmount(uid, component.RequiredMaterial)))); } - - public bool TryCloning(EntityUid uid, EntityUid bodyToClone, Entity mindEnt, CloningPodComponent? clonePod, float failChanceModifier = 1) + // Nyano: Adds float karmaBonus + public bool TryCloning(EntityUid uid, EntityUid bodyToClone, Entity mindEnt, CloningPodComponent? clonePod, float failChanceModifier = 1, float karmaBonus = 0.25f) { if (!Resolve(uid, ref clonePod)) return false; @@ -167,6 +183,12 @@ namespace Content.Server.Cloning if (!TryComp(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; @@ -222,11 +244,11 @@ namespace Content.Server.Cloning AddComp(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(mob); @@ -326,7 +348,6 @@ namespace Content.Server.Cloning var transform = Transform(uid); var indices = _transformSystem.GetGridTilePositionOrDefault((uid, transform)); var tileMix = _atmosphereSystem.GetTileMixture(transform.GridUid, null, indices, true); - if (HasComp(uid)) { _audio.PlayPvs(clonePod.ScreamSound, uid); @@ -354,6 +375,84 @@ namespace Content.Server.Cloning RemCompDeferred(uid); } + /// + /// Start Nyano Code: Handles fetching the mob and any appearance stuff... + /// + private EntityUid FetchAndSpawnMob(CloningPodComponent clonePod, HumanoidCharacterProfile pref, SpeciesPrototype speciesPrototype, HumanoidAppearanceComponent humanoid, EntityUid bodyToClone, float karmaBonus) + { + List sexes = new(); + bool switchingSpecies = false; + bool applyKarma = false; + var toSpawn = speciesPrototype.Prototype; + TryComp(bodyToClone, out var oldKarma); + + if (TryComp(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(mob, out var newHumanoid)) + { + if (switchingSpecies || HasComp(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(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(mob); + grammar.ProperNoun = true; + grammar.Gender = humanoid.Gender; + Dirty(grammar); + + EnsureComp(mob); + EnsureComp(mob); + EnsureComp(mob); + EnsureComp(mob); + EnsureComp(mob); + EnsureComp(mob); + RemComp(mob); + RemComp(mob); + RemComp(mob); + RemComp(mob); + + _tag.AddTag(mob, "DoorBumpOpener"); + + return mob; + } + //End Nyano Code public void Reset(RoundRestartCleanupEvent ev) { ClonesWaitingForMind.Clear(); diff --git a/Content.Server/Medical/Components/MedicalScannerComponent.cs b/Content.Server/Medical/Components/MedicalScannerComponent.cs index aef56d6c0b..96de649987 100644 --- a/Content.Server/Medical/Components/MedicalScannerComponent.cs +++ b/Content.Server/Medical/Components/MedicalScannerComponent.cs @@ -15,5 +15,8 @@ namespace Content.Server.Medical.Components [DataField, ViewVariables(VVAccess.ReadWrite)] public float CloningFailChanceMultiplier = 1f; + + // Nyano, needed for Metem Machine. + public float MetemKarmaBonus = 0.25f; } } diff --git a/Content.Server/Nyanotrasen/Cloning/MetempsychosisKarmaComponent.cs b/Content.Server/Nyanotrasen/Cloning/MetempsychosisKarmaComponent.cs new file mode 100644 index 0000000000..246495cee0 --- /dev/null +++ b/Content.Server/Nyanotrasen/Cloning/MetempsychosisKarmaComponent.cs @@ -0,0 +1,12 @@ +namespace Content.Server.Nyanotrasen.Cloning +{ + /// + /// This tracks how many times you have already been cloned and lowers your chance of getting a humanoid each time. + /// + [RegisterComponent] + public sealed partial class MetempsychosisKarmaComponent : Component + { + [DataField("score")] + public int Score = 0; + } +} diff --git a/Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineComponent.cs b/Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineComponent.cs new file mode 100644 index 0000000000..0adcc9b5b2 --- /dev/null +++ b/Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineComponent.cs @@ -0,0 +1,22 @@ +using Content.Shared.Random; + +namespace Content.Server.Nyanotrasen.Cloning +{ + [RegisterComponent] + public sealed partial class MetempsychoticMachineComponent : Component + { + /// + /// Chance you will spawn as a humanoid instead of a non humanoid. + /// + [DataField("humanoidBaseChance")] + public float HumanoidBaseChance = 0.75f; + + [ValidatePrototypeId] + [DataField("metempsychoticHumanoidPool")] + public string MetempsychoticHumanoidPool = "MetempsychoticHumanoidPool"; + + [ValidatePrototypeId] + [DataField("metempsychoticNonHumanoidPool")] + public string MetempsychoticNonHumanoidPool = "MetempsychoticNonhumanoidPool"; + } +} diff --git a/Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineSystem.cs b/Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineSystem.cs new file mode 100644 index 0000000000..62dc1b078e --- /dev/null +++ b/Content.Server/Nyanotrasen/Cloning/MetempsychoticMachineSystem.cs @@ -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(component.MetempsychoticHumanoidPool, out var humanoidPool) && + _prototypeManager.TryIndex(humanoidPool.Pick(), out var speciesPrototype)) + { + species = speciesPrototype; + return speciesPrototype.Prototype; + } + else + { + species = null; + _sawmill.Error("Could not index species for metempsychotic machine..."); + return "MobHuman"; + } + } + } +} diff --git a/Content.Shared/Humanoid/HumanoidAppearanceComponent.cs b/Content.Shared/Humanoid/HumanoidAppearanceComponent.cs index b0bc0eb9a0..4785482ada 100644 --- a/Content.Shared/Humanoid/HumanoidAppearanceComponent.cs +++ b/Content.Shared/Humanoid/HumanoidAppearanceComponent.cs @@ -6,6 +6,7 @@ using Robust.Shared.GameStates; 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; diff --git a/Resources/Locale/en-US/nyanotrasen/research/technologies.ftl b/Resources/Locale/en-US/nyanotrasen/research/technologies.ftl index 6b0debd6fd..2aa6625c2c 100644 --- a/Resources/Locale/en-US/nyanotrasen/research/technologies.ftl +++ b/Resources/Locale/en-US/nyanotrasen/research/technologies.ftl @@ -1,2 +1,3 @@ research-technology-psionic-countermeasures = Psionic Countermeasures research-technology-teleportation = Teleportation +research-technology-metempsychosis = Metempsychosis diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 30cad0ea0a..f251f158b8 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -466,7 +466,7 @@ - MailingUnitElectronics - SalvageMagnetMachineCircuitboard - StationMapElectronics -# - MetempsychoticMachineCircuitboard + - MetempsychoticMachineCircuitboard - DeepFryerMachineCircuitboard # End Nyano additions - SalvageExpeditionsComputerCircuitboard # DeltaV diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/CircuitBoards/production.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/CircuitBoards/production.yml index a1a7a859e0..0e4c262b54 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/CircuitBoards/production.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/CircuitBoards/production.yml @@ -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 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Structures/Machines/metempsychoticMachine.yml b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Machines/metempsychoticMachine.yml new file mode 100644 index 0000000000..d8e791af1e --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Machines/metempsychoticMachine.yml @@ -0,0 +1,25 @@ +- type: entity + parent: CloningPod + id: MetempsychoticMachine + name: metempsychotic machine + description: Speeds along the transmigration of a soul to its next vessel. + components: + - type: MetempsychoticMachine + - type: CloningPod + - type: Machine + board: MetempsychoticMachineCircuitboard + - type: Sprite + sprite: Nyanotrasen/Structures/Machines/metempsychotic.rsi + snapCardinals: true + layers: + - state: pod_0 + - type: Appearance + - type: GenericVisualizer + visuals: + enum.CloningPodVisuals.Status: + base: + Cloning: { state: pod_1 } + NoMind: { state: pod_1 } + Gore: { state: pod_1 } + Idle: { state: pod_0 } + - type: Psionic diff --git a/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/electronics.yml b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/electronics.yml index 591b8aec08..418864cd40 100644 --- a/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/electronics.yml +++ b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/electronics.yml @@ -1,11 +1,11 @@ -#- type: latheRecipe -# id: MetempsychoticMachineCircuitboard -# result: MetempsychoticMachineCircuitboard -# completetime: 4 -# materials: -# Steel: 100 -# Glass: 900 -# Gold: 100 +- type: latheRecipe + id: MetempsychoticMachineCircuitboard + result: MetempsychoticMachineCircuitboard + completetime: 4 + materials: + Steel: 100 + Glass: 900 + Gold: 100 - type: latheRecipe id: ReverseEngineeringMachineCircuitboard @@ -50,4 +50,4 @@ completetime: 4 materials: Steel: 100 - Glass: 900 \ No newline at end of file + Glass: 900 diff --git a/Resources/Prototypes/Nyanotrasen/Research/experimental.yml b/Resources/Prototypes/Nyanotrasen/Research/experimental.yml index 78599728c0..7c89c0f7d0 100644 --- a/Resources/Prototypes/Nyanotrasen/Research/experimental.yml +++ b/Resources/Prototypes/Nyanotrasen/Research/experimental.yml @@ -14,6 +14,22 @@ - ClothingHeadCage # - ShellSoulbreaker # DeltaV - Placing it under Exotic Ammunition because that's what it is. +- type: technology + id: Metempsychosis + name: research-technology-metempsychosis + icon: + sprite: Nyanotrasen/Structures/Machines/metempsychotic.rsi + state: pod_0 + discipline: Experimental + tier: 2 + cost: 15000 + recipeUnlocks: + - BiomassReclaimerMachineCircuitboard + - CloningConsoleComputerCircuitboard + - MedicalScannerMachineCircuitboard + - MetempsychoticMachineCircuitboard + + # Tier 3 # - type: technology diff --git a/Resources/Prototypes/Nyanotrasen/metempsychoticHumanoids.yml b/Resources/Prototypes/Nyanotrasen/metempsychoticHumanoids.yml new file mode 100644 index 0000000000..891067b1c1 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/metempsychoticHumanoids.yml @@ -0,0 +1,13 @@ +- type: weightedRandom + id: MetempsychoticHumanoidPool # Species prototypes + weights: + Human: 1 + Felinid: 1 + Oni: 1 + Arachnid: 1 + Harpy: 1 + Moth: 1 + Diona: 0.5 + Reptilian: 0.5 + SlimePerson: 0.5 + Vulpkanin: 0.5 diff --git a/Resources/Prototypes/Nyanotrasen/metempsychoticNonHumanoids.yml b/Resources/Prototypes/Nyanotrasen/metempsychoticNonHumanoids.yml new file mode 100644 index 0000000000..dcbe23f608 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/metempsychoticNonHumanoids.yml @@ -0,0 +1,9 @@ +- type: weightedRandom + id: MetempsychoticNonhumanoidPool # Entity prototypes + weights: + MobMonkey: 1 + MobGorilla: 1 + # MobKangaroo: 0.5 # Mobs here need to be either VERY funny or up to standard. + MobXenoQueen: 0.01 + MobCrab: 0.01 + MobPenguin: 1 #ODJ's orders diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/metempsychotic.rsi/meta.json b/Resources/Textures/Nyanotrasen/Structures/Machines/metempsychotic.rsi/meta.json new file mode 100644 index 0000000000..7276fde67e --- /dev/null +++ b/Resources/Textures/Nyanotrasen/Structures/Machines/metempsychotic.rsi/meta.json @@ -0,0 +1,18 @@ +{ + "version": 1, + "license": "CC-BY-4.0", + "copyright": "Created by discord user Four Hydra Heads#2075 (971500282364178512)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "pod_0" + }, + { + "name": "pod_1", + "delays": [ [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 ] ] + } + ] +} diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/metempsychotic.rsi/pod_0.png b/Resources/Textures/Nyanotrasen/Structures/Machines/metempsychotic.rsi/pod_0.png new file mode 100644 index 0000000000000000000000000000000000000000..b7a870e9d2a661c67165cb5472430ee6a5b5a24d GIT binary patch literal 6842 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 V%F6?q+CX1|EKIFTN{kMN{}(E?8}k4F literal 0 HcmV?d00001 diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/metempsychotic.rsi/pod_1.png b/Resources/Textures/Nyanotrasen/Structures/Machines/metempsychotic.rsi/pod_1.png new file mode 100644 index 0000000000000000000000000000000000000000..750e0c7feda7226d9554c5b11d72e6e8a9fd1532 GIT binary patch literal 16026 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 Bb3y