IW4-Dump-Files/maps/_interactive_objects.gsc

1483 lines
46 KiB
Plaintext

#include maps\_utility;
#include common_scripts\utility;
main()
{
// -- -- -- -- -- -- -- -- --
// EFECTS DEFINITIONS
// -- -- -- -- -- -- -- -- --
flag_init( "no_ai_tv_damage" );
qBarrels = false;
barrels = getentarray( "explodable_barrel", "targetname" );
if ( barrels.size )
qBarrels = true;
barrels = getentarray( "explodable_barrel", "script_noteworthy" );
if ( barrels.size > 0 )
qBarrels = true;
if ( qBarrels )
{
level.breakables_fx[ "barrel" ][ "explode" ] = loadfx( "props/barrelExp" );
level.breakables_fx[ "barrel" ][ "burn_start" ] = loadfx( "props/barrel_ignite" );
level.breakables_fx[ "barrel" ][ "burn" ] = loadfx( "props/barrel_fire_top" );
}
oilspill = getentarray( "oil_spill", "targetname" );
if ( oilspill.size )
{
level.breakables_fx[ "oilspill" ][ "burn" ] = loadfx( "props/barrel_fire" );
level.breakables_fx[ "oilspill" ][ "spark" ] = loadfx( "impacts/small_metalhit_1" );
}
tincans = getentarray( "tincan", "targetname" );
if ( tincans.size )
level.breakables_fx[ "tincan" ] = loadfx( "props/tincan_bounce" );
qBreakables = false;
breakables = getentarray( "breakable", "targetname" );
if ( breakables.size )
qBreakables = true;
breakables = getentarray( "breakable_vase", "targetname" );
if ( breakables.size )
qBreakables = true;
breakables = getentarray( "breakable box", "targetname" );
if ( barrels.size )
qBreakables = true;
breakables = getentarray( "breakable box", "script_noteworthy" );
if ( barrels.size )
qBreakables = true;
if ( qBreakables )
{
level.breakables_fx[ "vase" ] = loadfx( "props/vase_water" );
level.breakables_fx[ "bottle" ] = loadfx( "props/wine_bottle" );
level.breakables_fx[ "box" ][ 0 ] = loadfx( "props/crateExp_dust" );
level.breakables_fx[ "box" ][ 1 ] = loadfx( "props/crateExp_dust" );
level.breakables_fx[ "box" ][ 2 ] = loadfx( "props/crateExp_dust" );
level.breakables_fx[ "box" ][ 3 ] = loadfx( "props/crateExp_ammo" );
}
glassarray = getentarray( "glass", "targetname" );
glassarray = array_combine( glassarray, getentarray( "glass", "script_noteworthy" ) );
if ( glassarray.size )
{
level._glass_info = [];
level._glass_info[ "glass_large" ][ "breakfx" ] = loadfx( "props/car_glass_large" );
level._glass_info[ "glass_large" ][ "breaksnd" ] = "veh_glass_break_large";
level._glass_info[ "glass_med" ][ "breakfx" ] = loadfx( "props/car_glass_med" );
level._glass_info[ "glass_med" ][ "breaksnd" ] = "veh_glass_break_small";
level._glass_info[ "glass_small" ][ "breakfx" ] = loadfx( "props/car_glass_headlight" );
level._glass_info[ "glass_small" ][ "breaksnd" ] = "veh_glass_break_small";
}
tv_array = getentarray( "interactive_tv", "targetname" );
if ( tv_array.size )
{
precachemodel( "com_tv2_d" );
precachemodel( "com_tv1" );
precachemodel( "com_tv2" );
precachemodel( "com_tv1_testpattern" );
precachemodel( "com_tv2_testpattern" );
level.breakables_fx[ "tv_explode" ] = loadfx( "explosions/tv_explosion" );
}
level.tv_lite_array = getentarray( "interactive_tv_light", "targetname" );
security_camera_array = getentarray( "destroyable_security_camera", "script_noteworthy" );
if ( security_camera_array.size )
{
precachemodel( "com_security_camera" );
precachemodel( "com_security_camera_destroyed" );
level.breakables_fx[ "security_camera_explode" ] = loadfx( "props/securitycamera_explosion" );
}
// -- -- -- -- -- -- -- -- --
// -- -- -- -- -- -- -- -- --
// -- -- -- -- -- -- -- -- -
// SOUND DEFINITIONS
// -- -- -- -- -- -- -- -- -
level.barrelExpSound = "barrel_mtl_explode";
// -- -- -- -- -- -- -- -- -
// -- -- -- -- -- -- -- -- -
// -- -- -- -- -- -- -
// MISC SETTINGS
// -- -- -- -- -- -- -
maxBrokenPieces = 25;
level.breakables_peicesCollide[ "orange vase" ] = true;
level.breakables_peicesCollide[ "green vase" ] = true;
level.breakables_peicesCollide[ "bottle" ] = true;
//* * * * * * * * * * * * * IF YOU PUT THIS BACK IN - SEARCH FOR "PLATE WAIT" AND PUT THAT BACK IN TOO * * * * * * * * * * * * *
// level.breakables_peicesCollide[ "plate" ] = true;
//* * * * * * * * * * * * * IF YOU PUT THIS BACK IN - SEARCH FOR "PLATE WAIT" AND PUT THAT BACK IN TOO * * * * * * * * * * * * *
level.barrelHealth = 150;
// -- -- -- -- -- -- -
// -- -- -- -- -- -- -
level.precachemodeltype = [];
level.barrelExplodingThisFrame = false;
level.breakables_clip = [];
level.breakables_clip = getentarray( "vase_break_remove", "targetname" );
level.console_auto_aim = [];
level.console_auto_aim = getentarray( "xenon_auto_aim", "targetname" );
level.console_auto_aim_2nd = getentarray( "xenon_auto_aim_secondary", "targetname" );
for ( i = 0;i < level.console_auto_aim.size;i++ )
level.console_auto_aim[ i ] notsolid();
for ( i = 0;i < level.console_auto_aim_2nd.size;i++ )
level.console_auto_aim_2nd[ i ] notsolid();
maps\_utility::set_console_status();
if ( level.console )
{
level.console_auto_aim = undefined;
level.console_auto_aim_2nd = undefined;
}
temp = getentarray( "breakable clip", "targetname" );
for ( i = 0;i < temp.size;i++ )
level.breakables_clip[ level.breakables_clip.size ] = temp[ i ];
level._breakable_utility_modelarray = [];
level._breakable_utility_modelindex = 0;
level._breakable_utility_maxnum = maxBrokenPieces;
array_thread( getentarray( "tincan", "targetname" ), ::tincan_think );
array_thread( getentarray( "helmet_pop", "targetname" ), ::helmet_pop );
array_thread( getentarray( "explodable_barrel", "targetname" ), ::explodable_barrel_think );
array_thread( getentarray( "explodable_barrel", "script_noteworthy" ), ::explodable_barrel_think );
array_thread( getentarray( "shuddering_entity", "targetname" ), ::shuddering_entity_think );
array_thread( getentarray( "breakable box", "targetname" ), ::breakable_think );
array_thread( getentarray( "breakable box", "script_noteworthy" ), ::breakable_think );
array_thread( getentarray( "breakable", "targetname" ), ::breakable_think );
array_thread( getentarray( "breakable_vase", "targetname" ), ::breakable_think );
array_thread( getentarray( "oil_spill", "targetname" ), ::oil_spill_think );
array_thread( getentarray( "glass", "targetname" ), ::glass_logic );
array_thread( getentarray( "interactive_tv", "targetname" ), ::tv_logic );
array_thread( getentarray( "destroyable_security_camera", "script_noteworthy" ), ::security_camera_logic );
}
security_camera_logic()
{
self setcandamage( true );
damagemodel = undefined;
switch( self.model )
{
case "com_security_camera":
damagemodel = "com_security_camera_destroyed";
break;
}
self waittill( "damage", damage, other, direction_vec, P, type );
self setmodel( damagemodel );
// nice to play a sound here to acompany the effect
playfxontag( level.breakables_fx[ "security_camera_explode" ], self, "tag_deathfx" );
}
tv_logic()
{
self setcandamage( true );
self.damagemodel = undefined;
self.offmodel = undefined;
self.damagemodel = "com_tv2_d";
self.offmodel = "com_tv2";
self.onmodel = "com_tv2_testpattern";
if ( issubstr( self.model, "1" ) )
{
self.offmodel = "com_tv1";
self.onmodel = "com_tv1_testpattern";
}
if ( isdefined( self.target ) )
{
if ( isdefined( level.disable_interactive_tv_use_triggers ) )
{
usetrig = getent( self.target, "targetname" );
if ( isdefined( usetrig ) )
usetrig delete();
}
else
{
self.usetrig = getent( self.target, "targetname" );
self.usetrig usetriggerrequirelookat();
self.usetrig setcursorhint( "HINT_NOICON" );
}
}
array = get_array_of_closest( self.origin, level.tv_lite_array, undefined, undefined, 64 );
if ( array.size )
{
self.lite = array[ 0 ];
level.tv_lite_array = array_remove( level.tv_lite_array, self.lite );
self.liteintensity = self.lite getLightIntensity();
}
self thread tv_damage();
if ( isdefined( self.usetrig ) )
self thread tv_off();
}
tv_off()
{
self.usetrig endon( "death" );
while ( 1 )
{
wait .2;
self.usetrig waittill( "trigger" );
// it would be nice to play a sound here
self notify( "off" );
if ( self.model == self.offmodel )
{
self setmodel( self.onmodel );
if ( isdefined( self.lite ) )
self.lite setLightIntensity( self.liteintensity );
}
else
{
self setmodel( self.offmodel );
if ( isdefined( self.lite ) )
self.lite setLightIntensity( 0 );
}
}
}
tv_damage()
{
for ( ;; )
{
self waittill( "damage", damage, other, direction_vec, P, type );
if ( flag( "no_ai_tv_damage" ) )
{
if ( !isalive( other ) )
continue;
if ( !isplayer( other ) )
continue;
}
break;
}
if ( isdefined( level.tvhook ) )
[[ level.tvhook ]]();
self notify( "off" );
if ( isdefined( self.usetrig ) )
self.usetrig notify( "death" );
self setmodel( self.damagemodel );
if ( isdefined( self.lite ) )
self.lite setLightIntensity( 0 );
playfxontag( level.breakables_fx[ "tv_explode" ], self, "tag_fx" );
self playsound( "tv_shot_burst" );
if ( isdefined( self.usetrig ) )
self.usetrig delete();
}
glass_logic()
{
direction_vec = undefined;
crackedContents = undefined;
cracked = undefined;
glasshealth = 0;
// setup
if ( isdefined( self.target ) )
{
cracked = getent( self.target, "targetname" );
assertex( isdefined( cracked ), "Destructible glass at origin( " + self.origin + " ) has a target but the cracked version doesn't exist" );
}
if ( isdefined( self.script_linkTo ) )
{
links = self get_links();
assert( isdefined( links ) );
object = getent( links[ 0 ], "script_linkname" );
self linkto( object );
}
assertex( isdefined( self.destructible_type ), "Destructible glass at origin( " + self.origin + " ) doesnt have a destructible_type" );
switch( self.destructible_type )
{
case "glass_large":
break;
case "glass_med":
break;
case "glass_small":
break;
default:
assertMsg( "Destructible glass 'destructible_type' key / value of '" + self.destructible_type + "' is not valid" );
break;
}
if ( isdefined( cracked ) )
{
glasshealth = 99;
cracked linkto( self );
cracked hide();
// Set the contents to 0 to make it non - solid.
// Note "notSolid()" won't work since it forgets the contents.
crackedContents = cracked setContents( 0 );
}
if ( isdefined( self.script_health ) )
glasshealth = self.script_health;
else if ( isdefined( cracked ) )
glasshealth = 99;
else
glasshealth = 250;
// break
self setcandamage( true );
while ( glasshealth > 0 )
{
self waittill( "damage", damage, attacker, direction_vec, point, damageType );
if ( !isdefined( direction_vec ) )
direction_vec = ( 0, 0, 1 );
if ( !isdefined( damageType ) )
damage = 100000;// scripted calls to break the glass
else if ( damageType == "MOD_GRENADE_SPLASH" )
damage = damage * 1.75;
else if ( damageType == "MOD_IMPACT" )
damage = 100000;
glasshealth -= damage;
}
prevdamage = glasshealth * - 1;
self hide();
self notsolid();
if ( isdefined( cracked ) )
{
cracked show();
cracked setcandamage( true );
glasshealth = ( 200 ) - prevdamage;
// Set the contents back so that it's solid
cracked setContents( crackedContents );
while ( glasshealth > 0 )
{
cracked waittill( "damage", damage, other, direction_vec, point, damageType );
if ( !isdefined( direction_vec ) )
direction_vec = ( 0, 0, 1 );
if ( !isdefined( damageType ) )
damage = 100000;// scripted calls to break the glass
else if ( damageType == "MOD_GRENADE_SPLASH" )
damage = damage * 1.75;
else if ( damageType == "MOD_IMPACT" )
break;
glasshealth -= damage;
}
cracked delete();
}
glass_play_break_fx( self getorigin(), self.destructible_type, direction_vec );
self delete();
}
glass_play_break_fx( origin, info, direction_vec )
{
thread play_sound_in_space( level._glass_info[ info ][ "breaksnd" ], origin );
playfx( level._glass_info[ info ][ "breakfx" ], origin, direction_vec );
level notify( "glass_shatter" );
}
oil_spill_think()
{
self.end = getstruct( self.target, "targetname" );
self.start = getstruct( self.end.target, "targetname" );
self.barrel = getClosestEnt( self.start.origin, getentarray( "explodable_barrel", "targetname" ) );
if ( isdefined( self.barrel ) )
{
self.barrel.oilspill = true;
self thread oil_spill_burn_after();
}
self.extra = getent( self.target, "targetname" );
self setcandamage( true );
while ( 1 )
{
self waittill( "damage", amount, attacker, direction_vec, P, type );
if ( type == "MOD_MELEE" || type == "MOD_IMPACT" )
continue;
self.damageOwner = attacker;
playfx( level.breakables_fx[ "oilspill" ][ "spark" ], P, direction_vec );
P = pointOnSegmentNearestToPoint( self.start.origin, self.end.origin, P );
thread oil_spill_burn_section( P );
self thread oil_spill_burn( P, self.start.origin );
self thread oil_spill_burn( P, self.end.origin );
break;
}
if ( isdefined( self.barrel ) )
self.barrel waittill( "exploding" );
self.extra delete();
self hide();
wait 10;
self delete();
}
oil_spill_burn_after()
{
while ( 1 )
{
self.barrel waittill( "damage", amount, attacker, direction_vec, P, type );
if ( type == "MOD_MELEE" || type == "MOD_IMPACT" )
continue;
self.damageOwner = attacker;
break;
}
self radiusdamage( self.start.origin, 4, 10, 10, self.damageOwner );
}
OIL_SPILL_COUNT = 4;
OIL_SPILL_WAIT_TIME = 0.1;
OIL_SPILL_BAD_PLACE_DURATION = 0.5;
oil_spill_burn( P, dest )
{
forward = vectornormalize( dest - P );
dist = distance( p, dest );
range = 8;
interval = vector_multiply( forward, range );
angle = vectortoangles( forward );
right = anglestoright( angle );
barrels = getentarray( "explodable_barrel", "targetname" );
distsqr = 22 * 22;
test = spawn( "script_origin", P );
assert( OIL_SPILL_BAD_PLACE_DURATION > OIL_SPILL_COUNT * OIL_SPILL_WAIT_TIME );
num = 0;
while ( 1 )
{
dist -= range;
if ( dist < range * .1 )
break;
p += ( interval + vector_multiply( right, randomfloatrange( -6, 6 ) ) );
thread oil_spill_burn_section( P );
num++ ;
if ( num == OIL_SPILL_COUNT )
{
badplace_cylinder( "", OIL_SPILL_BAD_PLACE_DURATION, P, 64, 64 );
num = 0;
}
test.origin = P;
remove = [];
barrels = array_removeUndefined( barrels );
for ( i = 0; i < barrels.size; i++ )
{
vec = anglestoup( barrels[ i ].angles );
start = barrels[ i ].origin + ( vector_multiply( vec, 22 ) );
pos = physicstrace( start, start + ( 0, 0, -64 ) );
if ( distancesquared( P, pos ) < distsqr )
{
remove[ remove.size ] = barrels[ i ];
barrels[ i ] dodamage( ( 80 + randomfloat( 10 ) ), P );
}
}
for ( i = 0; i < remove.size; i++ )
barrels = array_remove( barrels, remove[ i ] );
wait OIL_SPILL_WAIT_TIME;
}
if ( !isdefined( self.barrel ) )
return;
if ( distance( P, self.start.origin ) < 32 )
self.barrel dodamage( ( 80 + randomfloat( 10 ) ), P );
}
oil_spill_burn_section( P )
{
count = 0;
time = 0;
playfx( level.breakables_fx[ "oilspill" ][ "burn" ], P );
/*
while ( time < 5 )
{
attacker = undefined;
if ( isdefined( self.damageOwner ) )
attacker = self.damageOwner;
self radiusdamage( P, 32, 5, 1, attacker );
time += 1;
wait 1;
}*/
}
explodable_barrel_think()
{
if ( self.classname != "script_model" )
return;
// if ( ( self.model != "com_barrel_benzin" ) && ( self.model != "com_barrel_benzin_snow" ) )
// return;
if ( !isdefined( level.precachemodeltype[ "com_barrel_benzin" ] ) )
{
level.precachemodeltype[ "com_barrel_benzin" ] = true;
precacheModel( "com_barrel_piece" );
precacheModel( "com_barrel_piece2" );
}
self endon( "exploding" );
self breakable_clip();
self xenon_auto_aim();
self.damageTaken = 0;
self setcandamage( true );
for ( ;; )
{
self waittill( "damage", amount, attacker, direction_vec, P, type );
if ( type == "MOD_MELEE" || type == "MOD_IMPACT" )
continue;
self.damageOwner = attacker;
if ( level.barrelExplodingThisFrame )
wait randomfloat( 1 );
self.damageTaken += amount;
if ( self.damageTaken == amount )
self thread explodable_barrel_burn();
}
}
MAX_COUNT = 19;
WAIT_TIME = 0.05;
BAD_PLACE_DURATION = 1;
explodable_barrel_burn()
{
count = 0;
startedfx = false;
up = anglestoup( self.angles );
worldup = anglestoup( ( 0, 90, 0 ) );
dot = vectordot( up, worldup );
offset1 = ( 0, 0, 0 );
offset2 = vector_multiply( up, 44 );
// if this isn't true, bad place will turn on and off on the barrel
assert( BAD_PLACE_DURATION > MAX_COUNT * WAIT_TIME );
if ( dot < .5 )
{
offset1 = vector_multiply( up, 22 ) - ( 0, 0, 30 );
offset2 = vector_multiply( up, 22 ) + ( 0, 0, 14 );
}
while ( self.damageTaken < level.barrelHealth )
{
if ( !startedfx )
{
playfx( level.breakables_fx[ "barrel" ][ "burn_start" ], self.origin + offset1 );
startedfx = true;
}
if ( count > MAX_COUNT )
count = 0;
playfx( level.breakables_fx[ "barrel" ][ "burn" ], self.origin + offset2 );
if ( count == 0 )
{
self.damageTaken += ( 10 + randomfloat( 10 ) );
badplace_cylinder( "", BAD_PLACE_DURATION, self.origin, 128, 250 );
}
count++;
wait WAIT_TIME;
if( !isdefined( self ) )
return; // support deleting explodable barrels.
}
self thread explodable_barrel_explode();
}
explodable_barrel_explode()
{
self notify( "exploding" );
self notify( "death" );
up = anglestoup( self.angles );
worldup = anglestoup( ( 0, 90, 0 ) );
dot = vectordot( up, worldup );
offset = ( 0, 0, 0 );
if ( dot < .5 )
{
start = ( self.origin + vector_multiply( up, 22 ) );
end = physicstrace( start, ( start + ( 0, 0, -64 ) ) );
offset = end - self.origin;
}
offset += ( 0, 0, 4 );
level thread play_sound_in_space( level.barrelExpSound, self.origin );
playfx( level.breakables_fx[ "barrel" ][ "explode" ], self.origin + offset );
physicsexplosionsphere( self.origin + offset, 100, 80, 1 );
level.barrelExplodingThisFrame = true;
if ( isdefined( self.remove ) )
{
self.remove connectpaths();
self.remove delete();
}
minDamage = 1;
maxDamage = 250;
blastRadius = 250;
if ( isdefined( self.radius ) )
blastRadius = self.radius;
// radiusDamage( self.origin + ( 0, 0, 56 ), blastRadius, maxDamage, minDamage );
attacker = undefined;
if ( isdefined( self.damageOwner ) )
{
attacker = self.damageOwner;
if ( isplayer( attacker ) )
arcadeMode_kill( self.origin, "rifle", 150 );
}
level.lastExplodingBarrel[ "time" ] = getTime();
level.lastExplodingBarrel[ "origin" ] = self.origin + ( 0, 0, 30 );
level.lastExplodingBarrel[ "radius" ] = blastRadius;
self radiusDamage( self.origin + ( 0, 0, 30 ), blastRadius, maxDamage, minDamage, attacker );
if ( randomint( 2 ) == 0 )
self setModel( "com_barrel_piece" );
else
self setModel( "com_barrel_piece2" );
if ( dot < .5 )
{
start = ( self.origin + vector_multiply( up, 22 ) );
pos = physicstrace( start, ( start + ( 0, 0, -64 ) ) );
self.origin = pos;
self.angles += ( 0, 0, 90 );
}
wait 0.05;
level.barrelExplodingThisFrame = false;
}
shuddering_entity_think()
{
assert( self.classname == "script_model" );
helmet = false;
if ( self.model == "prop_helmet_german_normandy" )
helmet = true;
self setcandamage( true );
for ( ;; )
{
self waittill( "damage", other, damage, direction_vec, point );
if ( helmet )
self vibrate( direction_vec, 20, 0.6, 0.75 );
else
self vibrate( direction_vec, 0.4, 0.4, 0.4 );
self waittill( "rotatedone" );
}
}
tincan_think()
{
if ( self.classname != "script_model" )
return;
self setcandamage( true );
self waittill( "damage", damage, ent );
if ( isAI( ent ) || isPlayer( ent ) )
direction_org = ( ( ent getEye() ) - ( 0, 0, ( randomint( 50 ) + 50 ) ) );
else
direction_org = ent.origin;
direction_vec = vectornormalize( self.origin - direction_org );
direction_vec = vector_multiply( direction_vec, .5 + randomfloat( 1 ) );
self notify( "death" );
playfx( level.breakables_fx[ "tincan" ], self.origin, direction_vec );
self delete();
}
helmet_pop()
{
if ( self.classname != "script_model" )
return;
self xenon_auto_aim();
self setcandamage( true );
self thread helmet_logic();
}
helmet_logic()
{
self waittill( "damage", damage, ent );
if ( isAI( ent ) )
direction_org = ent getEye();
else
direction_org = ent.origin;
direction_vec = vectornormalize( self.origin - direction_org );
if ( !isdefined( self.dontremove ) && isplayer( ent ) )
{
self thread animscripts\death::helmetLaunch( direction_vec );
return;
}
self notsolid();
self hide();
model = spawn( "script_model", self.origin + ( 0, 0, 5 ) );
model.angles = self.angles;
model setmodel( self.model );
model thread animscripts\death::helmetLaunch( direction_vec );
self.dontremove = false;
self notify( "ok_remove" );
}
allowBreak( ent )
{
if ( !isdefined( level.breakingEnts ) )
return true;
if ( level.breakingEnts.size == 0 )
return false;
else
{
for ( i = 0;i < level.breakingEnts.size;i++ )
{
if ( ent == level.breakingEnts[ i ] )
return true;
}
return false;
}
return true;
}
breakable_think_triggered( eBreakable )
{
for ( ;; )
{
self waittill( "trigger", other );
eBreakable notify( "damage", 100, other );
}
}
breakable_think()
{
if ( self.classname != "script_model" )
return;
if ( !isdefined( self.model ) )
return;
type = undefined;
if ( self.model == "egypt_prop_vase1" || self.model == "egypt_prop_vase3" || self.model == "egypt_prop_vase4" )
{
if ( !isdefined( level.precachemodeltype[ "egypt_prop_vase_o" ] ) )
{
level.precachemodeltype[ "egypt_prop_vase_o" ] = true;
precacheModel( "egypt_prop_vase_br2" );
precacheModel( "egypt_prop_vase_br5" );
precacheModel( "egypt_prop_vase_br7" );
}
type = "orange vase";
self breakable_clip();
self xenon_auto_aim();
}
else if ( self.model == "egypt_prop_vase2" || self.model == "egypt_prop_vase5" || self.model == "egypt_prop_vase6" )
{
if ( !isdefined( level.precachemodeltype[ "egypt_prop_vase_g" ] ) )
{
level.precachemodeltype[ "egypt_prop_vase_g" ] = true;
precacheModel( "egypt_prop_vase_br1" );
precacheModel( "egypt_prop_vase_br3" );
precacheModel( "egypt_prop_vase_br4" );
precacheModel( "egypt_prop_vase_br6" );
}
type = "green vase";
self breakable_clip();
self xenon_auto_aim();
}
else if ( self.model == "prop_crate_dak1" || self.model == "prop_crate_dak2" || self.model == "prop_crate_dak3" || self.model == "prop_crate_dak4" || self.model == "prop_crate_dak5" || self.model == "prop_crate_dak6" || self.model == "prop_crate_dak7" || self.model == "prop_crate_dak8" || self.model == "prop_crate_dak9" )
{
if ( !isdefined( level.precachemodeltype[ "prop_crate_dak_shard" ] ) )
{
level.precachemodeltype[ "prop_crate_dak_shard" ] = true;
precacheModel( "prop_crate_dak_shard" );
}
type = "wood box";
self breakable_clip();
self xenon_auto_aim();
}
else if ( self.model == "prop_winebottle_breakable" )
{
if ( !isdefined( level.precachemodeltype[ "prop_winebottle" ] ) )
{
level.precachemodeltype[ "prop_winebottle" ] = true;
precacheModel( "prop_winebottle_broken_top" );
precacheModel( "prop_winebottle_broken_bot" );
}
type = "bottle";
self xenon_auto_aim();
}
else if ( self.model == "prop_diningplate_roundfloral" )
{
if ( !isdefined( level.precachemodeltype[ "prop_diningplate_brokenfloral" ] ) )
{
level.precachemodeltype[ "prop_diningplate_brokenfloral" ] = true;
precacheModel( "prop_diningplate_brokenfloral1" );
precacheModel( "prop_diningplate_brokenfloral2" );
precacheModel( "prop_diningplate_brokenfloral3" );
precacheModel( "prop_diningplate_brokenfloral4" );
}
type = "plate";
self.plate = "round_floral";
self xenon_auto_aim();
}
else if ( self.model == "prop_diningplate_roundplain" )
{
if ( !isdefined( level.precachemodeltype[ "prop_diningplate_brokenplain" ] ) )
{
level.precachemodeltype[ "prop_diningplate_brokenplain" ] = true;
precacheModel( "prop_diningplate_brokenplain1" );
precacheModel( "prop_diningplate_brokenplain2" );
precacheModel( "prop_diningplate_brokenplain3" );
precacheModel( "prop_diningplate_brokenplain4" );
}
type = "plate";
self.plate = "round_plain";
self xenon_auto_aim();
}
else if ( self.model == "prop_diningplate_roundstack" )
{
if ( !isdefined( level.precachemodeltype[ "prop_diningplate_brokenplain" ] ) )
{
level.precachemodeltype[ "prop_diningplate_brokenplain" ] = true;
precacheModel( "prop_diningplate_brokenplain1" );
precacheModel( "prop_diningplate_brokenplain2" );
precacheModel( "prop_diningplate_brokenplain3" );
precacheModel( "prop_diningplate_brokenplain4" );
}
if ( !isdefined( level.precachemodeltype[ "prop_diningplate_brokenfloral" ] ) )
{
level.precachemodeltype[ "prop_diningplate_brokenfloral" ] = true;
precacheModel( "prop_diningplate_brokenfloral1" );
precacheModel( "prop_diningplate_brokenfloral2" );
precacheModel( "prop_diningplate_brokenfloral3" );
precacheModel( "prop_diningplate_brokenfloral4" );
}
type = "plate";
self.plate = "round_stack";
self xenon_auto_aim();
}
else if ( self.model == "prop_diningplate_ovalfloral" )
{
if ( !isdefined( level.precachemodeltype[ "prop_diningplate_brokenfloral" ] ) )
{
level.precachemodeltype[ "prop_diningplate_brokenfloral" ] = true;
precacheModel( "prop_diningplate_brokenfloral1" );
precacheModel( "prop_diningplate_brokenfloral2" );
precacheModel( "prop_diningplate_brokenfloral3" );
precacheModel( "prop_diningplate_brokenfloral4" );
}
type = "plate";
self.plate = "oval_floral";
self xenon_auto_aim();
}
else if ( self.model == "prop_diningplate_ovalplain" )
{
if ( !isdefined( level.precachemodeltype[ "prop_diningplate_brokenplain" ] ) )
{
level.precachemodeltype[ "prop_diningplate_brokenplain" ] = true;
precacheModel( "prop_diningplate_brokenplain1" );
precacheModel( "prop_diningplate_brokenplain2" );
precacheModel( "prop_diningplate_brokenplain3" );
precacheModel( "prop_diningplate_brokenplain4" );
}
type = "plate";
self.plate = "oval_plain";
self xenon_auto_aim();
}
else if ( self.model == "prop_diningplate_ovalstack" )
{
if ( !isdefined( level.precachemodeltype[ "prop_diningplate_brokenplain" ] ) )
{
level.precachemodeltype[ "prop_diningplate_brokenplain" ] = true;
precacheModel( "prop_diningplate_brokenplain1" );
precacheModel( "prop_diningplate_brokenplain2" );
precacheModel( "prop_diningplate_brokenplain3" );
precacheModel( "prop_diningplate_brokenplain4" );
}
if ( !isdefined( level.precachemodeltype[ "prop_diningplate_brokenfloral" ] ) )
{
level.precachemodeltype[ "prop_diningplate_brokenfloral" ] = true;
precacheModel( "prop_diningplate_brokenfloral1" );
precacheModel( "prop_diningplate_brokenfloral2" );
precacheModel( "prop_diningplate_brokenfloral3" );
precacheModel( "prop_diningplate_brokenfloral4" );
}
type = "plate";
self.plate = "oval_stack";
self xenon_auto_aim();
}
if ( !isdefined( type ) )
{
println( "Entity ", self.targetname, " at ", self.origin, " is not a valid breakable object." );
return;
}
if ( isdefined( self.target ) )
{
trig = getent( self.target, "targetname" );
if ( ( isdefined( trig ) ) && ( trig.classname == "trigger_multiple" ) )
trig thread breakable_think_triggered( self );
}
self setcandamage( true );
self thread breakable_logic( type );
}
breakable_logic( type )
{
ent = undefined;
for ( ;; )
{
self waittill( "damage", amount, ent );
if ( isdefined( ent ) && ent.code_classname == "script_vehicle" )
ent joltbody( self.origin + ( 0, 0, -90 ), .2 );
if ( type == "wood box" )
{
if ( !allowBreak( ent ) )
continue;
if ( ( !isdefined( level.flags ) ) || ( !isdefined( level.flags[ "Breakable Boxes" ] ) ) )
break;
if ( ( isdefined( level.flags[ "Breakable Boxes" ] ) ) && ( level.flags[ "Breakable Boxes" ] == true ) )
break;
continue;
}
break;
}
self notify( "death" );
soundAlias = undefined;
fx = undefined;
hasDependant = false;
switch( type )
{
case "orange vase":
case "green vase":
soundAlias = "bullet_large_vase";
fx = level.breakables_fx[ "vase" ];
break;
case "wood box":
if ( isdefined( level.crateImpactSound ) )
soundAlias = level.crateImpactSound;
else
soundAlias = "bullet_large_vase";
fx = level.breakables_fx[ "box" ][ randomint( level.breakables_fx[ "box" ].size ) ];
hasDependant = true;
break;
case "bottle":
soundAlias = "bullet_small_bottle";
fx = level.breakables_fx[ "bottle" ];
break;
case "plate":
soundAlias = "bullet_small_plate";
break;
}
thread play_sound_in_space( soundAlias, self.origin );
self thread make_broken_peices( self, type );
if ( isdefined( fx ) )
playfx( fx, self.origin );
// certain types should destroy objects sitting on top of them
if ( hasDependant )
{
others = getentarray( "breakable", "targetname" );
for ( i = 0;i < others.size;i++ )
{
other = others[ i ];
// see if it's within 40 units from this box on X or Y
diffX = abs( self.origin[ 0 ] - other.origin[ 0 ] );
diffY = abs( self.origin[ 1 ] - other.origin[ 1 ] );
if ( ( diffX <= 20 ) && ( diffY <= 20 ) )
{
// see if it's above the box( would probably be resting on it )
diffZ = ( self.origin[ 2 ] - other.origin[ 2 ] );
if ( diffZ <= 0 )
other notify( "damage", amount, ent );
}
}
}
if ( isdefined( self.remove ) )
{
self.remove connectpaths();
self.remove delete();
}
if ( !isdefined( self.dontremove ) )
self delete();
else
self.dontremove = false;
self notify( "ok_remove" );
}
xenon_auto_aim()
{
if ( ( isdefined( level.console_auto_aim ) ) && ( level.console_auto_aim.size > 0 ) )
self.autoaim = getClosestAccurantEnt( self.origin, level.console_auto_aim );
if ( isdefined( self.autoaim ) )
{
level.console_auto_aim = array_remove( level.console_auto_aim, self.autoaim );
self thread xenon_remove_auto_aim();
}
}
xenon_auto_aim_stop_logic()
{
self notify( "entered_xenon_auto_aim_stop_logic" );
self endon( "entered_xenon_auto_aim_stop_logic" );
self.autoaim waittill( "xenon_auto_aim_stop_logic" );
self.dontremove = undefined;
}
xenon_remove_auto_aim( wait_message )
{
self thread xenon_auto_aim_stop_logic();
self endon( "xenon_auto_aim_stop_logic" );
self.autoaim endon( "xenon_auto_aim_stop_logic" );
self notify( "xenon_remove_auto_aim" );
self.autoaim thread xenon_enable_auto_aim( wait_message );
self.dontremove = true;
self waittill( "damage", amount, ent );
self.autoaim disableAimAssist();
self.autoaim delete();
if ( self.dontremove )
self waittill( "ok_remove" );
self delete();
}
xenon_enable_auto_aim( wait_message )
{
self endon( "xenon_auto_aim_stop_logic" );
self endon( "death" );
if ( !isdefined( wait_message ) )
wait_message = true;
if ( isdefined( self.script_noteworthy ) && wait_message )
{
string = "enable_xenon_autoaim_" + self.script_noteworthy;
level waittill( string );
}
self.wait_message = false;
if ( isdefined( self.recreate ) && self.recreate == true )
self waittill( "recreate" );
self enableAimAssist();
}
breakable_clip()
{
// targeted brushmodels take priority over proximity based breakables - nate
if ( isdefined( self.target ) )
{
targ = getent( self.target, "targetname" );
if ( targ.classname == "script_brushmodel" )
{
self.remove = targ;
return;
}
}
// setup it's removable clip part
if ( ( isdefined( level.breakables_clip ) ) && ( level.breakables_clip.size > 0 ) )
self.remove = getClosestEnt( self.origin, level.breakables_clip );
if ( isdefined( self.remove ) )
level.breakables_clip = array_remove( level.breakables_clip, self.remove );
}
make_broken_peices( wholepiece, type )
{
rt = anglesToRight( wholepiece.angles );
fw = anglesToForward( wholepiece.angles );
up = anglesToUp( wholepiece.angles );
piece = [];
switch( type )
{
case "orange vase":
piece[ piece.size ] = addpiece( rt, fw, up, -7, 0, 22, wholepiece, ( 0, 0, 0 ), "egypt_prop_vase_br2" );
piece[ piece.size ] = addpiece( rt, fw, up, 13, -6, 28, wholepiece, ( 0, 245.1, 0 ), "egypt_prop_vase_br7" );
piece[ piece.size ] = addpiece( rt, fw, up, 12, 10, 27, wholepiece, ( 0, 180, 0 ), "egypt_prop_vase_br7" );
piece[ piece.size ] = addpiece( rt, fw, up, 3, 2, 0, wholepiece, ( 0, 0, 0 ), "egypt_prop_vase_br5" );
break;
case "green vase":
piece[ piece.size ] = addpiece( rt, fw, up, -6, -1, 26, wholepiece, ( 0, 0, 0 ), "egypt_prop_vase_br1" );
piece[ piece.size ] = addpiece( rt, fw, up, 12, 1, 31, wholepiece, ( 0, 348.5, 0 ), "egypt_prop_vase_br3" );
piece[ piece.size ] = addpiece( rt, fw, up, 6, 13, 29, wholepiece, ( 0, 153.5, 0 ), "egypt_prop_vase_br6" );
piece[ piece.size ] = addpiece( rt, fw, up, 3, 1, 0, wholepiece, ( 0, 0, 0 ), "egypt_prop_vase_br4" );
break;
case "wood box":
piece[ piece.size ] = addpiece( rt, fw, up, -10, 10, 25, wholepiece, ( 0, 0, 0 ), "prop_crate_dak_shard" );
piece[ piece.size ] = addpiece( rt, fw, up, 10, 10, 25, wholepiece, ( 0, 90, 0 ), "prop_crate_dak_shard" );
piece[ piece.size ] = addpiece( rt, fw, up, 10, -10, 25, wholepiece, ( 0, 180, 0 ), "prop_crate_dak_shard" );
piece[ piece.size ] = addpiece( rt, fw, up, -10, -10, 25, wholepiece, ( 0, 270, 0 ), "prop_crate_dak_shard" );
piece[ piece.size ] = addpiece( rt, fw, up, 10, 10, 5, wholepiece, ( 180, 0, 0 ), "prop_crate_dak_shard" );
piece[ piece.size ] = addpiece( rt, fw, up, 10, -10, 5, wholepiece, ( 180, 90, 0 ), "prop_crate_dak_shard" );
piece[ piece.size ] = addpiece( rt, fw, up, -10, -10, 5, wholepiece, ( 180, 180, 0 ), "prop_crate_dak_shard" );
piece[ piece.size ] = addpiece( rt, fw, up, -10, 10, 5, wholepiece, ( 180, 270, 0 ), "prop_crate_dak_shard" );
break;
case "bottle":
piece[ piece.size ] = addpiece( rt, fw, up, 0, 0, 10, wholepiece, ( 0, 0, 0 ), "prop_winebottle_broken_top" ); piece[ piece.size - 1 ].type = "bottle_top";
piece[ piece.size ] = addpiece( rt, fw, up, 0, 0, 0, wholepiece, ( 0, 0, 0 ), "prop_winebottle_broken_bot" ); piece[ piece.size - 1 ].type = "bottle_bot";
break;
case "plate":
{
switch( wholepiece.plate )
{
case "round_floral":
piece[ piece.size ] = addpiece( rt, fw, up, -3, -4, .5, wholepiece, ( 0, 150, 0 ), "prop_diningplate_brokenfloral1" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 3, -2, .5, wholepiece, ( 0, 149.8, 0 ), "prop_diningplate_brokenfloral2" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 1, 2, .5, wholepiece, ( 0, 150.2, 0 ), "prop_diningplate_brokenfloral3" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -4, 2, .5, wholepiece, ( 0, 146.8, 0 ), "prop_diningplate_brokenfloral4" ); piece[ piece.size - 1 ].type = "plate";
break;
case "round_plain":
piece[ piece.size ] = addpiece( rt, fw, up, -3, -4, .5, wholepiece, ( 0, 150, 0 ), "prop_diningplate_brokenplain1" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 3, -2, .5, wholepiece, ( 0, 149.8, 0 ), "prop_diningplate_brokenplain2" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 1, 2, .5, wholepiece, ( 0, 150.2, 0 ), "prop_diningplate_brokenplain3" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -4, 2, .5, wholepiece, ( 0, 146.8, 0 ), "prop_diningplate_brokenplain4" ); piece[ piece.size - 1 ].type = "plate";
break;
case "round_stack":
piece[ piece.size ] = addpiece( rt, fw, up, -3, -4, .5, wholepiece, ( 0, 150, 0 ), "prop_diningplate_brokenfloral1" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 3, -2, .5, wholepiece, ( 0, 149.8, 0 ), "prop_diningplate_brokenfloral2" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 1, 2, .5, wholepiece, ( 0, 150.2, 0 ), "prop_diningplate_brokenfloral3" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -4, 2, .5, wholepiece, ( 0, 146.8, 0 ), "prop_diningplate_brokenfloral4" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -4, 3, 2.5, wholepiece, ( 0, 60, 0 ), "prop_diningplate_brokenplain1" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -1, -3, 2.5, wholepiece, ( 0, 59.8, 0 ), "prop_diningplate_brokenplain2" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 2, -1, 2.5, wholepiece, ( 0, 60.2, 0 ), "prop_diningplate_brokenplain3" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 2, 4, 2.5, wholepiece, ( 0, 56.8, 0 ), "prop_diningplate_brokenplain4" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -3, -4, 4.5, wholepiece, ( 0, 150, 0 ), "prop_diningplate_brokenfloral1" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 3, -2, 4.5, wholepiece, ( 0, 149.8, 0 ), "prop_diningplate_brokenfloral2" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 1, 2, 4.5, wholepiece, ( 0, 150.2, 0 ), "prop_diningplate_brokenfloral3" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -4, 2, 4.5, wholepiece, ( 0, 146.8, 0 ), "prop_diningplate_brokenfloral4" ); piece[ piece.size - 1 ].type = "plate";
break;
case "oval_floral":
piece[ piece.size ] = addpiece( rt, fw, up, 4, -4, .5, wholepiece, ( 0, 205.9, 0 ), "prop_diningplate_brokenfloral1" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -6, 1, .5, wholepiece, ( 0, 352.2, 0 ), "prop_diningplate_brokenfloral2" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 4, 2, .5, wholepiece, ( 0, 150.2, 0 ), "prop_diningplate_brokenfloral3" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -2, 5, .5, wholepiece, ( 0, 102.3, 0 ), "prop_diningplate_brokenfloral4" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -3, -3, .5, wholepiece, ( 0, 246.7, 0 ), "prop_diningplate_brokenfloral4" ); piece[ piece.size - 1 ].type = "plate";
break;
case "oval_plain":
piece[ piece.size ] = addpiece( rt, fw, up, 4, -4, .5, wholepiece, ( 0, 205.9, 0 ), "prop_diningplate_brokenplain1" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -6, 1, .5, wholepiece, ( 0, 352.2, 0 ), "prop_diningplate_brokenplain2" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 4, 2, .5, wholepiece, ( 0, 150.2, 0 ), "prop_diningplate_brokenplain3" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -2, 5, .5, wholepiece, ( 0, 102.3, 0 ), "prop_diningplate_brokenplain4" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -3, -3, .5, wholepiece, ( 0, 246.7, 0 ), "prop_diningplate_brokenplain4" ); piece[ piece.size - 1 ].type = "plate";
break;
case "oval_stack":
piece[ piece.size ] = addpiece( rt, fw, up, 4, -4, .5, wholepiece, ( 0, 205.9, 0 ), "prop_diningplate_brokenfloral1" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -6, 1, .5, wholepiece, ( 0, 352.2, 0 ), "prop_diningplate_brokenfloral2" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 4, 2, .5, wholepiece, ( 0, 150.2, 0 ), "prop_diningplate_brokenfloral3" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -2, 5, .5, wholepiece, ( 0, 102.3, 0 ), "prop_diningplate_brokenfloral4" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -3, -3, .5, wholepiece, ( 0, 246.7, 0 ), "prop_diningplate_brokenfloral4" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -4, 5, 2.5, wholepiece, ( 0, 25.9, 0 ), "prop_diningplate_brokenplain1" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 6, 0, 2.5, wholepiece, ( 0, 172.2, 0 ), "prop_diningplate_brokenplain2" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, -4, -1, 2.5, wholepiece, ( 0, 330.2, 0 ), "prop_diningplate_brokenplain3" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 2, -4, 2.5, wholepiece, ( 0, 282.3, 0 ), "prop_diningplate_brokenplain4" ); piece[ piece.size - 1 ].type = "plate";
piece[ piece.size ] = addpiece( rt, fw, up, 3, 4, 2.5, wholepiece, ( 0, 66.7, 0 ), "prop_diningplate_brokenplain4" ); piece[ piece.size - 1 ].type = "plate";
break;
}
}break;
default:
return;
}
array_thread( piece, ::pieces_move, wholepiece.origin );
if ( ( isdefined( level.breakables_peicesCollide[ type ] ) ) && ( level.breakables_peicesCollide[ type ] == true ) )
{
height = piece[ 0 ].origin[ 2 ];
for ( i = 0; i < piece.size; i++ )
{
if ( height > piece[ i ].origin[ 2 ] )
height = piece[ i ].origin[ 2 ];
}
array_thread( piece, ::pieces_collision, height );
}
else
{
wait 2;
for ( i = 0;i < piece.size;i++ )
{
if ( isdefined( piece[ i ] ) )
piece[ i ] delete();
}
}
}
list_add( model )
{
if ( isdefined( level._breakable_utility_modelarray[ level._breakable_utility_modelindex ] ) )
level._breakable_utility_modelarray[ level._breakable_utility_modelindex ] delete();
level._breakable_utility_modelarray[ level._breakable_utility_modelindex ] = model;
level._breakable_utility_modelindex++ ;
if ( !( level._breakable_utility_modelindex < level._breakable_utility_maxnum ) )
level._breakable_utility_modelindex = 0;
}
pieces_move( origin )
{
self endon( "do not kill" );
if ( isdefined( self.type ) && self.type == "bottle_bot" )
return;
org = spawn( "script_origin", self.origin );
self linkto( org );
end = self.origin + ( randomfloat( 10 ) - 5, randomfloat( 10 ) - 5, randomfloat( 10 ) + 5 );
// end = self.origin + ( randomfloat( 50 ) - 25, randomfloat( 50 ) - 25, randomfloat( 50 ) + 25 );
vec = undefined;
if ( isdefined( self.type ) && self.type == "bottle_top" )
{
vec = ( randomfloat( 40 ) - 20, randomfloat( 40 ) - 20, 70 + randomfloat( 15 ) );
x = 1;
y = 1;
z = 1;
if ( randomint( 100 ) > 50 )
x = -1;
if ( randomint( 100 ) > 50 )
y = -1;
if ( randomint( 100 ) > 50 )
z = -1;
org rotatevelocity( ( 250 * x, 250 * y, randomfloat( 100 ) * z ), 2, 0, .5 );
}
else if ( isdefined( self.type ) && self.type == "plate" )
{
vec = vectornormalize( end - origin );
vec = vector_multiply( vec, 125 + randomfloat( 25 ) );
if ( randomint( 100 ) > 50 )
org rotateroll( ( 800 + randomfloat( 4000 ) ) * - 1, 5, 0, 0 );
else
org rotateroll( 800 + randomfloat( 4000 ), 5, 0, 0 );
}
else
{
vec = vectornormalize( end - origin );
vec = vector_multiply( vec, 60 + randomfloat( 50 ) );
if ( randomint( 100 ) > 50 )
org rotateroll( ( 800 + randomfloat( 1000 ) ) * - 1, 5, 0, 0 );
else
org rotateroll( 800 + randomfloat( 1000 ), 5, 0, 0 );
}
org moveGravity( vec, 5 );
wait 5;
if ( isdefined( self ) )
self unlink();
org delete();
}
pieces_collision( height )
{
self endon( "death" );
//* * * * * * * * * * * * * IF YOU PUT THIS BACK IN - SEARCH FOR "PLATE WAIT" AND PUT THAT BACK IN TOO * * * * * * * * * * * * *
// if ( isdefined( self.type ) && self.type == "plate" )
// wait .35;
// else
//* * * * * * * * * * * * * IF YOU PUT THIS BACK IN - SEARCH FOR "PLATE WAIT" AND PUT THAT BACK IN TOO * * * * * * * * * * * * *
wait .1;
trace = bullettrace( self.origin, self.origin - ( 0, 0, 50000 ), false, undefined );
vec = trace[ "position" ];
while ( self.origin[ 2 ] > vec[ 2 ] )
wait .05;
self unlink();
self.origin = ( self.origin[ 0 ], self.origin[ 1 ], vec[ 2 ] );
self notify( "do not kill" );
self unlink();
}
addpiece( rt, fw, up, xs, ys, zs, wholepiece, angles, model )
{
scale = 1;
// if ( isdefined( wholepiece.modelscale ) )
// scale = wholepiece.modelscale;
x = rt;
y = fw;
z = up;
x = vector_multiply( x, ys * scale );
y = vector_multiply( y, xs * scale );
z = vector_multiply( z, zs * scale );
origin = wholepiece.origin + x + y + z;
part = spawn( "script_model", origin );
part setmodel( model );
part.modelscale = scale;
part.angles = wholepiece.angles + angles;
list_add( part );
return part;
}
getFurthestEnt( org, array )
{
if ( array.size < 1 )
return;
dist = distance( array[ 0 ] getorigin(), org );
ent = array[ 0 ];
// dist = 256;
// ent = undefined;
for ( i = 0;i < array.size;i++ )
{
newdist = distance( array[ i ] getorigin(), org );
if ( newdist < dist )
continue;
dist = newdist;
ent = array[ i ];
}
return ent;
}
getClosestEnt( org, array )
{
if ( array.size < 1 )
return;
// dist = distance( array[ 0 ] getorigin(), org );
// ent = array[ 0 ];
dist = 256;
ent = undefined;
for ( i = 0;i < array.size;i++ )
{
newdist = distance( array[ i ] getorigin(), org );
if ( newdist >= dist )
continue;
dist = newdist;
ent = array[ i ];
}
return ent;
}
getClosestAccurantEnt( org, array )
{
if ( array.size < 1 )
return;
// dist = distance( array[ 0 ] getorigin(), org );
// ent = array[ 0 ];
dist = 8;
ent = undefined;
for ( i = 0;i < array.size;i++ )
{
newdist = distance( array[ i ] getorigin(), org );
if ( newdist >= dist )
continue;
dist = newdist;
ent = array[ i ];
}
return ent;
}
getClosestAimEnt( org, array )
{
if ( array.size < 1 )
return;
// dist = distance( array[ 0 ] getorigin(), org );
// ent = array[ 0 ];
dist = 1000000;
ent = undefined;
for ( i = 0;i < array.size;i++ )
{
newdist = distance( array[ i ] getorigin(), org );
if ( newdist >= dist )
continue;
dist = newdist;
ent = array[ i ];
}
return ent;
}