1 #using scripts\codescripts\struct;
2 #using scripts\shared\clientfield_shared;
3 #using scripts\shared\util_shared;
5 #insert scripts\shared\archetype_shared\archetype_shared.gsh;
6 #insert scripts\shared\shared.gsh;
7 #insert scripts\shared\version.gsh;
8 #insert scripts\shared\ai\systems\gib.gsh;
10 #namespace GibClientUtils;
45 processedBundles = [];
48 foreach ( definitionName, definition
in gibDefinitions )
50 gibBundle = SpawnStruct();
52 gibBundle.name = definitionName;
54 foreach ( gibPieceFlag, gibPieceName
in gibPieceLookup )
56 gibStruct = SpawnStruct();
57 gibStruct.gibmodel = GetStructField( definition, gibPieceLookup[ gibPieceFlag ] +
"_gibmodel" );
58 gibStruct.gibtag = GetStructField( definition, gibPieceLookup[ gibPieceFlag ] +
"_gibtag" );
59 gibStruct.gibfx = GetStructField( definition, gibPieceLookup[ gibPieceFlag ] +
"_gibfx" );
60 gibStruct.gibfxtag = GetStructField( definition, gibPieceLookup[ gibPieceFlag ] +
"_gibeffecttag" );
61 gibStruct.gibdynentfx = GetStructField( definition, gibPieceLookup[ gibPieceFlag ] +
"_gibdynentfx" );
62 gibStruct.gibsound = GetStructField( definition, gibPieceLookup[ gibPieceFlag ] +
"_gibsound" );
64 gibBundle.gibs[ gibPieceFlag ] = gibStruct;
67 processedBundles[ definitionName ] = gibBundle;
71 level.scriptbundles[
"gibcharacterdef" ] = processedBundles;
77 #define MIN_DISTANCE_SQ ( 120 * 120 )
82 level waittill(
"corpse_explode", localClientNum, body, origin );
89 if ( IsDefined( body ) &&
_HasGibDef( body ) && body IsRagdoll() )
103 if ( RandomInt( 100 ) >= 50 )
108 if ( IsDefined( origin ) && DistanceSquared( body.origin, origin ) <=
MIN_DISTANCE_SQ )
111 body.ignoreRagdoll =
true;
127 clone.gib_data = SpawnStruct();
130 clone.gib_data.gib_state = entity.gib_state;
131 clone.gib_data.gibdef = entity.gibdef;
134 clone.gib_data.hatmodel = entity.hatmodel;
135 clone.gib_data.head = entity.head;
136 clone.gib_data.legdmg1 = entity.legdmg1;
137 clone.gib_data.legdmg2 = entity.legdmg2;
138 clone.gib_data.legdmg3 = entity.legdmg3;
139 clone.gib_data.legdmg4 = entity.legdmg4;
140 clone.gib_data.torsodmg1 = entity.torsodmg1;
141 clone.gib_data.torsodmg2 = entity.torsodmg2;
142 clone.gib_data.torsodmg3 = entity.torsodmg3;
143 clone.gib_data.torsodmg4 = entity.torsodmg4;
144 clone.gib_data.torsodmg5 = entity.torsodmg5;
149 if ( entity IsPlayer() || entity IsPlayerCorpse() )
151 return entity GetPlayerGibDef();
153 else if ( IsDefined( entity.gib_data ) )
155 return entity.gib_data.gibdef;
158 return entity.gibdef;
163 if ( IsDefined( entity.gib_data ) && IsDefined( entity.gib_data.gib_state ) )
165 return entity.gib_data.gib_state;
167 else if ( IsDefined( entity.gib_state ) )
169 return entity.gib_state;
181 if ( rightLegGibbed && leftLegGibbed)
185 else if ( rightLegGibbed )
189 else if ( leftLegGibbed )
204 AssertMsg(
"Unable to find gib model." );
213 if ( rightArmGibbed && leftArmGibbed )
220 else if ( rightArmGibbed )
224 else if ( leftArmGibbed )
240 gibPiece = gibBundle.gibs[ gibFlag ];
242 if ( IsDefined( gibPiece ) )
244 return gibPiece.gibfxtag;
248 function private _GibEntity( localClientNum, gibFlags, shouldSpawnGibs )
261 if ( entity IsPlayer() || entity IsPlayerCorpse() )
266 gibDir = AnglesToForward( ( 0, yaw, 0 ) );
272 while ( gibFlags >= currentGibFlag )
274 if ( gibFlags & currentGibFlag )
276 gibPiece = gibBundle.gibs[ currentGibFlag ];
278 if ( IsDefined( gibPiece ) )
280 if ( shouldSpawnGibs )
282 entity thread
_GibPiece( localClientNum, entity, gibPiece.gibmodel, gibPiece.gibtag, gibPiece.gibdynentfx, gibDir );
285 _PlayGibFX( localClientNum, entity, gibPiece.gibfx, gibPiece.gibfxtag );
291 entity.ignoreRagdoll =
true;
298 currentGibFlag = currentGibFlag << 1;
306 if ( IsDefined( entity.gib_data ) )
308 entity.gib_data.gib_state = gib_state;
312 entity.gib_state = gib_state;
323 if ( !IsDefined( entity ) || !
_HasGibDef( entity ) )
328 if ( entity.type !==
"scriptmover" )
334 if (
IsGibbed( localClientNum, entity, gibFlag ) )
342 entity Detach( legModel,
"" );
350 entity
_GibEntity( localClientNum, gibFlag,
true );
360 if ( !IsDefined( entity ) )
365 if ( entity.type !==
"scriptmover" )
371 if (
IsGibbed( localClientNum, entity, gibFlag ) )
378 if ( IsDefined( gibModel ) && entity IsAttached( gibModel,
"" ) )
380 entity Detach( gibModel,
"" );
392 entity
_GibEntity( localClientNum, gibFlag,
true );
395 function private _GibHandler( localClientNum, oldValue, newValue, bNewEnt, bInitialSnap, fieldName, wasDemoJump )
399 if ( entity IsPlayer() || entity IsPlayerCorpse() )
408 if ( IsDefined( entity.maturegib ) && entity.maturegib && !
util::is_mature() )
413 if ( IsDefined( entity.restrictedgib ) && entity.restrictedgib && !IsShowGibsEnabled() )
428 entity
_GibEntity( localClientNum, gibFlags, shouldSpawnGibs );
430 entity.gib_state = newValue;
433 function _GibPiece( localClientNum, entity, gibModel, gibTag, gibFx, gibDir )
435 if ( !IsDefined( gibTag ) || !IsDefined( gibModel ) )
440 startPosition = entity GetTagOrigin( gibTag );
441 startAngles = entity GetTagAngles( gibTag );
442 endPosition = startPosition;
443 endAngles = startAngles;
444 forwardVector = undefined;
446 if ( !IsDefined( startPosition ) || !IsDefined( startAngles ) )
451 if ( IsDefined( gibDir ) )
453 startPosition = (0,0,0);
454 forwardVector = gibDir;
456 forwardVector *= RandomFloatRange( 100.0, 500.0 );
463 if ( IsDefined( entity ) )
465 endPosition = entity GetTagOrigin( gibTag );
466 endAngles = entity GetTagAngles( gibTag );
471 endPosition = startPosition + ( AnglesToForward( startAngles ) * 10 );
472 endAngles = startAngles;
475 if ( !IsDefined( endPosition ) || !IsDefined( endAngles ) )
480 forwardVector = VectorNormalize( endPosition - startPosition );
481 forwardVector *= RandomFloatRange( 0.6, 1.0 );
482 forwardVector += ( RandomFloatRange( 0, 0.2 ), RandomFloatRange( 0, 0.2 ), RandomFloatRange( 0.2, 0.7 ) );
485 if( IsDefined( entity ) )
487 gibEntity = CreateDynEntAndLaunch( localClientNum, gibModel, endPosition, endAngles, startPosition, forwardVector, gibFx,
true );
488 if ( IsDefined( gibEntity ) )
490 SetDynEntBodyRenderOptionsPacked( gibEntity, entity GetBodyRenderOptionsPacked() );
497 if ( IsDefined( entity._gibCallbacks ) &&
498 IsDefined( entity._gibCallbacks[gibFlag] ) )
500 foreach (
callback in entity._gibCallbacks[gibFlag] )
502 [[
callback]]( localClientNum, entity, gibFlag );
510 entity endon(
"entityshutdown" );
512 entity waittillmatch(
"_anim_notify_",
"gib_annihilate" );
519 entity endon(
"entityshutdown" );
521 entity waittillmatch(
"_anim_notify_",
"gib = \"head\"" );
528 entity endon(
"entityshutdown" );
530 entity waittillmatch(
"_anim_notify_",
"gib = \"arm_right\"" );
537 entity endon(
"entityshutdown" );
539 entity waittillmatch(
"_anim_notify_",
"gib = \"arm_left\"" );
546 entity endon(
"entityshutdown" );
548 entity waittillmatch(
"_anim_notify_",
"gib = \"leg_right\"" );
555 entity endon(
"entityshutdown" );
557 entity waittillmatch(
"_anim_notify_",
"gib = \"leg_left\"" );
563 return ( IsDefined( entity.gib_data ) && IsDefined( entity.gib_data.gibdef ) ) ||
564 IsDefined( entity.gibdef ) ||
565 ( ( entity GetPlayerGibDef() ) !=
"unknown" );
570 if ( IsDefined( fxFileName ) && IsDefined( fxTag ) && entity hasDobj(localClientNum) )
572 fx = PlayFxOnTag( localClientNum, fxFileName, entity, fxTag );
575 if(isDefined(entity.team))
577 SetFxTeam( localClientNum, fx, entity.team );
580 if(
IS_TRUE( level.SetGibFXToIgnorePause ) )
582 SetFXIgnorePause( localClientNum, fx,
true );
592 if ( IsDefined( soundAlias ) )
594 PlaySound( localClientNum, soundAlias, entity.origin );
610 assert( IsFunctionPtr( callbackFunction ) );
612 if ( !IsDefined( entity._gibCallbacks ) )
614 entity._gibCallbacks = [];
617 if ( !IsDefined( entity._gibCallbacks[gibFlag] ) )
619 entity._gibCallbacks[gibFlag] = [];
622 gibCallbacks = entity._gibCallbacks[gibFlag];
623 gibCallbacks[gibCallbacks.size] = callbackFunction;
624 entity._gibCallbacks[gibFlag] = gibCallbacks;
635 entity.ignoreRagdoll =
true;
684 clone =
Spawn( localClientNum, entity.origin,
"script_model" );
685 clone.angles = entity.angles;
706 clone SetModel( entity.model );
746 self _GibEntity( localClientNum, gibFlags,
true );