ew-progs/ew/effects/ewmisc.qc
2011-09-06 00:00:00 +00:00

632 lines
15 KiB
C++

/*
=============================
ewmisc.qc
coded by
Michael Rogers a.k.a Xsniper
ssj_xsniper@yahoo.com
xsniper.virtualave.net
Description:
This file holds miscellaneous EW things.
Such as Fire Columns which are a new
object that can be placed into levels.
=============================
*/
void() fire_column_remove;
void() BecomeExplosion;
float(float hamount) set_health;
//====================================================================================================
//Statue Code Below
/*
====================
misc_statue
This is a statue that just sits in the level, its eyecandy only.
Spawnflags
1 : skin 1
2 : skin 2
4 : skin 3
====================
*/
void() misc_statue =
{
local entity statue;
// start entity and place it in world
statue = spawn();
setorigin (statue, self.origin);
// set size and shape
statue.solid = SOLID_SLIDEBOX;
precache_model ("models/map/statue.md2");
setmodel (statue, "models/map/statue.md2");
setsize (statue, '-16 -16 -24', '16 16 40');
// set up angles
statue.angles = self.angles;
//set skin based on spawnflags
if (self.spawnflags & 1)
statue.skin = 0;
else if (self.spawnflags & 2)
statue.skin = 1;
else if (self.spawnflags & 4)
statue.skin = 2;
};
//====================================================================================================
//Fire Column Code Below
/*
====================
fire_column_touch
If you touch the fire column then get burned!
====================
*/
void() fire_column_touch =
{
//don't burn our owner
if (self.owner == other)
return;
//don't burn boss monsters
if (other.classname == "monster_bossf1" || other.classname == "monster_bossf2")
return;
//don't let arrows stick in me
if (other.model == "models/ammo/v_bolt.md2")
{
remove(other);
return;
}
//burn that punk who touched me!
T_Damage(other,self,self.owner,1);
};
void() fire_column_return =
{
self.solid = SOLID_SLIDEBOX;
self.effects = self.effects + EF_DIMLIGHT;
setmodel (self, "progs/flame2.mdl");
setsize (self, '-16 -16 -24', '16 16 40');
self.nextthink = time + self.firern;
self.think = fire_column_remove;
self.touch = fire_column_touch;
};
void() fire_column_remove =
{
self.effects = self.effects - EF_DIMLIGHT;
self.solid = SOLID_NOT;
setmodel (self, "");
setsize (self, '-16 -16 -24', '16 16 40');
self.nextthink = time + self.firere;
self.think = fire_column_return;
self.touch = SUB_Null;
};
/*
====================
create_fire_column
Creates a fire column that remains for x seconds
vector spot: place to put the fire
float continue: controls whether fire comes up and goes down continuously
0: doesnt do this
1: it does
float x: amount of seconds for firecolumn to remain
float antix: used for continuous fire so they come back from ground up
====================
*/
void(vector spot, float continue, float x, float antix) create_fire_column =
{
local entity fire;
// start entity and place it in world
fire = spawn();
setorigin (fire, spot);
// set size and shape
fire.solid = SOLID_SLIDEBOX;
setmodel (fire, "progs/flame2.mdl");
setsize (fire, '-16 -16 -24', '16 16 40');
fire.frame = 1;
//initialize firere and firern
//firere = fireremove
//firern = firereturn
fire.firere = antix + 5;
fire.firern = x + 5;
// polish him up
fire.classname = "firecolumn";
fire.effects = fire.effects + EF_DIMLIGHT;
// begin his thinking
fire.nextthink = time + x;
// are we continuous or not?
if (continue == 1)
fire.think = fire_column_remove;
else
fire.think = SUB_Remove;
// if you touch him then get burned!
fire.touch = fire_column_touch;
// we need to know who owns us so we dont burn him
fire.owner = self;
};
/*
====================
misc_fire_column
This is an object that can be placed into the world and it will create
a fire column at its origin.
====================
*/
void() misc_fire_column =
{
local float firecount, anticount, firetime;
local vector start, plus;
//set the starting height
start = '0 0 -10';
//set the increment amount
plus = '0 0 25';
//initialize firecount and anticount
firecount = 7;
anticount = 0;
if (self.spawnflags & 1) //fire column stays up forever
{
firetime = 999;
while(firecount > 0)
{
create_fire_column((self.origin + start),0,firetime,anticount);
start = start + plus;
firecount = firecount - 1;
}
}
else if (self.spawnflags & 2) //fire column comes up for 15 seconds then goes back down and comes up again
{
while(firecount > 0)
{
create_fire_column((self.origin + start),1,firecount,anticount);
start = start + plus;
firecount = firecount - 1;
anticount = anticount + 1;
}
}
else //default settings, comes up and goes back down, never appears again
{
while(firecount > 0)
{
create_fire_column((self.origin + start),0,firecount,anticount);
start = start + plus;
firecount = firecount - 1;
}
}
};
//====================================================================================================
//Explosion Code Below
/*
====================
explo_explode
Used by create_explosion, this does the blowing up and damaging of things nearby.
====================
*/
void() explo_explode =
{
T_RadiusDamage (self, self, self.dmg, self.owner);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_TAREXPLOSION);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
BecomeExplosion ();
};
void() explo_nospr_explode =
{
T_RadiusDamage (self, self, self.dmg, self.owner);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
//BecomeExplosion();
remove(self);
};
/*
==============================
big explosion animation frames
==============================
*/
void() big_explo1 =[ 0, big_explo2 ]
{
setmodel (self,"models/weapons/gfx/bossboom.mdl");
setsize (self, '-8 -8 -12', '8 8 20');
//make partially transparent
self.alpha = 0.3;
//make some noise
sound (self, CHAN_VOICE, "weapons/flaskexplode.wav", 1, ATTN_NORM);
};
void() big_explo2 =[ 1, big_explo3 ] {};
void() big_explo3 =[ 2, big_explo4 ] {};
void() big_explo4 =[ 3, big_explo5 ] {};
void() big_explo5 =[ 4, big_explo6 ] {};
void() big_explo6 =[ 5, big_explo7 ] {};
void() big_explo7 =[ 6, big_explo8 ] {};
void() big_explo8 =[ 7, big_explo9 ] {};
void() big_explo9 =[ 8, big_explo10 ] {};
void() big_explo10 =[ 9, big_explo11 ] {};
void() big_explo11 =[ 10, big_explo12 ] {};
void() big_explo12 =[ 11, big_explo13 ] {};
void() big_explo13 =[ 12, big_explo14 ] {};
void() big_explo14 =[ 13, big_explo14 ]
{
//time to really blow up
explo_explode();
};
/*
====================
create_explosion
Creates an explosion at the specified coordinate that happens in x seconds
vector spot: place to create the explosion
float x: amount of time in seconds to wait before the explosion occurs
float etype: type of explosion
0: particle explosion
1: big explosion
float damage: amount of damage to do
====================
*/
void(vector spot, float x, float etype, float damage) create_explosion =
{
local entity explo;
// start entity and place it in world
explo = spawn();
setorigin (explo, spot);
// set size and shape
explo.solid = SOLID_SLIDEBOX;
setmodel (explo, "");
setsize (explo, '-8 -8 -12', '8 8 20');
explo.nextthink = time + x;
// set our damage
explo.dmg = damage;
// do correct explosion type
if (etype == 0) //particle explosion with sprite
explo.think = explo_explode;
else if (etype == 1) //big explosion
explo.think = big_explo1;
else if (etype == 2) //particle explosion
explo.think = explo_nospr_explode;
else //incase they put something else in there
explo.think = explo_explode;
// few other things
explo.classname = "explosion";
explo.owner = self;
};
//====================================================================================================
//Black Hole Code Below
void () sp_holeremove =
{
//keep track of what time it is
bhtime = time;
sound (self, CHAN_VOICE, "weapons/lstart.wav", 1, ATTN_NORM);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_TELEPORT);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
remove (self);
};
void () sp_holetouch =
{
local float bhdmg;
local vector org, dir;
if ( (other.takedamage == DAMAGE_YES) || (other.takedamage == DAMAGE_AIM) )
{
bhdmg = 1;
T_Damage (other, self, self, bhdmg);
}
};
void () sp_holesuck =
{
local entity head;
local vector tohole;
local float disttohole, weakness;
//if bf2 is dead then its time to dissapear
if (bf2_dead == 1)
sp_holeremove();
head = findradius (self.origin, 1280);
while (head)
{
if ( (head.classname != "blackhole") && (head.classname != "plat") && (head.classname != "monster_bossf2") )
{
if ( (head.movetype != MOVETYPE_NONE) && (head.movetype != MOVETYPE_PUSH) )
{
disttohole = vlen(self.origin - head.origin);
if (disttohole > 80)
{
tohole = normalize(self.origin - head.origin);
tohole_x = tohole_x*375 + (40*random());
tohole_y = tohole_y*375 + (40*random());
if ( head.classname == "player" )
{
tohole_z = tohole_z*210;
}
else
{
tohole_z = tohole_z*320;
}
weakness = (1280 - disttohole) / 1280;
weakness = (weakness * weakness);
head.velocity = head.velocity + (tohole * weakness);
}
else
{
head.velocity = head.velocity * 0.9;
}
}
}
head = head.chain;
}
self.touch = sp_holetouch;
self.nextthink = time + 0.1;
self.think = sp_holesuck;
};
/*
====================
create_black_hole
Creates a spot in 3d space that draws everything towards it
vector spot: place to create the black hole
====================
*/
void(vector spot) create_black_hole =
{
local entity hole;
//put him into the world
hole = spawn();
hole.owner = self;
hole.movetype = MOVETYPE_FLYMISSILE;
hole.solid = SOLID_BBOX;
hole.classname = "blackhole";
//make him take damage so we can kill him
hole.takedamage = DAMAGE_AIM;
//set up health
hole.health = set_health(50);
//what to do if it dies
hole.th_die = sp_holeremove;
hole.ltime = time;
hole.avelocity = '800 650 500';
hole.velocity = '0 0 0';
//turn it into a monster
hole.monflag = "TRUE";
setmodel (hole, "models/enemies/demonorb.md2");
setsize (hole, '-6 -6 -6', '6 6 6');
sound (hole, CHAN_WEAPON, "misc/r_tele1.wav", 1, ATTN_NORM);
setorigin (hole, spot);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_TELEPORT);
WriteCoord (MSG_BROADCAST, hole.origin_x);
WriteCoord (MSG_BROADCAST, hole.origin_y);
WriteCoord (MSG_BROADCAST, hole.origin_z);
hole.touch = sp_holetouch;
hole.nextthink = time + 0.1;
hole.think = sp_holesuck;
};
//====================================================================================================
//On Fire / Burning Code Below
/*
=================
FirePhysical
This function is called by AmBurning and applies the
physical aspects of being on fire to the entity.
=================
*/
void() FirePhysical =
{
local float rdamage;
//set up the damage
rdamage = 1;
//do the damage
T_Damage(self,self.burninflictor,self.burninflictor,rdamage);
};
void() FireGFXThink =
{
//do some angles stuff
makevectors(self.owner.angles);
//dissapear if our time is up
if (time > self.ltime || time > self.owner.burningtime)
remove(self);
else //update our origin
setorigin(self, (self.owner.origin + (v_forward * 10) - (v_right * self.firern) + '0 0 5'));
//make some noise
sound (self, CHAN_WEAPON, "weapons/lock4.wav", 1, ATTN_NORM);
//gotta keep thinking about this
self.nextthink = time + 0.1;
self.think = FireGFXThink;
};
/*
==================
FireGraphical
This function is called by AmBurning and applies the
graphical aspects of being on fire to the entity.
float r: offset to the left or right of self.origin
==================
*/
void(float r) FireGraphical =
{
local entity firegfx;
//do some angles stuff
makevectors(self.angles);
firegfx = spawn();
setorigin(firegfx, (self.origin + (v_forward * 10) - (v_right * r) + '0 0 5'));
//set model
setmodel (firegfx, "progs/flame2.mdl");
//random chance of being a big flame
if (random() <= 0.2)
firegfx.frame = 1;
//set up our owner
firegfx.owner = self;
//set up duration
firegfx.ltime = time + 0.5;
//misc
firegfx.firern = r;
//lets do some thinking so we can stay with the entity when he moves
firegfx.nextthink = time + 0.1;
firegfx.think = FireGFXThink;
};
float() check_liquid =
{
local float p;
if (self.classname == "player")
makevectors(self.v_angle);
else
makevectors(self.angles);
//check for water, slime, or lava
p = pointcontents(self.origin + v_forward*16);
return p;
};
/*
================
AmBurning
This function is called by different entities during their think functions
or by the player during his playerprethink function. It basically
checks to see if the entity should be on fire right now. And if this is
the case then it will apply all the physical and graphical aspects of something
being on fire.
================
*/
void() AmBurning =
{
//check for lava
if (check_liquid() == CONTENT_LAVA) //standing in lava so ofcourse we are on fire!
self.onfire = 1;
//check if the entity is on fire
if (self.onfire == 1 && time < self.burningtime)
{
//yes we are on fire
if (time < self.burningtime && random() <= 0.2)
{
FirePhysical();
FireGraphical(-5 + random() * 2);
FireGraphical(0 + random() * 2);
FireGraphical(5 + random() *2);
}
//see if we are in water
if (check_liquid() == CONTENT_WATER)
self.onfire = 0; //not on fire anymore
}
else if(self.onfire == 1 && time > self.burningtime)
{
//lets stop burning now
self.onfire = 0;
self.burningtime = 0;
}
//not on fire so don't do anything
};
void(float numlines, string s1, string s2, string s3, string s4) DebugMsg =
{
if (numlines >= 1)
bprint(s1);
if (numlines >= 2)
bprint(s2);
if (numlines >= 3)
bprint(s3);
if (numlines >= 4)
bprint(s4);
};