Merge branch 'master' into buckle-locker-fix-1262
This commit is contained in:
@@ -1,6 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Timers;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
using Component = Robust.Shared.GameObjects.Component;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Mobs
|
||||
{
|
||||
@@ -13,21 +21,72 @@ namespace Content.Shared.GameObjects.Components.Mobs
|
||||
public sealed override uint? NetID => ContentNetIDs.OVERLAYEFFECTS;
|
||||
}
|
||||
|
||||
public enum ScreenEffects
|
||||
[Serializable, NetSerializable]
|
||||
public class OverlayContainer
|
||||
{
|
||||
None,
|
||||
CircleMask,
|
||||
GradientCircleMask,
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public string ID { get; }
|
||||
|
||||
public OverlayContainer([NotNull] string id)
|
||||
{
|
||||
ID = id;
|
||||
}
|
||||
|
||||
public OverlayContainer(OverlayType type) : this(type.ToString())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is OverlayContainer container)
|
||||
{
|
||||
return container.ID == ID;
|
||||
}
|
||||
|
||||
if (obj is string idString)
|
||||
{
|
||||
return idString == ID;
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (ID != null ? ID.GetHashCode() : 0);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public class OverlayEffectComponentState : ComponentState
|
||||
{
|
||||
public ScreenEffects ScreenEffect;
|
||||
public List<OverlayContainer> Overlays;
|
||||
|
||||
public OverlayEffectComponentState(ScreenEffects screenEffect) : base(ContentNetIDs.OVERLAYEFFECTS)
|
||||
public OverlayEffectComponentState(List<OverlayContainer> overlays) : base(ContentNetIDs.OVERLAYEFFECTS)
|
||||
{
|
||||
ScreenEffect = screenEffect;
|
||||
Overlays = overlays;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public class TimedOverlayContainer : OverlayContainer
|
||||
{
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public int Length { get; }
|
||||
|
||||
public TimedOverlayContainer(string id, int length) : base(id)
|
||||
{
|
||||
Length = length;
|
||||
}
|
||||
|
||||
public void StartTimer(Action finished) => Timer.Spawn(Length, finished);
|
||||
}
|
||||
|
||||
public enum OverlayType
|
||||
{
|
||||
GradientCircleMaskOverlay,
|
||||
CircleMaskOverlay,
|
||||
FlashOverlay
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Content.Shared.GameObjects.Components.Movement
|
||||
|
||||
/// <summary>
|
||||
/// Toggles one of the four cardinal directions. Each of the four directions are
|
||||
/// composed into a single direction vector, <see cref="PlayerInputMoverComponent.VelocityDir"/>. Enabling
|
||||
/// composed into a single direction vector, <see cref="SharedPlayerInputMoverComponent.VelocityDir"/>. Enabling
|
||||
/// opposite directions will cancel each other out, resulting in no direction.
|
||||
/// </summary>
|
||||
/// <param name="direction">Direction to toggle.</param>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components
|
||||
{
|
||||
public abstract class SharedPlaceableSurfaceComponent : Component
|
||||
{
|
||||
public override string Name => "PlaceableSurface";
|
||||
}
|
||||
}
|
||||
@@ -26,12 +26,27 @@ namespace Content.Shared.GameObjects.Components.Strap
|
||||
{
|
||||
public sealed override string Name => "Strap";
|
||||
|
||||
public virtual StrapPosition Position { get; set; }
|
||||
public sealed override uint? NetID => ContentNetIDs.STRAP;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum StrapVisuals
|
||||
public abstract StrapPosition Position { get; protected set; }
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class StrapComponentState : ComponentState
|
||||
{
|
||||
public readonly StrapPosition Position;
|
||||
|
||||
public StrapComponentState(StrapPosition position) : base(ContentNetIDs.BUCKLE)
|
||||
{
|
||||
RotationAngle
|
||||
Position = position;
|
||||
}
|
||||
|
||||
public bool Buckled { get; }
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum StrapVisuals
|
||||
{
|
||||
RotationAngle
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
public const uint BUCKLE = 1052;
|
||||
public const uint PROJECTILE = 1053;
|
||||
public const uint THROWN_ITEM = 1054;
|
||||
public const uint STRAP = 1055;
|
||||
|
||||
// Net IDs for integration tests.
|
||||
public const uint PREDICTION_TEST = 10001;
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.GameObjects.EntitySystemMessages
|
||||
{
|
||||
/// <summary>
|
||||
/// Requests a drag / drop interaction to be performed
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public class DragDropMessage : EntitySystemMessage
|
||||
{
|
||||
public GridCoordinates DropLocation { get; }
|
||||
public EntityUid Dropped { get; }
|
||||
public EntityUid Target { get; }
|
||||
|
||||
public DragDropMessage(GridCoordinates dropLocation, EntityUid dropped, EntityUid target)
|
||||
{
|
||||
DropLocation = dropLocation;
|
||||
Dropped = dropped;
|
||||
Target = target;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ using Content.Shared.GameObjects.Components.Mobs;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.GameObjects.EntitySystems
|
||||
{
|
||||
@@ -31,7 +30,7 @@ namespace Content.Shared.GameObjects.EntitySystems
|
||||
|
||||
return EntitySystem.Get<SharedInteractionSystem>()
|
||||
.InRangeUnobstructed(examiner.Transform.MapPosition, examined.Transform.MapPosition,
|
||||
ExamineRange, predicate: entity => entity == examiner || entity == examined, insideBlockerValid:true);
|
||||
ExamineRange, predicate: entity => entity == examiner || entity == examined, ignoreInsideBlocker:true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,10 +72,13 @@ namespace Content.Shared.GameObjects.EntitySystems
|
||||
/// <param name="range">maximum distance between the two sets of coordinates.</param>
|
||||
/// <param name="collisionMask">the mask to check for collisions</param>
|
||||
/// <param name="predicate">A predicate to check whether to ignore an entity or not. If it returns true, it will be ignored.</param>
|
||||
/// <param name="insideBlockerValid">if coordinates inside obstructions count as obstructed or not</param>
|
||||
/// <param name="ignoreInsideBlocker">if true and the coordinates are inside the obstruction, ignores the obstruction and
|
||||
/// considers the interaction unobstructed. Therefore, setting this to true makes this check more permissive, such
|
||||
/// as allowing an interaction to occur inside something impassable (like a wall). The default, false,
|
||||
/// makes the check more restrictive.</param>
|
||||
/// <returns>True if the two points are within a given range without being obstructed.</returns>
|
||||
public bool InRangeUnobstructed(MapCoordinates coords, MapCoordinates otherCoords, float range = InteractionRange,
|
||||
int collisionMask = (int)CollisionGroup.Impassable, Func<IEntity, bool> predicate = null, bool insideBlockerValid = false)
|
||||
int collisionMask = (int)CollisionGroup.Impassable, Func<IEntity, bool> predicate = null, bool ignoreInsideBlocker = false)
|
||||
{
|
||||
if (!coords.InRange(otherCoords, range))
|
||||
return false;
|
||||
@@ -87,7 +90,7 @@ namespace Content.Shared.GameObjects.EntitySystems
|
||||
|
||||
var ray = new CollisionRay(coords.Position, dir.Normalized, collisionMask);
|
||||
var rayResults = _physicsManager.IntersectRayWithPredicate(coords.MapId, ray, dir.Length, predicate, returnOnFirstHit: false).ToList();
|
||||
return rayResults.Count == 0 || (insideBlockerValid && rayResults.Count > 0 && (rayResults[0].HitPos - otherCoords.Position).Length < 1f);
|
||||
return rayResults.Count == 0 || (ignoreInsideBlocker && rayResults.Count > 0 && (rayResults[0].HitPos - otherCoords.Position).Length < 1f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -101,11 +104,14 @@ namespace Content.Shared.GameObjects.EntitySystems
|
||||
/// <param name="range">maximum distance between the two sets of coordinates.</param>
|
||||
/// <param name="collisionMask">the mask to check for collisions</param>
|
||||
/// <param name="ignoredEnt">the entity to be ignored when checking for collisions.</param>
|
||||
/// <param name="insideBlockerValid">if coordinates inside obstructions count as obstructed or not</param>
|
||||
/// <param name="ignoreInsideBlocker">if true and the coordinates are inside the obstruction, ignores the obstruction and
|
||||
/// considers the interaction unobstructed. Therefore, setting this to true makes this check more permissive, such
|
||||
/// as allowing an interaction to occur inside something impassable (like a wall). The default, false,
|
||||
/// makes the check more restrictive.</param>
|
||||
/// <returns>True if the two points are within a given range without being obstructed.</returns>
|
||||
public bool InRangeUnobstructed(MapCoordinates coords, MapCoordinates otherCoords, float range = InteractionRange,
|
||||
int collisionMask = (int)CollisionGroup.Impassable, IEntity ignoredEnt = null, bool insideBlockerValid = false) =>
|
||||
int collisionMask = (int)CollisionGroup.Impassable, IEntity ignoredEnt = null, bool ignoreInsideBlocker = false) =>
|
||||
InRangeUnobstructed(coords, otherCoords, range, collisionMask,
|
||||
ignoredEnt == null ? null : (Func<IEntity, bool>)(entity => ignoredEnt == entity), insideBlockerValid);
|
||||
ignoredEnt == null ? null : (Func<IEntity, bool>)(entity => ignoredEnt == entity), ignoreInsideBlocker);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ namespace Content.Shared.GameObjects.EntitySystems
|
||||
base.Shutdown();
|
||||
}
|
||||
|
||||
|
||||
protected void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, PhysicsComponent physics,
|
||||
CollidableComponent? collider = null)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Content.Shared.Input
|
||||
public static readonly BoundKeyFunction Drop = "Drop";
|
||||
public static readonly BoundKeyFunction ExamineEntity = "ExamineEntity";
|
||||
public static readonly BoundKeyFunction FocusChat = "FocusChatWindow";
|
||||
public static readonly BoundKeyFunction FocusOOC = "FocusOOCWindow";
|
||||
public static readonly BoundKeyFunction OpenCharacterMenu = "OpenCharacterMenu";
|
||||
public static readonly BoundKeyFunction OpenContextMenu = "OpenContextMenu";
|
||||
public static readonly BoundKeyFunction OpenCraftingMenu = "OpenCraftingMenu";
|
||||
|
||||
7
Content.Shared/Interfaces/IConfigurable.cs
Normal file
7
Content.Shared/Interfaces/IConfigurable.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Content.Shared.Interfaces
|
||||
{
|
||||
public interface IConfigurable<in T>
|
||||
{
|
||||
public void Configure(T parameters);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Shared.Antags;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Preferences
|
||||
@@ -9,6 +12,7 @@ namespace Content.Shared.Preferences
|
||||
public class HumanoidCharacterProfile : ICharacterProfile
|
||||
{
|
||||
private readonly Dictionary<string, JobPriority> _jobPriorities;
|
||||
private readonly List<string> _antagPreferences;
|
||||
public static int MinimumAge = 18;
|
||||
public static int MaximumAge = 90;
|
||||
|
||||
@@ -18,7 +22,8 @@ namespace Content.Shared.Preferences
|
||||
Sex sex,
|
||||
HumanoidCharacterAppearance appearance,
|
||||
Dictionary<string, JobPriority> jobPriorities,
|
||||
PreferenceUnavailableMode preferenceUnavailable)
|
||||
PreferenceUnavailableMode preferenceUnavailable,
|
||||
List<string> antagPreferences)
|
||||
{
|
||||
Name = name;
|
||||
Age = age;
|
||||
@@ -26,6 +31,7 @@ namespace Content.Shared.Preferences
|
||||
Appearance = appearance;
|
||||
_jobPriorities = jobPriorities;
|
||||
PreferenceUnavailable = preferenceUnavailable;
|
||||
_antagPreferences = antagPreferences;
|
||||
}
|
||||
|
||||
public HumanoidCharacterProfile(
|
||||
@@ -34,9 +40,10 @@ namespace Content.Shared.Preferences
|
||||
Sex sex,
|
||||
HumanoidCharacterAppearance appearance,
|
||||
IReadOnlyDictionary<string, JobPriority> jobPriorities,
|
||||
PreferenceUnavailableMode preferenceUnavailable)
|
||||
PreferenceUnavailableMode preferenceUnavailable,
|
||||
IReadOnlyList<string> antagPreferences)
|
||||
: this(name, age, sex, appearance, new Dictionary<string, JobPriority>(jobPriorities),
|
||||
preferenceUnavailable)
|
||||
preferenceUnavailable, new List<string>(antagPreferences))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -46,7 +53,7 @@ namespace Content.Shared.Preferences
|
||||
new Dictionary<string, JobPriority>
|
||||
{
|
||||
{SharedGameTicker.OverflowJob, JobPriority.High}
|
||||
}, PreferenceUnavailableMode.StayInLobby);
|
||||
}, PreferenceUnavailableMode.StayInLobby, new List<string>());
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
@@ -55,26 +62,27 @@ namespace Content.Shared.Preferences
|
||||
public ICharacterAppearance CharacterAppearance => Appearance;
|
||||
public HumanoidCharacterAppearance Appearance { get; }
|
||||
public IReadOnlyDictionary<string, JobPriority> JobPriorities => _jobPriorities;
|
||||
public IReadOnlyList<string> AntagPreferences => _antagPreferences;
|
||||
public PreferenceUnavailableMode PreferenceUnavailable { get; }
|
||||
|
||||
public HumanoidCharacterProfile WithName(string name)
|
||||
{
|
||||
return new HumanoidCharacterProfile(name, Age, Sex, Appearance, _jobPriorities, PreferenceUnavailable);
|
||||
return new HumanoidCharacterProfile(name, Age, Sex, Appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences);
|
||||
}
|
||||
|
||||
public HumanoidCharacterProfile WithAge(int age)
|
||||
{
|
||||
return new HumanoidCharacterProfile(Name, age, Sex, Appearance, _jobPriorities, PreferenceUnavailable);
|
||||
return new HumanoidCharacterProfile(Name, age, Sex, Appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences);
|
||||
}
|
||||
|
||||
public HumanoidCharacterProfile WithSex(Sex sex)
|
||||
{
|
||||
return new HumanoidCharacterProfile(Name, Age, sex, Appearance, _jobPriorities, PreferenceUnavailable);
|
||||
return new HumanoidCharacterProfile(Name, Age, sex, Appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences);
|
||||
}
|
||||
|
||||
public HumanoidCharacterProfile WithCharacterAppearance(HumanoidCharacterAppearance appearance)
|
||||
{
|
||||
return new HumanoidCharacterProfile(Name, Age, Sex, appearance, _jobPriorities, PreferenceUnavailable);
|
||||
return new HumanoidCharacterProfile(Name, Age, Sex, appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences);
|
||||
}
|
||||
|
||||
public HumanoidCharacterProfile WithJobPriorities(IReadOnlyDictionary<string, JobPriority> jobPriorities)
|
||||
@@ -85,7 +93,8 @@ namespace Content.Shared.Preferences
|
||||
Sex,
|
||||
Appearance,
|
||||
new Dictionary<string, JobPriority>(jobPriorities),
|
||||
PreferenceUnavailable);
|
||||
PreferenceUnavailable,
|
||||
_antagPreferences);
|
||||
}
|
||||
|
||||
public HumanoidCharacterProfile WithJobPriority(string jobId, JobPriority priority)
|
||||
@@ -100,12 +109,44 @@ namespace Content.Shared.Preferences
|
||||
dictionary[jobId] = priority;
|
||||
}
|
||||
|
||||
return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, dictionary, PreferenceUnavailable);
|
||||
return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, dictionary, PreferenceUnavailable, _antagPreferences);
|
||||
}
|
||||
|
||||
public HumanoidCharacterProfile WithPreferenceUnavailable(PreferenceUnavailableMode mode)
|
||||
{
|
||||
return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, _jobPriorities, mode);
|
||||
return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, _jobPriorities, mode, _antagPreferences);
|
||||
}
|
||||
|
||||
public HumanoidCharacterProfile WithAntagPreferences(IReadOnlyList<string> antagPreferences)
|
||||
{
|
||||
return new HumanoidCharacterProfile(
|
||||
Name,
|
||||
Age,
|
||||
Sex,
|
||||
Appearance,
|
||||
_jobPriorities,
|
||||
PreferenceUnavailable,
|
||||
new List<string>(antagPreferences));
|
||||
}
|
||||
|
||||
public HumanoidCharacterProfile WithAntagPreference(string antagId, bool pref)
|
||||
{
|
||||
var list = new List<string>(_antagPreferences);
|
||||
if(pref)
|
||||
{
|
||||
if(!list.Contains(antagId))
|
||||
{
|
||||
list.Add(antagId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(list.Contains(antagId))
|
||||
{
|
||||
list.Remove(antagId);
|
||||
}
|
||||
}
|
||||
return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, _jobPriorities, PreferenceUnavailable, list);
|
||||
}
|
||||
|
||||
public string Summary =>
|
||||
@@ -119,6 +160,7 @@ namespace Content.Shared.Preferences
|
||||
if (Sex != other.Sex) return false;
|
||||
if (PreferenceUnavailable != other.PreferenceUnavailable) return false;
|
||||
if (!_jobPriorities.SequenceEqual(other._jobPriorities)) return false;
|
||||
if (!_antagPreferences.SequenceEqual(other._antagPreferences)) return false;
|
||||
return Appearance.MemberwiseEquals(other.Appearance);
|
||||
}
|
||||
}
|
||||
|
||||
48
Content.Shared/Roles/AntagPrototype.cs
Normal file
48
Content.Shared/Roles/AntagPrototype.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Content.Shared.Antags
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes information for a single antag.
|
||||
/// </summary>
|
||||
[Prototype("antag")]
|
||||
public class AntagPrototype : IPrototype, IIndexedPrototype
|
||||
{
|
||||
public string ID { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of this antag as displayed to players.
|
||||
/// </summary>
|
||||
public string Name { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The antag's objective, displayed at round-start to the player.
|
||||
/// </summary>
|
||||
public string Objective { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the antag role is one of the bad guys.
|
||||
/// </summary>
|
||||
public bool Antagonist { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the player can set the antag role in antag preferences.
|
||||
/// </summary>
|
||||
public bool SetPreference { get; private set; }
|
||||
|
||||
public void LoadFrom(YamlMappingNode mapping)
|
||||
{
|
||||
ID = mapping.GetNode("id").AsString();
|
||||
Name = Loc.GetString(mapping.GetNode("name").ToString());
|
||||
Objective = mapping.GetNode("objective").ToString();
|
||||
Antagonist = mapping.GetNode("antagonist").AsBool();
|
||||
SetPreference = mapping.GetNode("setPreference").AsBool();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user