Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix hitscan visuals #34515

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions Content.Client/Weapons/Ranged/Systems/GunSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<EntityPrototype>]
public const string HitscanProto = "HitscanEffect";
Expand Down Expand Up @@ -102,20 +103,31 @@ private void OnMuzzleFlash(MuzzleFlashEvent args)
private void OnHitscan(HitscanEvent ev)
{
// ALL I WANT IS AN ANIMATED EFFECT

// TODO EFFECTS
// 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.
foreach (var a in ev.Sprites)
{
if (a.Sprite is not SpriteSpecifier.Rsi rsi)
continue;

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<SpriteComponent>(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);
Expand Down
19 changes: 10 additions & 9 deletions Content.Server/Weapons/Ranged/Systems/GunSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -396,23 +396,24 @@ 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<TransformComponent>();

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);
}

if (distance >= 1f)
{
Expand Down
Loading