885 lines
23 KiB
C++
885 lines
23 KiB
C++
/* items quickc program
|
|
by jim dose' 9/13/96
|
|
copyright (c)1996 hipnotic interactive, inc.
|
|
all rights reserved.
|
|
do not distribute.
|
|
*/
|
|
|
|
float underwater = 2;
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
hipnotic items
|
|
|
|
===============================================================================
|
|
*/
|
|
//
|
|
// hip_powerup_touch function
|
|
//
|
|
void() hip_powerup_touch =
|
|
{
|
|
local entity stemp;
|
|
local float best;
|
|
|
|
if (other.classname != "player")
|
|
return;
|
|
if (other.health <= 0)
|
|
return;
|
|
|
|
sprint (other, "you got the ");
|
|
sprint (other, self.netname);
|
|
sprint (other,"\n");
|
|
|
|
if (deathmatch)
|
|
{
|
|
self.mdl = self.model;
|
|
|
|
// if ((self.classname == "item_artifact_invulnerability") ||
|
|
// (self.classname == "item_artifact_invisibility"))
|
|
// self.nextthink = time + 60*5;
|
|
// else
|
|
self.nextthink = time + 60;
|
|
|
|
self.think = sub_regen;
|
|
}
|
|
|
|
sound (other, chan_voice, self.noise, 1, attn_norm);
|
|
stuffcmd (other, "bf\n");
|
|
self.solid = solid_not;
|
|
other.items2 = other.items2 | self.items2;
|
|
self.model = string_null;
|
|
|
|
// do the apropriate action
|
|
if ( self.classname == "item_artifact_wetsuit" )
|
|
{
|
|
other.wetsuit_time = 1;
|
|
other.wetsuit_finished = time + 30;
|
|
}
|
|
if ( self.classname == "item_artifact_empathy_shields" )
|
|
{
|
|
other.empathy_time = 1;
|
|
other.empathy_finished = time + 30;
|
|
}
|
|
|
|
activator = other;
|
|
sub_usetargets(); // fire all targets / killtargets
|
|
};
|
|
|
|
|
|
/*quaked item_artifact_wetsuit (0 .5 .8) (-16 -16 -24) (16 16 32)
|
|
player takes no damage from electrical attacks and swims faster for 30 seconds
|
|
*/
|
|
void() item_artifact_wetsuit =
|
|
{
|
|
self.touch = hip_powerup_touch;
|
|
|
|
precache_model ("progs/wetsuit.mdl");
|
|
precache_sound ("misc/wetsuit.wav");
|
|
precache_sound ("misc/weton.wav");
|
|
precache_sound ("items/suit2.wav");
|
|
self.noise = "misc/weton.wav";
|
|
setmodel (self, "progs/wetsuit.mdl");
|
|
self.netname = "wetsuit";
|
|
self.items2 = hip_it_wetsuit;
|
|
setsize (self, '-16 -16 -24', '16 16 32');
|
|
|
|
startitem ();
|
|
};
|
|
|
|
/*
|
|
===============================================================================
|
|
//
|
|
// horn of conjuring
|
|
//
|
|
===============================================================================
|
|
*/
|
|
|
|
void() horn_touch =
|
|
{
|
|
local float amount;
|
|
local float value;
|
|
|
|
if (other.classname != "player")
|
|
return;
|
|
|
|
if (deathmatch)
|
|
{
|
|
self.mdl = self.model;
|
|
|
|
self.nextthink = time + 60;
|
|
|
|
self.think = sub_regen;
|
|
}
|
|
|
|
self.solid = solid_not;
|
|
self.model = string_null;
|
|
sprint (other, "you got the horn of conjuring\n");
|
|
sound (other, chan_voice, self.noise, 1, attn_none);
|
|
stuffcmd (other, "bf\n");
|
|
activator = other;
|
|
horn_active = 1;
|
|
horn_charmer = other;
|
|
sub_usetargets(); // fire all targets / killtargets
|
|
horn_active = 0;
|
|
};
|
|
|
|
/*quaked item_hornofconjuring (0 .5 .8) (-16 -16 0) (16 16 32)
|
|
horn of conjuring.
|
|
you must make func_spawn entities connected to this entity
|
|
to spawn the charmed creature.
|
|
*/
|
|
void() item_hornofconjuring =
|
|
{
|
|
self.touch = horn_touch;
|
|
|
|
precache_model("progs/horn.mdl");
|
|
precache_sound("hipitems/horn.wav");
|
|
setmodel(self, "progs/horn.mdl");
|
|
self.noise = "hipitems/horn.wav";
|
|
setsize (self, '-16 -16 0', '16 16 32');
|
|
startitem ();
|
|
};
|
|
|
|
/*quaked item_artifact_empathy_shields (0 .5 .8) (-16 -16 0) (16 16 32)
|
|
empathy shield.
|
|
*/
|
|
void() item_artifact_empathy_shields =
|
|
{
|
|
self.touch = hip_powerup_touch;
|
|
|
|
precache_model("progs/empathy.mdl");
|
|
precache_sound("hipitems/empathy.wav");
|
|
precache_sound("hipitems/empathy2.wav");
|
|
precache_sound ("items/suit2.wav");
|
|
setmodel(self, "progs/empathy.mdl");
|
|
self.noise = "hipitems/empathy.wav";
|
|
self.netname = "empathy shields";
|
|
self.items2 = hip_it_empathy_shields;
|
|
setsize (self, '-16 -16 0', '16 16 32');
|
|
startitem ();
|
|
};
|
|
/*
|
|
===============================================================================
|
|
|
|
hipnotic weapons
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
/*quaked weapon_mjolnir (0 .5 .8) (-16 -16 0) (16 16 32)
|
|
*/
|
|
|
|
void() weapon_mjolnir =
|
|
{
|
|
precache_model ("progs/g_hammer.mdl");
|
|
setmodel (self, "progs/g_hammer.mdl");
|
|
self.weapon = 3;
|
|
self.netname = "mjolnir";
|
|
self.items = it_mjolnir;
|
|
self.touch = weapon_touch;
|
|
setsize (self, '-16 -16 0', '16 16 56');
|
|
startitem ();
|
|
};
|
|
|
|
/*quaked weapon_laser_gun (0 .5 .8) (-16 -16 0) (16 16 32)
|
|
*/
|
|
|
|
void() weapon_laser_gun =
|
|
{
|
|
precache_model ("progs/g_laserg.mdl");
|
|
setmodel (self, "progs/g_laserg.mdl");
|
|
self.weapon = 3;
|
|
self.netname = "laser cannon";
|
|
self.items = it_laser_cannon;
|
|
self.touch = weapon_touch;
|
|
setsize (self, '-16 -16 0', '16 16 56');
|
|
startitem ();
|
|
};
|
|
|
|
/*quaked weapon_proximity_gun (0 .5 .8) (-16 -16 0) (16 16 32)
|
|
*/
|
|
|
|
void() weapon_proximity_gun =
|
|
{
|
|
precache_model ("progs/g_prox.mdl");
|
|
setmodel (self, "progs/g_prox.mdl");
|
|
self.weapon = 3;
|
|
self.netname = "proximity gun";
|
|
self.items = it_proximity_gun;
|
|
self.touch = weapon_touch;
|
|
setsize (self, '-16 -16 0', '16 16 56');
|
|
startitem ();
|
|
};
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
hipnotic hazards
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
void() spikemine_home =
|
|
{
|
|
local entity head;
|
|
local entity selected;
|
|
local float cur_dist;
|
|
local float head_dist;
|
|
local vector dir, vtemp;
|
|
|
|
self.frame = self.frame + 1;
|
|
if (self.frame==9) self.frame = 0;
|
|
self.nextthink = time + 0.2;
|
|
self.think = spikemine_home;
|
|
|
|
// look in our immediate vicinity
|
|
|
|
if (self.search_time < time)
|
|
{
|
|
selected = world;
|
|
cur_dist = 2000;
|
|
head = findradius(self.origin, 2000);
|
|
while(head)
|
|
{
|
|
if(!(head.flags & fl_notarget) && (head.flags & fl_client))
|
|
{
|
|
if (visible(head) && (head.health > 0))
|
|
{
|
|
head_dist = vlen(head.origin-self.origin);
|
|
if (head_dist < cur_dist)
|
|
{
|
|
selected = head;
|
|
cur_dist = head_dist;
|
|
}
|
|
}
|
|
}
|
|
head = head.chain;
|
|
}
|
|
// if (selected != world && selected != self.enemy)
|
|
if (selected != world)
|
|
sound (self, chan_voice, "hipitems/spikmine.wav", 1, attn_norm);
|
|
self.enemy = selected;
|
|
self.search_time = time + 1.3;
|
|
}
|
|
if (self.enemy == world)
|
|
{
|
|
sound (self, chan_voice, "misc/null.wav", 1, attn_norm);
|
|
self.velocity = '0 0 0';
|
|
return;
|
|
}
|
|
vtemp = self.enemy.origin + '0 0 10';
|
|
dir = normalize(vtemp - self.origin);
|
|
if (infront(self.enemy))
|
|
{
|
|
self.velocity = dir * ((skill*50) + 50);
|
|
}
|
|
else
|
|
{
|
|
self.velocity = dir * ((skill*50) + 150);
|
|
}
|
|
};
|
|
|
|
void() spikemine_touch =
|
|
{
|
|
if (self.health>0)
|
|
{
|
|
if (other.classname == "trap_spike_mine")
|
|
return;
|
|
if (other.classname == "missile")
|
|
return;
|
|
if (other.classname == "grenade")
|
|
return;
|
|
if (other.classname == "hiplaser")
|
|
return;
|
|
if (other.classname == "proximity_grenade")
|
|
return;
|
|
|
|
t_damage(self,self,self,self.health+10);
|
|
// killed_monsters = killed_monsters + 1;
|
|
// writebyte (msg_all, svc_killedmonster);
|
|
}
|
|
// self.effects = self.effects | ef_muzzleflash;
|
|
|
|
t_radiusdamage (self, self, 110, world);
|
|
sound (self, chan_weapon, "weapons/r_exp3.wav", 1, attn_norm);
|
|
|
|
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);
|
|
|
|
sound (self, chan_voice, "misc/null.wav", 1, attn_norm);
|
|
self.velocity = '0 0 0';
|
|
self.touch = sub_null;
|
|
setmodel (self, "progs/s_explod.spr");
|
|
self.solid = solid_not;
|
|
s_explode1 ();
|
|
};
|
|
|
|
/*
|
|
spike_mine_first_think
|
|
*/
|
|
|
|
void() spike_mine_first_think =
|
|
{
|
|
self.think = spikemine_home;
|
|
self.nextthink = time + 0.1;
|
|
self.search_time = 0;
|
|
self.takedamage = damage_aim;
|
|
self.use = monster_use;
|
|
};
|
|
|
|
/*quaked trap_spike_mine (0 .5 .8) (-16 -16 0) (16 16 32)
|
|
*/
|
|
|
|
void() trap_spike_mine =
|
|
{
|
|
if (deathmatch)
|
|
{
|
|
remove(self);
|
|
return;
|
|
}
|
|
precache_model ("progs/spikmine.mdl");
|
|
precache_sound ("weapons/r_exp3.wav");
|
|
precache_sound ("hipitems/spikmine.wav");
|
|
precache_sound ("misc/null.wav");
|
|
setmodel (self, "progs/spikmine.mdl");
|
|
// setmodel (self, "progs/spike.mdl");
|
|
setsize (self, self.mins, self.maxs);
|
|
self.classname = "trap_spike_mine";
|
|
self.solid = solid_bbox;
|
|
self.movetype = movetype_flymissile;
|
|
// setsize (self, '0 0 0', '0 0 0');
|
|
// self.avelocity = '-100 100 -100';
|
|
self.avelocity = '-50 100 150';
|
|
if (cvar("skill") <= 1)
|
|
self.health = 200;
|
|
else
|
|
self.health = 400;
|
|
self.frame = 0;
|
|
self.think = spike_mine_first_think;
|
|
self.touch = spikemine_touch;
|
|
self.th_die = spikemine_touch;
|
|
self.th_stand = spikemine_home;
|
|
self.th_walk = spikemine_home;
|
|
self.th_run = spikemine_home;
|
|
self.th_melee = spikemine_home;
|
|
self.th_missile = spikemine_home;
|
|
self.nextthink = time + 0.2;
|
|
total_monsters = total_monsters + 1;
|
|
self.flags = self.flags | fl_monster;
|
|
self.deathtype = "was blasted by a spike mine";
|
|
};
|
|
|
|
//============================================================================
|
|
float lightning_random = 1;
|
|
float lightning_boom = 2;
|
|
|
|
void() spawnlightningthink =
|
|
{
|
|
if (time > self.delay)
|
|
{
|
|
remove(self);
|
|
return;
|
|
}
|
|
self.think = spawnlightningthink;
|
|
if (checkclient())
|
|
{
|
|
writebyte (msg_broadcast, svc_tempentity);
|
|
writebyte (msg_broadcast, te_lightning2);
|
|
writeentity (msg_broadcast, self);
|
|
writecoord (msg_broadcast, self.origin_x);
|
|
writecoord (msg_broadcast, self.origin_y);
|
|
writecoord (msg_broadcast, self.origin_z);
|
|
writecoord (msg_broadcast, self.oldorigin_x);
|
|
writecoord (msg_broadcast, self.oldorigin_y);
|
|
writecoord (msg_broadcast, self.oldorigin_z);
|
|
}
|
|
lightningdamage(self.origin, self.oldorigin, self.lastvictim, self.dmg);
|
|
self.nextthink = time + 0.1;
|
|
};
|
|
|
|
void() trap_lightning_use =
|
|
{
|
|
local vector p1, p2;
|
|
local vector dir;
|
|
local float dst;
|
|
local float remainder;
|
|
|
|
if (time >= self.pausetime)
|
|
{
|
|
if (self.spawnflags & lightning_boom)
|
|
sound (self, chan_auto, "weapons/lstart.wav", 1, attn_norm);
|
|
else
|
|
sound (self, chan_auto, "weapons/lhit.wav", 1, attn_norm);
|
|
if (self.classname == "trap_lightning_triggered")
|
|
self.pausetime = time + 0.1;
|
|
}
|
|
if (self.target)
|
|
{
|
|
p1 = self.origin;
|
|
p2 = self.enemy.origin;
|
|
}
|
|
else
|
|
{
|
|
makevectors (self.angles);
|
|
self.movedir = v_forward;
|
|
traceline (self.origin, self.origin + self.movedir*600, true, self);
|
|
p1 = self.origin;
|
|
p2 = trace_endpos;
|
|
}
|
|
// fix up both ends of the lightning
|
|
// lightning bolts are 30 units long each
|
|
dir = normalize( p2-p1 );
|
|
dst = vlen(p2-p1);
|
|
dst = dst / 30.0;
|
|
remainder = dst - floor(dst);
|
|
if (remainder > 0)
|
|
{
|
|
remainder = remainder - 1;
|
|
// split half the remainder with the front and back
|
|
remainder = remainder * 15;
|
|
p1 = p1 + (remainder*dir);
|
|
p2 = p2 - (remainder*dir);
|
|
}
|
|
if (self.duration > 0.1)
|
|
{
|
|
local entity temp;
|
|
|
|
temp = self;
|
|
self = spawn();
|
|
self.origin = p1;
|
|
self.oldorigin = p2;
|
|
self.lastvictim = temp;
|
|
self.dmg = temp.dmg;
|
|
self.delay = time + temp.duration;
|
|
spawnlightningthink();
|
|
self = temp;
|
|
}
|
|
else if (checkclient())
|
|
{
|
|
writebyte (msg_broadcast, svc_tempentity);
|
|
writebyte (msg_broadcast, te_lightning2);
|
|
writeentity (msg_broadcast, self);
|
|
writecoord (msg_broadcast, p1_x);
|
|
writecoord (msg_broadcast, p1_y);
|
|
writecoord (msg_broadcast, p1_z);
|
|
writecoord (msg_broadcast, p2_x);
|
|
writecoord (msg_broadcast, p2_y);
|
|
writecoord (msg_broadcast, p2_z);
|
|
lightningdamage(p1, p2, self, self.dmg);
|
|
}
|
|
else
|
|
lightningdamage(p1, p2, self, self.dmg);
|
|
};
|
|
|
|
void() lightning_think =
|
|
{
|
|
local float timedelay;
|
|
|
|
if (self.state)
|
|
{
|
|
trap_lightning_use();
|
|
}
|
|
if (self.cnt == 0)
|
|
{
|
|
if (self.spawnflags & lightning_random)
|
|
{
|
|
timedelay = self.wait*random();
|
|
}
|
|
else
|
|
{
|
|
timedelay = self.wait;
|
|
}
|
|
self.cnt = 1;
|
|
self.t_length = time + self.duration - 0.1;
|
|
self.pausetime = time + self.duration - 0.1;
|
|
if (self.pausetime < time + 0.3)
|
|
self.pausetime = time + 0.3;
|
|
if (timedelay < self.duration)
|
|
timedelay = self.duration;
|
|
self.t_width = time + timedelay;
|
|
}
|
|
if (time >= self.t_length)
|
|
{
|
|
self.cnt = 0;
|
|
self.nextthink = self.t_width;
|
|
}
|
|
else
|
|
{
|
|
self.nextthink = time + 0.2;
|
|
}
|
|
};
|
|
|
|
void() lightning_firstthink =
|
|
{
|
|
local entity targ;
|
|
if (self.target)
|
|
{
|
|
targ = find(world,targetname,self.target);
|
|
self.dest = targ.origin;
|
|
self.enemy = targ;
|
|
}
|
|
self.think = sub_null;
|
|
self.nextthink = 0;
|
|
if (self.classname != "trap_lightning_triggered")
|
|
{
|
|
self.nextthink = self.huntingcharmer + self.wait + self.ltime;
|
|
self.think = lightning_think;
|
|
}
|
|
};
|
|
|
|
/*quaked trap_lightning_triggered (0 .5 .8) (-8 -8 -8) (8 8 8) random boom
|
|
when triggered, fires lightning in the direction set in quakeed.
|
|
"wait" how long to wait between blasts (1.0 default)
|
|
if in random mode wait is multiplied by random
|
|
"dmg" how much damage lightning should inflict (30 default)
|
|
"duration" how long each lightning attack should last (0.1 default)
|
|
*/
|
|
|
|
void() trap_lightning_triggered =
|
|
{
|
|
if (self.wait == 0)
|
|
self.wait = 1.0;
|
|
if (self.dmg == 0)
|
|
self.dmg = 30;
|
|
if (self.duration == 0)
|
|
self.duration = 0.1;
|
|
self.cnt = 0;
|
|
self.use = trap_lightning_use;
|
|
precache_sound ("weapons/lhit.wav");
|
|
precache_sound ("weapons/lstart.wav");
|
|
self.huntingcharmer = self.nextthink;
|
|
self.think = lightning_firstthink;
|
|
self.nextthink = time + 0.25;
|
|
self.deathtype = "is electrocuted";
|
|
};
|
|
|
|
|
|
/*quaked trap_lightning (0 .5 .8) (-8 -8 -8) (8 8 8) random boom
|
|
continuously fire lightning.
|
|
"wait" how long to wait between blasts (1.0 default)
|
|
if in random mode wait is multiplied by random
|
|
"nextthink" delay before firing first lightning, so multiple traps can be stagered.
|
|
"dmg" how much damage lightning should inflict (30 default)
|
|
"duration" how long each lightning attack should last (0.1 default)
|
|
*/
|
|
void() trap_lightning =
|
|
{
|
|
trap_lightning_triggered ();
|
|
self.state = 1;
|
|
};
|
|
|
|
void() trap_lightning_switched_use =
|
|
{
|
|
self.state = 1 - self.state;
|
|
if (self.state == 1)
|
|
self.nextthink = self.huntingcharmer;
|
|
};
|
|
/*quaked trap_lightning_switched (0 .5 .8) (-8 -8 -8) (8 8 8) random boom
|
|
continuously fires lightning.
|
|
"wait" how long to wait between blasts (1.0 default)
|
|
if in random mode wait is multiplied by random
|
|
"nextthink" delay before firing first lightning, so multiple traps can be stagered.
|
|
"dmg" how much damage lightning should inflict (30 default)
|
|
"duration" how long each lightning attack should last (0.1 default)
|
|
"state" 0 (default) initially off, 1 initially on.
|
|
*/
|
|
void() trap_lightning_switched =
|
|
{
|
|
trap_lightning_triggered ();
|
|
self.use = trap_lightning_switched_use;
|
|
};
|
|
|
|
|
|
entity tesla_target;
|
|
float tesla_numtargets;
|
|
void() trap_tesla_scan =
|
|
{
|
|
local entity head;
|
|
local entity prev;
|
|
|
|
// look in our immediate vicinity
|
|
|
|
tesla_numtargets = 0;
|
|
head = findradius(self.origin, self.distance);
|
|
while(head)
|
|
{
|
|
if(!(head.flags & fl_notarget) && (head.flags & self.cnt))
|
|
{
|
|
if (visible(head) && (head.health > 0) && (head.struck_by_mjolnir==0))
|
|
{
|
|
if (tesla_numtargets == 0)
|
|
{
|
|
tesla_target = head;
|
|
}
|
|
else
|
|
{
|
|
prev.next_ent = head;
|
|
}
|
|
tesla_numtargets = tesla_numtargets + 1;
|
|
prev = head;
|
|
if (tesla_numtargets==self.count)
|
|
return;
|
|
}
|
|
}
|
|
head = head.chain;
|
|
}
|
|
};
|
|
|
|
void() teslalightningthink =
|
|
{
|
|
self.owner.attack_state = 2;
|
|
if (time > self.delay)
|
|
{
|
|
self.enemy.struck_by_mjolnir = 0;
|
|
remove(self);
|
|
return;
|
|
}
|
|
traceline (self.origin, self.enemy.origin, true, self);
|
|
|
|
if (trace_fraction != 1.0 || self.enemy.health<=0 || vlen(self.origin-self.enemy.origin) > (self.distance+10))
|
|
{
|
|
self.enemy.struck_by_mjolnir = 0;
|
|
remove(self);
|
|
return;
|
|
}
|
|
writebyte (msg_broadcast, svc_tempentity);
|
|
writebyte (msg_broadcast, te_lightning2);
|
|
writeentity (msg_broadcast, self);
|
|
writecoord (msg_broadcast, self.origin_x);
|
|
writecoord (msg_broadcast, self.origin_y);
|
|
writecoord (msg_broadcast, self.origin_z);
|
|
writecoord (msg_broadcast, trace_endpos_x);
|
|
writecoord (msg_broadcast, trace_endpos_y);
|
|
writecoord (msg_broadcast, trace_endpos_z);
|
|
lightningdamage(self.origin, trace_endpos, self.lastvictim, self.dmg);
|
|
self.nextthink = time + 0.1;
|
|
};
|
|
|
|
void(entity targ) spawnteslalightning =
|
|
{
|
|
local entity lgt;
|
|
// spawn actual lightning
|
|
lgt = spawn();
|
|
if (self.duration>0)
|
|
{
|
|
lgt.delay = time + self.duration;
|
|
}
|
|
else
|
|
{
|
|
lgt.delay = time + 9999;
|
|
}
|
|
lgt.enemy = targ;
|
|
targ.struck_by_mjolnir = 1;
|
|
lgt.distance = self.distance;
|
|
lgt.owner = self;
|
|
lgt.lastvictim = self.lastvictim;
|
|
lgt.dmg = self.dmg;
|
|
lgt.origin = self.origin;
|
|
lgt.think = teslalightningthink;
|
|
lgt.nextthink = time;
|
|
lgt.deathtype = self.deathtype;
|
|
};
|
|
|
|
void() trap_tesla_think =
|
|
{
|
|
if (self.state == 0)
|
|
{
|
|
self.nextthink = time + 0.25;
|
|
return;
|
|
}
|
|
if (self.attack_state == 0)
|
|
{
|
|
self.think = trap_tesla_think;
|
|
trap_tesla_scan();
|
|
if (tesla_numtargets > 0)
|
|
{
|
|
if (self.wait > 0)
|
|
sound (self, chan_auto, "misc/tesla.wav", 1, attn_norm);
|
|
self.attack_state = 1;
|
|
self.nextthink = time + self.wait;
|
|
return;
|
|
}
|
|
self.nextthink = time + 0.25;
|
|
if (self.delay > 0)
|
|
{
|
|
if (time > self.search_time)
|
|
{
|
|
self.attack_state = 3;
|
|
}
|
|
}
|
|
}
|
|
else if (self.attack_state == 1)
|
|
{
|
|
trap_tesla_scan();
|
|
while (tesla_numtargets > 0)
|
|
{
|
|
sound (self, chan_auto, "hipweap/mjolhit.wav", 1, attn_norm);
|
|
spawnteslalightning (tesla_target);
|
|
tesla_target = tesla_target.next_ent;
|
|
tesla_numtargets = tesla_numtargets - 1;
|
|
}
|
|
self.attack_state = 2;
|
|
self.nextthink = time + 1;
|
|
}
|
|
else if (self.attack_state == 2)
|
|
{
|
|
self.attack_state = 3;
|
|
self.nextthink = time + 0.2;
|
|
}
|
|
else if (self.attack_state == 3)
|
|
{
|
|
self.attack_state = 0;
|
|
self.nextthink = time + 0.1;
|
|
if (self.classname == "trap_gods_wrath")
|
|
{
|
|
self.nextthink = -1;
|
|
}
|
|
}
|
|
};
|
|
|
|
/*quaked trap_tesla_coil (0 .5 .8) (-8 -8 -8) (8 8 8) targetenemies
|
|
targets enemies in vicinity and fires at them
|
|
"wait" how long build up should be (2 second default)
|
|
"dmg" how much damage lightning should inflict (2 + 5*skill default)
|
|
"duration" how long each lightning attack should last (continuous default)
|
|
"distance" how far the tesla coil should reach (600 default)
|
|
"state" on/off for the coil (0 default is off)
|
|
"count" number of people to target (2 default)
|
|
*/
|
|
void() trap_tesla_coil =
|
|
{
|
|
precache_sound ("misc/tesla.wav");
|
|
precache_sound ("hipweap/mjolhit.wav"); // lightning sound
|
|
if (self.wait == 0)
|
|
self.wait = 2;
|
|
if (self.dmg == 0)
|
|
self.dmg = 2 + (5*cvar("skill"));
|
|
if (self.duration == 0)
|
|
self.duration = -1;
|
|
if (self.distance == 0)
|
|
self.distance = 600;
|
|
if (self.spawnflags & 1)
|
|
self.cnt = fl_client | fl_monster;
|
|
else
|
|
self.cnt = fl_client;
|
|
self.use = trap_lightning_switched_use;
|
|
if (self.delay == 0)
|
|
self.delay = -1;
|
|
self.nextthink = time + random();
|
|
self.think = trap_tesla_think;
|
|
self.lastvictim = world;
|
|
tesla_numtargets = 0;
|
|
self.attack_state = 0;
|
|
self.deathtype = "is electrocuted";
|
|
};
|
|
|
|
void() trap_gods_wrath_use =
|
|
{
|
|
if (self.attack_state==0)
|
|
{
|
|
self.search_time = time + self.delay;
|
|
self.lastvictim = activator;
|
|
trap_tesla_think();
|
|
}
|
|
};
|
|
|
|
/*quaked trap_gods_wrath (0 .5 .8) (-8 -8 -8) (8 8 8) targetenemies
|
|
targets enemies in vicinity and fires at them
|
|
"dmg" how much damage lightning should inflict (5 default)
|
|
"duration" how long each lightning attack should last (continuous default)
|
|
"distance" how far god's wrath should reach (600 default)
|
|
"delay" how long to wait until god calms down
|
|
this is only needed if no one is targetted (5 seconds default)
|
|
"count" number of people to target (2 default)
|
|
*/
|
|
void() trap_gods_wrath =
|
|
{
|
|
if (self.delay == 0)
|
|
self.delay = 5;
|
|
trap_tesla_coil();
|
|
self.wait = 0;
|
|
self.state = 1;
|
|
self.nextthink = -1;
|
|
self.deathtype = "suffers the wrath of god";
|
|
// self.attack_state = 1;
|
|
self.use = trap_gods_wrath_use;
|
|
};
|
|
|
|
void() trap_gravity_touch =
|
|
{
|
|
if ( self.attack_finished > time )
|
|
return;
|
|
|
|
if (other.takedamage)
|
|
{
|
|
t_damage (other, self, self, self.dmg );
|
|
self.attack_finished = time + 0.2;
|
|
}
|
|
};
|
|
|
|
void() trap_gravity_think =
|
|
{
|
|
local vector vel;
|
|
local vector dir;
|
|
local vector delta;
|
|
|
|
self.ltime = time;
|
|
trap_tesla_scan();
|
|
while (tesla_numtargets > 0)
|
|
{
|
|
delta = self.origin - tesla_target.origin;
|
|
dir = normalize( delta );
|
|
vel = dir * self.speed;
|
|
if ( ( tesla_target.wetsuit_finished > time ) &&
|
|
( self.spawnflags & underwater ) )
|
|
{
|
|
vel = vel * 0.6;
|
|
}
|
|
|
|
tesla_target.velocity = tesla_target.velocity + vel;
|
|
tesla_target = tesla_target.next_ent;
|
|
tesla_numtargets = tesla_numtargets - 1;
|
|
}
|
|
self.nextthink = time + 0.1;
|
|
};
|
|
|
|
/*quaked trap_gravity_well (.8 .5 0) (-8 -8 -8) (8 8 8) targetenemies underwater
|
|
targets enemies in vicinity and draws them near, gibbing them on contact.
|
|
|
|
underwater cuts the pull in half for players wearing the wetsuit
|
|
|
|
"distance" how far the gravity well should reach (600 default)
|
|
"count" number of people to target (2 default)
|
|
"speed" is how strong the pull is. (210 default)
|
|
"dmg" is how much damage to do each touch. (10000 default)
|
|
*/
|
|
void() trap_gravity_well =
|
|
{
|
|
self.solid = solid_trigger;
|
|
self.movetype = movetype_none;
|
|
setsize( self, '-16 -16 -16','16 16 16');
|
|
if ( self.dmg == 0 )
|
|
{
|
|
self.dmg = 10000;
|
|
}
|
|
if ( self.speed == 0 )
|
|
self.speed = 210;
|
|
if (self.distance == 0)
|
|
self.distance = 600;
|
|
if (self.spawnflags & 1)
|
|
self.cnt = fl_client | fl_monster;
|
|
else
|
|
self.cnt = fl_client;
|
|
|
|
self.attack_finished = 0;
|
|
self.think = trap_gravity_think;
|
|
self.touch = trap_gravity_touch;
|
|
self.lastvictim = world;
|
|
tesla_numtargets = 0;
|
|
self.nextthink = time + 0.1;
|
|
self.ltime = time;
|
|
};
|