2023-04-02 16:48:32 +03:00
using Content.Server.Administration.Logs ;
2023-08-11 03:44:52 +10:00
using Content.Server.Effects ;
2023-04-02 16:48:32 +03:00
using Content.Server.Weapons.Ranged.Systems ;
using Content.Shared.Camera ;
using Content.Shared.Damage ;
using Content.Shared.Database ;
using Content.Shared.FixedPoint ;
using Content.Shared.Projectiles ;
using Robust.Server.GameObjects ;
using Robust.Shared.Player ;
using Robust.Shared.Physics.Events ;
namespace Content.Server.Projectiles ;
public sealed class ProjectileSystem : SharedProjectileSystem
{
[Dependency] private readonly IAdminLogManager _adminLogger = default ! ;
2023-08-11 03:44:52 +10:00
[Dependency] private readonly ColorFlashEffectSystem _color = default ! ;
2023-04-02 16:48:32 +03:00
[Dependency] private readonly DamageableSystem _damageableSystem = default ! ;
[Dependency] private readonly GunSystem _guns = default ! ;
[Dependency] private readonly SharedCameraRecoilSystem _sharedCameraRecoil = default ! ;
public override void Initialize ( )
{
base . Initialize ( ) ;
SubscribeLocalEvent < ProjectileComponent , StartCollideEvent > ( OnStartCollide ) ;
}
private void OnStartCollide ( EntityUid uid , ProjectileComponent component , ref StartCollideEvent args )
{
// This is so entities that shouldn't get a collision are ignored.
2023-09-22 02:45:21 -07:00
if ( args . OurFixtureId ! = ProjectileFixture | | ! args . OtherFixture . Hard
| | component . DamagedEntity | | component is { Weapon : null , OnlyCollideWhenShot : true } )
2023-04-02 16:48:32 +03:00
return ;
2023-08-06 16:44:41 +03:00
var target = args . OtherEntity ;
2023-04-02 16:48:32 +03:00
// it's here so this check is only done once before possible hit
var attemptEv = new ProjectileReflectAttemptEvent ( uid , component , false ) ;
2023-08-06 16:44:41 +03:00
RaiseLocalEvent ( target , ref attemptEv ) ;
2023-04-02 16:48:32 +03:00
if ( attemptEv . Cancelled )
{
2023-08-06 16:44:41 +03:00
SetShooter ( component , target ) ;
2023-04-02 16:48:32 +03:00
return ;
}
2023-08-27 17:28:59 +01:00
var ev = new ProjectileHitEvent ( component . Damage , target , component . Shooter ) ;
2023-08-06 16:44:41 +03:00
RaiseLocalEvent ( uid , ref ev ) ;
var otherName = ToPrettyString ( target ) ;
2023-07-08 14:08:32 +10:00
var direction = args . OurBody . LinearVelocity . Normalized ( ) ;
2023-08-27 17:28:59 +01:00
var modifiedDamage = _damageableSystem . TryChangeDamage ( target , ev . Damage , component . IgnoreResistances , origin : component . Shooter ) ;
2023-08-06 16:44:41 +03:00
var deleted = Deleted ( target ) ;
2023-04-02 16:48:32 +03:00
if ( modifiedDamage is not null & & EntityManager . EntityExists ( component . Shooter ) )
{
if ( modifiedDamage . Total > FixedPoint2 . Zero & & ! deleted )
{
2023-08-11 03:44:52 +10:00
_color . RaiseEffect ( Color . Red , new List < EntityUid > { target } , Filter . Pvs ( target , entityManager : EntityManager ) ) ;
2023-04-02 16:48:32 +03:00
}
_adminLogger . Add ( LogType . BulletHit ,
2023-08-06 16:44:41 +03:00
HasComp < ActorComponent > ( target ) ? LogImpact . Extreme : LogImpact . High ,
2023-09-22 02:45:21 -07:00
$"Projectile {ToPrettyString(uid):projectile} shot by {ToPrettyString(component.Shooter!.Value):user} hit {otherName:target} and dealt {modifiedDamage.Total:damage} damage" ) ;
2023-04-02 16:48:32 +03:00
}
if ( ! deleted )
{
2023-08-06 16:44:41 +03:00
_guns . PlayImpactSound ( target , modifiedDamage , component . SoundHit , component . ForceSound ) ;
_sharedCameraRecoil . KickCamera ( target , direction ) ;
2023-04-02 16:48:32 +03:00
}
2023-08-06 16:44:41 +03:00
component . DamagedEntity = true ;
2023-05-15 15:21:05 +10:00
2023-08-06 16:44:41 +03:00
if ( component . DeleteOnCollide )
2023-04-02 16:48:32 +03:00
{
2023-08-06 16:44:41 +03:00
QueueDel ( uid ) ;
}
2023-04-02 16:48:32 +03:00
2023-08-06 16:44:41 +03:00
if ( component . ImpactEffect ! = null & & TryComp < TransformComponent > ( uid , out var xform ) )
{
2023-09-11 09:42:41 +10:00
RaiseNetworkEvent ( new ImpactEffectEvent ( component . ImpactEffect , GetNetCoordinates ( xform . Coordinates ) ) , Filter . Pvs ( xform . Coordinates , entityMan : EntityManager ) ) ;
2023-04-02 16:48:32 +03:00
}
}
}