diff --git a/Content.Client/GameObjects/Components/Weapons/Ranged/ClientRangedWeaponComponent.cs b/Content.Client/GameObjects/Components/Weapons/Ranged/ClientRangedWeaponComponent.cs index e37f6360b6..9bb8bc1050 100644 --- a/Content.Client/GameObjects/Components/Weapons/Ranged/ClientRangedWeaponComponent.cs +++ b/Content.Client/GameObjects/Components/Weapons/Ranged/ClientRangedWeaponComponent.cs @@ -1,6 +1,7 @@ -using Content.Shared.GameObjects.Components.Weapons.Ranged; +using Content.Shared.GameObjects.Components.Weapons.Ranged; using Robust.Shared.GameObjects; using Robust.Shared.Map; +using Robust.Shared.Maths; namespace Content.Client.GameObjects.Components.Weapons.Ranged { @@ -30,9 +31,9 @@ namespace Content.Client.GameObjects.Components.Weapons.Ranged FireRateSelector = rangedState.FireRateSelector; } - public void SyncFirePos(GridCoordinates worldPos) + public void SyncFirePos(GridId targetGrid, Vector2 targetPosition) { - SendNetworkMessage(new FirePosComponentMessage(worldPos)); + SendNetworkMessage(new FirePosComponentMessage(targetGrid, targetPosition)); } } -} \ No newline at end of file +} diff --git a/Content.Client/GameObjects/EntitySystems/RangedWeaponSystem.cs b/Content.Client/GameObjects/EntitySystems/RangedWeaponSystem.cs index ed3537fae7..027f6c6014 100644 --- a/Content.Client/GameObjects/EntitySystems/RangedWeaponSystem.cs +++ b/Content.Client/GameObjects/EntitySystems/RangedWeaponSystem.cs @@ -11,6 +11,7 @@ using Robust.Shared.Input; using Robust.Shared.Interfaces.Map; using Robust.Shared.Interfaces.Timing; using Robust.Shared.IoC; +using Robust.Shared.Map; namespace Content.Client.GameObjects.EntitySystems { @@ -96,9 +97,13 @@ namespace Content.Client.GameObjects.EntitySystems var worldPos = _eyeManager.ScreenToMap(_inputManager.MouseScreenPosition); if (!_mapManager.TryFindGridAt(worldPos, out var grid)) - grid = _mapManager.GetDefaultGrid(worldPos.MapId); - - weapon.SyncFirePos(grid.MapToGrid(worldPos)); + { + weapon.SyncFirePos(GridId.Invalid, worldPos.Position); + } + else + { + weapon.SyncFirePos(grid.Index, grid.MapToGrid(worldPos).Position); + } } } } diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs index ff8cc75244..ce2349aea0 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs @@ -159,10 +159,10 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels public override void OnAdd() { base.OnAdd(); - var rangedWeapon = Owner.GetComponent(); - rangedWeapon.Barrel = this; - rangedWeapon.FireHandler += Fire; - rangedWeapon.WeaponCanFireHandler += WeaponCanFire; + var rangedWeaponComponent = Owner.GetComponent(); + rangedWeaponComponent.Barrel = this; + rangedWeaponComponent.FireHandler += Fire; + rangedWeaponComponent.WeaponCanFireHandler += WeaponCanFire; } public override void OnRemove() @@ -208,7 +208,12 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels return true; } - private void Fire(IEntity shooter, GridCoordinates target) + /// + /// Fires a round of ammo out of the weapon. + /// + /// Entity that is operating the weapon, usually the player. + /// Target position on the map to shoot at. + private void Fire(IEntity shooter, Vector2 targetPos) { var soundSystem = EntitySystem.Get(); if (ShotsLeft == 0) @@ -229,8 +234,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels } // At this point firing is confirmed - var worldPosition = IoCManager.Resolve().GetGrid(target.GridID).LocalToWorld(target).Position; - var direction = (worldPosition - shooter.Transform.WorldPosition).ToAngle(); + var direction = (targetPos - shooter.Transform.WorldPosition).ToAngle(); var angle = GetRecoilAngle(direction); // This should really be client-side but for now we'll just leave it here if (shooter.TryGetComponent(out CameraRecoilComponent recoilComponent)) diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/ServerRangedWeaponComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/ServerRangedWeaponComponent.cs index 577549fa50..a2e0ea57c4 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/ServerRangedWeaponComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/ServerRangedWeaponComponent.cs @@ -1,4 +1,4 @@ -using System; +using System; using Content.Server.GameObjects.Components.GUI; using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels; @@ -12,6 +12,7 @@ using Robust.Shared.Audio; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Map; using Robust.Shared.Interfaces.Network; using Robust.Shared.Interfaces.Random; using Robust.Shared.Interfaces.Timing; @@ -19,6 +20,7 @@ using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Log; using Robust.Shared.Map; +using Robust.Shared.Maths; using Robust.Shared.Players; using Robust.Shared.Random; using Robust.Shared.Serialization; @@ -38,7 +40,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged public Func WeaponCanFireHandler; public Func UserCanFireHandler; - public Action FireHandler; + public Action FireHandler; public ServerRangedBarrelComponent Barrel { @@ -77,6 +79,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged serializer.DataField(this, p => p.ClumsyExplodeChance, "clumsyExplodeChance", 0.5f); } + /// public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession session = null) { base.HandleNetworkMessage(message, channel, session); @@ -95,7 +98,24 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged return; } - _tryFire(user, msg.Target); + if (msg.TargetGrid != GridId.Invalid) + { + // grid pos + if (!IoCManager.Resolve().TryGetGrid(msg.TargetGrid, out var grid)) + { + // Client sent us a message with an invalid grid. + break; + } + + var targetPos = grid.LocalToWorld(msg.TargetPosition); + TryFire(user, targetPos); + } + else + { + // map pos + TryFire(user, msg.TargetPosition); + } + break; } } @@ -105,7 +125,12 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged return new RangedWeaponComponentState(FireRateSelector); } - private void _tryFire(IEntity user, GridCoordinates coordinates) + /// + /// Tries to fire a round of ammo out of the weapon. + /// + /// Entity that is operating the weapon, usually the player. + /// Target position on the map to shoot at. + private void TryFire(IEntity user, Vector2 targetPos) { if (!user.TryGetComponent(out HandsComponent hands) || hands.GetActiveHand?.Owner != Owner) { @@ -158,7 +183,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged return; } - FireHandler?.Invoke(user, coordinates); + FireHandler?.Invoke(user, targetPos); } // Probably a better way to do this. diff --git a/Content.Shared/GameObjects/Components/Weapons/Ranged/SharedRangedWeaponComponent.cs b/Content.Shared/GameObjects/Components/Weapons/Ranged/SharedRangedWeaponComponent.cs index 0eb6a6e49b..882ae4beee 100644 --- a/Content.Shared/GameObjects/Components/Weapons/Ranged/SharedRangedWeaponComponent.cs +++ b/Content.Shared/GameObjects/Components/Weapons/Ranged/SharedRangedWeaponComponent.cs @@ -1,6 +1,7 @@ -using System; +using System; using Robust.Shared.GameObjects; using Robust.Shared.Map; +using Robust.Shared.Maths; using Robust.Shared.Serialization; namespace Content.Shared.GameObjects.Components.Weapons.Ranged @@ -26,14 +27,33 @@ namespace Content.Shared.GameObjects.Components.Weapons.Ranged } } + /// + /// A component message raised when the weapon is fired at a position on the map. + /// [Serializable, NetSerializable] public sealed class FirePosComponentMessage : ComponentMessage { - public GridCoordinates Target { get; } + /// + /// If this is not invalid, the target position is relative to the grid. + /// Otherwise, it is a map position. + /// + public GridId TargetGrid { get; } - public FirePosComponentMessage(GridCoordinates target) + /// + /// If Target Grid is not invalid, this is relative to the grid, otherwise + /// it is a map position. + /// + public Vector2 TargetPosition { get; } + + /// + /// Constructs a new instance of . + /// + /// The grid that the target position is on, if any. + /// Target position relative to the grid, or a map position if the grid is invalid. + public FirePosComponentMessage(GridId targetGrid, Vector2 targetPosition) { - Target = target; + TargetGrid = targetGrid; + TargetPosition = targetPosition; } } }