iw4x-rawfiles/iw4x/iw4x_00/maps/mp/_explosive_barrels.gsc

403 lines
10 KiB
Plaintext

main()
{
//------------------
//EFECTS DEFINITIONS
//------------------
qBarrels = false;
precacheItem( "barrel_mp" );
barrels = getentarray ("explodable_barrel","targetname");
if ( (isdefined(barrels)) && (barrels.size > 0) )
qBarrels = true;
barrels = getentarray ("explodable_barrel","script_noteworthy");
if ( (isdefined(barrels)) && (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(isdefined(oilspill) && oilspill.size > 0)
{
level.breakables_fx["oilspill"]["burn"] = loadfx ("props/barrel_fire");
level.breakables_fx["oilspill"]["spark"] = loadfx("impacts/small_metalhit_1");
}
//------------------
//------------------
//-----------------
//SOUND DEFINITIONS
//-----------------
level.barrelExpSound = "explo_metal_rand";
//-----------------
//-----------------
level.barrelHealth = 150;
maxBrokenPieces = 25;
//-------------
//-------------
level.precachemodeltype = [];
level.barrelExplodingThisFrame = false;
level.breakables_clip = [];
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;
common_scripts\utility::array_thread(getentarray ("explodable_barrel","targetname"), ::explodable_barrel_think);
//common_scripts\utility::array_thread(getentarray ("explodable_barrel","script_noteworthy"), ::explodable_barrel_think); ASK MO
common_scripts\utility::array_thread(getentarray ("oil_spill", "targetname"), ::oil_spill_think);
}
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"));
self.extra = getent(self.target, "targetname");
self setcandamage(true);
if(isdefined(self.barrel))
{
self.barrel.oilspill = true;
self thread oil_spill_burn_after();
}
while(1)
{
self waittill("damage", other, damage, direction_vec, P, type );
if(type == "MOD_MELEE" || type == "MOD_IMPACT")
continue;
self.damageOwner = other;
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();
}
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;
}
oil_spill_burn_after()
{
while(1)
{
self.barrel waittill("damage", amount ,attacker, direction_vec, P, type);
if(type == "MOD_MELEE" || type == "MOD_IMPACT")
continue;
break;
}
self.damageOwner = attacker;
// do not pass damage owner if they have disconnected before the barrels explode
if ( !isdefined( self.damageOwner ) )
self radiusdamage (self.origin, 4, 10, 10 );
else
self radiusdamage (self.origin, 4, 10, 10, self.damageOwner);
}
oil_spill_burn(P, dest)
{
forward = vectornormalize(dest - P);
dist = distance(p, dest);
range = 8;
interval = common_scripts\utility::vector_multiply(forward, range);
angle = vectortoangles(forward);
right = anglestoright(angle);
barrels = getentarray ("explodable_barrel","targetname");
distsqr = 22 * 22;
test = spawn("script_origin", P);
test hide();
num = 0;
while(1)
{
dist -= range;
if(dist < range *.1)
break;
p += (interval + common_scripts\utility::vector_multiply(right, randomfloatrange(-6, 6)));
thread oil_spill_burn_section(P);
num++;
if(num == 4)
{
num = 0;
}
test.origin = P;
remove = [];
barrels = common_scripts\utility::array_removeUndefined(barrels);
for(i=0; i<barrels.size; i++)
{
vec = anglestoup(barrels[i].angles);
start = barrels[i].origin + (common_scripts\utility::vector_multiply(vec, 22));
pos = physicstrace(start, start + (0,0,-64));
if(distancesquared(P, pos) < distsqr)
{
remove[remove.size] = barrels[i];
d = (80 + randomfloat(10));
if ( !isdefined ( self.damageOwner ) )
self radiusdamage (barrels[i].origin, 4, d, d);
else
self radiusdamage (barrels[i].origin, 4, d, d, self.damageOwner);
//barrels[i] dodamage( , P);
}
}
for(i=0; i<remove.size; i++)
barrels = common_scripts\utility::array_remove(barrels, remove[i]);
wait .1;
}
if(!isdefined(self.barrel))
return;
if( distance(P, self.start.origin) < 32)
{
d = (80 + randomfloat(10));
if ( !isdefined ( self.damageOwner ) )
self radiusdamage (self.barrel.origin, 4, d, d);
else
self radiusdamage (self.barrel.origin, 4, d, d, self.damageOwner);
}
}
oil_spill_burn_section(P)
{
count = 0;
time = 0;
playfx (level.breakables_fx["oilspill"]["burn"], P);
while(time < 5)
{
if ( !isdefined ( self.damageOwner ) )
self radiusdamage(P, 32, 5, 1);
else
self radiusdamage(P, 32, 5, 1, self.damageOwner);
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.damageTaken = 0;
self setcandamage(true);
for (;;)
{
self waittill("damage", amount ,attacker, direction_vec, P, type);
if(type == "MOD_MELEE" || type == "MOD_IMPACT")
continue;
self.damagetype = type;
self.damageOwner = attacker;
if (level.barrelExplodingThisFrame)
wait randomfloat(1);
self.damageTaken += amount;
if (self.damageTaken == amount)
self thread explodable_barrel_burn();
}
}
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 = common_scripts\utility::vector_multiply(up, 44);
if(dot < .5)
{
offset1 = common_scripts\utility::vector_multiply(up, 22) - (0,0,30);
offset2 = common_scripts\utility::vector_multiply(up, 22) + (0,0,14);
}
if( self.damagetype != "MOD_GRENADE_SPLASH" && self.damagetype != "MOD_GRENADE" )
{
while (self.damageTaken < level.barrelHealth)
{
if (!startedfx)
{
playfx (level.breakables_fx["barrel"]["burn_start"], self.origin + offset1);
startedfx = true;
}
if (count > 20)
count = 0;
playfx (level.breakables_fx["barrel"]["burn"], self.origin + offset2);
if (count == 0)
{
self.damageTaken += (10 + randomfloat(10));
}
count++;
wait 0.05;
}
}
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 + common_scripts\utility::vector_multiply(up, 22));
end = physicstrace(start, (start + (0,0,-64)));
offset = end - self.origin;
}
offset += (0,0,4);
self playsound (level.barrelExpSound);
//level thread play_sound_in_space(level.barrelExpSound, self.origin);
playfx (level.breakables_fx["barrel"]["explode"], self.origin + offset);
level.barrelExplodingThisFrame = true;
if (isdefined (self.remove))
{
self.remove delete();
}
phyExpMagnitude = 2;
minDamage = 1;
maxDamage = 250;
blastRadius = 250;
if (isdefined(self.radius))
blastRadius = self.radius;
// do not pass damage owner if they have disconnected before the barrels explode
if ( !isdefined( self.damageOwner ) )
self radiusDamage(self.origin + (0,0,30), blastRadius, maxDamage, minDamage, undefined, "MOD_EXPLOSIVE", "barrel_mp");
else
self radiusDamage(self.origin + (0,0,30), blastRadius, maxDamage, minDamage, self.damageOwner, "MOD_EXPLOSIVE", "barrel_mp" );
physicsExplosionSphere( self.origin + (0,0,30), blastRadius, blastRadius/2, phyExpMagnitude );
self maps\mp\gametypes\_shellshock::barrel_earthQuake();
if (randomint(2) == 0)
self setModel("com_barrel_piece");
else
self setModel("com_barrel_piece2");
self setCanDamage( false );
if(dot < .5)
{
start = (self.origin + common_scripts\utility::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;
}
getstruct(name, type)
{
if(!isdefined(level.struct_class_names))
return undefined;
array = level.struct_class_names[type][name];
if(!isdefined(array))
return undefined;
if(array.size > 1)
{
assertMsg ("getstruct used for more than one struct of type " + type + " called " + name +".");
return undefined;
}
return array[0];
}
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 = common_scripts\utility::array_remove ( level.breakables_clip , self.remove );
}