1385 lines
37 KiB
Plaintext
1385 lines
37 KiB
Plaintext
#include common_scripts\utility;
|
|
#include maps\_utility;
|
|
|
|
main()
|
|
{
|
|
/*
|
|
mortars = getentarray ("mortar","targetname");
|
|
for (i=0;i<mortars.size;i++)
|
|
mortars[i] thread burnville_style_mortar();
|
|
|
|
if ( !(isdefined (level.mortar) ) )
|
|
error ("level.mortar not defined. define in level script");
|
|
|
|
thread generic_style_init();
|
|
*/
|
|
}
|
|
|
|
hurtgen_style()
|
|
{
|
|
// One mortar within x distance goes off every x seconds but not within x units of the player
|
|
|
|
mortars = getentarray( "mortar", "targetname" );
|
|
lastmortar = -1;
|
|
|
|
for ( i = 0;i < mortars.size;i++ )
|
|
{
|
|
mortars[ i ] setup_mortar_terrain();
|
|
}
|
|
if ( !( isdefined( level.mortar ) ) )
|
|
error( "level.mortar not defined. define in level script" );
|
|
|
|
level waittill( "start_mortars" );
|
|
|
|
while ( 1 )
|
|
{
|
|
wait( 1 + ( randomfloat( 2 ) ) );
|
|
|
|
r = randomint( mortars.size );
|
|
//println ("mortar size: ", mortars.size);
|
|
//println ("r: ", r);
|
|
for ( i = 0;i < mortars.size;i++ )
|
|
{
|
|
c = ( i + r ) % mortars.size;
|
|
//println ("current number: ", c);
|
|
d = distance( level.player getorigin(), mortars[ c ].origin );
|
|
d2 = undefined;
|
|
if ( isdefined( level.foley ) )
|
|
d2 = distance( level.foley.origin, mortars[ c ].origin );
|
|
else
|
|
d2 = 360;
|
|
if ( ( d < 1600 ) && ( d > 400 ) && ( d2 > 350 ) && ( c != lastmortar ) )
|
|
{
|
|
mortars[ c ] activate_mortar( 400, 300, 25, undefined, undefined, undefined, false );
|
|
lastmortar = c;
|
|
if ( d < 500 )
|
|
maps\_shellshock::main( 4 );
|
|
// level.player shellshock("default", 4);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
railyard_style( fRandomtime, iMaxRange, iMinRange, iBlastRadius, iDamageMax, iDamageMin, fQuakepower, iQuaketime, iQuakeradius, targetsUsed, seedtime )
|
|
{
|
|
// One mortar within iMaxRange distance goes off every (random + random) seconds but not within iMinRange units of the player
|
|
// Terminate on demand by setting level.iStopBarrage != 0, operates indefinitely by default
|
|
// Pass optional custom radius damage settings to activate_mortar()
|
|
// Also pass optional custom earthquake settings to mortar_boom() via activate_mortar() if you want more shaking
|
|
|
|
if ( !isdefined( fRandomtime ) )
|
|
fRandomtime = 7;
|
|
if ( !isdefined( iMaxRange ) )
|
|
iMaxRange = 2200;
|
|
if ( !isdefined( iMinRange ) )
|
|
iMinRange = 300;
|
|
|
|
if ( !isdefined( level.iStopBarrage ) )
|
|
level.iStopBarrage = 0;
|
|
|
|
if ( !isdefined( targetsUsed ) ) // this allows railyard_style to get called again and not setup any terrain related stuff
|
|
targetsUsed = 0;
|
|
|
|
mortars = getentarray( "mortar", "targetname" );
|
|
lastmortar = -1;
|
|
|
|
for ( i = 0;i < mortars.size;i++ )
|
|
{
|
|
if ( isdefined( mortars[ i ].target ) && ( targetsUsed == 0 ) ) // no target necessary, mortar will just play effect and sound
|
|
{
|
|
mortars[ i ] setup_mortar_terrain();
|
|
}
|
|
}
|
|
if ( !( isdefined( level.mortar ) ) )
|
|
error( "level.mortar not defined. define in level script" );
|
|
|
|
if ( isdefined( level.mortar_notify ) )
|
|
level waittill( level.mortar_notify );
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( level.iStopBarrage != 0 )
|
|
wait 1;
|
|
while ( level.iStopBarrage == 0 )
|
|
{
|
|
if ( isdefined( seedtime ) )
|
|
{
|
|
wait( seedtime + ( randomfloat( fRandomtime ) + randomfloat( fRandomtime ) ) );
|
|
}
|
|
else
|
|
{
|
|
wait( randomfloat( fRandomtime ) + randomfloat( fRandomtime ) );
|
|
}
|
|
|
|
r = randomint( mortars.size );
|
|
//println ("mortar size: ", mortars.size);
|
|
//println ("r: ", r);
|
|
for ( i = 0;i < mortars.size;i++ )
|
|
{
|
|
c = ( i + r ) % mortars.size;
|
|
//println ("current number: ", c);
|
|
d = distance( level.player getorigin(), mortars[ c ].origin );
|
|
if ( ( d < iMaxRange ) && ( d > iMinRange ) && ( c != lastmortar ) )
|
|
{
|
|
mortars[ c ] activate_mortar( iBlastRadius, iDamageMax, iDamageMin, fQuakepower, iQuaketime, iQuakeradius, false );
|
|
lastmortar = c;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//println("MORTAR BARRAGE TERMINATED");
|
|
}
|
|
|
|
|
|
script_mortargroup_style()
|
|
{
|
|
mortars = [];
|
|
mortartrigs = [];
|
|
level.mortars = [];
|
|
models = getentarray( "script_model", "classname" );
|
|
for ( i = 0;i < models.size;i++ )
|
|
if ( isdefined( models[ i ].script_mortargroup ) )
|
|
{
|
|
if ( !isdefined( level.mortars[ models[ i ].script_mortargroup ] ) )
|
|
level.mortars[ models[ i ].script_mortargroup ] = [];
|
|
|
|
mortar = spawnstruct();
|
|
mortar.origin = models[ i ].origin;
|
|
mortar.angles = models[ i ].angles;
|
|
if ( isdefined( models[ i ].targetname ) )
|
|
mortar.targetname = models[ i ].targetname;
|
|
if ( isdefined( models[ i ].target ) )
|
|
mortar.target = models[ i ].target;
|
|
level.mortars[ models[ i ].script_mortargroup ]
|
|
[ level.mortars[ models[ i ].script_mortargroup ].size ] = mortar;
|
|
models[ i ] delete();
|
|
|
|
// mortars[mortars.size] = models[i];
|
|
|
|
}
|
|
for ( i = 0;i < mortars.size;i++ )
|
|
{
|
|
mortars[ i ] hide();
|
|
// mortars[i] setup_mortar_terrain(); // this was commented out going to run it and find out just why
|
|
mortars[ i ].has_terrain = false;
|
|
}
|
|
if ( !( isdefined( level.mortar ) ) )
|
|
level.mortar = loadfx( "explosions/artilleryExp_dirt_brown" );
|
|
|
|
triggers = array_combine( getentarray( "trigger_multiple", "classname" ), getentarray( "trigger_radius", "classname" ) );
|
|
for ( i = 0;i < triggers.size;i++ )
|
|
if ( isdefined( triggers[ i ].script_mortargroup ) )
|
|
{
|
|
if ( !isdefined( level.mortars[ triggers[ i ].script_mortargroup ] ) )
|
|
level.mortars[ triggers[ i ].script_mortargroup ] = [];
|
|
mortartrigs[ mortartrigs.size ] = triggers[ i ];
|
|
|
|
}
|
|
for ( i = 0;i < mortartrigs.size;i++ )
|
|
{
|
|
mortartrigs[ i ].mortargroup = 0;
|
|
mortartrigs[ i ] thread script_mortargroup_mortar_group();
|
|
}
|
|
|
|
lasttrig = undefined;
|
|
while ( 1 )
|
|
{
|
|
level waittill( "mortarzone", mortartrig );
|
|
if ( isdefined( lasttrig ) )
|
|
lasttrig notify( "wait again" );
|
|
level.mortarzone = mortartrig.script_mortargroup;
|
|
mortartrig thread script_mortargroup_mortarzone();
|
|
lasttrig = mortartrig;
|
|
|
|
}
|
|
}
|
|
|
|
script_mortargroup_mortarzone()
|
|
{
|
|
lastblast = [];
|
|
timer = gettime();
|
|
timed = false;
|
|
if ( isdefined( self.script_timer ) )
|
|
{
|
|
level notify( "timed barrage" );
|
|
timer = gettime() + self.script_timer * 1000;
|
|
timed = true;
|
|
}
|
|
if ( isdefined( self.script_radius ) )
|
|
mortar_radius = self.script_radius;
|
|
else
|
|
mortar_radius = 0;
|
|
|
|
if ( isdefined( self.script_delay_min ) && isdefined( self.script_delay_max ) )
|
|
customdelay = true;
|
|
else
|
|
customdelay = false;
|
|
|
|
count = 0;
|
|
nonbarragesize = 2;
|
|
barragesize = 4;
|
|
barraging = false;
|
|
|
|
while ( ( level.mortars[ self.script_mortargroup ].size > 0 && ( level.mortarzone == self.script_mortargroup ) ) || timed )
|
|
{
|
|
if ( customdelay )
|
|
{
|
|
wait( randomfloat( self.script_delay_max - self.script_delay_min ) + self.script_delay_min );
|
|
}
|
|
else if ( barraging )
|
|
{
|
|
if ( count < barragesize )
|
|
{
|
|
wait( randomfloat( .5 ) );
|
|
count++ ;
|
|
|
|
}
|
|
else
|
|
{
|
|
count = 0;
|
|
barragesize = 2 + randomint( 4 );
|
|
barraging = false;
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( count < nonbarragesize )
|
|
{
|
|
delay = randomFloat( 2 ) + 1;
|
|
wait( delay );
|
|
count++ ;
|
|
}
|
|
else
|
|
{
|
|
count = 0;
|
|
barraging = true;
|
|
nonbarragesize = randomint( 2 ) + 3;
|
|
continue;
|
|
}
|
|
|
|
}
|
|
mortarsinfront = [];
|
|
pick = randomint( level.mortars[ self.script_mortargroup ].size );
|
|
if ( randomint( 100 ) < 75 )
|
|
{
|
|
playerforward = anglestoforward( level.player.angles );
|
|
points = [];
|
|
for ( i = 0;i < level.mortars[ self.script_mortargroup ].size;i++ )
|
|
{
|
|
if ( mortar_radius > 0 && distance( level.player.origin, level.mortars[ self.script_mortargroup ][ i ].origin ) > mortar_radius )
|
|
continue;
|
|
if ( is_lastblast( level.mortars[ self.script_mortargroup ][ i ], lastblast ) )
|
|
continue;
|
|
normalvec = vectornormalize( level.mortars[ self.script_mortargroup ][ i ].origin - level.player.origin );
|
|
if ( vectordot( playerforward, normalvec ) > 0.3 )
|
|
points[ points.size ] = i;
|
|
|
|
}
|
|
if ( points.size > 0 )
|
|
pick = points[ randomint( points.size ) ];
|
|
}
|
|
if ( lastblast.size > 3 )
|
|
lastblast = [];
|
|
lastblast[ lastblast.size ] = level.mortars[ self.script_mortargroup ][ pick ];
|
|
level.mortars[ self.script_mortargroup ][ pick ] thread script_mortargroup_domortar();
|
|
// self.groupedmortars = array_remove(self.groupedmortars,self.groupedmortars[pick]);
|
|
if ( timed && gettime() > timer )
|
|
{
|
|
if ( isdefined( self.target ) )
|
|
{
|
|
target = getent( self.target, "targetname" );
|
|
if ( isdefined( target ) )
|
|
{
|
|
target notify( "trigger" );
|
|
level notify( "timed barrage finished" );
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
is_lastblast( mortar, lastblast )
|
|
{
|
|
for ( i = 0;i < lastblast.size;i++ )
|
|
if ( mortar == lastblast[ i ] )
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
script_mortargroup_domortar()
|
|
{
|
|
if ( isdefined( self.targetname ) && isdefined( level.mortarthread[ self.targetname ] ) )
|
|
level thread [[ level.mortarthread[ self.targetname ] ]]( self );
|
|
else
|
|
self thread activate_mortar( undefined, undefined, undefined, undefined, undefined, undefined, true );
|
|
self waittill( "mortar" );
|
|
if ( isdefined( self.target ) )
|
|
{
|
|
targ = getent( self.target, "targetname" );
|
|
if ( isdefined( targ ) )
|
|
targ notify( "trigger" );
|
|
}
|
|
}
|
|
|
|
script_mortargroup_mortar_group()
|
|
{
|
|
while ( 1 )
|
|
{
|
|
self waittill( "trigger" );
|
|
if ( isdefined( level.mortarzone ) && level.mortarzone == self.script_mortargroup )
|
|
continue;
|
|
level notify( "mortarzone", self );
|
|
self waittill( "wait again" );
|
|
|
|
}
|
|
}
|
|
|
|
trigger_targeted()
|
|
{
|
|
//While the player is touching a trigger named "mortartrigger" a targeted script_origin mortar with a defined
|
|
//script_mortargroup value will go off every x seconds regardless of the players distance to the mortar.
|
|
|
|
level.mortartrigger = getentarray( "mortartrigger", "targetname" );
|
|
level.mortars = getentarray( "script_origin", "classname" );
|
|
|
|
for ( i = 0;i < level.mortars.size;i++ )
|
|
{
|
|
if ( isdefined( level.mortars[ i ].script_mortargroup ) )
|
|
{
|
|
level.mortars[ i ] setup_mortar_terrain();
|
|
}
|
|
}
|
|
|
|
level.lastmortar = -1;
|
|
|
|
if ( !( isdefined( level.mortar ) ) )
|
|
error( "level.mortar not defined. define in level script" );
|
|
|
|
for ( i = 0;i < level.mortartrigger.size;i++ )
|
|
{
|
|
thread trigger_targeted_mortars( i );
|
|
}
|
|
}
|
|
|
|
trigger_targeted_mortars( num )
|
|
{
|
|
targeted_mortars = getentarray( level.mortartrigger[ num ].target, "targetname" );
|
|
|
|
while ( 1 )
|
|
{
|
|
if ( level.player istouching( level.mortartrigger[ num ] ) )
|
|
{
|
|
r = randomint( targeted_mortars.size );
|
|
while ( r == level.lastmortar )
|
|
{
|
|
r = randomint( targeted_mortars.size );
|
|
wait .1;
|
|
}
|
|
targeted_mortars[ r ] activate_mortar( undefined, undefined, undefined, undefined, undefined, undefined, false );
|
|
level.lastmortar = r;
|
|
}
|
|
wait( randomfloat( 3 ) + randomfloat( 4 ) );
|
|
}
|
|
}
|
|
|
|
bunker_style_mortar()
|
|
{
|
|
// script_structs are placed in the level and grouped with script_mortargroup with targetname "mortar"
|
|
// mortar group is turned on/off in script or with triggers with targetname "mortar_on" or "mortar_off"
|
|
// mortar locations will all go simultaneously when an artillery round hits if within FOV of the player (dust falling from ceiling)
|
|
// each mortar location has script_fxid so it can play a set fx
|
|
// mortars will go forever until that group of mortars is notified to stop
|
|
|
|
mortar_bunker_array = [];
|
|
ents = undefined;
|
|
groupNum = [];
|
|
structs = getstructarray( "mortar_bunker", "targetname" );
|
|
trigs = getentarray( "mortar_bunker", "targetname" );
|
|
if ( ( isdefined( trigs ) ) && ( trigs.size > 0 ) )
|
|
ents = array_merge( structs, trigs );
|
|
else
|
|
ents = structs;
|
|
assert( isdefined( ents ) );
|
|
assert( ents.size > 0 );
|
|
for ( i = 0 ; i < ents.size ; i++ )
|
|
{
|
|
if ( !isdefined( ents[ i ].script_mortargroup ) )
|
|
continue;
|
|
|
|
index = -1;
|
|
groupNumber = int( ents[ i ].script_mortargroup );
|
|
for ( p = 0 ; p < mortar_bunker_array.size ; p++ )
|
|
{
|
|
if ( groupNumber != groupNum[ p ] )
|
|
continue;
|
|
|
|
index = p;
|
|
break;
|
|
}
|
|
|
|
if ( index == -1 )
|
|
{
|
|
// new group
|
|
mortar_bunker_array[ mortar_bunker_array.size ] = [];
|
|
groupNum[ groupNum.size ] = groupNumber;
|
|
index = mortar_bunker_array.size - 1;
|
|
}
|
|
|
|
mortar_bunker_array[ index ][ mortar_bunker_array[ index ].size ] = ents[ i ];
|
|
}
|
|
|
|
for ( i = 0 ; i < mortar_bunker_array.size ; i++ )
|
|
thread bunker_style_mortar_think( mortar_bunker_array[ i ], structs );
|
|
|
|
wait 0.05;
|
|
|
|
array_thread( getentarray( "mortar_on", "targetname" ), ::bunker_style_mortar_trigger, "on" );
|
|
array_thread( getentarray( "mortar_off", "targetname" ), ::bunker_style_mortar_trigger, "off" );
|
|
}
|
|
|
|
bunker_style_mortar_think( mortar_bunker_array, structs )
|
|
{
|
|
min = undefined;
|
|
max = undefined;
|
|
if ( isdefined( level.mortarMinInterval ) )
|
|
min = level.mortarMinInterval;
|
|
else
|
|
min = 4;
|
|
if ( isdefined( level.mortarMaxInterval ) )
|
|
max = level.mortarMaxInterval;
|
|
else
|
|
max = 6;
|
|
groupNum = int( mortar_bunker_array[ 0 ].script_mortargroup );
|
|
|
|
|
|
for ( ;; )
|
|
{
|
|
level waittill( "start_mortars " + groupNum );
|
|
thread bunker_style_mortar_activate( mortar_bunker_array, min, max, groupNum, structs );
|
|
}
|
|
}
|
|
|
|
bunker_style_mortar_activate( mortar_bunker_array, min, max, groupNum, structs )
|
|
{
|
|
level endon( "start_mortars " + groupNum );
|
|
level endon( "stop_mortars " + groupNum );
|
|
while ( true )
|
|
{
|
|
wait( 0.05 );
|
|
sound_org = getclosest( level.player.origin, structs );
|
|
if( !isdefined( level.mortarNoIncomingSound ) )
|
|
{
|
|
play_sound_in_space( "mortar_incoming_bunker", sound_org.origin );
|
|
}
|
|
sound_org = getclosest( level.player.origin, structs );
|
|
//thread play_sound_in_space( "mortar_explosion_bunker", sound_org.origin );
|
|
thread play_sound_in_space( "exp_artillery_underground", sound_org.origin );
|
|
array_thread( mortar_bunker_array,::bunker_style_mortar_explode );
|
|
if( !isdefined( level.mortarNoQuake ) )
|
|
{
|
|
if ( cointoss() )
|
|
earthquake( 0.20, 1.5, sound_org.origin, 1250 );
|
|
else
|
|
earthquake( 0.35, 2.75, sound_org.origin, 1250 );
|
|
}
|
|
level notify( "mortar_hit" );
|
|
wait( randomfloatrange( min, max ) );
|
|
mortar_bunker_array = remove_undefined_from_array( mortar_bunker_array );
|
|
}
|
|
}
|
|
|
|
bunker_style_mortar_explode( min, max )
|
|
{
|
|
if ( !isdefined( self ) )
|
|
return;
|
|
|
|
/*-----------------------
|
|
ONLY PLAY EFFECT/ACTIVATE TRIGGER IF WITHIN PLAYER FOV
|
|
-------------------------*/
|
|
if ( ( isdefined( level.mortarWithinFOV ) ) && ( self mortar_within_player_fov( level.mortarWithinFOV ) == false ) )
|
|
return;
|
|
|
|
/*-----------------------
|
|
ONLY PLAY EFFECT/ACTIVATE TRIGGER IF WITHIN RADIUS
|
|
-------------------------*/
|
|
if ( isdefined( level.mortar_min_dist ) )
|
|
min_dist = level.mortar_min_dist;
|
|
else
|
|
min_dist = 1024;
|
|
|
|
min_dist_squared = min_dist * min_dist;
|
|
distSquared = distancesquared( level.player.origin, self.origin );
|
|
if ( distSquared > min_dist_squared )
|
|
return;
|
|
|
|
/*-----------------------
|
|
IF IT'S A TRIGGER RADIUS, DO DAMAGE TO BUST UP DESTRUCTIBLES
|
|
-------------------------*/
|
|
//trigger radius are put around destructibles that you want damaged if the player is looking at it
|
|
if ( ( isdefined( self.classname ) ) && ( self.classname == "trigger_radius") )
|
|
{
|
|
|
|
if ( ( !level.player istouching( self ) ) && ( distance( level.player.origin, self.origin ) < level.mortarDamageTriggerDist ) )
|
|
{
|
|
RadiusDamage( self.origin, self.radius, 500, 500 );
|
|
self delete();
|
|
return;
|
|
}
|
|
}
|
|
/*-----------------------
|
|
OTHERWISE, PLAY CEILING DUST
|
|
-------------------------*/
|
|
else
|
|
{
|
|
playfx( level._effect[ "mortar" ][ self.script_fxid ], self.origin );
|
|
if ( distSquared < 262144 ) //only play sound when within 512
|
|
thread play_sound_in_space( "emt_single_ceiling_debris", self.origin );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
bog_style_mortar()
|
|
{
|
|
// script_structs are placed in the level and grouped with script_mortargroup with targetname "mortar"
|
|
// mortar group is turned on/off in script
|
|
// mortar locations will start going off randomly and wont go off within x units of the player
|
|
// each mortar location has script_fxid so it can play a set fx ( this allows having mortars on land and water in the same group )
|
|
// mortars will go forever until that group of mortars is notified to stop
|
|
// each mortar has a cooldown time of x seconds before it can be used again
|
|
|
|
groups = [];
|
|
groupNum = [];
|
|
structs = getstructarray( "mortar", "targetname" );
|
|
assert( isdefined( structs ) );
|
|
assert( structs.size > 0 );
|
|
for ( i = 0 ; i < structs.size ; i++ )
|
|
{
|
|
if ( !isdefined( structs[ i ].script_mortargroup ) )
|
|
continue;
|
|
|
|
index = -1;
|
|
groupNumber = int( structs[ i ].script_mortargroup );
|
|
for ( p = 0 ; p < groups.size ; p++ )
|
|
{
|
|
if ( groupNumber != groupNum[ p ] )
|
|
continue;
|
|
|
|
index = p;
|
|
break;
|
|
}
|
|
|
|
if ( index == -1 )
|
|
{
|
|
// new group
|
|
groups[ groups.size ] = [];
|
|
groupNum[ groupNum.size ] = groupNumber;
|
|
index = groups.size - 1;
|
|
}
|
|
|
|
groups[ index ][ groups[ index ].size ] = structs[ i ];
|
|
}
|
|
|
|
for ( i = 0 ; i < groups.size ; i++ )
|
|
thread bog_style_mortar_think( groups[ i ] );
|
|
|
|
wait 0.05;
|
|
|
|
array_thread( getentarray( "mortar_on", "targetname" ), ::bog_style_mortar_trigger, "on" );
|
|
array_thread( getentarray( "mortar_off", "targetname" ), ::bog_style_mortar_trigger, "off" );
|
|
}
|
|
|
|
bog_style_mortar_think( mortars, groupNum )
|
|
{
|
|
min = undefined;
|
|
max = undefined;
|
|
if ( isdefined( level.mortarMinInterval ) )
|
|
min = level.mortarMinInterval;
|
|
else
|
|
min = 0.5;
|
|
if ( isdefined( level.mortarMaxInterval ) )
|
|
max = level.mortarMaxInterval;
|
|
else
|
|
max = 3;
|
|
groupNum = int( mortars[ 0 ].script_mortargroup );
|
|
for ( ;; )
|
|
{
|
|
level waittill( "start_mortars " + groupNum );
|
|
level thread bog_style_mortar_activate( mortars, groupNum, min, max );
|
|
}
|
|
}
|
|
|
|
bog_style_mortar_activate( mortars, groupNum, min, max )
|
|
{
|
|
level endon( "start_mortars " + groupNum );
|
|
level endon( "stop_mortars " + groupNum );
|
|
|
|
|
|
if ( isdefined( level.mortar_min_dist ) )
|
|
min_dist = level.mortar_min_dist;
|
|
else
|
|
min_dist = 300;
|
|
|
|
//trigger used to check if friendlies is too close (if level.mortarExcluders is defined)
|
|
mortarDistanceTrigger = spawn( "trigger_radius", ( 0, 0, 0), 0, min_dist, 256 );
|
|
thread bog_style_mortar_cleanup( mortarDistanceTrigger, groupNum );
|
|
|
|
for ( ;; )
|
|
{
|
|
for ( ;; )
|
|
{
|
|
wait 0.05;
|
|
rand = randomint( mortars.size );
|
|
if ( isdefined( mortars[ rand ].cooldown ) )
|
|
continue;
|
|
//don't trigger mortar if player too close
|
|
d = distance( level.player.origin, mortars[ rand ].origin );
|
|
if ( d < min_dist )
|
|
continue;
|
|
|
|
//don't trigger mortar in case we have friendlies we do not want to be hit by mortars
|
|
if ( ( isdefined( level.mortarExcluders ) ) && ( level.mortarExcluders.size > 0 ) )
|
|
{
|
|
mortarDistanceTrigger.origin = mortars[ rand ].origin; //trigger_radius used to determine if level.mortarExcluders are too close to detonate
|
|
if ( mortars_too_close( level.mortarExcluders, mortarDistanceTrigger ) )
|
|
continue;
|
|
}
|
|
|
|
// in case we need to see mortars in the distance
|
|
if ( !isdefined( level.noMaxMortarDist ) && ( d > 1000 ) )
|
|
continue;
|
|
if ( ( isdefined( level.mortar_max_dist ) ) && ( d > level.mortar_max_dist ) )
|
|
continue;
|
|
//if we need to check player FOV
|
|
if ( ( isdefined( level.mortarWithinFOV ) ) && ( mortars[ rand ] mortar_within_player_fov( level.mortarWithinFOV ) == false ) )
|
|
continue;
|
|
break;
|
|
}
|
|
if ( ( isdefined( level.noMortars ) ) && ( level.noMortars == true ) )
|
|
return;
|
|
mortars[ rand ] thread bog_style_mortar_explode();
|
|
|
|
wait( min + randomfloat( max - min ) );
|
|
}
|
|
}
|
|
|
|
bog_style_mortar_cleanup( mortarDistanceTrigger, groupNum )
|
|
{
|
|
level waittill( "stop_mortars " + groupNum );
|
|
mortarDistanceTrigger delete(); //delete the trigger_radius used to determine if level.mortarExcluders are too close to detonate
|
|
}
|
|
|
|
mortars_too_close( mortarExcluders, mortarDistanceTrigger )
|
|
{
|
|
foreach ( guy in level.mortarExcluders )
|
|
{
|
|
if ( !isalive( guy ) )
|
|
continue;
|
|
if ( !isdefined( guy ) )
|
|
continue;
|
|
if ( guy istouching( mortarDistanceTrigger ) )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
mortar_within_player_fov( fov )
|
|
{
|
|
playerEye = level.player getEye();
|
|
playerMortarFovOffset = ( 0, 0, 0 );
|
|
if ( isdefined( level.playerMortarFovOffset ) )
|
|
playerMortarFovOffset = level.playerMortarFovOffset;
|
|
|
|
bInFOV = within_fov( playerEye, level.player getPlayerAngles() + playerMortarFovOffset, self.origin, fov );
|
|
return bInFOV;
|
|
}
|
|
|
|
bog_style_mortar_explode( instant, customExploSound )
|
|
{
|
|
if ( !isdefined( level.mortarDamageRadius ) )
|
|
level.mortarDamageRadius = 250;
|
|
if ( !isdefined( instant ) )
|
|
instant = false;
|
|
|
|
self thread bog_style_mortar_cooldown();
|
|
if ( !instant )
|
|
self play_sound_in_space( level.scr_sound[ "mortar" ][ "incomming" ] );
|
|
if ( isdefined( customExploSound ) )
|
|
self thread play_sound_in_space( customExploSound );
|
|
else
|
|
self thread play_sound_in_space( level.scr_sound[ "mortar" ][ self.script_fxid ] );
|
|
|
|
//dont play an effect if it's behind the player - trying to save on particle effects
|
|
setplayerignoreradiusdamage( true );
|
|
radiusDamage( self.origin, level.mortarDamageRadius, 150, 50 );
|
|
setplayerignoreradiusdamage( false );
|
|
playfx( level._effect[ "mortar" ][ self.script_fxid ], self.origin );
|
|
|
|
if( isdefined( level.alwaysquake ) )
|
|
{
|
|
earthquake( 0.3, 1, level.player.origin, 2000 );
|
|
}
|
|
|
|
if ( getdvarint( "bog_camerashake" ) > 0 )
|
|
{
|
|
//if player is trying to snipe dont do view shake
|
|
if ( ( level.player getCurrentWeapon() == "dragunov" ) && ( level.player playerADS() > 0.8 ) )
|
|
return;
|
|
earthquake( 0.25, 0.75, self.origin, 1250 );
|
|
}
|
|
}
|
|
|
|
bog_style_mortar_cooldown()
|
|
{
|
|
self.cooldown = true;
|
|
wait( 3 + randomfloat( 2 ) );
|
|
self.cooldown = undefined;
|
|
}
|
|
|
|
bog_style_mortar_trigger( value )
|
|
{
|
|
assert( isdefined( self.script_mortargroup ) );
|
|
|
|
self waittill( "trigger" );
|
|
|
|
if ( value == "on" )
|
|
bog_style_mortar_on( self.script_mortargroup );
|
|
else if ( value == "off" )
|
|
bog_style_mortar_off( self.script_mortargroup );
|
|
}
|
|
|
|
bog_style_mortar_on( groupNum )
|
|
{
|
|
level notify( "start_mortars " + groupNum );
|
|
}
|
|
|
|
bog_style_mortar_off( groupNum )
|
|
{
|
|
level notify( "stop_mortars " + groupNum );
|
|
}
|
|
|
|
|
|
bunker_style_mortar_on( groupNum )
|
|
{
|
|
if ( !isdefined( level.mortarDamageTriggerDist ) )
|
|
level.mortarDamageTriggerDist = 512;
|
|
if ( !isdefined( level.mortarWithinFOV ) )
|
|
level.mortarWithinFOV = cos( 35 );
|
|
|
|
level notify( "start_mortars " + groupNum );
|
|
}
|
|
|
|
bunker_style_mortar_off( groupNum )
|
|
{
|
|
level waittill( "mortar_hit" ); //don't interrupt in the middle of an incoming sound before it hits
|
|
level notify( "stop_mortars " + groupNum );
|
|
}
|
|
|
|
bunker_style_mortar_off_nowait( groupNum )
|
|
{
|
|
level notify( "stop_mortars " + groupNum );
|
|
}
|
|
|
|
bunker_style_mortar_trigger( value )
|
|
{
|
|
assert( isdefined( self.script_mortargroup ) );
|
|
|
|
self waittill( "trigger" );
|
|
|
|
if ( value == "on" )
|
|
bunker_style_mortar_on( self.script_mortargroup );
|
|
else if ( value == "off" )
|
|
bunker_style_mortar_off( self.script_mortargroup );
|
|
}
|
|
|
|
burnville_style_mortar()
|
|
{
|
|
// Mortar waits for player to come within x units. Then explodes every x seconds if player is x range away
|
|
level endon( "stop falling mortars" );
|
|
setup_mortar_terrain();
|
|
|
|
wait( randomfloat( 0.5 ) + randomfloat( 0.5 ) );
|
|
|
|
while ( 1 )
|
|
{
|
|
if ( distance( level.player getorigin(), self.origin ) < 600 )
|
|
{
|
|
activate_mortar( undefined, undefined, undefined, undefined, undefined, undefined, false );
|
|
break;
|
|
}
|
|
wait( 1 );
|
|
}
|
|
|
|
wait( 7 + randomfloat( 20 ) );
|
|
|
|
while ( 1 )
|
|
{
|
|
if ( ( distance( level.player getorigin(), self.origin ) < 1200 ) &&
|
|
( distance( level.player getorigin(), self.origin ) > 400 ) )
|
|
{
|
|
activate_mortar( undefined, undefined, undefined, undefined, undefined, undefined, false );
|
|
|
|
wait( 3 + randomfloat( 14 ) );
|
|
}
|
|
|
|
wait( 1 );
|
|
}
|
|
}
|
|
|
|
setup_mortar_terrain()
|
|
{
|
|
self.has_terrain = false;
|
|
if ( isdefined( self.target ) )
|
|
{
|
|
self.terrain = getentarray( self.target, "targetname" );
|
|
self.has_terrain = true;
|
|
}
|
|
else
|
|
{
|
|
println( "z: mortar entity has no target: ", self.origin );
|
|
}
|
|
|
|
if ( !isdefined( self.terrain ) )
|
|
println( "z: mortar entity has target, but target doesnt exist: ", self.origin );
|
|
|
|
if ( isdefined( self.script_hidden ) )
|
|
{
|
|
if ( isdefined( self.script_hidden ) )
|
|
self.hidden_terrain = getent( self.script_hidden, "targetname" );
|
|
else if ( ( isdefined( self.terrain ) ) && ( isdefined( self.terrain[ 0 ].target ) ) )
|
|
self.hidden_terrain = getent( self.terrain[ 0 ].target, "targetname" );
|
|
|
|
if ( isdefined( self.hidden_terrain ) )
|
|
self.hidden_terrain hide();
|
|
}
|
|
|
|
else if ( isdefined( self.has_terrain ) )
|
|
{
|
|
if ( ( isdefined( self.terrain ) ) && ( isdefined( self.terrain[ 0 ].target ) ) )
|
|
self.hidden_terrain = getent( self.terrain[ 0 ].target, "targetname" );
|
|
|
|
if ( isdefined( self.hidden_terrain ) )
|
|
self.hidden_terrain hide();
|
|
}
|
|
|
|
}
|
|
|
|
activate_mortar( range, max_damage, min_damage, fQuakepower, iQuaketime, iQuakeradius, bIsstruct )
|
|
{
|
|
// if(bIsstruct)
|
|
// {
|
|
// if(distance(self.origin,level.player.origin) < 1000)
|
|
// incoming_sound( undefined, bIsstruct );
|
|
// }
|
|
// else
|
|
incoming_sound( undefined, bIsstruct );
|
|
|
|
level notify( "mortar" );
|
|
self notify( "mortar" );
|
|
|
|
|
|
if ( !isdefined( range ) )
|
|
range = 256;
|
|
if ( !isdefined( max_damage ) )
|
|
max_damage = 400;
|
|
if ( !isdefined( min_damage ) )
|
|
min_damage = 25;
|
|
|
|
radiusDamage( self.origin, range, max_damage, min_damage );
|
|
|
|
if ( ( isdefined( self.has_terrain ) && self.has_terrain == true ) && ( isdefined( self.terrain ) ) )
|
|
{
|
|
for ( i = 0;i < self.terrain.size;i++ )
|
|
{
|
|
if ( isdefined( self.terrain[ i ] ) )
|
|
self.terrain[ i ] delete();
|
|
}
|
|
}
|
|
|
|
if ( isdefined( self.hidden_terrain ) )
|
|
self.hidden_terrain show();
|
|
self.has_terrain = false;
|
|
|
|
mortar_boom( self.origin, fQuakepower, iQuaketime, iQuakeradius, undefined, bIsstruct );
|
|
}
|
|
|
|
mortar_boom( origin, fPower, iTime, iRadius, effect, bIsstruct )
|
|
{
|
|
if ( !isdefined( fPower ) )
|
|
fPower = 0.15;
|
|
if ( !isdefined( iTime ) )
|
|
iTime = 2;
|
|
if ( !isdefined( iRadius ) )
|
|
iRadius = 850;
|
|
|
|
|
|
thread mortar_sound( bIsstruct );
|
|
|
|
if ( isdefined( effect ) )
|
|
playfx( effect, origin );
|
|
else
|
|
playfx( level.mortar, origin );
|
|
|
|
earthquake( fPower, iTime, origin, iRadius );
|
|
|
|
// Special Burnville Shell shocking
|
|
if ( level.script != "burnville" )
|
|
return;
|
|
if ( isdefined( level.playerMortar ) )
|
|
return;
|
|
if ( distance( level.player.origin, origin ) > 300 )
|
|
return;
|
|
if ( level.script == "carchase" || level.script == "breakout" )
|
|
return;
|
|
|
|
level.playerMortar = true;
|
|
level notify( "shell shock player", iTime * 4 );
|
|
maps\_shellshock::main( iTime * 4 );
|
|
// level.player shellshock("default", iTime*4);
|
|
|
|
|
|
// earthquake(0.15, 2, origin, 1050);
|
|
/*
|
|
earthquake(float scale, float duration, vector source, float radius)
|
|
|
|
Example:
|
|
scale = 0.15;
|
|
duration = 1;
|
|
source = (866, 2240, 0);
|
|
radius = 600;
|
|
|
|
earthquake(scale, duration, source, radius);
|
|
*/
|
|
}
|
|
|
|
mortar_sound( bIsstruct )
|
|
{
|
|
if ( !isdefined( level.mortar_last_sound ) )
|
|
level.mortar_last_sound = -1;
|
|
|
|
soundnum = randomint( 3 ) + 1;
|
|
while ( soundnum == level.mortar_last_sound )
|
|
soundnum = randomint( 3 ) + 1;
|
|
|
|
level.mortar_last_sound = soundnum;
|
|
|
|
if ( !bIsstruct )
|
|
self playsound( "mortar_explosion" + soundnum );
|
|
else
|
|
play_sound_in_space( "mortar_explosion" + soundnum, self.origin );
|
|
}
|
|
|
|
incoming_sound( soundnum, bIsstruct )
|
|
{
|
|
currenttime = gettime();
|
|
if ( !isdefined( level.lastmortarincomingtime ) )
|
|
{
|
|
level.lastmortarincomingtime = currenttime;
|
|
}
|
|
else if ( ( currenttime - level.lastmortarincomingtime ) < 1000 )
|
|
{
|
|
wait 1;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
level.lastmortarincomingtime = currenttime;
|
|
}
|
|
|
|
if ( !isdefined( soundnum ) )
|
|
soundnum = randomint( 3 ) + 1;
|
|
|
|
if ( soundnum == 1 )
|
|
{
|
|
if ( bIsstruct )
|
|
thread play_sound_in_space( "mortar_incoming1", self.origin );
|
|
else
|
|
self playsound( "mortar_incoming1" );
|
|
wait( 1.07 - 0.25 );
|
|
}
|
|
else
|
|
if ( soundnum == 2 )
|
|
{
|
|
if ( bIsstruct )
|
|
thread play_sound_in_space( "mortar_incoming2", self.origin );
|
|
else
|
|
self playsound( "mortar_incoming2" );
|
|
wait( 0.67 - 0.25 );
|
|
}
|
|
else
|
|
{
|
|
if ( bIsstruct )
|
|
thread play_sound_in_space( "mortar_incoming3", self.origin );
|
|
else
|
|
self playsound( "mortar_incoming3" );
|
|
wait( 1.55 - 0.25 );
|
|
}
|
|
}
|
|
|
|
generic_style_init()
|
|
{
|
|
level._explosion_iMaxRange = [];
|
|
level._explosion_iMinRange = [];
|
|
level._explosion_iBlastRadius = [];
|
|
level._explosion_iDamageMax = [];
|
|
level._explosion_iDamageMin = [];
|
|
level._explosion_fQuakePower = [];
|
|
level._explosion_iQuakeTime = [];
|
|
level._explosion_iQuakeRadius = [];
|
|
}
|
|
|
|
generic_style_setradius( strExplosion, iMinRange, iMaxRange )
|
|
{
|
|
level._explosion_iMinRange[ strExplosion ] = iMinRange;
|
|
level._explosion_iMaxRange[ strExplosion ] = iMaxRange;
|
|
}
|
|
|
|
generic_style_setdamage( strExplosion, iBlastRadius, iDamageMin, iDamageMax )
|
|
{
|
|
level._explosion_iBlastRadius[ strExplosion ] = iBlastRadius;
|
|
level._explosion_iDamageMin[ strExplosion ] = iDamageMin;
|
|
level._explosion_iDamageMax[ strExplosion ] = iDamageMax;
|
|
}
|
|
|
|
generic_style_setquake( strExplosion, fQuakePower, iQuakeTime, iQuakeRadius )
|
|
{
|
|
level._explosion_fQuakePower[ strExplosion ] = fQuakePower;
|
|
level._explosion_iQuakeTime[ strExplosion ] = iQuakeTime;
|
|
level._explosion_iQuakeRadius[ strExplosion ] = iQuakeRadius;
|
|
}
|
|
|
|
// REQUIRED: level._effect[strExplosion] = loadfx(...);
|
|
// REQUIRED: level._effectType[strExplosion] = strType ("mortar", "bomb" or "artillery")
|
|
|
|
// Allows for multiple sets of explosions in a single level
|
|
// One explosion within iMaxRange distance goes off every (random + random) seconds but not within iMinRange units of the player
|
|
// Starts on notify specified by level.explosion_start[strExplosion]
|
|
// Terminates on notify specified by level.explosion_stop[strExplosion]
|
|
// Terminate on demand by setting level.bStopBarrage[strExplosion] == true, operates indefinitely by default
|
|
generic_style( strExplosion, fDelay, iBarrageSize, fBarrageDelay, iMinRange, iMaxRange, bTargetsUsed )
|
|
{
|
|
//// Safety checks
|
|
assertex( ( isdefined( strExplosion ) && ( strExplosion != "" ) ), "strExplosion not passed. pass in level script" );
|
|
assertex( ( isdefined( level._effect ) && isdefined( level._effect[ strExplosion ] ) ), "level._effect[strMortars] not defined. define in level script" );
|
|
|
|
//// Initialize Defaults
|
|
iLastExplosion = -1;
|
|
iMaxRangeLocal = iMaxRange;
|
|
iMinRangeLocal = iMinRange;
|
|
|
|
generic_style_setradius( strExplosion, 300, 2200 );
|
|
|
|
if ( !isdefined( fDelay ) )
|
|
fDelay = 7;
|
|
|
|
if ( !isdefined( iBarrageSize ) )
|
|
iBarrageSize = 1;
|
|
|
|
if ( !isdefined( fBarrageDelay ) )
|
|
fBarrageDelay = 0;
|
|
|
|
if ( !isdefined( bTargetsUsed ) ) // this allows generic_style to get called again and not setup any terrain related stuff
|
|
bTargetsUsed = false;
|
|
|
|
if ( isdefined( level.explosion_stopNotify ) && isdefined( level.explosion_stopNotify[ strExplosion ] ) )
|
|
level endon( level.explosion_stopNotify[ strExplosion ] );
|
|
|
|
// for backwards compatibility
|
|
if ( !isdefined( level.bStopBarrage ) || !isdefined( level.bStopBarrage[ strExplosion ] ) )
|
|
level.bStopBarrage[ strExplosion ] = false;
|
|
|
|
//// Explosion Points
|
|
aeExplosions = getentarray( strExplosion, "targetname" );
|
|
|
|
//// Terrain Setup
|
|
for ( i = 0; i < aeExplosions.size; i++ )
|
|
{
|
|
if ( isdefined( aeExplosions[ i ].target ) && ( !bTargetsUsed ) ) // no target necessary, mortar will just play effect and sound
|
|
aeExplosions[ i ] setup_mortar_terrain();
|
|
}
|
|
|
|
//// Start Wait
|
|
if ( isdefined( level.explosion_startNotify ) && isdefined( level.explosion_startNotify[ strExplosion ] ) )
|
|
level waittill( level.explosion_startNotify[ strExplosion ] );
|
|
|
|
//// Main Loop
|
|
while ( true )
|
|
{
|
|
while ( !level.bStopBarrage[ strExplosion ] )
|
|
{
|
|
for ( j = 0; j < iBarrageSize; j++ )
|
|
{
|
|
// putting this here allows for updates during barrage
|
|
if ( !isdefined( iMaxRange ) )
|
|
iMaxRangeLocal = level._explosion_iMaxRange[ strExplosion ];
|
|
if ( !isdefined( iMinRange ) )
|
|
iMinRangeLocal = level._explosion_iMinRange[ strExplosion ];
|
|
|
|
iRand = randomint( aeExplosions.size );
|
|
for ( i = 0; i < aeExplosions.size; i++ )
|
|
{
|
|
iCur = ( i + iRand ) % aeExplosions.size;
|
|
fDist = distance( level.player getorigin(), aeExplosions[ iCur ].origin );
|
|
if ( ( fDist < iMaxRangeLocal ) && ( fDist > iMinRangeLocal ) && ( iCur != iLastExplosion ) )
|
|
// if ( (fDist < iMaxRangeLocal) && (fDist > iMinRangeLocal))
|
|
{
|
|
aeExplosions[ iCur ].iMinRange = iMinRangeLocal;
|
|
aeExplosions[ iCur ] explosion_activate( strExplosion );
|
|
iLastExplosion = iCur;
|
|
break;
|
|
}
|
|
}
|
|
iLastExplosion = -1;
|
|
if ( isdefined( level.explosion_delay ) && isdefined( level.explosion_delay[ strExplosion ] ) )
|
|
wait( level.explosion_delay[ strExplosion ] );
|
|
else
|
|
wait( randomfloat( fDelay ) + randomFloat( fDelay ) );
|
|
}
|
|
if ( isdefined( level.explosion_barrage_delay ) && isdefined( level.explosion_barrage_delay[ strExplosion ] ) )
|
|
wait( level.explosion_barrage_delay[ strExplosion ] );
|
|
else
|
|
wait( randomfloat( fBarrageDelay ) + randomFloat( fBarrageDelay ) );
|
|
}
|
|
wait( 0.05 );
|
|
}
|
|
}
|
|
|
|
explosion_activate( strExplosion, iBlastRadius, iDamageMin, iDamageMax, fQuakePower, iQuakeTime, iQuakeRadius )
|
|
{
|
|
//// Initialize Defaults
|
|
generic_style_setdamage( strExplosion, 256, 25, 400 );
|
|
generic_style_setquake( strExplosion, 0.15, 2, 850 );
|
|
|
|
if ( !isdefined( iBlastRadius ) )
|
|
iBlastRadius = level._explosion_iBlastRadius[ strExplosion ];
|
|
if ( !isdefined( iDamageMin ) )
|
|
iDamageMin = level._explosion_iDamageMin[ strExplosion ];
|
|
if ( !isdefined( iDamageMax ) )
|
|
iDamageMax = level._explosion_iDamageMax[ strExplosion ];
|
|
|
|
if ( !isdefined( fQuakePower ) )
|
|
fQuakePower = level._explosion_fQuakePower[ strExplosion ];
|
|
if ( !isdefined( iQuakeTime ) )
|
|
iQuakeTime = level._explosion_iQuakeTime[ strExplosion ];
|
|
if ( !isdefined( iQuakeRadius ) )
|
|
iQuakeRadius = level._explosion_iQuakeRadius[ strExplosion ];
|
|
|
|
//// Incoming Sound
|
|
explosion_incoming( strExplosion );
|
|
|
|
level notify( "explosion", strExplosion );
|
|
|
|
bDoDamage = true;
|
|
fPreDist = undefined;
|
|
eLocation = self;
|
|
if ( isdefined( self.iMinRange ) && distance( level.player.origin, self.origin ) < self.iMinRange )
|
|
{
|
|
// get closest location outside iMinRange
|
|
aeExplosions = getentarray( strExplosion, "targetname" );
|
|
for ( iCur = 0; iCur < aeExplosions.size; iCur++ )
|
|
{
|
|
fDist = distance( level.player getorigin(), aeExplosions[ iCur ].origin );
|
|
if ( fDist > self.iMinRange )
|
|
{
|
|
if ( !isdefined( fPreDist ) || fDist < fPreDist )
|
|
{
|
|
fPreDist = fDist;
|
|
eLocation = aeExplosions[ iCur ];
|
|
}
|
|
}
|
|
}
|
|
if ( !isdefined( fPreDist ) )
|
|
{
|
|
bDoDamage = false;
|
|
}
|
|
}
|
|
|
|
if ( bDoDamage )
|
|
radiusDamage( eLocation.origin, iBlastRadius, iDamageMax, iDamageMin );
|
|
|
|
//// Process Terrain
|
|
if ( ( isdefined( eLocation.has_terrain ) && eLocation.has_terrain == true ) && ( isdefined( eLocation.terrain ) ) )
|
|
{
|
|
for ( i = 0;i < eLocation.terrain.size;i++ )
|
|
{
|
|
if ( isdefined( eLocation.terrain[ i ] ) )
|
|
eLocation.terrain[ i ] delete();
|
|
}
|
|
}
|
|
|
|
if ( isdefined( eLocation.hidden_terrain ) )
|
|
eLocation.hidden_terrain show();
|
|
eLocation.has_terrain = false;
|
|
|
|
//// Explosion Effects
|
|
eLocation explosion_boom( strExplosion, fQuakePower, iQuakeTime, iQuakeRadius );
|
|
}
|
|
|
|
explosion_boom( strExplosion, fPower, iTime, iRadius )
|
|
{
|
|
if ( !isdefined( fPower ) )
|
|
fPower = 0.15;
|
|
if ( !isdefined( iTime ) )
|
|
iTime = 2;
|
|
if ( !isdefined( iRadius ) )
|
|
iRadius = 850;
|
|
|
|
explosion_sound( strExplosion );
|
|
|
|
explosion_origin = self.origin;
|
|
|
|
playfx( level._effect[ strExplosion ], explosion_origin );
|
|
earthquake( fPower, iTime, explosion_origin, iRadius );
|
|
|
|
if ( distance( level.player.origin, explosion_origin ) > 300 )
|
|
return;
|
|
if ( level.script == "carchase" || level.script == "breakout" )
|
|
return;
|
|
|
|
level.playerMortar = true;
|
|
level notify( "shell shock player", iTime * 4 );
|
|
maps\_shellshock::main( iTime * 4 );
|
|
}
|
|
|
|
explosion_sound( strExplosion )
|
|
{
|
|
if ( !isdefined( level._explosion_last_sound ) )
|
|
level._explosion_last_sound = 0;
|
|
|
|
soundnum = randomint( 3 ) + 1;
|
|
while ( soundnum == level._explosion_last_sound )
|
|
soundnum = randomint( 3 ) + 1;
|
|
|
|
level._explosion_last_sound = soundnum;
|
|
|
|
if ( level._effectType[ strExplosion ] == "mortar" )
|
|
{
|
|
switch( soundnum )
|
|
{
|
|
case 1:
|
|
self playsound( "mortar_explosion1" );
|
|
break;
|
|
case 2:
|
|
self playsound( "mortar_explosion2" );
|
|
break;
|
|
case 3:
|
|
self playsound( "mortar_explosion3" );
|
|
break;
|
|
}
|
|
}
|
|
else if ( level._effectType[ strExplosion ] == "artillery" )
|
|
{
|
|
switch( soundnum )
|
|
{
|
|
case 1:
|
|
self playsound( "mortar_explosion4" );
|
|
break;
|
|
case 2:
|
|
self playsound( "mortar_explosion5" );
|
|
break;
|
|
case 3:
|
|
self playsound( "mortar_explosion1" );
|
|
break;
|
|
}
|
|
}
|
|
else if ( level._effectType[ strExplosion ] == "bomb" )
|
|
{
|
|
switch( soundnum )
|
|
{
|
|
case 1:
|
|
self playsound( "mortar_explosion1" );
|
|
break;
|
|
case 2:
|
|
self playsound( "mortar_explosion4" );
|
|
break;
|
|
case 3:
|
|
self playsound( "mortar_explosion5" );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
explosion_incoming( strExplosion, soundnum )
|
|
{
|
|
if ( !isdefined( level._explosion_last_incoming ) )
|
|
level._explosion_last_incoming = -1;
|
|
|
|
soundnum = randomint( 4 ) + 1;
|
|
while ( soundnum == level._explosion_last_incoming )
|
|
soundnum = randomint( 4 ) + 1;
|
|
|
|
level._explosion_last_incoming = soundnum;
|
|
|
|
if ( level._effectType[ strExplosion ] == "mortar" )
|
|
{
|
|
switch( soundnum )
|
|
{
|
|
case 1:
|
|
self playsound( "mortar_incoming1" );
|
|
wait( 1.07 - 0.25 );
|
|
break;
|
|
case 2:
|
|
self playsound( "mortar_incoming2" );
|
|
wait( 0.67 - 0.25 );
|
|
break;
|
|
case 3:
|
|
self playsound( "mortar_incoming3" );
|
|
wait( 1.55 - 0.25 );
|
|
break;
|
|
default:
|
|
wait( 1.75 );
|
|
break;
|
|
}
|
|
}
|
|
else if ( level._effectType[ strExplosion ] == "artillery" )
|
|
{
|
|
switch( soundnum )
|
|
{
|
|
case 1:
|
|
self playsound( "mortar_incoming4" );
|
|
wait( 1.07 - 0.25 );
|
|
break;
|
|
case 2:
|
|
self playsound( "mortar_incoming4_new" );
|
|
wait( 0.67 - 0.25 );
|
|
break;
|
|
case 3:
|
|
self playsound( "mortar_incoming1_new" );
|
|
wait( 1.55 - 0.25 );
|
|
break;
|
|
default:
|
|
wait( 1.75 );
|
|
break;
|
|
}
|
|
}
|
|
else if ( level._effectType[ strExplosion ] == "bomb" )
|
|
{
|
|
switch( soundnum )
|
|
{
|
|
case 1:
|
|
self playsound( "mortar_incoming2_new" );
|
|
wait( 1.75 );
|
|
break;
|
|
case 2:
|
|
self playsound( "mortar_incoming3_new" );
|
|
wait( 1.75 );
|
|
break;
|
|
case 3:
|
|
self playsound( "mortar_incoming4_new" );
|
|
wait( 1.75 );
|
|
break;
|
|
default:
|
|
wait( 1.75 );
|
|
break;
|
|
}
|
|
}
|
|
}
|