fix metempsychosis (#2156)
* this is an insult to my sanity * this is an insult to my sanity * Revert "Merge branch 'shitcode' of https://github.com/MilonPL/Delta-v into shitcode" This reverts commit3de8ffc704, reversing changes made tob22c053376. * FUCKING GITSHIT * AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA * docs and shit
This commit is contained in:
parent
a4755ff66e
commit
38d6e87dd9
|
|
@ -1,12 +1,10 @@
|
|||
using Content.Server.Nyanotrasen.Cloning;
|
||||
using Content.Server.DeltaV.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]
|
||||
|
|
@ -23,18 +21,22 @@ public sealed class MetempsychosisTest
|
|||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
prototypeManager.TryIndex<WeightedRandomPrototype>(metemComponent.MetempsychoticHumanoidPool,
|
||||
prototypeManager.TryIndex(metemComponent.MetempsychoticHumanoidPool,
|
||||
out var humanoidPool);
|
||||
prototypeManager.TryIndex<WeightedRandomPrototype>(metemComponent.MetempsychoticNonHumanoidPool,
|
||||
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!");
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
@ -9,6 +9,8 @@ using Content.Server.Jobs;
|
|||
using Content.Server.Materials;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Server.Psionics; // DeltaV
|
||||
using Content.Server.Traits.Assorted; // DeltaV
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
|
|
@ -33,26 +35,10 @@ using Robust.Shared.Containers;
|
|||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
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
|
||||
{
|
||||
public sealed class CloningSystem : EntitySystem
|
||||
public sealed partial class CloningSystem : EntitySystem // DeltaV - Set to partial, see CloningSystem.Metempsychosis.cs
|
||||
{
|
||||
[Dependency] private readonly DeviceLinkSystem _signalSystem = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = null!;
|
||||
|
|
@ -76,8 +62,6 @@ 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<MindComponent, EntityUid> ClonesWaitingForMind = new();
|
||||
public const float EasyModeCloningCost = 0.7f;
|
||||
|
|
@ -158,6 +142,10 @@ namespace Content.Server.Cloning
|
|||
if (!Resolve(uid, ref clonePod))
|
||||
return false;
|
||||
|
||||
// DeltaV - This method should use Entity<CloningPodComponent> pod instead
|
||||
// But I don't want to completely mangle it so we do this here
|
||||
var podEnt = new Entity<CloningPodComponent>(uid, clonePod);
|
||||
|
||||
if (HasComp<ActiveCloningPodComponent>(uid))
|
||||
return false;
|
||||
|
||||
|
|
@ -244,13 +232,13 @@ namespace Content.Server.Cloning
|
|||
AddComp<ActiveCloningPodComponent>(uid);
|
||||
return true;
|
||||
}
|
||||
// End Nyano-code.
|
||||
}
|
||||
// end of genetic damage checks
|
||||
|
||||
var mob = FetchAndSpawnMob(clonePod, pref, speciesPrototype, humanoid, bodyToClone, karmaBonus); //DeltaV Replaces CloneAppearance with Metem/Clone via FetchAndSpawnMob
|
||||
// DeltaV - Replaces CloneAppearance with Metem/Clone via FetchAndSpawnMob
|
||||
var mob = FetchAndSpawnMob(podEnt, pref, speciesPrototype, humanoid, bodyToClone, karmaBonus);
|
||||
|
||||
///Nyano - Summary: adds the potential psionic trait to the reanimated mob.
|
||||
// Nyano - Summary: adds the potential psionic trait to the reanimated mob.
|
||||
EnsureComp<PotentialPsionicComponent>(mob);
|
||||
|
||||
var ev = new CloningEvent(bodyToClone, mob);
|
||||
|
|
@ -348,6 +336,7 @@ 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<EmaggedComponent>(uid))
|
||||
{
|
||||
_audio.PlayPvs(clonePod.ScreamSound, uid);
|
||||
|
|
@ -375,84 +364,6 @@ namespace Content.Server.Cloning
|
|||
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, _transformSystem.GetMapCoordinates(clonePod.Owner));
|
||||
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(mob, 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();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using Content.Server.Bible.Components;
|
||||
using Content.Server.Nyanotrasen.Cloning;
|
||||
using Content.Server.DeltaV.Cloning;
|
||||
using Content.Shared.Abilities.Psionics;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Body.Components;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,172 @@
|
|||
using Content.Server.DeltaV.Cloning;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Speech;
|
||||
using Content.Shared.Emoting;
|
||||
using Content.Shared.Damage.ForceSay;
|
||||
using Content.Shared.SSDIndicator;
|
||||
using Content.Server.Speech.Components;
|
||||
using Content.Server.Ghost.Roles.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Server.Psionics;
|
||||
using Robust.Shared.Random;
|
||||
using Content.Shared.Mind.Components;
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared.Cloning;
|
||||
using Content.Shared.Random.Helpers;
|
||||
using Robust.Shared.GameObjects.Components.Localization;
|
||||
|
||||
namespace Content.Server.Cloning;
|
||||
|
||||
public sealed partial class CloningSystem
|
||||
{
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
[Dependency] private readonly GrammarSystem _grammar = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the entity prototype to spawn for a clone based on karma and chance calculations.
|
||||
/// </summary>
|
||||
private string GetSpawnEntity(Entity<MetempsychoticMachineComponent> ent, float karmaBonus, SpeciesPrototype oldSpecies, out SpeciesPrototype? species, int karma = 0)
|
||||
{
|
||||
// First time being cloned - return original species
|
||||
if (karma == 0)
|
||||
{
|
||||
species = oldSpecies;
|
||||
return oldSpecies.Prototype;
|
||||
}
|
||||
|
||||
var chance = ent.Comp.HumanoidBaseChance + karmaBonus;
|
||||
chance -= (1 - ent.Comp.HumanoidBaseChance) * karma;
|
||||
|
||||
// Perfect clone chance
|
||||
if (chance > 1 && _robustRandom.Prob(chance - 1))
|
||||
{
|
||||
species = oldSpecies;
|
||||
return oldSpecies.Prototype;
|
||||
}
|
||||
|
||||
// Roll for humanoid vs non-humanoid
|
||||
chance = Math.Clamp(chance, 0, 1);
|
||||
if (_robustRandom.Prob(chance))
|
||||
{
|
||||
if (_prototype.TryIndex(ent.Comp.MetempsychoticHumanoidPool, out var humanoidPool))
|
||||
{
|
||||
var protoId = humanoidPool.Pick();
|
||||
if (_prototype.TryIndex<SpeciesPrototype>(protoId, out var speciesPrototype))
|
||||
{
|
||||
species = speciesPrototype;
|
||||
return speciesPrototype.Prototype;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (_prototype.TryIndex(ent.Comp.MetempsychoticNonHumanoidPool, out var nonHumanoidPool))
|
||||
{
|
||||
// For non-humanoids, return the entity prototype directly
|
||||
species = null;
|
||||
return nonHumanoidPool.Pick();
|
||||
}
|
||||
|
||||
// Fallback to original species if prototype indexing fails
|
||||
Log.Error("Failed to get valid clone type - falling back to original species");
|
||||
species = oldSpecies;
|
||||
return oldSpecies.Prototype;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles fetching the mob and managing appearance for cloning with metempsychosis mechanics
|
||||
/// </summary>
|
||||
private EntityUid FetchAndSpawnMob(
|
||||
Entity<CloningPodComponent> pod,
|
||||
HumanoidCharacterProfile pref,
|
||||
SpeciesPrototype speciesPrototype,
|
||||
HumanoidAppearanceComponent humanoid,
|
||||
EntityUid bodyToClone,
|
||||
float karmaBonus)
|
||||
{
|
||||
List<Sex> sexes = [];
|
||||
var switchingSpecies = false;
|
||||
var applyKarma = false;
|
||||
var toSpawn = speciesPrototype.Prototype;
|
||||
|
||||
// Get existing karma score or start at 0
|
||||
var karmaScore = 0;
|
||||
if (TryComp<MetempsychosisKarmaComponent>(bodyToClone, out var oldKarma))
|
||||
{
|
||||
karmaScore = oldKarma.Score;
|
||||
}
|
||||
|
||||
if (TryComp<MetempsychoticMachineComponent>(pod.Owner, out var metem))
|
||||
{
|
||||
var metemEntity = new Entity<MetempsychoticMachineComponent>(pod.Owner, metem);
|
||||
toSpawn = GetSpawnEntity(metemEntity, karmaBonus, speciesPrototype, out var newSpecies, karmaScore);
|
||||
applyKarma = true;
|
||||
|
||||
if (newSpecies != null)
|
||||
{
|
||||
sexes = newSpecies.Sexes;
|
||||
speciesPrototype = newSpecies;
|
||||
|
||||
if (speciesPrototype.ID != newSpecies.ID)
|
||||
switchingSpecies = true;
|
||||
}
|
||||
}
|
||||
|
||||
var mob = Spawn(toSpawn, _transformSystem.GetMapCoordinates(pod.Owner));
|
||||
|
||||
// Only try to handle humanoid appearance if we have a humanoid component
|
||||
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 = karmaScore + 1; // Increment karma 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);
|
||||
var grammarEnt = new Entity<GrammarComponent>(mob, grammar);
|
||||
_grammar.SetProperNoun(grammarEnt, true);
|
||||
_grammar.SetGender(grammarEnt, humanoid.Gender);
|
||||
Dirty(mob, grammar);
|
||||
|
||||
SetupBasicComponents(mob);
|
||||
|
||||
return mob;
|
||||
}
|
||||
|
||||
// I hate this
|
||||
private void SetupBasicComponents(EntityUid mob)
|
||||
{
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
namespace Content.Server.DeltaV.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]
|
||||
public int Score;
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
using Content.Shared.Random;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.DeltaV.Cloning;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class MetempsychoticMachineComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Base probability of remaining humanoid during cloning. Higher karma reduces this chance.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float HumanoidBaseChance = 0.75f;
|
||||
|
||||
/// <summary>
|
||||
/// Species prototypes pool to use for humanoids.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<WeightedRandomPrototype> MetempsychoticHumanoidPool = "MetempsychoticHumanoidPool";
|
||||
|
||||
/// <summary>
|
||||
/// Entitiy prototypes pool to use for non-humanoids.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<WeightedRandomPrototype> MetempsychoticNonHumanoidPool = "MetempsychoticNonhumanoidPool";
|
||||
}
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
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";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue