diff --git a/Content.Client/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterBoundUserInterface.cs b/Content.Client/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterBoundUserInterface.cs
new file mode 100644
index 00000000000..c52ee94d6e3
--- /dev/null
+++ b/Content.Client/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterBoundUserInterface.cs
@@ -0,0 +1,53 @@
+using Content.Shared._CorvaxNext.BluespaceHarvester;
+using JetBrains.Annotations;
+
+namespace Content.Client._CorvaxNext.BluespaceHarvester;
+
+[UsedImplicitly]
+public sealed class BluespaceHarvesterBoundUserInterface : BoundUserInterface
+{
+ private BluespaceHarvesterMenu? _window;
+
+ public BluespaceHarvesterBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
+ {
+ }
+
+ protected override void Open()
+ {
+ base.Open();
+
+ _window = new BluespaceHarvesterMenu(this);
+ _window.OnClose += Close;
+ _window?.OpenCentered();
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ if (!disposing)
+ return;
+
+ _window?.Dispose();
+ _window = null;
+ }
+
+ protected override void UpdateState(BoundUserInterfaceState state)
+ {
+ base.UpdateState(state);
+
+ if (state is not BluespaceHarvesterBoundUserInterfaceState current)
+ return;
+
+ _window?.UpdateState(current);
+ }
+
+ public void SendTargetLevel(int level)
+ {
+ SendMessage(new BluespaceHarvesterTargetLevelMessage(level));
+ }
+
+ public void SendBuy(Shared._CorvaxNext.BluespaceHarvester.BluespaceHarvesterCategory category)
+ {
+ SendMessage(new BluespaceHarvesterBuyMessage(category));
+ }
+}
diff --git a/Content.Client/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterCategory.xaml b/Content.Client/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterCategory.xaml
new file mode 100644
index 00000000000..eef4ac89883
--- /dev/null
+++ b/Content.Client/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterCategory.xaml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/Content.Client/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterCategory.xaml.cs b/Content.Client/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterCategory.xaml.cs
new file mode 100644
index 00000000000..b3b20863460
--- /dev/null
+++ b/Content.Client/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterCategory.xaml.cs
@@ -0,0 +1,20 @@
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.XAML;
+using Content.Shared._CorvaxNext.BluespaceHarvester;
+
+namespace Content.Client._CorvaxNext.BluespaceHarvester;
+
+[GenerateTypedNameReferences]
+public sealed partial class BluespaceHarvesterCategory : Control
+{
+ public BluespaceHarvesterCategory(BluespaceHarvesterCategoryInfo category, bool canBuy)
+ {
+ RobustXamlLoader.Load(this);
+
+ CategoryLabel.Text = Loc.GetString($"bluespace-harvester-category-{Enum.GetName(typeof(Shared._CorvaxNext.BluespaceHarvester.BluespaceHarvesterCategory), category.Type)}");
+
+ CategoryButton.Text = $"{category.Cost}";
+ CategoryButton.Disabled = !canBuy;
+ }
+}
diff --git a/Content.Client/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterMenu.xaml b/Content.Client/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterMenu.xaml
new file mode 100644
index 00000000000..8c1e8842d7e
--- /dev/null
+++ b/Content.Client/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterMenu.xaml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content.Client/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterMenu.xaml.cs b/Content.Client/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterMenu.xaml.cs
new file mode 100644
index 00000000000..cf1621406f3
--- /dev/null
+++ b/Content.Client/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterMenu.xaml.cs
@@ -0,0 +1,59 @@
+using Content.Client.UserInterface.Controls;
+using Content.Shared._CorvaxNext.BluespaceHarvester;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client._CorvaxNext.BluespaceHarvester;
+
+[GenerateTypedNameReferences]
+public sealed partial class BluespaceHarvesterMenu : FancyWindow
+{
+ private readonly BluespaceHarvesterBoundUserInterface _owner;
+
+ public BluespaceHarvesterMenu(BluespaceHarvesterBoundUserInterface owner)
+ {
+ RobustXamlLoader.Load(this);
+
+ _owner = owner;
+
+ InputLevelBar.OnTextEntered += (args) =>
+ {
+ if (!int.TryParse(args.Text, out var level) || level < 0 || level > 20)
+ {
+ InputLevelBar.Text = "0";
+ return;
+ }
+ _owner.SendTargetLevel(level);
+ };
+
+ // EntityView.SetEntity(_owner.Owner);
+ }
+
+ public void UpdateState(BluespaceHarvesterBoundUserInterfaceState state)
+ {
+ TargetLevel.Text = $"{state.TargetLevel}";
+ CurrentLevel.Text = $"{state.CurrentLevel}";
+ DesiredBar.Value = ((float)state.CurrentLevel) / ((float)state.MaxLevel);
+
+ PowerUsageLabel.Text = Loc.GetString("power-monitoring-window-value", ("value", state.PowerUsage));
+ PowerUsageNextLabel.Text = Loc.GetString("power-monitoring-window-value", ("value", state.PowerUsageNext));
+ PowerSuppliertLabel.Text = Loc.GetString("power-monitoring-window-value", ("value", state.PowerSuppliert));
+
+ AvailablePointsLabel.Text = $"{state.Points}";
+ TotalPontsLabel.Text = $"{state.TotalPoints}";
+ GenerationPointsLabel.Text = $"{state.PointsGen}";
+
+ Categories.RemoveAllChildren();
+ foreach (var category in state.Categories)
+ {
+ var child = new BluespaceHarvesterCategory(category, state.Points >= category.Cost);
+
+ child.CategoryButton.OnButtonDown += (args) =>
+ {
+ _owner.SendBuy(category.Type);
+ };
+
+ Categories.AddChild(child);
+ }
+ }
+}
diff --git a/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterBundleComponent.cs b/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterBundleComponent.cs
new file mode 100644
index 00000000000..9682da2120c
--- /dev/null
+++ b/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterBundleComponent.cs
@@ -0,0 +1,14 @@
+using Content.Shared.Storage;
+
+namespace Content.Server._CorvaxNext.BluespaceHarvester;
+
+// TODO: Make it not tied to the harvester for mappers and loot in debris and dungeons.
+[RegisterComponent]
+public sealed partial class BluespaceHarvesterBundleComponent : Component
+{
+ [DataField]
+ public List Contents = new();
+
+ [DataField]
+ public bool Spawned;
+}
diff --git a/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterBundleSystem.cs b/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterBundleSystem.cs
new file mode 100644
index 00000000000..bd15528d785
--- /dev/null
+++ b/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterBundleSystem.cs
@@ -0,0 +1,44 @@
+using Content.Shared.Destructible;
+using Content.Shared.Storage.Components;
+using Robust.Shared.Random;
+
+namespace Content.Server._CorvaxNext.BluespaceHarvester;
+
+public sealed class BluespaceHarvesterBundleSystem : EntitySystem
+{
+ [Dependency] private readonly IRobustRandom _random = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnOpen);
+ SubscribeLocalEvent(OnDestruction);
+ }
+
+ private void OnOpen(Entity bundle, ref StorageBeforeOpenEvent args)
+ {
+ CreateLoot(bundle);
+ }
+
+ private void OnDestruction(Entity bundle, ref DestructionEventArgs args)
+ {
+ CreateLoot(bundle);
+ }
+
+ private void CreateLoot(Entity bundle)
+ {
+ if (bundle.Comp.Spawned)
+ return;
+
+ var content = _random.Pick(bundle.Comp.Contents);
+ var position = Transform(bundle.Owner).Coordinates;
+
+ for (var i = 0; i < content.Amount; i++)
+ {
+ Spawn(content.PrototypeId, position);
+ }
+
+ bundle.Comp.Spawned = true;
+ }
+}
diff --git a/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterComponent.cs b/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterComponent.cs
new file mode 100644
index 00000000000..a83f9706335
--- /dev/null
+++ b/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterComponent.cs
@@ -0,0 +1,162 @@
+using Content.Shared._CorvaxNext.BluespaceHarvester;
+using Robust.Shared.Audio;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server._CorvaxNext.BluespaceHarvester;
+
+[RegisterComponent, Access(typeof(BluespaceHarvesterSystem))]
+public sealed partial class BluespaceHarvesterComponent : Component
+{
+ ///
+ /// Responsible for forcibly turning off the harvester and blocking input level.
+ ///
+ [DataField]
+ public bool Reseted;
+
+ ///
+ /// The current level at which the harvester is located is what other parameters are calculated from.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public int CurrentLevel;
+
+ ///
+ /// The level to which the harvester always strives if possible. It is installed by the player, but during the reset, this feature is blocked.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public int TargetLevel;
+
+ ///
+ /// The level above which it is impossible not to set TargetLevel.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public int MaxLevel = 20;
+
+ ///
+ /// The level above which the Danger begin to rise.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public int StableLevel = 10;
+
+ ///
+ /// Similar to StableLevel, but replaces it when hacked by a Emag.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public int EmaggedStableLevel = 5;
+
+ ///
+ /// Points generated by harvesters, which can be spent on purchasing things in categories.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public int Points;
+
+ ///
+ /// Displays how many points have been generated, regardless of spending.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public int TotalPoints;
+
+ ///
+ /// Tap to visualize any state of the harvester after hacking.
+ ///
+ [DataField]
+ public BluespaceHarvesterVisuals RedspaceTap = BluespaceHarvesterVisuals.TapRedspace;
+
+ ///
+ /// The level of danger on which the spawn of DANGEROUS rifts depends.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public int Danger;
+
+ ///
+ /// This will allow you to pay a certain fee for careless work with this device.
+ /// Given mainly for reset when there is a loss of electricity from the source,
+ /// but the value is not too large to cause a lot of harm.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public int DangerFromReset = 75;
+
+ ///
+ /// After this danger value, the generation of dangerous creatures and anomalies will begin.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public int DangerLimit = 175;
+
+ ///
+ /// A prototype rift created when the number of allowed points is exceeded.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public EntProtoId Rift = "BluespaceHarvesterRift";
+
+ ///
+ /// The maximum number of rifts that can appear, the lower this value,
+ /// the greater the chance of strong mobs
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public int RiftCount = 3;
+
+ ///
+ /// Tries once every 1 second, with this chance to create a rift if DangerLimit is exceeded.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float RiftChance = 0.08f;
+
+ ///
+ /// Replaces RiftChance when hacked by Emag.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float EmaggedRiftChance = 0.03f;
+
+ [DataField]
+ public List Categories = new()
+ {
+ new BluespaceHarvesterCategoryInfo()
+ {
+ PrototypeId = "RandomHarvesterBiologicalLoot",
+ Cost = 7_500,
+ Type = BluespaceHarvesterCategory.Biological,
+ },
+ new BluespaceHarvesterCategoryInfo()
+ {
+ PrototypeId = "RandomHarvesterTechnologicalLoot",
+ Cost = 7_500,
+ Type = BluespaceHarvesterCategory.Technological,
+ },
+ new BluespaceHarvesterCategoryInfo()
+ {
+ PrototypeId = "RandomHarvesterIndustrialLoot",
+ Cost = 7_500,
+ Type = BluespaceHarvesterCategory.Industrial,
+ },
+ new BluespaceHarvesterCategoryInfo()
+ {
+ PrototypeId = "RandomHarvesterDestructionLoot",
+ Cost = 7_500,
+ Type = BluespaceHarvesterCategory.Destruction,
+ },
+ };
+
+ ///
+ /// The radius within which crates and rifts can appear.
+ ///
+ [DataField]
+ public float SpawnRadius = 5f;
+
+ [DataField]
+ public EntProtoId SpawnEffect = "EffectEmpPulse";
+
+ [DataField]
+ public SoundSpecifier SpawnSound = new SoundPathSpecifier("/Audio/Effects/teleport_arrival.ogg");
+}
+
+[Serializable]
+public sealed class BluespaceHarvesterTap
+{
+ ///
+ /// The minimum level from which Visual is enabled.
+ ///
+ [DataField]
+ public int Level;
+
+ [DataField]
+ public BluespaceHarvesterVisuals Visual;
+}
diff --git a/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterRiftComponent.cs b/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterRiftComponent.cs
new file mode 100644
index 00000000000..36f2d17b00a
--- /dev/null
+++ b/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterRiftComponent.cs
@@ -0,0 +1,53 @@
+using Robust.Shared.Prototypes;
+
+namespace Content.Server._CorvaxNext.BluespaceHarvester;
+
+[RegisterComponent]
+public sealed partial class BluespaceHarvesterRiftComponent : Component
+{
+ ///
+ /// The current danger level of the portal with which he will buy things from the Spawn list.
+ ///
+ [DataField]
+ public int Danger;
+
+ ///
+ /// The portal also periodically generates a random, weak mob from the PassiveSpawn list.
+ ///
+ [DataField]
+ public float PassiveSpawnCooldown = 30f;
+
+ [DataField]
+ public float PassiveSpawnAccumulator;
+
+ ///
+ /// A list of weak monsters that will encourage breaking rifts.
+ ///
+ [DataField]
+ public List PassiveSpawn = new();
+
+ ///
+ /// Delay between attempts to spawn more than 3 mobs.
+ ///
+ [DataField]
+ public float SpawnCooldown = 5f;
+
+ [DataField]
+ public float SpawnAccumulator;
+
+ ///
+ /// Monsters and their cost for purchase through the portal are described here; there may be expensive but very dangerous creatures, for example, kudzu or a dragon.
+ ///
+ [DataField]
+ public List Spawn = new();
+}
+
+[Serializable, DataDefinition]
+public partial struct EntitySpawn
+{
+ [DataField]
+ public EntProtoId? Id = null;
+
+ [DataField]
+ public int Cost;
+}
diff --git a/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterRiftSystem.cs b/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterRiftSystem.cs
new file mode 100644
index 00000000000..68dbd410493
--- /dev/null
+++ b/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterRiftSystem.cs
@@ -0,0 +1,70 @@
+using Robust.Shared.Random;
+
+namespace Content.Server._CorvaxNext.BluespaceHarvester;
+
+public sealed class BluespaceHarvesterRiftSystem : EntitySystem
+{
+ [Dependency] private readonly IRobustRandom _random = default!;
+
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+
+ var query = EntityQueryEnumerator();
+ while (query.MoveNext(out var uid, out var comp, out var xform))
+ {
+ comp.PassiveSpawnAccumulator += frameTime;
+ if (comp.PassiveSpawnAccumulator >= comp.PassiveSpawnCooldown)
+ {
+ comp.PassiveSpawnAccumulator -= comp.PassiveSpawnCooldown;
+ comp.PassiveSpawnAccumulator += _random.NextFloat(comp.PassiveSpawnCooldown / 2f);
+
+ // Random, not particularly dangerous mob.
+ Spawn(_random.Pick(comp.PassiveSpawn), xform.Coordinates);
+ }
+
+ comp.SpawnAccumulator += frameTime;
+
+ if (comp.SpawnAccumulator < comp.SpawnCooldown)
+ continue;
+
+ comp.SpawnAccumulator -= comp.SpawnCooldown;
+ comp.PassiveSpawnAccumulator += _random.NextFloat(comp.SpawnCooldown);
+
+ UpdateSpawn((uid, comp, xform));
+ }
+ }
+
+ private void UpdateSpawn(Entity ent)
+ {
+ var rift = ent.Comp1;
+ var xfrom = ent.Comp2;
+
+ var count = 0;
+ while (rift.Danger != 0 && count < 3)
+ {
+ count++;
+
+ var pickable = new List();
+ foreach (var spawn in rift.Spawn)
+ {
+ if (spawn.Cost <= rift.Danger)
+ pickable.Add(spawn);
+ }
+
+ // If we cannot choose anything, this means that we have used up all the danger sufficient before spawn.
+ if (pickable.Count == 0)
+ {
+ rift.Danger = 0; // This will disable pointless spawn attempts.
+ break;
+ }
+
+ // In order for there to be a dangerous mob,
+ // it should still be a good story,
+ // because they still have a whole cart of ordinary ones.
+ var pick = _random.Pick(pickable);
+ rift.Danger -= pick.Cost; // Deduct the risk spent on the purchase.
+ Spawn(pick.Id, xfrom.Coordinates);
+ }
+ }
+}
diff --git a/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterSystem.cs b/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterSystem.cs
new file mode 100644
index 00000000000..cf6ca040e6c
--- /dev/null
+++ b/Content.Server/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterSystem.cs
@@ -0,0 +1,402 @@
+using Content.Server.NodeContainer;
+using Content.Server.NodeContainer.EntitySystems;
+using Content.Server.NodeContainer.Nodes;
+using Content.Server.Power.Components;
+using Content.Server.Power.NodeGroups;
+using Content.Shared.Audio;
+using Content.Shared._CorvaxNext.BluespaceHarvester;
+using Content.Shared.Destructible;
+using Content.Shared.Emag.Components;
+using Microsoft.CodeAnalysis;
+using Robust.Server.GameObjects;
+using Robust.Shared.Random;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using Robust.Shared.Audio.Systems;
+
+namespace Content.Server._CorvaxNext.BluespaceHarvester;
+
+public sealed class BluespaceHarvesterSystem : EntitySystem
+{
+ [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
+ [Dependency] private readonly NodeContainerSystem _nodeContainer = default!;
+ [Dependency] private readonly TransformSystem _transform = default!;
+ [Dependency] private readonly EntityLookupSystem _lookup = default!;
+ [Dependency] private readonly UserInterfaceSystem _ui = default!;
+ [Dependency] private readonly IRobustRandom _random = default!;
+ [Dependency] private readonly SharedAudioSystem _audio = default!;
+ [Dependency] private readonly SharedAmbientSoundSystem _ambientSound = default!;
+
+ public List Taps = new List()
+ {
+ new BluespaceHarvesterTap() { Level = 0, Visual = BluespaceHarvesterVisuals.Tap0 },
+ new BluespaceHarvesterTap() { Level = 1, Visual = BluespaceHarvesterVisuals.Tap1 },
+ new BluespaceHarvesterTap() { Level = 5, Visual = BluespaceHarvesterVisuals.Tap2 },
+ new BluespaceHarvesterTap() { Level = 10, Visual = BluespaceHarvesterVisuals.Tap3 },
+ new BluespaceHarvesterTap() { Level = 15, Visual = BluespaceHarvesterVisuals.Tap4 },
+ new BluespaceHarvesterTap() { Level = 20, Visual = BluespaceHarvesterVisuals.Tap5 },
+ };
+
+ private float _updateTimer;
+ private const float UpdateTime = 1.0f;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnTargetLevel);
+ SubscribeLocalEvent(OnBuy);
+ SubscribeLocalEvent(OnDestruction);
+ }
+
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+
+ _updateTimer += frameTime;
+
+ if (_updateTimer < UpdateTime)
+ return;
+
+ _updateTimer -= UpdateTime;
+
+ var query = EntityQueryEnumerator();
+ while (query.MoveNext(out var uid, out var harvester, out var consumer))
+ {
+ var ent = (uid, harvester);
+
+ // We start only after manual switching on.
+ if (harvester is { Reseted: false, CurrentLevel: 0 })
+ harvester.Reseted = true;
+
+ // The HV wires cannot transmit a lot of electricity so quickly,
+ // which is why it will not start.
+ // So this is simply using the amount of free electricity in the network.
+ var supplier = GetPowerSupplier(uid, harvester);
+ if (supplier < GetUsagePower(harvester.CurrentLevel) && harvester.CurrentLevel != 0)
+ {
+ // If there is insufficient production,
+ // it will reset itself (turn off) and you will need to start it again,
+ // this will not allow you to set it to maximum and enjoy life
+ Reset(uid, harvester);
+ }
+
+ if (harvester.Reseted)
+ {
+ if (harvester.CurrentLevel < harvester.TargetLevel)
+ harvester.CurrentLevel++;
+ }
+
+ if (harvester.CurrentLevel > harvester.TargetLevel)
+ harvester.CurrentLevel--;
+
+ // Increasing the amount of energy regardless of its ability to generate it
+ // will make it impossible to set the desired value and go to rest.
+ consumer.DrawRate = GetUsagePower(harvester.CurrentLevel);
+
+ var generation = GetPointGeneration(uid, harvester);
+ harvester.Points += generation;
+ harvester.TotalPoints += generation;
+
+ // the generation of danger points can be negative, so there is this limitation here.
+ harvester.Danger += GetDangerPointGeneration(uid, harvester);
+ if (harvester.Danger < 0)
+ harvester.Danger = 0;
+
+ // If the danger points exceeded the DangerLimit and we were lucky enough to create a portal, then they will be created.
+ if (harvester.Danger > harvester.DangerLimit && _random.NextFloat(0.0f, 1.0f) <= GetRiftChance(uid, harvester))
+ {
+ SpawnRifts(uid, harvester);
+ }
+
+ if (TryComp(uid, out var ambient))
+ _ambientSound.SetAmbience(uid, harvester.Reseted, ambient); // Bzhzh, bzhzh
+
+ UpdateAppearance(uid, harvester);
+ UpdateUI(uid, harvester);
+ }
+ }
+
+ private void OnDestruction(Entity harvester, ref DestructionEventArgs args)
+ {
+ SpawnRifts(harvester.Owner, harvester.Comp);
+ }
+
+ private void OnTargetLevel(Entity harvester, ref BluespaceHarvesterTargetLevelMessage args)
+ {
+ // If we switch off, we don't need to be switched on.
+ if (!harvester.Comp.Reseted && harvester.Comp.CurrentLevel != 0)
+ return;
+
+ harvester.Comp.TargetLevel = args.TargetLevel;
+ harvester.Comp.Reseted = true; // We start only after manual switching on.
+ UpdateUI(harvester.Owner, harvester.Comp);
+ }
+
+ private void OnBuy(Entity harvester, ref BluespaceHarvesterBuyMessage args)
+ {
+ if (!harvester.Comp.Reseted)
+ return;
+
+ if (!TryGetCategory(harvester.Owner, args.Category, out var info, harvester.Comp))
+ return;
+
+ var category = (BluespaceHarvesterCategoryInfo) info;
+
+ if (harvester.Comp.Points < category.Cost)
+ return;
+
+ harvester.Comp.Points -= category.Cost; // Damn capitalism.
+ SpawnLoot(harvester.Owner, category.PrototypeId, harvester.Comp);
+ }
+
+ private void UpdateAppearance(EntityUid uid, BluespaceHarvesterComponent? harvester = null)
+ {
+ if (!Resolve(uid, ref harvester))
+ return;
+
+ var level = harvester.CurrentLevel;
+ BluespaceHarvesterTap? max = null;
+
+ foreach (var tap in Taps)
+ {
+ if (tap.Level > level)
+ continue;
+
+ if (max == null || tap.Level > max.Level)
+ max = tap;
+ }
+
+ // We get the biggest Tap of all, and replace it with a harvester.
+ if (max == null)
+ return;
+
+ if (Emagged(uid))
+ _appearance.SetData(uid, BluespaceHarvesterVisualLayers.Base, (int) harvester.RedspaceTap);
+ else
+ _appearance.SetData(uid, BluespaceHarvesterVisualLayers.Base, (int) max.Visual);
+
+ _appearance.SetData(uid, BluespaceHarvesterVisualLayers.Effects, level != 0);
+ }
+
+ private void UpdateUI(EntityUid uid, BluespaceHarvesterComponent? harvester = null)
+ {
+ if (!Resolve(uid, ref harvester))
+ return;
+
+ _ui.SetUiState(uid, BluespaceHarvesterUiKey.Key, new BluespaceHarvesterBoundUserInterfaceState(
+ harvester.TargetLevel,
+ harvester.CurrentLevel,
+ harvester.MaxLevel,
+ GetUsagePower(harvester.CurrentLevel),
+ GetUsageNextPower(harvester.CurrentLevel),
+ GetPowerSupplier(uid, harvester),
+ harvester.Points,
+ harvester.TotalPoints,
+ GetPointGeneration(uid, harvester),
+ harvester.Categories
+ ));
+ }
+
+ private uint GetUsageNextPower(int level)
+ {
+ return GetUsagePower(level + 1);
+ }
+
+ private uint GetUsagePower(int level)
+ {
+ // Hopefully in the future you will need to put a mathematical formula or function here.
+ return level switch
+ {
+ 0 => 500,
+ 1 => 500,
+ 2 => 1_000,
+ 3 => 5_000,
+ 4 => 10_000,
+ 5 => 25_000,
+ 6 => 50_000,
+ 7 => 100_000,
+ 8 => 150_000,
+ 9 => 300_000,
+ 10 => 500_000,
+ 11 => 1_000_000,
+ 12 => 1_500_000,
+ 13 => 2_000_000,
+ 14 => 2_500_000,
+ 15 => 3_000_000,
+ 16 => 3_500_000,
+ 17 => 4_000_000,
+ 18 => 4_500_000,
+ 19 => 5_000_000,
+ 20 => 10_000_000,
+ _ => 15_000_000,
+ };
+ }
+
+ ///
+ /// Finds a free point in space and creates a prototype there, similar to a bluespace anomaly.
+ ///
+ private EntityUid? SpawnLoot(EntityUid uid, string prototype, BluespaceHarvesterComponent? harvester = null)
+ {
+ if (!Resolve(uid, ref harvester))
+ return null;
+
+ var xform = Transform(uid);
+ var coords = xform.Coordinates;
+ var newCoords = coords.Offset(_random.NextVector2(harvester.SpawnRadius));
+
+ for (var i = 0; i < 20; i++)
+ {
+ var randVector = _random.NextVector2(harvester.SpawnRadius);
+ newCoords = coords.Offset(randVector);
+
+ if (!_lookup.GetEntitiesIntersecting(newCoords.ToMap(EntityManager, _transform), LookupFlags.Static).Any())
+ break;
+ }
+
+ _audio.PlayPvs(harvester.SpawnSound, uid);
+ Spawn(harvester.SpawnEffect, newCoords);
+
+ return Spawn(prototype, newCoords);
+ }
+
+ private int GetPointGeneration(EntityUid uid, BluespaceHarvesterComponent? harvester = null)
+ {
+ if (!Resolve(uid, ref harvester))
+ return 0;
+
+ return harvester.CurrentLevel * 4 * (Emagged(uid) ? 2 : 1);
+ }
+
+ private int GetDangerPointGeneration(EntityUid uid, BluespaceHarvesterComponent? harvester = null)
+ {
+ if (!Resolve(uid, ref harvester))
+ return 0;
+
+ var stable = GetStableLevel(uid, harvester);
+
+ if (harvester.CurrentLevel < stable && harvester.CurrentLevel != 0)
+ return -1;
+
+ if (harvester.CurrentLevel == stable)
+ return 0;
+
+ return (harvester.CurrentLevel - stable) * 4;
+ }
+
+ private float GetRiftChance(EntityUid uid, BluespaceHarvesterComponent? harvester = null)
+ {
+ if (!Resolve(uid, ref harvester))
+ return 0;
+
+ return Emagged(uid) ? harvester.EmaggedRiftChance : harvester.RiftChance;
+ }
+
+ private int GetStableLevel(EntityUid uid, BluespaceHarvesterComponent? harvester = null)
+ {
+ if (!Resolve(uid, ref harvester))
+ return 0;
+
+ return Emagged(uid) ? harvester.EmaggedStableLevel : harvester.StableLevel;
+ }
+
+ ///
+ /// Receives information about all consumers and generators, subtracts and returns the amount of excess energy in the network.
+ ///
+ private float GetPowerSupplier(EntityUid uid, BluespaceHarvesterComponent? harvester = null, NodeContainerComponent? nodeComp = null)
+ {
+ if (!Resolve(uid, ref harvester, ref nodeComp))
+ return 0;
+
+ if (!_nodeContainer.TryGetNode(nodeComp, "input", out var node))
+ return 0;
+
+ if (node.NodeGroup is not PowerNet netQ)
+ return 0;
+
+ var totalSources = 0.0f;
+ foreach (var psc in netQ.Suppliers)
+ {
+ totalSources += psc.Enabled ? psc.MaxSupply : 0f;
+ }
+
+ foreach (var pcc in netQ.Dischargers)
+ {
+ if (!TryComp(pcc.Owner, out PowerNetworkBatteryComponent? batteryComp))
+ continue;
+
+ totalSources += batteryComp.NetworkBattery.CurrentSupply;
+ }
+
+ var totalConsumer = 0.0f;
+ foreach (var pcc in netQ.Consumers)
+ {
+ totalConsumer += pcc.DrawRate;
+ }
+
+ foreach (var pcc in netQ.Chargers)
+ {
+ if (!TryComp(pcc.Owner, out PowerNetworkBatteryComponent? batteryComp))
+ continue;
+
+ totalConsumer += batteryComp.NetworkBattery.CurrentReceiving;
+ }
+
+ return totalSources - totalConsumer;
+ }
+
+ private bool TryGetCategory(EntityUid uid, BluespaceHarvesterCategory target, [NotNullWhen(true)] out BluespaceHarvesterCategoryInfo? info, BluespaceHarvesterComponent? harvester = null)
+ {
+ info = null;
+ if (!Resolve(uid, ref harvester))
+ return false;
+
+ foreach (var category in harvester.Categories)
+ {
+ if (category.Type != target)
+ continue;
+
+ info = category;
+ return true;
+ }
+
+ return false;
+ }
+
+ private void Reset(EntityUid uid, BluespaceHarvesterComponent? harvester = null)
+ {
+ if (!Resolve(uid, ref harvester))
+ return;
+
+ harvester.Danger += harvester.DangerFromReset;
+ harvester.Reseted = true;
+ harvester.TargetLevel = 0;
+ }
+
+ private bool Emagged(EntityUid uid)
+ {
+ return HasComp(uid);
+ }
+
+ private void SpawnRifts(EntityUid uid, BluespaceHarvesterComponent? harvester = null, int? danger = null)
+ {
+ if (!Resolve(uid, ref harvester))
+ return;
+
+ int currentDanger = danger ?? harvester.Danger;
+
+ var count = _random.Next(harvester.RiftCount);
+ for (var i = 0; i < count; i++)
+ {
+ // Haha loot!
+ var entity = SpawnLoot(uid, harvester.Rift, harvester);
+ if (entity == null)
+ continue;
+
+ EnsureComp((EntityUid) entity).Danger = currentDanger / count;
+ }
+
+ // We gave all the danger to the rifts.
+ harvester.Danger = 0;
+ }
+}
diff --git a/Content.Shared/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterUi.cs b/Content.Shared/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterUi.cs
new file mode 100644
index 00000000000..057e943a8d4
--- /dev/null
+++ b/Content.Shared/_CorvaxNext/BluespaceHarvester/BluespaceHarvesterUi.cs
@@ -0,0 +1,109 @@
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared._CorvaxNext.BluespaceHarvester;
+
+[Serializable, NetSerializable]
+public sealed class BluespaceHarvesterBoundUserInterfaceState : BoundUserInterfaceState
+{
+ public readonly int TargetLevel;
+ public readonly int CurrentLevel;
+ public readonly int MaxLevel;
+
+ public readonly uint PowerUsage;
+ public readonly uint PowerUsageNext;
+ public readonly float PowerSuppliert;
+
+ public readonly int Points;
+ public readonly int TotalPoints;
+ public readonly int PointsGen;
+
+ public readonly List Categories;
+
+ public BluespaceHarvesterBoundUserInterfaceState(int targetLevel, int currentLevel, int maxLevel, uint powerUsage, uint powerUsageNext, float powerSuppliert, int points, int totalPoints, int pointsGen, List categories)
+ {
+ TargetLevel = targetLevel;
+ CurrentLevel = currentLevel;
+ MaxLevel = maxLevel;
+
+ PowerUsage = powerUsage;
+ PowerUsageNext = powerUsageNext;
+ PowerSuppliert = powerSuppliert;
+
+ Points = points;
+ TotalPoints = totalPoints;
+ PointsGen = pointsGen;
+
+ Categories = categories;
+ }
+}
+
+[Serializable, NetSerializable]
+public sealed class BluespaceHarvesterTargetLevelMessage : BoundUserInterfaceMessage
+{
+ public readonly int TargetLevel;
+
+ public BluespaceHarvesterTargetLevelMessage(int targetLevel)
+ {
+ TargetLevel = targetLevel;
+ }
+}
+
+[Serializable, NetSerializable]
+public sealed class BluespaceHarvesterBuyMessage : BoundUserInterfaceMessage
+{
+ public readonly BluespaceHarvesterCategory Category;
+
+ public BluespaceHarvesterBuyMessage(BluespaceHarvesterCategory category)
+ {
+ Category = category;
+ }
+}
+
+[Serializable, NetSerializable]
+public enum BluespaceHarvesterUiKey : byte
+{
+ Key,
+}
+
+[Serializable, NetSerializable]
+public enum BluespaceHarvesterVisuals : byte
+{
+ Tap0,
+ Tap1,
+ Tap2,
+ Tap3,
+ Tap4,
+ Tap5,
+ TapRedspace,
+}
+
+[Serializable, NetSerializable]
+public enum BluespaceHarvesterVisualLayers : byte
+{
+ Base,
+ Effects,
+}
+
+[Serializable, NetSerializable, DataDefinition]
+public partial struct BluespaceHarvesterCategoryInfo
+{
+ [DataField("id")]
+ public EntProtoId PrototypeId = "RandomHarvesterIndustrialLoot";
+
+ [DataField]
+ public int Cost = 0;
+
+ [DataField]
+ public BluespaceHarvesterCategory Type;
+}
+
+
+[Serializable, NetSerializable]
+public enum BluespaceHarvesterCategory : byte
+{
+ Industrial,
+ Technological,
+ Biological,
+ Destruction,
+}
diff --git a/Resources/Locale/en-US/_corvaxnext/bluespace_harvester.ftl b/Resources/Locale/en-US/_corvaxnext/bluespace_harvester.ftl
new file mode 100644
index 00000000000..23f8f5549e1
--- /dev/null
+++ b/Resources/Locale/en-US/_corvaxnext/bluespace_harvester.ftl
@@ -0,0 +1,18 @@
+bluespace-harvester-window-title = Bluespace harvester
+bluespace-harvester-window-lable-input = Input
+bluespace-harvester-window-lable-output = Output
+bluespace-harvester-window-level-input = Input level:
+bluespace-harvester-window-level-target = Target level:
+bluespace-harvester-window-level-current = Current level:
+bluespace-harvester-window-level-desired = Desired level:
+bluespace-harvester-window-power-usage = Power usage:
+bluespace-harvester-window-power-next = Power to next level:
+bluespace-harvester-window-power-surplus = Power surplus:
+bluespace-harvester-window-points-available = Available points:
+bluespace-harvester-window-points-generation = Generation points:
+bluespace-harvester-window-points-total = Total points:
+bluespace-harvester-category-Industrial = Industrial
+bluespace-harvester-category-Technological = Technological
+bluespace-harvester-category-Biological = Biological
+bluespace-harvester-category-Destruction = Destruction
+research-technology-bluespace-mining = Bluespace Mining
diff --git a/Resources/Locale/ru-RU/_corvaxnext/bluespace_harvester.ftl b/Resources/Locale/ru-RU/_corvaxnext/bluespace_harvester.ftl
new file mode 100644
index 00000000000..e55e123d69a
--- /dev/null
+++ b/Resources/Locale/ru-RU/_corvaxnext/bluespace_harvester.ftl
@@ -0,0 +1,18 @@
+bluespace-harvester-window-title = Блюспейс Добытчик
+bluespace-harvester-window-lable-input = Вход
+bluespace-harvester-window-lable-output = Выход
+bluespace-harvester-window-level-input = Входной уровень:
+bluespace-harvester-window-level-target = Целевой уровень:
+bluespace-harvester-window-level-current = Текущий уровень:
+bluespace-harvester-window-level-desired = Желаемый уровень:
+bluespace-harvester-window-power-usage = Использование энергии:
+bluespace-harvester-window-power-next = Мощность до следующего уровня:
+bluespace-harvester-window-power-surplus = Избыток энергии:
+bluespace-harvester-window-points-available = Доступно очков:
+bluespace-harvester-window-points-generation = Очки генерации:
+bluespace-harvester-window-points-total = Всего очков:
+bluespace-harvester-category-Industrial = Промышленная
+bluespace-harvester-category-Technological = Технологическая
+bluespace-harvester-category-Biological = Биологическая
+bluespace-harvester-category-Destruction = Разрушительная
+research-technology-bluespace-mining = Блюспейс Добыча
diff --git a/Resources/Locale/ru-RU/_corvaxnext/station-goal/station-goal-component.ftl b/Resources/Locale/ru-RU/_corvaxnext/station-goal/station-goal-component.ftl
new file mode 100644
index 00000000000..cec9a40646c
--- /dev/null
+++ b/Resources/Locale/ru-RU/_corvaxnext/station-goal/station-goal-component.ftl
@@ -0,0 +1,9 @@
+station-goal-bluespace-harvest =
+ { station-goal-start }[bold]
+ Цель смены станции { $station } — создание и тестирование на перегрузку экспериментального блюспейс-добытчика и добыча в нём 30 тысяч очков.[/bold]
+
+ Вам необходимо построить блюспейс-добычтик, сделать для него достаточное количество электропитания и добыть 30 тысяч очков добычи.
+
+ После выполнения цели станции, экипаж может потратить добытые очки.
+
+ { station-goal-end }
diff --git a/Resources/Prototypes/Corvax/Maps/delta.yml b/Resources/Prototypes/Corvax/Maps/delta.yml
index 97a67ceabdd..c0ab8d5748c 100644
--- a/Resources/Prototypes/Corvax/Maps/delta.yml
+++ b/Resources/Prototypes/Corvax/Maps/delta.yml
@@ -89,3 +89,4 @@
- Bunker
- XenobiologyRepair
- VirusologyAmbusol
+ - BluespaceHarvest
diff --git a/Resources/Prototypes/Corvax/Maps/glacier.yml b/Resources/Prototypes/Corvax/Maps/glacier.yml
index c78f549d1a5..d59ef4a5690 100644
--- a/Resources/Prototypes/Corvax/Maps/glacier.yml
+++ b/Resources/Prototypes/Corvax/Maps/glacier.yml
@@ -90,3 +90,4 @@
- Theatre
- Botany
- Bunker
+ - BluespaceHarvest
diff --git a/Resources/Prototypes/Corvax/Maps/pearl.yml b/Resources/Prototypes/Corvax/Maps/pearl.yml
index 9fe56d1cd36..9d2524632bd 100644
--- a/Resources/Prototypes/Corvax/Maps/pearl.yml
+++ b/Resources/Prototypes/Corvax/Maps/pearl.yml
@@ -79,3 +79,4 @@
- Theatre
- Botany
- Bunker
+ - BluespaceHarvest
diff --git a/Resources/Prototypes/Corvax/Maps/pilgrim.yml b/Resources/Prototypes/Corvax/Maps/pilgrim.yml
index 954e057f4a2..ab9d2c8bec0 100644
--- a/Resources/Prototypes/Corvax/Maps/pilgrim.yml
+++ b/Resources/Prototypes/Corvax/Maps/pilgrim.yml
@@ -85,3 +85,4 @@
- ShuttleEmergency
- Theatre
- Botany
+ - BluespaceHarvest
diff --git a/Resources/Prototypes/Corvax/Maps/silly.yml b/Resources/Prototypes/Corvax/Maps/silly.yml
index 9e0093ddf41..aee0147aa0f 100644
--- a/Resources/Prototypes/Corvax/Maps/silly.yml
+++ b/Resources/Prototypes/Corvax/Maps/silly.yml
@@ -79,3 +79,4 @@
- Theatre
- Botany
- Bunker
+ - BluespaceHarvest
diff --git a/Resources/Prototypes/Corvax/Maps/split.yml b/Resources/Prototypes/Corvax/Maps/split.yml
index 83bb1518504..72f48dc2f2a 100644
--- a/Resources/Prototypes/Corvax/Maps/split.yml
+++ b/Resources/Prototypes/Corvax/Maps/split.yml
@@ -185,3 +185,4 @@
- Zoo
- MiningOutpost
- Tesla
+ - BluespaceHarvest
diff --git a/Resources/Prototypes/Corvax/Maps/terra.yml b/Resources/Prototypes/Corvax/Maps/terra.yml
index 815ab3b48ef..2c3fc955fe8 100644
--- a/Resources/Prototypes/Corvax/Maps/terra.yml
+++ b/Resources/Prototypes/Corvax/Maps/terra.yml
@@ -85,3 +85,4 @@
- Zoo
- MiningOutpost
- Tesla
+ - BluespaceHarvest
diff --git a/Resources/Prototypes/Corvax/Objectives/goals.yml b/Resources/Prototypes/Corvax/Objectives/goals.yml
index 482836319b4..6d92393e658 100644
--- a/Resources/Prototypes/Corvax/Objectives/goals.yml
+++ b/Resources/Prototypes/Corvax/Objectives/goals.yml
@@ -91,3 +91,7 @@
- type: stationGoal
id: AstraRepair
text: station-goal-astra-repair
+
+- type: stationGoal # Corvax-Next
+ id: BluespaceHarvest
+ text: station-goal-bluespace-harvest
diff --git a/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/circuit_board.yml b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/circuit_board.yml
new file mode 100644
index 00000000000..8807cf228ba
--- /dev/null
+++ b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/circuit_board.yml
@@ -0,0 +1,24 @@
+- type: entity
+ id: MachineBluespaceHarvesterCircuitboard
+ parent: BaseMachineCircuitboard
+ name: Bluespace Harvester board
+ description: A machine board for a Bluespace Harvester
+ components:
+ - type: Sprite
+ sprite: _CorvaxNext/Bluespace/module.rsi
+ state: bluespace
+ - type: MachineBoard
+ prototype: BluespaceHarvester
+ stackRequirements:
+ Glass: 15
+ Steel: 15
+ CableHV: 5
+ Manipulator: 5
+ Capacitor: 5
+ MatterBin: 15
+ tagRequirements:
+ GlassBeaker:
+ amount: 5
+ defaultPrototype: Beaker
+ - type: Item
+ size: Normal
diff --git a/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/crates.yml b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/crates.yml
new file mode 100644
index 00000000000..3271f8c0cb8
--- /dev/null
+++ b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/crates.yml
@@ -0,0 +1,64 @@
+- type: entity
+ parent: CrateBaseSecure
+ id: CrateIndustrialSecure
+ name: bluespace industrial crate
+ components:
+ - type: CargoSellBlacklist
+ - type: Icon
+ sprite: _CorvaxNext/Bluespace/Crates/industrial_secure.rsi
+ - type: Sprite
+ sprite: _CorvaxNext/Bluespace/Crates/industrial_secure.rsi
+ - type: AccessReader
+ access: [["Engineering"]]
+
+- type: entity
+ parent: CrateBaseSecure
+ id: CrateTechnologicalSecure
+ name: bluespace technological crate
+ components:
+ - type: CargoSellBlacklist
+ - type: Icon
+ sprite: _CorvaxNext/Bluespace/Crates/technological_secure.rsi
+ - type: Sprite
+ sprite: _CorvaxNext/Bluespace/Crates/technological_secure.rsi
+ - type: AccessReader
+ access: [["Research"]]
+
+- type: entity
+ parent: CrateBaseSecure
+ id: CrateBiologicalSecure
+ name: bluespace biological crate
+ components:
+ - type: CargoSellBlacklist
+ - type: Icon
+ sprite: _CorvaxNext/Bluespace/Crates/biological_secure.rsi
+ - type: Sprite
+ sprite: _CorvaxNext/Bluespace/Crates/biological_secure.rsi
+ - type: AccessReader
+ access: [["Research"], ["Chemistry"]]
+
+- type: entity
+ parent: CrateBaseSecure
+ id: CrateDestructionSecure
+ name: bluespace destruction crate
+ components:
+ - type: CargoSellBlacklist
+ - type: Icon
+ sprite: _CorvaxNext/Bluespace/Crates/destruction_secure.rsi
+ - type: Sprite
+ sprite: _CorvaxNext/Bluespace/Crates/destruction_secure.rsi
+ - type: AccessReader
+ access: [["Armory"]]
+
+- type: entity
+ parent: CrateBaseSecure
+ id: CrateLimitedSecure
+ name: bluespace limited crate
+ components:
+ - type: CargoSellBlacklist
+ - type: Icon
+ sprite: _CorvaxNext/Bluespace/Crates/limited_secure.rsi
+ - type: Sprite
+ sprite: _CorvaxNext/Bluespace/Crates/limited_secure.rsi
+ - type: AccessReader
+ access: [["Command"]]
diff --git a/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/loot.yml b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/loot.yml
new file mode 100644
index 00000000000..ed488c2a94c
--- /dev/null
+++ b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/loot.yml
@@ -0,0 +1,327 @@
+# Industrial Loot
+- type: entity
+ id: CrateHarvesterSingularity
+ parent: CrateLimitedSecure
+ description: You've got a bad feeling about this.
+ suffix: Bluespace Harvester, Singularity, DO NOT MAP
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: Singularity
+
+- type: entity
+ id: CrateHarvesterSingularityFake
+ parent: CrateLimitedSecure
+ description: You've got a bad feeling about this.
+ suffix: Bluespace Harvester, Singularity Fake
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: SingularityToy
+ amount: 1
+
+- type: entity
+ id: CrateHarvesterMaterials
+ parent: CrateIndustrialSecure
+ suffix: Bluespace Harvester, Materials
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterMaterials
+ amount: 5
+
+- type: entity
+ id: CrateHarvesterPowerCell
+ parent: CrateIndustrialSecure
+ suffix: Bluespace Harvester, Power Cell
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterPowerCell
+ amount: 3
+
+- type: entity
+ id: CrateHarvesterBeer
+ parent: CrateIndustrialSecure
+ suffix: Bluespace Harvester, Beer
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterBeer
+ amount: 30
+
+- type: entity
+ id: CrateHarvesterTools
+ parent: CrateIndustrialSecure
+ suffix: Bluespace Harvester, Tools
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterTools
+ amount: 3
+
+- type: entity
+ id: CrateHarvesterBackpackHolding
+ parent: CrateIndustrialSecure
+ suffix: Bluespace Harvester, Backpack Holding
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterBackpackHolding
+ amount: 2
+
+- type: entity
+ id: CrateHarvesterAmeJar
+ parent: CrateIndustrialSecure
+ suffix: Bluespace Harvester, AmeJar
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: AmeJar
+ amount: 10
+
+- type: entity
+ id: CrateHarvesterCircuitboard
+ parent: CrateIndustrialSecure
+ suffix: Bluespace Harvester, Circuitboard
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterCircuitboard
+ amount: 3
+
+# Technological Loot
+- type: entity
+ id: CrateHarvesterResearchDisk
+ parent: CrateTechnologicalSecure
+ suffix: Bluespace Harvester, ResearchDisk
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterResearchDisk
+ amount: 4
+
+- type: entity
+ id: CrateHarvesterTechnologyDisk
+ parent: CrateTechnologicalSecure
+ suffix: Bluespace Harvester, TechnologyDisk
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterTechnologyDisk
+ amount: 7
+
+- type: entity
+ id: CrateHarvesterAnomaly
+ parent: CrateTechnologicalSecure
+ suffix: Bluespace Harvester, Anomaly
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomAnomalySpawner
+ amount: 1
+
+- type: entity
+ id: CrateHarvesterArtifact
+ parent: CrateTechnologicalSecure
+ suffix: Bluespace Harvester, Artifact
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomArtifactSpawner
+ amount: 1
+
+- type: entity
+ id: CrateHarvesterAnomalyKit
+ parent: CrateTechnologicalSecure
+ suffix: Bluespace Harvester, AnomalyKit
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterAnomalyKit
+ amount: 4
+
+- type: entity
+ id: CrateHarvesterEncryptionKey
+ parent: CrateTechnologicalSecure
+ suffix: Bluespace Harvester, EncryptionKey
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterEncryptionKey
+ amount: 5
+
+- type: entity
+ id: CrateHarvesterBorg
+ parent: CrateTechnologicalSecure
+ suffix: Bluespace Harvester, Borg
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterBorg
+ amount: 3
+
+- type: entity
+ id: CrateHarvesterMech
+ parent: CrateTechnologicalSecure
+ suffix: Bluespace Harvester, Mech
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterMech
+ amount: 2
+
+- type: entity
+ id: CrateHarvesterReagentSlime
+ parent: CrateLimitedSecure
+ suffix: Bluespace Harvester, ReagentSlime
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: ReagentSlimeSpawner
+ amount: 16
+
+# Biological Loot
+- type: entity
+ id: CrateHarvesterInjection
+ parent: CrateBiologicalSecure
+ suffix: Bluespace Harvester, Injection
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterInjection
+ amount: 4
+
+- type: entity
+ id: CrateHarvesterImplanter
+ parent: CrateBiologicalSecure
+ suffix: Bluespace Harvester, Implanter
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterImplanter
+ amount: 7
+
+- type: entity
+ id: CrateHarvesterMedkit
+ parent: CrateBiologicalSecure
+ suffix: Bluespace Harvester, Medkit
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterMedkit
+ amount: 10
+
+- type: entity
+ id: CrateHarvesterRomerol
+ parent: CrateLimitedSecure
+ suffix: Bluespace Harvester, Romerol
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: SyringeRomerol
+ amount: 3
+ - id: PillRomerol
+ amount: 10
+
+- type: entity
+ id: CrateHarvesterDoctorsDelight
+ parent: CrateLimitedSecure
+ suffix: Bluespace Harvester, DoctorsDelight
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterDoctorsDelight
+ amount: 30
+
+
+- type: entity
+ id: CrateHarvesterSeeds
+ parent: CrateBiologicalSecure
+ suffix: Bluespace Harvester, Seeds
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterSeeds
+ amount: 4
+
+# Destructionl Loot
+- type: entity
+ id: CrateHarvesterTurretSyndicate
+ parent: CrateLimitedSecure
+ suffix: Bluespace Harvester, Behonker
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: SpawnMobBehonker
+ amount: 6
+
+- type: entity
+ id: CrateHarvesterWeaponElite
+ parent: CrateLimitedSecure
+ suffix: Bluespace Harvester, WeaponElite
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterWeaponElite
+ amount: 3
+
+- type: entity
+ id: CrateHarvesterWeaponLaser
+ parent: CrateDestructionSecure
+ suffix: Bluespace Harvester, WeaponLaser
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterWeaponLaser
+ amount: 6
+
+- type: entity
+ id: CrateHarvesterWeaponShotgun
+ parent: CrateDestructionSecure
+ suffix: Bluespace Harvester, WeaponShotgun
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterWeaponShotgun
+ amount: 4
+
+- type: entity
+ id: CrateHarvesterWeaponRifle
+ parent: CrateDestructionSecure
+ suffix: Bluespace Harvester, WeaponRifle
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterWeaponRifle
+ amount: 3
+
+- type: entity
+ id: CrateHarvesterWeaponLight
+ parent: CrateDestructionSecure
+ suffix: Bluespace Harvester, WeaponLight
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterWeaponLight
+ amount: 5
+
+- type: entity
+ id: CrateHarvesterWeaponDisabler
+ parent: CrateDestructionSecure
+ suffix: Bluespace Harvester, WeaponDisabler
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterWeaponDisabler
+ amount: 8
+
+- type: entity
+ id: CrateHarvesterBomb
+ parent: CrateDestructionSecure
+ suffix: Bluespace Harvester, Bomb
+ components:
+ - type: BluespaceHarvesterBundle
+ contents:
+ - id: RandomHarvesterBomb
+ amount: 8
diff --git a/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/machine.yml b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/machine.yml
new file mode 100644
index 00000000000..b660ac3ba7d
--- /dev/null
+++ b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/machine.yml
@@ -0,0 +1,80 @@
+- type: entity
+ id: BluespaceHarvester
+ parent: [ BaseMachine, ConstructibleMachine ]
+ name: bluespace harvester
+ description: Uses huge amounts of energy to extract matter from all corners of the universe.
+ components:
+ - type: BluespaceHarvester
+ - type: Appearance
+ - type: Physics
+ - type: Fixtures
+ fixtures:
+ fix1:
+ shape: !type:PhysShapeAabb
+ bounds: "-1.5,-1.5,1.5,1.5"
+ density: 50
+ mask:
+ - LargeMobMask
+ layer:
+ - WallLayer
+ - type: Sprite
+ sprite: _CorvaxNext/Bluespace/harvester.rsi
+ snapCardinals: true
+ layers:
+ - state: tap_0
+ map: [ "base" ]
+ - state: south_effect
+ map: [ "effects" ]
+ visible: false
+ shader: unshaded
+ - type: GenericVisualizer
+ visuals:
+ enum.BluespaceHarvesterVisualLayers.Base:
+ base:
+ 0: { state: tap_0 }
+ 1: { state: tap_1 }
+ 2: { state: tap_2 }
+ 3: { state: tap_3 }
+ 4: { state: tap_4 }
+ 5: { state: tap_5 }
+ 6: { state: tap_redspace }
+ enum.BluespaceHarvesterVisualLayers.Effects:
+ effects:
+ True: { visible: true }
+ False: { visible: false }
+ - type: Destructible
+ thresholds:
+ - trigger: !type:DamageTrigger
+ damage: 350 # We don't need to break it
+ behaviors:
+ - !type:DoActsBehavior
+ acts: [ "Destruction" ]
+ - type: ActivatableUI
+ key: enum.BluespaceHarvesterUiKey.Key
+ - type: UserInterface
+ interfaces:
+ enum.BluespaceHarvesterUiKey.Key:
+ type: BluespaceHarvesterBoundUserInterface
+ - type: Machine
+ board: MachineBluespaceHarvesterCircuitboard
+ - type: NodeContainer
+ examinable: true
+ nodes:
+ input: !type:CableDeviceNode
+ nodeGroupID: HVPower
+ - type: PowerConsumer
+ voltage: High
+ - type: AmbientSound
+ enabled: false
+ volume: -1
+ range: 7
+ sound:
+ path: /Audio/Ambience/Objects/gravity_gen_hum.ogg
+ - type: PointLight
+ radius: 2.5
+ energy: 0.5
+ castShadows: false
+ - type: AccessReader
+ access: [ [ "Engineering" ], [ "Research" ], [ "Command" ] ]
+ - type: GuideHelp
+ guides: [ Power ] # TODO: Add BH guide
diff --git a/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/recipe.yml b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/recipe.yml
new file mode 100644
index 00000000000..521216b96cf
--- /dev/null
+++ b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/recipe.yml
@@ -0,0 +1,9 @@
+- type: latheRecipe
+ id: MachineBluespaceHarvesterCircuitboard
+ result: MachineBluespaceHarvesterCircuitboard
+ completetime: 10
+ materials:
+ Steel: 100
+ Glass: 900
+ Gold: 300
+ Silver: 300
diff --git a/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/research.yml b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/research.yml
new file mode 100644
index 00000000000..0d69e6428ee
--- /dev/null
+++ b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/research.yml
@@ -0,0 +1,11 @@
+- type: technology
+ id: BluespaceMining
+ name: research-technology-bluespace-mining
+ icon:
+ sprite: Objects/Misc/stock_parts.rsi
+ state: ansible_crystal
+ discipline: Experimental
+ tier: 2
+ cost: 10000
+ recipeUnlocks:
+ - MachineBluespaceHarvesterCircuitboard
diff --git a/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/rifts.yml b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/rifts.yml
new file mode 100644
index 00000000000..0d367a48600
--- /dev/null
+++ b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/rifts.yml
@@ -0,0 +1,102 @@
+- type: entity
+ id: BluespaceHarvesterRift
+ name: redspace rift
+ description: Run! Run while you can! Just run!
+ placement:
+ mode: SnapgridCenter
+ components:
+ - type: BluespaceHarvesterRift
+ passiveSpawn:
+ - MobFleshJared
+ - MobFleshGolem
+ - MobFleshClamp
+ - MobFleshLover
+ - FleshBlocker
+ spawn:
+ # Flesh
+ - id: MobFleshJared
+ cost: 30
+ - id: MobFleshGolem
+ cost: 30
+ - id: MobFleshClamp
+ cost: 30
+ - id: MobFleshLover
+ cost: 30
+ - id: FleshBlocker
+ cost: 30
+ # Slimes
+ - id: MobAdultSlimesBlueAngry
+ cost: 40
+ - id: MobAdultSlimesYellowAngry
+ cost: 40
+ - id: MobAdultSlimesGreenAngry
+ cost: 40
+ - id: ReagentSlimeSpawner
+ cost: 60
+ # Carps
+ - id: MobCarp
+ cost: 70
+ - id: MobCarpMagic
+ cost: 90
+ # Space
+ - id: MobKangarooSpace
+ cost: 35
+ - id: MobBearSpace
+ cost: 35
+ - id: MobPurpleSnake
+ cost: 35
+ - id: MobTick
+ cost: 35
+ - id: MobWatcherLavaland
+ cost: 100
+ # Spiders
+ - id: MobSpiderSpace
+ cost: 50
+ - id: MobGiantSpiderAngry
+ cost: 55
+ - id: MobClownSpider
+ cost: 55
+ # DEATH
+ - id: FleshKudzu
+ cost: 300
+ - id: SpawnMobBehonker
+ cost: 600
+ - id: MobDragon
+ cost: 700
+ - type: Transform
+ anchored: true
+ - type: Physics
+ bodyType: Static
+ canCollide: false
+ - type: Fixtures
+ - type: Sprite
+ layers:
+ - sprite: Structures/Specific/carp_rift.rsi
+ state: icon
+ color: "#ff0000"
+ shader: unshaded
+ - type: InteractionOutline
+ - type: Clickable
+ - type: PointLight
+ enabled: true
+ color: "#ff0000"
+ radius: 12.0
+ energy: 5.0
+ netsync: false
+ - type: NavMapBeacon
+ color: "#ff0000"
+ text: redspace rift
+ - type: Damageable
+ damageContainer: Inorganic
+ damageModifierSet: Metallic
+ - type: Destructible
+ thresholds:
+ - trigger:
+ !type:DamageTrigger
+ damage: 100
+ behaviors:
+ - !type:DoActsBehavior
+ acts: [ "Destruction" ]
+ - type: EmitSoundOnSpawn
+ sound:
+ path: /Audio/Weapons/Guns/Gunshots/rocket_launcher.ogg
diff --git a/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/spawners.yml b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/spawners.yml
new file mode 100644
index 00000000000..f9050f5fc7e
--- /dev/null
+++ b/Resources/Prototypes/_CorvaxNext/BluespaceHarvester/spawners.yml
@@ -0,0 +1,708 @@
+# Branchs
+- type: entity
+ id: RandomHarvesterDestructionLoot
+ name: random harvester biological loot spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: _CorvaxNext/Bluespace/harvester.rsi
+ state: tap_5
+ - type: RandomSpawner
+ prototypes:
+ - CrateHarvesterWeaponLaser
+ - CrateHarvesterWeaponShotgun
+ - CrateHarvesterWeaponRifle
+ - CrateHarvesterWeaponLight
+ - CrateHarvesterWeaponDisabler
+ - CrateHarvesterBomb
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - CrateHarvesterTurretSyndicate # Death
+ - CrateHarvesterWeaponElite
+ rareChance: 0.1
+
+- type: entity
+ id: RandomHarvesterIndustrialLoot
+ name: random harvester industrial loot spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: _CorvaxNext/Bluespace/harvester.rsi
+ state: tap_5
+ - type: RandomSpawner
+ prototypes:
+ - CrateHarvesterMaterials
+ - CrateHarvesterPowerCell
+ - CrateHarvesterBeer
+ - CrateHarvesterTools
+ - RandomHarvesterBackpackHolding
+ - CrateHarvesterAmeJar
+ - CrateHarvesterCircuitboard
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - CrateHarvesterSingularity # Death
+ - CrateHarvesterSingularityFake
+ rareChance: 0.1
+
+- type: entity
+ id: RandomHarvesterTechnologicalLoot
+ name: random harvester technological loot spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: _CorvaxNext/Bluespace/harvester.rsi
+ state: tap_5
+ - type: RandomSpawner
+ prototypes:
+ - CrateHarvesterAnomaly
+ - CrateHarvesterArtifact
+ - CrateHarvesterTechnologyDisk
+ - CrateHarvesterResearchDisk
+ - CrateHarvesterAnomalyKit
+ - CrateHarvesterEncryptionKey
+ - CrateHarvesterBorg
+ - CrateHarvesterMech
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - CrateHarvesterReagentSlime # Death
+ - BaseResearchAndDevelopmentPointSource
+ rareChance: 0.1
+
+- type: entity
+ id: RandomHarvesterBiologicalLoot
+ name: random harvester biological loot spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: _CorvaxNext/Bluespace/harvester.rsi
+ state: tap_5
+ - type: RandomSpawner
+ prototypes:
+ - CrateHarvesterImplanter
+ - CrateHarvesterInjection
+ - CrateHarvesterMedkit
+ - CrateHarvesterSeeds
+ rarePrototypes:
+ - CrateHarvesterRomerol # Death
+ - CrateHarvesterDoctorsDelight
+ chance: 1.0
+ offset: 0.0
+ rareChance: 0.1
+
+# Industrial
+- type: entity
+ id: RandomHarvesterMaterials
+ name: random harvester materials spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Materials/Sheets/other.rsi
+ state: plasma_3
+ - type: RandomSpawner
+ prototypes:
+ - SheetPlastic
+ - SheetSteel
+ - SheetPlasteel
+ - SheetGlass
+ - SheetRGlass
+ - SheetPGlass
+ - SheetRPGlass
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - IngotSilver
+ - IngotGold
+ - SheetUranium
+ - SheetUGlass
+ - SheetRUGlass
+ - MaterialSheetMeat
+ rareChance: 0.4
+
+- type: entity
+ id: RandomHarvesterPowerCell
+ name: random harvester power cell spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Power/power_cells.rsi
+ state: hyper
+ - type: RandomSpawner
+ prototypes:
+ - PowerCellMediumPrinted
+ - PowerCellHigh
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - PowerCellAntiqueProto
+ - PowerCellHigh
+ rareChance: 0.25
+
+- type: entity
+ id: RandomHarvesterBeer
+ name: random harvester beer spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Consumable/Drinks/beer.rsi
+ state: icon
+ - type: RandomSpawner
+ prototypes:
+ - DrinkBeerBottleFull
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - DrinkSingulo
+ rareChance: 0.05
+
+- type: entity
+ id: RandomHarvesterTools
+ name: random harvester tools spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Tools/drill.rsi
+ state: drill_screw
+ - type: RandomSpawner
+ prototypes:
+ - WelderExperimental
+ - PowerDrill
+ - JawsOfLife
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - RCDRecharging
+ - AccessConfigurator
+ rareChance: 0.075
+
+- type: entity
+ id: RandomHarvesterBackpackHolding
+ name: random harvester backpack holding spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Clothing/Back/Backpacks/holding.rsi
+ state: holding
+ - type: RandomSpawner
+ prototypes:
+ - ClothingBackpackSatchelHolding
+ - ClothingBackpackDuffelHolding
+ - ClothingBackpackHolding
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - ClosetBluespace
+ - ClosetBluespaceUnstable
+ rareChance: 0.3
+
+- type: entity
+ id: RandomHarvesterCircuitboard
+ name: random harvester circuitboard spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Misc/module.rsi
+ state: cpuboard
+ - type: RandomSpawner
+ prototypes:
+ - SecurityTechFabCircuitboard
+ - MedicalTechFabCircuitboard
+ - TelecomServerCircuitboard
+ - AmmoTechFabCircuitboard
+ - CargoBountyComputerCircuitboard
+ - CargoRequestComputerCircuitboard
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - ResearchAndDevelopmentServerMachineCircuitboard
+ - IDComputerCircuitboard
+ - CommsComputerCircuitboard
+ - BodyScannerComputerCircuitboard
+ - CloningConsoleComputerCircuitboard
+ - CloningPodMachineCircuitboard
+ - CargoShuttleComputerCircuitboard
+ rareChance: 0.2
+
+# Technological
+- type: entity
+ id: RandomHarvesterTechnologyDisk
+ name: random harvester technology disk spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Misc/module.rsi
+ state: datadisk_label
+ - type: RandomSpawner
+ prototypes:
+ - TechnologyDisk
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - TechnologyDiskRare
+ rareChance: 0.3
+
+- type: entity
+ id: RandomHarvesterResearchDisk
+ name: random harvester research disk spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Specific/Research/researchdisk.rsi
+ state: icon
+ - type: RandomSpawner
+ prototypes:
+ - ResearchDisk5000
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - ResearchDisk10000
+ rareChance: 0.3
+
+- type: entity
+ id: RandomHarvesterAnomalyKit
+ name: random harvester anomaly kit spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Weapons/Guns/Revolvers/chimp.rsi
+ state: base
+ - type: RandomSpawner
+ prototypes:
+ - AnomalyScanner
+ - WeaponPistolCHIMP
+ - AnomalyLocator
+ - AnomalyLocatorWide
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - WeaponPistolCHIMPUpgraded
+ rareChance: 0.3
+
+- type: entity
+ id: RandomHarvesterEncryptionKey
+ name: random harvester encryption key spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Devices/encryption_keys.rsi
+ state: crypt_gold
+ - type: RandomSpawner
+ prototypes:
+ - BoxEncryptionKeyService
+ - BoxEncryptionKeySecurity
+ - BoxEncryptionKeyScience
+ - BoxEncryptionKeyRobo
+ - BoxEncryptionKeyPassenger
+ - BoxEncryptionKeyMedical
+ - BoxEncryptionKeyMedicalScience
+ - BoxEncryptionKeyEngineering
+ - BoxEncryptionKeyCargo
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - EncryptionKeyStationMaster
+ - EncryptionKeyCentCom
+ - EncryptionKeySyndie
+ - EncryptionKeyBinary
+ rareChance: 0.05
+
+- type: entity
+ id: RandomHarvesterBorg
+ name: random harvester borg spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Mobs/Silicon/chassis.rsi
+ state: engineer
+ - type: RandomSpawner
+ prototypes:
+ - BorgChassisMining
+ - BorgChassisEngineer
+ - BorgChassisJanitor
+ - BorgChassisService
+ - BorgChassisMedical
+ chance: 1.0
+ offset: 0.0
+
+- type: entity
+ id: RandomHarvesterMech
+ name: random harvester mech spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Specific/Mech/mecha.rsi
+ state: ripley-open
+ - type: RandomSpawner
+ prototypes:
+ - MechHamtrBattery
+ - MechHonkerBattery
+ - MechRipley
+ chance: 1.0
+ offset: 0.0
+
+# Biological
+- type: entity
+ id: RandomHarvesterInjection
+ name: random harvester injection spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Specific/Chemistry/syringe.rsi
+ state: syringe_base0
+ - type: RandomSpawner
+ prototypes:
+ - BluespaceBeaker
+ - SyringeBluespace
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - Hypospray
+ - HypopenBox
+ rareChance: 0.02
+
+- type: entity
+ id: RandomHarvesterImplanter
+ name: random harvester implanter spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Specific/Medical/implanter.rsi
+ state: implanter0
+ - type: RandomSpawner
+ prototypes:
+ - BikeHornImplanter
+ - LightImplanter
+ - MindShieldImplanter
+ - SadTromboneImplanter
+ - TrackingImplanter
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - MacroBombImplanter
+ - MicroBombImplanter
+ - StorageImplanter
+ - EmpImplanter
+ - FreedomImplanter
+ - DeathRattleImplanter
+ - UplinkImplanter
+ - DnaScramblerImplanter
+ rareChance: 0.01
+
+- type: entity
+ id: RandomHarvesterMedkit
+ name: random harvester medkit spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Specific/Medical/firstaidkits.rsi
+ state: blackkit
+ - type: RandomSpawner
+ prototypes:
+ - MedkitOxygenFilled
+ - MedkitAdvancedFilled
+ - MedkitBruteFilled
+ - MedkitBurnFilled
+ - MedkitRadiationFilled
+ - MedkitToxinFilled
+ - MedkitCombatFilled
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - StimkitFilled
+ rareChance: 0.01
+
+- type: entity
+ id: RandomHarvesterSeeds
+ name: random harvester seeds spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Specific/Hydroponics/blood_tomato.rsi
+ state: seed
+ - type: RandomSpawner
+ prototypes:
+ - CrateHydroponicsSeeds
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - CrateHydroponicsSeedsExotic
+ - CrateHydroponicsSeedsMedicinal
+ rareChance: 0.5
+
+- type: entity
+ id: RandomHarvesterDoctorsDelight
+ name: random harvester doctors delight spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Consumable/Drinks/doctorsdelightglass.rsi
+ state: icon
+ - type: RandomSpawner
+ prototypes:
+ - DrinkDoctorsDelightGlass
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - OmnizineChemistryBottle
+ rareChance: 0.2
+
+# Destruction Loot
+- type: entity
+ id: RandomHarvesterWeaponLaser
+ name: random harvester weapon laser spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Weapons/Guns/Battery/laser_gun.rsi
+ state: icon
+ - type: RandomSpawner
+ prototypes:
+ - WeaponLaserCarbine
+ - WeaponLaserCannon
+ - WeaponMakeshiftLaser
+ - WeaponLaserGun
+ - WeaponXrayCannon
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - WeaponAdvancedLaser
+ rareChance: 0.2
+
+- type: entity
+ id: RandomHarvesterWeaponShotgun
+ name: random harvester weapon Shotgun spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Weapons/Guns/Battery/laser_gun.rsi
+ state: icon
+ - type: RandomSpawner
+ prototypes:
+ - WeaponShotgunEnforcer
+ - WeaponShotgunKammerer
+ - WeaponShotgunDoubleBarreled
+ - WeaponShotgunSawn
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - WeaponShotgunBulldog
+ rareChance: 0.05
+
+- type: entity
+ id: RandomHarvesterWeaponRifle
+ name: random harvester weapon rifle spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Weapons/Guns/Battery/laser_gun.rsi
+ state: icon
+ - type: RandomSpawner
+ prototypes:
+ - WeaponRifleLecter
+ - WeaponSubMachineGunWt550
+ - WeaponRifleAk
+ - WeaponSubMachineGunDrozd
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - WeaponSubMachineGunC20r
+ rareChance: 0.05
+
+- type: entity
+ id: RandomHarvesterWeaponLight
+ name: random harvester weapon light spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Weapons/Guns/Battery/laser_gun.rsi
+ state: icon
+ - type: RandomSpawner
+ prototypes:
+ - WeaponRevolverInspector
+ - WeaponRevolverMateba
+ - WeaponPistolMk58
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - WeaponRevolverDeckard
+ - WeaponRevolverPython
+ - WeaponPistolCobra
+ - WeaponPistolViper
+ rareChance: 0.05
+
+- type: entity
+ id: RandomHarvesterWeaponDisabler
+ name: random harvester weapon disabler spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Weapons/Guns/Battery/laser_gun.rsi
+ state: icon
+ - type: RandomSpawner
+ prototypes:
+ - Stunbaton
+ - WeaponDisabler
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - WeaponTaser
+ rareChance: 0.2
+
+- type: entity
+ id: RandomHarvesterWeaponElite
+ name: random harvester weapon elite spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Weapons/Guns/Battery/laser_gun.rsi
+ state: icon
+ - type: RandomSpawner
+ prototypes:
+ - WeaponPulseRifle
+ - WeaponPulsePistol
+ - WeaponLightMachineGunL6
+ - WeaponSniperHristov
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - WeaponPulseCarbine
+ - WeaponMinigun
+ - WeaponLauncherMultipleRocket
+ rareChance: 0.2
+
+- type: entity
+ id: RandomHarvesterBomb
+ name: random harvester bomb spawner
+ suffix: Bluespace Harvester, DO NOT MAP
+ parent: MarkerBase
+ categories: [ HideSpawnMenu ]
+ components:
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Weapons/Guns/Battery/laser_gun.rsi
+ state: icon
+ - type: RandomSpawner
+ prototypes:
+ - ExGrenade
+ - GrenadeFlashBang
+ - TrainingBomb
+ chance: 1.0
+ offset: 0.0
+ rarePrototypes:
+ - SyndicateBomb
+ - SyndieMiniBomb
+ - HolyHandGrenade
+ - C4
+ - EmpGrenade
+ rareChance: 0.05
diff --git a/Resources/Prototypes/_CorvaxNext/debug.yml b/Resources/Prototypes/_CorvaxNext/debug.yml
new file mode 100644
index 00000000000..89ab0eccaac
--- /dev/null
+++ b/Resources/Prototypes/_CorvaxNext/debug.yml
@@ -0,0 +1,30 @@
+# The only normal way to quickly test a bluespace harvester
+- type: entity
+ parent: GeneratorRTG
+ id: GeneratorRTGDamaged100kW
+ name: RTG
+ description: A Radioisotope Thermoelectric Generator for long term power.
+ suffix: 100kW, Debug
+ components:
+ - type: PowerSupplier
+ supplyRate: 100000
+
+- type: entity
+ parent: GeneratorRTG
+ id: GeneratorRTGDamaged1MW
+ name: RTG
+ description: A Radioisotope Thermoelectric Generator for long term power.
+ suffix: 1MW, Debug
+ components:
+ - type: PowerSupplier
+ supplyRate: 1000000
+
+- type: entity
+ parent: GeneratorRTG
+ id: GeneratorRTGDamaged100MW
+ name: RTG
+ description: A Radioisotope Thermoelectric Generator for long term power.
+ suffix: 100MW, Debug
+ components:
+ - type: PowerSupplier
+ supplyRate: 100000000
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/base.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/base.png
new file mode 100644
index 00000000000..efe675aa393
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/base.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/closed.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/closed.png
new file mode 100644
index 00000000000..b943f18800e
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/closed.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/icon.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/icon.png
new file mode 100644
index 00000000000..3dbffeb031b
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/icon.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/locked.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/locked.png
new file mode 100644
index 00000000000..b7dafe399da
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/locked.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/meta.json b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/meta.json
new file mode 100644
index 00000000000..8a6325022e5
--- /dev/null
+++ b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/meta.json
@@ -0,0 +1,45 @@
+{
+ "version": 1,
+ "license": "CC0-1.0",
+ "copyright": "Created by Tornado-Technology (github) for Space Station 14.",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "base"
+ },
+ {
+ "name": "closed"
+ },
+ {
+ "name": "open"
+ },
+ {
+ "name": "welded"
+ },
+ {
+ "name": "sparking",
+ "delays": [
+ [
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1
+ ]
+ ]
+ },
+ {
+ "name": "locked"
+ },
+ {
+ "name": "unlocked"
+ }
+ ]
+}
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/open.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/open.png
new file mode 100644
index 00000000000..d594537a107
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/open.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/sparking.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/sparking.png
new file mode 100644
index 00000000000..87b78b9b465
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/sparking.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/unlocked.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/unlocked.png
new file mode 100644
index 00000000000..7244b37f5c7
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/unlocked.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/welded.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/welded.png
new file mode 100644
index 00000000000..33047239a4e
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/biological_secure.rsi/welded.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/base.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/base.png
new file mode 100644
index 00000000000..9322c5d9482
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/base.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/closed.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/closed.png
new file mode 100644
index 00000000000..ca8f2ba3816
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/closed.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/icon.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/icon.png
new file mode 100644
index 00000000000..d62167dc8bc
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/icon.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/locked.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/locked.png
new file mode 100644
index 00000000000..b7dafe399da
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/locked.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/meta.json b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/meta.json
new file mode 100644
index 00000000000..8a6325022e5
--- /dev/null
+++ b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/meta.json
@@ -0,0 +1,45 @@
+{
+ "version": 1,
+ "license": "CC0-1.0",
+ "copyright": "Created by Tornado-Technology (github) for Space Station 14.",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "base"
+ },
+ {
+ "name": "closed"
+ },
+ {
+ "name": "open"
+ },
+ {
+ "name": "welded"
+ },
+ {
+ "name": "sparking",
+ "delays": [
+ [
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1
+ ]
+ ]
+ },
+ {
+ "name": "locked"
+ },
+ {
+ "name": "unlocked"
+ }
+ ]
+}
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/open.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/open.png
new file mode 100644
index 00000000000..d594537a107
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/open.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/sparking.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/sparking.png
new file mode 100644
index 00000000000..87b78b9b465
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/sparking.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/unlocked.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/unlocked.png
new file mode 100644
index 00000000000..7244b37f5c7
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/unlocked.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/welded.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/welded.png
new file mode 100644
index 00000000000..33047239a4e
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/destruction_secure.rsi/welded.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/base.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/base.png
new file mode 100644
index 00000000000..4c6ace744a9
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/base.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/closed.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/closed.png
new file mode 100644
index 00000000000..1558ea3ac0d
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/closed.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/icon.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/icon.png
new file mode 100644
index 00000000000..cd49c297a30
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/icon.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/locked.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/locked.png
new file mode 100644
index 00000000000..b7dafe399da
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/locked.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/meta.json b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/meta.json
new file mode 100644
index 00000000000..8a6325022e5
--- /dev/null
+++ b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/meta.json
@@ -0,0 +1,45 @@
+{
+ "version": 1,
+ "license": "CC0-1.0",
+ "copyright": "Created by Tornado-Technology (github) for Space Station 14.",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "base"
+ },
+ {
+ "name": "closed"
+ },
+ {
+ "name": "open"
+ },
+ {
+ "name": "welded"
+ },
+ {
+ "name": "sparking",
+ "delays": [
+ [
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1
+ ]
+ ]
+ },
+ {
+ "name": "locked"
+ },
+ {
+ "name": "unlocked"
+ }
+ ]
+}
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/open.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/open.png
new file mode 100644
index 00000000000..d594537a107
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/open.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/sparking.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/sparking.png
new file mode 100644
index 00000000000..87b78b9b465
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/sparking.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/unlocked.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/unlocked.png
new file mode 100644
index 00000000000..7244b37f5c7
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/unlocked.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/welded.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/welded.png
new file mode 100644
index 00000000000..33047239a4e
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/industrial_secure.rsi/welded.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/base.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/base.png
new file mode 100644
index 00000000000..1c6b21ca7df
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/base.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/closed.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/closed.png
new file mode 100644
index 00000000000..c0b8f6f2df3
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/closed.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/icon.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/icon.png
new file mode 100644
index 00000000000..21ebafaaf2d
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/icon.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/locked.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/locked.png
new file mode 100644
index 00000000000..b7dafe399da
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/locked.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/meta.json b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/meta.json
new file mode 100644
index 00000000000..8a6325022e5
--- /dev/null
+++ b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/meta.json
@@ -0,0 +1,45 @@
+{
+ "version": 1,
+ "license": "CC0-1.0",
+ "copyright": "Created by Tornado-Technology (github) for Space Station 14.",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "base"
+ },
+ {
+ "name": "closed"
+ },
+ {
+ "name": "open"
+ },
+ {
+ "name": "welded"
+ },
+ {
+ "name": "sparking",
+ "delays": [
+ [
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1
+ ]
+ ]
+ },
+ {
+ "name": "locked"
+ },
+ {
+ "name": "unlocked"
+ }
+ ]
+}
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/open.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/open.png
new file mode 100644
index 00000000000..d594537a107
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/open.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/sparking.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/sparking.png
new file mode 100644
index 00000000000..87b78b9b465
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/sparking.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/unlocked.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/unlocked.png
new file mode 100644
index 00000000000..7244b37f5c7
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/unlocked.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/welded.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/welded.png
new file mode 100644
index 00000000000..33047239a4e
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/limited_secure.rsi/welded.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/base.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/base.png
new file mode 100644
index 00000000000..f3ced660dba
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/base.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/closed.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/closed.png
new file mode 100644
index 00000000000..7d9fab533e0
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/closed.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/icon.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/icon.png
new file mode 100644
index 00000000000..fd93f3123d1
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/icon.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/locked.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/locked.png
new file mode 100644
index 00000000000..b7dafe399da
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/locked.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/meta.json b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/meta.json
new file mode 100644
index 00000000000..8a6325022e5
--- /dev/null
+++ b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/meta.json
@@ -0,0 +1,45 @@
+{
+ "version": 1,
+ "license": "CC0-1.0",
+ "copyright": "Created by Tornado-Technology (github) for Space Station 14.",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "base"
+ },
+ {
+ "name": "closed"
+ },
+ {
+ "name": "open"
+ },
+ {
+ "name": "welded"
+ },
+ {
+ "name": "sparking",
+ "delays": [
+ [
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1
+ ]
+ ]
+ },
+ {
+ "name": "locked"
+ },
+ {
+ "name": "unlocked"
+ }
+ ]
+}
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/open.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/open.png
new file mode 100644
index 00000000000..d594537a107
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/open.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/sparking.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/sparking.png
new file mode 100644
index 00000000000..87b78b9b465
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/sparking.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/unlocked.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/unlocked.png
new file mode 100644
index 00000000000..7244b37f5c7
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/unlocked.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/welded.png b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/welded.png
new file mode 100644
index 00000000000..33047239a4e
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/Crates/technological_secure.rsi/welded.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/meta.json b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/meta.json
new file mode 100644
index 00000000000..b55f40f1ef5
--- /dev/null
+++ b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/meta.json
@@ -0,0 +1,114 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from https://github.com/ParadiseSS13/Paradise/blob/HEAD/icons/obj/machines/bluespace_tap.dmii",
+ "size": {
+ "x": 96,
+ "y": 96
+ },
+ "states": [
+ {
+ "name": "tap_0",
+ "delays": [
+ [
+ 0.25,
+ 0.25,
+ 0.25,
+ 0.25
+ ]
+ ]
+ },
+ {
+ "name": "tap_1",
+ "delays": [
+ [
+ 0.25,
+ 0.25,
+ 0.25,
+ 0.25
+ ]
+ ]
+ },
+ {
+ "name": "tap_2",
+ "delays": [
+ [
+ 0.25,
+ 0.25,
+ 0.25,
+ 0.25
+ ]
+ ]
+ },
+ {
+ "name": "tap_3",
+ "delays": [
+ [
+ 0.25,
+ 0.25,
+ 0.25,
+ 0.25
+ ]
+ ]
+ },
+ {
+ "name": "tap_4",
+ "delays": [
+ [
+ 0.25,
+ 0.25,
+ 0.25,
+ 0.25
+ ]
+ ]
+ },
+ {
+ "name": "tap_5",
+ "delays": [
+ [
+ 0.25,
+ 0.25,
+ 0.25,
+ 0.25
+ ]
+ ]
+ },
+ {
+ "name": "tap_redspace",
+ "delays": [
+ [
+ 0.25,
+ 0.25,
+ 0.25,
+ 0.25
+ ]
+ ]
+ },
+ {
+ "name": "south_effect",
+ "delays": [
+ [
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1
+ ]
+ ]
+ },
+ {
+ "name": "redspace_effect",
+ "delays": [
+ [
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1
+ ]
+ ]
+ }
+ ]
+}
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/redspace_effect.png b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/redspace_effect.png
new file mode 100644
index 00000000000..ba254db8e00
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/redspace_effect.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/south_effect.png b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/south_effect.png
new file mode 100644
index 00000000000..0e9c89bd3a1
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/south_effect.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_0.png b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_0.png
new file mode 100644
index 00000000000..8b5ebf9a523
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_0.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_1.png b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_1.png
new file mode 100644
index 00000000000..edf4ca11d33
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_1.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_2.png b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_2.png
new file mode 100644
index 00000000000..f778661aa48
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_2.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_3.png b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_3.png
new file mode 100644
index 00000000000..5fb2f9ecba4
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_3.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_4.png b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_4.png
new file mode 100644
index 00000000000..df60570b8b5
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_4.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_5.png b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_5.png
new file mode 100644
index 00000000000..a652eade979
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_5.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_redspace.png b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_redspace.png
new file mode 100644
index 00000000000..21b5a5c8e08
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/harvester.rsi/tap_redspace.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/module.rsi/bluespace.png b/Resources/Textures/_CorvaxNext/Bluespace/module.rsi/bluespace.png
new file mode 100644
index 00000000000..313b7e6e56b
Binary files /dev/null and b/Resources/Textures/_CorvaxNext/Bluespace/module.rsi/bluespace.png differ
diff --git a/Resources/Textures/_CorvaxNext/Bluespace/module.rsi/meta.json b/Resources/Textures/_CorvaxNext/Bluespace/module.rsi/meta.json
new file mode 100644
index 00000000000..992528ff474
--- /dev/null
+++ b/Resources/Textures/_CorvaxNext/Bluespace/module.rsi/meta.json
@@ -0,0 +1,14 @@
+{
+ "version": 1,
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Created by Tornado-Technology (github)",
+ "states": [
+ {
+ "name": "bluespace"
+ }
+ ]
+}