11using Game . Shared ;
22
3+ using Source ;
34using Source . Common ;
5+ using Source . Common . Commands ;
6+ using Source . Common . Formats . BSP ;
7+ using Source . Common . Mathematics ;
8+ using Source . Common . Physics ;
9+
10+ using System . Numerics ;
11+
12+ using DEFINE = Source . DEFINE < Game . Server . PhysImpact > ;
413
514namespace Game . Server ;
615
@@ -13,3 +22,96 @@ public class PhysBox : Breakable
1322 public static readonly SendTable DT_PhysBox = new ( DT_BaseEntity , [ ] ) ;
1423 public static readonly new ServerClass ServerClass = new ServerClass ( DT_PhysBox ) ;
1524}
25+
26+ [ LinkEntityToClass ( "env_physimpact" ) ]
27+ public class PhysImpact : PointEntity
28+ {
29+ public const int bitsPHYSIMPACT_NOFALLOFF = 0x00000001 ;
30+ public const int bitsPHYSIMPACT_INFINITE_LENGTH = 0x00000002 ;
31+ public const int bitsPHYSIMPACT_IGNORE_MASS = 0x00000004 ;
32+ public const int bitsPHYSIMPACT_IGNORE_NORMAL = 0x00000008 ;
33+
34+ public const float DEFAULT_EXPLODE_DISTANCE = 256 ;
35+
36+ public static readonly ConVar debug_physimpact = new ( "debug_physimpact" , "0" ) ;
37+
38+ public static readonly new DataMap DataDesc = new ( typeof ( PhysImpact ) , PointEntity . DataDesc , [
39+ DEFINE . KEYFIELD ( nameof ( Damage ) , FieldType . Float , "magnitude" ) ,
40+ DEFINE . KEYFIELD ( nameof ( Distance ) , FieldType . Float , "distance" ) ,
41+ DEFINE . KEYFIELD ( nameof ( DirectionEntityName ) , FieldType . String , "directionentityname" ) ,
42+
43+ DEFINE . INPUTFUNC ( FieldType . Void , "Impact" , nameof ( InputImpact ) , ( INPUTFUNCPTR ) ( ( self , data ) => ( ( PhysImpact ) self ) . InputImpact ( data ) ) ) ,
44+ ] ) ;
45+ public override DataMap ? GetDataDescMap ( ) => DataDesc ;
46+
47+ float Damage ;
48+ float Distance ;
49+ string ? DirectionEntityName ;
50+
51+ public override void Activate ( ) {
52+ base . Activate ( ) ;
53+ }
54+
55+ public override void Spawn ( ) {
56+ SetMoveType ( Source . MoveType . None ) ;
57+ SetSolid ( SolidType . None ) ;
58+ SetModelName ( null ) ;
59+
60+ if ( Distance == 0 )
61+ Distance = DEFAULT_EXPLODE_DISTANCE ;
62+ }
63+
64+ void PointAtEntity ( ) {
65+ if ( string . IsNullOrEmpty ( DirectionEntityName ) )
66+ return ;
67+
68+ Util . PointAtNamedEntity ( this , DirectionEntityName ) ;
69+ }
70+
71+ public void InputImpact ( InputData inputdata ) {
72+ if ( ! string . IsNullOrEmpty ( DirectionEntityName ) )
73+ PointAtEntity ( ) ;
74+
75+ MathLib . AngleVectors ( GetAbsAngles ( ) , out Vector3 dir ) ;
76+
77+ float dist = HasSpawnFlags ( bitsPHYSIMPACT_INFINITE_LENGTH ) ? MAX_TRACE_LENGTH : Distance ;
78+ Vector3 start = GetAbsOrigin ( ) ;
79+ Vector3 end = start + ( dir * dist ) ;
80+
81+ Util . TraceLine ( start , end , Mask . Shot , this , Source . CollisionGroup . None , out Trace trace ) ;
82+ if ( trace . StartSolid ) {
83+ Vector3 startOffset = start + ( dir * 0.1f ) ;
84+ Util . TraceLine ( startOffset , end , Mask . Shot , this , Source . CollisionGroup . None , out trace ) ;
85+ }
86+
87+ if ( trace . Fraction != 1.0 ) {
88+ if ( trace . StartSolid )
89+ trace . Plane . Normal = - dir ;
90+ BaseEntity ? ent = ( BaseEntity ? ) trace . Ent ;
91+
92+ IPhysicsObject ? physics = ent ? . VPhysicsGetObject ( ) ;
93+ if ( ent != null && physics != null ) {
94+ TakeDamageInfo info = new ( ) ;
95+ info . SetAttacker ( this ) ;
96+ info . SetInflictor ( this ) ;
97+ info . SetDamage ( 0 ) ;
98+ info . SetDamageForce ( vec3_origin ) ;
99+ info . SetDamageType ( DamageType . Generic ) ;
100+
101+ ent . DispatchTraceAttack ( info , dir , ref trace ) ;
102+ ApplyMultiDamage ( ) ;
103+
104+ float damage = HasSpawnFlags ( bitsPHYSIMPACT_NOFALLOFF | bitsPHYSIMPACT_INFINITE_LENGTH ) ?
105+ Damage : ( Damage * ( 1.0f - trace . Fraction ) ) ;
106+
107+ if ( HasSpawnFlags ( bitsPHYSIMPACT_IGNORE_MASS ) )
108+ damage *= physics . GetMass ( ) ;
109+
110+ if ( ! HasSpawnFlags ( bitsPHYSIMPACT_IGNORE_NORMAL ) )
111+ dir = - trace . Plane . Normal ;
112+
113+ physics . ApplyForceOffset ( damage * dir * phys_pushscale . GetFloat ( ) , trace . EndPos ) ;
114+ }
115+ }
116+ }
117+ }
0 commit comments