Re-organize all projects (#4166)

This commit is contained in:
DrSmugleaf
2021-06-09 22:19:39 +02:00
committed by GitHub
parent 9f50e4061b
commit ff1a2d97ea
1773 changed files with 5258 additions and 5508 deletions

View File

@@ -0,0 +1,466 @@
#nullable enable
using Content.Shared.DragDrop;
using Content.Shared.Physics;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using static Content.Shared.Interaction.SharedInteractionSystem;
namespace Content.Shared.Interaction.Helpers
{
public static class SharedUnobstructedExtensions
{
private static SharedInteractionSystem SharedInteractionSystem => EntitySystem.Get<SharedInteractionSystem>();
#region Entities
public static bool InRangeUnobstructed(
this IEntity origin,
IEntity other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
return SharedInteractionSystem.InRangeUnobstructed(origin, other, range, collisionMask, predicate,
ignoreInsideBlocker, popup);
}
public static bool InRangeUnobstructed(
this IEntity origin,
IComponent other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
return SharedInteractionSystem.InRangeUnobstructed(origin, other, range, collisionMask, predicate,
ignoreInsideBlocker, popup);
}
public static bool InRangeUnobstructed(
this IEntity origin,
IContainer other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
var otherEntity = other.Owner;
return SharedInteractionSystem.InRangeUnobstructed(origin, otherEntity, range, collisionMask, predicate,
ignoreInsideBlocker, popup);
}
public static bool InRangeUnobstructed(
this IEntity origin,
EntityCoordinates other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
return SharedInteractionSystem.InRangeUnobstructed(origin, other, range, collisionMask, predicate,
ignoreInsideBlocker, popup);
}
public static bool InRangeUnobstructed(
this IEntity origin,
MapCoordinates other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
return SharedInteractionSystem.InRangeUnobstructed(origin, other, range, collisionMask, predicate,
ignoreInsideBlocker, popup);
}
#endregion
#region Components
public static bool InRangeUnobstructed(
this IComponent origin,
IEntity other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
var originEntity = origin.Owner;
return SharedInteractionSystem.InRangeUnobstructed(originEntity, other, range, collisionMask, predicate,
ignoreInsideBlocker, popup);
}
public static bool InRangeUnobstructed(
this IComponent origin,
IComponent other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
var originEntity = origin.Owner;
return SharedInteractionSystem.InRangeUnobstructed(originEntity, other, range, collisionMask, predicate,
ignoreInsideBlocker, popup);
}
public static bool InRangeUnobstructed(
this IComponent origin,
IContainer other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
var originEntity = origin.Owner;
var otherEntity = other.Owner;
return SharedInteractionSystem.InRangeUnobstructed(originEntity, otherEntity, range, collisionMask, predicate,
ignoreInsideBlocker, popup);
}
public static bool InRangeUnobstructed(
this IComponent origin,
EntityCoordinates other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
var originEntity = origin.Owner;
return SharedInteractionSystem.InRangeUnobstructed(originEntity, other, range, collisionMask, predicate,
ignoreInsideBlocker, popup);
}
public static bool InRangeUnobstructed(
this IComponent origin,
MapCoordinates other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
var originEntity = origin.Owner;
return SharedInteractionSystem.InRangeUnobstructed(originEntity, other, range, collisionMask, predicate,
ignoreInsideBlocker, popup);
}
#endregion
#region Containers
public static bool InRangeUnobstructed(
this IContainer origin,
IEntity other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false)
{
var originEntity = origin.Owner;
return SharedInteractionSystem.InRangeUnobstructed(originEntity, other, range, collisionMask, predicate,
ignoreInsideBlocker);
}
public static bool InRangeUnobstructed(
this IContainer origin,
IComponent other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
var originEntity = origin.Owner;
return SharedInteractionSystem.InRangeUnobstructed(originEntity, other, range, collisionMask, predicate,
ignoreInsideBlocker, popup);
}
public static bool InRangeUnobstructed(
this IContainer origin,
IContainer other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
var originEntity = origin.Owner;
var otherEntity = other.Owner;
return SharedInteractionSystem.InRangeUnobstructed(originEntity, otherEntity, range, collisionMask,
predicate, ignoreInsideBlocker, popup);
}
public static bool InRangeUnobstructed(
this IContainer origin,
EntityCoordinates other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
var originEntity = origin.Owner;
return SharedInteractionSystem.InRangeUnobstructed(originEntity, other, range, collisionMask, predicate,
ignoreInsideBlocker, popup);
}
public static bool InRangeUnobstructed(
this IContainer origin,
MapCoordinates other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
var originEntity = origin.Owner;
return SharedInteractionSystem.InRangeUnobstructed(originEntity, other, range, collisionMask, predicate,
ignoreInsideBlocker, popup);
}
#endregion
#region EntityCoordinates
public static bool InRangeUnobstructed(
this EntityCoordinates origin,
IEntity other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false)
{
var originPosition = origin.ToMap(other.EntityManager);
var otherPosition = other.Transform.MapPosition;
return SharedInteractionSystem.InRangeUnobstructed(originPosition, otherPosition, range, collisionMask,
predicate, ignoreInsideBlocker);
}
public static bool InRangeUnobstructed(
this EntityCoordinates origin,
IComponent other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false)
{
var originPosition = origin.ToMap(other.Owner.EntityManager);
var otherPosition = other.Owner.Transform.MapPosition;
return SharedInteractionSystem.InRangeUnobstructed(originPosition, otherPosition, range, collisionMask,
predicate, ignoreInsideBlocker);
}
public static bool InRangeUnobstructed(
this EntityCoordinates origin,
IContainer other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false)
{
var originPosition = origin.ToMap(other.Owner.EntityManager);
var otherPosition = other.Owner.Transform.MapPosition;
return SharedInteractionSystem.InRangeUnobstructed(originPosition, otherPosition, range, collisionMask,
predicate, ignoreInsideBlocker);
}
public static bool InRangeUnobstructed(
this EntityCoordinates origin,
EntityCoordinates other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
IEntityManager? entityManager = null)
{
entityManager ??= IoCManager.Resolve<IEntityManager>();
var originPosition = origin.ToMap(entityManager);
var otherPosition = other.ToMap(entityManager);
return SharedInteractionSystem.InRangeUnobstructed(originPosition, otherPosition, range, collisionMask,
predicate, ignoreInsideBlocker);
}
public static bool InRangeUnobstructed(
this EntityCoordinates origin,
MapCoordinates other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
IEntityManager? entityManager = null)
{
entityManager ??= IoCManager.Resolve<IEntityManager>();
var originPosition = origin.ToMap(entityManager);
return SharedInteractionSystem.InRangeUnobstructed(originPosition, other, range, collisionMask, predicate,
ignoreInsideBlocker);
}
#endregion
#region MapCoordinates
public static bool InRangeUnobstructed(
this MapCoordinates origin,
IEntity other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false)
{
var otherPosition = other.Transform.MapPosition;
return SharedInteractionSystem.InRangeUnobstructed(origin, otherPosition, range, collisionMask, predicate,
ignoreInsideBlocker);
}
public static bool InRangeUnobstructed(
this MapCoordinates origin,
IComponent other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false)
{
var otherPosition = other.Owner.Transform.MapPosition;
return SharedInteractionSystem.InRangeUnobstructed(origin, otherPosition, range, collisionMask, predicate,
ignoreInsideBlocker);
}
public static bool InRangeUnobstructed(
this MapCoordinates origin,
IContainer other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false)
{
var otherPosition = other.Owner.Transform.MapPosition;
return SharedInteractionSystem.InRangeUnobstructed(origin, otherPosition, range, collisionMask, predicate,
ignoreInsideBlocker);
}
public static bool InRangeUnobstructed(
this MapCoordinates origin,
EntityCoordinates other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
IEntityManager? entityManager = null)
{
entityManager ??= IoCManager.Resolve<IEntityManager>();
var otherPosition = other.ToMap(entityManager);
return SharedInteractionSystem.InRangeUnobstructed(origin, otherPosition, range, collisionMask, predicate,
ignoreInsideBlocker);
}
public static bool InRangeUnobstructed(
this MapCoordinates origin,
MapCoordinates other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false)
{
return SharedInteractionSystem.InRangeUnobstructed(origin, other, range, collisionMask, predicate,
ignoreInsideBlocker);
}
#endregion
#region EventArgs
public static bool InRangeUnobstructed(
this ITargetedInteractEventArgs args,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
return SharedInteractionSystem.InRangeUnobstructed(args.User, args.Target, range, collisionMask, predicate, ignoreInsideBlocker, popup);
}
public static bool InRangeUnobstructed(
this AfterInteractEventArgs args,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
var user = args.User;
var target = args.Target;
if (target == null)
return SharedInteractionSystem.InRangeUnobstructed(user, args.ClickLocation, range, collisionMask, predicate, ignoreInsideBlocker, popup);
else
return SharedInteractionSystem.InRangeUnobstructed(user, target, range, collisionMask, predicate, ignoreInsideBlocker, popup);
}
#endregion
#region EntityEventArgs
public static bool InRangeUnobstructed(
this DragDropEvent args,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
var user = args.User;
var dropped = args.Dragged;
var target = args.Target;
if (!SharedInteractionSystem.InRangeUnobstructed(user, target, range, collisionMask, predicate, ignoreInsideBlocker, popup))
return false;
if (!SharedInteractionSystem.InRangeUnobstructed(user, dropped, range, collisionMask, predicate, ignoreInsideBlocker, popup))
return false;
return true;
}
public static bool InRangeUnobstructed(
this AfterInteractEvent args,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
var user = args.User;
var target = args.Target;
if (target == null)
return SharedInteractionSystem.InRangeUnobstructed(user, args.ClickLocation, range, collisionMask, predicate, ignoreInsideBlocker, popup);
else
return SharedInteractionSystem.InRangeUnobstructed(user, target, range, collisionMask, predicate, ignoreInsideBlocker, popup);
}
#endregion
}
}

View File

@@ -0,0 +1,376 @@
#nullable enable
using Content.Shared.DragDrop;
using Content.Shared.Examine;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using static Content.Shared.Examine.ExamineSystemShared;
using static Content.Shared.Interaction.SharedInteractionSystem;
namespace Content.Shared.Interaction.Helpers
{
public static class SharedUnoccludedExtensions
{
#region Entities
public static bool InRangeUnOccluded(
this IEntity origin,
IEntity other,
float range = ExamineRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
return ExamineSystemShared.InRangeUnOccluded(origin, other, range, predicate, ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this IEntity origin,
IComponent other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
return ExamineSystemShared.InRangeUnOccluded(origin, other, range, predicate, ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this IEntity origin,
IContainer other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var otherEntity = other.Owner;
return ExamineSystemShared.InRangeUnOccluded(origin, otherEntity, range, predicate, ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this IEntity origin,
EntityCoordinates other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
return ExamineSystemShared.InRangeUnOccluded(origin, other, range, predicate, ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this IEntity origin,
MapCoordinates other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
return ExamineSystemShared.InRangeUnOccluded(origin, other, range, predicate, ignoreInsideBlocker);
}
#endregion
#region Components
public static bool InRangeUnOccluded(
this IComponent origin,
IEntity other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var originEntity = origin.Owner;
return ExamineSystemShared.InRangeUnOccluded(originEntity, other, range, predicate, ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this IComponent origin,
IComponent other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var originEntity = origin.Owner;
return ExamineSystemShared.InRangeUnOccluded(originEntity, other, range, predicate, ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this IComponent origin,
IContainer other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var originEntity = origin.Owner;
var otherEntity = other.Owner;
return ExamineSystemShared.InRangeUnOccluded(originEntity, otherEntity, range, predicate,
ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this IComponent origin,
EntityCoordinates other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var originEntity = origin.Owner;
return ExamineSystemShared.InRangeUnOccluded(originEntity, other, range, predicate, ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this IComponent origin,
MapCoordinates other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var originEntity = origin.Owner;
return ExamineSystemShared.InRangeUnOccluded(originEntity, other, range, predicate,
ignoreInsideBlocker);
}
#endregion
#region Containers
public static bool InRangeUnOccluded(
this IContainer origin,
IEntity other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var originEntity = origin.Owner;
return ExamineSystemShared.InRangeUnOccluded(originEntity, other, range, predicate,
ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this IContainer origin,
IComponent other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var originEntity = origin.Owner;
return ExamineSystemShared.InRangeUnOccluded(originEntity, other, range, predicate, ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this IContainer origin,
IContainer other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var originEntity = origin.Owner;
var otherEntity = other.Owner;
return ExamineSystemShared.InRangeUnOccluded(originEntity, otherEntity, range, predicate,
ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this IContainer origin,
EntityCoordinates other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var originEntity = origin.Owner;
return ExamineSystemShared.InRangeUnOccluded(originEntity, other, range, predicate, ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this IContainer origin,
MapCoordinates other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var originEntity = origin.Owner;
return ExamineSystemShared.InRangeUnOccluded(originEntity, other, range, predicate, ignoreInsideBlocker);
}
#endregion
#region EntityCoordinates
public static bool InRangeUnOccluded(
this EntityCoordinates origin,
IEntity other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var originPosition = origin.ToMap(other.EntityManager);
var otherPosition = other.Transform.MapPosition;
return ExamineSystemShared.InRangeUnOccluded(originPosition, otherPosition, range,
predicate, ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this EntityCoordinates origin,
IComponent other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var originPosition = origin.ToMap(other.Owner.EntityManager);
var otherPosition = other.Owner.Transform.MapPosition;
return ExamineSystemShared.InRangeUnOccluded(originPosition, otherPosition, range,
predicate, ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this EntityCoordinates origin,
IContainer other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var originPosition = origin.ToMap(other.Owner.EntityManager);
var otherPosition = other.Owner.Transform.MapPosition;
return ExamineSystemShared.InRangeUnOccluded(originPosition, otherPosition, range,
predicate, ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this EntityCoordinates origin,
EntityCoordinates other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true,
IEntityManager? entityManager = null)
{
entityManager ??= IoCManager.Resolve<IEntityManager>();
var originPosition = origin.ToMap(entityManager);
var otherPosition = other.ToMap(entityManager);
return ExamineSystemShared.InRangeUnOccluded(originPosition, otherPosition, range,
predicate, ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this EntityCoordinates origin,
MapCoordinates other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true,
IEntityManager? entityManager = null)
{
entityManager ??= IoCManager.Resolve<IEntityManager>();
var originPosition = origin.ToMap(entityManager);
return ExamineSystemShared.InRangeUnOccluded(originPosition, other, range, predicate,
ignoreInsideBlocker);
}
#endregion
#region MapCoordinates
public static bool InRangeUnOccluded(
this MapCoordinates origin,
IEntity other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var otherPosition = other.Transform.MapPosition;
return ExamineSystemShared.InRangeUnOccluded(origin, otherPosition, range, predicate,
ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this MapCoordinates origin,
IComponent other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var otherPosition = other.Owner.Transform.MapPosition;
return ExamineSystemShared.InRangeUnOccluded(origin, otherPosition, range, predicate,
ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this MapCoordinates origin,
IContainer other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
var otherPosition = other.Owner.Transform.MapPosition;
return ExamineSystemShared.InRangeUnOccluded(origin, otherPosition, range, predicate,
ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this MapCoordinates origin,
EntityCoordinates other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true,
IEntityManager? entityManager = null)
{
entityManager ??= IoCManager.Resolve<IEntityManager>();
var otherPosition = other.ToMap(entityManager);
return ExamineSystemShared.InRangeUnOccluded(origin, otherPosition, range, predicate,
ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this MapCoordinates origin,
MapCoordinates other,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
return ExamineSystemShared.InRangeUnOccluded(origin, other, range, predicate,
ignoreInsideBlocker);
}
#endregion
#region EventArgs
public static bool InRangeUnOccluded(
this ITargetedInteractEventArgs args,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
return ExamineSystemShared.InRangeUnOccluded(args, range, predicate,
ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this DragDropEvent args,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
return ExamineSystemShared.InRangeUnOccluded(args, range, predicate,
ignoreInsideBlocker);
}
public static bool InRangeUnOccluded(
this AfterInteractEventArgs args,
float range = InteractionRange,
Ignored? predicate = null,
bool ignoreInsideBlocker = true)
{
return ExamineSystemShared.InRangeUnOccluded(args, range, predicate,
ignoreInsideBlocker);
}
#endregion
}
}

View File

@@ -0,0 +1,59 @@
using System;
using JetBrains.Annotations;
using Robust.Shared.Analyzers;
using Robust.Shared.GameObjects;
namespace Content.Shared.Interaction
{
/// <summary>
/// This interface gives components behavior when being activated (by default,
/// this is done via the "E" key) when the user is in range and has unobstructed access to the target entity
/// (allows inside blockers). This includes activating an object in the world as well as activating an
/// object in inventory. Unlike IUse, this can be performed on entities that aren't in the active hand,
/// even when the active hand is currently holding something else.
/// </summary>
[RequiresExplicitImplementation]
public interface IActivate
{
/// <summary>
/// Called when this component is activated by another entity who is in range.
/// </summary>
[Obsolete("Use ActivateInWorldMessage instead")]
void Activate(ActivateEventArgs eventArgs);
}
public class ActivateEventArgs : EventArgs, ITargetedInteractEventArgs
{
public ActivateEventArgs(IEntity user, IEntity target)
{
User = user;
Target = target;
}
public IEntity User { get; }
public IEntity Target { get; }
}
/// <summary>
/// Raised when an entity is activated in the world.
/// </summary>
[PublicAPI]
public class ActivateInWorldEvent : HandledEntityEventArgs
{
/// <summary>
/// Entity that activated the target world entity.
/// </summary>
public IEntity User { get; }
/// <summary>
/// Entity that was activated in the world.
/// </summary>
public IEntity Target { get; }
public ActivateInWorldEvent(IEntity user, IEntity target)
{
User = user;
Target = target;
}
}
}

View File

@@ -0,0 +1,92 @@
#nullable enable
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Robust.Shared.Analyzers;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
#nullable enable
namespace Content.Shared.Interaction
{
/// <summary>
/// This interface gives components a behavior when their entity is in the active hand, when
/// clicking on another object and no interaction occurs, at any range. This includes
/// clicking on an object in the world as well as clicking on an object in inventory.
/// </summary>
[RequiresExplicitImplementation]
public interface IAfterInteract
{
/// <summary>
/// The interaction priority. Higher numbers get called first.
/// </summary>
/// <value>Priority defaults to 0</value>
int Priority => 0;
/// <summary>
/// Called when we interact with nothing, or when we interact with an entity out of range that has no behavior
/// </summary>
[Obsolete("Use AfterInteractMessage instead")]
Task<bool> AfterInteract(AfterInteractEventArgs eventArgs);
}
public class AfterInteractEventArgs : EventArgs
{
public IEntity User { get; }
public EntityCoordinates ClickLocation { get; }
public IEntity? Target { get; }
public bool CanReach { get; }
public AfterInteractEventArgs(IEntity user, EntityCoordinates clickLocation, IEntity? target, bool canReach)
{
User = user;
ClickLocation = clickLocation;
Target = target;
CanReach = canReach;
}
}
/// <summary>
/// Raised directed on the used object when clicking on another object and no attack event was handled.
/// </summary>
[PublicAPI]
public class AfterInteractEvent : HandledEntityEventArgs
{
/// <summary>
/// Entity that triggered the interaction.
/// </summary>
public IEntity User { get; }
/// <summary>
/// Entity that the user used to interact.
/// </summary>
public IEntity Used { get; }
/// <summary>
/// Entity that was interacted on. This can be null if the attack did not click on an entity.
/// </summary>
public IEntity? Target { get; }
/// <summary>
/// Location that the user clicked outside of their interaction range.
/// </summary>
public EntityCoordinates ClickLocation { get; }
/// <summary>
/// Is the click location close enough to reach by the player? This does not check for obstructions, just that the target is within
/// reach radius around the user.
/// </summary>
public bool CanReach { get; }
public AfterInteractEvent(IEntity user, IEntity used, IEntity? target,
EntityCoordinates clickLocation, bool canReach)
{
User = user;
Used = used;
Target = target;
ClickLocation = clickLocation;
CanReach = canReach;
}
}
}

View File

@@ -0,0 +1,56 @@
using System;
using JetBrains.Annotations;
using Robust.Shared.Analyzers;
using Robust.Shared.GameObjects;
namespace Content.Shared.Interaction
{
/// <summary>
/// This interface gives components behavior when being clicked on by a user with an empty hand
/// who is in range and has unobstructed reach of the target entity (allows inside blockers).
/// </summary>
[RequiresExplicitImplementation]
public interface IInteractHand
{
/// <summary>
/// Called when a player directly interacts with an empty hand when user is in range of the target entity.
/// </summary>
[Obsolete("Use InteractHandEvent instead")]
bool InteractHand(InteractHandEventArgs eventArgs);
}
public class InteractHandEventArgs : EventArgs, ITargetedInteractEventArgs
{
public InteractHandEventArgs(IEntity user, IEntity target)
{
User = user;
Target = target;
}
public IEntity User { get; }
public IEntity Target { get; }
}
/// <summary>
/// Raised directed on a target entity when it is interacted with by a user with an empty hand.
/// </summary>
[PublicAPI]
public class InteractHandEvent : HandledEntityEventArgs
{
/// <summary>
/// Entity that triggered the interaction.
/// </summary>
public IEntity User { get; }
/// <summary>
/// Entity that was interacted on.
/// </summary>
public IEntity Target { get; }
public InteractHandEvent(IEntity user, IEntity target)
{
User = user;
Target = target;
}
}
}

View File

@@ -0,0 +1,81 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Robust.Shared.Analyzers;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
namespace Content.Shared.Interaction
{
/// <summary>
/// This interface gives components behavior when their entity is clicked on by a user with an object in their hand
/// who is in range and has unobstructed reach of the target entity (allows inside blockers). This includes
/// clicking on an object in the world as well as clicking on an object in inventory.
/// </summary>
[RequiresExplicitImplementation]
public interface IInteractUsing
{
/// <summary>
/// The interaction priority. Higher numbers get called first.
/// </summary>
/// <value>Priority defaults to 0</value>
int Priority => 0;
/// <summary>
/// Called when using one object on another when user is in range of the target entity.
/// </summary>
[Obsolete("Use InteractUsingMessage instead")]
Task<bool> InteractUsing(InteractUsingEventArgs eventArgs);
}
public class InteractUsingEventArgs : EventArgs, ITargetedInteractEventArgs
{
public InteractUsingEventArgs(IEntity user, EntityCoordinates clickLocation, IEntity @using, IEntity target)
{
User = user;
ClickLocation = clickLocation;
Using = @using;
Target = target;
}
public IEntity User { get; }
public EntityCoordinates ClickLocation { get; }
public IEntity Using { get; }
public IEntity Target { get; }
}
/// <summary>
/// Raised when a target entity is interacted with by a user while holding an object in their hand.
/// </summary>
[PublicAPI]
public class InteractUsingEvent : HandledEntityEventArgs
{
/// <summary>
/// Entity that triggered the interaction.
/// </summary>
public IEntity User { get; }
/// <summary>
/// Entity that the user used to interact.
/// </summary>
public IEntity Used { get; }
/// <summary>
/// Entity that was interacted on.
/// </summary>
public IEntity Target { get; }
/// <summary>
/// The original location that was clicked by the user.
/// </summary>
public EntityCoordinates ClickLocation { get; }
public InteractUsingEvent(IEntity user, IEntity used, IEntity target, EntityCoordinates clickLocation)
{
User = user;
Used = used;
Target = target;
ClickLocation = clickLocation;
}
}
}

View File

@@ -0,0 +1,72 @@
using System;
using JetBrains.Annotations;
using Robust.Shared.Analyzers;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
namespace Content.Shared.Interaction
{
/// <summary>
/// This interface gives components behavior when being clicked on by a user with an object
/// outside the range of direct use
/// </summary>
[RequiresExplicitImplementation]
public interface IRangedInteract
{
/// <summary>
/// Called when we try to interact with an entity out of range
/// </summary>
[Obsolete("Use RangedInteractMessage instead")]
bool RangedInteract(RangedInteractEventArgs eventArgs);
}
[PublicAPI]
public class RangedInteractEventArgs : EventArgs
{
public RangedInteractEventArgs(IEntity user, IEntity @using, EntityCoordinates clickLocation)
{
User = user;
Using = @using;
ClickLocation = clickLocation;
}
public IEntity User { get; }
public IEntity Using { get; }
public EntityCoordinates ClickLocation { get; }
}
/// <summary>
/// Raised when an entity is interacted with that is out of the user entity's range of direct use.
/// </summary>
[PublicAPI]
public class RangedInteractEvent : HandledEntityEventArgs
{
/// <summary>
/// Entity that triggered the interaction.
/// </summary>
public IEntity User { get; }
/// <summary>
/// Entity that the user used to interact.
/// </summary>
public IEntity Used { get; }
/// <summary>
/// Entity that was interacted on.
/// </summary>
public IEntity Target { get; }
/// <summary>
/// Location that the user clicked outside of their interaction range.
/// </summary>
public EntityCoordinates ClickLocation { get; }
public RangedInteractEvent(IEntity user, IEntity used, IEntity target, EntityCoordinates clickLocation)
{
User = user;
Used = used;
Target = target;
ClickLocation = clickLocation;
}
}
}

View File

@@ -0,0 +1,18 @@
#nullable enable
using Robust.Shared.GameObjects;
namespace Content.Shared.Interaction
{
public interface ITargetedInteractEventArgs
{
/// <summary>
/// Performer of the attack
/// </summary>
IEntity User { get; }
/// <summary>
/// Target of the attack
/// </summary>
IEntity Target { get; }
}
}

View File

@@ -0,0 +1,55 @@
using System;
using JetBrains.Annotations;
using Robust.Shared.Analyzers;
using Robust.Shared.GameObjects;
namespace Content.Shared.Interaction
{
/// <summary>
/// This interface gives components behavior when using the entity in your active hand
/// (done by clicking the entity in the active hand or pressing the keybind that defaults to Z).
/// </summary>
[RequiresExplicitImplementation]
public interface IUse
{
/// <summary>
/// Called when we activate an object we are holding to use it
/// </summary>
/// <returns></returns>
[Obsolete("Use UseInHandMessage instead")]
bool UseEntity(UseEntityEventArgs eventArgs);
}
public class UseEntityEventArgs : EventArgs
{
public UseEntityEventArgs(IEntity user)
{
User = user;
}
public IEntity User { get; }
}
/// <summary>
/// Raised when using the entity in your hands.
/// </summary>
[PublicAPI]
public class UseInHandEvent : HandledEntityEventArgs
{
/// <summary>
/// Entity holding the item in their hand.
/// </summary>
public IEntity User { get; }
/// <summary>
/// Item that was used.
/// </summary>
public IEntity Used { get; }
public UseInHandEvent(IEntity user, IEntity used)
{
User = user;
Used = used;
}
}
}

View File

@@ -0,0 +1,336 @@
using System.Linq;
using Content.Shared.Notification;
using Content.Shared.Physics;
using JetBrains.Annotations;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Broadphase;
namespace Content.Shared.Interaction
{
/// <summary>
/// Governs interactions during clicking on entities
/// </summary>
[UsedImplicitly]
public class SharedInteractionSystem : EntitySystem
{
public const float InteractionRange = 2;
public const float InteractionRangeSquared = InteractionRange * InteractionRange;
public delegate bool Ignored(IEntity entity);
/// <summary>
/// Traces a ray from coords to otherCoords and returns the length
/// of the vector between coords and the ray's first hit.
/// </summary>
/// <param name="origin">Set of coordinates to use.</param>
/// <param name="other">Other set of coordinates to use.</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>
/// <returns>Length of resulting ray.</returns>
public float UnobstructedDistance(
MapCoordinates origin,
MapCoordinates other,
int collisionMask = (int) CollisionGroup.Impassable,
Ignored? predicate = null)
{
var dir = other.Position - origin.Position;
if (dir.LengthSquared.Equals(0f)) return 0f;
predicate ??= _ => false;
var ray = new CollisionRay(origin.Position, dir.Normalized, collisionMask);
var rayResults = Get<SharedBroadPhaseSystem>().IntersectRayWithPredicate(origin.MapId, ray, dir.Length, predicate.Invoke, false).ToList();
if (rayResults.Count == 0) return dir.Length;
return (rayResults[0].HitPos - origin.Position).Length;
}
/// <summary>
/// Traces a ray from coords to otherCoords and returns the length
/// of the vector between coords and the ray's first hit.
/// </summary>
/// <param name="origin">Set of coordinates to use.</param>
/// <param name="other">Other set of coordinates to use.</param>
/// <param name="collisionMask">The mask to check for collisions</param>
/// <param name="ignoredEnt">
/// The entity to be ignored when checking for collisions.
/// </param>
/// <returns>Length of resulting ray.</returns>
public float UnobstructedDistance(
MapCoordinates origin,
MapCoordinates other,
int collisionMask = (int) CollisionGroup.Impassable,
IEntity? ignoredEnt = null)
{
var predicate = ignoredEnt == null
? null
: (Ignored) (e => e == ignoredEnt);
return UnobstructedDistance(origin, other, collisionMask, predicate);
}
/// <summary>
/// Checks that these coordinates are within a certain distance without any
/// entity that matches the collision mask obstructing them.
/// If the <paramref name="range"/> is zero or negative,
/// this method will only check if nothing obstructs the two sets
/// of coordinates.
/// </summary>
/// <param name="origin">Set of coordinates to use.</param>
/// <param name="other">Other set of coordinates to use.</param>
/// <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="ignoreInsideBlocker">
/// If true and <see cref="origin"/> or <see cref="other"/> 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 origin,
MapCoordinates other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false)
{
if (!origin.InRange(other, range)) return false;
var dir = other.Position - origin.Position;
if (dir.LengthSquared.Equals(0f)) return true;
if (range > 0f && !(dir.LengthSquared <= range * range)) return false;
predicate ??= _ => false;
var ray = new CollisionRay(origin.Position, dir.Normalized, (int) collisionMask);
var rayResults = Get<SharedBroadPhaseSystem>().IntersectRayWithPredicate(origin.MapId, ray, dir.Length, predicate.Invoke, false).ToList();
if (rayResults.Count == 0) return true;
if (!ignoreInsideBlocker) return false;
foreach (var result in rayResults)
{
if (!result.HitEntity.TryGetComponent(out IPhysBody? p))
{
continue;
}
var bBox = p.GetWorldAABB();
if (bBox.Contains(origin.Position) || bBox.Contains(other.Position))
{
continue;
}
return false;
}
return true;
}
/// <summary>
/// Checks that two entities are within a certain distance without any
/// entity that matches the collision mask obstructing them.
/// If the <paramref name="range"/> is zero or negative,
/// this method will only check if nothing obstructs the two entities.
/// </summary>
/// <param name="origin">The first entity to use.</param>
/// <param name="other">Other entity to use.</param>
/// <param name="range">
/// Maximum distance between the two entities.
/// </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="ignoreInsideBlocker">
/// If true and <see cref="origin"/> or <see cref="other"/> 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>
/// <param name="popup">
/// Whether or not to popup a feedback message on the origin entity for
/// it to see.
/// </param>
/// <returns>
/// True if the two points are within a given range without being obstructed.
/// </returns>
public bool InRangeUnobstructed(
IEntity origin,
IEntity other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
predicate ??= e => e == origin || e == other;
return InRangeUnobstructed(origin, other.Transform.MapPosition, range, collisionMask, predicate, ignoreInsideBlocker, popup);
}
/// <summary>
/// Checks that an entity and a component are within a certain
/// distance without any entity that matches the collision mask
/// obstructing them.
/// If the <paramref name="range"/> is zero or negative,
/// this method will only check if nothing obstructs the entity and component.
/// </summary>
/// <param name="origin">The entity to use.</param>
/// <param name="other">The component to use.</param>
/// <param name="range">
/// Maximum distance between the entity and component.
/// </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="ignoreInsideBlocker">
/// If true and <see cref="origin"/> or <see cref="other"/> 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>
/// <param name="popup">
/// Whether or not to popup a feedback message on the origin entity for
/// it to see.
/// </param>
/// <returns>
/// True if the two points are within a given range without being obstructed.
/// </returns>
public bool InRangeUnobstructed(
IEntity origin,
IComponent other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
return InRangeUnobstructed(origin, other.Owner, range, collisionMask, predicate, ignoreInsideBlocker, popup);
}
/// <summary>
/// Checks that an entity and a set of grid coordinates are within a certain
/// distance without any entity that matches the collision mask
/// obstructing them.
/// If the <paramref name="range"/> is zero or negative,
/// this method will only check if nothing obstructs the entity and component.
/// </summary>
/// <param name="origin">The entity to use.</param>
/// <param name="other">The grid coordinates to use.</param>
/// <param name="range">
/// Maximum distance between the two entity and set of grid 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="ignoreInsideBlocker">
/// If true and <see cref="origin"/> or <see cref="other"/> 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>
/// <param name="popup">
/// Whether or not to popup a feedback message on the origin entity for
/// it to see.
/// </param>
/// <returns>
/// True if the two points are within a given range without being obstructed.
/// </returns>
public bool InRangeUnobstructed(
IEntity origin,
EntityCoordinates other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
return InRangeUnobstructed(origin, other.ToMap(EntityManager), range, collisionMask, predicate, ignoreInsideBlocker, popup);
}
/// <summary>
/// Checks that an entity and a set of map coordinates are within a certain
/// distance without any entity that matches the collision mask
/// obstructing them.
/// If the <paramref name="range"/> is zero or negative,
/// this method will only check if nothing obstructs the entity and component.
/// </summary>
/// <param name="origin">The entity to use.</param>
/// <param name="other">The map coordinates to use.</param>
/// <param name="range">
/// Maximum distance between the two entity and set of map 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="ignoreInsideBlocker">
/// If true and <see cref="origin"/> or <see cref="other"/> 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>
/// <param name="popup">
/// Whether or not to popup a feedback message on the origin entity for
/// it to see.
/// </param>
/// <returns>
/// True if the two points are within a given range without being obstructed.
/// </returns>
public bool InRangeUnobstructed(
IEntity origin,
MapCoordinates other,
float range = InteractionRange,
CollisionGroup collisionMask = CollisionGroup.Impassable,
Ignored? predicate = null,
bool ignoreInsideBlocker = false,
bool popup = false)
{
var originPosition = origin.Transform.MapPosition;
predicate ??= e => e == origin;
var inRange = InRangeUnobstructed(originPosition, other, range, collisionMask, predicate, ignoreInsideBlocker);
if (!inRange && popup)
{
var message = Robust.Shared.Localization.Loc.GetString("You can't reach there!");
origin.PopupMessage(message);
}
return inRange;
}
}
}