diff --git a/Content.Benchmarks/Content.Benchmarks.csproj b/Content.Benchmarks/Content.Benchmarks.csproj
index 700556482f..2eedacc7f0 100644
--- a/Content.Benchmarks/Content.Benchmarks.csproj
+++ b/Content.Benchmarks/Content.Benchmarks.csproj
@@ -11,7 +11,7 @@
8
-
+
diff --git a/Content.Client/GameObjects/Components/Chemistry/ChemMaster/ChemMasterWindow.cs b/Content.Client/GameObjects/Components/Chemistry/ChemMaster/ChemMasterWindow.cs
index a204c63124..3a2dece8e9 100644
--- a/Content.Client/GameObjects/Components/Chemistry/ChemMaster/ChemMasterWindow.cs
+++ b/Content.Client/GameObjects/Components/Chemistry/ChemMaster/ChemMasterWindow.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using Content.Client.UserInterface;
@@ -273,6 +273,34 @@ namespace Content.Client.GameObjects.Components.Chemistry.ChemMaster
var castState = (ChemMasterBoundUserInterfaceState) state;
Title = castState.DispenserName;
UpdatePanelInfo(castState);
+ if (Contents.Children != null)
+ {
+ SetButtonDisabledRecursive(Contents, !castState.HasPower);
+ EjectButton.Disabled = !castState.HasBeaker;
+ }
+ }
+
+ ///
+ /// This searches recursively through all the children of "parent"
+ /// and sets the Disabled value of any buttons found to "val"
+ ///
+ /// The control which childrens get searched
+ /// The value to which disabled gets set
+ private void SetButtonDisabledRecursive(Control parent, bool val)
+ {
+ foreach (var child in parent.Children)
+ {
+ if (child is Button but)
+ {
+ but.Disabled = val;
+ continue;
+ }
+
+ if (child.Children != null)
+ {
+ SetButtonDisabledRecursive(child, val);
+ }
+ }
}
///
diff --git a/Content.Client/GameObjects/Components/Chemistry/ReagentDispenser/ReagentDispenserBoundUserInterface.cs b/Content.Client/GameObjects/Components/Chemistry/ReagentDispenser/ReagentDispenserBoundUserInterface.cs
index 8f362cc49a..1aabef19dc 100644
--- a/Content.Client/GameObjects/Components/Chemistry/ReagentDispenser/ReagentDispenserBoundUserInterface.cs
+++ b/Content.Client/GameObjects/Components/Chemistry/ReagentDispenser/ReagentDispenserBoundUserInterface.cs
@@ -72,8 +72,8 @@ namespace Content.Client.GameObjects.Components.Chemistry
var castState = (ReagentDispenserBoundUserInterfaceState)state;
_lastState = castState;
- _window?.UpdateState(castState); //Update window state
UpdateReagentsList(castState.Inventory); //Update reagents list & reagent button actions
+ _window?.UpdateState(castState); //Update window state
}
///
diff --git a/Content.Client/GameObjects/Components/Chemistry/ReagentDispenser/ReagentDispenserWindow.cs b/Content.Client/GameObjects/Components/Chemistry/ReagentDispenser/ReagentDispenserWindow.cs
index fade17e84c..66b5fd693f 100644
--- a/Content.Client/GameObjects/Components/Chemistry/ReagentDispenser/ReagentDispenserWindow.cs
+++ b/Content.Client/GameObjects/Components/Chemistry/ReagentDispenser/ReagentDispenserWindow.cs
@@ -161,6 +161,29 @@ namespace Content.Client.GameObjects.Components.Chemistry
}
}
+ ///
+ /// This searches recursively through all the children of "parent"
+ /// and sets the Disabled value of any buttons found to "val"
+ ///
+ /// The control which childrens get searched
+ /// The value to which disabled gets set
+ private void SetButtonDisabledRecursive(Control parent, bool val)
+ {
+ foreach (var child in parent.Children)
+ {
+ if (child is Button but)
+ {
+ but.Disabled = val;
+ continue;
+ }
+
+ if (child.Children != null)
+ {
+ SetButtonDisabledRecursive(child, val);
+ }
+ }
+ }
+
///
/// Update the UI state when new state data is received from the server.
///
@@ -171,6 +194,20 @@ namespace Content.Client.GameObjects.Components.Chemistry
Title = castState.DispenserName;
UpdateContainerInfo(castState);
+ // Disable all buttons if not powered
+ if (Contents.Children != null)
+ {
+ SetButtonDisabledRecursive(Contents, !castState.HasPower);
+ EjectButton.Disabled = false;
+ }
+
+ // Disable the Clear & Eject button if no beaker
+ if (!castState.HasBeaker)
+ {
+ ClearButton.Disabled = true;
+ EjectButton.Disabled = true;
+ }
+
switch (castState.SelectedDispenseAmount.Int())
{
case 1:
diff --git a/Content.Client/GameObjects/Components/RadiatingLightComponent.cs b/Content.Client/GameObjects/Components/RadiatingLightComponent.cs
new file mode 100644
index 0000000000..76b57f2fb4
--- /dev/null
+++ b/Content.Client/GameObjects/Components/RadiatingLightComponent.cs
@@ -0,0 +1,46 @@
+using System;
+using Robust.Client.Animations;
+using Robust.Client.GameObjects;
+using Robust.Client.GameObjects.Components.Animations;
+using Robust.Shared.Animations;
+using Robust.Shared.GameObjects;
+using Robust.Shared.Maths;
+
+namespace Content.Client.GameObjects.Components
+{
+ [RegisterComponent]
+ public class RadiatingLightComponent : Component
+ {
+ public override string Name => "RadiatingLight";
+
+ protected override void Startup()
+ {
+ base.Startup();
+
+ var animation = new Animation
+ {
+ Length = TimeSpan.FromSeconds(4),
+ AnimationTracks =
+ {
+ new AnimationTrackComponentProperty
+ {
+ ComponentType = typeof(PointLightComponent),
+ InterpolationMode = AnimationInterpolationMode.Linear,
+ Property = nameof(PointLightComponent.Radius),
+ KeyFrames =
+ {
+ new AnimationTrackProperty.KeyFrame(3.0f, 0),
+ new AnimationTrackProperty.KeyFrame(2.0f, 1),
+ new AnimationTrackProperty.KeyFrame(3.0f, 2)
+ }
+ }
+ }
+ };
+
+ var playerComponent = Owner.EnsureComponent();
+ playerComponent.Play(animation, "emergency");
+
+ playerComponent.AnimationCompleted += s => playerComponent.Play(animation, s);
+ }
+ }
+}
diff --git a/Content.IntegrationTests/Tests/Atmos/ConstantsTest.cs b/Content.IntegrationTests/Tests/Atmos/ConstantsTest.cs
new file mode 100644
index 0000000000..eac4460b8c
--- /dev/null
+++ b/Content.IntegrationTests/Tests/Atmos/ConstantsTest.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Linq;
+using Content.Shared.Atmos;
+using NUnit.Framework;
+
+namespace Content.IntegrationTests.Tests.Atmos
+{
+ [TestFixture]
+ [TestOf(typeof(Atmospherics))]
+ public class ConstantsTest : ContentIntegrationTest
+ {
+ [Test]
+ public void TotalGasesTest()
+ {
+ var server = StartServerDummyTicker();
+
+ server.Post(() =>
+ {
+ Assert.That(Atmospherics.Gases.Count(), Is.EqualTo(Atmospherics.TotalNumberOfGases));
+
+ Assert.That(Enum.GetValues(typeof(Gas)).Length, Is.EqualTo(Atmospherics.TotalNumberOfGases));
+ });
+ }
+ }
+}
diff --git a/Content.Server/Atmos/AtmosCommands.cs b/Content.Server/Atmos/AtmosCommands.cs
index c38f586c86..29525acaae 100644
--- a/Content.Server/Atmos/AtmosCommands.cs
+++ b/Content.Server/Atmos/AtmosCommands.cs
@@ -302,7 +302,7 @@ namespace Content.Server.Atmos
var moles = 0f;
foreach (var tile in gam)
{
- if (tile.Air.Immutable) continue;
+ if (tile.Air == null || tile.Air.Immutable) continue;
tiles++;
moles += tile.Air.TotalMoles;
tile.Air.RemoveRatio(1f);
diff --git a/Content.Server/GameObjects/Components/Atmos/GasAnalyzerComponent.cs b/Content.Server/GameObjects/Components/Atmos/GasAnalyzerComponent.cs
index 0e5bd87125..777d238060 100644
--- a/Content.Server/GameObjects/Components/Atmos/GasAnalyzerComponent.cs
+++ b/Content.Server/GameObjects/Components/Atmos/GasAnalyzerComponent.cs
@@ -2,37 +2,39 @@
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces;
using Content.Server.Interfaces.GameObjects.Components.Items;
+using Content.Server.Utility;
using Content.Shared.Atmos;
using Content.Shared.GameObjects.Components;
using Content.Shared.GameObjects.EntitySystems;
-using Content.Shared.Interfaces;
using Content.Shared.Interfaces.GameObjects.Components;
-using Content.Shared.Utility;
using Robust.Server.GameObjects.Components.UserInterface;
using Robust.Server.Interfaces.GameObjects;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
+using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Map;
-using Robust.Shared.Utility;
-using System;
+using Robust.Shared.Maths;
using System.Collections.Generic;
namespace Content.Server.GameObjects.Components.Atmos
{
[RegisterComponent]
- public class GasAnalyzerComponent : SharedGasAnalyzerComponent, IAfterInteract, IDropped
+ public class GasAnalyzerComponent : SharedGasAnalyzerComponent, IAfterInteract, IDropped, IUse
{
#pragma warning disable 649
[Dependency] private IServerNotifyManager _notifyManager = default!;
+ [Dependency] private IMapManager _mapManager = default!;
#pragma warning restore 649
private BoundUserInterface _userInterface = default!;
private GasAnalyzerDanger _pressureDanger;
private float _timeSinceSync;
- private const float TimeBetweenSyncs = 10f;
+ private const float TimeBetweenSyncs = 2f;
+ private bool _checkPlayer = false; // Check at the player pos or at some other tile?
+ private GridCoordinates? _position; // The tile that we scanned
public override void Initialize()
{
@@ -49,9 +51,28 @@ namespace Content.Server.GameObjects.Components.Atmos
///
/// Call this from other components to open the gas analyzer UI.
+ /// Uses the player position.
///
+ /// The session to open the ui for
public void OpenInterface(IPlayerSession session)
{
+ _checkPlayer = true;
+ _position = null;
+ _userInterface.Open(session);
+ UpdateUserInterface();
+ Resync();
+ }
+
+ ///
+ /// Call this from other components to open the gas analyzer UI.
+ /// Uses a given position.
+ ///
+ /// The session to open the ui for
+ /// The position to analyze the gas
+ public void OpenInterface(IPlayerSession session, GridCoordinates pos)
+ {
+ _checkPlayer = false;
+ _position = pos;
_userInterface.Open(session);
UpdateUserInterface();
Resync();
@@ -59,6 +80,7 @@ namespace Content.Server.GameObjects.Components.Atmos
public void CloseInterface(IPlayerSession session)
{
+ _position = null;
_userInterface.Close(session);
Resync();
}
@@ -69,6 +91,7 @@ namespace Content.Server.GameObjects.Components.Atmos
if (_timeSinceSync > TimeBetweenSyncs)
{
Resync();
+ UpdateUserInterface();
}
}
@@ -103,9 +126,35 @@ namespace Content.Server.GameObjects.Components.Atmos
private void UpdateUserInterface()
{
string? error = null;
- var gam = EntitySystem.Get().GetGridAtmosphere(Owner.Transform.GridID);
- var tile = gam?.GetTile(Owner.Transform.GridPosition).Air;
+ // Check if the player is still holding the gas analyzer => if not, don't update
+ foreach (var session in _userInterface.SubscribedSessions)
+ {
+ if (session.AttachedEntity == null)
+ return;
+
+ if (!session.AttachedEntity.TryGetComponent(out IHandsComponent handsComponent))
+ return;
+
+ var activeHandEntity = handsComponent?.GetActiveHand?.Owner;
+ if (activeHandEntity == null || !activeHandEntity.TryGetComponent(out GasAnalyzerComponent gasAnalyzer))
+ {
+ return;
+ }
+ }
+
+ var pos = Owner.Transform.GridPosition;
+ if (!_checkPlayer && _position.HasValue)
+ {
+ // Check if position is out of range => don't update
+ if (!_position.Value.InRange(_mapManager, pos, SharedInteractionSystem.InteractionRange))
+ return;
+
+ pos = _position.Value;
+ }
+
+ var gam = EntitySystem.Get().GetGridAtmosphere(pos.GridID);
+ var tile = gam?.GetTile(pos).Air;
if (tile == null)
{
error = "No Atmosphere!";
@@ -172,13 +221,21 @@ namespace Content.Server.GameObjects.Components.Atmos
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
{
+ if (!eventArgs.CanReach)
+ {
+ _notifyManager.PopupMessage(eventArgs.User, eventArgs.User, Loc.GetString("You can't reach there!"));
+ return;
+ }
+
if (eventArgs.User.TryGetComponent(out IActorComponent actor))
{
- OpenInterface(actor.playerSession);
+ OpenInterface(actor.playerSession, eventArgs.ClickLocation);
//TODO: show other sprite when ui open?
}
}
+
+
void IDropped.Dropped(DroppedEventArgs eventArgs)
{
if (eventArgs.User.TryGetComponent(out IActorComponent actor))
@@ -187,5 +244,16 @@ namespace Content.Server.GameObjects.Components.Atmos
//TODO: if other sprite is shown, change again
}
}
+
+ bool IUse.UseEntity(UseEntityEventArgs eventArgs)
+ {
+ if (eventArgs.User.TryGetComponent(out IActorComponent actor))
+ {
+ OpenInterface(actor.playerSession);
+ //TODO: show other sprite when ui open?
+ return true;
+ }
+ return false;
+ }
}
}
diff --git a/Content.Server/GameObjects/Components/Atmos/GridAtmosphereComponent.cs b/Content.Server/GameObjects/Components/Atmos/GridAtmosphereComponent.cs
index 91bdd4b6cd..ea05c19642 100644
--- a/Content.Server/GameObjects/Components/Atmos/GridAtmosphereComponent.cs
+++ b/Content.Server/GameObjects/Components/Atmos/GridAtmosphereComponent.cs
@@ -13,7 +13,6 @@ using Robust.Shared.GameObjects.Components.Transform;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.Interfaces.Timing;
using Robust.Shared.IoC;
-using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Serialization;
@@ -191,7 +190,7 @@ namespace Content.Server.GameObjects.Components.Atmos
tile.UpdateAdjacent();
tile.UpdateVisuals();
- foreach (var direction in Cardinal())
+ foreach (var direction in Cardinal)
{
var otherIndices = indices.Offset(direction);
var otherTile = GetTile(otherIndices);
@@ -306,7 +305,7 @@ namespace Content.Server.GameObjects.Components.Atmos
public Dictionary GetAdjacentTiles(MapIndices indices)
{
var sides = new Dictionary();
- foreach (var dir in Cardinal())
+ foreach (var dir in Cardinal)
{
var side = indices.Offset(dir);
var tile = GetTile(side);
@@ -475,8 +474,8 @@ namespace Content.Server.GameObjects.Components.Atmos
return null;
}
- private static IEnumerable Cardinal() =>
- new[]
+ private static readonly Direction[] Cardinal =
+ new []
{
Direction.North, Direction.East, Direction.South, Direction.West
};
diff --git a/Content.Server/GameObjects/Components/Chemistry/ChemMasterComponent.cs b/Content.Server/GameObjects/Components/Chemistry/ChemMasterComponent.cs
index 2f7caaf156..4f20a0c4e9 100644
--- a/Content.Server/GameObjects/Components/Chemistry/ChemMasterComponent.cs
+++ b/Content.Server/GameObjects/Components/Chemistry/ChemMasterComponent.cs
@@ -83,6 +83,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
_beakerContainer =
ContainerManagerComponent.Ensure($"{Name}-reagentContainerContainer", Owner);
_powerReceiver = Owner.GetComponent();
+ _powerReceiver.OnPowerStateChanged += OnPowerChanged;
//BufferSolution = Owner.BufferSolution
BufferSolution.Solution = new Solution();
@@ -91,6 +92,11 @@ namespace Content.Server.GameObjects.Components.Chemistry
UpdateUserInterface();
}
+ private void OnPowerChanged(object sender, PowerStateEventArgs e)
+ {
+ UpdateUserInterface();
+ }
+
///
/// Handles ui messages from the client. For things such as button presses
/// which interact with the world and require server action.
@@ -98,10 +104,16 @@ namespace Content.Server.GameObjects.Components.Chemistry
/// A user interface message from the client.
private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
{
- if (!PlayerCanUseChemMaster(obj.Session.AttachedEntity))
+ var msg = (UiActionMessage) obj.Message;
+ var needsPower = msg.action switch
+ {
+ UiAction.Eject => false,
+ _ => true,
+ };
+
+ if (!PlayerCanUseChemMaster(obj.Session.AttachedEntity, needsPower))
return;
- var msg = (UiActionMessage) obj.Message;
switch (msg.action)
{
case UiAction.Eject:
@@ -134,7 +146,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
///
/// The player entity.
/// Returns true if the entity can use the chem master, and false if it cannot.
- private bool PlayerCanUseChemMaster(IEntity playerEntity)
+ private bool PlayerCanUseChemMaster(IEntity playerEntity, bool needsPower = true)
{
//Need player entity to check if they are still able to use the chem master
if (playerEntity == null)
@@ -143,7 +155,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
if (!ActionBlockerSystem.CanInteract(playerEntity) || !ActionBlockerSystem.CanUse(playerEntity))
return false;
//Check if device is powered
- if (!Powered)
+ if (needsPower && !Powered)
return false;
return true;
@@ -158,12 +170,12 @@ namespace Content.Server.GameObjects.Components.Chemistry
var beaker = _beakerContainer.ContainedEntity;
if (beaker == null)
{
- return new ChemMasterBoundUserInterfaceState(false, ReagentUnit.New(0), ReagentUnit.New(0),
+ return new ChemMasterBoundUserInterfaceState(Powered, false, ReagentUnit.New(0), ReagentUnit.New(0),
"", Owner.Name, null, BufferSolution.ReagentList.ToList(), BufferModeTransfer, BufferSolution.CurrentVolume, BufferSolution.MaxVolume);
}
var solution = beaker.GetComponent();
- return new ChemMasterBoundUserInterfaceState(true, solution.CurrentVolume, solution.MaxVolume,
+ return new ChemMasterBoundUserInterfaceState(Powered, true, solution.CurrentVolume, solution.MaxVolume,
beaker.Name, Owner.Name, solution.ReagentList.ToList(), BufferSolution.ReagentList.ToList(), BufferModeTransfer, BufferSolution.CurrentVolume, BufferSolution.MaxVolume);
}
@@ -252,9 +264,15 @@ namespace Content.Server.GameObjects.Components.Chemistry
{
var random = IoCManager.Resolve();
+ if (BufferSolution.CurrentVolume == 0)
+ return;
+
if (action == UiAction.CreateBottles)
{
var individualVolume = BufferSolution.CurrentVolume / ReagentUnit.New(bottleAmount);
+ if (individualVolume < ReagentUnit.New(1))
+ return;
+
var actualVolume = ReagentUnit.Min(individualVolume, ReagentUnit.New(30));
for (int i = 0; i < bottleAmount; i++)
{
@@ -289,6 +307,9 @@ namespace Content.Server.GameObjects.Components.Chemistry
else //Pills
{
var individualVolume = BufferSolution.CurrentVolume / ReagentUnit.New(pillAmount);
+ if (individualVolume < ReagentUnit.New(1))
+ return;
+
var actualVolume = ReagentUnit.Min(individualVolume, ReagentUnit.New(50));
for (int i = 0; i < pillAmount; i++)
{
@@ -341,9 +362,6 @@ namespace Content.Server.GameObjects.Components.Chemistry
return;
}
- if (!Powered)
- return;
-
var activeHandEntity = hands.GetActiveHand?.Owner;
if (activeHandEntity == null)
{
diff --git a/Content.Server/GameObjects/Components/Chemistry/ReagentDispenserComponent.cs b/Content.Server/GameObjects/Components/Chemistry/ReagentDispenserComponent.cs
index f9a698e717..a9c384dafb 100644
--- a/Content.Server/GameObjects/Components/Chemistry/ReagentDispenserComponent.cs
+++ b/Content.Server/GameObjects/Components/Chemistry/ReagentDispenserComponent.cs
@@ -80,6 +80,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
_beakerContainer =
ContainerManagerComponent.Ensure($"{Name}-reagentContainerContainer", Owner);
_powerReceiver = Owner.GetComponent();
+ _powerReceiver.OnPowerStateChanged += OnPowerChanged;
InitializeFromPrototype();
UpdateUserInterface();
@@ -105,6 +106,11 @@ namespace Content.Server.GameObjects.Components.Chemistry
}
}
+ private void OnPowerChanged(object sender, PowerStateEventArgs e)
+ {
+ UpdateUserInterface();
+ }
+
///
/// Handles ui messages from the client. For things such as button presses
/// which interact with the world and require server action.
@@ -112,10 +118,16 @@ namespace Content.Server.GameObjects.Components.Chemistry
/// A user interface message from the client.
private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
{
- if(!PlayerCanUseDispenser(obj.Session.AttachedEntity))
+ var msg = (UiButtonPressedMessage) obj.Message;
+ var needsPower = msg.Button switch
+ {
+ UiButton.Eject => false,
+ _ => true,
+ };
+
+ if(!PlayerCanUseDispenser(obj.Session.AttachedEntity, needsPower))
return;
- var msg = (UiButtonPressedMessage) obj.Message;
switch (msg.Button)
{
case UiButton.Eject:
@@ -161,7 +173,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
///
/// The player entity.
/// Returns true if the entity can use the dispenser, and false if it cannot.
- private bool PlayerCanUseDispenser(IEntity playerEntity)
+ private bool PlayerCanUseDispenser(IEntity playerEntity, bool needsPower = true)
{
//Need player entity to check if they are still able to use the dispenser
if (playerEntity == null)
@@ -170,7 +182,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
if (!ActionBlockerSystem.CanInteract(playerEntity) || !ActionBlockerSystem.CanUse(playerEntity))
return false;
//Check if device is powered
- if (!Powered)
+ if (needsPower && !Powered)
return false;
return true;
@@ -185,12 +197,12 @@ namespace Content.Server.GameObjects.Components.Chemistry
var beaker = _beakerContainer.ContainedEntity;
if (beaker == null)
{
- return new ReagentDispenserBoundUserInterfaceState(false, ReagentUnit.New(0), ReagentUnit.New(0),
+ return new ReagentDispenserBoundUserInterfaceState(Powered, false, ReagentUnit.New(0), ReagentUnit.New(0),
"", Inventory, Owner.Name, null, _dispenseAmount);
}
var solution = beaker.GetComponent();
- return new ReagentDispenserBoundUserInterfaceState(true, solution.CurrentVolume, solution.MaxVolume,
+ return new ReagentDispenserBoundUserInterfaceState(Powered, true, solution.CurrentVolume, solution.MaxVolume,
beaker.Name, Inventory, Owner.Name, solution.ReagentList.ToList(), _dispenseAmount);
}
@@ -263,9 +275,6 @@ namespace Content.Server.GameObjects.Components.Chemistry
return;
}
- if (!Powered)
- return;
-
var activeHandEntity = hands.GetActiveHand?.Owner;
if (activeHandEntity == null)
{
diff --git a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingSystem.cs b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingSystem.cs
index 6443a5e0b2..385954b9d6 100644
--- a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingSystem.cs
+++ b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingSystem.cs
@@ -37,9 +37,9 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
public IReadOnlyDictionary> Graph => _graph;
private readonly Dictionary> _graph = new Dictionary>();
-
+
private readonly PathfindingJobQueue _pathfindingQueue = new PathfindingJobQueue();
-
+
// Queued pathfinding graph updates
private readonly Queue _collidableUpdateQueue = new Queue();
private readonly Queue _moveUpdateQueue = new Queue();
@@ -50,11 +50,11 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
private readonly Dictionary _lastKnownPositions = new Dictionary();
public const int TrackedCollisionLayers = (int)
- (CollisionGroup.Impassable |
+ (CollisionGroup.Impassable |
CollisionGroup.MobImpassable |
- CollisionGroup.SmallImpassable |
+ CollisionGroup.SmallImpassable |
CollisionGroup.VaultImpassable);
-
+
///
/// Ask for the pathfinder to gimme somethin
///
@@ -83,7 +83,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
private void ProcessGraphUpdates()
{
var totalUpdates = 0;
-
+
foreach (var update in _collidableUpdateQueue)
{
var entity = _entitymanager.GetEntity(update.Owner);
@@ -98,7 +98,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
totalUpdates++;
}
-
+
_collidableUpdateQueue.Clear();
foreach (var update in _accessReaderUpdateQueue)
@@ -115,7 +115,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
totalUpdates++;
}
-
+
_accessReaderUpdateQueue.Clear();
foreach (var tile in _tileUpdateQueue)
@@ -123,10 +123,10 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
HandleTileUpdate(tile);
totalUpdates++;
}
-
+
_tileUpdateQueue.Clear();
var moveUpdateCount = Math.Max(50 - totalUpdates, 0);
-
+
// Other updates are high priority so for this we'll just defer it if there's a spike (explosion, etc.)
// If the move updates grow too large then we'll just do it
if (_moveUpdateQueue.Count > 100)
@@ -135,12 +135,12 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
}
moveUpdateCount = Math.Min(moveUpdateCount, _moveUpdateQueue.Count);
-
+
for (var i = 0; i < moveUpdateCount; i++)
{
HandleCollidableMove(_moveUpdateQueue.Dequeue());
}
-
+
DebugTools.Assert(_moveUpdateQueue.Count < 1000);
}
@@ -171,10 +171,10 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
{
_graph.Add(gridId, new Dictionary());
}
-
+
_graph[gridId].Add(indices, newChunk);
newChunk.Initialize(_mapManager.GetGrid(gridId));
-
+
return newChunk;
}
@@ -204,6 +204,9 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
public override void Initialize()
{
+ // TODO: Remove this once the memory leaks are solved.
+ return;
+
SubscribeLocalEvent(QueueCollisionChangeMessage);
SubscribeLocalEvent(QueueMoveEvent);
SubscribeLocalEvent(QueueAccessChangeMessage);
@@ -221,12 +224,12 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
UnsubscribeLocalEvent();
UnsubscribeLocalEvent();
UnsubscribeLocalEvent();
-
+
_mapManager.OnGridRemoved -= HandleGridRemoval;
_mapManager.GridChanged -= QueueGridChange;
_mapManager.TileChanged -= QueueTileChange;
}
-
+
private void HandleTileUpdate(TileRef tile)
{
var node = GetNode(tile);
@@ -280,7 +283,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
{
return;
}
-
+
var grid = _mapManager.GetGrid(entity.Transform.GridID);
var tileRef = grid.GetTileRef(entity.Transform.GridPosition);
@@ -313,7 +316,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
private void HandleCollidableMove(MoveEvent moveEvent)
{
var entityUid = moveEvent.Sender.Uid;
-
+
if (!_lastKnownPositions.TryGetValue(entityUid, out var oldNode))
{
return;
@@ -326,7 +329,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
HandleEntityRemove(moveEvent.Sender);
return;
}
-
+
var newTile = _mapManager.GetGrid(moveEvent.NewPosition.GridID).GetTileRef(moveEvent.NewPosition);
if (oldNode == null || oldNode.TileRef == newTile)
@@ -365,7 +368,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding
}
var access = AccessReader.FindAccessTags(entity);
-
+
foreach (var reader in node.AccessReaders)
{
if (!reader.IsAllowed(access))
diff --git a/Content.Server/IgnoredComponents.cs b/Content.Server/IgnoredComponents.cs
index f40975a84c..4aa536c30d 100644
--- a/Content.Server/IgnoredComponents.cs
+++ b/Content.Server/IgnoredComponents.cs
@@ -20,6 +20,7 @@
"EmergencyLight",
"Clickable",
"CanSeeGases",
+ "RadiatingLight",
};
}
diff --git a/Content.Shared/Atmos/Atmospherics.cs b/Content.Shared/Atmos/Atmospherics.cs
index 9e8252c585..4659ab2441 100644
--- a/Content.Shared/Atmos/Atmospherics.cs
+++ b/Content.Shared/Atmos/Atmospherics.cs
@@ -59,7 +59,7 @@ namespace Content.Shared.Atmos
public const float CellVolume = 2500f;
///
- /// Moles in a 2.5 m^3 cell at 101.325 Pa and 20ºC
+ /// Moles in a 2.5 m^3 cell at 101.325 kPa and 20ºC
///
public const float MolesCellStandard = (OneAtmosphere * CellVolume / (T20C * R));
diff --git a/Content.Shared/GameObjects/Components/Chemistry/ChemMaster/SharedChemMasterComponent.cs b/Content.Shared/GameObjects/Components/Chemistry/ChemMaster/SharedChemMasterComponent.cs
index 793e842886..8a4f630fb0 100644
--- a/Content.Shared/GameObjects/Components/Chemistry/ChemMaster/SharedChemMasterComponent.cs
+++ b/Content.Shared/GameObjects/Components/Chemistry/ChemMaster/SharedChemMasterComponent.cs
@@ -1,4 +1,4 @@
-#nullable enable
+#nullable enable
using System;
using System.Collections.Generic;
using Content.Shared.Chemistry;
@@ -19,6 +19,7 @@ namespace Content.Shared.GameObjects.Components.Chemistry
[Serializable, NetSerializable]
public class ChemMasterBoundUserInterfaceState : BoundUserInterfaceState
{
+ public readonly bool HasPower;
public readonly bool HasBeaker;
public readonly ReagentUnit BeakerCurrentVolume;
public readonly ReagentUnit BeakerMaxVolume;
@@ -39,9 +40,10 @@ namespace Content.Shared.GameObjects.Components.Chemistry
public readonly ReagentUnit BufferCurrentVolume;
public readonly ReagentUnit BufferMaxVolume;
- public ChemMasterBoundUserInterfaceState(bool hasBeaker, ReagentUnit beakerCurrentVolume, ReagentUnit beakerMaxVolume, string containerName,
+ public ChemMasterBoundUserInterfaceState(bool hasPower, bool hasBeaker, ReagentUnit beakerCurrentVolume, ReagentUnit beakerMaxVolume, string containerName,
string dispenserName, List containerReagents, List bufferReagents, bool bufferModeTransfer, ReagentUnit bufferCurrentVolume, ReagentUnit bufferMaxVolume)
{
+ HasPower = hasPower;
HasBeaker = hasBeaker;
BeakerCurrentVolume = beakerCurrentVolume;
BeakerMaxVolume = beakerMaxVolume;
diff --git a/Content.Shared/GameObjects/Components/Chemistry/ReagentDispenser/SharedReagentDispenserComponent.cs b/Content.Shared/GameObjects/Components/Chemistry/ReagentDispenser/SharedReagentDispenserComponent.cs
index d9ff0581dd..b2d094a5d0 100644
--- a/Content.Shared/GameObjects/Components/Chemistry/ReagentDispenser/SharedReagentDispenserComponent.cs
+++ b/Content.Shared/GameObjects/Components/Chemistry/ReagentDispenser/SharedReagentDispenserComponent.cs
@@ -25,6 +25,7 @@ namespace Content.Shared.GameObjects.Components.Chemistry
[Serializable, NetSerializable]
public class ReagentDispenserBoundUserInterfaceState : BoundUserInterfaceState
{
+ public readonly bool HasPower;
public readonly bool HasBeaker;
public readonly ReagentUnit BeakerCurrentVolume;
public readonly ReagentUnit BeakerMaxVolume;
@@ -40,9 +41,10 @@ namespace Content.Shared.GameObjects.Components.Chemistry
public readonly string DispenserName;
public readonly ReagentUnit SelectedDispenseAmount;
- public ReagentDispenserBoundUserInterfaceState(bool hasBeaker, ReagentUnit beakerCurrentVolume, ReagentUnit beakerMaxVolume, string containerName,
+ public ReagentDispenserBoundUserInterfaceState(bool hasPower, bool hasBeaker, ReagentUnit beakerCurrentVolume, ReagentUnit beakerMaxVolume, string containerName,
List inventory, string dispenserName, List containerReagents, ReagentUnit selectedDispenseAmount)
{
+ HasPower = hasPower;
HasBeaker = hasBeaker;
BeakerCurrentVolume = beakerCurrentVolume;
BeakerMaxVolume = beakerMaxVolume;
diff --git a/Resources/Prototypes/Entities/Objects/Tools/lantern.yml b/Resources/Prototypes/Entities/Objects/Tools/lantern.yml
new file mode 100644
index 0000000000..e1346cac53
--- /dev/null
+++ b/Resources/Prototypes/Entities/Objects/Tools/lantern.yml
@@ -0,0 +1,27 @@
+- type: entity
+ name: lantern
+ parent: BaseItem
+ id: lantern
+ description: The holy light guides the way
+ components:
+ - type: HandheldLight
+ - type: Sprite
+ sprite: Objects/Tools/lantern.rsi
+ layers:
+ - state: lantern
+ - state: lantern-on
+ shader: unshaded
+ visible: false
+ - type: Icon
+ sprite: Objects/Tools/lantern.rsi
+ state: lantern
+ - type: Item
+ sprite: Objects/Tools/lantern.rsi
+ HeldPrefix: off
+ - type: PointLight
+ enabled: false
+ radius: 3
+ energy: 2.5
+ color: "#FFC458"
+ - type: RadiatingLight
+ - type: LoopingSound
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Explosives/grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Explosives/grenades.yml
index 8eb1973058..3e945ab5aa 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Explosives/grenades.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Explosives/grenades.yml
@@ -86,3 +86,33 @@
visuals:
- type: TimerTriggerVisualizer
countdown_sound: /Audio/Effects/countdown.ogg
+
+- type: entity
+ name: the nuclear option
+ description: Please don't throw it, think of the children.
+ parent: BaseItem
+ id: NuclearGrenade
+ components:
+ - type: Sprite
+ sprite: Objects/Weapons/Grenades/nukenade.rsi
+ layers:
+ - state: icon
+ map: ["enum.TriggerVisualLayers.Base"]
+ - type: Icon
+ sprite: Objects/Weapons/Grenades/nukenade.rsi
+ state: icon
+ - type: Item
+ size: 5
+ - type: OnUseTimerTrigger
+ delay: 5
+ - type: Explosive
+ devastationRange: 25
+ heavyImpactRange: 25
+ flashRange: 50
+ - type: Damageable
+ - type: Destructible
+ thresholdvalue: 50
+ - type: Appearance
+ visuals:
+ - type: TimerTriggerVisualizer
+ countdown_sound: /Audio/Effects/countdown.ogg
diff --git a/Resources/Textures/Objects/Tools/lantern.rsi/lantern-on.png b/Resources/Textures/Objects/Tools/lantern.rsi/lantern-on.png
new file mode 100644
index 0000000000..7573695619
Binary files /dev/null and b/Resources/Textures/Objects/Tools/lantern.rsi/lantern-on.png differ
diff --git a/Resources/Textures/Objects/Tools/lantern.rsi/lantern.png b/Resources/Textures/Objects/Tools/lantern.rsi/lantern.png
new file mode 100644
index 0000000000..d9f5bd0bbb
Binary files /dev/null and b/Resources/Textures/Objects/Tools/lantern.rsi/lantern.png differ
diff --git a/Resources/Textures/Objects/Tools/lantern.rsi/meta.json b/Resources/Textures/Objects/Tools/lantern.rsi/meta.json
new file mode 100644
index 0000000000..2205be15d5
--- /dev/null
+++ b/Resources/Textures/Objects/Tools/lantern.rsi/meta.json
@@ -0,0 +1,101 @@
+{
+ "version": 1,
+ "license": "CC BY-SA 3.0",
+ "copyright": "Taken from https://github.com/tgstation/tgstation at commit 9bebd81ae0b0a7f952b59886a765c681205de31f",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "lantern",
+ "directions": 1,
+ "delays": [
+ [
+ 1.0
+ ]
+ ]
+ },
+ {
+ "name": "lantern-on",
+ "directions": 1,
+ "delays": [
+ [
+ 1.0
+ ]
+ ]
+ },
+ {
+ "name": "off-inhand-left",
+ "directions": 4,
+ "delays": [
+ [
+ 1
+ ],
+ [
+ 1
+ ],
+ [
+ 1
+ ],
+ [
+ 1
+ ]
+ ]
+ },
+ {
+ "name": "off-inhand-right",
+ "directions": 4,
+ "delays": [
+ [
+ 1
+ ],
+ [
+ 1
+ ],
+ [
+ 1
+ ],
+ [
+ 1
+ ]
+ ]
+ },
+ {
+ "name": "on-inhand-left",
+ "directions": 4,
+ "delays": [
+ [
+ 1
+ ],
+ [
+ 1
+ ],
+ [
+ 1
+ ],
+ [
+ 1
+ ]
+ ]
+ },
+ {
+ "name": "on-inhand-right",
+ "directions": 4,
+ "delays": [
+ [
+ 1
+ ],
+ [
+ 1
+ ],
+ [
+ 1
+ ],
+ [
+ 1
+ ]
+ ]
+ }
+ ]
+}
diff --git a/Resources/Textures/Objects/Tools/lantern.rsi/off-inhand-left.png b/Resources/Textures/Objects/Tools/lantern.rsi/off-inhand-left.png
new file mode 100644
index 0000000000..d38b5e8c64
Binary files /dev/null and b/Resources/Textures/Objects/Tools/lantern.rsi/off-inhand-left.png differ
diff --git a/Resources/Textures/Objects/Tools/lantern.rsi/off-inhand-right.png b/Resources/Textures/Objects/Tools/lantern.rsi/off-inhand-right.png
new file mode 100644
index 0000000000..de8ce0ad50
Binary files /dev/null and b/Resources/Textures/Objects/Tools/lantern.rsi/off-inhand-right.png differ
diff --git a/Resources/Textures/Objects/Tools/lantern.rsi/on-inhand-left.png b/Resources/Textures/Objects/Tools/lantern.rsi/on-inhand-left.png
new file mode 100644
index 0000000000..d38b5e8c64
Binary files /dev/null and b/Resources/Textures/Objects/Tools/lantern.rsi/on-inhand-left.png differ
diff --git a/Resources/Textures/Objects/Tools/lantern.rsi/on-inhand-right.png b/Resources/Textures/Objects/Tools/lantern.rsi/on-inhand-right.png
new file mode 100644
index 0000000000..de8ce0ad50
Binary files /dev/null and b/Resources/Textures/Objects/Tools/lantern.rsi/on-inhand-right.png differ
diff --git a/Resources/Textures/Objects/Weapons/Grenades/nukenade.rsi/icon.png b/Resources/Textures/Objects/Weapons/Grenades/nukenade.rsi/icon.png
new file mode 100644
index 0000000000..d6e9ebe4fb
Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Grenades/nukenade.rsi/icon.png differ
diff --git a/Resources/Textures/Objects/Weapons/Grenades/nukenade.rsi/meta.json b/Resources/Textures/Objects/Weapons/Grenades/nukenade.rsi/meta.json
new file mode 100644
index 0000000000..198dbe1347
--- /dev/null
+++ b/Resources/Textures/Objects/Weapons/Grenades/nukenade.rsi/meta.json
@@ -0,0 +1,25 @@
+{
+ "version": 1,
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from https://github.com/vgstation-coders/vgstation13/icons/obj/grenade.dmi at commit 8c96d52deed1eeea28a16334eea549369d7f9974",
+ "states": [
+ {
+ "name": "icon",
+ "directions": 1,
+ "delays": [
+ [1.0]
+ ]
+ },
+ {
+ "name": "primed",
+ "directions": 1,
+ "delays": [
+ [0.2, 0.2]
+ ]
+ }
+ ]
+}
diff --git a/Resources/Textures/Objects/Weapons/Grenades/nukenade.rsi/primed.png b/Resources/Textures/Objects/Weapons/Grenades/nukenade.rsi/primed.png
new file mode 100644
index 0000000000..6938870e05
Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Grenades/nukenade.rsi/primed.png differ
diff --git a/RobustToolbox b/RobustToolbox
index 6c3c22affe..64a3916c04 160000
--- a/RobustToolbox
+++ b/RobustToolbox
@@ -1 +1 @@
-Subproject commit 6c3c22affec7dfadf8c1216ec9398256ceb34a2a
+Subproject commit 64a3916c04daecf44b4617f2e8755900326957f0
diff --git a/SpaceStation14.sln b/SpaceStation14.sln
index 13082efa99..99f3ac6702 100644
--- a/SpaceStation14.sln
+++ b/SpaceStation14.sln
@@ -69,9 +69,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{DDD55F86
RobustToolbox\Tools\download_natives.py = RobustToolbox\Tools\download_natives.py
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lidgren.Network.UnitTests", "RobustToolbox\Lidgren.Network.UnitTests\Lidgren.Network.UnitTests.csproj", "{682E3140-4F27-4ECB-8029-D436319DDC48}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lidgren.Network.UnitTests", "RobustToolbox\Lidgren.Network.UnitTests\Lidgren.Network.UnitTests.csproj", "{682E3140-4F27-4ECB-8029-D436319DDC48}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetSerializer", "RobustToolbox\NetSerializer\NetSerializer\NetSerializer.csproj", "{7B9472D3-79D4-48D1-9B22-BCDE518FE842}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetSerializer", "RobustToolbox\NetSerializer\NetSerializer\NetSerializer.csproj", "{7B9472D3-79D4-48D1-9B22-BCDE518FE842}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Robust.Physics", "RobustToolbox\Robust.Physics\Robust.Physics.csproj", "{3BC34700-882F-426B-82BB-56D5708B5E0D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -79,68 +81,68 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {C899FCA4-7037-4E49-ABC2-44DE72487110}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C899FCA4-7037-4E49-ABC2-44DE72487110}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7AC832A1-2461-4EB5-AC26-26F6AFFA9E46}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {7AC832A1-2461-4EB5-AC26-26F6AFFA9E46}.Release|Any CPU.Build.0 = Release|Any CPU
- {7AC832A1-2461-4EB5-AC26-26F6AFFA9E46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7AC832A1-2461-4EB5-AC26-26F6AFFA9E46}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A2E5F175-78AF-4DDD-8F97-E2D2552372ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A2E5F175-78AF-4DDD-8F97-E2D2552372ED}.Release|Any CPU.Build.0 = Release|Any CPU
- {A2E5F175-78AF-4DDD-8F97-E2D2552372ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A2E5F175-78AF-4DDD-8F97-E2D2552372ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {AB7AF1C8-30FF-4436-9DF0-179BE5B0C132}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {AB7AF1C8-30FF-4436-9DF0-179BE5B0C132}.Release|Any CPU.Build.0 = Release|Any CPU
- {AB7AF1C8-30FF-4436-9DF0-179BE5B0C132}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {AB7AF1C8-30FF-4436-9DF0-179BE5B0C132}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B38DBBD0-04C2-4D1A-84E2-B3446F6ADF2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B38DBBD0-04C2-4D1A-84E2-B3446F6ADF2A}.Release|Any CPU.Build.0 = Release|Any CPU
- {B38DBBD0-04C2-4D1A-84E2-B3446F6ADF2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B38DBBD0-04C2-4D1A-84E2-B3446F6ADF2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {45C9B43F-305D-4651-9863-F6384CBC847F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {45C9B43F-305D-4651-9863-F6384CBC847F}.Release|Any CPU.Build.0 = Release|Any CPU
- {45C9B43F-305D-4651-9863-F6384CBC847F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {45C9B43F-305D-4651-9863-F6384CBC847F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {26AEEBB3-DDE7-443A-9F43-7BC7F4ACF6B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {26AEEBB3-DDE7-443A-9F43-7BC7F4ACF6B5}.Release|Any CPU.Build.0 = Release|Any CPU
{26AEEBB3-DDE7-443A-9F43-7BC7F4ACF6B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{26AEEBB3-DDE7-443A-9F43-7BC7F4ACF6B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8EDF4429-251A-416D-BB68-93F227191BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8EDF4429-251A-416D-BB68-93F227191BCF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {26AEEBB3-DDE7-443A-9F43-7BC7F4ACF6B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {26AEEBB3-DDE7-443A-9F43-7BC7F4ACF6B5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B38DBBD0-04C2-4D1A-84E2-B3446F6ADF2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B38DBBD0-04C2-4D1A-84E2-B3446F6ADF2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B38DBBD0-04C2-4D1A-84E2-B3446F6ADF2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B38DBBD0-04C2-4D1A-84E2-B3446F6ADF2A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A2E5F175-78AF-4DDD-8F97-E2D2552372ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A2E5F175-78AF-4DDD-8F97-E2D2552372ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A2E5F175-78AF-4DDD-8F97-E2D2552372ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A2E5F175-78AF-4DDD-8F97-E2D2552372ED}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C899FCA4-7037-4E49-ABC2-44DE72487110}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C899FCA4-7037-4E49-ABC2-44DE72487110}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8EDF4429-251A-416D-BB68-93F227191BCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8EDF4429-251A-416D-BB68-93F227191BCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {59250BAF-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {59250BAF-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8EDF4429-251A-416D-BB68-93F227191BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8EDF4429-251A-416D-BB68-93F227191BCF}.Release|Any CPU.Build.0 = Release|Any CPU
{59250BAF-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{59250BAF-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4809F412-3132-419E-BF9D-CCF7593C3533}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4809F412-3132-419E-BF9D-CCF7593C3533}.Release|Any CPU.Build.0 = Release|Any CPU
- {4809F412-3132-419E-BF9D-CCF7593C3533}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4809F412-3132-419E-BF9D-CCF7593C3533}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {83429BD6-6358-4B18-BE51-401DF8EA2673}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {83429BD6-6358-4B18-BE51-401DF8EA2673}.Release|Any CPU.Build.0 = Release|Any CPU
+ {59250BAF-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {59250BAF-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU
{83429BD6-6358-4B18-BE51-401DF8EA2673}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{83429BD6-6358-4B18-BE51-401DF8EA2673}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B04AAE71-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B04AAE71-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU
+ {83429BD6-6358-4B18-BE51-401DF8EA2673}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {83429BD6-6358-4B18-BE51-401DF8EA2673}.Release|Any CPU.Build.0 = Release|Any CPU
{B04AAE71-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B04AAE71-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0529F740-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0529F740-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU
- {0529F740-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0529F740-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {93F23A82-00C5-4572-964E-E7C9457726D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {93F23A82-00C5-4572-964E-E7C9457726D4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B04AAE71-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B04AAE71-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU
{93F23A82-00C5-4572-964E-E7C9457726D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{93F23A82-00C5-4572-964E-E7C9457726D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {41B450C0-A361-4CD7-8121-7072B8995CFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {41B450C0-A361-4CD7-8121-7072B8995CFC}.Release|Any CPU.Build.0 = Release|Any CPU
- {41B450C0-A361-4CD7-8121-7072B8995CFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {41B450C0-A361-4CD7-8121-7072B8995CFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F0ADA779-40B8-4F7E-BA6C-CDB19F3065D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F0ADA779-40B8-4F7E-BA6C-CDB19F3065D9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {93F23A82-00C5-4572-964E-E7C9457726D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {93F23A82-00C5-4572-964E-E7C9457726D4}.Release|Any CPU.Build.0 = Release|Any CPU
{F0ADA779-40B8-4F7E-BA6C-CDB19F3065D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F0ADA779-40B8-4F7E-BA6C-CDB19F3065D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F0ADA779-40B8-4F7E-BA6C-CDB19F3065D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F0ADA779-40B8-4F7E-BA6C-CDB19F3065D9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0529F740-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0529F740-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0529F740-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0529F740-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AB7AF1C8-30FF-4436-9DF0-179BE5B0C132}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AB7AF1C8-30FF-4436-9DF0-179BE5B0C132}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AB7AF1C8-30FF-4436-9DF0-179BE5B0C132}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AB7AF1C8-30FF-4436-9DF0-179BE5B0C132}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7AC832A1-2461-4EB5-AC26-26F6AFFA9E46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7AC832A1-2461-4EB5-AC26-26F6AFFA9E46}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7AC832A1-2461-4EB5-AC26-26F6AFFA9E46}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7AC832A1-2461-4EB5-AC26-26F6AFFA9E46}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4809F412-3132-419E-BF9D-CCF7593C3533}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4809F412-3132-419E-BF9D-CCF7593C3533}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4809F412-3132-419E-BF9D-CCF7593C3533}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4809F412-3132-419E-BF9D-CCF7593C3533}.Release|Any CPU.Build.0 = Release|Any CPU
+ {45C9B43F-305D-4651-9863-F6384CBC847F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {45C9B43F-305D-4651-9863-F6384CBC847F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {45C9B43F-305D-4651-9863-F6384CBC847F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {45C9B43F-305D-4651-9863-F6384CBC847F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {41B450C0-A361-4CD7-8121-7072B8995CFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {41B450C0-A361-4CD7-8121-7072B8995CFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {41B450C0-A361-4CD7-8121-7072B8995CFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {41B450C0-A361-4CD7-8121-7072B8995CFC}.Release|Any CPU.Build.0 = Release|Any CPU
{682E3140-4F27-4ECB-8029-D436319DDC48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{682E3140-4F27-4ECB-8029-D436319DDC48}.Debug|Any CPU.Build.0 = Debug|Any CPU
{682E3140-4F27-4ECB-8029-D436319DDC48}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -149,6 +151,10 @@ Global
{7B9472D3-79D4-48D1-9B22-BCDE518FE842}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B9472D3-79D4-48D1-9B22-BCDE518FE842}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B9472D3-79D4-48D1-9B22-BCDE518FE842}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3BC34700-882F-426B-82BB-56D5708B5E0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3BC34700-882F-426B-82BB-56D5708B5E0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3BC34700-882F-426B-82BB-56D5708B5E0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3BC34700-882F-426B-82BB-56D5708B5E0D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -167,6 +173,7 @@ Global
{DDD55F86-0406-42E5-8443-93EDC6BB2D75} = {83B4CBBA-547A-42F0-A7CD-8A67D93196CE}
{682E3140-4F27-4ECB-8029-D436319DDC48} = {83B4CBBA-547A-42F0-A7CD-8A67D93196CE}
{7B9472D3-79D4-48D1-9B22-BCDE518FE842} = {83B4CBBA-547A-42F0-A7CD-8A67D93196CE}
+ {3BC34700-882F-426B-82BB-56D5708B5E0D} = {83B4CBBA-547A-42F0-A7CD-8A67D93196CE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AA37ED9F-F8D6-468E-A101-658AD605B09A}