/* ============================= 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); };