Make energy sword reflect projectiles and hitscan shots (#14029)
This commit is contained in:
@@ -36,6 +36,7 @@ public sealed partial class GunSystem : SharedGunSystem
|
||||
[Dependency] private readonly PricingSystem _pricing = default!;
|
||||
[Dependency] private readonly StaminaSystem _stamina = default!;
|
||||
[Dependency] private readonly StunSystem _stun = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
|
||||
public const float DamagePitchVariation = SharedMeleeWeaponSystem.DamagePitchVariation;
|
||||
public const float GunClumsyChance = 0.5f;
|
||||
@@ -192,18 +193,42 @@ public sealed partial class GunSystem : SharedGunSystem
|
||||
ShootProjectile(ent.Value, mapDirection, gunVelocity, user, gun.ProjectileSpeed);
|
||||
break;
|
||||
case HitscanPrototype hitscan:
|
||||
var ray = new CollisionRay(fromMap.Position, mapDirection.Normalized, hitscan.CollisionMask);
|
||||
|
||||
var rayCastResults =
|
||||
Physics.IntersectRay(fromMap.MapId, ray, hitscan.MaxLength, user, false).ToList();
|
||||
EntityUid? lastHit = null;
|
||||
|
||||
if (rayCastResults.Count >= 1)
|
||||
var from = fromMap;
|
||||
var fromEffect = fromCoordinates; // can't use map coords above because funny FireEffects
|
||||
var dir = mapDirection.Normalized;
|
||||
var lastUser = user;
|
||||
for (var reflectAttempt = 0; reflectAttempt < 3; reflectAttempt++)
|
||||
{
|
||||
var result = rayCastResults[0];
|
||||
var hitEntity = result.HitEntity;
|
||||
var distance = result.Distance;
|
||||
FireEffects(fromCoordinates, distance, mapDirection.ToAngle(), hitscan, hitEntity);
|
||||
var ray = new CollisionRay(from.Position, dir, hitscan.CollisionMask);
|
||||
var rayCastResults =
|
||||
Physics.IntersectRay(from.MapId, ray, hitscan.MaxLength, lastUser, false).ToList();
|
||||
if (!rayCastResults.Any())
|
||||
break;
|
||||
|
||||
var result = rayCastResults[0];
|
||||
var hit = result.HitEntity;
|
||||
lastHit = hit;
|
||||
|
||||
FireEffects(fromEffect, result.Distance, dir.Normalized.ToAngle(), hitscan, hit);
|
||||
|
||||
var ev = new HitScanReflectAttemptEvent(dir, false);
|
||||
RaiseLocalEvent(hit, ref ev);
|
||||
|
||||
if (!ev.Reflected)
|
||||
break;
|
||||
|
||||
fromEffect = Transform(hit).Coordinates;
|
||||
from = fromEffect.ToMap(EntityManager, _transform);
|
||||
dir = ev.Direction;
|
||||
lastUser = hit;
|
||||
}
|
||||
|
||||
if (lastHit != null)
|
||||
{
|
||||
EntityUid hitEntity = lastHit.Value;
|
||||
if (hitscan.StaminaDamage > 0f)
|
||||
_stamina.TakeStaminaDamage(hitEntity, hitscan.StaminaDamage, source:user);
|
||||
|
||||
@@ -219,7 +244,7 @@ public sealed partial class GunSystem : SharedGunSystem
|
||||
if (!Deleted(hitEntity))
|
||||
{
|
||||
if (dmg.Total > FixedPoint2.Zero)
|
||||
RaiseNetworkEvent(new DamageEffectEvent(Color.Red, new List<EntityUid> {result.HitEntity}), Filter.Pvs(hitEntity, entityManager: EntityManager));
|
||||
RaiseNetworkEvent(new DamageEffectEvent(Color.Red, new List<EntityUid> {hitEntity}), Filter.Pvs(hitEntity, entityManager: EntityManager));
|
||||
|
||||
// TODO get fallback position for playing hit sound.
|
||||
PlayImpactSound(hitEntity, dmg, hitscan.Sound, hitscan.ForceSound);
|
||||
@@ -239,7 +264,7 @@ public sealed partial class GunSystem : SharedGunSystem
|
||||
}
|
||||
else
|
||||
{
|
||||
FireEffects(fromCoordinates, hitscan.MaxLength, mapDirection.ToAngle(), hitscan);
|
||||
FireEffects(fromEffect, hitscan.MaxLength, dir.ToAngle(), hitscan);
|
||||
}
|
||||
|
||||
Audio.PlayPredicted(gun.SoundGunshot, gunUid, user);
|
||||
|
||||
Reference in New Issue
Block a user