Merge branch 'DeltaV-Station:master' into seer
This commit is contained in:
commit
e53253f659
|
|
@ -0,0 +1,5 @@
|
|||
using Content.Shared.Abilities.Psionics;
|
||||
|
||||
namespace Content.Client.Abilities.Psionics;
|
||||
|
||||
public sealed class TelegnosisPowerSystem : SharedTelegnosisPowerSystem;
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
using Content.Server.Chat.Systems;
|
||||
using Content.Shared.Administration;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.ContentPack;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Administration.Commands;
|
||||
|
||||
[AdminCommand(AdminFlags.Fun)]
|
||||
public sealed class AnnounceCustomCommand : IConsoleCommand
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _protoManager = default!;
|
||||
[Dependency] private readonly IResourceManager _res = default!;
|
||||
|
||||
public string Command => "announcecustom";
|
||||
public string Description => Loc.GetString("cmd-announcecustom-desc");
|
||||
public string Help => Loc.GetString("cmd-announcecustom-help", ("command", Command));
|
||||
|
||||
public void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var chat = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
|
||||
|
||||
switch (args.Length)
|
||||
{
|
||||
case 0:
|
||||
shell.WriteError(Loc.GetString("shell-need-minimum-one-argument"));
|
||||
return;
|
||||
case > 4:
|
||||
shell.WriteError(Loc.GetString("shell-wrong-arguments-number"));
|
||||
return;
|
||||
}
|
||||
|
||||
var message = args[0];
|
||||
var sender = "Central Command";
|
||||
var color = Color.Gold;
|
||||
var sound = new SoundPathSpecifier("/Audio/Announcements/announce.ogg");
|
||||
|
||||
// Optional sender argument
|
||||
if (args.Length >= 2)
|
||||
sender = args[1];
|
||||
|
||||
// Optional color argument
|
||||
if (args.Length >= 3)
|
||||
{
|
||||
try
|
||||
{
|
||||
color = Color.FromHex(args[2]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
shell.WriteError(Loc.GetString("shell-invalid-color-hex"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Optional sound argument
|
||||
if (args.Length >= 4)
|
||||
sound = new SoundPathSpecifier(args[3]);
|
||||
|
||||
chat.DispatchGlobalAnnouncement(message, sender, true, sound, color);
|
||||
shell.WriteLine(Loc.GetString("shell-command-success"));
|
||||
}
|
||||
|
||||
public CompletionResult GetCompletion(IConsoleShell shell, string[] args)
|
||||
{
|
||||
return args.Length switch
|
||||
{
|
||||
1 => CompletionResult.FromHint(Loc.GetString("cmd-announcecustom-arg-message")),
|
||||
2 => CompletionResult.FromHint(Loc.GetString("shell-argument-username-optional-hint")),
|
||||
3 => CompletionResult.FromHint(Loc.GetString("cmd-announcecustom-arg-color")),
|
||||
4 => CompletionResult.FromHintOptions(
|
||||
CompletionHelper.AudioFilePath(args[3], _protoManager, _res),
|
||||
Loc.GetString("cmd-announcecustom-arg-sound")
|
||||
),
|
||||
_ => CompletionResult.Empty
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -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,42 +1,60 @@
|
|||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Server.Fluids.EntitySystems;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Shared.Fluids.Components;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Content.Server.Destructible.Thresholds.Behaviors
|
||||
namespace Content.Server.Destructible.Thresholds.Behaviors;
|
||||
|
||||
[UsedImplicitly]
|
||||
[DataDefinition]
|
||||
public sealed partial class SpillBehavior : IThresholdBehavior
|
||||
{
|
||||
[UsedImplicitly]
|
||||
[DataDefinition]
|
||||
public sealed partial class SpillBehavior : IThresholdBehavior
|
||||
/// <summary>
|
||||
/// Optional fallback solution name if SpillableComponent is not present.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string? Solution;
|
||||
|
||||
/// <summary>
|
||||
/// When triggered, spills the entity's solution onto the ground.
|
||||
/// Will first try to use the solution from a SpillableComponent if present,
|
||||
/// otherwise falls back to the solution specified in the behavior's data fields.
|
||||
/// The solution is properly drained/split before spilling to prevent double-spilling with other behaviors.
|
||||
/// </summary>
|
||||
/// <param name="owner">Entity whose solution will be spilled</param>
|
||||
/// <param name="system">System calling this behavior</param>
|
||||
/// <param name="cause">Optional entity that caused this behavior to trigger</param>
|
||||
public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null)
|
||||
{
|
||||
[DataField]
|
||||
public string? Solution;
|
||||
var solutionContainerSystem = system.EntityManager.System<SharedSolutionContainerSystem>();
|
||||
var spillableSystem = system.EntityManager.System<PuddleSystem>();
|
||||
var coordinates = system.EntityManager.GetComponent<TransformComponent>(owner).Coordinates;
|
||||
|
||||
/// <summary>
|
||||
/// If there is a SpillableComponent on EntityUidowner use it to create a puddle/smear.
|
||||
/// Or whatever solution is specified in the behavior itself.
|
||||
/// If none are available do nothing.
|
||||
/// </summary>
|
||||
/// <param name="owner">Entity on which behavior is executed</param>
|
||||
/// <param name="system">system calling the behavior</param>
|
||||
/// <param name="cause"></param>
|
||||
public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null)
|
||||
Solution targetSolution;
|
||||
|
||||
// First try to get solution from SpillableComponent
|
||||
if (system.EntityManager.TryGetComponent(owner, out SpillableComponent? spillableComponent) &&
|
||||
solutionContainerSystem.TryGetSolution(owner, spillableComponent.SolutionName, out var solution, out var compSolution))
|
||||
{
|
||||
var solutionContainerSystem = system.EntityManager.System<SharedSolutionContainerSystem>();
|
||||
var spillableSystem = system.EntityManager.System<PuddleSystem>();
|
||||
|
||||
var coordinates = system.EntityManager.GetComponent<TransformComponent>(owner).Coordinates;
|
||||
|
||||
if (system.EntityManager.TryGetComponent(owner, out SpillableComponent? spillableComponent) &&
|
||||
solutionContainerSystem.TryGetSolution(owner, spillableComponent.SolutionName, out _, out var compSolution))
|
||||
{
|
||||
spillableSystem.TrySplashSpillAt(owner, coordinates, compSolution, out _, false, user: cause);
|
||||
}
|
||||
else if (Solution != null &&
|
||||
solutionContainerSystem.TryGetSolution(owner, Solution, out _, out var behaviorSolution))
|
||||
{
|
||||
spillableSystem.TrySplashSpillAt(owner, coordinates, behaviorSolution, out _, user: cause);
|
||||
}
|
||||
// If entity is drainable, drain the solution. Otherwise just split it.
|
||||
// Both methods ensure the solution is properly removed.
|
||||
targetSolution = system.EntityManager.HasComponent<DrainableSolutionComponent>(owner)
|
||||
? solutionContainerSystem.Drain((owner, system.EntityManager.GetComponent<DrainableSolutionComponent>(owner)), solution.Value, compSolution.Volume)
|
||||
: compSolution.SplitSolution(compSolution.Volume);
|
||||
}
|
||||
// Fallback to solution specified in behavior data
|
||||
else if (Solution != null &&
|
||||
solutionContainerSystem.TryGetSolution(owner, Solution, out var solutionEnt, out var behaviorSolution))
|
||||
{
|
||||
targetSolution = system.EntityManager.HasComponent<DrainableSolutionComponent>(owner)
|
||||
? solutionContainerSystem.Drain((owner, system.EntityManager.GetComponent<DrainableSolutionComponent>(owner)), solutionEnt.Value, behaviorSolution.Volume)
|
||||
: behaviorSolution.SplitSolution(behaviorSolution.Volume);
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
// Spill the solution that was drained/split
|
||||
spillableSystem.TrySplashSpillAt(owner, coordinates, targetSolution, out _, false, cause);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using Content.Server.Body.Systems;
|
|||
using Content.Server.Kitchen.Components;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.Body.Part; // DeltaV
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.DoAfter;
|
||||
|
|
@ -160,9 +161,12 @@ namespace Content.Server.Kitchen.EntitySystems
|
|||
_transform.SetCoordinates(victimUid, Transform(uid).Coordinates);
|
||||
// THE WHAT?
|
||||
// TODO: Need to be able to leave them on the spike to do DoT, see ss13.
|
||||
var gibs = _bodySystem.GibBody(victimUid);
|
||||
var gibs = _bodySystem.GibBody(victimUid, gibOrgans: true); // DeltaV: spawn organs
|
||||
foreach (var gib in gibs) {
|
||||
QueueDel(gib);
|
||||
// Begin DeltaV changes: Only delete limbs instead of organs
|
||||
if (HasComp<BodyPartComponent>(gib))
|
||||
QueueDel(gib);
|
||||
// End DeltaV changes
|
||||
}
|
||||
|
||||
_audio.PlayEntity(component.SpikeSound, Filter.Pvs(uid), uid, true);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ using Content.Shared.Actions.Events;
|
|||
|
||||
namespace Content.Server.Abilities.Psionics
|
||||
{
|
||||
public sealed class TelegnosisPowerSystem : EntitySystem
|
||||
public sealed class TelegnosisPowerSystem : SharedTelegnosisPowerSystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly StatusEffectsSystem _statusEffects = default!;
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using Content.Shared.Interaction.Events;
|
||||
|
||||
namespace Content.Shared.Abilities.Psionics;
|
||||
|
||||
public abstract class SharedTelegnosisPowerSystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<TelegnosticProjectionComponent, InteractionAttemptEvent>(OnInteractionAttempt);
|
||||
}
|
||||
|
||||
private void OnInteractionAttempt(Entity<TelegnosticProjectionComponent> ent, ref InteractionAttemptEvent args)
|
||||
{
|
||||
// no astrally stealing someones shoes
|
||||
args.Cancelled = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototy
|
|||
|
||||
namespace Content.Shared.Abilities.Psionics
|
||||
{
|
||||
[RegisterComponent]
|
||||
[RegisterComponent, Access(typeof(SharedTelegnosisPowerSystem))]
|
||||
public sealed partial class TelegnosisPowerComponent : Component
|
||||
{
|
||||
[DataField("prototype")]
|
||||
|
|
@ -20,4 +20,4 @@ namespace Content.Shared.Abilities.Psionics
|
|||
[DataField("telegnosisActionEntity")]
|
||||
public EntityUid? TelegnosisActionEntity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
namespace Content.Shared.Abilities.Psionics
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed partial class TelegnosticProjectionComponent : Component
|
||||
{}
|
||||
}
|
||||
namespace Content.Shared.Abilities.Psionics;
|
||||
|
||||
[RegisterComponent, Access(typeof(SharedTelegnosisPowerSystem))]
|
||||
public sealed partial class TelegnosticProjectionComponent : Component;
|
||||
|
|
|
|||
|
|
@ -1,74 +1,4 @@
|
|||
Entries:
|
||||
- author: Ygg01
|
||||
changes:
|
||||
- message: Digging dirt.
|
||||
type: Add
|
||||
id: 158
|
||||
time: '2023-12-06T15:58:00.0000000+00:00'
|
||||
- author: Velcroboy
|
||||
changes:
|
||||
- message: Buffed Food Cart storage. Get out there and slang some burgers, chefs!
|
||||
type: Tweak
|
||||
id: 159
|
||||
time: '2023-12-06T15:58:43.0000000+00:00'
|
||||
- author: ps3moira
|
||||
changes:
|
||||
- message: Added mouse operative reinforcements, which can be bought from the Syndicate
|
||||
uplink
|
||||
type: Add
|
||||
id: 160
|
||||
time: '2023-12-06T16:03:07.0000000+00:00'
|
||||
- author: evilexecutive
|
||||
changes:
|
||||
- message: Harpies now have a visual indication when they're playing a Midi.
|
||||
type: Add
|
||||
- message: Harpies have been re-balanced so that they now actually have a numerical
|
||||
positive.
|
||||
type: Tweak
|
||||
id: 161
|
||||
time: '2023-12-06T20:10:49.0000000+00:00'
|
||||
- author: DebugOk
|
||||
changes:
|
||||
- message: Due to abuse, prisoners now require whitelist to play.
|
||||
type: Tweak
|
||||
id: 162
|
||||
time: '2023-12-07T13:22:03.0000000+00:00'
|
||||
- author: ps3moira
|
||||
changes:
|
||||
- message: Removed bionic syrinx implanter from surplus crate.
|
||||
type: Remove
|
||||
id: 163
|
||||
time: '2023-12-11T23:11:41.0000000+00:00'
|
||||
- author: ps3moira
|
||||
changes:
|
||||
- message: Removed Carpotoxin from Sashimi, now they are sushi-grade!
|
||||
type: Remove
|
||||
id: 164
|
||||
time: '2023-12-13T20:12:46.0000000+00:00'
|
||||
- author: Adrian16199
|
||||
changes:
|
||||
- message: Crew has learned how to make a straw hat out of wheat bushels!
|
||||
type: Add
|
||||
id: 165
|
||||
time: '2023-12-13T20:13:45.0000000+00:00'
|
||||
- author: IamVelcroboy
|
||||
changes:
|
||||
- message: Added Yule! Happy Holidays!
|
||||
type: Add
|
||||
id: 166
|
||||
time: '2023-12-13T20:21:34.0000000+00:00'
|
||||
- author: ps3moira
|
||||
changes:
|
||||
- message: Added Fish n' Chips. Thank the British!
|
||||
type: Add
|
||||
id: 167
|
||||
time: '2023-12-13T20:32:51.0000000+00:00'
|
||||
- author: Adrian16199
|
||||
changes:
|
||||
- message: Felinids now meow out their words. They can also sigh now.
|
||||
type: Tweak
|
||||
id: 168
|
||||
time: '2023-12-13T21:28:39.0000000+00:00'
|
||||
- author: VMSolidus
|
||||
changes:
|
||||
- message: Harpies no longer choke on completely breathable air
|
||||
|
|
@ -3714,3 +3644,84 @@
|
|||
id: 657
|
||||
time: '2024-11-08T13:38:47.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/2148
|
||||
- author: Aikakakah
|
||||
changes:
|
||||
- message: Added a black turtleneck!
|
||||
type: Add
|
||||
id: 658
|
||||
time: '2024-11-08T20:50:40.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/1905
|
||||
- author: deltanedas
|
||||
changes:
|
||||
- message: Butchering people now drops organs.
|
||||
type: Tweak
|
||||
id: 659
|
||||
time: '2024-11-09T04:40:16.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/2154
|
||||
- author: MilonPL
|
||||
changes:
|
||||
- message: The metempsychosis will always use your player character on the first
|
||||
cloning attempt.
|
||||
type: Tweak
|
||||
- message: Fixed metempsychosis never selecting non-humanoid characters.
|
||||
type: Fix
|
||||
id: 660
|
||||
time: '2024-11-09T10:47:17.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/2156
|
||||
- author: MilonPL
|
||||
changes:
|
||||
- message: Fixed beaker solutions duplicating whenever it's thrown.
|
||||
type: Fix
|
||||
id: 661
|
||||
time: '2024-11-09T12:46:34.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/2157
|
||||
- author: deltanedas
|
||||
changes:
|
||||
- message: The Synthesis Specialist's vendor can now be restocked.
|
||||
type: Tweak
|
||||
id: 662
|
||||
time: '2024-11-09T13:16:44.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/2143
|
||||
- author: deltanedas
|
||||
changes:
|
||||
- message: Fixed telegnostic projections being able to interact with things.
|
||||
type: Tweak
|
||||
id: 663
|
||||
time: '2024-11-09T19:27:59.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/2117
|
||||
- author: Unkn0wnGh0st333
|
||||
changes:
|
||||
- message: Synthesis Specialist ghost rules have been slightly adjusted.
|
||||
type: Tweak
|
||||
id: 664
|
||||
time: '2024-11-09T19:44:28.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/2152
|
||||
- author: Colin-Tel
|
||||
changes:
|
||||
- message: Removed the "Raise Glimmer" objective for traitors.
|
||||
type: Remove
|
||||
id: 665
|
||||
time: '2024-11-10T20:18:53.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/2107
|
||||
- author: Colin-Tel
|
||||
changes:
|
||||
- message: Adjusted antagonist rule C3 and the line about bribery in C1.
|
||||
type: Tweak
|
||||
id: 666
|
||||
time: '2024-11-10T20:20:26.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/2164
|
||||
- author: Stop-Signs
|
||||
changes:
|
||||
- message: Removed the T3 Lockout on epi techs
|
||||
type: Remove
|
||||
id: 667
|
||||
time: '2024-11-11T02:57:13.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/2144
|
||||
- author: Radezolid
|
||||
changes:
|
||||
- message: The syringe gun is now a researcheable technology in the T2 civilian
|
||||
category. Get it from the medical techfab once it's researched.
|
||||
type: Tweak
|
||||
id: 668
|
||||
time: '2024-11-11T15:41:44.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/2169
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,8 @@
|
|||
## AnnounceCustomCommand
|
||||
cmd-announcecustom-desc = Send an in-game announcement with custom color and sound.
|
||||
cmd-announcecustom-help = {$command} <message> [sender] [color] [sound] - Send announcement. Sender defaults to CentCom, color to Gold, sound to announce.ogg
|
||||
|
||||
# Completion hints
|
||||
cmd-announcecustom-arg-message = message
|
||||
cmd-announcecustom-arg-color = color in #RRGGBB format (optional)
|
||||
cmd-announcecustom-arg-sound = sound path (optional)
|
||||
|
|
@ -30,12 +30,13 @@ ghost-role-information-silvia-rules = Keep the medical team company and help out
|
|||
ghost-role-information-synthesis-name = Synthesis Specialist
|
||||
ghost-role-information-synthesis-description = You are a member of Interdyne Pharmaceutics! You are provided all the tools to manufacture a variety of medical cocktails. Establish your craft, peddle your poisons, and make profit.
|
||||
ghost-role-information-synthesis-rules =
|
||||
Brew deadly poisons, marvelous medicines, and anything in between.
|
||||
Sell your concoctions to local agents, crew, and anyone with supplies.
|
||||
Stay on your ship, it is your lifeblood!
|
||||
|
||||
You are a [color=yellow][bold]Free-Agent[/bold][/color]. You are free to act as either an antagonist or a non-antagonist.
|
||||
You are just a chemist so do not act like a full-on antagonist, i.e. no killing people yourself unless your ship is in danger.
|
||||
|
||||
Brew deadly poisons, marvelous medicines, and anything in between.
|
||||
Sell your concoctions to [color=red]local agents[/color], crew, and anyone with supplies.
|
||||
Stay on your ship; it is your job, home, and lifeblood.
|
||||
|
||||
ghost-role-information-closet-skeleton-rules = You are a old member of the station, try to get your previous job back or dwell in the maintenance tunnels!.
|
||||
You are a [color=green][bold]Non-antagonist[/bold][/color]. You should generally not seek to harm the station and its crew.
|
||||
You're allowed some minor mischief.
|
||||
|
|
|
|||
|
|
@ -5,3 +5,4 @@ research-technology-energy-gun = Energy Guns
|
|||
research-technology-energy-gun-advance = Advanced Energy Manipulation
|
||||
research-technology-advance-laser = Advanced Laser Manipulation
|
||||
research-technology-robust-melee = Robust Melee
|
||||
research-technology-syringe-gun = Syringe Gun
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
ClothingOuterPonchoClassic: 2
|
||||
ClothingUniformJumpsuitKilt: 3 # DeltaV - SCOTTTTLANDDDDD FURREVERRRRR!!
|
||||
ClothingEyesEyepatch: 2 # Delta-V Yarrr
|
||||
ClothingUniformBlackTurtleneck : 2 # DeltaV - Clothing addition
|
||||
ClothingHeadHatPwig: 2
|
||||
ClothingOuterRobesJudge: 2
|
||||
ClothingOuterPoncho: 2
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
- type: entity
|
||||
parent: CrateEngineering
|
||||
id: CrateEngineEssentials
|
||||
name: engine essentials crate
|
||||
description: Everything you need to power the station, in a superposition of containing both a singularity and a tesla.
|
||||
suffix: 1 per map MAX
|
||||
components:
|
||||
- type: EntityTableContainerFill
|
||||
containers:
|
||||
entity_storage: !type:GroupSelector
|
||||
children:
|
||||
- !type:NestedSelector
|
||||
tableId: TeslaEssentials
|
||||
- !type:NestedSelector
|
||||
tableId: SingularityEssentials
|
||||
|
||||
- type: entityTable
|
||||
id: TeslaEssentials
|
||||
table: !type:AllSelector
|
||||
children:
|
||||
- id: TeslaGeneratorFlatpack
|
||||
- id: TeslaGeneratorFlatpack
|
||||
prob: 0.3 # Small chance of a free backup
|
||||
- id: TeslaCoilFlatpack
|
||||
amount: !type:RangeNumberSelector
|
||||
range: 4, 6
|
||||
- id: TeslaGroundingRodFlatpack
|
||||
amount: !type:ConstantNumberSelector
|
||||
value: 4
|
||||
|
||||
- type: entityTable
|
||||
id: SingularityEssentials
|
||||
table: !type:AllSelector
|
||||
children:
|
||||
- id: SingularityGeneratorFlatpack
|
||||
- id: SingularityGeneratorFlatpack
|
||||
prob: 0.3 # Small chance of a free backup
|
||||
# intentionally separate rolls so they are probably mismatched
|
||||
# you might get spare tanks you might have to get more from the tank dispenser
|
||||
- id: RadiationCollectorFlatpack
|
||||
amount: !type:RangeNumberSelector
|
||||
range: 8, 12
|
||||
- id: PlasmaTankFilled
|
||||
amount: !type:RangeNumberSelector
|
||||
range: 8, 12
|
||||
|
|
@ -397,3 +397,13 @@
|
|||
- type: Clothing
|
||||
sprite: DeltaV/Clothing/Uniforms/Jumpsuit/prosecutorred.rsi
|
||||
|
||||
- type: entity
|
||||
parent: ClothingUniformFoldableBase
|
||||
id: ClothingUniformBlackTurtleneck
|
||||
name: black turtleneck
|
||||
description: A simple black turtleneck. Perfect for any wannabe spy.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: DeltaV/Clothing/Uniforms/Jumpsuit/black_turtleneck.rsi
|
||||
- type: Clothing
|
||||
sprite: DeltaV/Clothing/Uniforms/Jumpsuit/black_turtleneck.rsi
|
||||
|
|
|
|||
|
|
@ -38,4 +38,12 @@
|
|||
sprite: DeltaV/Structures/Wallmounts/signs.rsi
|
||||
state: direction_court
|
||||
|
||||
|
||||
- type: entity
|
||||
parent: BaseSignDirectional
|
||||
id: SignDirectionaAI
|
||||
name: AI sign
|
||||
description: A direction sign, pointing out which way the AI core is.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: DeltaV/Structures/Wallmounts/signs.rsi
|
||||
state: direction_aicore
|
||||
|
|
|
|||
|
|
@ -5,3 +5,20 @@
|
|||
materials:
|
||||
Steel: 300
|
||||
Glass: 100
|
||||
|
||||
- type: latheRecipe
|
||||
id: LauncherSyringe
|
||||
result: LauncherSyringe
|
||||
completetime: 3
|
||||
materials:
|
||||
Steel: 1000
|
||||
Glass: 500
|
||||
Plastic: 500
|
||||
|
||||
- type: latheRecipe
|
||||
id: MiniSyringe
|
||||
result: MiniSyringe
|
||||
completetime: 1
|
||||
materials:
|
||||
Plastic: 150
|
||||
Steel: 50
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
- type: technology
|
||||
id: SyringeGun
|
||||
name: research-technology-syringe-gun
|
||||
icon:
|
||||
sprite: Objects/Weapons/Guns/Cannons/syringe_gun.rsi
|
||||
state: syringe_gun
|
||||
discipline: CivilianServices
|
||||
tier: 2
|
||||
cost: 10000
|
||||
recipeUnlocks:
|
||||
- LauncherSyringe
|
||||
- MiniSyringe
|
||||
|
|
@ -482,6 +482,7 @@
|
|||
- type: VendingMachineRestock
|
||||
canRestock:
|
||||
- ChemVendInventory
|
||||
- ChemVendInventorySyndicate # DeltaV: Let it restock synthesis/nukie vendor
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: base
|
||||
|
|
|
|||
|
|
@ -436,6 +436,8 @@
|
|||
- MagazineBoxSpecialHoly
|
||||
- MagazineBoxSpecialMindbreaker
|
||||
- AdvancedTruncheon
|
||||
- LauncherSyringe
|
||||
- MiniSyringe
|
||||
# End DeltaV additions
|
||||
|
||||
- type: entity
|
||||
|
|
@ -1066,6 +1068,10 @@
|
|||
- WhiteCane
|
||||
- AACTablet # DeltaV
|
||||
dynamicRecipes:
|
||||
# Begin DeltaV additions
|
||||
- LauncherSyringe
|
||||
- MiniSyringe
|
||||
# End DeltaV additions
|
||||
- ChemicalPayload
|
||||
- CryostasisBeaker
|
||||
- BluespaceBeaker
|
||||
|
|
|
|||
|
|
@ -2160,7 +2160,7 @@
|
|||
parent: VendingMachineChemicals
|
||||
id: VendingMachineChemicalsSyndicate
|
||||
name: SyndieJuice
|
||||
description: Not made with freshly squeezed syndies I hope.
|
||||
description: Not made with freshly squeezed syndies I hope. Backwards compatible with standard ChemVend restocks. # DeltaV: Add chemvend part
|
||||
components:
|
||||
- type: VendingMachine
|
||||
pack: ChemVendInventorySyndicate
|
||||
|
|
|
|||
|
|
@ -50,18 +50,3 @@
|
|||
# components:
|
||||
# - BecomePsionicCondition
|
||||
# - type: BecomeGolemCondition
|
||||
|
||||
- type: entity
|
||||
id: RaiseGlimmerObjective
|
||||
parent: BaseTraitorObjective
|
||||
name: Raise Glimmer.
|
||||
description: Get the glimmer above the specified amount.
|
||||
components:
|
||||
- type: Objective
|
||||
difficulty: 2.5
|
||||
#unique: false
|
||||
icon:
|
||||
sprite: Nyanotrasen/Icons/psi.rsi
|
||||
state: psi
|
||||
- type: RaiseGlimmerCondition
|
||||
target: 500
|
||||
|
|
|
|||
|
|
@ -49,8 +49,6 @@
|
|||
weights:
|
||||
RandomTraitorAliveObjective: 1
|
||||
RandomTraitorProgressObjective: 1
|
||||
RaiseGlimmerObjective: 0.5 # Nyanotrasen - Raise glimmer to a target amount, see Resources/Prototypes/Nyanotrasen/Objectives/traitor.yml
|
||||
|
||||
|
||||
#Thief groups
|
||||
- type: weightedRandom
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@
|
|||
icon:
|
||||
sprite: Interface/Misc/research_disciplines.rsi
|
||||
state: industrial
|
||||
lockoutTier: 4 # DeltaV: Lockout occurs at t4
|
||||
tierPrerequisites:
|
||||
1: 0
|
||||
2: 0.75
|
||||
3: 0.75
|
||||
2: 1 # DeltaV: raised to 1
|
||||
3: 1 # DeltaV: raised to 1
|
||||
|
||||
- type: techDiscipline
|
||||
id: Arsenal
|
||||
|
|
@ -17,10 +18,11 @@
|
|||
icon:
|
||||
sprite: Interface/Misc/research_disciplines.rsi
|
||||
state: arsenal
|
||||
lockoutTier: 4 # DeltaV: Lockout occurs at t4
|
||||
tierPrerequisites:
|
||||
1: 0
|
||||
2: 0.75
|
||||
3: 0.75
|
||||
2: 1 # DeltaV: raised to 1
|
||||
3: 1 # DeltaV: raised to 1
|
||||
|
||||
- type: techDiscipline
|
||||
id: Experimental
|
||||
|
|
@ -29,10 +31,11 @@
|
|||
icon:
|
||||
sprite: Interface/Misc/research_disciplines.rsi
|
||||
state: experimental
|
||||
lockoutTier: 4 # DeltaV: Lockout occurs at t4
|
||||
tierPrerequisites:
|
||||
1: 0
|
||||
2: 0.75
|
||||
3: 0.75
|
||||
2: 1 # DeltaV: raised to 1
|
||||
3: 1 # DeltaV: raised to 1
|
||||
|
||||
- type: techDiscipline
|
||||
id: CivilianServices
|
||||
|
|
@ -41,7 +44,8 @@
|
|||
icon:
|
||||
sprite: Interface/Misc/research_disciplines.rsi
|
||||
state: civilianservices
|
||||
lockoutTier: 4 # DeltaV: Lockout occurs at t4
|
||||
tierPrerequisites:
|
||||
1: 0
|
||||
2: 0.75
|
||||
3: 0.75
|
||||
2: 1 # DeltaV: raised to 1
|
||||
3: 1 # DeltaV: raised to 1
|
||||
|
|
|
|||
|
|
@ -116,7 +116,6 @@
|
|||
- Giving a character additional access or a job because you are friends with the player who is playing that character.
|
||||
- Trusting a character because you are friends with the player who is playing that character.
|
||||
- Not fighting a character because you are friends with the player who is playing that character.
|
||||
- Ignoring your objective to kill a character because your character and theirs became friends in a previous round.
|
||||
|
||||
## Metagrudging Examples
|
||||
These are all examples of things that are prohibited by at least one metashield item that is never revealed IC.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Security, Justice, and Command roles are held to a higher standard of roleplay,
|
|||
- Your character must act in a manner that NanoTrasen would reasonably hire them to this position.
|
||||
- Your character is presumed to be sane, competent in their duties, and able to make decisions to the benefit of the station.
|
||||
- Giving away Traitor objective items and sensitive equipment should be avoided in these roles. Your character should value them deeply.
|
||||
- Leeway is given to making deals with criminals if the deal benefits the safety or situation of the crew and station.
|
||||
- Leeway is given to making deals with criminals if the deal benefits the safety or situation of the crew and station OR if the deal involves items of a primarily sentimental value (e.g. HoP's Ian scrapbook, LO's lucky dollar).
|
||||
- Leeway can be given in [color=#ff0000]extreme circumstances[/color] of emergency/crisis.
|
||||
- The three departments are required to read and follow Delta-V Space Law, Standard Operating Procedure, Alert Procedure, and Company Policy to the best of their ability.
|
||||
- [color=#ff0000]Circumstances and context may permit you to break these laws. However, the fact that this rule is malleable is not an excuse to ignore it entirely.[/color]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
<Document>
|
||||
# Rule C3: Antagonist Guidelines
|
||||
[color=#ffff00]Being an antagonist does not allow you to stop playing a character. Determine how your character would react to being given these objectives, and work through it appropriately.[/color]
|
||||
|
||||
Through engaging in antagonistic activity, you should seek to make the round more engaging and fun as the primary driver of the narrative of a round. Succeeding as an antagonist should not be your goal, but rather telling the most interesting story for everyone involved.
|
||||
- [color=#ff0000]Antagonists are free to complete their objectives through committing proportional damage. Through roleplay, damage becomes more proportional.[/color] Example: Holding the singulo hostage for a theft objective is acceptable, while simply singuloosing and using that chaos is unacceptable.
|
||||
- Killing players unrelated to your immediate objective in a manner that results in their round removal should be avoided. Crew that do not make an attempt at self preservation, or engage in valid-hunting, are exempt from this.
|
||||
- If you are concerned as to whether or not what you're about to do is allowed, feel free to AHelp and ask an admin for clarification. [color=#ff0000]Lack of administrator response does not constitute approval.[/color]
|
||||
- While antagonists are [color=#ffff00]not required[/color] to complete their objectives, they are still encouraged to act as an antagonist in the round while roleplaying.
|
||||
- Other antagonists are not necessarily your friends. Other antagonists are often free agents that you may negotiate with at your own risk.
|
||||
- If you are a team antagonist, you must work with your partners to complete any shared objectives.
|
||||
- Excessively lame tactics are strictly forbidden for all antags except for station-destroying antags, such as nuclear operatives or space dragons. Examples include:
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 519 B |
Binary file not shown.
|
After Width: | Height: | Size: 579 B |
Binary file not shown.
|
After Width: | Height: | Size: 598 B |
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-4.0",
|
||||
"copyright": "Created by Aikakakah (github) for Delta-V",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "icon"
|
||||
},
|
||||
{
|
||||
"name": "inhand-left",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "inhand-right",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "equipped-INNERCLOTHING",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "rolled-equipped-INNERCLOTHING",
|
||||
"directions": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 450 B |
|
|
@ -23,6 +23,10 @@
|
|||
"name": "direction_justice",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "direction_aicore",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "chapel"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue