[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";
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)
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);
// TODO: Pseudo RNG so the client can predict these.
#region Hitscan effects
- private void FireEffects(EntityCoordinates fromCoordinates, float distance, Angle mapDirection, HitscanPrototype hitscan, EntityUid? hitEntity = null)
+ private void FireEffects(EntityCoordinates fromCoordinates, float distance, Angle angle, HitscanPrototype hitscan, EntityUid? hitEntity = null)
{
// Lord
// 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 angle = mapDirection;
+ var fromXform = Transform(fromCoordinates.EntityId);
// 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)
{