From 69bd44c94c54d7f012a30d33302159833f6375bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Aguilera=20Puerto?= Date: Mon, 31 Aug 2020 18:55:42 +0200 Subject: [PATCH 1/4] Adds click attacks --- .../EntitySystems/MeleeWeaponSystem.cs | 32 ++++- .../Combat/Melee/MeleeWeaponSpeedCon.cs | 2 +- .../Weapon/Melee/MeleeWeaponComponent.cs | 127 ++++++++++++------ .../EntitySystems/Click/InteractionSystem.cs | 30 +++-- .../EntitySystems/MeleeWeaponSystem.cs | 7 +- .../MeleeWeaponSystemMessages.cs | 18 ++- .../Components/Interaction/IAttack.cs | 17 ++- 7 files changed, 167 insertions(+), 66 deletions(-) diff --git a/Content.Client/GameObjects/EntitySystems/MeleeWeaponSystem.cs b/Content.Client/GameObjects/EntitySystems/MeleeWeaponSystem.cs index 1a4b1212ee..daefa7c8c9 100644 --- a/Content.Client/GameObjects/EntitySystems/MeleeWeaponSystem.cs +++ b/Content.Client/GameObjects/EntitySystems/MeleeWeaponSystem.cs @@ -21,7 +21,8 @@ namespace Content.Client.GameObjects.EntitySystems public override void Initialize() { - SubscribeNetworkEvent(PlayWeaponArc); + SubscribeNetworkEvent(PlayWeaponArc); + SubscribeNetworkEvent(PlayWeapon); } public override void FrameUpdate(float frameTime) @@ -34,7 +35,7 @@ namespace Content.Client.GameObjects.EntitySystems } } - private void PlayWeaponArc(PlayMeleeWeaponAnimationMessage msg) + private void PlayWeaponArc(PlayMeleeWeaponArcAnimationMessage msg) { if (!_prototypeManager.TryIndex(msg.ArcPrototype, out MeleeWeaponAnimationPrototype weaponArc)) { @@ -80,5 +81,32 @@ namespace Content.Client.GameObjects.EntitySystems }); } } + + private void PlayWeapon(PlayMeleeWeaponAnimationMessage msg) + { + var attacker = EntityManager.GetEntity(msg.Attacker); + + var lunge = attacker.EnsureComponent(); + lunge.SetData(msg.Angle); + + if (!EntityManager.TryGetEntity(msg.Hit, out var hitEntity) + || !hitEntity.TryGetComponent(out ISpriteComponent sprite)) + { + return; + } + + var originalColor = sprite.Color; + var newColor = Color.Red * originalColor; + sprite.Color = newColor; + + Timer.Spawn(100, () => + { + // Only reset back to the original color if something else didn't change the color in the mean time. + if (sprite.Color == newColor) + { + sprite.Color = originalColor; + } + }); + } } } diff --git a/Content.Server/AI/Utility/Considerations/Combat/Melee/MeleeWeaponSpeedCon.cs b/Content.Server/AI/Utility/Considerations/Combat/Melee/MeleeWeaponSpeedCon.cs index fc56a593f7..63e1bddd46 100644 --- a/Content.Server/AI/Utility/Considerations/Combat/Melee/MeleeWeaponSpeedCon.cs +++ b/Content.Server/AI/Utility/Considerations/Combat/Melee/MeleeWeaponSpeedCon.cs @@ -15,7 +15,7 @@ namespace Content.Server.AI.Utility.Considerations.Combat.Melee return 0.0f; } - return meleeWeaponComponent.CooldownTime / 10.0f; + return meleeWeaponComponent.ArcCooldownTime / 10.0f; } } } diff --git a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs index ce4a5bf376..7f4f536b0f 100644 --- a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs @@ -29,53 +29,41 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee public override string Name => "MeleeWeapon"; private TimeSpan _lastAttackTime; + private TimeSpan _cooldownEnd; - private int _damage; - private float _range; - private float _arcWidth; - private string _arc; private string _hitSound; - public float CooldownTime => _cooldownTime; - private float _cooldownTime = 1f; + private string _missSound; + public float ArcCooldownTime { get; private set; } = 1f; + public float CooldownTime { get; private set; } = 0.5f; [ViewVariables(VVAccess.ReadWrite)] - public string Arc - { - get => _arc; - set => _arc = value; - } + public string Arc { get; set; } [ViewVariables(VVAccess.ReadWrite)] - public float ArcWidth - { - get => _arcWidth; - set => _arcWidth = value; - } + public float ArcWidth { get; set; } [ViewVariables(VVAccess.ReadWrite)] - public float Range - { - get => _range; - set => _range = value; - } + public float Range { get; set; } [ViewVariables(VVAccess.ReadWrite)] - public int Damage - { - get => _damage; - set => _damage = value; - } + public int Damage { get; set; } + + [ViewVariables(VVAccess.ReadWrite)] + public DamageType DamageType { get; set; } public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); - serializer.DataField(ref _damage, "damage", 5); - serializer.DataField(ref _range, "range", 1); - serializer.DataField(ref _arcWidth, "arcwidth", 90); - serializer.DataField(ref _arc, "arc", "default"); - serializer.DataField(ref _hitSound, "hitSound", "/Audio/Weapons/genhit1.ogg"); - serializer.DataField(ref _cooldownTime, "cooldownTime", 1f); + serializer.DataField(this, x => x.Damage, "damage", 5); + serializer.DataField(this, x => x.Range, "range", 1); + serializer.DataField(this, x => x.ArcWidth, "arcwidth", 90); + serializer.DataField(this, x => x.Arc, "arc", "default"); + serializer.DataField(this, x => x._hitSound, "hitSound", "/Audio/Weapons/genhit1.ogg"); + serializer.DataField(this, x => x._missSound, "hitSound", "/Audio/Weapons/punchmiss.ogg"); + serializer.DataField(this, x => x.ArcCooldownTime, "arcCooldownTime", 1f); + serializer.DataField(this, x => x.CooldownTime, "cooldownTime", 1f); + serializer.DataField(this, x => x.DamageType, "damageType", DamageType.Blunt); } protected virtual bool OnHitEntities(IReadOnlyList entities, AttackEventArgs eventArgs) @@ -83,13 +71,15 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee return true; } - void IAttack.Attack(AttackEventArgs eventArgs) + bool IAttack.WideAttack(AttackEventArgs eventArgs) { + if (!eventArgs.WideAttack) return true; + var curTime = IoCManager.Resolve().CurTime; - var span = curTime - _lastAttackTime; - if(span.TotalSeconds < _cooldownTime) { - return; - } + + if(curTime < _cooldownEnd) + return true; + var location = eventArgs.User.Transform.GridPosition; var angle = new Angle(eventArgs.ClickLocation.ToMapPos(_mapManager) - location.ToMapPos(_mapManager)); @@ -103,7 +93,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee } else { - audioSystem.PlayFromEntity("/Audio/Weapons/punchmiss.ogg", eventArgs.User); + audioSystem.PlayFromEntity(_missSound, eventArgs.User); } var hitEntities = new List(); @@ -114,12 +104,12 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee if (entity.TryGetComponent(out IDamageableComponent damageComponent)) { - damageComponent.ChangeDamage(DamageType.Blunt, Damage, false, Owner); + damageComponent.ChangeDamage(DamageType, Damage, false, Owner); hitEntities.Add(entity); } } - if(!OnHitEntities(hitEntities, eventArgs)) return; + if(!OnHitEntities(hitEntities, eventArgs)) return true; if (Arc != null) { @@ -127,13 +117,64 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee sys.SendAnimation(Arc, angle, eventArgs.User, hitEntities); } - _lastAttackTime = IoCManager.Resolve().CurTime; + _lastAttackTime = curTime; + _cooldownEnd = _lastAttackTime + TimeSpan.FromSeconds(ArcCooldownTime); if (Owner.TryGetComponent(out ItemCooldownComponent cooldown)) { cooldown.CooldownStart = _lastAttackTime; - cooldown.CooldownEnd = _lastAttackTime + TimeSpan.FromSeconds(_cooldownTime); + cooldown.CooldownEnd = _cooldownEnd; } + + return true; + } + + bool IAttack.ClickAttack(AttackEventArgs eventArgs) + { + if (eventArgs.WideAttack) return false; + + var curTime = IoCManager.Resolve().CurTime; + + if(curTime < _cooldownEnd || !eventArgs.Target.IsValid()) + return true; + + var target = eventArgs.TargetEntity; + + var location = eventArgs.User.Transform.GridPosition; + var angle = new Angle(eventArgs.ClickLocation.ToMapPos(_mapManager) - location.ToMapPos(_mapManager)); + + var audioSystem = EntitySystem.Get(); + if (target != null) + { + audioSystem.PlayFromEntity( _hitSound, target); + } + else + { + audioSystem.PlayFromEntity(_missSound, eventArgs.User); + return true; + } + + if (target.TryGetComponent(out IDamageableComponent damageComponent)) + { + damageComponent.ChangeDamage(DamageType, Damage, false, Owner); + } + + if (!OnHitEntities(new[] {target}, eventArgs)) + return true; + + var sys = _entitySystemManager.GetEntitySystem(); + sys.SendAnimation(angle, eventArgs.User, target); + + _lastAttackTime = curTime; + _cooldownEnd = _lastAttackTime + TimeSpan.FromSeconds(CooldownTime); + + if (Owner.TryGetComponent(out ItemCooldownComponent cooldown)) + { + cooldown.CooldownStart = _lastAttackTime; + cooldown.CooldownEnd = _cooldownEnd; + } + + return true; } private HashSet ArcRayCast(Vector2 position, Angle angle, IEntity ignore) @@ -149,7 +190,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee for (var i = 0; i < increments; i++) { var castAngle = new Angle(baseAngle + increment * i); - var res = _physicsManager.IntersectRay(mapId, new CollisionRay(position, castAngle.ToVec(), 23), _range, ignore).FirstOrDefault(); + var res = _physicsManager.IntersectRay(mapId, new CollisionRay(position, castAngle.ToVec(), 23), Range, ignore).FirstOrDefault(); if (res.HitEntity != null) { resSet.Add(res.HitEntity); diff --git a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs index ddab046408..2fd492635f 100644 --- a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs @@ -176,7 +176,7 @@ namespace Content.Server.GameObjects.EntitySystems.Click if (userEntity.TryGetComponent(out CombatModeComponent combatMode) && combatMode.IsInCombatMode) { - DoAttack(userEntity, coords); + DoAttack(userEntity, coords, true); } return true; @@ -198,7 +198,7 @@ namespace Content.Server.GameObjects.EntitySystems.Click if (entity.TryGetComponent(out CombatModeComponent combatMode) && combatMode.IsInCombatMode) { - DoAttack(entity, coords); + DoAttack(entity, coords, false); } else { @@ -229,7 +229,10 @@ namespace Content.Server.GameObjects.EntitySystems.Click return true; } - UserInteraction(userEntity, coords, uid); + if(userEntity.TryGetComponent(out CombatModeComponent combat) && combat.IsInCombatMode) + DoAttack(userEntity, coords, false, uid); + else + UserInteraction(userEntity, coords, uid); return true; } @@ -790,7 +793,7 @@ namespace Content.Server.GameObjects.EntitySystems.Click } } - private void DoAttack(IEntity player, GridCoordinates coordinates) + private void DoAttack(IEntity player, GridCoordinates coordinates, bool wideAttack, EntityUid target = default) { // Verify player is on the same map as the entity he clicked on if (_mapManager.GetGrid(coordinates.GridID).ParentMapId != player.Transform.MapID) @@ -800,12 +803,13 @@ namespace Content.Server.GameObjects.EntitySystems.Click return; } - if (!ActionBlockerSystem.CanAttack(player)) + if (!ActionBlockerSystem.CanAttack(player) || + (!wideAttack && !InRangeUnobstructed(player.Transform.MapPosition, coordinates.ToMap(_mapManager), ignoreInsideBlocker:true))) { return; } - var eventArgs = new AttackEventArgs(player, coordinates); + var eventArgs = new AttackEventArgs(player, coordinates, wideAttack, target); // Verify player has a hand, and find what object he is currently holding in his active hand if (player.TryGetComponent(out var hands)) @@ -814,22 +818,20 @@ namespace Content.Server.GameObjects.EntitySystems.Click if (item != null) { - var attacked = false; foreach (var attackComponent in item.GetAllComponents()) { - attackComponent.Attack(eventArgs); - attacked = true; - } - if (attacked) - { - return; + if(wideAttack ? attackComponent.WideAttack(eventArgs) : attackComponent.ClickAttack(eventArgs)) + return; } } } foreach (var attackComponent in player.GetAllComponents()) { - attackComponent.Attack(eventArgs); + if (wideAttack) + attackComponent.WideAttack(eventArgs); + else + attackComponent.ClickAttack(eventArgs); } } } diff --git a/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs b/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs index 82ba72537a..986a278535 100644 --- a/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs @@ -11,8 +11,13 @@ namespace Content.Server.GameObjects.EntitySystems { public void SendAnimation(string arc, Angle angle, IEntity attacker, IEnumerable hits) { - RaiseNetworkEvent(new MeleeWeaponSystemMessages.PlayMeleeWeaponAnimationMessage(arc, angle, attacker.Uid, + RaiseNetworkEvent(new MeleeWeaponSystemMessages.PlayMeleeWeaponArcAnimationMessage(arc, angle, attacker.Uid, hits.Select(e => e.Uid).ToList())); } + + public void SendAnimation(Angle angle, IEntity attacker, IEntity hit) + { + RaiseNetworkEvent(new MeleeWeaponSystemMessages.PlayMeleeWeaponAnimationMessage(angle, attacker.Uid, hit.Uid)); + } } } diff --git a/Content.Shared/GameObjects/EntitySystemMessages/MeleeWeaponSystemMessages.cs b/Content.Shared/GameObjects/EntitySystemMessages/MeleeWeaponSystemMessages.cs index 989defae06..849ba09936 100644 --- a/Content.Shared/GameObjects/EntitySystemMessages/MeleeWeaponSystemMessages.cs +++ b/Content.Shared/GameObjects/EntitySystemMessages/MeleeWeaponSystemMessages.cs @@ -9,9 +9,9 @@ namespace Content.Shared.GameObjects.EntitySystemMessages public static class MeleeWeaponSystemMessages { [Serializable, NetSerializable] - public sealed class PlayMeleeWeaponAnimationMessage : EntitySystemMessage + public sealed class PlayMeleeWeaponArcAnimationMessage : EntitySystemMessage { - public PlayMeleeWeaponAnimationMessage(string arcPrototype, Angle angle, EntityUid attacker, List hits) + public PlayMeleeWeaponArcAnimationMessage(string arcPrototype, Angle angle, EntityUid attacker, List hits) { ArcPrototype = arcPrototype; Angle = angle; @@ -24,5 +24,19 @@ namespace Content.Shared.GameObjects.EntitySystemMessages public EntityUid Attacker { get; } public List Hits { get; } } + + [Serializable, NetSerializable] + public sealed class PlayMeleeWeaponAnimationMessage : EntitySystemMessage + { + public PlayMeleeWeaponAnimationMessage(Angle angle, EntityUid attacker, EntityUid hit) + { + Attacker = attacker; + Hit = hit; + } + + public Angle Angle { get; } + public EntityUid Attacker { get; } + public EntityUid Hit { get; } + } } } diff --git a/Content.Shared/Interfaces/GameObjects/Components/Interaction/IAttack.cs b/Content.Shared/Interfaces/GameObjects/Components/Interaction/IAttack.cs index cf2950a519..218b403600 100644 --- a/Content.Shared/Interfaces/GameObjects/Components/Interaction/IAttack.cs +++ b/Content.Shared/Interfaces/GameObjects/Components/Interaction/IAttack.cs @@ -1,5 +1,9 @@ -using System; +#nullable enable +using System; +using Content.Shared.GameObjects.Components.Research; +using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.IoC; using Robust.Shared.Map; namespace Content.Shared.Interfaces.GameObjects.Components @@ -9,18 +13,25 @@ namespace Content.Shared.Interfaces.GameObjects.Components /// public interface IAttack { - void Attack(AttackEventArgs eventArgs); + // Redirects to ClickAttack by default. + bool WideAttack(AttackEventArgs eventArgs) => ClickAttack(eventArgs); + bool ClickAttack(AttackEventArgs eventArgs); } public class AttackEventArgs : EventArgs { - public AttackEventArgs(IEntity user, GridCoordinates clickLocation) + public AttackEventArgs(IEntity user, GridCoordinates clickLocation, bool wideAttack, EntityUid target = default) { User = user; ClickLocation = clickLocation; + WideAttack = wideAttack; + Target = target; } public IEntity User { get; } public GridCoordinates ClickLocation { get; } + public bool WideAttack { get; } + public EntityUid Target { get; } + public IEntity? TargetEntity => IoCManager.Resolve()?.GetEntity(Target) ?? null; } } From b927fddf4c666a39c6e59f0cc6ab9650839c632c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Aguilera=20Puerto?= Date: Mon, 31 Aug 2020 19:32:06 +0200 Subject: [PATCH 2/4] Better click attack effect --- .../EntitySystems/MeleeWeaponSystem.cs | 32 ++----------------- .../Weapon/Melee/MeleeWeaponComponent.cs | 15 +++++++-- .../EntitySystems/MeleeWeaponSystem.cs | 7 +--- .../MeleeWeaponSystemMessages.cs | 18 ++--------- 4 files changed, 17 insertions(+), 55 deletions(-) diff --git a/Content.Client/GameObjects/EntitySystems/MeleeWeaponSystem.cs b/Content.Client/GameObjects/EntitySystems/MeleeWeaponSystem.cs index daefa7c8c9..1a4b1212ee 100644 --- a/Content.Client/GameObjects/EntitySystems/MeleeWeaponSystem.cs +++ b/Content.Client/GameObjects/EntitySystems/MeleeWeaponSystem.cs @@ -21,8 +21,7 @@ namespace Content.Client.GameObjects.EntitySystems public override void Initialize() { - SubscribeNetworkEvent(PlayWeaponArc); - SubscribeNetworkEvent(PlayWeapon); + SubscribeNetworkEvent(PlayWeaponArc); } public override void FrameUpdate(float frameTime) @@ -35,7 +34,7 @@ namespace Content.Client.GameObjects.EntitySystems } } - private void PlayWeaponArc(PlayMeleeWeaponArcAnimationMessage msg) + private void PlayWeaponArc(PlayMeleeWeaponAnimationMessage msg) { if (!_prototypeManager.TryIndex(msg.ArcPrototype, out MeleeWeaponAnimationPrototype weaponArc)) { @@ -81,32 +80,5 @@ namespace Content.Client.GameObjects.EntitySystems }); } } - - private void PlayWeapon(PlayMeleeWeaponAnimationMessage msg) - { - var attacker = EntityManager.GetEntity(msg.Attacker); - - var lunge = attacker.EnsureComponent(); - lunge.SetData(msg.Angle); - - if (!EntityManager.TryGetEntity(msg.Hit, out var hitEntity) - || !hitEntity.TryGetComponent(out ISpriteComponent sprite)) - { - return; - } - - var originalColor = sprite.Color; - var newColor = Color.Red * originalColor; - sprite.Color = newColor; - - Timer.Spawn(100, () => - { - // Only reset back to the original color if something else didn't change the color in the mean time. - if (sprite.Color == newColor) - { - sprite.Color = originalColor; - } - }); - } } } diff --git a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs index 7f4f536b0f..06d4338b7c 100644 --- a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs @@ -36,6 +36,9 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee public float ArcCooldownTime { get; private set; } = 1f; public float CooldownTime { get; private set; } = 0.5f; + [ViewVariables(VVAccess.ReadWrite)] + public string ClickArc { get; set; } + [ViewVariables(VVAccess.ReadWrite)] public string Arc { get; set; } @@ -59,6 +62,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee serializer.DataField(this, x => x.Range, "range", 1); serializer.DataField(this, x => x.ArcWidth, "arcwidth", 90); serializer.DataField(this, x => x.Arc, "arc", "default"); + serializer.DataField(this, x => x.ClickArc, "clickArc", "punch"); serializer.DataField(this, x => x._hitSound, "hitSound", "/Audio/Weapons/genhit1.ogg"); serializer.DataField(this, x => x._missSound, "hitSound", "/Audio/Weapons/punchmiss.ogg"); serializer.DataField(this, x => x.ArcCooldownTime, "arcCooldownTime", 1f); @@ -159,11 +163,16 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee damageComponent.ChangeDamage(DamageType, Damage, false, Owner); } - if (!OnHitEntities(new[] {target}, eventArgs)) + var targets = new[] {target}; + + if (!OnHitEntities(targets, eventArgs)) return true; - var sys = _entitySystemManager.GetEntitySystem(); - sys.SendAnimation(angle, eventArgs.User, target); + if (ClickArc != null) + { + var sys = _entitySystemManager.GetEntitySystem(); + sys.SendAnimation(ClickArc, angle, eventArgs.User, targets); + } _lastAttackTime = curTime; _cooldownEnd = _lastAttackTime + TimeSpan.FromSeconds(CooldownTime); diff --git a/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs b/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs index 986a278535..82ba72537a 100644 --- a/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs @@ -11,13 +11,8 @@ namespace Content.Server.GameObjects.EntitySystems { public void SendAnimation(string arc, Angle angle, IEntity attacker, IEnumerable hits) { - RaiseNetworkEvent(new MeleeWeaponSystemMessages.PlayMeleeWeaponArcAnimationMessage(arc, angle, attacker.Uid, + RaiseNetworkEvent(new MeleeWeaponSystemMessages.PlayMeleeWeaponAnimationMessage(arc, angle, attacker.Uid, hits.Select(e => e.Uid).ToList())); } - - public void SendAnimation(Angle angle, IEntity attacker, IEntity hit) - { - RaiseNetworkEvent(new MeleeWeaponSystemMessages.PlayMeleeWeaponAnimationMessage(angle, attacker.Uid, hit.Uid)); - } } } diff --git a/Content.Shared/GameObjects/EntitySystemMessages/MeleeWeaponSystemMessages.cs b/Content.Shared/GameObjects/EntitySystemMessages/MeleeWeaponSystemMessages.cs index 849ba09936..989defae06 100644 --- a/Content.Shared/GameObjects/EntitySystemMessages/MeleeWeaponSystemMessages.cs +++ b/Content.Shared/GameObjects/EntitySystemMessages/MeleeWeaponSystemMessages.cs @@ -9,9 +9,9 @@ namespace Content.Shared.GameObjects.EntitySystemMessages public static class MeleeWeaponSystemMessages { [Serializable, NetSerializable] - public sealed class PlayMeleeWeaponArcAnimationMessage : EntitySystemMessage + public sealed class PlayMeleeWeaponAnimationMessage : EntitySystemMessage { - public PlayMeleeWeaponArcAnimationMessage(string arcPrototype, Angle angle, EntityUid attacker, List hits) + public PlayMeleeWeaponAnimationMessage(string arcPrototype, Angle angle, EntityUid attacker, List hits) { ArcPrototype = arcPrototype; Angle = angle; @@ -24,19 +24,5 @@ namespace Content.Shared.GameObjects.EntitySystemMessages public EntityUid Attacker { get; } public List Hits { get; } } - - [Serializable, NetSerializable] - public sealed class PlayMeleeWeaponAnimationMessage : EntitySystemMessage - { - public PlayMeleeWeaponAnimationMessage(Angle angle, EntityUid attacker, EntityUid hit) - { - Attacker = attacker; - Hit = hit; - } - - public Angle Angle { get; } - public EntityUid Attacker { get; } - public EntityUid Hit { get; } - } } } From 391444c8796f0a5d3e61b9a17a70d453227ecd9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Aguilera=20Puerto?= Date: Mon, 31 Aug 2020 20:54:33 +0200 Subject: [PATCH 3/4] Add an effect that shows the item you're using to attack with when attacking --- .../EntitySystems/MeleeWeaponSystem.cs | 27 ++++++++++++++++++- .../Weapon/Melee/MeleeWeaponComponent.cs | 15 +++++++---- .../EntitySystems/MeleeWeaponSystem.cs | 6 ++--- .../MeleeWeaponSystemMessages.cs | 6 ++++- .../Components/Interaction/IAttack.cs | 2 +- 5 files changed, 45 insertions(+), 11 deletions(-) diff --git a/Content.Client/GameObjects/EntitySystems/MeleeWeaponSystem.cs b/Content.Client/GameObjects/EntitySystems/MeleeWeaponSystem.cs index 1a4b1212ee..83a8950ba1 100644 --- a/Content.Client/GameObjects/EntitySystems/MeleeWeaponSystem.cs +++ b/Content.Client/GameObjects/EntitySystems/MeleeWeaponSystem.cs @@ -1,10 +1,14 @@ -using Content.Client.GameObjects.Components.Mobs; +using System; +using Content.Client.GameObjects.Components.Mobs; using Content.Client.GameObjects.Components.Weapons.Melee; using Content.Shared.GameObjects.Components.Weapons.Melee; using JetBrains.Annotations; +using Robust.Client.GameObjects; using Robust.Client.Interfaces.GameObjects.Components; using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.EntitySystemMessages; using Robust.Shared.GameObjects.Systems; +using Robust.Shared.Interfaces.Timing; using Robust.Shared.IoC; using Robust.Shared.Log; using Robust.Shared.Maths; @@ -18,6 +22,7 @@ namespace Content.Client.GameObjects.EntitySystems public sealed class MeleeWeaponSystem : EntitySystem { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly IGameTiming _gameTiming = default!; public override void Initialize() { @@ -53,6 +58,26 @@ namespace Content.Client.GameObjects.EntitySystems var weaponArcAnimation = entity.GetComponent(); weaponArcAnimation.SetData(weaponArc, msg.Angle, attacker); + // Due to ISpriteComponent limitations, weapons that don't use an RSI won't have this effect. + if (EntityManager.TryGetEntity(msg.Source, out var source) && msg.TextureEffect && source.TryGetComponent(out ISpriteComponent sourceSprite) + && sourceSprite.BaseRSI?.Path != null) + { + var sys = Get(); + var curTime = _gameTiming.CurTime; + var effect = new EffectSystemMessage + { + EffectSprite = sourceSprite.BaseRSI.Path.ToString(), + RsiState = sourceSprite.LayerGetState(0).Name, + Coordinates = attacker.Transform.GridPosition, + Color = Vector4.Multiply(new Vector4(255, 255, 255, 125), 1.0f), + ColorDelta = Vector4.Multiply(new Vector4(0, 0, 0, -10), 1.0f), + Velocity = msg.Angle.ToVec(), + Acceleration = msg.Angle.ToVec() * 5f, + Born = curTime, + DeathTime = curTime.Add(TimeSpan.FromMilliseconds(300f)), + }; + sys.CreateEffect(effect); + } foreach (var uid in msg.Hits) { diff --git a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs index 06d4338b7c..b3c402e800 100644 --- a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs @@ -17,6 +17,8 @@ using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; using Content.Shared.Damage; using Content.Shared.Interfaces.GameObjects.Components; +using Robust.Server.GameObjects; +using Robust.Shared.GameObjects.EntitySystemMessages; namespace Content.Server.GameObjects.Components.Weapon.Melee { @@ -24,7 +26,6 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee public class MeleeWeaponComponent : Component, IAttack { [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly IEntitySystemManager _entitySystemManager = default!; [Dependency] private readonly IPhysicsManager _physicsManager = default!; public override string Name => "MeleeWeapon"; @@ -54,6 +55,9 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee [ViewVariables(VVAccess.ReadWrite)] public DamageType DamageType { get; set; } + [ViewVariables(VVAccess.ReadWrite)] + public bool ClickAttackEffect { get; set; } + public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); @@ -68,6 +72,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee serializer.DataField(this, x => x.ArcCooldownTime, "arcCooldownTime", 1f); serializer.DataField(this, x => x.CooldownTime, "cooldownTime", 1f); serializer.DataField(this, x => x.DamageType, "damageType", DamageType.Blunt); + serializer.DataField(this, x => x.ClickAttackEffect, "clickAttackEffect", true); } protected virtual bool OnHitEntities(IReadOnlyList entities, AttackEventArgs eventArgs) @@ -117,8 +122,8 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee if (Arc != null) { - var sys = _entitySystemManager.GetEntitySystem(); - sys.SendAnimation(Arc, angle, eventArgs.User, hitEntities); + var sys = EntitySystem.Get(); + sys.SendAnimation(Arc, angle, eventArgs.User, Owner, hitEntities); } _lastAttackTime = curTime; @@ -170,8 +175,8 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee if (ClickArc != null) { - var sys = _entitySystemManager.GetEntitySystem(); - sys.SendAnimation(ClickArc, angle, eventArgs.User, targets); + var sys = EntitySystem.Get(); + sys.SendAnimation(ClickArc, angle, eventArgs.User, Owner, targets, ClickAttackEffect); } _lastAttackTime = curTime; diff --git a/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs b/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs index 82ba72537a..0613f1ec58 100644 --- a/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/MeleeWeaponSystem.cs @@ -9,10 +9,10 @@ namespace Content.Server.GameObjects.EntitySystems { public sealed class MeleeWeaponSystem : EntitySystem { - public void SendAnimation(string arc, Angle angle, IEntity attacker, IEnumerable hits) + public void SendAnimation(string arc, Angle angle, IEntity attacker, IEntity source, IEnumerable hits, bool textureEffect = false) { - RaiseNetworkEvent(new MeleeWeaponSystemMessages.PlayMeleeWeaponAnimationMessage(arc, angle, attacker.Uid, - hits.Select(e => e.Uid).ToList())); + RaiseNetworkEvent(new MeleeWeaponSystemMessages.PlayMeleeWeaponAnimationMessage(arc, angle, attacker.Uid, source.Uid, + hits.Select(e => e.Uid).ToList(), textureEffect)); } } } diff --git a/Content.Shared/GameObjects/EntitySystemMessages/MeleeWeaponSystemMessages.cs b/Content.Shared/GameObjects/EntitySystemMessages/MeleeWeaponSystemMessages.cs index 989defae06..2f1bd231fa 100644 --- a/Content.Shared/GameObjects/EntitySystemMessages/MeleeWeaponSystemMessages.cs +++ b/Content.Shared/GameObjects/EntitySystemMessages/MeleeWeaponSystemMessages.cs @@ -11,18 +11,22 @@ namespace Content.Shared.GameObjects.EntitySystemMessages [Serializable, NetSerializable] public sealed class PlayMeleeWeaponAnimationMessage : EntitySystemMessage { - public PlayMeleeWeaponAnimationMessage(string arcPrototype, Angle angle, EntityUid attacker, List hits) + public PlayMeleeWeaponAnimationMessage(string arcPrototype, Angle angle, EntityUid attacker, EntityUid source, List hits, bool textureEffect = false) { ArcPrototype = arcPrototype; Angle = angle; Attacker = attacker; + Source = source; Hits = hits; + TextureEffect = textureEffect; } public string ArcPrototype { get; } public Angle Angle { get; } public EntityUid Attacker { get; } + public EntityUid Source { get; } public List Hits { get; } + public bool TextureEffect { get; } } } } diff --git a/Content.Shared/Interfaces/GameObjects/Components/Interaction/IAttack.cs b/Content.Shared/Interfaces/GameObjects/Components/Interaction/IAttack.cs index 218b403600..48bf6a3e5a 100644 --- a/Content.Shared/Interfaces/GameObjects/Components/Interaction/IAttack.cs +++ b/Content.Shared/Interfaces/GameObjects/Components/Interaction/IAttack.cs @@ -32,6 +32,6 @@ namespace Content.Shared.Interfaces.GameObjects.Components public GridCoordinates ClickLocation { get; } public bool WideAttack { get; } public EntityUid Target { get; } - public IEntity? TargetEntity => IoCManager.Resolve()?.GetEntity(Target) ?? null; + public IEntity? TargetEntity => Target.IsValid() ? IoCManager.Resolve()?.GetEntity(Target) ?? null : null; } } From 3922759a819fc6ec7f3021130429c82438149984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Aguilera=20Puerto?= Date: Wed, 2 Sep 2020 15:22:26 +0200 Subject: [PATCH 4/4] address reviews --- .../Components/Weapon/Melee/MeleeWeaponComponent.cs | 6 +++--- .../GameObjects/Components/Interaction/IAttack.cs | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs index ce36d4814a..ef2cf24729 100644 --- a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs @@ -119,7 +119,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee } } - if(!OnHitEntities(hitEntities, eventArgs)) return true; + if(!OnHitEntities(hitEntities, eventArgs)) return false; if (Arc != null) { @@ -161,7 +161,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee else { audioSystem.PlayFromEntity(_missSound, eventArgs.User); - return true; + return false; } if (target.TryGetComponent(out IDamageableComponent damageComponent)) @@ -172,7 +172,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee var targets = new[] {target}; if (!OnHitEntities(targets, eventArgs)) - return true; + return false; if (ClickArc != null) { diff --git a/Content.Shared/Interfaces/GameObjects/Components/Interaction/IAttack.cs b/Content.Shared/Interfaces/GameObjects/Components/Interaction/IAttack.cs index 48bf6a3e5a..0a1a310405 100644 --- a/Content.Shared/Interfaces/GameObjects/Components/Interaction/IAttack.cs +++ b/Content.Shared/Interfaces/GameObjects/Components/Interaction/IAttack.cs @@ -26,12 +26,16 @@ namespace Content.Shared.Interfaces.GameObjects.Components ClickLocation = clickLocation; WideAttack = wideAttack; Target = target; + + IEntity? targetEntity = null; + IoCManager.Resolve()?.TryGetEntity(Target, out targetEntity); + TargetEntity = targetEntity; } public IEntity User { get; } public GridCoordinates ClickLocation { get; } public bool WideAttack { get; } public EntityUid Target { get; } - public IEntity? TargetEntity => Target.IsValid() ? IoCManager.Resolve()?.GetEntity(Target) ?? null : null; + public IEntity? TargetEntity { get; } } }