350 lines
No EOL
7.5 KiB
C++
350 lines
No EOL
7.5 KiB
C++
/*
|
|
=============================
|
|
ewportal.qc
|
|
coded by
|
|
Michael Rogers a.k.a Xsniper
|
|
ssj_xsniper@yahoo.com
|
|
http://www.xsniper.net/
|
|
|
|
Description:
|
|
This file contains all functions pertaining to the demon portal,
|
|
which is used in Flood Co-op mode.
|
|
=============================
|
|
*/
|
|
|
|
void(vector org) spawn_tfog;
|
|
void(vector org, entity death_owner) spawn_tdeath;
|
|
void(vector spot) create_dwellerbot;
|
|
void(vector spot) create_wraithbot;
|
|
void(vector spot) create_tenebbot;
|
|
void(vector spot) create_tormentbot;
|
|
void(vector spot) create_mercabot;
|
|
void(vector spot) create_hhoundbot;
|
|
void(vector spot) create_outriderbot;
|
|
void(vector spot) create_scoutbot;
|
|
void() CheckRules;
|
|
//==============================================================================
|
|
//Portal Summoning Code Below
|
|
|
|
void() portal_glow =
|
|
{
|
|
//reset our glow color if we are done being in pain
|
|
if (time > self.pain_finished)
|
|
{
|
|
self.glow_size = 150;
|
|
self.glow_red = 1;
|
|
self.glow_green = 0;
|
|
self.glow_blue = 0;
|
|
|
|
//put our old skin back on
|
|
self.skin = 0;
|
|
}
|
|
};
|
|
|
|
float() count_monsters =
|
|
{
|
|
local entity mon;
|
|
local float tempcount;
|
|
|
|
//initialize tempcount
|
|
tempcount = 0;
|
|
|
|
mon = find(world, monflag, "TRUE");
|
|
|
|
while (mon)
|
|
{
|
|
tempcount = tempcount + 1;
|
|
|
|
//next monster
|
|
mon = find(mon, monflag, "TRUE");
|
|
}
|
|
|
|
//decrement tempcount by one because portal shouldnt be counted
|
|
tempcount = tempcount - 1;
|
|
|
|
//pass the value back
|
|
return tempcount;
|
|
};
|
|
|
|
float(float rate) set_spawn_rate =
|
|
{
|
|
local float r;
|
|
local float newrate
|
|
|
|
//calculate r based on skill level
|
|
if (cvar("skill") == 0)
|
|
r = 0;
|
|
else if (cvar("skill") == 1)
|
|
r = 1;
|
|
else if (cvar("skill") == 2)
|
|
r = 2;
|
|
else if (cvar("skill") == 3)
|
|
r = 3;
|
|
|
|
newrate = rate - r;
|
|
|
|
return (newrate);
|
|
};
|
|
|
|
vector() find_demon_spot =
|
|
{
|
|
local entity spot;
|
|
local entity thing;
|
|
local float spotcount;
|
|
|
|
//initialize spotcount
|
|
spotcount = 0;
|
|
|
|
//find an info_player_deathmatch
|
|
spot = find(world, classname, "info_player_deathmatch");
|
|
|
|
while(spot != world)
|
|
{
|
|
//check for players
|
|
thing = findradius(spot.origin, 32);
|
|
|
|
if (spot.classname == "info_player_deathmatch" && spot.oldspot != 1)
|
|
{
|
|
if (thing.classname != "player" && !(thing.flags & FL_MONSTER))
|
|
{
|
|
//set this spot to our oldspot
|
|
spot.oldspot = 1;
|
|
|
|
//got our spot so lets go
|
|
return spot.origin;
|
|
}
|
|
}
|
|
else if (spot.classname == "info_player_deathmatch" && spot.oldspot == 1)
|
|
spotcount = spotcount + 1;
|
|
|
|
spot = nextent(spot);
|
|
}
|
|
|
|
//need to reset old spots
|
|
if (spotcount > 0)
|
|
reset_old_spots();
|
|
|
|
//if we couldn't find a spot then summon infront of portal
|
|
return (self.origin + (v_forward * 80));
|
|
};
|
|
|
|
float() portal_check_summon =
|
|
{
|
|
local vector start, end;
|
|
|
|
//set up angles stuff
|
|
self.v_angle = self.angles;
|
|
makevectors (self.angles);
|
|
|
|
//we need to check for walls so that we don't summon demons inside them
|
|
|
|
// Check in front of the necromancer for a wall
|
|
start = self.origin;
|
|
end = start + (v_forward * 80);
|
|
|
|
// Check 80 units infront
|
|
traceline (start, end, TRUE, self);
|
|
|
|
// If there is a wall or obstacle then return NOSUMMON
|
|
if (trace_fraction != 1.0)
|
|
return (0); //NOSUMMON
|
|
|
|
return (1); //SUMMON
|
|
};
|
|
|
|
void() portal_summon =
|
|
{
|
|
local float r;
|
|
|
|
//set up random variable
|
|
r = random();
|
|
|
|
//set up angles stuff
|
|
makevectors (self.angles);
|
|
|
|
//pick which monster to summon at random
|
|
if (r <= 0.125) //create dweller
|
|
{
|
|
//create 1 infront, and 1 somewhere else
|
|
create_dwellerbot((self.origin + (v_forward * 80)));
|
|
create_dwellerbot(find_demon_spot());
|
|
}
|
|
else if (r <= 0.25) //create wraith
|
|
{
|
|
//create 1 infront, and 1 somewhere else
|
|
create_wraithbot((self.origin + (v_forward * 80)));
|
|
create_wraithbot(find_demon_spot());
|
|
}
|
|
else if (r <= 0.375) //create teneb
|
|
{
|
|
//create 1 infront, and 1 somewhere else
|
|
create_tenebbot((self.origin + (v_forward * 80)));
|
|
create_tenebbot(find_demon_spot());
|
|
}
|
|
else if (r <= 0.5) //create torment
|
|
{
|
|
//create 1 infront, and 1 somewhere else
|
|
create_tormentbot((self.origin + (v_forward * 80)));
|
|
create_tormentbot(find_demon_spot());
|
|
}
|
|
else if (r <= 0.625) //create merc a
|
|
{
|
|
//create 1 infront, and 1 somewhere else
|
|
create_mercabot((self.origin + (v_forward * 80)));
|
|
create_mercabot(find_demon_spot());
|
|
}
|
|
else if (r <= 0.75) //create hhound
|
|
{
|
|
//create 1 infront, and 1 somewhere else
|
|
create_hhoundbot((self.origin + (v_forward * 80)));
|
|
create_hhoundbot(find_demon_spot());
|
|
}
|
|
else if (r <= 0.875) //create outrider
|
|
{
|
|
//create 1 infront, and 1 somewhere else
|
|
create_outriderbot((self.origin + (v_forward * 80)));
|
|
create_outriderbot(find_demon_spot());
|
|
}
|
|
else //create scout
|
|
{
|
|
//create 1 infront, and 1 somewhere else
|
|
create_scoutbot((self.origin + (v_forward * 80)));
|
|
create_scoutbot(find_demon_spot());
|
|
}
|
|
};
|
|
|
|
void() spawn_demons =
|
|
{
|
|
//check multiplayer rules
|
|
CheckRules();
|
|
|
|
//reset our glow color if we aren't hurting
|
|
portal_glow();
|
|
|
|
//get num_mon_types
|
|
num_mon_types = count_monsters();
|
|
|
|
if (portal_check_summon() && num_mon_types < 15)
|
|
{
|
|
// make some noise
|
|
sound (self, CHAN_VOICE, "misc/portalopen.wav", 1, ATTN_NORM);
|
|
portal_summon();
|
|
}
|
|
|
|
//set up his next think
|
|
self.nextthink = time + set_spawn_rate(8);
|
|
self.think = spawn_demons;
|
|
};
|
|
|
|
void() portal_pain =
|
|
{
|
|
local float h, i, j;
|
|
|
|
//give j a random value
|
|
j = random() * 10;
|
|
|
|
//initialize i
|
|
i = 0;
|
|
|
|
//revert to old glow after time > self.pain_finished
|
|
self.pain_finished = time + 0.3;
|
|
|
|
//increase our glow size to the max
|
|
self.glow_size = 250;
|
|
|
|
//adjust glow to random colors through loop
|
|
while (i < j)
|
|
{
|
|
h = random();
|
|
|
|
if (random() <= 0.33)
|
|
self.glow_red = h;
|
|
else if (random() <= 0.66)
|
|
self.glow_green = h;
|
|
else
|
|
self.glow_blue = h;
|
|
|
|
i = i + 0.5;
|
|
}
|
|
|
|
//put on our pain skin
|
|
self.skin = 1;
|
|
};
|
|
|
|
/*
|
|
=====================
|
|
create_demon_portal
|
|
|
|
This will make a portal that spawns different types
|
|
of demons until it is destroyed. It can only be
|
|
destroyed by praying around the portal.
|
|
|
|
The demon portal will spawn the following creatures:
|
|
|
|
-dwellers
|
|
-wraiths
|
|
-tenebs
|
|
-torments
|
|
-mercas
|
|
-hhounds
|
|
-outriders
|
|
-scouts
|
|
=====================
|
|
*/
|
|
void(entity spot) create_demon_portal =
|
|
{
|
|
local entity portal;
|
|
local float r;
|
|
|
|
// start entity and place it in world
|
|
portal = spawn();
|
|
setorigin (portal, spot.origin);
|
|
spawn_tfog (portal.origin);
|
|
spawn_tdeath (portal.origin, portal);
|
|
|
|
// set size and shape
|
|
portal.solid = SOLID_SLIDEBOX;
|
|
portal.movetype = MOVETYPE_STEP;
|
|
setmodel (portal, "models/map/goyle.md2");
|
|
setsize (portal, '-16 -16 -24', '16 16 40');
|
|
portal.takedamage = DAMAGE_AIM;
|
|
portal.th_pain = portal_pain;
|
|
portal.th_die = banish_monster;
|
|
|
|
// define his animation
|
|
portal.health = 2000;
|
|
portal.spirit = 1000;
|
|
portal.alpha = 1; //we aren't transparent
|
|
|
|
// pick a random animation frame
|
|
r = random();
|
|
|
|
if (r <= 0.2)
|
|
portal.frame = 0;
|
|
else if (r <= 0.4)
|
|
portal.frame = 1;
|
|
else if (r <= 0.6)
|
|
portal.frame = 2;
|
|
else if (r <= 0.8)
|
|
portal.frame = 3;
|
|
else
|
|
portal.frame = 4;
|
|
|
|
// polish him up
|
|
portal.classname = "demon_portal";
|
|
portal.angles = spot.angles;
|
|
|
|
// make the portal glow red
|
|
portal.glow_size = 150;
|
|
portal.glow_red = 1;
|
|
|
|
//set up our monflag
|
|
portal.monflag = "TRUE";
|
|
|
|
// begin his thinking
|
|
portal.nextthink = time + 0.1 + random();
|
|
portal.think = spawn_demons;
|
|
};
|
|
|
|
|
|
|