Caching next exent
This commit is contained in:
commit
9f1bee4131
|
|
@ -1,5 +0,0 @@
|
|||
using Content.Shared.Abilities.Psionics;
|
||||
|
||||
namespace Content.Client.Abilities.Psionics;
|
||||
|
||||
public sealed class TelegnosisPowerSystem : SharedTelegnosisPowerSystem;
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
using Content.Server.DeltaV.Cloning;
|
||||
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]
|
||||
|
|
@ -21,22 +23,18 @@ public sealed class MetempsychosisTest
|
|||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
prototypeManager.TryIndex(metemComponent.MetempsychoticHumanoidPool,
|
||||
prototypeManager.TryIndex<WeightedRandomPrototype>(metemComponent.MetempsychoticHumanoidPool,
|
||||
out var humanoidPool);
|
||||
prototypeManager.TryIndex(metemComponent.MetempsychoticNonHumanoidPool,
|
||||
prototypeManager.TryIndex<WeightedRandomPrototype>(metemComponent.MetempsychoticNonHumanoidPool,
|
||||
out var nonHumanoidPool);
|
||||
|
||||
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!");
|
||||
});
|
||||
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,8 +9,6 @@ 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;
|
||||
|
|
@ -35,10 +33,26 @@ 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 partial class CloningSystem : EntitySystem // DeltaV - Set to partial, see CloningSystem.Metempsychosis.cs
|
||||
public sealed class CloningSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly DeviceLinkSystem _signalSystem = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = null!;
|
||||
|
|
@ -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<MindComponent, EntityUid> ClonesWaitingForMind = new();
|
||||
public const float EasyModeCloningCost = 0.7f;
|
||||
|
|
@ -142,10 +158,6 @@ 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;
|
||||
|
||||
|
|
@ -232,13 +244,13 @@ namespace Content.Server.Cloning
|
|||
AddComp<ActiveCloningPodComponent>(uid);
|
||||
return true;
|
||||
}
|
||||
// End Nyano-code.
|
||||
}
|
||||
// end of genetic damage checks
|
||||
|
||||
// DeltaV - Replaces CloneAppearance with Metem/Clone via FetchAndSpawnMob
|
||||
var mob = FetchAndSpawnMob(podEnt, pref, speciesPrototype, humanoid, bodyToClone, karmaBonus);
|
||||
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.
|
||||
///Nyano - Summary: adds the potential psionic trait to the reanimated mob.
|
||||
EnsureComp<PotentialPsionicComponent>(mob);
|
||||
|
||||
var ev = new CloningEvent(bodyToClone, mob);
|
||||
|
|
@ -336,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<EmaggedComponent>(uid))
|
||||
{
|
||||
_audio.PlayPvs(clonePod.ScreamSound, uid);
|
||||
|
|
@ -364,6 +375,84 @@ 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,79 +0,0 @@
|
|||
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.DeltaV.Cloning;
|
||||
using Content.Server.Nyanotrasen.Cloning;
|
||||
using Content.Shared.Abilities.Psionics;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Body.Components;
|
||||
|
|
|
|||
|
|
@ -1,172 +0,0 @@
|
|||
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");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
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;
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
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,60 +1,42 @@
|
|||
using Content.Server.Fluids.EntitySystems;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Server.Fluids.EntitySystems;
|
||||
using Content.Shared.Fluids.Components;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Content.Server.Destructible.Thresholds.Behaviors;
|
||||
|
||||
[UsedImplicitly]
|
||||
[DataDefinition]
|
||||
public sealed partial class SpillBehavior : IThresholdBehavior
|
||||
namespace Content.Server.Destructible.Thresholds.Behaviors
|
||||
{
|
||||
/// <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)
|
||||
[UsedImplicitly]
|
||||
[DataDefinition]
|
||||
public sealed partial class SpillBehavior : IThresholdBehavior
|
||||
{
|
||||
var solutionContainerSystem = system.EntityManager.System<SharedSolutionContainerSystem>();
|
||||
var spillableSystem = system.EntityManager.System<PuddleSystem>();
|
||||
var coordinates = system.EntityManager.GetComponent<TransformComponent>(owner).Coordinates;
|
||||
[DataField]
|
||||
public string? Solution;
|
||||
|
||||
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))
|
||||
/// <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)
|
||||
{
|
||||
// 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;
|
||||
var solutionContainerSystem = system.EntityManager.System<SharedSolutionContainerSystem>();
|
||||
var spillableSystem = system.EntityManager.System<PuddleSystem>();
|
||||
|
||||
// Spill the solution that was drained/split
|
||||
spillableSystem.TrySplashSpillAt(owner, coordinates, targetSolution, out _, false, cause);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ 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;
|
||||
|
|
@ -161,12 +160,9 @@ 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, gibOrgans: true); // DeltaV: spawn organs
|
||||
var gibs = _bodySystem.GibBody(victimUid);
|
||||
foreach (var gib in gibs) {
|
||||
// Begin DeltaV changes: Only delete limbs instead of organs
|
||||
if (HasComp<BodyPartComponent>(gib))
|
||||
QueueDel(gib);
|
||||
// End DeltaV changes
|
||||
QueueDel(gib);
|
||||
}
|
||||
|
||||
_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 : SharedTelegnosisPowerSystem
|
||||
public sealed class TelegnosisPowerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly StatusEffectsSystem _statusEffects = default!;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
namespace Content.Server.Nyanotrasen.Cloning
|
||||
{
|
||||
/// <summary>
|
||||
/// This tracks how many times you have already been cloned and lowers your chance of getting a humanoid each time.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class MetempsychosisKarmaComponent : Component
|
||||
{
|
||||
[DataField("score")]
|
||||
public int Score = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
using Content.Shared.Random;
|
||||
|
||||
namespace Content.Server.Nyanotrasen.Cloning
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed partial class MetempsychoticMachineComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Chance you will spawn as a humanoid instead of a non humanoid.
|
||||
/// </summary>
|
||||
[DataField("humanoidBaseChance")]
|
||||
public float HumanoidBaseChance = 0.75f;
|
||||
|
||||
[ValidatePrototypeId<WeightedRandomPrototype>]
|
||||
[DataField("metempsychoticHumanoidPool")]
|
||||
public string MetempsychoticHumanoidPool = "MetempsychoticHumanoidPool";
|
||||
|
||||
[ValidatePrototypeId<WeightedRandomPrototype>]
|
||||
[DataField("metempsychoticNonHumanoidPool")]
|
||||
public string MetempsychoticNonHumanoidPool = "MetempsychoticNonhumanoidPool";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Content.Shared.Random;
|
||||
using Content.Shared.Random.Helpers;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Nyanotrasen.Cloning
|
||||
{
|
||||
public sealed class MetempsychoticMachineSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
|
||||
public string GetSpawnEntity(EntityUid uid, float karmaBonus, MetempsychoticMachineComponent component, SpeciesPrototype oldSpecies, out SpeciesPrototype? species, int? karma = null)
|
||||
{
|
||||
var chance = component.HumanoidBaseChance + karmaBonus;
|
||||
|
||||
if (karma != null)
|
||||
chance -= ((1 - component.HumanoidBaseChance) * (float) karma);
|
||||
|
||||
if (chance > 1 && _random.Prob(chance - 1))
|
||||
{
|
||||
species = oldSpecies;
|
||||
return oldSpecies.Prototype;
|
||||
}
|
||||
else
|
||||
chance = 1;
|
||||
|
||||
chance = Math.Clamp(chance, 0, 1);
|
||||
if (_random.Prob(chance) &&
|
||||
_prototypeManager.TryIndex<WeightedRandomPrototype>(component.MetempsychoticHumanoidPool, out var humanoidPool) &&
|
||||
_prototypeManager.TryIndex<SpeciesPrototype>(humanoidPool.Pick(), out var speciesPrototype))
|
||||
{
|
||||
species = speciesPrototype;
|
||||
return speciesPrototype.Prototype;
|
||||
}
|
||||
else
|
||||
{
|
||||
species = null;
|
||||
_sawmill.Error("Could not index species for metempsychotic machine...");
|
||||
return "MobHuman";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -33,6 +33,14 @@ namespace Content.Server.StationEvents
|
|||
{
|
||||
// A little starting variance so schedulers dont all proc at once.
|
||||
component.TimeUntilNextEvent = RobustRandom.NextFloat(component.MinimumTimeUntilFirstEvent, component.MinimumTimeUntilFirstEvent + 120);
|
||||
|
||||
// DeltaV - end init NextEventComp
|
||||
NextEventComponent? nextEventComponent = null;
|
||||
if (Resolve(uid, ref nextEventComponent, false)
|
||||
&& _event.TryGenerateRandomEvent(component.ScheduledGameRules, out string? firstEvent, TimeSpan.FromSeconds(component.TimeUntilNextEvent))
|
||||
&& firstEvent != null)
|
||||
_next.UpdateNextEvent(nextEventComponent, firstEvent, TimeSpan.FromSeconds(component.TimeUntilNextEvent));
|
||||
// DeltaV - end init NextEventComp
|
||||
}
|
||||
|
||||
protected override void Ended(EntityUid uid, BasicStationEventSchedulerComponent component, GameRuleComponent gameRule,
|
||||
|
|
@ -60,19 +68,21 @@ namespace Content.Server.StationEvents
|
|||
eventScheduler.TimeUntilNextEvent -= frameTime;
|
||||
continue;
|
||||
}
|
||||
NextEventComponent? nextEventComponent = null;
|
||||
|
||||
// DeltaV events using NextEventComponent
|
||||
NextEventComponent? nextEventComponent = null;
|
||||
|
||||
if (Resolve(uid, ref nextEventComponent, false)) // If there is a nextEventComponent use the stashed event instead of running it directly.
|
||||
{
|
||||
if (!_event.TryGenerateRandomEvent(eventScheduler.ScheduledGameRules, out string? generatedEvent) || generatedEvent == null)
|
||||
ResetTimer(eventScheduler);
|
||||
TimeSpan nextEventTime = _timing.CurTime + TimeSpan.FromSeconds(eventScheduler.TimeUntilNextEvent);
|
||||
if (!_event.TryGenerateRandomEvent(eventScheduler.ScheduledGameRules, out string? generatedEvent, nextEventTime) || generatedEvent == null)
|
||||
continue;
|
||||
// Cycle the stashed event with the new generated event and time.
|
||||
string storedEvent= _next.UpdateNextEvent(nextEventComponent, generatedEvent, (float)_timing.CurTime.TotalSeconds + eventScheduler.TimeUntilNextEvent);
|
||||
string storedEvent= _next.UpdateNextEvent(nextEventComponent, generatedEvent, nextEventTime);
|
||||
if (storedEvent == null || storedEvent == string.Empty) //If there was no stored event don't try to run it.
|
||||
continue;
|
||||
GameTicker.AddGameRule(storedEvent);
|
||||
ResetTimer(eventScheduler);
|
||||
continue;
|
||||
}
|
||||
// DeltaV end events using NextEventComponent
|
||||
|
|
|
|||
|
|
@ -58,16 +58,23 @@ public sealed class EventManagerSystem : EntitySystem
|
|||
/// </summary>
|
||||
public void RunRandomEvent(EntityTableSelector limitedEventsTable)
|
||||
{
|
||||
if(TryGenerateRandomEvent(limitedEventsTable, out string? randomLimitedEvent) && randomLimitedEvent != null) // DeltaV seperated into own method
|
||||
if(TryGenerateRandomEvent(limitedEventsTable, out string? randomLimitedEvent) && randomLimitedEvent != null) // DeltaV - seperated into own method
|
||||
GameTicker.AddGameRule(randomLimitedEvent);
|
||||
}
|
||||
|
||||
// DeltaV seperate event generation method
|
||||
// DeltaV - overloaded for backwards compatiblity
|
||||
public bool TryGenerateRandomEvent(EntityTableSelector limitedEventsTable, out string? randomLimitedEvent)
|
||||
{
|
||||
return TryGenerateRandomEvent(limitedEventsTable, out randomLimitedEvent, null);
|
||||
}
|
||||
// DeltaV - end overloaded for backwards compatiblity
|
||||
|
||||
// DeltaV - seperate event generation method
|
||||
public bool TryGenerateRandomEvent(EntityTableSelector limitedEventsTable, out string? randomLimitedEvent, TimeSpan? eventRunTime) // Event time checks compared to eventRunTime
|
||||
// unless its null in which case current time is used
|
||||
{
|
||||
randomLimitedEvent = null;
|
||||
// Snippet from upstreams RunRandomEvent
|
||||
if (!TryBuildLimitedEvents(limitedEventsTable, out var limitedEvents))
|
||||
if (!TryBuildLimitedEvents(limitedEventsTable, out var limitedEvents, eventRunTime))
|
||||
{
|
||||
Log.Warning("Provided event table could not build dict!");
|
||||
return false;
|
||||
|
|
@ -86,21 +93,27 @@ public sealed class EventManagerSystem : EntitySystem
|
|||
Log.Warning("A requested event is not available!");
|
||||
return false;
|
||||
}
|
||||
// End snippet from upstreams RunRandomEvent
|
||||
|
||||
return true;
|
||||
}
|
||||
// DeltaV end seperate event generation method
|
||||
// DeltaV - end seperate event generation method
|
||||
|
||||
// DeltaV - overloaded for backwards compatiblity
|
||||
public bool TryBuildLimitedEvents(EntityTableSelector limitedEventsTable, out Dictionary<EntityPrototype, StationEventComponent> limitedEvents)
|
||||
{
|
||||
return TryBuildLimitedEvents(limitedEventsTable, out limitedEvents, null);
|
||||
}
|
||||
// DeltaV - end overloaded for backwards compatiblity
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the provided EntityTableSelector gives at least one prototype with a StationEvent comp.
|
||||
/// </summary>
|
||||
public bool TryBuildLimitedEvents(EntityTableSelector limitedEventsTable, out Dictionary<EntityPrototype, StationEventComponent> limitedEvents)
|
||||
public bool TryBuildLimitedEvents(EntityTableSelector limitedEventsTable, out Dictionary<EntityPrototype, StationEventComponent> limitedEvents, TimeSpan? eventRunTime) // DeltaV - Add a time overide
|
||||
{
|
||||
limitedEvents = new Dictionary<EntityPrototype, StationEventComponent>();
|
||||
|
||||
var availableEvents = AvailableEvents(); // handles the player counts and individual event restrictions
|
||||
|
||||
var availableEvents = AvailableEvents(eventRunTime); // handles the player counts and individual event restrictions
|
||||
// DeltaV - Overide time for stashing events
|
||||
if (availableEvents.Count == 0)
|
||||
{
|
||||
Log.Warning("No events were available to run!");
|
||||
|
|
@ -186,6 +199,16 @@ public sealed class EventManagerSystem : EntitySystem
|
|||
return null;
|
||||
}
|
||||
|
||||
// DeltaV - overloaded for backwards compatiblity
|
||||
public Dictionary<EntityPrototype, StationEventComponent> AvailableEvents(
|
||||
bool ignoreEarliestStart = false,
|
||||
int? playerCountOverride = 100,
|
||||
TimeSpan? currentTimeOverride = null)
|
||||
{
|
||||
return AvailableEvents(null, ignoreEarliestStart, playerCountOverride, currentTimeOverride);
|
||||
}
|
||||
// DeltaV - end overloaded for backwards compatiblity
|
||||
|
||||
/// <summary>
|
||||
/// Gets the events that have met their player count, time-until start, etc.
|
||||
/// </summary>
|
||||
|
|
@ -193,16 +216,21 @@ public sealed class EventManagerSystem : EntitySystem
|
|||
/// <param name="currentTimeOverride">Override for round time, if using this to simulate events rather than in an actual round.</param>
|
||||
/// <returns></returns>
|
||||
public Dictionary<EntityPrototype, StationEventComponent> AvailableEvents(
|
||||
bool ignoreEarliestStart = true,
|
||||
TimeSpan? eventRunTime,
|
||||
bool ignoreEarliestStart = false,
|
||||
int? playerCountOverride = 100,
|
||||
TimeSpan? currentTimeOverride = null)
|
||||
TimeSpan? currentTimeOverride = null
|
||||
)
|
||||
{
|
||||
var playerCount = playerCountOverride ?? _playerManager.PlayerCount;
|
||||
|
||||
// playerCount does a lock so we'll just keep the variable here
|
||||
var currentTime = currentTimeOverride ?? (!ignoreEarliestStart
|
||||
? GameTicker.RoundDuration()
|
||||
: TimeSpan.Zero);
|
||||
var currentTime = currentTimeOverride ?? (
|
||||
(!ignoreEarliestStart
|
||||
? eventRunTime // DeltaV - Use eventRunTime instead of RoundDuration if provided
|
||||
?? GameTicker.RoundDuration()
|
||||
: TimeSpan.Zero)
|
||||
);
|
||||
|
||||
var result = new Dictionary<EntityPrototype, StationEventComponent>();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,20 @@
|
|||
using Content.Server.GameTicking;
|
||||
using Content.Server.GameTicking.Rules;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.DeltaV.StationEvents;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server.StationEvents;
|
||||
|
||||
public sealed class RampingStationEventSchedulerSystem : GameRuleSystem<RampingStationEventSchedulerComponent>
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!; // DeltaV
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly EventManagerSystem _event = default!;
|
||||
[Dependency] private readonly GameTicker _gameTicker = default!;
|
||||
[Dependency] private readonly NextEventSystem _next = default!; // DeltaV
|
||||
|
||||
/// <summary>
|
||||
/// Returns the ChaosModifier which increases as round time increases to a point.
|
||||
|
|
@ -36,6 +40,14 @@ public sealed class RampingStationEventSchedulerSystem : GameRuleSystem<RampingS
|
|||
component.StartingChaos = component.MaxChaos / 10;
|
||||
|
||||
PickNextEventTime(uid, component);
|
||||
|
||||
// DeltaV - end init NextEventComp
|
||||
NextEventComponent? nextEventComponent = null;
|
||||
if (Resolve(uid, ref nextEventComponent, false)
|
||||
&& _event.TryGenerateRandomEvent(component.ScheduledGameRules, out string? firstEvent, TimeSpan.FromSeconds(component.TimeUntilNextEvent))
|
||||
&& firstEvent != null)
|
||||
_next.UpdateNextEvent(nextEventComponent, firstEvent, TimeSpan.FromSeconds(component.TimeUntilNextEvent));
|
||||
// DeltaV - end init NextEventComp
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
|
|
@ -57,6 +69,24 @@ public sealed class RampingStationEventSchedulerSystem : GameRuleSystem<RampingS
|
|||
continue;
|
||||
}
|
||||
|
||||
// DeltaV events using NextEventComponent
|
||||
NextEventComponent? nextEventComponent = null;
|
||||
|
||||
if (Resolve(uid, ref nextEventComponent, false)) // If there is a nextEventComponent use the stashed event instead of running it directly.
|
||||
{
|
||||
PickNextEventTime(uid, scheduler);
|
||||
TimeSpan nextEventTime = _timing.CurTime + TimeSpan.FromSeconds(scheduler.TimeUntilNextEvent);
|
||||
if (!_event.TryGenerateRandomEvent(scheduler.ScheduledGameRules, out string? generatedEvent, nextEventTime) || generatedEvent == null)
|
||||
continue;
|
||||
// Cycle the stashed event with the new generated event and time.
|
||||
string storedEvent = _next.UpdateNextEvent(nextEventComponent, generatedEvent, nextEventTime);
|
||||
if (storedEvent == null || storedEvent == string.Empty) //If there was no stored event don't try to run it.
|
||||
continue;
|
||||
GameTicker.AddGameRule(storedEvent);
|
||||
continue;
|
||||
}
|
||||
// DeltaV end events using NextEventComponent
|
||||
|
||||
PickNextEventTime(uid, scheduler);
|
||||
_event.RunRandomEvent(scheduler.ScheduledGameRules);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,5 +15,5 @@ public sealed partial class NextEventComponent : Component
|
|||
/// Round time of the scheduler's next station event.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float NextEventTime;
|
||||
public TimeSpan NextEventTime;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ public sealed partial class NextEventSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Updates the NextEventComponent with the provided id and time and returns the previously stored id.
|
||||
/// </summary>
|
||||
public EntProtoId UpdateNextEvent(NextEventComponent component, EntProtoId newEventId, float newEventTime)
|
||||
public EntProtoId UpdateNextEvent(NextEventComponent component, EntProtoId newEventId, TimeSpan newEventTime)
|
||||
{
|
||||
EntProtoId oldEventId = component.NextEventId; // Store components current NextEventId for return
|
||||
component.NextEventId = newEventId;
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
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, Access(typeof(SharedTelegnosisPowerSystem))]
|
||||
[RegisterComponent]
|
||||
public sealed partial class TelegnosisPowerComponent : Component
|
||||
{
|
||||
[DataField("prototype")]
|
||||
|
|
@ -20,4 +20,4 @@ namespace Content.Shared.Abilities.Psionics
|
|||
[DataField("telegnosisActionEntity")]
|
||||
public EntityUid? TelegnosisActionEntity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
namespace Content.Shared.Abilities.Psionics;
|
||||
|
||||
[RegisterComponent, Access(typeof(SharedTelegnosisPowerSystem))]
|
||||
public sealed partial class TelegnosticProjectionComponent : Component;
|
||||
namespace Content.Shared.Abilities.Psionics
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed partial class TelegnosticProjectionComponent : Component
|
||||
{}
|
||||
}
|
||||
|
|
@ -1,4 +1,86 @@
|
|||
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
|
||||
type: Fix
|
||||
id: 169
|
||||
time: '2023-12-14T05:13:43.0000000+00:00'
|
||||
- author: UnicornOnLSD
|
||||
changes:
|
||||
- message: Changed bags of holding cost to be more consistent.
|
||||
type: Tweak
|
||||
id: 170
|
||||
time: '2023-12-14T09:17:35.0000000+00:00'
|
||||
- author: Adrian16199
|
||||
changes:
|
||||
- message: Fixed non-wizden species not having markings.
|
||||
|
|
@ -3632,100 +3714,3 @@
|
|||
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
|
||||
- author: Tomce795
|
||||
changes:
|
||||
- message: Added a new stamp for Prosecutor and added it to their starting loadout.
|
||||
Also added the Space Law book to the starting loadout for both Prosec and Clerk.
|
||||
type: Add
|
||||
id: 669
|
||||
time: '2024-11-12T04:15:14.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/2158
|
||||
- author: Unkn0wnGh0st333
|
||||
changes:
|
||||
- message: Whoops someone forgot to give Clerk and Prosecutor their company-mandated
|
||||
mindshields... that's fixed now.
|
||||
type: Tweak
|
||||
id: 670
|
||||
time: '2024-11-12T06:21:28.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/2175
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,8 +0,0 @@
|
|||
## 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,11 @@ 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 =
|
||||
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.
|
||||
Sell your concoctions to local agents, crew, and anyone with supplies.
|
||||
Stay on your ship, it is your lifeblood!
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -5,4 +5,3 @@ 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,7 +16,6 @@
|
|||
ClothingOuterPonchoClassic: 2
|
||||
ClothingUniformJumpsuitKilt: 3 # DeltaV - SCOTTTTLANDDDDD FURREVERRRRR!!
|
||||
ClothingEyesEyepatch: 2 # Delta-V Yarrr
|
||||
ClothingUniformBlackTurtleneck : 2 # DeltaV - Clothing addition
|
||||
ClothingHeadHatPwig: 2
|
||||
ClothingOuterRobesJudge: 2
|
||||
ClothingOuterPoncho: 2
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
- 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,13 +397,3 @@
|
|||
- 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,12 +38,4 @@
|
|||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
parent: BaseGameRule
|
||||
id: GlimmerEventScheduler
|
||||
components:
|
||||
- type: NextEvent
|
||||
- type: BasicStationEventScheduler
|
||||
minMaxEventTiming:
|
||||
min: 300
|
||||
|
|
|
|||
|
|
@ -5,20 +5,3 @@
|
|||
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
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
- 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,7 +482,6 @@
|
|||
- type: VendingMachineRestock
|
||||
canRestock:
|
||||
- ChemVendInventory
|
||||
- ChemVendInventorySyndicate # DeltaV: Let it restock synthesis/nukie vendor
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: base
|
||||
|
|
|
|||
|
|
@ -436,8 +436,6 @@
|
|||
- MagazineBoxSpecialHoly
|
||||
- MagazineBoxSpecialMindbreaker
|
||||
- AdvancedTruncheon
|
||||
- LauncherSyringe
|
||||
- MiniSyringe
|
||||
# End DeltaV additions
|
||||
|
||||
- type: entity
|
||||
|
|
@ -1068,10 +1066,6 @@
|
|||
- 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. Backwards compatible with standard ChemVend restocks. # DeltaV: Add chemvend part
|
||||
description: Not made with freshly squeezed syndies I hope.
|
||||
components:
|
||||
- type: VendingMachine
|
||||
pack: ChemVendInventorySyndicate
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
parent: BaseGameRule
|
||||
id: MeteorSwarmScheduler
|
||||
components:
|
||||
- type: NextEvent # DeltaV: Queue Event
|
||||
- type: GameRule
|
||||
- type: BasicStationEventScheduler
|
||||
minimumTimeUntilFirstEvent: 600 # 10 min
|
||||
|
|
@ -68,6 +69,7 @@
|
|||
parent: BaseGameRule
|
||||
id: MeteorSwarmMildScheduler
|
||||
components:
|
||||
- type: NextEvent # DeltaV: Queue Event
|
||||
- type: GameRule
|
||||
- type: BasicStationEventScheduler
|
||||
minimumTimeUntilFirstEvent: 600 # 10 min
|
||||
|
|
@ -82,6 +84,7 @@
|
|||
parent: BaseGameRule
|
||||
id: KesslerSyndromeScheduler
|
||||
components:
|
||||
- type: NextEvent # DeltaV: Queue Event
|
||||
- type: GameRule
|
||||
- type: RampingStationEventScheduler
|
||||
scheduledGameRules: !type:NestedSelector
|
||||
|
|
@ -94,6 +97,7 @@
|
|||
id: GameRuleMeteorSwarm
|
||||
abstract: true
|
||||
components:
|
||||
- type: NextEvent # DeltaV: Queue Event
|
||||
- type: GameRule
|
||||
- type: StationEvent
|
||||
reoccurrenceDelay: 1
|
||||
|
|
|
|||
|
|
@ -309,6 +309,7 @@
|
|||
id: RampingStationEventScheduler
|
||||
parent: BaseGameRule
|
||||
components:
|
||||
- type: NextEvent # DeltaV: Queue Event
|
||||
- type: RampingStationEventScheduler
|
||||
averageChaos: 4.5 # DeltaV
|
||||
averageEndTime: 180 # DeltaV
|
||||
|
|
|
|||
|
|
@ -50,3 +50,18 @@
|
|||
# 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,6 +49,8 @@
|
|||
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,11 +5,10 @@
|
|||
icon:
|
||||
sprite: Interface/Misc/research_disciplines.rsi
|
||||
state: industrial
|
||||
lockoutTier: 4 # DeltaV: Lockout occurs at t4
|
||||
tierPrerequisites:
|
||||
1: 0
|
||||
2: 1 # DeltaV: raised to 1
|
||||
3: 1 # DeltaV: raised to 1
|
||||
2: 0.75
|
||||
3: 0.75
|
||||
|
||||
- type: techDiscipline
|
||||
id: Arsenal
|
||||
|
|
@ -18,11 +17,10 @@
|
|||
icon:
|
||||
sprite: Interface/Misc/research_disciplines.rsi
|
||||
state: arsenal
|
||||
lockoutTier: 4 # DeltaV: Lockout occurs at t4
|
||||
tierPrerequisites:
|
||||
1: 0
|
||||
2: 1 # DeltaV: raised to 1
|
||||
3: 1 # DeltaV: raised to 1
|
||||
2: 0.75
|
||||
3: 0.75
|
||||
|
||||
- type: techDiscipline
|
||||
id: Experimental
|
||||
|
|
@ -31,11 +29,10 @@
|
|||
icon:
|
||||
sprite: Interface/Misc/research_disciplines.rsi
|
||||
state: experimental
|
||||
lockoutTier: 4 # DeltaV: Lockout occurs at t4
|
||||
tierPrerequisites:
|
||||
1: 0
|
||||
2: 1 # DeltaV: raised to 1
|
||||
3: 1 # DeltaV: raised to 1
|
||||
2: 0.75
|
||||
3: 0.75
|
||||
|
||||
- type: techDiscipline
|
||||
id: CivilianServices
|
||||
|
|
@ -44,8 +41,7 @@
|
|||
icon:
|
||||
sprite: Interface/Misc/research_disciplines.rsi
|
||||
state: civilianservices
|
||||
lockoutTier: 4 # DeltaV: Lockout occurs at t4
|
||||
tierPrerequisites:
|
||||
1: 0
|
||||
2: 1 # DeltaV: raised to 1
|
||||
3: 1 # DeltaV: raised to 1
|
||||
2: 0.75
|
||||
3: 0.75
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@
|
|||
- 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 OR if the deal involves items of a primarily sentimental value (e.g. HoP's Ian scrapbook, LO's lucky dollar).
|
||||
- Leeway is given to making deals with criminals if the deal benefits the safety or situation of the crew and station.
|
||||
- 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,12 +1,9 @@
|
|||
<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.
|
Before Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 519 B |
Binary file not shown.
|
Before Width: | Height: | Size: 579 B |
Binary file not shown.
|
Before Width: | Height: | Size: 598 B |
|
|
@ -1,30 +0,0 @@
|
|||
{
|
||||
"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.
|
Before Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 450 B |
|
|
@ -23,10 +23,6 @@
|
|||
"name": "direction_justice",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "direction_aicore",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "chapel"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue