Merge branch 'master-upstream' into expl_int_analyzer
# Conflicts: # Content.Server/GameObjects/Components/Body/Part/BodyPartComponent.cs # Content.Server/GameObjects/Components/Botany/PlantHolderComponent.cs # Content.Server/GameObjects/Components/Chemistry/PillComponent.cs # Content.Server/GameObjects/Components/Interactable/TilePryingComponent.cs # Content.Server/GameObjects/Components/Items/FloorTileItemComponent.cs # Content.Server/GameObjects/Components/Items/RCD/RCDAmmoComponent.cs # Content.Server/GameObjects/Components/Items/RCD/RCDComponent.cs # Content.Server/GameObjects/Components/Medical/HealingComponent.cs # Content.Server/GameObjects/Components/Power/WirePlacerComponent.cs # Content.Shared/Chemistry/Solution.cs
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Chemistry
|
||||
{
|
||||
[Serializable, NetSerializable]
|
||||
public enum FoamVisuals : byte
|
||||
{
|
||||
State,
|
||||
Color
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using Content.Shared.Chemistry;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Chemistry
|
||||
{
|
||||
/// <summary>
|
||||
/// High-level solution transferring operations like "what happens when a syringe tries to inject this entity."
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This interface is most often implemented by using <see cref="SharedSolutionContainerComponent"/>
|
||||
/// and setting the appropriate <see cref="SolutionContainerCaps"/>
|
||||
/// </remarks>
|
||||
public interface ISolutionInteractionsComponent : IComponent
|
||||
{
|
||||
//
|
||||
// INJECTING
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// Whether we CAN POTENTIALLY be injected with solutions by items like syringes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This should NOT change to communicate behavior like "the container is full".
|
||||
/// Change <see cref="InjectSpaceAvailable"/> to 0 for that.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// If refilling is allowed (<see cref="CanRefill"/>) you should also always allow injecting.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
bool CanInject => false;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of solution space available for injecting.
|
||||
/// </summary>
|
||||
ReagentUnit InjectSpaceAvailable => ReagentUnit.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Actually inject reagents.
|
||||
/// </summary>
|
||||
void Inject(Solution solution)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// DRAWING
|
||||
//
|
||||
|
||||
bool CanDraw => false;
|
||||
ReagentUnit DrawAvailable => ReagentUnit.Zero;
|
||||
|
||||
Solution Draw(ReagentUnit amount)
|
||||
{
|
||||
return new();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// REFILLING
|
||||
//
|
||||
|
||||
bool CanRefill => false;
|
||||
ReagentUnit RefillSpaceAvailable => ReagentUnit.Zero;
|
||||
|
||||
void Refill(Solution solution)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// DRAINING
|
||||
//
|
||||
|
||||
bool CanDrain => false;
|
||||
ReagentUnit DrainAvailable => ReagentUnit.Zero;
|
||||
|
||||
Solution Drain(ReagentUnit amount)
|
||||
{
|
||||
return new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,10 @@ namespace Content.Shared.GameObjects.Components.Chemistry.ReagentDispenser
|
||||
SetDispenseAmount1,
|
||||
SetDispenseAmount5,
|
||||
SetDispenseAmount10,
|
||||
SetDispenseAmount15,
|
||||
SetDispenseAmount20,
|
||||
SetDispenseAmount25,
|
||||
SetDispenseAmount30,
|
||||
SetDispenseAmount50,
|
||||
SetDispenseAmount100,
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using Content.Shared.Chemistry;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Chemistry
|
||||
{
|
||||
public abstract class SharedHyposprayComponent : Component
|
||||
{
|
||||
public sealed override string Name => "Hypospray";
|
||||
public sealed override uint? NetID => ContentNetIDs.HYPOSPRAY;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
protected sealed class HyposprayComponentState : ComponentState
|
||||
{
|
||||
public ReagentUnit CurVolume { get; }
|
||||
public ReagentUnit MaxVolume { get; }
|
||||
|
||||
public HyposprayComponentState(ReagentUnit curVolume, ReagentUnit maxVolume) : base(ContentNetIDs.HYPOSPRAY)
|
||||
{
|
||||
CurVolume = curVolume;
|
||||
MaxVolume = maxVolume;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ namespace Content.Shared.GameObjects.Components.Chemistry
|
||||
}
|
||||
}
|
||||
|
||||
protected enum InjectorToggleMode
|
||||
public enum InjectorToggleMode
|
||||
{
|
||||
Inject,
|
||||
Draw
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Content.Shared.GameObjects.Components.Chemistry
|
||||
/// <summary>
|
||||
/// Holds a <see cref="Solution"/> with a limited volume.
|
||||
/// </summary>
|
||||
public abstract class SharedSolutionContainerComponent : Component, IExamine
|
||||
public abstract class SharedSolutionContainerComponent : Component, IExamine, ISolutionInteractionsComponent
|
||||
{
|
||||
public override string Name => "SolutionContainer";
|
||||
|
||||
@@ -60,9 +60,11 @@ namespace Content.Shared.GameObjects.Components.Chemistry
|
||||
|
||||
public bool CanUseWithChemDispenser => Capabilities.HasCap(SolutionContainerCaps.FitsInDispenser);
|
||||
|
||||
public bool CanAddSolutions => Capabilities.HasCap(SolutionContainerCaps.AddTo);
|
||||
public bool CanInject => Capabilities.HasCap(SolutionContainerCaps.Injectable) || CanRefill;
|
||||
public bool CanDraw => Capabilities.HasCap(SolutionContainerCaps.Drawable) || CanDrain;
|
||||
|
||||
public bool CanRemoveSolutions => Capabilities.HasCap(SolutionContainerCaps.RemoveFrom);
|
||||
public bool CanRefill => Capabilities.HasCap(SolutionContainerCaps.Refillable);
|
||||
public bool CanDrain => Capabilities.HasCap(SolutionContainerCaps.Drainable);
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
@@ -71,7 +73,7 @@ namespace Content.Shared.GameObjects.Components.Chemistry
|
||||
serializer.DataField(this, x => x.CanReact, "canReact", true);
|
||||
serializer.DataField(this, x => x.MaxVolume, "maxVol", ReagentUnit.New(0));
|
||||
serializer.DataField(this, x => x.Solution, "contents", new Solution());
|
||||
serializer.DataField(this, x => x.Capabilities, "caps", SolutionContainerCaps.AddTo | SolutionContainerCaps.RemoveFrom | SolutionContainerCaps.CanExamine);
|
||||
serializer.DataField(this, x => x.Capabilities, "caps", SolutionContainerCaps.None);
|
||||
}
|
||||
|
||||
public void RemoveAllSolution()
|
||||
@@ -209,6 +211,43 @@ namespace Content.Shared.GameObjects.Components.Chemistry
|
||||
message.AddMarkup(Loc.GetString(messageString, colorHex, Loc.GetString(proto.PhysicalDescription)));
|
||||
}
|
||||
|
||||
ReagentUnit ISolutionInteractionsComponent.RefillSpaceAvailable => EmptyVolume;
|
||||
ReagentUnit ISolutionInteractionsComponent.InjectSpaceAvailable => EmptyVolume;
|
||||
ReagentUnit ISolutionInteractionsComponent.DrawAvailable => CurrentVolume;
|
||||
ReagentUnit ISolutionInteractionsComponent.DrainAvailable => CurrentVolume;
|
||||
|
||||
void ISolutionInteractionsComponent.Refill(Solution solution)
|
||||
{
|
||||
if (!CanRefill)
|
||||
return;
|
||||
|
||||
TryAddSolution(solution);
|
||||
}
|
||||
|
||||
void ISolutionInteractionsComponent.Inject(Solution solution)
|
||||
{
|
||||
if (!CanInject)
|
||||
return;
|
||||
|
||||
TryAddSolution(solution);
|
||||
}
|
||||
|
||||
Solution ISolutionInteractionsComponent.Draw(ReagentUnit amount)
|
||||
{
|
||||
if (!CanDraw)
|
||||
return new Solution();
|
||||
|
||||
return SplitSolution(amount);
|
||||
}
|
||||
|
||||
Solution ISolutionInteractionsComponent.Drain(ReagentUnit amount)
|
||||
{
|
||||
if (!CanDrain)
|
||||
return new Solution();
|
||||
|
||||
return SplitSolution(amount);
|
||||
}
|
||||
|
||||
private void UpdateAppearance()
|
||||
{
|
||||
if (Owner.Deleted || !Owner.TryGetComponent<SharedAppearanceComponent>(out var appearance))
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Chemistry
|
||||
{
|
||||
[Serializable, NetSerializable]
|
||||
public enum SmokeVisuals : byte
|
||||
{
|
||||
Color
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#nullable enable
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.GUI
|
||||
{
|
||||
/// <summary>
|
||||
/// Give to an entity to say they can strip another entity.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public class SharedStrippingComponent : Component, IDragDropOn
|
||||
{
|
||||
public override string Name => "Stripping";
|
||||
|
||||
public bool CanDragDropOn(DragDropEventArgs eventArgs)
|
||||
{
|
||||
if (!eventArgs.Dragged.TryGetComponent(out SharedStrippableComponent? strippable)) return false;
|
||||
return strippable.CanBeStripped(Owner);
|
||||
}
|
||||
|
||||
public bool DragDropOn(DragDropEventArgs eventArgs)
|
||||
{
|
||||
// Handled by StrippableComponent
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
#nullable enable
|
||||
#nullable enable
|
||||
using System;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Items
|
||||
@@ -127,4 +128,20 @@ namespace Content.Shared.GameObjects.Components.Items
|
||||
Middle,
|
||||
Right
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Component message for displaying an animation of an entity flying towards the owner of a HandsComponent
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public class AnimatePickupEntityMessage : ComponentMessage
|
||||
{
|
||||
public readonly EntityUid EntityId;
|
||||
public readonly EntityCoordinates EntityPosition;
|
||||
public AnimatePickupEntityMessage(EntityUid entity, EntityCoordinates entityPosition)
|
||||
{
|
||||
Directed = true;
|
||||
EntityId = entity;
|
||||
EntityPosition = entityPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.Timing;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Mobs
|
||||
{
|
||||
/// <summary>
|
||||
/// Full screen overlays; Blindness, death, flash, alcohol etc.
|
||||
/// </summary>
|
||||
public abstract class SharedOverlayEffectsComponent : Component
|
||||
{
|
||||
public override string Name => "OverlayEffectsUI";
|
||||
|
||||
public sealed override uint? NetID => ContentNetIDs.OVERLAYEFFECTS;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public class OverlayContainer : IEquatable<string>, IEquatable<OverlayContainer>
|
||||
{
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public string ID { get; }
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public List<OverlayParameter> Parameters { get; } = new();
|
||||
|
||||
public OverlayContainer([NotNull] string id)
|
||||
{
|
||||
ID = id;
|
||||
}
|
||||
|
||||
public OverlayContainer(SharedOverlayID id) : this(id.ToString())
|
||||
{
|
||||
}
|
||||
|
||||
public OverlayContainer(SharedOverlayID id, params OverlayParameter[] parameters) : this(id)
|
||||
{
|
||||
Parameters.AddRange(parameters);
|
||||
}
|
||||
|
||||
public bool TryGetOverlayParameter<T>(out T parameter) where T : OverlayParameter
|
||||
{
|
||||
var found = Parameters.FirstOrDefault(p => p is T);
|
||||
if (found != null)
|
||||
{
|
||||
parameter = found as T;
|
||||
return true;
|
||||
}
|
||||
|
||||
parameter = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Equals(string other)
|
||||
{
|
||||
return ID == other;
|
||||
}
|
||||
|
||||
public bool Equals(OverlayContainer other)
|
||||
{
|
||||
return ID == other?.ID;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ID != null ? ID.GetHashCode() : 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public class OverlayEffectComponentMessage : ComponentMessage
|
||||
{
|
||||
public List<OverlayContainer> Overlays;
|
||||
|
||||
public OverlayEffectComponentMessage(List<OverlayContainer> overlays)
|
||||
{
|
||||
Directed = true;
|
||||
Overlays = overlays;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public class ResendOverlaysMessage : ComponentMessage
|
||||
{
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public abstract class OverlayParameter
|
||||
{
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public class TimedOverlayParameter : OverlayParameter
|
||||
{
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public int Length { get; set; }
|
||||
|
||||
public double StartedAt { get; private set; }
|
||||
|
||||
public TimedOverlayParameter(int length)
|
||||
{
|
||||
Length = length;
|
||||
StartedAt = IoCManager.Resolve<IGameTiming>().CurTime.TotalMilliseconds;
|
||||
}
|
||||
}
|
||||
|
||||
public enum SharedOverlayID
|
||||
{
|
||||
GradientCircleMaskOverlay,
|
||||
CircleMaskOverlay,
|
||||
FlashOverlay,
|
||||
RadiationPulseOverlay,
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
#nullable enable
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects.EntitySystems.ActionBlocker;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Storage
|
||||
@@ -100,6 +102,22 @@ namespace Content.Shared.GameObjects.Components.Storage
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Component message for displaying an animation of entities flying into a storage entity
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public class AnimateInsertingEntitiesMessage : ComponentMessage
|
||||
{
|
||||
public readonly List<EntityUid> StoredEntities;
|
||||
public readonly List<EntityCoordinates> EntityPositions;
|
||||
public AnimateInsertingEntitiesMessage(List<EntityUid> storedEntities, List<EntityCoordinates> entityPositions)
|
||||
{
|
||||
Directed = true;
|
||||
StoredEntities = storedEntities;
|
||||
EntityPositions = entityPositions;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Component message for removing a contained entity from the storage entity
|
||||
/// </summary>
|
||||
|
||||
300
Content.Shared/GameObjects/Components/Tag/TagComponent.cs
Normal file
300
Content.Shared/GameObjects/Components/Tag/TagComponent.cs
Normal file
@@ -0,0 +1,300 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Shared.Prototypes.Tag;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Tag
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class TagComponent : Component
|
||||
{
|
||||
public override string Name => "Tag";
|
||||
|
||||
[ViewVariables]
|
||||
private readonly HashSet<string> _tags = new();
|
||||
|
||||
public IReadOnlySet<string> Tags => _tags;
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
|
||||
serializer.DataReadWriteFunction(
|
||||
"tags",
|
||||
null!,
|
||||
(ids) =>
|
||||
{
|
||||
_tags.Clear();
|
||||
|
||||
if (ids == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AddTags(ids);
|
||||
},
|
||||
() => _tags);
|
||||
}
|
||||
|
||||
public override ComponentState GetComponentState()
|
||||
{
|
||||
var tags = new string[_tags.Count];
|
||||
var i = 0;
|
||||
|
||||
foreach (var tag in _tags)
|
||||
{
|
||||
tags[i] = tag;
|
||||
}
|
||||
|
||||
return new TagComponentState(tags);
|
||||
}
|
||||
|
||||
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
|
||||
{
|
||||
if (curState is not TagComponentState state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_tags.Clear();
|
||||
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
foreach (var tag in state.Tags)
|
||||
{
|
||||
GetTagOrThrow(tag, prototypeManager);
|
||||
_tags.Add(tag);
|
||||
}
|
||||
}
|
||||
|
||||
private TagPrototype GetTagOrThrow(string id, IPrototypeManager? manager = null)
|
||||
{
|
||||
manager ??= IoCManager.Resolve<IPrototypeManager>();
|
||||
return manager.Index<TagPrototype>(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to add a tag if it doesn't already exist.
|
||||
/// </summary>
|
||||
/// <param name="id">The tag to add.</param>
|
||||
/// <returns>true if it was added, false if it already existed.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if no <see cref="TagPrototype"/> exists with the given id.
|
||||
/// </exception>
|
||||
public bool AddTag(string id)
|
||||
{
|
||||
GetTagOrThrow(id);
|
||||
var added = _tags.Add(id);
|
||||
|
||||
if (added)
|
||||
{
|
||||
Dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to add the given tags if they don't already exist.
|
||||
/// </summary>
|
||||
/// <param name="ids">The tags to add.</param>
|
||||
/// <returns>true if any tags were added, false if they all already existed.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public bool AddTags(params string[] ids)
|
||||
{
|
||||
return AddTags(ids.AsEnumerable());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to add the given tags if they don't already exist.
|
||||
/// </summary>
|
||||
/// <param name="ids">The tags to add.</param>
|
||||
/// <returns>true if any tags were added, false if they all already existed.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public bool AddTags(IEnumerable<string> ids)
|
||||
{
|
||||
var count = _tags.Count;
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
foreach (var id in ids)
|
||||
{
|
||||
GetTagOrThrow(id, prototypeManager);
|
||||
_tags.Add(id);
|
||||
}
|
||||
|
||||
if (_tags.Count > count)
|
||||
{
|
||||
Dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a tag has been added.
|
||||
/// </summary>
|
||||
/// <param name="id">The tag to check for.</param>
|
||||
/// <returns>true if it exists, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if no <see cref="TagPrototype"/> exists with the given id.
|
||||
/// </exception>
|
||||
public bool HasTag(string id)
|
||||
{
|
||||
GetTagOrThrow(id);
|
||||
return _tags.Contains(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if all of the given tags have been added.
|
||||
/// </summary>
|
||||
/// <param name="ids">The tags to check for.</param>
|
||||
/// <returns>true if they all exist, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public bool HasAllTags(params string[] ids)
|
||||
{
|
||||
return HasAllTags(ids.AsEnumerable());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if all of the given tags have been added.
|
||||
/// </summary>
|
||||
/// <param name="ids">The tags to check for.</param>
|
||||
/// <returns>true if they all exist, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public bool HasAllTags(IEnumerable<string> ids)
|
||||
{
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
foreach (var id in ids)
|
||||
{
|
||||
GetTagOrThrow(id, prototypeManager);
|
||||
|
||||
if (!_tags.Contains(id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if any of the given tags have been added.
|
||||
/// </summary>
|
||||
/// <param name="ids">The tags to check for.</param>
|
||||
/// <returns>true if any of them exist, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public bool HasAnyTag(params string[] ids)
|
||||
{
|
||||
return HasAnyTag(ids.AsEnumerable());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if any of the given tags have been added.
|
||||
/// </summary>
|
||||
/// <param name="ids">The tags to check for.</param>
|
||||
/// <returns>true if any of them exist, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public bool HasAnyTag(IEnumerable<string> ids)
|
||||
{
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
foreach (var id in ids)
|
||||
{
|
||||
GetTagOrThrow(id, prototypeManager);
|
||||
|
||||
if (_tags.Contains(id))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to remove a tag if it exists.
|
||||
/// </summary>
|
||||
/// <param name="id">The tag to remove.</param>
|
||||
/// <returns>
|
||||
/// true if it was removed, false otherwise even if it didn't exist.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if no <see cref="TagPrototype"/> exists with the given id.
|
||||
/// </exception>
|
||||
public bool RemoveTag(string id)
|
||||
{
|
||||
GetTagOrThrow(id);
|
||||
|
||||
if (_tags.Remove(id))
|
||||
{
|
||||
Dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to remove all of the given tags if they exist.
|
||||
/// </summary>
|
||||
/// <param name="ids">The tags to remove.</param>
|
||||
/// <returns>
|
||||
/// true if it was removed, false otherwise even if they didn't exist.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public bool RemoveTags(params string[] ids)
|
||||
{
|
||||
return RemoveTags(ids.AsEnumerable());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to remove all of the given tags if they exist.
|
||||
/// </summary>
|
||||
/// <param name="ids">The tags to remove.</param>
|
||||
/// <returns>true if any tag was removed, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public bool RemoveTags(IEnumerable<string> ids)
|
||||
{
|
||||
var count = _tags.Count;
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
foreach (var id in ids)
|
||||
{
|
||||
GetTagOrThrow(id, prototypeManager);
|
||||
_tags.Remove(id);
|
||||
}
|
||||
|
||||
if (_tags.Count < count)
|
||||
{
|
||||
Dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.Prototypes.Tag;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Tag
|
||||
{
|
||||
public static class TagComponentExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Tries to add a tag to an entity if the tag doesn't already exist.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to add the tag to.</param>
|
||||
/// <param name="id">The tag to add.</param>
|
||||
/// <returns>
|
||||
/// true if it was added, false otherwise even if it already existed.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if no <see cref="TagPrototype"/> exists with the given id.
|
||||
/// </exception>
|
||||
public static bool AddTag(this IEntity entity, string id)
|
||||
{
|
||||
return entity.EnsureComponent(out TagComponent tagComponent) &&
|
||||
tagComponent.AddTag(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to add the given tags to an entity if the tags don't already exist.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to add the tag to.</param>
|
||||
/// <param name="ids">The tags to add.</param>
|
||||
/// <returns>
|
||||
/// true if any tags were added, false otherwise even if they all already existed.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public static bool AddTags(this IEntity entity, params string[] ids)
|
||||
{
|
||||
return entity.EnsureComponent(out TagComponent tagComponent) &&
|
||||
tagComponent.AddTags(ids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to add the given tags to an entity if the tags don't already exist.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to add the tag to.</param>
|
||||
/// <param name="ids">The tags to add.</param>
|
||||
/// <returns>
|
||||
/// true if any tags were added, false otherwise even if they all already existed.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public static bool AddTags(this IEntity entity, IEnumerable<string> ids)
|
||||
{
|
||||
return entity.EnsureComponent(out TagComponent tagComponent) &&
|
||||
tagComponent.AddTags(ids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to add a tag to an entity if it has a <see cref="TagComponent"/>
|
||||
/// and the tag doesn't already exist.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to add the tag to.</param>
|
||||
/// <param name="id">The tag to add.</param>
|
||||
/// <returns>
|
||||
/// true if it was added, false otherwise even if it already existed.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if no <see cref="TagPrototype"/> exists with the given id.
|
||||
/// </exception>
|
||||
public static bool TryAddTag(this IEntity entity, string id)
|
||||
{
|
||||
return entity.TryGetComponent(out TagComponent? tagComponent) &&
|
||||
tagComponent.AddTag(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to add the given tags to an entity if it has a
|
||||
/// <see cref="TagComponent"/> and the tags don't already exist.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to add the tag to.</param>
|
||||
/// <param name="ids">The tags to add.</param>
|
||||
/// <returns>
|
||||
/// true if any tags were added, false otherwise even if they all already existed.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public static bool TryAddTags(this IEntity entity, params string[] ids)
|
||||
{
|
||||
return entity.TryGetComponent(out TagComponent? tagComponent) &&
|
||||
tagComponent.AddTags(ids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to add the given tags to an entity if it has a
|
||||
/// <see cref="TagComponent"/> and the tags don't already exist.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to add the tag to.</param>
|
||||
/// <param name="ids">The tags to add.</param>
|
||||
/// <returns>
|
||||
/// true if any tags were added, false otherwise even if they all already existed.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public static bool TryAddTags(this IEntity entity, IEnumerable<string> ids)
|
||||
{
|
||||
return entity.TryGetComponent(out TagComponent? tagComponent) &&
|
||||
tagComponent.AddTags(ids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a tag has been added to an entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to check.</param>
|
||||
/// <param name="id">The tag to check for.</param>
|
||||
/// <returns>true if it exists, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if no <see cref="TagPrototype"/> exists with the given id.
|
||||
/// </exception>
|
||||
public static bool HasTag(this IEntity entity, string id)
|
||||
{
|
||||
return entity.TryGetComponent(out TagComponent? tagComponent) &&
|
||||
tagComponent.HasTag(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if all of the given tags have been added to an entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to check.</param>
|
||||
/// <param name="ids">The tags to check for.</param>
|
||||
/// <returns>true if they all exist, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public static bool HasAllTags(this IEntity entity, params string[] ids)
|
||||
{
|
||||
return entity.TryGetComponent(out TagComponent? tagComponent) &&
|
||||
tagComponent.HasAllTags(ids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if all of the given tags have been added to an entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to check.</param>
|
||||
/// <param name="ids">The tags to check for.</param>
|
||||
/// <returns>true if they all exist, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public static bool HasAllTags(this IEntity entity, IEnumerable<string> ids)
|
||||
{
|
||||
return entity.TryGetComponent(out TagComponent? tagComponent) &&
|
||||
tagComponent.HasAllTags(ids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if all of the given tags have been added to an entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to check.</param>
|
||||
/// <param name="ids">The tags to check for.</param>
|
||||
/// <returns>true if any of them exist, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public static bool HasAnyTag(this IEntity entity, params string[] ids)
|
||||
{
|
||||
return entity.TryGetComponent(out TagComponent? tagComponent) &&
|
||||
tagComponent.HasAnyTag(ids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if all of the given tags have been added to an entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to check.</param>
|
||||
/// <param name="ids">The tags to check for.</param>
|
||||
/// <returns>true if any of them exist, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public static bool HasAnyTag(this IEntity entity, IEnumerable<string> ids)
|
||||
{
|
||||
return entity.TryGetComponent(out TagComponent? tagComponent) &&
|
||||
tagComponent.HasAnyTag(ids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to remove a tag from an entity if it exists.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to remove the tag from.</param>
|
||||
/// <param name="id">The tag to remove.</param>
|
||||
/// <returns>
|
||||
/// true if it was removed, false otherwise even if it didn't exist.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if no <see cref="TagPrototype"/> exists with the given id.
|
||||
/// </exception>
|
||||
public static bool RemoveTag(this IEntity entity, string id)
|
||||
{
|
||||
return entity.TryGetComponent(out TagComponent? tagComponent) &&
|
||||
tagComponent.RemoveTag(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to remove a tag from an entity if it exists.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to remove the tag from.</param>
|
||||
/// <param name="ids">The tag to remove.</param>
|
||||
/// <returns>
|
||||
/// true if it was removed, false otherwise even if it didn't exist.
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
/// </returns>
|
||||
public static bool RemoveTags(this IEntity entity, params string[] ids)
|
||||
{
|
||||
return entity.TryGetComponent(out TagComponent? tagComponent) &&
|
||||
tagComponent.RemoveTags(ids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to remove a tag from an entity if it exists.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to remove the tag from.</param>
|
||||
/// <param name="ids">The tag to remove.</param>
|
||||
/// <returns>
|
||||
/// true if it was removed, false otherwise even if it didn't exist.
|
||||
/// </returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public static bool RemoveTags(this IEntity entity, IEnumerable<string> ids)
|
||||
{
|
||||
return entity.TryGetComponent(out TagComponent? tagComponent) &&
|
||||
tagComponent.RemoveTags(ids);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#nullable enable
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Tag
|
||||
{
|
||||
public class TagComponentState : ComponentState
|
||||
{
|
||||
public TagComponentState(string[] tags) : base(ContentNetIDs.TAG)
|
||||
{
|
||||
Tags = tags;
|
||||
}
|
||||
|
||||
public string[] Tags { get; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user