cod4-sdk/raw/maps/_mortar.gsc

1154 lines
30 KiB
Text
Raw Normal View History

2008-01-19 00:00:00 +00:00
#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) );
}
}
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;
for (;;)
{
for(;;)
{
wait 0.05;
rand = randomint( mortars.size );
if ( isdefined ( mortars[ rand ].cooldown ) )
continue;
d = distance( level.player.origin, mortars[rand].origin );
if ( d < min_dist )
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 ) );
}
}
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( 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, 250, 150, 50 );
setplayerignoreradiusdamage( false );
playfx ( level._effect[ "mortar" ][ self.script_fxid ], self.origin );
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 );
}
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:
player = getent("player", "classname");
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;
}
}
}