@@ -16,6 +16,7 @@ namespace Game.Server;
1616using System . Diagnostics ;
1717using System . Numerics ;
1818
19+ using DEFINE = Source . DEFINE < Game . Server . PhysicsProp > ;
1920using FIELD_BPD = Source . FIELD < BasePropDoor > ;
2021using FIELD_DP = Source . FIELD < DynamicProp > ;
2122using FIELD_PBM = Source . FIELD < PhysBoxMultiplayer > ;
@@ -62,6 +63,13 @@ public class BreakableProp : BaseProp, IBreakableWithPropData
6263 public static readonly SendTable DT_BreakableProp = new ( DT_BaseAnimating , [ ] ) ;
6364 public static readonly new ServerClass ServerClass = new ServerClass ( DT_BreakableProp ) ;
6465
66+ public bool PropDataOverrodeBlockLOS ( ) => BlockLOSSetByPropData ;
67+
68+ public void DisableAutoFade ( ) {
69+ FadeScale = 0 ;
70+ DefaultFadeScale = 0 ;
71+ }
72+
6573 public void SetDmgModBullet ( float dmgMod ) => DmgModBullet = dmgMod ;
6674 public void SetDmgModClub ( float dmgMod ) => DmgModClub = dmgMod ;
6775 public void SetDmgModExplosive ( float dmgMod ) => DmgModExplosive = dmgMod ;
@@ -82,7 +90,7 @@ public class BreakableProp : BaseProp, IBreakableWithPropData
8290 public int GetBreakableCount ( ) => BreakableCount ;
8391 public void SetMaxBreakableSize ( int size ) => MaxBreakableSize = size ;
8492 public int GetMaxBreakableSize ( ) => MaxBreakableSize ;
85- public void SetPropDataBlocksLOS ( bool blocksLOS ) => SetBlocksLOS ( blocksLOS ) ;
93+ public void SetPropDataBlocksLOS ( bool blocksLOS ) { BlockLOSSetByPropData = true ; SetBlocksLOS ( blocksLOS ) ; }
8694 public void SetPropDataIsAIWalkable ( bool blocksLOS ) => SetAIWalkable ( blocksLOS ) ;
8795 public void SetBasePropData ( ReadOnlySpan < char > propdata ) => BasePropData = propdata . IsEmpty ? null : new ( propdata ) ;
8896 public ReadOnlySpan < char > GetBasePropData ( ) => BasePropData ;
@@ -107,6 +115,8 @@ public class BreakableProp : BaseProp, IBreakableWithPropData
107115 protected float ExplodeRadius ;
108116 protected PhysicsMultiplayerMode m_iPhysicsMode ;
109117 protected MultiplayerBreak MpBreakMode ;
118+ bool BlockLOSSetByPropData ;
119+ float DefaultFadeScale ;
110120}
111121
112122[ LinkEntityToClass ( "func_physbox_multiplayer" ) ]
@@ -146,7 +156,36 @@ public class PhysicsProp : BreakableProp
146156 [ NetworkName ( "m_bAwake" ) ]
147157 public bool Awake ;
148158
159+ public static readonly new DataMap DataDesc = new ( typeof ( PhysicsProp ) , BaseEntity . DataDesc , [
160+ DEFINE . KEYFIELD ( nameof ( MassScale ) , FieldType . Float , "massscale" ) ,
161+ DEFINE . KEYFIELD ( nameof ( InertiaScale ) , FieldType . Float , "inertiascale" ) ,
162+ DEFINE . KEYFIELD ( nameof ( DamageType ) , FieldType . Integer , "Damagetype" ) ,
163+ DEFINE . KEYFIELD ( nameof ( OverrideScript ) , FieldType . String , "overridescript" ) ,
164+ DEFINE . KEYFIELD ( nameof ( DamageToEnableMotion ) , FieldType . Integer , "damagetoenablemotion" ) ,
165+ DEFINE . KEYFIELD ( nameof ( ForceToEnableMotion ) , FieldType . Float , "forcetoenablemotion" ) ,
166+ ] ) ;
167+ public override DataMap ? GetDataDescMap ( ) => DataDesc ;
168+
169+ public static int g_ActiveGibCount = 0 ;
170+
171+ float MassScale ;
172+ float InertiaScale ;
173+ int DamageType ;
174+ string ? OverrideScript ;
175+ int DamageToEnableMotion ;
176+ float ForceToEnableMotion ;
177+
178+ public override void Term ( ) {
179+ if ( HasSpawnFlags ( SF_PHYSPROP_IS_GIB ) )
180+ g_ActiveGibCount -- ;
181+
182+ base . Term ( ) ;
183+ }
184+
149185 public override void Spawn ( ) {
186+ if ( HasSpawnFlags ( SF_PHYSPROP_IS_GIB ) )
187+ g_ActiveGibCount ++ ;
188+
150189 // Condense classnames to one, except for "prop_physics_override"
151190 if ( FClassnameIs ( this , "physics_prop" ) )
152191 SetClassname ( "prop_physics" ) ;
@@ -160,7 +199,21 @@ public override void Spawn() {
160199 if ( FClassnameIs ( this , "prop_physics_override" ) )
161200 SetClassname ( "prop_physics" ) ;
162201
202+ if ( HasSpawnFlags ( SF_PHYSPROP_DEBRIS ) || HasInteraction ( PropDataInteractions . PhysgunCreateFlare ) )
203+ SetCollisionGroup ( HasSpawnFlags ( SF_PHYSPROP_FORCE_TOUCH_TRIGGERS ) ? Source . CollisionGroup . DebrisTrigger : Source . CollisionGroup . Debris ) ;
204+
205+ if ( HasSpawnFlags ( SF_PHYSPROP_NO_ROTORWASH_PUSH ) )
206+ AddEFlags ( EFL . NoRotorWashPush ) ;
207+
163208 CreateVPhysics ( ) ;
209+
210+ if ( ! PropDataOverrodeBlockLOS ( ) )
211+ CalculateBlockLOS ( ) ;
212+
213+ if ( ( ( ReadOnlySpan < char > ) GetModelName ( ) ) . Equals ( "models/props_c17/door01_left.mdl" , StringComparison . Ordinal ) ) {
214+ SetFadeDistance ( - 1 , 0 ) ;
215+ DisableAutoFade ( ) ;
216+ }
164217 }
165218
166219 public static bool PropIsGib ( BaseEntity entity ) {
@@ -174,18 +227,52 @@ public static bool PropIsGib(BaseEntity entity) {
174227 public bool IsGib ( ) => ( SpawnFlags & SF_PHYSPROP_IS_GIB ) != 0 ;
175228
176229 public virtual bool CreateVPhysics ( ) {
177- SetSolid ( SolidType . VPhysics ) ;
230+ bool asleep = HasSpawnFlags ( SF_PHYSPROP_START_ASLEEP ) ;
178231
179- if ( m_takedamage == ( byte ) Damage . No )
180- SetMoveType ( Source . MoveType . None ) ;
232+ Solid tmpSolid = default ;
233+ PhysModelParseSolid ( ref tmpSolid , this , GetModelIndex ( ) ) ;
234+
235+ if ( MassScale > 0 )
236+ tmpSolid . Params . Mass *= MassScale ;
237+
238+ if ( InertiaScale > 0 ) {
239+ tmpSolid . Params . Inertia *= InertiaScale ;
240+ if ( tmpSolid . Params . Inertia < 0.5 )
241+ tmpSolid . Params . Inertia = 0.5f ;
242+ }
243+
244+ PhysGetMassCenterOverride ( this , modelinfo . GetVCollide ( GetModelIndex ( ) ) , ref tmpSolid ) ;
245+ if ( HasSpawnFlags ( SF_PHYSPROP_NO_COLLISIONS ) )
246+ tmpSolid . Params . EnableCollisions = false ;
247+
248+ PhysSolidOverride ( ref tmpSolid , OverrideScript ) ;
181249
182- IPhysicsObject ? physObj = VPhysicsInitNormal ( SolidType . VPhysics , GetSolidFlags ( ) , false ) ;
183- if ( physObj == null ) {
250+ IPhysicsObject ? physicsObject = VPhysicsInitNormal ( SolidType . VPhysics , 0 , asleep , ref tmpSolid ) ;
251+
252+ if ( physicsObject == null ) {
184253 SetSolid ( SolidType . None ) ;
185254 SetMoveType ( Source . MoveType . None ) ;
186255 Warning ( $ "ERROR!: Can't create physics object for { GetModelName ( ) } \n ") ;
187256 return false ;
188257 }
258+ else {
259+ if ( DamageType == 1 )
260+ PhysSetGameFlags ( physicsObject , PhysicsFlags . DamageSlice ) ;
261+
262+ if ( HasSpawnFlags ( SF_PHYSPROP_MOTIONDISABLED ) || DamageToEnableMotion > 0 || ForceToEnableMotion > 0 )
263+ physicsObject . EnableMotion ( false ) ;
264+ }
265+
266+ if ( HasInteraction ( PropDataInteractions . PhysgunLaunchSpinZ ) ) {
267+ if ( ( VPhysicsGetObject ( ) ! . GetGameFlags ( ) & PhysicsFlags . DamageSlice ) == 0 )
268+ PhysSetGameFlags ( physicsObject , PhysicsFlags . DamageSlice ) ;
269+ }
270+
271+ if ( HasInteraction ( PropDataInteractions . PhysgunDamageNone ) )
272+ PhysSetGameFlags ( physicsObject , PhysicsFlags . NoImpactDamage ) ;
273+
274+ if ( HasSpawnFlags ( SF_PHYSPROP_PREVENT_PICKUP ) )
275+ PhysSetGameFlags ( physicsObject , PhysicsFlags . NoPlayerPickup ) ;
189276
190277 return true ;
191278 }
0 commit comments