diff --git a/Content.Client/Weapons/Ranged/Systems/GunSystem.cs b/Content.Client/Weapons/Ranged/Systems/GunSystem.cs index 0ad22bf1d878..fb6e58809189 100644 --- a/Content.Client/Weapons/Ranged/Systems/GunSystem.cs +++ b/Content.Client/Weapons/Ranged/Systems/GunSystem.cs @@ -37,6 +37,7 @@ public sealed partial class GunSystem : SharedGunSystem [Dependency] private readonly InputSystem _inputSystem = default!; [Dependency] private readonly SharedCameraRecoilSystem _recoil = default!; [Dependency] private readonly SharedMapSystem _maps = default!; + [Dependency] private readonly SharedTransformSystem _xform = default!; [ValidatePrototypeId] public const string HitscanProto = "HitscanEffect"; @@ -102,6 +103,14 @@ private void OnMuzzleFlash(MuzzleFlashEvent args) private void OnHitscan(HitscanEvent ev) { // ALL I WANT IS AN ANIMATED EFFECT + + // This is very jank + // because the effect consists of three unrelatd entities, the hitscan beam can be split appart. + // E.g., if a grid rotates while part of the beam is parented to the grid, and part of it is parented to the map. + // Ideally, there should only be one entity, with one sprite that has multiple layers + // Or at the very least, have the other entities parented to the same entity to make sure they stick together. + // TODO EFFECTS + // Fix this jank foreach (var a in ev.Sprites) { if (a.Sprite is not SpriteSpecifier.Rsi rsi) @@ -109,13 +118,17 @@ private void OnHitscan(HitscanEvent ev) var coords = GetCoordinates(a.coordinates); - if (Deleted(coords.EntityId)) + if (!TryComp(coords.EntityId, out TransformComponent? relativeXform)) continue; var ent = Spawn(HitscanProto, coords); var sprite = Comp(ent); + var xform = Transform(ent); - xform.LocalRotation = a.angle; + var targetWorldRot = a.angle + _xform.GetWorldRotation(relativeXform); + var delta = targetWorldRot - _xform.GetWorldRotation(xform); + _xform.SetLocalRotationNoLerp(ent, xform.LocalRotation + delta, xform); + sprite[EffectLayers.Unshaded].AutoAnimated = false; sprite.LayerSetSprite(EffectLayers.Unshaded, rsi); sprite.LayerSetState(EffectLayers.Unshaded, rsi.RsiState); diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs index d22b5ec2af7b..374ad507e983 100644 --- a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs +++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs @@ -396,48 +396,45 @@ private void FireEffects(EntityCoordinates fromCoordinates, float distance, Angl // Forgive me for the shitcode I am about to do // Effects tempt me not var sprites = new List<(NetCoordinates coordinates, Angle angle, SpriteSpecifier sprite, float scale)>(); - var gridUid = fromCoordinates.GetGridUid(EntityManager); + var fromXform = Transform(fromCoordinates.EntityId); var angle = mapDirection; // We'll get the effects relative to the grid / map of the firer // Look you could probably optimise this a bit with redundant transforms at this point. - var xformQuery = GetEntityQuery(); - if (xformQuery.TryGetComponent(gridUid, out var gridXform)) + var gridUid = fromXform.GridUid; + if (gridUid != fromCoordinates.EntityId && TryComp(gridUid, out TransformComponent? gridXform)) { - var (_, gridRot, gridInvMatrix) = TransformSystem.GetWorldPositionRotationInvMatrix(gridXform, xformQuery); - - fromCoordinates = new EntityCoordinates(gridUid.Value, - Vector2.Transform(fromCoordinates.ToMapPos(EntityManager, TransformSystem), gridInvMatrix)); - - // Use the fallback angle I guess? + var (_, gridRot, gridInvMatrix) = TransformSystem.GetWorldPositionRotationInvMatrix(gridXform); + var map = _transform.ToMapCoordinates(fromCoordinates); + fromCoordinates = new EntityCoordinates(gridUid.Value, Vector2.Transform(map.Position, gridInvMatrix)); angle -= gridRot; } + else + { + angle -= _transform.GetWorldRotation(fromXform); + } + var fromNetCoords = GetNetCoordinates(fromCoordinates); + var dir = angle.ToVec(); if (distance >= 1f) { if (hitscan.MuzzleFlash != null) { - var coords = fromCoordinates.Offset(angle.ToVec().Normalized() / 2); - var netCoords = GetNetCoordinates(coords); - + var netCoords = new NetCoordinates(fromNetCoords.NetEntity, fromNetCoords.Position + dir / 2); sprites.Add((netCoords, angle, hitscan.MuzzleFlash, 1f)); } if (hitscan.TravelFlash != null) { - var coords = fromCoordinates.Offset(angle.ToVec() * (distance + 0.5f) / 2); - var netCoords = GetNetCoordinates(coords); - + var netCoords = new NetCoordinates(fromNetCoords.NetEntity, fromNetCoords.Position + dir * (distance + 0.5f) / 2); sprites.Add((netCoords, angle, hitscan.TravelFlash, distance - 1.5f)); } } if (hitscan.ImpactFlash != null) { - var coords = fromCoordinates.Offset(angle.ToVec() * distance); - var netCoords = GetNetCoordinates(coords); - + var netCoords = new NetCoordinates(fromNetCoords.NetEntity,fromNetCoords.Position + dir * distance); sprites.Add((netCoords, angle.FlipPositive(), hitscan.ImpactFlash, 1f)); }