Re-organize all projects (#4166)
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
376
Content.Shared/Interaction/Helpers/SharedUnoccludedExtensions.cs
Normal file
376
Content.Shared/Interaction/Helpers/SharedUnoccludedExtensions.cs
Normal 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
|
||||
}
|
||||
}
|
||||
59
Content.Shared/Interaction/IActivate.cs
Normal file
59
Content.Shared/Interaction/IActivate.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
92
Content.Shared/Interaction/IAfterInteract.cs
Normal file
92
Content.Shared/Interaction/IAfterInteract.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
56
Content.Shared/Interaction/IInteractHand.cs
Normal file
56
Content.Shared/Interaction/IInteractHand.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
81
Content.Shared/Interaction/IInteractUsing.cs
Normal file
81
Content.Shared/Interaction/IInteractUsing.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
72
Content.Shared/Interaction/IRangedInteract.cs
Normal file
72
Content.Shared/Interaction/IRangedInteract.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Content.Shared/Interaction/ITargetedInteractEventArgs.cs
Normal file
18
Content.Shared/Interaction/ITargetedInteractEventArgs.cs
Normal 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; }
|
||||
|
||||
}
|
||||
}
|
||||
55
Content.Shared/Interaction/IUse.cs
Normal file
55
Content.Shared/Interaction/IUse.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
336
Content.Shared/Interaction/SharedInteractionSystem.cs
Normal file
336
Content.Shared/Interaction/SharedInteractionSystem.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user