@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.GameObjects.Components.Timing;
|
||||
@@ -28,26 +28,26 @@ using Robust.Shared.Players;
|
||||
namespace Content.Server.GameObjects.EntitySystems
|
||||
{
|
||||
/// <summary>
|
||||
/// This interface gives components behavior when being clicked on or "attacked" by a user with an object in their hand
|
||||
/// This interface gives components behavior when being 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).
|
||||
/// </summary>
|
||||
public interface IAttackBy
|
||||
public interface IInteractUsing
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when using one object on another when user is in range of the target entity.
|
||||
/// </summary>
|
||||
bool AttackBy(AttackByEventArgs eventArgs);
|
||||
bool InteractUsing(InteractUsingEventArgs eventArgs);
|
||||
}
|
||||
|
||||
public class AttackByEventArgs : EventArgs, ITargetedAttackEventArgs
|
||||
public class InteractUsingEventArgs : EventArgs, ITargetedInteractEventArgs
|
||||
{
|
||||
public IEntity User { get; set; }
|
||||
public GridCoordinates ClickLocation { get; set; }
|
||||
public IEntity AttackWith { get; set; }
|
||||
public IEntity Attacked { get; set; }
|
||||
public IEntity Using { get; set; }
|
||||
public IEntity Target { get; set; }
|
||||
}
|
||||
|
||||
public interface ITargetedAttackEventArgs
|
||||
public interface ITargetedInteractEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Performer of the attack
|
||||
@@ -56,45 +56,46 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
/// <summary>
|
||||
/// Target of the attack
|
||||
/// </summary>
|
||||
IEntity Attacked { get; }
|
||||
IEntity Target { get; }
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface gives components behavior when being clicked on or "attacked" by a user with an empty hand
|
||||
/// 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>
|
||||
public interface IAttackHand
|
||||
public interface IInteractHand
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when a player directly interacts with an empty hand when user is in range of the target entity.
|
||||
/// </summary>
|
||||
bool AttackHand(AttackHandEventArgs eventArgs);
|
||||
bool InteractHand(InteractHandEventArgs eventArgs);
|
||||
}
|
||||
|
||||
public class AttackHandEventArgs : EventArgs, ITargetedAttackEventArgs
|
||||
public class InteractHandEventArgs : EventArgs, ITargetedInteractEventArgs
|
||||
{
|
||||
public IEntity User { get; set; }
|
||||
public IEntity Attacked { get; set; }
|
||||
public IEntity Target { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface gives components behavior when being clicked by objects outside the range of direct use
|
||||
/// This interface gives components behavior when being clicked on by a user with an object
|
||||
/// outside the range of direct use
|
||||
/// </summary>
|
||||
public interface IRangedAttackBy
|
||||
public interface IRangedInteract
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when we try to interact with an entity out of range
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool RangedAttackBy(RangedAttackByEventArgs eventArgs);
|
||||
bool RangedInteract(RangedInteractEventArgs eventArgs);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public class RangedAttackByEventArgs : EventArgs
|
||||
public class RangedInteractEventArgs : EventArgs
|
||||
{
|
||||
public IEntity User { get; set; }
|
||||
public IEntity Weapon { get; set; }
|
||||
public IEntity Using { get; set; }
|
||||
public GridCoordinates ClickLocation { get; set; }
|
||||
}
|
||||
|
||||
@@ -102,19 +103,19 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
/// This interface gives components a behavior when clicking on another object and no interaction occurs,
|
||||
/// at any range.
|
||||
/// </summary>
|
||||
public interface IAfterAttack
|
||||
public interface IAfterInteract
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when we interact with nothing, or when we interact with an entity out of range that has no behavior
|
||||
/// </summary>
|
||||
void AfterAttack(AfterAttackEventArgs eventArgs);
|
||||
void AfterInteract(AfterInteractEventArgs eventArgs);
|
||||
}
|
||||
|
||||
public class AfterAttackEventArgs : EventArgs
|
||||
public class AfterInteractEventArgs : EventArgs
|
||||
{
|
||||
public IEntity User { get; set; }
|
||||
public GridCoordinates ClickLocation { get; set; }
|
||||
public IEntity Attacked { get; set; }
|
||||
public IEntity Target { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -146,10 +147,10 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
void Activate(ActivateEventArgs eventArgs);
|
||||
}
|
||||
|
||||
public class ActivateEventArgs : EventArgs, ITargetedAttackEventArgs
|
||||
public class ActivateEventArgs : EventArgs, ITargetedInteractEventArgs
|
||||
{
|
||||
public IEntity User { get; set; }
|
||||
public IEntity Attacked { get; set; }
|
||||
public IEntity Target { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -382,7 +383,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
}
|
||||
|
||||
// all activates should only fire when in range / unbostructed
|
||||
var activateEventArgs = new ActivateEventArgs {User = user, Attacked = used};
|
||||
var activateEventArgs = new ActivateEventArgs {User = user, Target = used};
|
||||
if (InteractionChecks.InRangeUnobstructed(activateEventArgs))
|
||||
{
|
||||
activateComp.Activate(activateEventArgs);
|
||||
@@ -499,8 +500,8 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
{
|
||||
if (item != null)
|
||||
{
|
||||
// After attack: Check if we clicked on an empty location, if so the only interaction we can do is AfterAttack
|
||||
InteractAfterAttack(player, item, coordinates);
|
||||
// After attack: Check if we clicked on an empty location, if so the only interaction we can do is AfterInteract
|
||||
InteractAfter(player, item, coordinates);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -525,7 +526,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
}
|
||||
}
|
||||
|
||||
// RangedAttack/AfterAttack: Check distance between user and clicked item, if too large parse it in the ranged function
|
||||
// RangedInteract/AfterInteract: Check distance between user and clicked item, if too large parse it in the ranged function
|
||||
// TODO: have range based upon the item being used? or base it upon some variables of the player himself?
|
||||
var distance = (playerTransform.WorldPosition - attacked.Transform.WorldPosition).LengthSquared;
|
||||
if (distance > InteractionRangeSquared)
|
||||
@@ -536,16 +537,16 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
return;
|
||||
}
|
||||
|
||||
return; // Add some form of ranged AttackHand here if you need it someday, or perhaps just ways to modify the range of AttackHand
|
||||
return; // Add some form of ranged InteractHand here if you need it someday, or perhaps just ways to modify the range of InteractHand
|
||||
}
|
||||
|
||||
// We are close to the nearby object and the object isn't contained in our active hand
|
||||
// AttackBy/AfterAttack: We will either use the item on the nearby object
|
||||
// InteractUsing/AfterInteract: We will either use the item on the nearby object
|
||||
if (item != null)
|
||||
{
|
||||
Interaction(player, item, attacked, coordinates);
|
||||
}
|
||||
// AttackHand/Activate: Since our hand is empty we will use AttackHand/Activate
|
||||
// InteractHand/Activate: Since our hand is empty we will use InteractHand/Activate
|
||||
else
|
||||
{
|
||||
Interaction(player, attacked);
|
||||
@@ -553,9 +554,9 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We didn't click on any entity, try doing an AfterAttack on the click location
|
||||
/// We didn't click on any entity, try doing an AfterInteract on the click location
|
||||
/// </summary>
|
||||
private void InteractAfterAttack(IEntity user, IEntity weapon, GridCoordinates clickLocation)
|
||||
private void InteractAfter(IEntity user, IEntity weapon, GridCoordinates clickLocation)
|
||||
{
|
||||
var message = new AfterAttackMessage(user, weapon, null, clickLocation);
|
||||
RaiseLocalEvent(message);
|
||||
@@ -564,18 +565,18 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
return;
|
||||
}
|
||||
|
||||
var afterAttacks = weapon.GetAllComponents<IAfterAttack>().ToList();
|
||||
var afterAttackEventArgs = new AfterAttackEventArgs {User = user, ClickLocation = clickLocation};
|
||||
var afterInteracts = weapon.GetAllComponents<IAfterInteract>().ToList();
|
||||
var afterInteractEventArgs = new AfterInteractEventArgs {User = user, ClickLocation = clickLocation};
|
||||
|
||||
foreach (var afterAttack in afterAttacks)
|
||||
foreach (var afterInteract in afterInteracts)
|
||||
{
|
||||
afterAttack.AfterAttack(afterAttackEventArgs);
|
||||
afterInteract.AfterInteract(afterInteractEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses a weapon/object on an entity
|
||||
/// Finds components with the AttackBy interface and calls their function
|
||||
/// Finds components with the InteractUsing interface and calls their function
|
||||
/// </summary>
|
||||
public void Interaction(IEntity user, IEntity weapon, IEntity attacked, GridCoordinates clickLocation)
|
||||
{
|
||||
@@ -586,10 +587,10 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
return;
|
||||
}
|
||||
|
||||
var attackBys = attacked.GetAllComponents<IAttackBy>().ToList();
|
||||
var attackByEventArgs = new AttackByEventArgs
|
||||
var attackBys = attacked.GetAllComponents<IInteractUsing>().ToList();
|
||||
var attackByEventArgs = new InteractUsingEventArgs
|
||||
{
|
||||
User = user, ClickLocation = clickLocation, AttackWith = weapon, Attacked = attacked
|
||||
User = user, ClickLocation = clickLocation, Using = weapon, Target = attacked
|
||||
};
|
||||
|
||||
// all AttackBys should only happen when in range / unobstructed, so no range check is needed
|
||||
@@ -597,9 +598,9 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
{
|
||||
foreach (var attackBy in attackBys)
|
||||
{
|
||||
if (attackBy.AttackBy(attackByEventArgs))
|
||||
if (attackBy.InteractUsing(attackByEventArgs))
|
||||
{
|
||||
// If an AttackBy returns a status completion we finish our attack
|
||||
// If an InteractUsing returns a status completion we finish our attack
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -613,21 +614,21 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
}
|
||||
|
||||
// If we aren't directly attacking the nearby object, lets see if our item has an after attack we can do
|
||||
var afterAttacks = weapon.GetAllComponents<IAfterAttack>().ToList();
|
||||
var afterAttackEventArgs = new AfterAttackEventArgs
|
||||
var afterAttacks = weapon.GetAllComponents<IAfterInteract>().ToList();
|
||||
var afterAttackEventArgs = new AfterInteractEventArgs
|
||||
{
|
||||
User = user, ClickLocation = clickLocation, Attacked = attacked
|
||||
User = user, ClickLocation = clickLocation, Target = attacked
|
||||
};
|
||||
|
||||
foreach (var afterAttack in afterAttacks)
|
||||
{
|
||||
afterAttack.AfterAttack(afterAttackEventArgs);
|
||||
afterAttack.AfterInteract(afterAttackEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses an empty hand on an entity
|
||||
/// Finds components with the AttackHand interface and calls their function
|
||||
/// Finds components with the InteractHand interface and calls their function
|
||||
/// </summary>
|
||||
public void Interaction(IEntity user, IEntity attacked)
|
||||
{
|
||||
@@ -638,17 +639,17 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
return;
|
||||
}
|
||||
|
||||
var attackHands = attacked.GetAllComponents<IAttackHand>().ToList();
|
||||
var attackHandEventArgs = new AttackHandEventArgs {User = user, Attacked = attacked};
|
||||
var attackHands = attacked.GetAllComponents<IInteractHand>().ToList();
|
||||
var attackHandEventArgs = new InteractHandEventArgs {User = user, Target = attacked};
|
||||
|
||||
// all attackHands should only fire when in range / unbostructed
|
||||
if (InteractionChecks.InRangeUnobstructed(attackHandEventArgs))
|
||||
{
|
||||
foreach (var attackHand in attackHands)
|
||||
{
|
||||
if (attackHand.AttackHand(attackHandEventArgs))
|
||||
if (attackHand.InteractHand(attackHandEventArgs))
|
||||
{
|
||||
// If an AttackHand returns a status completion we finish our attack
|
||||
// If an InteractHand returns a status completion we finish our attack
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -896,18 +897,18 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
if (rangedMsg.Handled)
|
||||
return;
|
||||
|
||||
var rangedAttackBys = attacked.GetAllComponents<IRangedAttackBy>().ToList();
|
||||
var rangedAttackByEventArgs = new RangedAttackByEventArgs
|
||||
var rangedAttackBys = attacked.GetAllComponents<IRangedInteract>().ToList();
|
||||
var rangedAttackByEventArgs = new RangedInteractEventArgs
|
||||
{
|
||||
User = user, Weapon = weapon, ClickLocation = clickLocation
|
||||
User = user, Using = weapon, ClickLocation = clickLocation
|
||||
};
|
||||
|
||||
// See if we have a ranged attack interaction
|
||||
foreach (var t in rangedAttackBys)
|
||||
{
|
||||
if (t.RangedAttackBy(rangedAttackByEventArgs))
|
||||
if (t.RangedInteract(rangedAttackByEventArgs))
|
||||
{
|
||||
// If an AttackBy returns a status completion we finish our attack
|
||||
// If an InteractUsing returns a status completion we finish our attack
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -917,16 +918,16 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
if (afterAtkMsg.Handled)
|
||||
return;
|
||||
|
||||
var afterAttacks = weapon.GetAllComponents<IAfterAttack>().ToList();
|
||||
var afterAttackEventArgs = new AfterAttackEventArgs
|
||||
var afterAttacks = weapon.GetAllComponents<IAfterInteract>().ToList();
|
||||
var afterAttackEventArgs = new AfterInteractEventArgs
|
||||
{
|
||||
User = user, ClickLocation = clickLocation, Attacked = attacked
|
||||
User = user, ClickLocation = clickLocation, Target = attacked
|
||||
};
|
||||
|
||||
//See if we have a ranged attack interaction
|
||||
foreach (var afterAttack in afterAttacks)
|
||||
{
|
||||
afterAttack.AfterAttack(afterAttackEventArgs);
|
||||
afterAttack.AfterInteract(afterAttackEventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user