627 lines
No EOL
16 KiB
Text
627 lines
No EOL
16 KiB
Text
#include common_scripts\utility;
|
|
#include maps\mp\gametypes\_missions;
|
|
|
|
precache_gib_fx()
|
|
{
|
|
level.lastGibTime = 0;
|
|
level.gibDelay = 3 * 1000; // 3 seconds
|
|
level.minGibs = 2;
|
|
level.maxGibs = 4;
|
|
level.totalGibs = RandomIntRange( level.minGibs, level.maxGibs );
|
|
level._effect["animscript_gib_fx"] = LoadFx( "weapon/bullet/fx_flesh_gib_fatal_01_mp" );
|
|
level._effect["animscript_gibtrail_fx"] = LoadFx( "trail/fx_trail_blood_streak_mp" );
|
|
}
|
|
|
|
do_gib( iDamage, sMeansOfDeath, weapon )
|
|
{
|
|
if ( do_explosive_gib( iDamage, sMeansOfDeath, weapon ) || do_bullet_gib( iDamage, sMeansOfDeath, weapon ))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
do_explosive_gib( iDamage, sMeansOfDeath, weapon, sHitLoc, vAttackerOrigin )
|
|
{
|
|
if ( weapon == "m8_white_smoke_mp" )
|
|
return false;
|
|
|
|
if ( weapon == "tabun_gas_mp" )
|
|
return false;
|
|
|
|
if ( weapon == "signal_flare_mp" )
|
|
return false;
|
|
|
|
if ( weapon == "molotov_mp" )
|
|
return false;
|
|
|
|
if ( sMeansOfDeath == "MOD_EXPLOSIVE" ||
|
|
sMeansOfDeath == "MOD_GRENADE" ||
|
|
sMeansOfDeath == "MOD_GRENADE_SPLASH" ||
|
|
sMeansOfDeath == "MOD_PROJECTILE" ||
|
|
sMeansOfDeath == "MOD_PROJECTILE_SPLASH" ||
|
|
sMeansOfDeath == "MOD_SUICIDE")
|
|
{
|
|
// do the gibs only if the damage was enough to kill the player in one hit
|
|
// even if the were already damaged
|
|
if ( iDamage >= self.maxhealth )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
is_weapon_shotgun( sWeapon )
|
|
{
|
|
if (WeaponClass( sWeapon ) == "spread")
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
do_bullet_gib( iDamage, sMeansOfDeath, sWeapon, sHitLoc, vAttackerOrigin )
|
|
{
|
|
if ( !isdefined( vAttackerOrigin ) )
|
|
return false;
|
|
|
|
if( !isdefined( sHitLoc ) )
|
|
return false;
|
|
|
|
if( sMeansOfDeath == "MOD_MELEE" )
|
|
return false;
|
|
|
|
shotty_gib = is_weapon_shotgun( sWeapon );
|
|
|
|
// shotgun damage is less than 50
|
|
if( iDamage < 35 && !shotty_gib )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
distSquared = DistanceSquared( self.origin, vAttackerOrigin );
|
|
maxDist = 300;
|
|
gib_chance = 50;
|
|
|
|
if( shotty_gib ) // shotgun
|
|
{
|
|
if( distSquared < 110*110 )
|
|
{
|
|
gib_chance = 100;
|
|
}
|
|
else if( distSquared < 200*200 )
|
|
{
|
|
gib_chance = 75;
|
|
}
|
|
else if( distSquared < 270*270 )
|
|
{
|
|
gib_chance = 50;
|
|
}
|
|
else if( distSquared < 330*330 )
|
|
{
|
|
if( RandomInt( 100 ) < 50 )
|
|
{
|
|
gib_chance = 50;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if( isSubStr( sWeapon, "gunner" ) )
|
|
{
|
|
maxDist = 3000;
|
|
}
|
|
else if( issubstr(sWeapon,"mg42") || issubstr(sWeapon,"30cal") ) // heavy weapons
|
|
{
|
|
gib_chance = 30;
|
|
maxDist = 2000;
|
|
}
|
|
else if( issubstr( sWeapon, "ptrs41_" ) )
|
|
{
|
|
maxDist = 3500;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( distSquared < maxDist*maxDist && RandomInt( 100 ) < gib_chance && GetTime() > level.lastGibTime + level.gibDelay )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
get_explosion_gib_ref( direction )
|
|
{
|
|
/#
|
|
// Dvars for testing bigs.
|
|
if( GetDvarInt( "gib_delay" ) > 0 )
|
|
{
|
|
level.gibDelay = GetDvarInt( "gib_delay" );
|
|
}
|
|
|
|
if( GetDvar( "gib_test" ) != "" )
|
|
{
|
|
self.gib_ref = GetDvar( "gib_test" );
|
|
return;
|
|
}
|
|
#/
|
|
|
|
// If already set, then use it. Useful for canned gib deaths.
|
|
// if( IsDefined( self.gib_ref ) )
|
|
// {
|
|
// return;
|
|
// }
|
|
|
|
if( GetTime() > level.lastGibTime + level.gibDelay && level.totalGibs > 0 )
|
|
{
|
|
level.totalGibs--;
|
|
|
|
// MikeD( 5/5/2008 ): Allows multiple guys to GIB at once.
|
|
// level.lastGibTime = GetTime();
|
|
level thread set_last_gib_time();
|
|
|
|
refs = [];
|
|
switch( direction )
|
|
{
|
|
case "left":
|
|
refs[refs.size] = "left_arm";
|
|
refs[refs.size] = "left_leg";
|
|
|
|
gib_ref = get_random( refs );
|
|
break;
|
|
|
|
case "right":
|
|
refs[refs.size] = "right_arm";
|
|
refs[refs.size] = "right_leg";
|
|
|
|
gib_ref = get_random( refs );
|
|
break;
|
|
|
|
case "forward":
|
|
refs[refs.size] = "right_arm";
|
|
refs[refs.size] = "left_arm";
|
|
refs[refs.size] = "right_leg";
|
|
refs[refs.size] = "left_leg";
|
|
refs[refs.size] = "guts";
|
|
refs[refs.size] = "no_legs";
|
|
|
|
gib_ref = get_random( refs );
|
|
break;
|
|
|
|
case "back":
|
|
refs[refs.size] = "right_arm";
|
|
refs[refs.size] = "left_arm";
|
|
refs[refs.size] = "right_leg";
|
|
refs[refs.size] = "left_leg";
|
|
refs[refs.size] = "no_legs";
|
|
|
|
gib_ref = get_random( refs );
|
|
break;
|
|
|
|
default: // "up"
|
|
refs[refs.size] = "right_arm";
|
|
refs[refs.size] = "left_arm";
|
|
refs[refs.size] = "right_leg";
|
|
refs[refs.size] = "left_leg";
|
|
refs[refs.size] = "no_legs";
|
|
refs[refs.size] = "guts";
|
|
|
|
gib_ref = get_random( refs );
|
|
break;
|
|
}
|
|
|
|
|
|
self.gib_ref = gib_ref;
|
|
}
|
|
else
|
|
{
|
|
self.gib_ref = undefined;
|
|
}
|
|
}
|
|
|
|
get_gib_ref_by_direction( damageyaw )
|
|
{
|
|
gib_debug_print( "gibs: damageyaw " + damageyaw );
|
|
|
|
// one in five chance of doing the upwards gib
|
|
if( randomint(5) == 0 || damageyaw == 0)
|
|
{
|
|
gib_debug_print("gibs: gib_ref UP" );
|
|
get_explosion_gib_ref( "up" );
|
|
}
|
|
else
|
|
if( ( damageyaw > 135 ) ||( damageyaw <= -135 ) ) // Front quadrant
|
|
{
|
|
gib_debug_print("gibs: gib_ref FORWARD" );
|
|
get_explosion_gib_ref( "forward" );
|
|
}
|
|
else if( ( damageyaw > 45 ) &&( damageyaw <= 135 ) ) // Right quadrant
|
|
{
|
|
gib_debug_print("gibs: gib_ref RIGHT" );
|
|
get_explosion_gib_ref( "right" );
|
|
}
|
|
else if( ( damageyaw > -45 ) &&( damageyaw <= 45 ) ) // Back quadrant
|
|
{
|
|
gib_debug_print("gibs: gib_ref BACK" );
|
|
get_explosion_gib_ref( "back" );
|
|
}
|
|
else
|
|
{ // Left quadrant
|
|
gib_debug_print("gibs: gib_ref LEFT" );
|
|
get_explosion_gib_ref( "left" );
|
|
}
|
|
}
|
|
|
|
gib_debug_print( text )
|
|
{
|
|
/#
|
|
if( GetDvarInt( "debug_gibs" ) > 0 )
|
|
{
|
|
println(text );
|
|
}
|
|
#/
|
|
}
|
|
|
|
gib_player( iDamage, sMeansOfDeath, sWeapon, sHitLoc, vDamageDir, vAttackerOrigin )
|
|
{
|
|
// if( !is_mature() )
|
|
// {
|
|
// return;
|
|
// }
|
|
|
|
if ( do_explosive_gib( iDamage, sMeansOfDeath, sWeapon, sHitLoc, vAttackerOrigin ) )
|
|
{
|
|
if (isdefined(vDamageDir))
|
|
{
|
|
gib_debug_print( "gibs: angles " + self.angles[1] );
|
|
gib_debug_print( "gibs: vDamageDir " + vectortoangles(vDamageDir)[1] );
|
|
damageyaw = AngleClamp180( vectortoangles(vDamageDir)[1] - self.angles[1] );
|
|
}
|
|
else
|
|
{
|
|
damageyaw = 0;
|
|
}
|
|
get_gib_ref_by_direction(damageyaw);
|
|
}
|
|
else if ( do_bullet_gib( iDamage, sMeansOfDeath, sWeapon, sHitLoc, vAttackerOrigin ) )
|
|
{
|
|
get_bullet_gib_ref( iDamage, sMeansOfDeath, sWeapon, sHitLoc, vDamageDir);
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( !IsDefined( self.gib_ref ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
self maps\mp\gametypes\_weapons::detach_all_weapons();
|
|
flamethrowerTank = self maps\mp\gametypes\_teams::detachFlamethrowerTank();
|
|
|
|
maps\mp\gametypes\_missions::doMissionCallback( "playerGib", self );
|
|
|
|
gib_ref = self.gib_ref;
|
|
|
|
limb_data = get_limb_data( gib_ref );
|
|
|
|
if( !IsDefined( limb_data ) )
|
|
{
|
|
/#
|
|
println( "^3do_gib: - limb_data is not setup for gib_ref on model: " + self.model + " and gib_ref of: " + self.gib_ref );
|
|
#/
|
|
|
|
return false;
|
|
}
|
|
|
|
forward = undefined;
|
|
velocity = undefined;
|
|
|
|
pos1 = [];
|
|
pos2 = [];
|
|
velocities = [];
|
|
|
|
// level thread draw_line( self GetTagOrigin( limb_data["spawn_tags"] ), self GetTagOrigin( limb_data["spawn_tags"] ) + velocity );
|
|
|
|
if ( flamethrowerTank )
|
|
{
|
|
self maps\mp\gametypes\_teams::attachFlamethrowerTank();
|
|
}
|
|
|
|
if( limb_data["spawn_tags"][0] != "" )
|
|
{
|
|
if( isdefined(self.gib_vel) )
|
|
{
|
|
for( i = 0; i < limb_data["spawn_tags"].size; i++ )
|
|
{
|
|
velocities[i] = self.gib_vel;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( i = 0; i < limb_data["spawn_tags"].size; i++ )
|
|
{
|
|
pos1[pos1.size] = self GetTagOrigin( limb_data["spawn_tags"][i] );
|
|
}
|
|
|
|
wait( 0.05 );
|
|
|
|
for( i = 0; i < limb_data["spawn_tags"].size; i++ )
|
|
{
|
|
pos2[pos2.size] = self GetTagOrigin( limb_data["spawn_tags"][i] );
|
|
}
|
|
|
|
for( i = 0; i < pos1.size; i++ )
|
|
{
|
|
forward = VectorNormalize( pos2[i] - pos1[i] );
|
|
velocities[i] = forward * RandomIntRange( 600, 1000 );
|
|
velocities[i] = velocities[i] + ( 0, 0, RandomIntRange( 400, 700 ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
if( IsDefined( limb_data["fx"] ) )
|
|
{
|
|
for( i = 0; i < limb_data["spawn_tags"].size; i++ )
|
|
{
|
|
if( limb_data["spawn_tags"][i] == "" )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
PlayFxOnTag( level._effect[limb_data["fx"]], self, limb_data["spawn_tags"][i] );
|
|
}
|
|
}
|
|
|
|
self PlaySound( "death_gibs" );
|
|
self thread throw_gib( limb_data["spawn_models"], limb_data["spawn_tags"], velocities );
|
|
|
|
// Set the upperbody model
|
|
self SetModel( limb_data["body_model"] );
|
|
|
|
// Attach the legs
|
|
self Attach( limb_data["legs_model"] );
|
|
|
|
if ( gib_ref == "no_legs" )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
get_limb_data( gib_ref )
|
|
{
|
|
temp_array = [];
|
|
|
|
// Slightly faster, store the isdefined stuff before checking, which will be less code-calls.
|
|
torsoDmg1_defined = IsDefined( self.torsoDmg1 );
|
|
torsoDmg2_defined = IsDefined( self.torsoDmg2 );
|
|
torsoDmg3_defined = IsDefined( self.torsoDmg3 );
|
|
torsoDmg4_defined = IsDefined( self.torsoDmg4 );
|
|
torsoDmg5_defined = IsDefined( self.torsoDmg5 );
|
|
legDmg1_defined = IsDefined( self.legDmg1 );
|
|
legDmg2_defined = IsDefined( self.legDmg2 );
|
|
legDmg3_defined = IsDefined( self.legDmg3 );
|
|
legDmg4_defined = IsDefined( self.legDmg4 );
|
|
|
|
gibSpawn1_defined = IsDefined( self.gibSpawn1 );
|
|
gibSpawn2_defined = IsDefined( self.gibSpawn2 );
|
|
gibSpawn3_defined = IsDefined( self.gibSpawn3 );
|
|
gibSpawn4_defined = IsDefined( self.gibSpawn4 );
|
|
gibSpawn5_defined = IsDefined( self.gibSpawn5 );
|
|
|
|
gibSpawnTag1_defined = IsDefined( self.gibSpawnTag1 );
|
|
gibSpawnTag2_defined = IsDefined( self.gibSpawnTag2 );
|
|
gibSpawnTag3_defined = IsDefined( self.gibSpawnTag3 );
|
|
gibSpawnTag4_defined = IsDefined( self.gibSpawnTag4 );
|
|
gibSpawnTag5_defined = IsDefined( self.gibSpawnTag5 );
|
|
|
|
// Right arm is getting blown off! /////////////////////////////////////////////////////
|
|
if( torsoDmg2_defined && legDmg1_defined && gibSpawn1_defined && gibSpawnTag1_defined )
|
|
{
|
|
temp_array["right_arm"]["body_model"] = self.torsoDmg2;
|
|
temp_array["right_arm"]["legs_model"] = self.legDmg1;
|
|
temp_array["right_arm"]["spawn_models"][0] = self.gibSpawn1;
|
|
|
|
temp_array["right_arm"]["spawn_tags"][0] = self.gibSpawnTag1;
|
|
temp_array["right_arm"]["fx"] = "animscript_gib_fx";
|
|
}
|
|
|
|
// Left arm is getting blown off! //////////////////////////////////////////////////////
|
|
if( torsoDmg3_defined && legDmg1_defined && gibSpawn2_defined && gibSpawnTag2_defined )
|
|
{
|
|
temp_array["left_arm"]["body_model"] = self.torsoDmg3;
|
|
temp_array["left_arm"]["legs_model"] = self.legDmg1;
|
|
temp_array["left_arm"]["spawn_models"][0] = self.gibSpawn2;
|
|
|
|
temp_array["left_arm"]["spawn_tags"][0] = self.gibSpawnTag2;
|
|
temp_array["left_arm"]["fx"] = "animscript_gib_fx";
|
|
}
|
|
|
|
// Right leg is getting blown off! ////////////////////////////////////////////////////
|
|
if( torsoDmg1_defined && legDmg2_defined && gibSpawn3_defined && gibSpawnTag3_defined )
|
|
{
|
|
temp_array["right_leg"]["body_model"] = self.torsoDmg1;
|
|
temp_array["right_leg"]["legs_model"] = self.legDmg2;
|
|
temp_array["right_leg"]["spawn_models"][0] = self.gibSpawn3;
|
|
|
|
temp_array["right_leg"]["spawn_tags"][0] = self.gibSpawnTag3;
|
|
temp_array["right_leg"]["fx"] = "animscript_gib_fx";
|
|
}
|
|
|
|
|
|
// Left leg is getting blown off! /////////////////////////////////////////////////////
|
|
if( torsoDmg1_defined && legDmg3_defined && gibSpawn4_defined && gibSpawnTag4_defined )
|
|
{
|
|
temp_array["left_leg"]["body_model"] = self.torsoDmg1;
|
|
temp_array["left_leg"]["legs_model"] = self.legDmg3;
|
|
temp_array["left_leg"]["spawn_models"][0] = self.gibSpawn4;
|
|
|
|
temp_array["left_leg"]["spawn_tags"][0] = self.gibSpawnTag4;
|
|
temp_array["left_leg"]["fx"] = "animscript_gib_fx";
|
|
}
|
|
|
|
// No legs! ///////////////////////////////////////////////////////////////////////////
|
|
if( torsoDmg1_defined && legDmg4_defined && gibSpawn4_defined && gibSpawn3_defined && gibSpawnTag3_defined && gibSpawnTag4_defined )
|
|
{
|
|
temp_array["no_legs"]["body_model"] = self.torsoDmg1;
|
|
temp_array["no_legs"]["legs_model"] = self.legDmg4;
|
|
temp_array["no_legs"]["spawn_models"][0] = self.gibSpawn4;
|
|
temp_array["no_legs"]["spawn_models"][1] = self.gibSpawn3;
|
|
|
|
temp_array["no_legs"]["spawn_tags"][0] = self.gibSpawnTag4;
|
|
temp_array["no_legs"]["spawn_tags"][1] = self.gibSpawnTag3;
|
|
temp_array["no_legs"]["fx"] = "animscript_gib_fx";
|
|
}
|
|
|
|
// Guts! //////////////////////////////////////////////////////////////////////////////
|
|
if( torsoDmg4_defined && legDmg1_defined )
|
|
{
|
|
temp_array["guts"]["body_model"] = self.torsoDmg4;
|
|
temp_array["guts"]["legs_model"] = self.legDmg1;
|
|
|
|
temp_array["guts"]["spawn_models"][0] = "";
|
|
// temp_array["guts"]["spawn_tags"][0] = "J_SpineLower";
|
|
temp_array["guts"]["spawn_tags"][0] = "";
|
|
temp_array["guts"]["fx"] = "animscript_gib_fx";
|
|
}
|
|
|
|
// Head! //////////////////////////////////////////////////////////////////////////////
|
|
if( torsoDmg5_defined && legDmg1_defined )
|
|
{
|
|
temp_array["head"]["body_model"] = self.torsoDmg5;
|
|
temp_array["head"]["legs_model"] = self.legDmg1;
|
|
|
|
if( gibSpawn5_defined && gibSpawnTag5_defined )
|
|
{
|
|
temp_array["head"]["spawn_models"][0] = self.gibSpawn5;
|
|
temp_array["head"]["spawn_tags"][0] = self.gibSpawnTag5;
|
|
}
|
|
else
|
|
{
|
|
temp_array["head"]["spawn_models"][0] = "";
|
|
temp_array["head"]["spawn_tags"][0] = "";
|
|
}
|
|
temp_array["head"]["fx"] = "animscript_gib_fx";
|
|
}
|
|
if( IsDefined( temp_array[gib_ref] ) )
|
|
{
|
|
return temp_array[gib_ref];
|
|
}
|
|
else
|
|
{
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
throw_gib( spawn_models, spawn_tags, velocities )
|
|
{
|
|
if( velocities.size < 1 ) // For guts
|
|
{
|
|
return;
|
|
}
|
|
|
|
for( i = 0; i < spawn_models.size; i++ )
|
|
{
|
|
origin = self GetTagOrigin( spawn_tags[i] );
|
|
angles = self GetTagAngles( spawn_tags[i] );
|
|
CreateDynEntAndLaunch( spawn_models[i], origin, angles, origin, velocities[i], level._effect["animscript_gibtrail_fx"] );
|
|
// gib = Spawn( "script_model", self GetTagOrigin( spawn_tags[i] ) );
|
|
// gib.angles = self GetTagAngles( spawn_tags[i] );
|
|
// gib SetModel( spawn_models[i] );
|
|
//
|
|
// // Play trail fX
|
|
// PlayFxOnTag( level._effect["animscript_gibtrail_fx"], gib, "tag_fx" );
|
|
//
|
|
// gib PhysicsLaunch( self.origin, velocities[i] );
|
|
//
|
|
// gib thread gib_delete();
|
|
}
|
|
}
|
|
|
|
gib_delete()
|
|
{
|
|
wait( 10 + RandomFloat( 5 ) );
|
|
self Delete();
|
|
}
|
|
|
|
get_random( array )
|
|
{
|
|
return array[RandomInt( array.size )];
|
|
}
|
|
|
|
set_last_gib_time()
|
|
{
|
|
level notify( "stop_last_gib_time" );
|
|
level endon( "stop_last_gib_time" );
|
|
|
|
wait( 0.05 );
|
|
level.lastGibTime = GetTime();
|
|
level.totalGibs = RandomIntRange( level.minGibs, level.maxGibs );
|
|
}
|
|
|
|
get_bullet_gib_ref(iDamage, sMeansOfDeath, sWeapon, sHitLoc, vDir)
|
|
{
|
|
self.gib_ref = undefined;
|
|
|
|
level.lastGibTime = GetTime();
|
|
|
|
refs = [];
|
|
switch( sHitLoc )
|
|
{
|
|
case "torso_upper":
|
|
case "torso_lower":
|
|
refs[refs.size] = "guts";
|
|
refs[refs.size] = "right_arm";
|
|
refs[refs.size] = "left_arm";
|
|
break;
|
|
case "right_arm_upper":
|
|
case "right_arm_lower":
|
|
case "right_hand":
|
|
refs[refs.size] = "right_arm";
|
|
break;
|
|
case "left_arm_upper":
|
|
case "left_arm_lower":
|
|
case "left_hand":
|
|
refs[refs.size] = "left_arm";
|
|
break;
|
|
case "right_leg_upper":
|
|
case "right_leg_lower":
|
|
case "right_foot":
|
|
refs[refs.size] = "right_leg";
|
|
refs[refs.size] = "no_legs";
|
|
break;
|
|
case "left_leg_upper":
|
|
case "left_leg_lower":
|
|
case "left_foot":
|
|
refs[refs.size] = "left_leg";
|
|
refs[refs.size] = "no_legs";
|
|
break;
|
|
case "helmet":
|
|
case "head":
|
|
refs[refs.size] = "head";
|
|
break;
|
|
}
|
|
|
|
if( refs.size )
|
|
{
|
|
self.gib_ref = get_random( refs );
|
|
/#
|
|
println("GIBS: " + sHitLoc + " " + self.gib_ref );
|
|
#/
|
|
}
|
|
|
|
range = 600;
|
|
nrange = -600;
|
|
self.gib_vel = vDir * RandomIntRange( 500, 900 );
|
|
self.gib_vel += ( RandomIntRange( nrange, range ), RandomIntRange( nrange, range ), RandomIntRange( 400, 1000 ) );
|
|
} |