quake-hipnotic-sdk/progs/hipgrem.qc
1997-03-11 00:00:00 +00:00

1858 lines
55 KiB
C++

/*
==============================================================================
gremlin
==============================================================================
*/
$cd hipwork\models\grem
$origin 0 0 23
$scale 2
$base grembase.asc
$skin grem
$frame stand1.asc stand2.asc stand3.asc stand4.asc stand5.asc stand6.asc
$frame stand7.asc stand8.asc stand9.asc stand10.asc stand11.asc stand12.asc
$frame stand13.asc stand14.asc stand15.asc stand16.asc stand17.asc
$frame walk1.asc walk2.asc walk3.asc walk4.asc walk5.asc walk6.asc
$frame walk7.asc walk8.asc walk9.asc walk10.asc walk11.asc walk12.asc
$frame run1.asc run2.asc run3.asc run4.asc run5.asc run6.asc run7.asc run8.asc
$frame run9.asc run10.asc run11.asc run12.asc run13.asc run14.asc run15.asc
$frame jump1.asc jump2.asc jump3.asc jump4.asc jump5.asc jump6.asc jump7.asc
$frame jump8.asc jump9.asc jump10.asc jump11.asc jump12.asc jump13.asc jump14.asc
$frame jump15.asc jump16.asc
$frame attk1.asc attk2.asc attk3.asc attk4.asc attk5.asc attk6.asc
$frame attk7.asc attk8.asc attk9.asc attk10.asc attk11.asc
$frame maul1.asc maul2.asc maul3.asc maul4.asc maul5.asc maul6.asc
$frame maul7.asc maul8.asc maul9.asc maul10.asc maul11.asc maul12.asc maul13.asc
$frame spawn1.asc spawn2.asc spawn3.asc spawn4.asc spawn5.asc spawn6.asc
$frame look1.asc look2.asc look3.asc look4.asc look5.asc look6.asc look7.asc
$frame look8.asc look9.asc look10.asc
$frame pain1.asc pain2.asc pain3.asc pain4.asc
$frame death1.asc death2.asc death3.asc death4.asc death5.asc death6.asc death7.asc
$frame death8.asc death9.asc death10.asc death11.asc death12.asc
$frame flip1.asc flip2.asc flip3.asc flip4.asc flip5.asc flip6.asc flip7.asc
$frame flip8.asc
$frame lunge1.asc lunge2.asc lunge3.asc lunge4.asc lunge5.asc lunge6.asc lunge7.asc
$frame lunge8.asc lunge9.asc lunge10.asc lunge11.asc
$frame gfire1.asc gfire2.asc gfire3.asc gfire4.asc gfire5.asc gfire6.asc
$frame glook1.asc glook2.asc glook3.asc glook4.asc glook5.asc glook6.asc glook7.asc
$frame glook8.asc glook9.asc glook10.asc glook11.asc glook12.asc glook13.asc
$frame glook14.asc glook15.asc glook16.asc glook17.asc glook18.asc glook19.asc glook20.asc
$frame gpain1.asc gpain2.asc gpain3.asc
$frame grun1.asc grun2.asc grun3.asc grun4.asc grun5.asc grun6.asc grun7.asc
$frame grun8.asc grun9.asc grun10.asc grun11.asc grun12.asc grun13.asc grun14.asc grun15.asc
//============================================================================
float numgremlins;
float numspawngremlins;
/*
===========
gremlinattemptweaponsteal
see if we can steal enemy's weapon
============
*/
entity()gremlinfindvictim;
float() gremlinfindtarget;
float() gremlinattemptweaponsteal =
{
local vector delta;
local entity tempself;
local float best;
local entity victim;
local float amount;
if (self.stoleweapon)
{
dprint("gremlin trying to steal a weapon again\n");
return false;
}
if (!(self.enemy.flags & fl_client))
{
return false;
}
delta = (self.enemy.origin - self.origin);
if (vlen(delta) > 100)
return false;
if (random() < 0.5)
return false;
//
// we are within range so lets go for it
//
victim = self.enemy;
best = victim.weapon;
if (best == it_axe || best == it_shotgun || best == it_mjolnir)
return false;
// take that weapon from the entity
victim.items = victim.items - (victim.items & best);
// give it to our gremlin
self.items = self.items | best;
self.weapon = best;
// take some ammo while we are at it
self.items = self.items - ( self.items & (it_shells | it_nails | it_rockets | it_cells ) );
if (best == it_super_shotgun)
{
amount = victim.ammo_shells;
if (amount > 20)
amount = 20;
victim.ammo_shells = victim.ammo_shells - amount;
self.ammo_shells = self.ammo_shells + amount;
self.items = self.items | it_shells;
self.currentammo = self.ammo_shells;
sprint (victim, "gremlin stole your super shotgun\n");
}
else if (best == it_nailgun)
{
amount = victim.ammo_nails;
if (amount > 40)
amount = 40;
victim.ammo_nails = victim.ammo_nails - amount;
self.ammo_nails = self.ammo_nails + amount;
self.items = self.items | it_nails;
self.currentammo = self.ammo_nails;
sprint (victim, "gremlin stole your nailgun\n");
}
else if (best == it_super_nailgun)
{
amount = victim.ammo_nails;
if (amount > 40)
amount = 40;
victim.ammo_nails = victim.ammo_nails - amount;
self.ammo_nails = self.ammo_nails + amount;
self.items = self.items | it_nails;
self.currentammo = self.ammo_nails;
sprint (victim, "gremlin stole your super nailgun\n");
}
else if (best == it_grenade_launcher)
{
amount = victim.ammo_rockets;
if (amount > 5)
amount = 5;
victim.ammo_rockets = victim.ammo_rockets - amount;
self.ammo_rockets = self.ammo_rockets + amount;
self.items = self.items | it_rockets;
self.currentammo = self.ammo_rockets;
sprint (victim, "gremlin stole your grenade launcher\n");
}
else if (best == it_rocket_launcher)
{
amount = victim.ammo_rockets;
if (amount > 5)
amount = 5;
victim.ammo_rockets = victim.ammo_rockets - amount;
self.ammo_rockets = self.ammo_rockets + amount;
self.items = self.items | it_rockets;
self.currentammo = self.ammo_rockets;
sprint (victim, "gremlin stole your rocket launcher\n");
}
else if (best == it_lightning)
{
amount = victim.ammo_cells;
if (amount > 40)
amount = 40;
victim.ammo_cells = victim.ammo_cells - amount;
self.ammo_cells = self.ammo_cells + amount;
self.items = self.items | it_cells;
self.currentammo = self.ammo_cells;
sprint (victim, "gremlin stole your lightning gun\n");
}
else if (best == it_laser_cannon)
{
amount = victim.ammo_cells;
if (amount > 40)
amount = 40;
victim.ammo_cells = victim.ammo_cells - amount;
self.ammo_cells = self.ammo_cells + amount;
self.items = self.items | it_cells;
self.currentammo = self.ammo_cells;
sprint (victim, "gremlin stole your laser cannon\n");
}
else if (best == it_proximity_gun)
{
amount = victim.ammo_rockets;
if (amount > 5)
amount = 5;
victim.ammo_rockets = victim.ammo_rockets - amount;
self.ammo_rockets = self.ammo_rockets + amount;
self.items = self.items | it_rockets;
self.currentammo = self.ammo_rockets;
sprint (victim, "gremlin stole your proximity gun\n");
}
tempself = self;
self = victim;
self.weapon = w_bestweapon ();
w_setcurrentammo ();
self = tempself;
// tag the gremlin as having stolen a weapon
self.stoleweapon = true;
self.attack_finished = time;
// don't fire the first shot at the person we stole the weapon from
// all the time
if (random()>0.65)
self.lastvictim = victim;
else
self.lastvictim = self;
// self.attack_state = as_straight;
// find a recipient
victim = gremlinfindvictim();
if (victim != world)
{
self.enemy = victim;
foundtarget();
self.attack_finished = time;
self.search_time = time + 1.0;
}
return true;
};
//============================================================================
/*
===========
gremlinfindtarget
gremlin is currently not attacking anything, so try to find a target
============
*/
float() gremlinfindtarget =
{
local entity head;
local entity gorge;
local float dist;
local float result;
if ((self.stoleweapon==0) && time > self.wait)
{
self.wait = time + 1.0;
dist = 2000;
gorge = world;
head = nextent(world);
while (head!=world)
{
if ((head.health < 1) && (head.flags & (fl_monster|fl_client)))
{
result = fabs(head.origin_z - self.origin_z);
if ((visible(head)) && (result<80) && (head.gorging == false) && (visible_distance<dist))
{
dist = visible_distance;
gorge = head;
}
}
head = nextent(head);
}
if ((gorge != world) && (dist < (700*random())))
{
// dprint("starting to gorge on ");
// dprint(gorge.classname);
// dprint("\n");
self.oldenemy = self.enemy;
self.gorging = true;
self.enemy = gorge;
self.search_time = time + 4.0;
foundtarget();
return true;
}
}
else if (self.stoleweapon)
{
head = gremlinfindvictim();
if (head != world)
{
self.enemy = head;
foundtarget();
self.attack_finished = time;
self.search_time = time + 2.0;
return true;
}
}
result = findtarget();
self.search_time = time + 2.0;
return result;
};
//============================================================================
/*
=============
gremlin_walk
the monster is walking it's beat
=============
*/
void(float dist) gremlin_walk =
{
movedist = dist;
// check for noticing a player
if (gremlinfindtarget ())
return;
movetogoal (dist);
};
//============================================================================
/*
=============
gremlin_stand
the monster is staying in one place for a while, with slight angle turns
=============
*/
void() gremlin_stand =
{
if (findtarget ())
return;
if (time > self.pausetime)
{
self.th_walk ();
return;
}
};
//============================================================================
float() gremlinchecknoammo;
void() gremlin_glook1;
/*
=============
gremlin_run
the monster has an enemy it is trying to kill
=============
*/
void(float dist) gremlin_run =
{
local entity oldtarget;
local float r;
local vector d;
if (self.watertype == content_lava)
{ // do damage
t_damage (self, world, world, 2000);
}
movedist = dist;
if (self.stoleweapon)
self.frame = self.frame + $grun1.asc - $run1.asc;
if (self.gorging)
{
traceline(self.origin, self.enemy.origin, true, self);
if (trace_fraction != 1.0)
{
self.gorging = false;
return;
}
if (!visible(self.enemy))
{
self.gorging = false;
return;
}
r = vlen(self.enemy.origin - self.origin);
if (r < 130)
{
ai_face();
if (r < 45)
{
self.th_melee ();
self.attack_state = as_straight;
return;
}
else if (walkmove (self.angles_y, dist) == false)
{
self.gorging = false;
return;
}
return;
}
movetogoal (dist); // done in c code...
}
else
{
if (random()>0.97)
{
if (gremlinfindtarget())
return;
}
// get away from player if we stole a weapon
if (self.stoleweapon)
{
if (self.enemy.health < 0 && self.enemy.classname == "player")
{
gremlin_glook1();
return;
}
if (!gremlinchecknoammo())
{
if (self.t_length==1)
{
remove(self.trigger_field);
self.goalentity = self.enemy;
self.t_length = 0;
}
return;
}
r = vlen(self.enemy.origin - self.origin);
d = normalize(self.origin-self.enemy.origin);
if (self.t_length == 0)
{
if (r<150)
{
self.trigger_field = spawn();
setsize(self.trigger_field,'-1 -1 -1','1 1 1');
self.t_length = 1;
}
}
if (self.t_length==1)
{
if (r > 250)
{
remove(self.trigger_field);
self.goalentity = self.enemy;
self.t_length = 0;
// self.attack_state = as_sliding;
}
else
{
if (r < 160)
{
local vector ang;
local float done;
local vector end;
local float c;
ang = vectoangles(d);
done = 0;
c = 0;
while (done == 0)
{
makevectors(ang);
end = self.enemy.origin + v_forward * 350;
traceline(self.enemy.origin,end,false,self);
if (trace_fraction == 1.0)
{
traceline(self.origin,end,false,self);
if (trace_fraction == 1.0)
done = 1;
}
ang_y = anglemod(ang_y + 36);
c = c + 1;
if (c == 10)
{
done = 1;
}
}
setorigin(self.trigger_field,end);
}
self.goalentity = self.trigger_field;
self.ideal_yaw = vectoyaw(normalize(self.goalentity.origin-self.origin));
changeyaw ();
movetogoal (dist); // done in c code...
self.nextthink = time + 0.1;
return;
}
}
}
ai_run(dist);
self.nextthink = time + 0.1;
}
};
//============================================================================
void() gremlin_jumptouch;
void() gremlin_fliptouch;
void(float side) gremlin_melee;
void(float side) gremlin_gorge;
void() gremlin_stand1 =[ $stand1.asc, gremlin_stand2 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand2 =[ $stand2.asc, gremlin_stand3 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand3 =[ $stand3.asc, gremlin_stand4 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand4 =[ $stand4.asc, gremlin_stand5 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand5 =[ $stand5.asc, gremlin_stand6 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand6 =[ $stand6.asc, gremlin_stand7 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand7 =[ $stand7.asc, gremlin_stand8 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand8 =[ $stand8.asc, gremlin_stand9 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand9 =[ $stand9.asc, gremlin_stand10 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand10 =[ $stand10.asc, gremlin_stand11 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand11 =[ $stand11.asc, gremlin_stand12 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand12 =[ $stand12.asc, gremlin_stand13 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand13 =[ $stand13.asc, gremlin_stand14 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand14 =[ $stand14.asc, gremlin_stand15 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand15 =[ $stand15.asc, gremlin_stand16 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand16 =[ $stand16.asc, gremlin_stand17 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_stand17 =[ $stand17.asc, gremlin_stand1 ] {gremlin_stand();self.nextthink = time + 0.2;};
void() gremlin_walk1 =[ $walk1.asc, gremlin_walk2 ] {
if (random() < 0.1)
sound (self, chan_voice, "grem/idle.wav", 1, attn_idle);
gremlin_walk(8);};
void() gremlin_walk2 =[ $walk2.asc, gremlin_walk3 ] {gremlin_walk(8);};
void() gremlin_walk3 =[ $walk3.asc, gremlin_walk4 ] {gremlin_walk(8);};
void() gremlin_walk4 =[ $walk4.asc, gremlin_walk5 ] {gremlin_walk(8);};
void() gremlin_walk5 =[ $walk5.asc, gremlin_walk6 ] {gremlin_walk(8);};
void() gremlin_walk6 =[ $walk6.asc, gremlin_walk7 ] {gremlin_walk(8);};
void() gremlin_walk7 =[ $walk7.asc, gremlin_walk8 ] {gremlin_walk(8);};
void() gremlin_walk8 =[ $walk8.asc, gremlin_walk9 ] {gremlin_walk(8);};
void() gremlin_walk9 =[ $walk9.asc, gremlin_walk10 ] {gremlin_walk(8);};
void() gremlin_walk10 =[ $walk10.asc, gremlin_walk11 ] {gremlin_walk(8);};
void() gremlin_walk11 =[ $walk11.asc, gremlin_walk12 ] {gremlin_walk(8);};
void() gremlin_walk12 =[ $walk12.asc, gremlin_walk1 ] {gremlin_walk(8);};
void() gremlin_run1 =[ $run1.asc, gremlin_run2 ] {
if (random() < 0.1)
sound (self, chan_voice, "grem/idle.wav", 1, attn_idle);
gremlin_run(0);};
void() gremlin_run2 =[ $run2.asc, gremlin_run3 ] {gremlin_run(8);};
void() gremlin_run3 =[ $run3.asc, gremlin_run4 ] {gremlin_run(12);};
void() gremlin_run4 =[ $run4.asc, gremlin_run5 ] {gremlin_run(16);};
void() gremlin_run5 =[ $run5.asc, gremlin_run6 ] {gremlin_run(16);};
void() gremlin_run6 =[ $run6.asc, gremlin_run7 ] {gremlin_run(12);};
void() gremlin_run7 =[ $run7.asc, gremlin_run8 ] {gremlin_run(8);};
void() gremlin_run8 =[ $run8.asc, gremlin_run9 ] {gremlin_run(0);};
void() gremlin_run9 =[ $run9.asc, gremlin_run10 ] {gremlin_run(8);};
void() gremlin_run10 =[ $run10.asc, gremlin_run11 ] {gremlin_run(12);};
void() gremlin_run11 =[ $run11.asc, gremlin_run12 ] {gremlin_run(16);};
void() gremlin_run12 =[ $run12.asc, gremlin_run1 ] {gremlin_run(16);};
void() gremlin_run13 =[ $run13.asc, gremlin_run14 ] {gremlin_run(12);};
void() gremlin_run14 =[ $run14.asc, gremlin_run15 ] {gremlin_run(8);};
void() gremlin_run15 =[ $run15.asc, gremlin_run1 ] {gremlin_run(0);};
void() gremlin_jump1 =[ $jump1.asc, gremlin_jump2 ] {ai_face();};
void() gremlin_jump2 =[ $jump2.asc, gremlin_jump3 ] {ai_face();};
void() gremlin_jump3 =[ $jump3.asc, gremlin_jump4 ] {ai_face();};
void() gremlin_jump4 =[ $jump4.asc, gremlin_jump5 ] {ai_face();};
void() gremlin_jump5 =[ $jump5.asc, gremlin_jump6 ]
{
ai_face();
if (self.flags & fl_onground)
{
self.touch = gremlin_jumptouch;
makevectors (self.angles);
self.origin_z = self.origin_z + 1;
self.velocity = v_forward * 300 + '0 0 300';
self.flags = self.flags - fl_onground;
}
else
{
gremlin_run1();
}
};
void() gremlin_jump6 =[ $jump6.asc, gremlin_jump7 ] {};
void() gremlin_jump7 =[ $jump7.asc, gremlin_jump8 ] {};
void() gremlin_jump8 =[ $jump8.asc, gremlin_jump9 ] {};
void() gremlin_jump9 =[ $jump9.asc, gremlin_jump10 ] {};
void() gremlin_jump10 =[ $jump10.asc, gremlin_jump11 ] {};
void() gremlin_jump11 =[ $jump11.asc, gremlin_jump1 ]
{
self.nextthink = time + 3;
// if three seconds pass, assume gremlin is stuck and jump again
};
void() gremlin_jump12 =[ $jump12.asc, gremlin_jump13 ] {};
void() gremlin_jump13 =[ $jump13.asc, gremlin_jump14 ] {};
void() gremlin_jump14 =[ $jump14.asc, gremlin_jump15 ] {};
void() gremlin_jump15 =[ $jump15.asc, gremlin_jump16 ] {};
void() gremlin_jump16 =[ $jump16.asc, gremlin_run1 ] {};
void() gremlin_shot1 = [$gfire1.asc, gremlin_shot2 ] {self.effects = self.effects | ef_muzzleflash;};
void() gremlin_shot2 = [$gfire2.asc, gremlin_shot3 ] {};
void() gremlin_shot3 = [$gfire3.asc, gremlin_shot4 ] {};
void() gremlin_shot4 = [$gfire4.asc, gremlin_shot5 ] {};
void() gremlin_shot5 = [$gfire5.asc, gremlin_shot6 ] {};
void() gremlin_shot6 = [$gfire6.asc, gremlin_run1 ] {};
//============================================================================
void(float ox) gremlin_firenailgun;
void() gremlin_nail1 =[$gfire1.asc, gremlin_nail2 ]
{
self.effects = self.effects | ef_muzzleflash;
gremlin_firenailgun(4);
};
void() gremlin_nail2 =[$gfire1.asc, gremlin_nail3 ]
{
self.effects = self.effects | ef_muzzleflash;
gremlin_firenailgun(4);
};
void() gremlin_nail3 =[$gfire1.asc, gremlin_nail4 ]
{
self.effects = self.effects | ef_muzzleflash;
gremlin_firenailgun(4);
};
void() gremlin_nail4 =[$gfire1.asc, gremlin_nail5 ]
{
self.effects = self.effects | ef_muzzleflash;
gremlin_firenailgun(4);
};
void() gremlin_nail5 =[$gfire1.asc, gremlin_nail6 ]
{
self.effects = self.effects | ef_muzzleflash;
gremlin_firenailgun(4);
};
void() gremlin_nail6 =[$gfire1.asc, gremlin_nail7 ]
{
self.effects = self.effects | ef_muzzleflash;
gremlin_firenailgun(4);
};
void() gremlin_nail7 = [$gfire1.asc, gremlin_run1 ] {};
void(float ox) gremlin_firelasergun;
void() gremlin_laser1 =[$gfire1.asc, gremlin_laser2 ]
{
self.effects = self.effects | ef_muzzleflash;
gremlin_firelasergun(4);
};
void() gremlin_laser2 =[$gfire1.asc, gremlin_laser3 ]
{
self.effects = self.effects | ef_muzzleflash;
gremlin_firelasergun(4);
};
void() gremlin_laser3 =[$gfire1.asc, gremlin_laser4 ]
{
self.effects = self.effects | ef_muzzleflash;
gremlin_firelasergun(4);
};
void() gremlin_laser4 =[$gfire1.asc, gremlin_laser5 ]
{
self.effects = self.effects | ef_muzzleflash;
gremlin_firelasergun(4);
};
void() gremlin_laser5 =[$gfire1.asc, gremlin_laser6 ]
{
self.effects = self.effects | ef_muzzleflash;
gremlin_firelasergun(4);
};
void() gremlin_laser6 =[$gfire1.asc, gremlin_laser7 ]
{
self.effects = self.effects | ef_muzzleflash;
gremlin_firelasergun(4);
};
void() gremlin_laser7 = [$gfire1.asc, gremlin_run1 ] {};
//============================================================================
void() gremlin_firelightninggun;
void() gremlin_light1 =[$gfire1.asc, gremlin_light2 ]
{
gremlin_firelightninggun();
};
void() gremlin_light2 = [$gfire1.asc, gremlin_light3 ]
{
gremlin_firelightninggun();
};
void() gremlin_light3 =[$gfire1.asc, gremlin_light4 ]
{
gremlin_firelightninggun();
};
void() gremlin_light4 = [$gfire1.asc, gremlin_light5 ]
{
gremlin_firelightninggun();
};
void() gremlin_light5 = [$gfire1.asc, gremlin_run1 ] {};
//============================================================================
void() gremlin_rocket1 = [$gfire1.asc, gremlin_rocket2 ] {self.effects = self.effects | ef_muzzleflash;};
void() gremlin_rocket2 = [$gfire2.asc, gremlin_rocket3 ] {};
void() gremlin_rocket3 = [$gfire3.asc, gremlin_rocket4 ] {};
void() gremlin_rocket4 = [$gfire4.asc, gremlin_rocket5 ] {};
void() gremlin_rocket5 = [$gfire5.asc, gremlin_rocket6 ] {};
void() gremlin_rocket6 = [$gfire6.asc, gremlin_run1 ] {};
void() gremlin_lunge1 =[ $lunge1.asc, gremlin_lunge2 ] {ai_charge(0);};
void() gremlin_lunge2 =[ $lunge2.asc, gremlin_lunge3 ] {ai_charge(0);};
void() gremlin_lunge3 =[ $lunge3.asc, gremlin_lunge4 ] {ai_charge(0);};
void() gremlin_lunge4 =[ $lunge4.asc, gremlin_lunge5 ] {ai_charge(0);};
void() gremlin_lunge5 =[ $lunge5.asc, gremlin_lunge6 ] {ai_charge(0);};
void() gremlin_lunge6 =[ $lunge6.asc, gremlin_lunge7 ] {ai_charge(0);};
void() gremlin_lunge7 =[ $lunge7.asc, gremlin_lunge8 ] {ai_charge(15);};
void() gremlin_lunge8 =[ $lunge8.asc, gremlin_lunge9 ] {ai_charge(0);gremlin_melee(0);};
void() gremlin_lunge9 =[ $lunge9.asc, gremlin_lunge10] {ai_charge(0);};
void() gremlin_lunge10 =[ $lunge10.asc, gremlin_lunge11] {ai_charge(0);};
void() gremlin_lunge11 =[ $lunge11.asc, gremlin_run1] {ai_charge(0);};
void() gremlin_claw1 =[ $attk1.asc, gremlin_claw2 ] {ai_charge(0);};
void() gremlin_claw2 =[ $attk2.asc, gremlin_claw3 ] {ai_charge(0);};
void() gremlin_claw3 =[ $attk3.asc, gremlin_claw4 ] {ai_charge(0);};
void() gremlin_claw4 =[ $attk4.asc, gremlin_claw5 ] {ai_charge(0);};
void() gremlin_claw5 =[ $attk5.asc, gremlin_claw6 ] {ai_charge(0);};
void() gremlin_claw6 =[ $attk6.asc, gremlin_claw7 ] {ai_charge(0);gremlin_melee(200);};
void() gremlin_claw7 =[ $attk7.asc, gremlin_claw8 ] {ai_charge(15);};
void() gremlin_claw8 =[ $attk8.asc, gremlin_claw9 ] {ai_charge(0);};
void() gremlin_claw9 =[ $attk9.asc, gremlin_claw10] {ai_charge(0);};
void() gremlin_claw10 =[ $attk10.asc, gremlin_claw11] {ai_charge(0);};
void() gremlin_claw11 =[ $attk11.asc, gremlin_run1] {ai_charge(0);};
void() gremlin_gorge1 =[ $maul1.asc, gremlin_gorge2] {ai_charge(1);};
void() gremlin_gorge2 =[ $maul2.asc, gremlin_gorge3] {ai_charge(1);};
void() gremlin_gorge3 =[ $maul3.asc, gremlin_gorge4] {ai_charge(2);};
void() gremlin_gorge4 =[ $maul4.asc, gremlin_gorge5] {ai_charge(0);};
void() gremlin_gorge5 =[ $maul5.asc, gremlin_gorge6] {ai_charge(0);};
void() gremlin_gorge6 =[ $maul6.asc, gremlin_gorge7] {ai_charge(0);gremlin_gorge(200);};
void() gremlin_gorge7 =[ $maul7.asc, gremlin_gorge8] {ai_charge(0);};
void() gremlin_gorge8 =[ $maul8.asc, gremlin_gorge9] {ai_charge(0);gremlin_gorge(-200);};
void() gremlin_gorge9 =[ $maul9.asc, gremlin_gorge10] {ai_charge(0);};
void() gremlin_gorge10 =[ $maul10.asc, gremlin_gorge11] {ai_charge(0);};
void() gremlin_gorge11 =[ $maul11.asc, gremlin_gorge12] {ai_charge(0);};
void() gremlin_gorge12 =[ $maul12.asc, gremlin_gorge13] {ai_charge(0);};
void() gremlin_gorge13 =[ $maul13.asc, gremlin_gorge1] {ai_charge(0);};
void() gremlin_look1 =[ $look1.asc, gremlin_look2] {self.nextthink = time + 0.2;};
void() gremlin_look2 =[ $look2.asc, gremlin_look3] {self.nextthink = time + 0.2;};
void() gremlin_look3 =[ $look3.asc, gremlin_look4] {self.nextthink = time + 0.2;};
void() gremlin_look4 =[ $look4.asc, gremlin_look5] {self.nextthink = time + 0.2;};
void() gremlin_look5 =[ $look5.asc, gremlin_look6] {self.nextthink = time + 0.2;};
void() gremlin_look6 =[ $look6.asc, gremlin_look7] {self.nextthink = time + 0.2;};
void() gremlin_look7 =[ $look7.asc, gremlin_look8] {self.nextthink = time + 0.2;};
void() gremlin_look8 =[ $look8.asc, gremlin_look9] {self.nextthink = time + 0.2;};
void() gremlin_look9 =[ $look9.asc, gremlin_run1]
{
if (self.oldenemy.health > 0)
{
self.enemy = self.oldenemy;
hunttarget ();
}
else
{
if (self.movetarget)
self.th_walk ();
else
self.th_stand ();
}
};
void() gremlindropbackpack;
void() gremlin_glook1 =[ $glook1.asc, gremlin_glook2] {};
void() gremlin_glook2 =[ $glook2.asc, gremlin_glook3] {};
void() gremlin_glook3 =[ $glook3.asc, gremlin_glook4] {};
void() gremlin_glook4 =[ $glook4.asc, gremlin_glook5] {};
void() gremlin_glook5 =[ $glook5.asc, gremlin_glook6] {};
void() gremlin_glook6 =[ $glook6.asc, gremlin_glook7] {};
void() gremlin_glook7 =[ $glook7.asc, gremlin_glook8] {};
void() gremlin_glook8 =[ $glook8.asc, gremlin_glook9] {};
void() gremlin_glook9 =[ $glook9.asc, gremlin_glook10] {};
void() gremlin_glook10 =[ $glook10.asc, gremlin_glook11] {};
void() gremlin_glook11 =[ $glook11.asc, gremlin_glook12] {};
void() gremlin_glook12 =[ $glook12.asc, gremlin_glook13] {};
void() gremlin_glook13 =[ $glook13.asc, gremlin_glook14] {};
void() gremlin_glook14 =[ $glook14.asc, gremlin_glook15] {};
void() gremlin_glook15 =[ $glook15.asc, gremlin_glook16] {};
void() gremlin_glook16 =[ $glook16.asc, gremlin_glook17] {};
void() gremlin_glook17 =[ $glook17.asc, gremlin_glook18] {};
void() gremlin_glook18 =[ $glook18.asc, gremlin_glook19] {};
void() gremlin_glook19 =[ $glook19.asc, gremlin_glook20] {};
void() gremlin_glook20 =[ $glook20.asc, gremlin_glook20]
{
gremlindropbackpack();
self.stoleweapon = false;
if (self.oldenemy.health > 0)
{
self.enemy = self.oldenemy;
hunttarget ();
}
else
{
if (self.movetarget)
self.th_walk ();
else
self.th_stand ();
}
};
void() gremlin_pain1 =[ $pain1.asc, gremlin_pain2 ] {ai_back(4);};
void() gremlin_pain2 =[ $pain2.asc, gremlin_pain3 ] {ai_back(4);};
void() gremlin_pain3 =[ $pain3.asc, gremlin_pain4 ] {ai_back(2);};
void() gremlin_pain4 =[ $pain4.asc, gremlin_run1 ] {};
void() gremlin_gunpain1 =[ $gpain1.asc, gremlin_gunpain2 ] {ai_back(4);};
void() gremlin_gunpain2 =[ $gpain2.asc, gremlin_gunpain3 ] {ai_back(2);};
void() gremlin_gunpain3 =[ $gpain3.asc, gremlin_run1 ] {};
void(entity attacker, float damage) gremlin_pain =
{
local float r;
if (random()<0.8)
{
self.gorging = false;
self.enemy = attacker;
foundtarget();
}
if (self.touch == gremlin_jumptouch)
return;
if (self.pain_finished > time)
return;
self.pain_finished = time + 1;
// if (random()<0.5)
// sound (self, chan_voice, "grem/pain2.wav", 1, attn_norm);
// else
r = random();
if (r<0.33)
sound (self, chan_voice, "grem/pain1.wav", 1, attn_norm);
else if (r<0.66)
sound (self, chan_voice, "grem/pain2.wav", 1, attn_norm);
else
sound (self, chan_voice, "grem/pain3.wav", 1, attn_norm);
if (self.stoleweapon)
{
gremlin_gunpain1 ();
}
else
{
gremlin_pain1 ();
}
};
void() gremlin_spawn1 =[ $spawn1.asc, gremlin_spawn2 ] {self.nextthink = time + 0.3;
self.th_pain = sub_null;
// sound (self, chan_voice, "grem/idle.wav", 1, attn_idle);
};
void() gremlin_spawn2 =[ $spawn2.asc, gremlin_spawn3 ] {self.nextthink = time + 0.3;};
void() gremlin_spawn3 =[ $spawn3.asc, gremlin_spawn4 ] {self.nextthink = time + 0.3;};
void() gremlin_spawn4 =[ $spawn4.asc, gremlin_spawn5 ] {self.nextthink = time + 0.3;};
void() gremlin_spawn5 =[ $spawn5.asc, gremlin_spawn6 ] {self.nextthink = time + 0.3;};
void() gremlin_spawn6 =[ $spawn6.asc, gremlin_run1 ] {
self.th_pain = gremlin_pain;
};
void() gremlin_die1 =[ $death1.asc, gremlin_die2 ] {
sound (self, chan_voice, "grem/death.wav", 1, attn_norm);};
void() gremlin_die2 =[ $death2.asc, gremlin_die3 ] {ai_forward(2);};
void() gremlin_die3 =[ $death3.asc, gremlin_die4 ] {ai_forward(1);};
void() gremlin_die4 =[ $death4.asc, gremlin_die5 ] {ai_forward(2);};
void() gremlin_die5 =[ $death5.asc, gremlin_die6 ] {ai_forward(1);};
void() gremlin_die6 =[ $death6.asc, gremlin_die7 ]
{self.solid = solid_not;};
void() gremlin_die7 =[ $death7.asc, gremlin_die8 ] {ai_forward(2);};
void() gremlin_die8 =[ $death8.asc, gremlin_die9 ] {ai_forward(1);};
void() gremlin_die9 =[ $death9.asc, gremlin_die10 ] {ai_forward(2);};
void() gremlin_die10 =[ $death10.asc, gremlin_die11 ] {ai_forward(1);};
void() gremlin_die11 =[ $death11.asc, gremlin_die12 ] {ai_forward(2);};
void() gremlin_die12 =[ $death12.asc, gremlin_die12 ] {};
void() gremlin_gib=
{
sound (self, chan_voice, "player/udeath.wav", 1, attn_norm);
throwhead ("progs/h_grem.mdl", -35);
throwgib ("progs/gib1.mdl", -35);
throwgib ("progs/gib1.mdl", -35);
throwgib ("progs/gib1.mdl", -35);
};
void() gremlin_flip1 =[ $flip1.asc, gremlin_flip2 ]
{
ai_face();
makevectors (self.angles);
self.origin_z = self.origin_z + 1;
self.velocity = '0 0 350' - (v_forward * 200);
if (self.flags & fl_onground)
self.flags = self.flags - fl_onground;
sound (self, chan_voice, "grem/death.wav", 1, attn_norm);
};
void() gremlin_flip2 =[ $flip2.asc, gremlin_flip3 ] {ai_face();};
void() gremlin_flip3 =[ $flip3.asc, gremlin_flip4 ] {};
void() gremlin_flip4 =[ $flip4.asc, gremlin_flip5 ] {};
void() gremlin_flip5 =[ $flip5.asc, gremlin_flip6 ] {};
void() gremlin_flip6 =[ $flip6.asc, gremlin_flip7 ] {self.touch = gremlin_fliptouch;};
void() gremlin_flip7 =[ $flip7.asc, gremlin_gib ]
{
self.nextthink = time + 3;
// if three seconds pass, assume gremlin is stuck and jump again
};
void() gremlin_flip8 =[ $flip8.asc, gremlin_flip8 ]
{
self.solid = solid_not;
};
/*
===============
gremlindropbackpack
===============
*/
void() gremlindropbackpack =
{
local entity item;
item = spawn();
item.origin = self.origin - '0 0 24';
self.items = self.items - ( self.items & (it_shells | it_nails | it_rockets | it_cells ) );
item.items = self.items;
if (item.items & it_axe)
item.netname = "axe";
else if (item.items & it_shotgun)
item.netname = "shotgun";
else if (item.items & it_super_shotgun)
item.netname = "double-barrelled shotgun";
else if (item.items & it_nailgun)
item.netname = "nailgun";
else if (item.items & it_super_nailgun)
item.netname = "super nailgun";
else if (item.items & it_grenade_launcher)
item.netname = "grenade launcher";
else if (item.items & it_rocket_launcher)
item.netname = "rocket launcher";
else if (item.items & it_lightning)
item.netname = "thunderbolt";
else if (item.items & it_laser_cannon)
item.netname = "laser cannon";
else if (item.items & it_proximity_gun)
item.netname = "proximity gun";
else if (item.items & it_mjolnir)
item.netname = "mjolnir";
else
item.netname = "";
item.ammo_shells = self.ammo_shells;
item.ammo_nails = self.ammo_nails;
item.ammo_rockets = self.ammo_rockets;
item.ammo_cells = self.ammo_cells;
if (item.ammo_shells < 0) item.ammo_shells = 0;
if (item.ammo_nails < 0) item.ammo_nails = 0;
if (item.ammo_rockets < 0) item.ammo_rockets = 0;
if (item.ammo_cells < 0) item.ammo_cells = 0;
item.velocity_z = 300;
item.velocity_x = -100 + (random() * 200);
item.velocity_y = -100 + (random() * 200);
item.flags = fl_item;
item.solid = solid_trigger;
item.movetype = movetype_toss;
setmodel (item, "progs/backpack.mdl");
setsize (item, '-16 -16 0', '16 16 56');
item.touch = backpacktouch;
item.nextthink = time + 120; // remove after 2 minutes
item.think = sub_remove;
};
void() gremlin_die =
{
local vector vec;
local float dot;
// check for gib
if (self.items & (it_super_shotgun|it_nailgun|it_super_nailgun|it_grenade_launcher|it_rocket_launcher|it_lightning|it_laser_cannon|it_proximity_gun))
{
gremlindropbackpack();
self.stoleweapon = false;
}
makevectors (self.angles);
vec = normalize (damage_attacker.origin - self.origin);
dot = vec * v_forward;
if (self.health < -35)
{
sound (self, chan_voice, "player/udeath.wav", 1, attn_norm);
throwhead ("progs/h_grem.mdl", self.health);
throwgib ("progs/gib1.mdl", self.health);
throwgib ("progs/gib1.mdl", self.health);
throwgib ("progs/gib1.mdl", self.health);
return;
}
else if (dot>0.7 && (random()<0.5) && (self.flags & fl_onground))
{
gremlin_flip1();
return;
}
// regular death
gremlin_die1 ();
};
float() gremlinweaponattack;
void() gremlin_meleeattack =
{
local float num;
if (self.gorging)
{
gremlin_gorge1();
}
else
{
if (self.stoleweapon == 1)
{
objerror("gremlin meleeing with stolen weapon");
}
else if ((self.enemy.flags & fl_client) && random() < 0.4)
{
if (gremlinattemptweaponsteal())
return;
}
num = random();
if (num<0.3)
{
gremlin_claw1 ();
}
else if (num < 0.6)
{
gremlin_lunge1 ();
}
else
{
gremlin_claw1 ();
}
}
};
/*
============
gremlin_recoil
============
*/
/*
void() gremlin_recoil =
{
self.nextthink = time + 0.1;
self.flags = self.flags - fl_onground;
if (vlen(self.velocity)<2)
{
self.movetype = self.spawnsolidtype;
self.think = self.spawnthink;
}
};
*/
/*
============
gremlinrecoil
============
*/
/*
void(vector dir, float mag) gremlinrecoil =
{
self.spawnsolidtype = self.movetype;
self.movetype = movetype_bounce;
self.spawnthink = self.think;
self.think = gremlin_recoil;
self.nextthink = time;
self.velocity = mag * dir;
self.velocity_z = self.velocity_z + 100;
self.flags = self.flags - fl_onground;
};
*/
/*
============
gremlinchecknoammo
attack with a weapon
============
*/
float() gremlinchecknoammo =
{
if (self.currentammo > 0)
return true;
else
{
self.stoleweapon = false;
return false;
}
};
/*
============
gremlinfindvictim
find a victim to shoot at
============
*/
entity() gremlinfindvictim =
{
local entity head;
local entity selected;
local float dist;
local float head_dist;
local float decision;
self.search_time = time + 1.0;
// look in our immediate vicinity
selected = world;
dist = 1000;
head = findradius(self.origin, 1000);
while(head)
{
if(!(head.flags & fl_notarget) && ((head.flags & fl_monster) || (head.flags & fl_client)))
{
if (visible(head) && (head.health > 0) && (head !=self))
{
head_dist = vlen(head.origin-self.origin);
if (head == self.lastvictim)
head_dist = head_dist * 2;
if (head.flags & fl_client)
head_dist = head_dist / 1.5;
if (head.classname == self.classname)
head_dist = head_dist * 1.5;
if (head_dist < dist)
{
selected = head;
dist = head_dist;
}
}
}
head = head.chain;
}
self.lastvictim = selected;
return selected;
};
/*
============
gremlin_firerocket
fire a rocket
============
*/
void() gremlin_firerocket =
{
local entity missile, mpuff;
local vector dir;
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
self.effects = self.effects | ef_muzzleflash;
sound (self, chan_weapon, "weapons/sgun1.wav", 1, attn_norm);
self.punchangle_x = -2;
missile = spawn ();
missile.owner = self;
missile.movetype = movetype_flymissile;
missile.solid = solid_bbox;
missile.classname = "missile";
// set missile speed
dir = normalize(self.enemy.origin - self.origin);
self.v_angle = vectoangles(dir);
makevectors(self.v_angle);
dir = dir + crandom()* 0.1 * v_right + crandom()* 0.1 *v_up;
missile.velocity = normalize(dir);
missile.velocity = missile.velocity * 1000;
missile.angles = vectoangles(missile.velocity);
missile.touch = t_missiletouch;
// set missile duration
missile.nextthink = time + 5;
missile.think = sub_remove;
setmodel (missile, "progs/missile.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin + v_forward*8 + '0 0 16');
// gremlinrecoil(dir,-1000);
};
/*
============
gremlin_firenailgun
fire a nailgun
============
*/
void(float ox) gremlin_firenailgun =
{
local vector dir;
self.currentammo = self.ammo_nails = self.ammo_nails - 1;
self.effects = self.effects | ef_muzzleflash;
sound (self, chan_weapon, "weapons/rocket1i.wav", 1, attn_norm);
dir = normalize(self.enemy.origin - self.origin);
self.v_angle = vectoangles(dir);
makevectors(self.v_angle);
dir = dir + crandom()* 0.1 * v_right + crandom()* 0.1 *v_up;
dir = normalize(dir);
launch_spike (self.origin + '0 0 16', dir);
};
/*
============
gremlin_firelasergun
fire a laser cannon
============
*/
void(float ox) gremlin_firelasergun =
{
local vector dir;
self.currentammo = self.ammo_cells = self.ammo_cells - 1;
self.effects = self.effects | ef_muzzleflash;
sound (self, chan_weapon, "weapons/rocket1i.wav", 1, attn_norm);
dir = normalize(self.enemy.origin - self.origin);
self.v_angle = vectoangles(dir);
makevectors(self.v_angle);
dir = dir + crandom()* 0.1 * v_right + crandom()* 0.1 *v_up;
dir = normalize(dir);
hip_launchlaser(self.origin + '0 0 16', dir, 0);
};
/*
============
gremlin_fireshotgun
fire a shotgun
============
*/
void() gremlin_fireshotgun =
{
local vector dir;
self.currentammo = self.ammo_shells = self.ammo_shells - 1;
self.effects = self.effects | ef_muzzleflash;
sound (self, chan_weapon, "weapons/guncock.wav", 1, attn_norm);
dir = normalize(self.enemy.origin - self.origin);
self.v_angle = vectoangles(dir);
makevectors(self.v_angle);
dir = dir + crandom()* 0.1 *v_right + crandom()* 0.1 *v_up;
dir = normalize(dir);
self.v_angle = vectoangles(dir);
firebullets (6, dir, '0.04 0.04 0');
};
/*
============
gremlin_firesupershotgun
fire a shotgun
============
*/
void() gremlin_firesupershotgun =
{
local vector dir;
self.currentammo = self.ammo_shells = self.ammo_shells - 2;
self.effects = self.effects | ef_muzzleflash;
sound (self ,chan_weapon, "weapons/shotgn2.wav", 1, attn_norm);
dir = normalize(self.enemy.origin - self.origin);
self.v_angle = vectoangles(dir);
makevectors(self.v_angle);
dir = dir + crandom()* 0.3 *v_right + crandom()* 0.3 *v_up;
dir = normalize(dir);
self.v_angle = vectoangles(dir);
firebullets (14, dir, '0.14 0.08 0');
};
/*
============
gremlin_firelightninggun
fire lightning gun
============
*/
void() gremlin_firelightninggun =
{
local vector org, dir;
local float cells;
// explode if under water
if (self.watertype <= content_water)
{
cells = self.ammo_cells;
self.ammo_cells = 0;
discharged = 1;
t_radiusdamage (self, self, 35*cells, world);
discharged = 0;
// w_setcurrentammo ();
return;
}
self.effects = self.effects | ef_muzzleflash;
ai_face ();
self.currentammo = self.ammo_cells = self.ammo_cells - 2;
org = self.origin + '0 0 16';
dir = self.enemy.origin + '0 0 16' - org;
dir = normalize (dir);
dir = normalize(self.enemy.origin - self.origin);
self.v_angle = vectoangles(dir);
makevectors(self.v_angle);
dir = dir + crandom()* 0.1 *v_right + crandom()* 0.1 *v_up;
dir = normalize(dir);
traceline (org, self.origin + dir*600, true, self);
writebyte (msg_broadcast, svc_tempentity);
writebyte (msg_broadcast, te_lightning2);
writeentity (msg_broadcast, self);
writecoord (msg_broadcast, org_x);
writecoord (msg_broadcast, org_y);
writecoord (msg_broadcast, org_z);
writecoord (msg_broadcast, trace_endpos_x);
writecoord (msg_broadcast, trace_endpos_y);
writecoord (msg_broadcast, trace_endpos_z);
lightningdamage (org, trace_endpos+(dir*4), self, 30);
};
/*
================
gremlinfireproximitygrenade
================
*/
void() gremlinfireproximitygrenade =
{
local entity missile;
local vector dir;
numproximitygrenades = numproximitygrenades + 1;
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
sound (self, chan_weapon, "weapons/grenade.wav", 1, attn_norm);
missile = spawn ();
missile.owner = self;
missile.lastvictim = self;
missile.movetype = movetype_toss;
missile.solid = solid_bbox;
missile.classname = "proximity_grenade";
missile.takedamage = damage_no;
missile.health = 5;
missile.state = 0;
// set missile speed
dir = normalize(self.enemy.origin - self.origin);
self.v_angle = vectoangles(dir);
makevectors(self.v_angle);
dir = dir + crandom()* 0.1 *v_right + crandom()* 0.1 *v_up;
dir = normalize(dir);
missile.velocity = dir * 600;
missile.velocity_z = 200;
missile.avelocity = '100 600 100';
missile.angles = vectoangles(missile.velocity);
missile.touch = proximitygrenadetouch;
// set missile duration
missile.nextthink = time + 2;
missile.delay = time + 15 + (10*random());
missile.think = proximitybomb;
missile.th_die = proximitygrenadeexplode;
setmodel (missile, "progs/proxbomb.mdl");
setorigin (missile, self.origin);
setsize (missile, '-1 -1 -1', '1 1 1');
};
/*
============
gremlinweaponattack
attack with a weapon
============
*/
void() gremlin_shot1;
void() gremlin_nail1;
void() gremlin_light1;
void() gremlin_rocket1;
float() gremlinweaponattack =
{
local float r;
local entity targ;
local vector vec;
if (!gremlinchecknoammo ())
return false;
self.show_hostile = time + 1; // wake monsters up
if (self.weapon == it_shotgun)
{
gremlin_shot1 ();
gremlin_fireshotgun();
sub_attackfinished(1);
}
else if (self.weapon == it_super_shotgun)
{
gremlin_shot1 ();
gremlin_firesupershotgun();
sub_attackfinished(1);
}
else if (self.weapon == it_nailgun)
{
gremlin_nail3 ();
sub_attackfinished(1);
}
else if (self.weapon == it_super_nailgun)
{
gremlin_nail3 ();
sub_attackfinished(1);
}
else if (self.weapon == it_grenade_launcher)
{
gremlin_rocket1();
ogrefiregrenade();
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
sub_attackfinished(1);
}
else if (self.weapon == it_rocket_launcher)
{
gremlin_rocket1();
gremlin_firerocket();
sub_attackfinished(1);
}
else if (self.weapon == it_lightning)
{
gremlin_light1();
sub_attackfinished(1);
sound (self, chan_auto, "weapons/lstart.wav", 1, attn_norm);
}
else if (self.weapon == it_laser_cannon)
{
gremlin_laser3();
sub_attackfinished(1);
}
else if (self.weapon == it_proximity_gun)
{
gremlin_rocket1();
gremlinfireproximitygrenade();
sub_attackfinished(1);
}
return true;
};
void() gremlin_missileattack =
{
if (self.stoleweapon)
{
if (gremlinweaponattack())
return;
else if ((random()<0.1) && (self.flags & fl_onground))
{
gremlin_jump1();
return;
}
}
if (self.flags & fl_onground)
gremlin_jump1();
};
/*quaked monster_gremlin (1 0 0) (-32 -32 -24) (32 32 64) ambush
*/
void() monster_gremlin =
{
if (deathmatch)
{
remove(self);
return;
}
numgremlins = numgremlins + 1;
precache_model ("progs/grem.mdl");
precache_model ("progs/h_grem.mdl");
precache_sound ("grem/death.wav");
precache_sound ("grem/attack.wav");
precache_sound ("demon/djump.wav");
precache_sound ("demon/dhit2.wav");
precache_sound ("grem/pain1.wav");
precache_sound ("grem/pain2.wav");
precache_sound ("grem/pain3.wav");
precache_sound ("grem/idle.wav");
precache_sound ("grem/sight1.wav");
self.solid = solid_slidebox;
self.movetype = movetype_step;
setmodel (self, "progs/grem.mdl");
setsize (self, vec_hull_min, vec_hull_max);
self.health = 100;
self.max_health = 101;
self.yaw_speed = 40;
self.th_stand = gremlin_stand1;
self.th_walk = gremlin_walk1;
self.th_run = gremlin_run1;
self.th_die = gremlin_die;
self.th_melee = gremlin_meleeattack; // one of two attacks
self.th_missile = gremlin_missileattack; // check for random jump or firing of weapon
self.th_pain = gremlin_pain;
walkmonster_start();
};
float() gremlincheckattack =
{
local vector spot1, spot2;
local entity targ;
local float chance;
targ = self.enemy;
if (time < self.attack_finished)
return false;
// see if any entities are in the way of the shot
spot1 = self.origin;// + self.view_ofs;
spot2 = targ.origin;// + targ.view_ofs;
if ((vlen(spot2 - spot1) <= 90) && (self.stoleweapon == 0))
{
self.attack_state = as_melee;
return true;
}
// missile attack
chance = 0.03 + self.stoleweapon;
if (random() < chance)
{
self.attack_state = as_missile;
return true;
}
return false;
};
//===========================================================================
void(float side) gremlin_melee =
{
local float ldmg;
local vector delta;
ai_face ();
// walkmove (self.ideal_yaw, 12); // allow a little closing
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 100)
return;
if (!candamage (self.enemy, self))
return;
sound (self, chan_weapon, "grem/attack.wav", 1, attn_norm);
ldmg = 10 + 5*random();
t_damage (self.enemy, self, self, ldmg);
makevectors (self.angles);
spawnmeatspray (self.origin + v_forward*16, side * v_right);
};
//===========================================================================
void(float dm) gremlin_throwhead =
{
local string gibname;
if (self.classname == "monster_ogre")
gibname = "progs/h_ogre.mdl";
else if (self.classname == "monster_knight")
gibname = "progs/h_knight.mdl";
else if (self.classname == "monster_shambler")
gibname = "progs/h_shams.mdl";
else if (self.classname == "monster_demon1")
gibname = "progs/h_demon.mdl";
else if (self.classname == "monster_wizard")
gibname = "progs/h_wizard.mdl";
else if (self.classname == "monster_zombie")
gibname = "progs/h_zombie.mdl";
else if (self.classname == "monster_dog")
gibname = "progs/h_dog.mdl";
else if (self.classname == "monster_hell_knight")
gibname = "progs/h_hellkn.mdl";
else if (self.classname == "monster_enforcer")
gibname = "progs/h_mega.mdl";
else if (self.classname == "monster_army")
gibname = "progs/h_guard.mdl";
else if (self.classname == "monster_shalrath")
gibname = "progs/h_shal.mdl";
else if (self.classname == "monster_gremlin")
gibname = "progs/h_grem.mdl";
else if (self.classname == "monster_scourge")
gibname = "progs/h_scourg.mdl";
else if (self.classname == "monster_fish")
gibname = "progs/gib1.mdl";
else
gibname = "progs/h_player.mdl";
throwhead(gibname,dm);
};
//===========================================================================
/*
============
gremlin_damage
the damage is coming from inflictor, but get mad at attacker
============
*/
void(entity targ, entity inflictor, entity attacker, float damage) gremlin_damage=
{
// check for godmode or invincibility
if (targ.flags & fl_godmode)
return;
if (targ.invincible_finished >= time)
{
if (self.invincible_sound < time)
{
sound (targ, chan_item, "items/protect3.wav", 1, attn_norm);
self.invincible_sound = time + 2;
}
return;
}
// team play damage avoidance
if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) )
return;
// do the damage
targ.health = targ.health - damage;
};
void() gremlin_split =
{
local entity grem;
local entity temp;
local entity head;
local float done;
local vector ang;
local float c;
local vector pos;
local float proceed;
if (numspawngremlins >= (numgremlins*2))
return;
done = 0;
c = 0;
ang = self.angles;
while (done == 0)
{
makevectors(ang);
pos = self.origin + (80 * v_forward);
head = findradius(pos, 35);
proceed = 1;
while (head)
{
if ((head.health > 0) && (head.flags & (fl_monster | fl_client)))
proceed = 0;
head = head.chain;
}
traceline(self.origin,pos,false,self);
if (trace_fraction == 1 && (proceed == 1))
{
traceline(self.origin,(pos-'40 40 0'),false,self);
if (trace_fraction == 1)
{
traceline(self.origin,(pos+'40 40 0'),false,self);
if (trace_fraction == 1)
{
traceline(self.origin,(pos + '0 0 64'),false,self);
if (trace_fraction == 1)
{
traceline(self.origin,(pos - '0 0 64'),false,self);
if (trace_fraction != 1)
{
done = 1;
}
}
}
}
}
if (done == 0)
{
ang_y = ang_y + 36;
c = c + 1;
if (c==10)
{
return;
}
}
}
numspawngremlins = numspawngremlins + 1;
grem = spawn();
sub_copyentity(self,grem);
grem.solid = solid_slidebox;
grem.movetype = movetype_step;
setmodel (grem, "progs/grem.mdl");
setsize (grem, vec_hull_min, vec_hull_max);
if (self.health < 100) self.health = 100;
grem.health = self.health / 2;
self.health = self.health / 2;
// grem.max_health = 101;
// grem.gorging = false;
grem.stoleweapon = false;
grem.items = 0;
total_monsters = total_monsters + 1;
writebyte (msg_broadcast, svc_updatestat);
writebyte (msg_broadcast, stat_totalmonsters);
writelong (msg_broadcast, total_monsters);
setorigin(grem, pos);
temp = self;
self = grem;
gremlin_spawn1();
self.enemy = world;
self.gorging = false;
self = temp;
};
void(float side) gremlin_gorge =
{
local float ldmg;
local vector delta;
local entity temp;
// ai_face ();
// walkmove (self.ideal_yaw, 6); // allow a little closing
delta = self.enemy.origin - self.origin;
// self.enemy.takedamage = damage_yes;
sound (self, chan_weapon, "demon/dhit2.wav", 1, attn_norm);
// sound (self, chan_weapon, "grem/attack.wav", 1, attn_norm);
ldmg = 7+5*random();
gremlin_damage (self.enemy, self, self, ldmg);
makevectors (self.angles);
spawnmeatspray (self.origin + v_forward*16, side * v_right);
if (self.enemy.health < -200.0)
{
if (self.enemy.gorging==false)
{
self.enemy.gorging = true;
sound (self, chan_voice, "player/udeath.wav", 1, attn_norm);
temp = self;
self = self.enemy;
gremlin_throwhead(-15);
// throwgib ("progs/gib1.mdl", -15);
// throwgib ("progs/gib2.mdl", -15);
// throwgib ("progs/gib3.mdl", -15);
self = temp;
ldmg = 150 + 100*random();
t_heal(self,ldmg,false);
// if (self.health >= self.max_health)
gremlin_split();
}
self.enemy = world;
self.gorging = false;
/*
if (self.stoleweapon)
{
temp = gremlinfindvictim();
if (temp != world)
{
self.enemy = temp;
foundtarget();
self.search_time = time + 1.0;
// return;
}
}
*/
// findtarget();
/*
if (self.oldenemy.health > 0)
{
self.enemy = self.oldenemy;
hunttarget ();
}
else
{
if (self.movetarget)
self.th_walk ();
else
self.th_stand ();
}
*/
gremlin_look1();
}
};
void() gremlin_jumptouch =
{
local float ldmg;
if (self.health <= 0)
return;
/*
if (other.takedamage)
{
if ( vlen(self.velocity) > 400 )
{
ldmg = 40 + 10*random();
t_damage (other, self, self, ldmg);
}
}
*/
if (!checkbottom(self))
{
if (self.flags & fl_onground)
{
self.touch = sub_null;
self.think = gremlin_jump1;
self.nextthink = time + 0.1;
}
return; // not on ground yet
}
self.touch = sub_null;
self.think = gremlin_jump12;
self.nextthink = time + 0.1;
};
void() gremlin_fliptouch =
{
local float ldmg;
if (!checkbottom(self))
{
if (self.flags & fl_onground)
{
self.touch = sub_null;
self.think = gremlin_flip1;
self.nextthink = time + 0.1;
}
return; // not on ground yet
}
self.touch = sub_null;
self.think = gremlin_flip8;
self.nextthink = time + 0.1;
};