From 50f42d71a279a170d3525043e61df6d57fc513ef Mon Sep 17 00:00:00 2001 From: Acruid Date: Sat, 20 Apr 2019 16:18:16 -0700 Subject: [PATCH] Interaction System Messages (#202) * Adds entity messages to the InteractionSystem. * Changed Handled check formatting to match the rest of the codebase. --- .../Components/GUI/ServerHandsComponent.cs | 11 +- .../EntitySystems/Click/InteractionSystem.cs | 261 +++++++++++++++++- 2 files changed, 257 insertions(+), 15 deletions(-) diff --git a/Content.Server/GameObjects/Components/GUI/ServerHandsComponent.cs b/Content.Server/GameObjects/Components/GUI/ServerHandsComponent.cs index 2f77d9ed7c..cd0f36dbba 100644 --- a/Content.Server/GameObjects/Components/GUI/ServerHandsComponent.cs +++ b/Content.Server/GameObjects/Components/GUI/ServerHandsComponent.cs @@ -25,6 +25,8 @@ namespace Content.Server.GameObjects { public class HandsComponent : SharedHandsComponent, IHandsComponent { + [Dependency] private readonly IEntitySystemManager _entitySystemManager; + private string activeIndex; [ViewVariables(VVAccess.ReadWrite)] @@ -436,7 +438,8 @@ namespace Content.Server.GameObjects var used = GetActiveHand?.Owner; if (used != null) { - InteractionSystem.TryUseInteraction(Owner, used); + var interactionSystem = _entitySystemManager.GetEntitySystem(); + interactionSystem.TryUseInteraction(Owner, used); } } @@ -474,7 +477,8 @@ namespace Content.Server.GameObjects if (playerEntity == Owner && used != null) { - InteractionSystem.Interaction(Owner, used, slot.ContainedEntity, + var interactionSystem = _entitySystemManager.GetEntitySystem(); + interactionSystem.Interaction(Owner, used, slot.ContainedEntity, GridCoordinates.Nullspace); } @@ -490,7 +494,8 @@ namespace Content.Server.GameObjects if (playerEntity == Owner && used != null) { - InteractionSystem.TryUseInteraction(Owner, used); + var interactionSystem = _entitySystemManager.GetEntitySystem(); + interactionSystem.TryUseInteraction(Owner, used); } break; diff --git a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs index 07cfc857bc..e1de64f8b2 100644 --- a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs @@ -153,9 +153,6 @@ namespace Content.Server.GameObjects.EntitySystems if(!EntityManager.TryGetEntity(uid, out var used)) return; - if(!used.TryGetComponent(out IActivate activateComp)) - return; - var playerEnt = ((IPlayerSession) session).AttachedEntity; if(playerEnt == null || !playerEnt.IsValid()) @@ -164,6 +161,14 @@ namespace Content.Server.GameObjects.EntitySystems if (!playerEnt.Transform.GridPosition.InRange(used.Transform.GridPosition, INTERACTION_RANGE)) return; + var activateMsg = new ActivateInWorldMessage(playerEnt, used); + RaiseEvent(activateMsg); + if(activateMsg.Handled) + return; + + if (!used.TryGetComponent(out IActivate activateComp)) + return; + activateComp.Activate(new ActivateEventArgs { User = playerEnt }); } @@ -277,8 +282,13 @@ namespace Content.Server.GameObjects.EntitySystems /// /// /// - public static void InteractAfterattack(IEntity user, IEntity weapon, GridCoordinates clicklocation) + public void InteractAfterattack(IEntity user, IEntity weapon, GridCoordinates clicklocation) { + var message = new AfterAttackMessage(user, weapon, null, clicklocation); + RaiseEvent(message); + if(message.Handled) + return; + List afterattacks = weapon.GetAllComponents().ToList(); for (var i = 0; i < afterattacks.Count; i++) @@ -294,8 +304,13 @@ namespace Content.Server.GameObjects.EntitySystems /// /// /// - public static void Interaction(IEntity user, IEntity weapon, IEntity attacked, GridCoordinates clicklocation) + public void Interaction(IEntity user, IEntity weapon, IEntity attacked, GridCoordinates clicklocation) { + var attackMsg = new AttackByMessage(user, weapon, attacked, clicklocation); + RaiseEvent(attackMsg); + if(attackMsg.Handled) + return; + List interactables = attacked.GetAllComponents().ToList(); for (var i = 0; i < interactables.Count; i++) @@ -307,7 +322,11 @@ namespace Content.Server.GameObjects.EntitySystems } //Else check damage component to see if we damage if not attackby, and if so can we attack object - + + var afterAtkMsg = new AfterAttackMessage(user, weapon, attacked, clicklocation); + RaiseEvent(afterAtkMsg); + if (afterAtkMsg.Handled) + return; //If we aren't directly attacking the nearby object, lets see if our item has an after attack we can do List afterattacks = weapon.GetAllComponents().ToList(); @@ -324,8 +343,13 @@ namespace Content.Server.GameObjects.EntitySystems /// /// /// - public static void Interaction(IEntity user, IEntity attacked) + public void Interaction(IEntity user, IEntity attacked) { + var message = new AttackHandMessage(user, attacked); + RaiseEvent(message); + if(message.Handled) + return; + List interactables = attacked.GetAllComponents().ToList(); for (var i = 0; i < interactables.Count; i++) @@ -345,7 +369,7 @@ namespace Content.Server.GameObjects.EntitySystems /// /// /// - public static void TryUseInteraction(IEntity user, IEntity used) + public void TryUseInteraction(IEntity user, IEntity used) { if (user != null && used != null && ActionBlockerSystem.CanUse(user)) { @@ -359,8 +383,13 @@ namespace Content.Server.GameObjects.EntitySystems /// /// /// - public static void UseInteraction(IEntity user, IEntity used) + public void UseInteraction(IEntity user, IEntity used) { + var useMsg = new UseInHandMessage(user, used); + RaiseEvent(useMsg); + if(useMsg.Handled) + return; + List usables = used.GetAllComponents().ToList(); //Try to use item on any components which have the interface @@ -380,14 +409,19 @@ namespace Content.Server.GameObjects.EntitySystems /// /// /// - public static void RangedInteraction(IEntity user, IEntity weapon, IEntity attacked, GridCoordinates clicklocation) + public void RangedInteraction(IEntity user, IEntity weapon, IEntity attacked, GridCoordinates clickLocation) { + var rangedMsg = new RangedAttackMessage(user, weapon, attacked, clickLocation); + RaiseEvent(rangedMsg); + if(rangedMsg.Handled) + return; + List rangedusables = attacked.GetAllComponents().ToList(); //See if we have a ranged attack interaction for (var i = 0; i < rangedusables.Count; i++) { - if (rangedusables[i].RangedAttackBy(new RangedAttackByEventArgs { User = user, Weapon = weapon, ClickLocation = clicklocation })) //If an attackby returns a status completion we finish our attack + if (rangedusables[i].RangedAttackBy(new RangedAttackByEventArgs { User = user, Weapon = weapon, ClickLocation = clickLocation })) //If an attackby returns a status completion we finish our attack { return; } @@ -395,14 +429,217 @@ namespace Content.Server.GameObjects.EntitySystems if (weapon != null) { + var afterAtkMsg = new AfterAttackMessage(user, weapon, attacked, clickLocation); + RaiseEvent(afterAtkMsg); + if (afterAtkMsg.Handled) + return; + List afterattacks = weapon.GetAllComponents().ToList(); //See if we have a ranged attack interaction for (var i = 0; i < afterattacks.Count; i++) { - afterattacks[i].AfterAttack(new AfterAttackEventArgs { User = user, ClickLocation = clicklocation, Attacked = attacked }); + afterattacks[i].AfterAttack(new AfterAttackEventArgs { User = user, ClickLocation = clickLocation, Attacked = attacked }); } } } } + + /// + /// Raised when being clicked on or "attacked" by a user with an object in their hand + /// + public class AttackByMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that triggered the attack. + /// + public IEntity User { get; } + + /// + /// Entity that the User attacked with. + /// + public IEntity ItemInHand { get; } + + /// + /// Entity that was attacked. + /// + public IEntity Attacked { get; } + + /// + /// The original location that was clicked by the user. + /// + public GridCoordinates ClickLocation { get; } + + public AttackByMessage(IEntity user, IEntity itemInHand, IEntity attacked, GridCoordinates clickLocation) + { + User = user; + ItemInHand = itemInHand; + Attacked = attacked; + ClickLocation = clickLocation; + } + } + + /// + /// Raised when being clicked on or "attacked" by a user with an empty hand. + /// + public class AttackHandMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that triggered the attack. + /// + public IEntity User { get; } + + /// + /// Entity that was attacked. + /// + public IEntity Attacked { get; } + + public AttackHandMessage(IEntity user, IEntity attacked) + { + User = user; + Attacked = attacked; + } + } + + /// + /// Raised when being clicked by objects outside the range of direct use. + /// + public class RangedAttackMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that triggered the attack. + /// + public IEntity User { get; } + + /// + /// Entity that the User attacked with. + /// + public IEntity ItemInHand { get; set; } + + /// + /// Entity that was attacked. + /// + public IEntity Attacked { get; } + + /// + /// Location that the user clicked outside of their interaction range. + /// + public GridCoordinates ClickLocation { get; } + + public RangedAttackMessage(IEntity user, IEntity itemInHand, IEntity attacked, GridCoordinates clickLocation) + { + User = user; + ItemInHand = itemInHand; + ClickLocation = clickLocation; + Attacked = attacked; + } + } + + /// + /// Raised when clicking on another object and no attack event was handled. + /// + public class AfterAttackMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that triggered the attack. + /// + public IEntity User { get; } + + /// + /// Entity that the User attacked with. + /// + public IEntity ItemInHand { get; set; } + + /// + /// Entity that was attacked. This can be null if the attack did not click on an entity. + /// + public IEntity Attacked { get; } + + /// + /// Location that the user clicked outside of their interaction range. + /// + public GridCoordinates ClickLocation { get; } + + public AfterAttackMessage(IEntity user, IEntity itemInHand, IEntity attacked, GridCoordinates clickLocation) + { + User = user; + Attacked = attacked; + ClickLocation = clickLocation; + ItemInHand = itemInHand; + } + } + + /// + /// Raised when using the entity in your hands. + /// + public class UseInHandMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity holding the item in their hand. + /// + public IEntity User { get; } + + /// + /// Item that was used. + /// + public IEntity Used { get; } + + public UseInHandMessage(IEntity user, IEntity used) + { + User = user; + Used = used; + } + } + + /// + /// Raised when an entity is activated in the world. + /// + public class ActivateInWorldMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that activated the world entity. + /// + public IEntity User { get; } + + /// + /// Entity that was activated in the world. + /// + public IEntity Activated { get; } + + public ActivateInWorldMessage(IEntity user, IEntity activated) + { + User = user; + Activated = activated; + } + } }