as released 1997-05-01

This commit is contained in:
archive 2023-05-09 02:32:06 +00:00
commit 54989d6d04
64 changed files with 28656 additions and 0 deletions

763
AI.QC Normal file
View File

@ -0,0 +1,763 @@
void() movetarget_f;
void() t_movetarget;
void() knight_walk1;
void() knight_bow6;
void() knight_bow1;
void(entity etemp, entity stemp, entity stemp, float dmg) T_Damage;
/*
.enemy
Will be world if not currently angry at anyone.
.movetarget
The next path spot to walk toward. If .enemy, ignore .movetarget.
When an enemy is killed, the monster will try to return to it's path.
.huntt_ime
Set to time + something when the player is in sight, but movement straight for
him is blocked. This causes the monster to use wall following code for
movement direction instead of sighting on the player.
.ideal_yaw
A yaw angle of the intended direction, which will be turned towards at up
to 45 deg / state. If the enemy is in view and hunt_time is not active,
this will be the exact line towards the enemy.
.pausetime
A monster will leave it's stand state and head towards it's .movetarget when
time > .pausetime.
walkmove(angle, speed) primitive is all or nothing
*/
//
// globals
//
float current_yaw;
//
// when a monster becomes angry at a player, that monster will be used
// as the sight target the next frame so that monsters near that one
// will wake up even if they wouldn't have noticed the player
//
entity sight_entity;
float sight_entity_time;
float(float v) anglemod =
{
while (v >= 360)
v = v - 360;
while (v < 0)
v = v + 360;
return v;
};
/*
==============================================================================
MOVETARGET CODE
The angle of the movetarget effects standing and bowing direction, but has no effect on movement, which allways heads to the next target.
targetname
must be present. The name of this movetarget.
target
the next spot to move to. If not present, stop here for good.
pausetime
The number of seconds to spend standing or bowing for path_stand or path_bow
==============================================================================
*/
void() movetarget_f =
{
if (!self.targetname)
objerror ("monster_movetarget: no targetname");
self.solid = SOLID_TRIGGER;
self.touch = t_movetarget;
setsize (self, '-8 -8 -8', '8 8 8');
};
/*QUAKED path_corner (0.5 0.3 0) (-8 -8 -8) (8 8 8)
Monsters will continue walking towards the next target corner.
*/
void() path_corner =
{
movetarget_f ();
};
/*
=============
t_movetarget
Something has bumped into a movetarget. If it is a monster
moving towards it, change the next destination and continue.
==============
*/
void() t_movetarget =
{
local entity temp;
if (other.movetarget != self)
return;
if (other.enemy)
return; // fighting, not following a path
temp = self;
self = other;
other = temp;
if (self.classname == "monster_ogre")
sound (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);// play chainsaw drag sound
//dprint ("t_movetarget\n");
self.goalentity = self.movetarget = find (world, targetname, other.target);
self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
if (!self.movetarget)
{
self.pausetime = time + 999999;
self.th_stand ();
return;
}
};
//============================================================================
/*
=============
range
returns the range catagorization of an entity reletive to self
0 melee range, will become hostile even if back is turned
1 visibility and infront, or visibility and show hostile
2 infront and show hostile
3 only triggered by damage
=============
*/
float(entity targ) range =
{
local vector spot1, spot2;
local float r;
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
r = vlen (spot1 - spot2);
if (r < 120)
return RANGE_MELEE;
if (r < 500)
return RANGE_NEAR;
if (r < 1000)
return RANGE_MID;
return RANGE_FAR;
};
/*
=============
visible
returns 1 if the entity is visible to self, even if not infront ()
=============
*/
float (entity targ) visible =
{
local vector spot1, spot2;
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
traceline (spot1, spot2, TRUE, self); // see through other monsters
if (trace_inopen && trace_inwater)
return FALSE; // sight line crossed contents
if (trace_fraction == 1)
return TRUE;
return FALSE;
};
/*
=============
infront
returns 1 if the entity is in front (in sight) of self
=============
*/
float(entity targ) infront =
{
local vector vec;
local float dot;
makevectors (self.angles);
vec = normalize (targ.origin - self.origin);
dot = vec * v_forward;
if ( dot > 0.3)
{
return TRUE;
}
return FALSE;
};
//============================================================================
/*
===========
ChangeYaw
Turns towards self.ideal_yaw at self.yaw_speed
Sets the global variable current_yaw
Called every 0.1 sec by monsters
============
*/
/*
void() ChangeYaw =
{
local float ideal, move;
//current_yaw = self.ideal_yaw;
// mod down the current angle
current_yaw = anglemod( self.angles_y );
ideal = self.ideal_yaw;
if (current_yaw == ideal)
return;
move = ideal - current_yaw;
if (ideal > current_yaw)
{
if (move > 180)
move = move - 360;
}
else
{
if (move < -180)
move = move + 360;
}
if (move > 0)
{
if (move > self.yaw_speed)
move = self.yaw_speed;
}
else
{
if (move < 0-self.yaw_speed )
move = 0-self.yaw_speed;
}
current_yaw = anglemod (current_yaw + move);
self.angles_y = current_yaw;
};
*/
//============================================================================
void() HuntTarget =
{
self.goalentity = self.enemy;
self.think = self.th_run;
self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
self.nextthink = time + 0.1;
SUB_AttackFinished (1); // wait a while before first attack
};
void() SightSound =
{
local float rsnd;
if (self.classname == "monster_ogre")
sound (self, CHAN_VOICE, "ogre/ogwake.wav", 1, ATTN_NORM);
else if (self.classname == "monster_knight")
{
if (self.skin == 0)
sound (self, CHAN_VOICE, "knight/ksight.wav", 1, ATTN_NORM);
}
else if (self.classname == "monster_shambler")
sound (self, CHAN_VOICE, "shambler/ssight.wav", 1, ATTN_NORM);
else if (self.classname == "monster_demon1")
sound (self, CHAN_VOICE, "demon/sight2.wav", 1, ATTN_NORM);
else if (self.classname == "monster_wizard")
sound (self, CHAN_VOICE, "wizard/wsight.wav", 1, ATTN_NORM);
else if (self.classname == "monster_zombie")
sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_NORM);
else if (self.classname == "monster_dog")
sound (self, CHAN_VOICE, "dog/dsight.wav", 1, ATTN_NORM);
else if (self.classname == "monster_hell_knight")
{
if (self.skin == 0)
sound (self, CHAN_VOICE, "hknight/sight1.wav", 1, ATTN_NORM);
}
else if (self.classname == "monster_tarbaby")
sound (self, CHAN_VOICE, "blob/sight1.wav", 1, ATTN_NORM);
else if (self.classname == "monster_vomit")
sound (self, CHAN_VOICE, "vomitus/v_sight1.wav", 1, ATTN_NORM);
else if (self.classname == "monster_eel")
sound (self, CHAN_VOICE, "eel/eelc5.wav", 1, ATTN_NORM);
else if (self.classname == "monster_wrath")
sound (self, CHAN_VOICE, "wrath/wsee.wav", 1, ATTN_NORM);
else if (self.classname == "monster_enforcer")
{
rsnd = rint(random() * 3);
if (rsnd == 1)
sound (self, CHAN_VOICE, "enforcer/sight1.wav", 1, ATTN_NORM);
else if (rsnd == 2)
sound (self, CHAN_VOICE, "enforcer/sight2.wav", 1, ATTN_NORM);
else if (rsnd == 0)
sound (self, CHAN_VOICE, "enforcer/sight3.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "enforcer/sight4.wav", 1, ATTN_NORM);
}
else if (self.classname == "monster_army")
sound (self, CHAN_VOICE, "soldier/sight1.wav", 1, ATTN_NORM);
else if (self.classname == "monster_shalrath")
sound (self, CHAN_VOICE, "shalrath/sight.wav", 1, ATTN_NORM);
else if (self.classname == "monster_dragon")
sound (self, CHAN_VOICE, "dragon/see.wav", 1, ATTN_NORM);
};
void() FoundTarget =
{
if (self.enemy.classname == "player")
{ // let other monsters see this monster for a while
sight_entity = self;
sight_entity_time = time;
}
self.show_hostile = time + 1; // wake up other monsters
SightSound ();
HuntTarget ();
};
/*
===========
FindTarget
Self is currently not attacking anything, so try to find a target
Returns TRUE if an enemy was sighted
When a player fires a missile, the point of impact becomes a fakeplayer so
that monsters that see the impact will respond as if they had seen the
player.
To avoid spending too much time, only a single client (or fakeclient) is
checked each frame. This means multi player games will have slightly
slower noticing monsters.
============
*/
float() FindTarget =
{
local entity client;
local float r;
// if the first spawnflag bit is set, the monster will only wake up on
// really seeing the player, not another monster getting angry
// spawnflags & 3 is a big hack, because zombie crucified used the first
// spawn flag prior to the ambush flag, and I forgot about it, so the second
// spawn flag works as well
if (sight_entity_time >= time - 0.1 && !(self.spawnflags & 3) )
{
client = sight_entity;
if (client.enemy == self.enemy)
return;
}
else
{
client = checkclient ();
if (!client)
return FALSE; // current check entity isn't in PVS
}
if (client == self.enemy)
return FALSE;
if (client.flags & FL_NOTARGET)
return FALSE;
if (client.items & IT_INVISIBILITY)
return FALSE;
r = range (client);
if (r == RANGE_FAR)
return FALSE;
if (!visible (client))
return FALSE;
if (r == RANGE_NEAR)
{
if (client.show_hostile < time && !infront (client))
return FALSE;
}
else if (r == RANGE_MID)
{
if ( /* client.show_hostile < time || */ !infront (client))
return FALSE;
}
//
// got one
//
self.enemy = client;
if (self.enemy.classname != "player")
{
self.enemy = self.enemy.enemy;
if (self.enemy.classname != "player")
{
self.enemy = world;
return FALSE;
}
}
// PGM hack
if (self.classname != "dragon")
FoundTarget ();
return TRUE;
};
//=============================================================================
void(float dist) ai_forward =
{
walkmove (self.angles_y, dist);
};
void(float dist) ai_back =
{
walkmove ( (self.angles_y+180), dist);
};
/*
=============
ai_pain
stagger back a bit
=============
*/
void(float dist) ai_pain =
{
ai_back (dist);
/*
local float away;
away = anglemod (vectoyaw (self.origin - self.enemy.origin)
+ 180*(random()- 0.5) );
walkmove (away, dist);
*/
};
/*
=============
ai_painforward
stagger back a bit
=============
*/
void(float dist) ai_painforward =
{
walkmove (self.ideal_yaw, dist);
};
/*
=============
ai_walk
The monster is walking it's beat
=============
*/
void(float dist) ai_walk =
{
local vector mtemp;
movedist = dist;
/* Dragon movement handled in dragon.qc.... this is legacy.
if (self.classname == "monster_dragon")
{
movetogoal (dist);
return;
}
*/
// check for noticing a player
if (FindTarget ())
return;
movetogoal (dist);
};
/*
=============
ai_stand
The monster is staying in one place for a while, with slight angle turns
=============
*/
void() ai_stand =
{
if (FindTarget ())
return;
if (time > self.pausetime)
{
self.th_walk ();
return;
}
// change angle slightly
};
/*
=============
ai_turn
don't move, but turn towards ideal_yaw
=============
*/
void() ai_turn =
{
if (FindTarget ())
return;
ChangeYaw ();
};
//=============================================================================
/*
=============
ChooseTurn
=============
*/
void(vector dest3) ChooseTurn =
{
local vector dir, newdir;
dir = self.origin - dest3;
newdir_x = trace_plane_normal_y;
newdir_y = 0 - trace_plane_normal_x;
newdir_z = 0;
if (dir * newdir > 0)
{
dir_x = 0 - trace_plane_normal_y;
dir_y = trace_plane_normal_x;
}
else
{
dir_x = trace_plane_normal_y;
dir_y = 0 - trace_plane_normal_x;
}
dir_z = 0;
self.ideal_yaw = vectoyaw(dir);
};
/*
============
FacingIdeal
============
*/
float() FacingIdeal =
{
local float delta;
delta = anglemod(self.angles_y - self.ideal_yaw);
if (delta > 45 && delta < 315)
return FALSE;
return TRUE;
};
//=============================================================================
float() WizardCheckAttack;
float() DogCheckAttack;
float() CheckAnyAttack =
{
if (!enemy_vis)
return;
if (self.classname == "monster_army")
return SoldierCheckAttack ();
if (self.classname == "monster_ogre")
return OgreCheckAttack ();
if (self.classname == "monster_shambler")
return ShamCheckAttack ();
if (self.classname == "monster_demon1")
return DemonCheckAttack ();
if (self.classname == "monster_dog")
return DogCheckAttack ();
if (self.classname == "monster_wizard")
return WizardCheckAttack ();
return CheckAttack ();
};
/*
=============
ai_run_melee
Turn and close until within an angle to launch a melee attack
=============
*/
void() ai_run_melee =
{
self.ideal_yaw = enemy_yaw;
ChangeYaw ();
if (FacingIdeal())
{
self.th_melee ();
self.attack_state = AS_STRAIGHT;
}
};
/*
=============
ai_run_missile
Turn in place until within an angle to launch a missile attack
=============
*/
void() ai_run_missile =
{
self.ideal_yaw = enemy_yaw;
ChangeYaw ();
if (FacingIdeal())
{
self.th_missile ();
self.attack_state = AS_STRAIGHT;
}
};
/*
=============
ai_run_slide
Strafe sideways, but stay at aproximately the same range
=============
*/
void() ai_run_slide =
{
local float ofs;
self.ideal_yaw = enemy_yaw;
ChangeYaw ();
if (self.lefty)
ofs = 90;
else
ofs = -90;
if (walkmove (self.ideal_yaw + ofs, movedist))
return;
self.lefty = 1 - self.lefty;
walkmove (self.ideal_yaw - ofs, movedist);
};
/*
=============
ai_run
The monster has an enemy it is trying to kill
=============
*/
void(float dist) ai_run =
{
local vector delta;
local float axis;
local float direct, ang_rint, ang_floor, ang_ceil;
movedist = dist;
// see if the enemy is dead
if (self.enemy.health <= 0)
{
self.enemy = world;
// FIXME: look all around for other targets
if (self.oldenemy.health > 0)
{
self.enemy = self.oldenemy;
HuntTarget ();
}
else
{
if (self.movetarget)
self.th_walk ();
else
self.th_stand ();
return;
}
}
self.show_hostile = time + 1; // wake up other monsters
// check knowledge of enemy
enemy_vis = visible(self.enemy);
if (enemy_vis)
self.search_time = time + 5;
// look for other coop players
if (coop && self.search_time < time)
{
if (FindTarget ())
return;
}
enemy_infront = infront(self.enemy);
enemy_range = range(self.enemy);
enemy_yaw = vectoyaw(self.enemy.origin - self.origin);
if (self.attack_state == AS_MISSILE)
{
//dprint ("ai_run_missile\n");
ai_run_missile ();
return;
}
if (self.attack_state == AS_MELEE)
{
//dprint ("ai_run_melee\n");
ai_run_melee ();
return;
}
if (CheckAnyAttack ())
return; // beginning an attack
if (self.attack_state == AS_SLIDING)
{
ai_run_slide ();
return;
}
// head straight in
movetogoal (dist); // done in C code...
};

385
BOSS.QC Normal file
View File

@ -0,0 +1,385 @@
/*
==============================================================================
BOSS-ONE
==============================================================================
*/
$cd /raid/quake/id1/models/boss1
$origin 0 0 -15
$base base
$skin skin
$scale 5
$frame rise1 rise2 rise3 rise4 rise5 rise6 rise7 rise8 rise9 rise10
$frame rise11 rise12 rise13 rise14 rise15 rise16 rise17
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
$frame walk9 walk10 walk11 walk12 walk13 walk14 walk15
$frame walk16 walk17 walk18 walk19 walk20 walk21 walk22
$frame walk23 walk24 walk25 walk26 walk27 walk28 walk29 walk30 walk31
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
$frame attack9 attack10 attack11 attack12 attack13 attack14 attack15
$frame attack16 attack17 attack18 attack19 attack20 attack21 attack22
$frame attack23
$frame shocka1 shocka2 shocka3 shocka4 shocka5 shocka6 shocka7 shocka8
$frame shocka9 shocka10
$frame shockb1 shockb2 shockb3 shockb4 shockb5 shockb6
$frame shockc1 shockc2 shockc3 shockc4 shockc5 shockc6 shockc7 shockc8
$frame shockc9 shockc10
void(vector p) boss_missile;
void() boss_face =
{
// go for another player if multi player
if (self.enemy.health <= 0 || random() < 0.02)
{
self.enemy = find(self.enemy, classname, "player");
if (!self.enemy)
self.enemy = find(self.enemy, classname, "player");
}
ai_face();
};
void() boss_rise1 =[ $rise1, boss_rise2 ] {
sound (self, CHAN_WEAPON, "boss1/out1.wav", 1, ATTN_NORM);
};
void() boss_rise2 =[ $rise2, boss_rise3 ] {
sound (self, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM);
};
void() boss_rise3 =[ $rise3, boss_rise4 ] {};
void() boss_rise4 =[ $rise4, boss_rise5 ] {};
void() boss_rise5 =[ $rise5, boss_rise6 ] {};
void() boss_rise6 =[ $rise6, boss_rise7 ] {};
void() boss_rise7 =[ $rise7, boss_rise8 ] {};
void() boss_rise8 =[ $rise8, boss_rise9 ] {};
void() boss_rise9 =[ $rise9, boss_rise10 ] {};
void() boss_rise10 =[ $rise10, boss_rise11 ] {};
void() boss_rise11 =[ $rise11, boss_rise12 ] {};
void() boss_rise12 =[ $rise12, boss_rise13 ] {};
void() boss_rise13 =[ $rise13, boss_rise14 ] {};
void() boss_rise14 =[ $rise14, boss_rise15 ] {};
void() boss_rise15 =[ $rise15, boss_rise16 ] {};
void() boss_rise16 =[ $rise16, boss_rise17 ] {};
void() boss_rise17 =[ $rise17, boss_missile1 ] {};
void() boss_idle1 =[ $walk1, boss_idle2 ]
{
// look for other players
};
void() boss_idle2 =[ $walk2, boss_idle3 ] {boss_face();};
void() boss_idle3 =[ $walk3, boss_idle4 ] {boss_face();};
void() boss_idle4 =[ $walk4, boss_idle5 ] {boss_face();};
void() boss_idle5 =[ $walk5, boss_idle6 ] {boss_face();};
void() boss_idle6 =[ $walk6, boss_idle7 ] {boss_face();};
void() boss_idle7 =[ $walk7, boss_idle8 ] {boss_face();};
void() boss_idle8 =[ $walk8, boss_idle9 ] {boss_face();};
void() boss_idle9 =[ $walk9, boss_idle10 ] {boss_face();};
void() boss_idle10 =[ $walk10, boss_idle11 ] {boss_face();};
void() boss_idle11 =[ $walk11, boss_idle12 ] {boss_face();};
void() boss_idle12 =[ $walk12, boss_idle13 ] {boss_face();};
void() boss_idle13 =[ $walk13, boss_idle14 ] {boss_face();};
void() boss_idle14 =[ $walk14, boss_idle15 ] {boss_face();};
void() boss_idle15 =[ $walk15, boss_idle16 ] {boss_face();};
void() boss_idle16 =[ $walk16, boss_idle17 ] {boss_face();};
void() boss_idle17 =[ $walk17, boss_idle18 ] {boss_face();};
void() boss_idle18 =[ $walk18, boss_idle19 ] {boss_face();};
void() boss_idle19 =[ $walk19, boss_idle20 ] {boss_face();};
void() boss_idle20 =[ $walk20, boss_idle21 ] {boss_face();};
void() boss_idle21 =[ $walk21, boss_idle22 ] {boss_face();};
void() boss_idle22 =[ $walk22, boss_idle23 ] {boss_face();};
void() boss_idle23 =[ $walk23, boss_idle24 ] {boss_face();};
void() boss_idle24 =[ $walk24, boss_idle25 ] {boss_face();};
void() boss_idle25 =[ $walk25, boss_idle26 ] {boss_face();};
void() boss_idle26 =[ $walk26, boss_idle27 ] {boss_face();};
void() boss_idle27 =[ $walk27, boss_idle28 ] {boss_face();};
void() boss_idle28 =[ $walk28, boss_idle29 ] {boss_face();};
void() boss_idle29 =[ $walk29, boss_idle30 ] {boss_face();};
void() boss_idle30 =[ $walk30, boss_idle31 ] {boss_face();};
void() boss_idle31 =[ $walk31, boss_idle1 ] {boss_face();};
void() boss_missile1 =[ $attack1, boss_missile2 ] {boss_face();};
void() boss_missile2 =[ $attack2, boss_missile3 ] {boss_face();};
void() boss_missile3 =[ $attack3, boss_missile4 ] {boss_face();};
void() boss_missile4 =[ $attack4, boss_missile5 ] {boss_face();};
void() boss_missile5 =[ $attack5, boss_missile6 ] {boss_face();};
void() boss_missile6 =[ $attack6, boss_missile7 ] {boss_face();};
void() boss_missile7 =[ $attack7, boss_missile8 ] {boss_face();};
void() boss_missile8 =[ $attack8, boss_missile9 ] {boss_face();};
void() boss_missile9 =[ $attack9, boss_missile10 ] {boss_missile('100 100 200');};
void() boss_missile10 =[ $attack10, boss_missile11 ] {boss_face();};
void() boss_missile11 =[ $attack11, boss_missile12 ] {boss_face();};
void() boss_missile12 =[ $attack12, boss_missile13 ] {boss_face();};
void() boss_missile13 =[ $attack13, boss_missile14 ] {boss_face();};
void() boss_missile14 =[ $attack14, boss_missile15 ] {boss_face();};
void() boss_missile15 =[ $attack15, boss_missile16 ] {boss_face();};
void() boss_missile16 =[ $attack16, boss_missile17 ] {boss_face();};
void() boss_missile17 =[ $attack17, boss_missile18 ] {boss_face();};
void() boss_missile18 =[ $attack18, boss_missile19 ] {boss_face();};
void() boss_missile19 =[ $attack19, boss_missile20 ] {boss_face();};
void() boss_missile20 =[ $attack20, boss_missile21 ] {boss_missile('100 -100 200');};
void() boss_missile21 =[ $attack21, boss_missile22 ] {boss_face();};
void() boss_missile22 =[ $attack22, boss_missile23 ] {boss_face();};
void() boss_missile23 =[ $attack23, boss_missile1 ] {boss_face();};
void() boss_shocka1 =[ $shocka1, boss_shocka2 ] {};
void() boss_shocka2 =[ $shocka2, boss_shocka3 ] {};
void() boss_shocka3 =[ $shocka3, boss_shocka4 ] {};
void() boss_shocka4 =[ $shocka4, boss_shocka5 ] {};
void() boss_shocka5 =[ $shocka5, boss_shocka6 ] {};
void() boss_shocka6 =[ $shocka6, boss_shocka7 ] {};
void() boss_shocka7 =[ $shocka7, boss_shocka8 ] {};
void() boss_shocka8 =[ $shocka8, boss_shocka9 ] {};
void() boss_shocka9 =[ $shocka9, boss_shocka10 ] {};
void() boss_shocka10 =[ $shocka10, boss_missile1 ] {};
void() boss_shockb1 =[ $shockb1, boss_shockb2 ] {};
void() boss_shockb2 =[ $shockb2, boss_shockb3 ] {};
void() boss_shockb3 =[ $shockb3, boss_shockb4 ] {};
void() boss_shockb4 =[ $shockb4, boss_shockb5 ] {};
void() boss_shockb5 =[ $shockb5, boss_shockb6 ] {};
void() boss_shockb6 =[ $shockb6, boss_shockb7 ] {};
void() boss_shockb7 =[ $shockb1, boss_shockb8 ] {};
void() boss_shockb8 =[ $shockb2, boss_shockb9 ] {};
void() boss_shockb9 =[ $shockb3, boss_shockb10 ] {};
void() boss_shockb10 =[ $shockb4, boss_missile1 ] {};
void() boss_shockc1 =[ $shockc1, boss_shockc2 ] {};
void() boss_shockc2 =[ $shockc2, boss_shockc3 ] {};
void() boss_shockc3 =[ $shockc3, boss_shockc4 ] {};
void() boss_shockc4 =[ $shockc4, boss_shockc5 ] {};
void() boss_shockc5 =[ $shockc5, boss_shockc6 ] {};
void() boss_shockc6 =[ $shockc6, boss_shockc7 ] {};
void() boss_shockc7 =[ $shockc7, boss_shockc8 ] {};
void() boss_shockc8 =[ $shockc8, boss_shockc9 ] {};
void() boss_shockc9 =[ $shockc9, boss_shockc10 ] {};
void() boss_shockc10 =[ $shockc10, boss_death1 ] {};
void() boss_death1 = [$death1, boss_death2] {
sound (self, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM);
};
void() boss_death2 = [$death2, boss_death3] {};
void() boss_death3 = [$death3, boss_death4] {};
void() boss_death4 = [$death4, boss_death5] {};
void() boss_death5 = [$death5, boss_death6] {};
void() boss_death6 = [$death6, boss_death7] {};
void() boss_death7 = [$death7, boss_death8] {};
void() boss_death8 = [$death8, boss_death9] {};
void() boss_death9 = [$death9, boss_death10]
{
sound (self, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
};
void() boss_death10 = [$death9, boss_death10]
{
killed_monsters = killed_monsters + 1;
WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // FIXME: reliable broadcast
SUB_UseTargets ();
remove (self);
};
void(vector p) boss_missile =
{
local vector offang;
local vector org, vec, d;
local float t;
offang = vectoangles (self.enemy.origin - self.origin);
makevectors (offang);
org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
// lead the player on hard mode
if (skill > 1)
{
t = vlen(self.enemy.origin - org) / 300;
vec = self.enemy.velocity;
vec_z = 0;
d = self.enemy.origin + t * vec;
}
else
{
d = self.enemy.origin;
}
vec = normalize (d - org);
launch_spike (org, vec);
setmodel (newmis, "progs/lavaball.mdl");
newmis.avelocity = '200 100 300';
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
newmis.velocity = vec*300;
newmis.touch = T_MissileTouch; // rocket explosion
sound (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);
// check for dead enemy
if (self.enemy.health <= 0)
boss_idle1 ();
};
void() boss_awake =
{
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
self.takedamage = DAMAGE_NO;
setmodel (self, "progs/boss.mdl");
setsize (self, '-128 -128 -24', '128 128 256');
if (skill == 0)
self.health = 1;
else
self.health = 3;
self.enemy = activator;
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
self.yaw_speed = 20;
boss_rise1 ();
};
/*QUAKED monster_boss (1 0 0) (-128 -128 -24) (128 128 256)
*/
void() monster_boss =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/boss.mdl");
precache_model ("progs/lavaball.mdl");
precache_sound ("weapons/rocket1i.wav");
precache_sound ("boss1/out1.wav");
precache_sound ("boss1/sight1.wav");
precache_sound ("misc/power.wav");
precache_sound ("boss1/throw.wav");
precache_sound ("boss1/pain.wav");
precache_sound ("boss1/death.wav");
total_monsters = total_monsters + 1;
self.use = boss_awake;
};
//===========================================================================
entity le1, le2;
float lightning_end;
void() lightning_fire =
{
local vector p1, p2;
if (time >= lightning_end)
{ // done here, put the terminals back up
self = le1;
door_go_down ();
self = le2;
door_go_down ();
return;
}
p1 = (le1.mins + le1.maxs) * 0.5;
p1_z = le1.absmin_z - 16;
p2 = (le2.mins + le2.maxs) * 0.5;
p2_z = le2.absmin_z - 16;
// compensate for length of bolt
p2 = p2 - normalize(p2-p1)*100;
self.nextthink = time + 0.1;
self.think = lightning_fire;
WriteByte (MSG_ALL, SVC_TEMPENTITY);
WriteByte (MSG_ALL, TE_LIGHTNING3);
WriteEntity (MSG_ALL, world);
WriteCoord (MSG_ALL, p1_x);
WriteCoord (MSG_ALL, p1_y);
WriteCoord (MSG_ALL, p1_z);
WriteCoord (MSG_ALL, p2_x);
WriteCoord (MSG_ALL, p2_y);
WriteCoord (MSG_ALL, p2_z);
};
void() lightning_use =
{
if (lightning_end >= time + 1)
return;
le1 = find( world, target, "lightning");
le2 = find( le1, target, "lightning");
if (!le1 || !le2)
{
dprint ("missing lightning targets\n");
return;
}
if (
(le1.state != STATE_TOP && le1.state != STATE_BOTTOM)
|| (le2.state != STATE_TOP && le2.state != STATE_BOTTOM)
|| (le1.state != le2.state) )
{
// dprint ("not aligned\n");
return;
}
// don't let the electrodes go back up until the bolt is done
le1.nextthink = -1;
le2.nextthink = -1;
lightning_end = time + 1;
sound (self, CHAN_VOICE, "misc/power.wav", 1, ATTN_NORM);
lightning_fire ();
// advance the boss pain if down
self = find (world, classname, "monster_boss");
if (!self)
return;
self.enemy = activator;
if (le1.state == STATE_TOP && self.health > 0)
{
sound (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM);
self.health = self.health - 1;
if (self.health >= 2)
boss_shocka1();
else if (self.health == 1)
boss_shockb1();
else if (self.health == 0)
boss_shockc1();
}
};
/*QUAKED event_lightning (0 1 1) (-16 -16 -16) (16 16 16)
Just for boss level.
*/
void() event_lightning =
{
self.use = lightning_use;
};

141
BUTTONS.QC Normal file
View File

@ -0,0 +1,141 @@
// button and multiple button
void() button_wait;
void() button_return;
void() button_wait =
{
self.state = STATE_TOP;
self.nextthink = self.ltime + self.wait;
self.think = button_return;
activator = self.enemy;
SUB_UseTargets();
self.frame = 1; // use alternate textures
};
void() button_done =
{
self.state = STATE_BOTTOM;
};
void() button_return =
{
self.state = STATE_DOWN;
SUB_CalcMove (self.pos1, self.speed, button_done);
self.frame = 0; // use normal textures
if (self.health)
self.takedamage = DAMAGE_YES; // can be shot again
};
void() button_blocked =
{ // do nothing, just don't ome all the way back out
};
void() button_fire =
{
if (self.state == STATE_UP || self.state == STATE_TOP)
return;
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
self.state = STATE_UP;
SUB_CalcMove (self.pos2, self.speed, button_wait);
};
void() button_use =
{
self.enemy = activator;
button_fire ();
};
void() button_touch =
{
if (other.classname != "player")
return;
self.enemy = other;
button_fire ();
};
void() button_killed =
{
self.enemy = damage_attacker;
self.health = self.max_health;
self.takedamage = DAMAGE_NO; // wil be reset upon return
button_fire ();
};
/*QUAKED func_button (0 .5 .8) ?
When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again.
"angle" determines the opening direction
"target" all entities with a matching targetname will be used
"speed" override the default 40 speed
"wait" override the default 1 second wait (-1 = never return)
"lip" override the default 4 pixel lip remaining at end of move
"health" if set, the button must be killed instead of touched
"sounds"
0) steam metal
1) wooden clunk
2) metallic click
3) in-out
*/
void() func_button =
{
local float gtemp, ftemp;
if (self.sounds == 0)
{
precache_sound ("buttons/airbut1.wav");
self.noise = "buttons/airbut1.wav";
}
if (self.sounds == 1)
{
precache_sound ("buttons/switch21.wav");
self.noise = "buttons/switch21.wav";
}
if (self.sounds == 2)
{
precache_sound ("buttons/switch02.wav");
self.noise = "buttons/switch02.wav";
}
if (self.sounds == 3)
{
precache_sound ("buttons/switch04.wav");
self.noise = "buttons/switch04.wav";
}
SetMovedir ();
self.movetype = MOVETYPE_PUSH;
self.solid = SOLID_BSP;
setmodel (self, self.model);
self.blocked = button_blocked;
self.use = button_use;
if (self.health)
{
self.max_health = self.health;
self.th_die = button_killed;
self.takedamage = DAMAGE_YES;
}
else
self.touch = button_touch;
if (!self.speed)
self.speed = 40;
if (!self.wait)
self.wait = 1;
if (!self.lip)
self.lip = 4;
self.state = STATE_BOTTOM;
self.pos1 = self.origin;
self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
};

145
BUZZSAW.QC Normal file
View File

@ -0,0 +1,145 @@
// buzzsaw.qc
$skin buzzsaw
$frame buzzsaw
$frame bzzrot01 bzzrot02 bzzrot03 bzzrot04 bzzrot05 bzzrot06
void() buzzsaw_stand1 = [ $buzzsaw, buzzsaw_stand1 ]
{
if ( self.pain_finished < time)
{
sound ( self, CHAN_VOICE, "buzz/buzz1.wav", 0.2, ATTN_NORM);
self.pain_finished = time + 1;
}
self.angles_x = self.angles_x - 60;
self.avelocity_x = 60;
};
void() buzzsaw_fly =
{
local vector dir;
if ( self.pain_finished < time)
{
sound ( self, CHAN_VOICE, "buzz/buzz1.wav", 0.2, ATTN_NORM);
self.pain_finished = time + 1;
}
dir = self.goalentity.origin - self.origin;
dir = normalize (dir);
dir = dir * self.speed;
setorigin (self, self.origin + dir);
self.angles_x = self.angles_x - 60;
self.avelocity_x = 60;
};
/*
void() buzzsaw_fly1 = [ $bzzrot01, buzzsaw_fly2 ] { buzzsaw_fly(); };
void() buzzsaw_fly2 = [ $bzzrot02, buzzsaw_fly3 ] { buzzsaw_fly(); };
void() buzzsaw_fly3 = [ $bzzrot03, buzzsaw_fly4 ] { buzzsaw_fly(); };
void() buzzsaw_fly4 = [ $bzzrot04, buzzsaw_fly5 ] { buzzsaw_fly(); };
void() buzzsaw_fly5 = [ $bzzrot05, buzzsaw_fly6 ] { buzzsaw_fly(); };
void() buzzsaw_fly6 = [ $bzzrot06, buzzsaw_fly1 ] { buzzsaw_fly(); };
*/
void() buzzsaw_fly1 = [ $bzzrot01, buzzsaw_fly1 ] { buzzsaw_fly(); };
void() buzzsaw_touch =
{
local vector sprayDir;
if ( other.classname == "player" || other.flags & FL_MONSTER)
{
if ( self.attack_finished < time )
{
sound (self, CHAN_WEAPON, "buzz/buzz.wav", 1, ATTN_NORM);
self.attack_finished = time + 2;
}
T_Damage (other, self, self, self.currentammo);
sprayDir = normalize(self.goalentity.origin - self.origin);
sprayDir = sprayDir * 200;
SpawnMeatSpray ( self.origin, sprayDir);
other.velocity = sprayDir;
other.velocity_z = 200;
}
};
void() buzzsaw_use =
{
self.touch = buzzsaw_touch;
if (self.target)
{
self.movetarget = find(world, targetname, self.target);
self.goalentity = self.movetarget;
self.th_stand = buzzsaw_fly1;
self.th_walk = buzzsaw_fly1;
self.th_run = buzzsaw_fly1;
self.think = buzzsaw_fly1;
self.nextthink = time + 0.1;
}
else
{
self.nextthink = time + 0.1;
self.think = buzzsaw_stand1;
}
self.use = SUB_Null;
};
/*QUAKED buzzsaw (0 .5 .8) (-18 -18 -18) (18 18 18) Vertical
The buzzsaw trap.
currentammo: amount of damage for each contact. (default 10)
speed: speed that it will follow it's path. (default 10)
Use the angle buttons to point the buzzsaw in the direction it
should face.
Place on a monster path if you want it to move.
If it is targeted, it will wait until triggered to activate.
It will not damage players until activated.
*/
void() buzzsaw =
{
precache_model ("progs/buzzsaw.mdl");
precache_sound ("buzz/buzz.wav");
precache_sound ("buzz/buzz1.wav");
setmodel (self, "progs/buzzsaw.mdl");
self.takedamage = DAMAGE_NO;
self.solid = SOLID_TRIGGER;
self.movetype = MOVETYPE_FLY;
if(self.angles_y == 0 || self.angles_y == 180)
setsize (self, '-18 0 -18', '18 0 18');
else if(self.angles_y == 90 || self.angles_y == 270)
setsize (self, '0 -18 -18', '0 18 18');
else
objerror ("Buzzsaw: Not at 90 degree angle!");
setorigin (self, self.origin);
if (!self.speed)
self.speed = 10;
if (!self.currentammo)
self.currentammo = 10;
self.pain_finished = time + random()*2;
if (!self.targetname)
{
self.think = buzzsaw_use;
self.nextthink = time + 0.2;
}
else
{
self.use = buzzsaw_use;
}
};

1825
CLIENT.QC Normal file

File diff suppressed because it is too large Load Diff

376
COMBAT.QC Normal file
View File

@ -0,0 +1,376 @@
// combat.qc
float IsExplosionDamage;
void() T_MissileTouch;
void() info_player_start;
void(entity targ, entity attacker) ClientObituary;
void() monster_death_use;
//============================================================================
/*
============
CanDamage
Returns true if the inflictor can directly damage the target. Used for
explosions and melee attacks.
============
*/
float(entity targ, entity inflictor) CanDamage =
{
// bmodels need special checking because their origin is 0,0,0
if (targ.movetype == MOVETYPE_PUSH)
{
traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
if (trace_fraction == 1)
return TRUE;
if (trace_ent == targ)
return TRUE;
return FALSE;
}
traceline(inflictor.origin, targ.origin, TRUE, self);
if (trace_fraction == 1)
return TRUE;
traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
if (trace_fraction == 1)
return TRUE;
traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
if (trace_fraction == 1)
return TRUE;
traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
if (trace_fraction == 1)
return TRUE;
traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
if (trace_fraction == 1)
return TRUE;
return FALSE;
};
/*
============
Killed
============
*/
void(entity targ, entity attacker) Killed =
{
local entity oself;
oself = self;
self = targ;
if (self.health < -99)
self.health = -99; // don't let sbar look bad if a player
if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
{ // doors, triggers, etc
self.th_die ();
self = oself;
return;
}
self.enemy = attacker;
// bump the monster counter
if (self.flags & FL_MONSTER)
{
killed_monsters = killed_monsters + 1;
WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
}
// PGM - guarantee gib if killed by buzzsaw.
if (attacker.classname == "buzzsaw" ||
attacker.classname == "Vengeance" ||
attacker.classname == "pendulum")
self.health = -99;
// PGM - gravity fix!
self.gravity = 1.0;
ClientObituary(self, attacker);
self.takedamage = DAMAGE_NO;
self.touch = SUB_Null;
monster_death_use();
self.th_die ();
self = oself;
};
// ====
// Function prototype for shield impact handler.
// ====
float(entity targ, entity inflictor, entity attacker, float damage) shield_hit;
/*
============
T_Damage
The damage is coming from inflictor, but get mad at attacker
This should be the only function that ever reduces health.
============
*/
void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
{
local vector dir;
local entity oldself;
local float save;
local float take;
if (!targ.takedamage)
return;
if (targ.classname == "trigger_explosion")
{
if ( IsExplosionDamage != 1)
return;
}
IsExplosionDamage = 0;
if (targ.items2 & IT2_SHIELD)
{
// Allow some damage to pass through.
damage = shield_hit(targ, inflictor, attacker, damage);
if (damage == 0)
return;
}
// used by buttons and triggers to set activator for target firing
damage_attacker = attacker;
// check for quad damage powerup on the attacker
if (attacker.super_damage_finished > time)
damage = damage * 4;
// rune power up (Black Magic)
if (deathmatch)
damage = RuneApplyBlack(damage, attacker);
// save damage based on the target's armor level
//ZOID--
if (TeamArmorDam(targ, inflictor, attacker, damage))
save = ceil(targ.armortype*damage);
else
save = 0;
//--ZOID
if (save >= targ.armorvalue)
{
save = targ.armorvalue;
targ.armortype = 0; // lost all armor
targ.items2 = targ.items2 -
(targ.items2 & (IT2_ARMOR1 | IT2_ARMOR2 | IT2_ARMOR3));
}
targ.armorvalue = targ.armorvalue - save;
take = ceil(damage-save);
// add to the damage total for clients, which will be sent as a single
// message at the end of the frame
// FIXME: remove after combining shotgun blasts?
if (targ.flags & FL_CLIENT)
{
targ.dmg_take = targ.dmg_take + take;
targ.dmg_save = targ.dmg_save + save;
targ.dmg_inflictor = inflictor;
}
// figure momentum add
if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
{
dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
dir = normalize(dir);
targ.velocity = targ.velocity + dir*damage*8;
}
// check for godmode or invincibility
if (targ.flags & FL_GODMODE)
return;
if (targ.invincible_finished >= time)
{
if (targ.invincible_sound < time)
{
sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
targ.invincible_sound = time + 2;
}
return;
}
// team play damage avoidance
// if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) )
// return;
//ZOID--
if (!TeamHealthDam(targ, inflictor, attacker, damage))
return; // same team
//--ZOID
// rune power up (Earth Magic)
if (deathmatch)
take = RuneApplyEarth(take, targ);
// do the damage
targ.health = targ.health - take;
if (targ.health <= 0)
{
Killed (targ, attacker);
return;
}
// react to the damage
oldself = self;
self = targ;
if ( (self.flags & FL_MONSTER) && attacker != world)
{
// get mad unless of the same class (except for soldiers)
if (self != attacker && attacker != self.enemy)
{
if ( (self.classname != attacker.classname)
|| (self.classname == "monster_army" ) )
{
if ( self.classname != "monster_dragon")
{
if (self.enemy.classname == "player")
self.oldenemy = self.enemy;
self.enemy = attacker;
FoundTarget ();
}
}
}
}
if (self.th_pain)
{
self.th_pain (attacker, take);
// nightmare mode monsters don't go into pain frames often
if (skill == 3)
self.pain_finished = time + 5;
}
self = oldself;
};
/*
============
T_EELZap
============
*/
void(entity inflictor, entity attacker, float damage) T_EELZap =
{
local float points;
local entity head;
local vector org;
head = findradius(inflictor.origin, damage+40);
while (head)
{
if (head.takedamage)
{
org = head.origin + (head.mins + head.maxs)*0.5;
points = 0.5*vlen (inflictor.origin - org);
if (points < 0)
points = 0;
points = damage - points;
if (head == attacker)
points = points * 0.5;
if (points > 0)
{
if (CanDamage (head, inflictor))
{ // eels take no damage from this attack
if (head.classname != "monster_eel" &&
(head.flags & FL_INWATER))
T_Damage (head, inflictor, attacker, points);
}
}
}
head = head.chain;
}
};
/*
============
T_RadiusDamage
============
*/
void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
{
local float points;
local entity head;
local vector org;
IsExplosionDamage = 1;
head = findradius(inflictor.origin, damage+40);
while (head)
{
if (head != ignore)
{
if (head.takedamage)
{
org = head.origin + (head.mins + head.maxs)*0.5;
points = 0.5*vlen (inflictor.origin - org);
if (points < 0)
points = 0;
points = damage - points;
if (head == attacker)
points = points * 0.5;
if (points > 0)
{
if (CanDamage (head, inflictor))
{ // shambler takes half damage from all explosions
if (head.classname == "monster_shambler")
T_Damage (head, inflictor, attacker, points*0.5);
else
T_Damage (head, inflictor, attacker, points);
}
}
}
}
head = head.chain;
}
};
/*
============
T_BeamDamage
============
*/
void(entity attacker, float damage) T_BeamDamage =
{
local float points;
local entity head;
head = findradius(attacker.origin, damage+40);
while (head)
{
if (head.takedamage)
{
points = 0.5*vlen (attacker.origin - head.origin);
if (points < 0)
points = 0;
points = damage - points;
if (head == attacker)
points = points * 0.5;
if (points > 0)
{
if (CanDamage (head, attacker))
{
if (head.classname == "monster_shambler")
T_Damage (head, attacker, attacker, points*0.5);
else
T_Damage (head, attacker, attacker, points);
}
}
}
head = head.chain;
}
};

790
DEFS.QC Normal file
View File

@ -0,0 +1,790 @@
/*
==============================================================================
SOURCE FOR GLOBALVARS_T C STRUCTURE
==============================================================================
*/
//
// system globals
//
entity self;
entity other;
entity world;
float time;
float frametime;
float force_retouch; // force all entities to touch triggers
// next frame. this is needed because
// non-moving things don't normally scan
// for triggers, and when a trigger is
// created (like a teleport trigger), it
// needs to catch everything.
// decremented each frame, so set to 2
// to guarantee everything is touched
string mapname;
float deathmatch;
float coop;
float teamplay;
//float norandom; // ROGUE: disable random respawn of powerups.
float serverflags; // propagated from level to level, used to
// keep track of completed episodes
float total_secrets;
float total_monsters;
float found_secrets; // number of secrets found
float killed_monsters; // number of monsters killed
// spawnparms are used to encode information about clients across server
// level changes
float parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8, parm9, parm10, parm11, parm12, parm13, parm14, parm15, parm16;
//
// global variables set by built in functions
//
vector v_forward, v_up, v_right; // set by makevectors()
// set by traceline / tracebox
float trace_allsolid;
float trace_startsolid;
float trace_fraction;
vector trace_endpos;
vector trace_plane_normal;
float trace_plane_dist;
entity trace_ent;
float trace_inopen;
float trace_inwater;
entity msg_entity; // destination of single entity writes
//
// required prog functions
//
void() main; // only for testing
void() StartFrame;
void() PlayerPreThink;
void() PlayerPostThink;
void() ClientKill;
void() ClientConnect;
void() PutClientInServer; // call after setting the parm1... parms
void() ClientDisconnect;
void() SetNewParms; // called when a client first connects to
// a server. sets parms so they can be
// saved off for restarts
void() SetChangeParms; // call to set parms for self so they can
// be saved for a level transition
//================================================
void end_sys_globals; // flag for structure dumping
//================================================
/*
==============================================================================
SOURCE FOR ENTVARS_T C STRUCTURE
==============================================================================
*/
//
// system fields (*** = do not set in prog code, maintained by C code)
//
.float modelindex; // *** model index in the precached list
.vector absmin, absmax; // *** origin + mins / maxs
.float ltime; // local time for entity
.float movetype;
.float solid;
.vector origin; // ***
.vector oldorigin; // ***
.vector velocity;
.vector angles;
.vector avelocity;
.vector punchangle; // temp angle adjust from damage or recoil
.string classname; // spawn function
.string model;
.float frame;
.float skin;
.float effects;
.vector mins, maxs; // bounding box extents reletive to origin
.vector size; // maxs - mins
.void() touch;
.void() use;
.void() think;
.void() blocked; // for doors or plats, called when can't push other
.float nextthink;
.entity groundentity;
// stats
.float health;
.float frags;
.float weapon; // one of the IT_SHOTGUN, etc flags
.string weaponmodel;
.float weaponframe;
.float currentammo;
.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
.float items; // bit flags
.float takedamage;
.entity chain;
.float deadflag;
.vector view_ofs; // add to origin to get eye point
.float button0; // fire
.float button1; // use
.float button2; // jump
.float impulse; // weapon changes
.float fixangle;
.vector v_angle; // view / targeting angle for players
.float idealpitch; // calculated pitch angle for lookup up slopes
.string netname;
.entity enemy;
.float flags;
.float colormap;
.float team;
.float max_health; // players maximum health is stored here
.float teleport_time; // don't back up
.float armortype; // save this fraction of incoming damage
.float armorvalue;
.float waterlevel; // 0 = not in, 1 = feet, 2 = wast, 3 = eyes
.float watertype; // a contents value
.float ideal_yaw;
.float yaw_speed;
.entity aiment;
.entity goalentity; // a movetarget or an enemy
.float spawnflags;
.string target;
.string targetname;
// damage is accumulated through a frame. and sent as one single
// message, so the super shotgun doesn't generate huge messages
.float dmg_take;
.float dmg_save;
.entity dmg_inflictor;
.entity owner; // who launched a missile
.vector movedir; // mostly for doors, but also used for waterjump
.string message; // trigger messages
.float sounds; // either a cd track number or sound number
.string noise, noise1, noise2, noise3; // contains names of wavs to play
//================================================
void end_sys_fields; // flag for structure dumping
//================================================
.float items2;
//.float new_weapon;
//.float new_items;
.float ammo_shells1, ammo_nails1, ammo_rockets1, ammo_cells1;
.float ammo_lava_nails;
.float ammo_multi_rockets;
.float ammo_plasma;
.float gravity;
/*
==============================================================================
VARS NOT REFERENCED BY C CODE
==============================================================================
*/
//
// constants
//
float FALSE = 0;
float TRUE = 1;
// edict.flags
float FL_FLY = 1;
float FL_SWIM = 2;
float FL_CLIENT = 8; // set for all client edicts
float FL_INWATER = 16; // for enter / leave water splash
float FL_MONSTER = 32;
float FL_GODMODE = 64; // player cheat
float FL_NOTARGET = 128; // player cheat
float FL_ITEM = 256; // extra wide size for bonus items
float FL_ONGROUND = 512; // standing on something
float FL_PARTIALGROUND = 1024; // not all corners are valid
float FL_WATERJUMP = 2048; // player jumping out of water
float FL_JUMPRELEASED = 4096; // for jump debouncing
// edict.movetype values
float MOVETYPE_NONE = 0; // never moves
//float MOVETYPE_ANGLENOCLIP = 1;
//float MOVETYPE_ANGLECLIP = 2;
float MOVETYPE_WALK = 3; // players only
float MOVETYPE_STEP = 4; // discrete, not real time unless fall
float MOVETYPE_FLY = 5;
float MOVETYPE_TOSS = 6; // gravity
float MOVETYPE_PUSH = 7; // no clip to world, push and crush
float MOVETYPE_NOCLIP = 8;
float MOVETYPE_FLYMISSILE = 9; // fly with extra size against monsters
float MOVETYPE_BOUNCE = 10;
float MOVETYPE_BOUNCEMISSILE = 11; // bounce with extra size
// edict.solid values
float SOLID_NOT = 0; // no interaction with other objects
float SOLID_TRIGGER = 1; // touch on edge, but not blocking
float SOLID_BBOX = 2; // touch on edge, block
float SOLID_SLIDEBOX = 3; // touch on edge, but not an onground
float SOLID_BSP = 4; // bsp clip, touch on edge, block
// range values
float RANGE_MELEE = 0;
float RANGE_NEAR = 1;
float RANGE_MID = 2;
float RANGE_FAR = 3;
// deadflag values
float DEAD_NO = 0;
float DEAD_DYING = 1;
float DEAD_DEAD = 2;
float DEAD_RESPAWNABLE = 3;
// takedamage values
float DAMAGE_NO = 0;
float DAMAGE_YES = 1;
float DAMAGE_AIM = 2;
// items
float IT_AXE = 2048; // 1
float IT_SHOTGUN = 1;
float IT_SUPER_SHOTGUN = 2;
float IT_NAILGUN = 4;
float IT_SUPER_NAILGUN = 8;
float IT_GRENADE_LAUNCHER = 16;
float IT_ROCKET_LAUNCHER = 32;
float IT_LIGHTNING = 64; // 8
float IT_SHELLS = 128;
float IT_NAILS = 256;
float IT_ROCKETS = 512;
float IT_CELLS = 1024;
float IT_LAVA_NAILGUN = 4096;
float IT_LAVA_SUPER_NAILGUN = 8192;
float IT_MULTI_GRENADE = 16384; //15
float IT_MULTI_ROCKET = 32768;
float IT_PLASMA_GUN = 65536;
float IT_KEY1 = 131072;
float IT_KEY2 = 262144;
float IT_INVISIBILITY = 524288;
float IT_INVULNERABILITY = 1048576;
float IT_SUIT = 2097152;
float IT_QUAD = 4194304; //23
//ZOID --
float IT_GRAPPLE = 8388608; // grapple overload, hope it
//-- ZOID // doesn't mess things up!
float IT2_ARMOR1 = 1; //24
float IT2_ARMOR2 = 2;
float IT2_ARMOR3 = 4;
float IT2_LAVA_NAILS = 8;
float IT2_PLASMA_AMMO = 16;
float IT2_MULTI_ROCKETS = 32; //29
float IT2_SHIELD = 64;
float IT2_ANTIGRAV = 128;
float IT2_SUPERHEALTH = 256; //32
float IT2_EARTHQUAKE = 512;
float IT2_V_SPHERE = 1024;
// point content values
float CONTENT_EMPTY = -1;
float CONTENT_SOLID = -2;
float CONTENT_WATER = -3;
float CONTENT_SLIME = -4;
float CONTENT_LAVA = -5;
float CONTENT_SKY = -6;
float STATE_TOP = 0;
float STATE_BOTTOM = 1;
float STATE_UP = 2;
float STATE_DOWN = 3;
vector VEC_ORIGIN = '0 0 0';
vector VEC_HULL_MIN = '-16 -16 -24';
vector VEC_HULL_MAX = '16 16 32';
vector VEC_HULL2_MIN = '-32 -32 -24';
vector VEC_HULL2_MAX = '32 32 64';
// protocol bytes
float SVC_UPDATESTAT = 3; // pgm black magic
float SVC_TEMPENTITY = 23;
float SVC_KILLEDMONSTER = 27;
float SVC_FOUNDSECRET = 28;
float SVC_INTERMISSION = 30;
float SVC_FINALE = 31;
float SVC_CDTRACK = 32;
float SVC_SELLSCREEN = 33;
float SVC_CUTSCENE = 34;
float STAT_TOTALMONSTERS = 12; // pgm black magic
float TE_SPIKE = 0;
float TE_SUPERSPIKE = 1;
float TE_GUNSHOT = 2;
float TE_EXPLOSION = 3;
float TE_TAREXPLOSION = 4;
float TE_LIGHTNING1 = 5;
float TE_LIGHTNING2 = 6;
float TE_WIZSPIKE = 7;
float TE_KNIGHTSPIKE = 8;
float TE_LIGHTNING3 = 9;
float TE_LAVASPLASH = 10;
float TE_TELEPORT = 11;
float TE_EXPLOSION2 = 12;
float TE_BEAM = 13;
// sound channels
// channel 0 never willingly overrides
// other channels (1-7) allways override a playing sound on that channel
float CHAN_AUTO = 0;
float CHAN_WEAPON = 1;
float CHAN_VOICE = 2;
float CHAN_ITEM = 3;
float CHAN_BODY = 4;
float ATTN_NONE = 0;
float ATTN_NORM = 1;
float ATTN_IDLE = 2;
float ATTN_STATIC = 3;
// update types
float UPDATE_GENERAL = 0;
float UPDATE_STATIC = 1;
float UPDATE_BINARY = 2;
float UPDATE_TEMP = 3;
// entity effects
float EF_BRIGHTFIELD = 1;
float EF_MUZZLEFLASH = 2;
float EF_BRIGHTLIGHT = 4;
float EF_DIMLIGHT = 8;
// messages
float MSG_BROADCAST = 0; // unreliable to all
float MSG_ONE = 1; // reliable to one (msg_entity)
float MSG_ALL = 2; // reliable to all
float MSG_INIT = 3; // write to the init string
//================================================
//
// globals
//
float movedist;
float gameover; // set when a rule exits
string string_null; // null string, nothing should be held here
float empty_float;
entity newmis; // launch_spike sets this after spawning it
entity activator; // the entity that activated a trigger or brush
entity damage_attacker; // set by T_Damage
float framecount;
float skill;
// rogue globals!
float earthquake_active;
float earthquake_intensity;
float cutscene_running;
entity tag_token_owner;
//================================================
//
// world fields (FIXME: make globals)
//
.string wad;
.string map;
.float worldtype; // 0=medieval 1=metal 2=base
//================================================
.string killtarget;
//
// quakeed fields
//
.float light_lev; // not used by game, but parsed by light util
.float style;
//
// monster ai
//
.void() th_stand;
.void() th_walk;
.void() th_run;
.void() th_missile;
.void() th_melee;
.void(entity attacker, float damage) th_pain;
.void() th_die;
.entity oldenemy; // mad at this player before taking damage
.float speed;
.float lefty;
.float search_time;
.float attack_state;
float AS_STRAIGHT = 1;
float AS_SLIDING = 2;
float AS_MELEE = 3;
float AS_MISSILE = 4;
//
// player only fields
//
.float walkframe;
.float attack_finished;
.float pain_finished;
.float invincible_finished;
.float invisible_finished;
.float super_damage_finished;
.float radsuit_finished;
.float invincible_time, invincible_sound;
.float invisible_time, invisible_sound;
.float super_time, super_sound;
.float rad_time;
.float fly_sound;
.float shield_finished, antigrav_finished;
.float shield_time, antigrav_time;
.entity shield_entity;
.float axhitme;
.float show_hostile; // set to time+0.2 whenever a client fires a
// weapon or takes damage. Used to alert
// monsters that otherwise would let the player go
.float jump_flag; // player jump flag
.float swim_flag; // player swimming sound flag
.float air_finished; // when time > air_finished, start drowning
.float bubble_count; // keeps track of the number of bubbles
.string deathtype; // keeps track of how the player died
//
// object stuff
//
.string mdl;
.vector mangle; // angle at start
.vector oldorigin; // only used by secret door
.float t_length, t_width;
//
// doors, etc
//
.vector dest, dest1, dest2;
.float wait; // time from firing to restarting
.float delay; // time from activation to firing
.entity trigger_field; // door's trigger entity
.string noise4;
//
// monsters
//
.float pausetime;
.entity movetarget;
//
// doors
//
.float aflag;
.float dmg; // damage done by door when hit
//
// misc
//
.float cnt; // misc flag
//
// subs
//
.void() think1;
.vector finaldest, finalangle;
//
// triggers
//
.float count; // for counting triggers
//
// plats / doors / buttons
//
.float lip;
.float state;
.vector pos1, pos2; // top and bottom positions
.float height;
//
// sounds
//
.float waitmin, waitmax;
.float distance;
.float volume;
//
// elevator fields
//
.float elevatorLastUse;
.float elevatorOnFloor;
.float elevatorToFloor;
.vector elevatorDestination;
//
// plat2 fields
//
.float plat2Called;
.float plat2LastMove;
.float plat2GoTime;
.float plat2GoTo;
//
// new AI fields
//
.float orbitPosition;
//
// dragon specific fields
//
.float playerInRoom;
.float playerInTransit;
.float dragonInRoom;
.float dragonInTransit;
.float dragonAttacking;
.float dragonPainSequence;
.vector dragonLastVelocity;
//
// Other Rogue Fields
//
.float AGping;
.float childrenSpawned;
.float ltrailLastUsed;
.float shield_death_time;
.float shieldSoundTime;
.float dragonDeathState;
.float tag_frags;
.float tag_message_time;
//===========================================================================
//
// builtin functions
//
void(vector ang) makevectors = #1; // sets v_forward, etc globals
void(entity e, vector o) setorigin = #2;
void(entity e, string m) setmodel = #3; // set movetype and solid first
void(entity e, vector min, vector max) setsize = #4;
// #5 was removed
void() break = #6;
float() random = #7; // returns 0 - 1
void(entity e, float chan, string samp, float vol, float atten) sound = #8;
vector(vector v) normalize = #9;
void(string e) error = #10;
void(string e) objerror = #11;
float(vector v) vlen = #12;
float(vector v) vectoyaw = #13;
entity() spawn = #14;
void(entity e) remove = #15;
// sets trace_* globals
// nomonsters can be:
// An entity will also be ignored for testing if forent == test,
// forent->owner == test, or test->owner == forent
// a forent of world is ignored
void(vector v1, vector v2, float nomonsters, entity forent) traceline = #16;
entity() checkclient = #17; // returns a client to look for
entity(entity start, .string fld, string match) find = #18;
string(string s) precache_sound = #19;
string(string s) precache_model = #20;
void(entity client, string s)stuffcmd = #21;
entity(vector org, float rad) findradius = #22;
void(string s) bprint = #23;
void(entity client, string s) sprint = #24;
void(string s) dprint = #25;
string(float f) ftos = #26;
string(vector v) vtos = #27;
void() coredump = #28; // prints all edicts
void() traceon = #29; // turns statment trace on
void() traceoff = #30;
void(entity e) eprint = #31; // prints an entire edict
float(float yaw, float dist) walkmove = #32; // returns TRUE or FALSE
// #33 was removed
float(float yaw, float dist) droptofloor= #34; // TRUE if landed on floor
void(float style, string value) lightstyle = #35;
float(float v) rint = #36; // round to nearest int
float(float v) floor = #37; // largest integer <= v
float(float v) ceil = #38; // smallest integer >= v
// #39 was removed
float(entity e) checkbottom = #40; // true if self is on ground
float(vector v) pointcontents = #41; // returns a CONTENT_*
// #42 was removed
float(float f) fabs = #43;
vector(entity e, float speed) aim = #44; // returns the shooting vector
float(string s) cvar = #45; // return cvar.value
void(string s) localcmd = #46; // put string into local que
entity(entity e) nextent = #47; // for looping through all ents
void(vector o, vector d, float color, float count) particle = #48;// start a particle effect
void() ChangeYaw = #49; // turn towards self.ideal_yaw
// at self.yaw_speed
// #50 was removed
vector(vector v) vectoangles = #51;
//
// direct client message generation
//
void(float to, float f) WriteByte = #52;
void(float to, float f) WriteChar = #53;
void(float to, float f) WriteShort = #54;
void(float to, float f) WriteLong = #55;
void(float to, float f) WriteCoord = #56;
void(float to, float f) WriteAngle = #57;
void(float to, string s) WriteString = #58;
void(float to, entity s) WriteEntity = #59;
//
// broadcast client message generation
//
// void(float f) bWriteByte = #59;
// void(float f) bWriteChar = #60;
// void(float f) bWriteShort = #61;
// void(float f) bWriteLong = #62;
// void(float f) bWriteCoord = #63;
// void(float f) bWriteAngle = #64;
// void(string s) bWriteString = #65;
// void(entity e) bWriteEntity = #66;
void(float step) movetogoal = #67;
string(string s) precache_file = #68; // no effect except for -copy
void(entity e) makestatic = #69;
void(string s) changelevel = #70;
//#71 was removed
void(string var, string val) cvar_set = #72; // sets cvar.value
void(entity client, string s) centerprint = #73; // sprint, but in middle
void(vector pos, string samp, float vol, float atten) ambientsound = #74;
string(string s) precache_model2 = #75; // registered version only
string(string s) precache_sound2 = #76; // registered version only
string(string s) precache_file2 = #77; // registered version only
void(entity e) setspawnparms = #78; // set parm1... to the
// values at level start
// for coop respawn
//============================================================================
//
// subs.qc
//
void(vector tdest, float tspeed, void() func) SUB_CalcMove;
void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt;
void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove;
void() SUB_CalcMoveDone;
void() SUB_CalcAngleMoveDone;
void() SUB_Null;
void() SUB_UseTargets;
void() SUB_Remove;
//
// combat.qc
//
void(entity targ, entity inflictor, entity attacker, float damage) T_Damage;
float (entity e, float healamount, float ignore) T_Heal; // health function
float(entity targ, entity inflictor) CanDamage;
//
// new_items.qc
//
void(entity theEntity) UpdateAmmoCounts;
//
// dmatch.qc
//
void() tag_token_respawn;
void() tag_token_touch;
void() tag_token_drop;
// sphere.qc
void(entity ownerEntity) sphere_remove;

363
DEMON.QC Normal file
View File

@ -0,0 +1,363 @@
/*
==============================================================================
DEMON
==============================================================================
*/
$cd /raid/quake/id1/models/demon3
$scale 0.8
$origin 0 0 24
$base base
$skin base
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame stand10 stand11 stand12 stand13
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
$frame run1 run2 run3 run4 run5 run6
$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9 leap10
$frame leap11 leap12
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
$frame attacka1 attacka2 attacka3 attacka4 attacka5 attacka6 attacka7 attacka8
$frame attacka9 attacka10 attacka11 attacka12 attacka13 attacka14 attacka15
//============================================================================
void() Demon_JumpTouch;
void() demon1_stand1 =[ $stand1, demon1_stand2 ] {ai_stand();};
void() demon1_stand2 =[ $stand2, demon1_stand3 ] {ai_stand();};
void() demon1_stand3 =[ $stand3, demon1_stand4 ] {ai_stand();};
void() demon1_stand4 =[ $stand4, demon1_stand5 ] {ai_stand();};
void() demon1_stand5 =[ $stand5, demon1_stand6 ] {ai_stand();};
void() demon1_stand6 =[ $stand6, demon1_stand7 ] {ai_stand();};
void() demon1_stand7 =[ $stand7, demon1_stand8 ] {ai_stand();};
void() demon1_stand8 =[ $stand8, demon1_stand9 ] {ai_stand();};
void() demon1_stand9 =[ $stand9, demon1_stand10 ] {ai_stand();};
void() demon1_stand10 =[ $stand10, demon1_stand11 ] {ai_stand();};
void() demon1_stand11 =[ $stand11, demon1_stand12 ] {ai_stand();};
void() demon1_stand12 =[ $stand12, demon1_stand13 ] {ai_stand();};
void() demon1_stand13 =[ $stand13, demon1_stand1 ] {ai_stand();};
void() demon1_walk1 =[ $walk1, demon1_walk2 ] {
if (random() < 0.2)
sound (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE);
ai_walk(8);
};
void() demon1_walk2 =[ $walk2, demon1_walk3 ] {ai_walk(6);};
void() demon1_walk3 =[ $walk3, demon1_walk4 ] {ai_walk(6);};
void() demon1_walk4 =[ $walk4, demon1_walk5 ] {ai_walk(7);};
void() demon1_walk5 =[ $walk5, demon1_walk6 ] {ai_walk(4);};
void() demon1_walk6 =[ $walk6, demon1_walk7 ] {ai_walk(6);};
void() demon1_walk7 =[ $walk7, demon1_walk8 ] {ai_walk(10);};
void() demon1_walk8 =[ $walk8, demon1_walk1 ] {ai_walk(10);};
void() demon1_run1 =[ $run1, demon1_run2 ] {
if (random() < 0.2)
sound (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE);
ai_run(20);};
void() demon1_run2 =[ $run2, demon1_run3 ] {ai_run(15);};
void() demon1_run3 =[ $run3, demon1_run4 ] {ai_run(36);};
void() demon1_run4 =[ $run4, demon1_run5 ] {ai_run(20);};
void() demon1_run5 =[ $run5, demon1_run6 ] {ai_run(15);};
void() demon1_run6 =[ $run6, demon1_run1 ] {ai_run(36);};
void() demon1_jump1 =[ $leap1, demon1_jump2 ] {ai_face();};
void() demon1_jump2 =[ $leap2, demon1_jump3 ] {ai_face();};
void() demon1_jump3 =[ $leap3, demon1_jump4 ] {ai_face();};
void() demon1_jump4 =[ $leap4, demon1_jump5 ]
{
ai_face();
self.touch = Demon_JumpTouch;
makevectors (self.angles);
self.origin_z = self.origin_z + 1;
self.velocity = v_forward * 600 + '0 0 250';
if (self.flags & FL_ONGROUND)
self.flags = self.flags - FL_ONGROUND;
};
void() demon1_jump5 =[ $leap5, demon1_jump6 ] {};
void() demon1_jump6 =[ $leap6, demon1_jump7 ] {};
void() demon1_jump7 =[ $leap7, demon1_jump8 ] {};
void() demon1_jump8 =[ $leap8, demon1_jump9 ] {};
void() demon1_jump9 =[ $leap9, demon1_jump10 ] {};
void() demon1_jump10 =[ $leap10, demon1_jump1 ] {
self.nextthink = time + 3;
// if three seconds pass, assume demon is stuck and jump again
};
void() demon1_jump11 =[ $leap11, demon1_jump12 ] {};
void() demon1_jump12 =[ $leap12, demon1_run1 ] {};
void() demon1_atta1 =[ $attacka1, demon1_atta2 ] {ai_charge(4);};
void() demon1_atta2 =[ $attacka2, demon1_atta3 ] {ai_charge(0);};
void() demon1_atta3 =[ $attacka3, demon1_atta4 ] {ai_charge(0);};
void() demon1_atta4 =[ $attacka4, demon1_atta5 ] {ai_charge(1);};
void() demon1_atta5 =[ $attacka5, demon1_atta6 ] {ai_charge(2); Demon_Melee(200);};
void() demon1_atta6 =[ $attacka6, demon1_atta7 ] {ai_charge(1);};
void() demon1_atta7 =[ $attacka7, demon1_atta8 ] {ai_charge(6);};
void() demon1_atta8 =[ $attacka8, demon1_atta9 ] {ai_charge(8);};
void() demon1_atta9 =[ $attacka9, demon1_atta10] {ai_charge(4);};
void() demon1_atta10 =[ $attacka10, demon1_atta11] {ai_charge(2);};
void() demon1_atta11 =[ $attacka11, demon1_atta12] {Demon_Melee(-200);};
void() demon1_atta12 =[ $attacka12, demon1_atta13] {ai_charge(5);};
void() demon1_atta13 =[ $attacka13, demon1_atta14] {ai_charge(8);};
void() demon1_atta14 =[ $attacka14, demon1_atta15] {ai_charge(4);};
void() demon1_atta15 =[ $attacka15, demon1_run1] {ai_charge(4);};
void() demon1_pain1 =[ $pain1, demon1_pain2 ] {};
void() demon1_pain2 =[ $pain2, demon1_pain3 ] {};
void() demon1_pain3 =[ $pain3, demon1_pain4 ] {};
void() demon1_pain4 =[ $pain4, demon1_pain5 ] {};
void() demon1_pain5 =[ $pain5, demon1_pain6 ] {};
void() demon1_pain6 =[ $pain6, demon1_run1 ] {};
void(entity attacker, float damage) demon1_pain =
{
if (self.touch == Demon_JumpTouch)
return;
if (self.pain_finished > time)
return;
self.pain_finished = time + 1;
sound (self, CHAN_VOICE, "demon/dpain1.wav", 1, ATTN_NORM);
if (random()*200 > damage)
return; // didn't flinch
demon1_pain1 ();
};
void() demon1_die1 =[ $death1, demon1_die2 ] {
sound (self, CHAN_VOICE, "demon/ddeath.wav", 1, ATTN_NORM);};
void() demon1_die2 =[ $death2, demon1_die3 ] {};
void() demon1_die3 =[ $death3, demon1_die4 ] {};
void() demon1_die4 =[ $death4, demon1_die5 ] {};
void() demon1_die5 =[ $death5, demon1_die6 ] {};
void() demon1_die6 =[ $death6, demon1_die7 ]
{self.solid = SOLID_NOT;};
void() demon1_die7 =[ $death7, demon1_die8 ] {};
void() demon1_die8 =[ $death8, demon1_die9 ] {};
void() demon1_die9 =[ $death9, demon1_die9 ] {};
void() demon_die =
{
// check for gib
if (self.health < -80)
{
sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
ThrowHead ("progs/h_demon.mdl", self.health);
ThrowGib ("progs/gib1.mdl", self.health);
ThrowGib ("progs/gib1.mdl", self.health);
ThrowGib ("progs/gib1.mdl", self.health);
return;
}
// regular death
demon1_die1 ();
};
void() Demon_MeleeAttack =
{
demon1_atta1 ();
};
/*QUAKED monster_demon1 (1 0 0) (-32 -32 -24) (32 32 64) Ambush
*/
void() monster_demon1 =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/demon.mdl");
precache_model ("progs/h_demon.mdl");
precache_sound ("demon/ddeath.wav");
precache_sound ("demon/dhit2.wav");
precache_sound ("demon/djump.wav");
precache_sound ("demon/dpain1.wav");
precache_sound ("demon/idle1.wav");
precache_sound ("demon/sight2.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/demon.mdl");
setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
self.health = 300;
self.th_stand = demon1_stand1;
self.th_walk = demon1_walk1;
self.th_run = demon1_run1;
self.th_die = demon_die;
self.th_melee = Demon_MeleeAttack; // one of two attacks
self.th_missile = demon1_jump1; // jump attack
self.th_pain = demon1_pain;
walkmonster_start();
};
/*
==============================================================================
DEMON
==============================================================================
*/
/*
==============
CheckDemonMelee
Returns TRUE if a melee attack would hit right now
==============
*/
float() CheckDemonMelee =
{
if (enemy_range == RANGE_MELEE)
{ // FIXME: check canreach
self.attack_state = AS_MELEE;
return TRUE;
}
return FALSE;
};
/*
==============
CheckDemonJump
==============
*/
float() CheckDemonJump =
{
local vector dist;
local float d;
if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z
+ 0.75 * self.enemy.size_z)
return FALSE;
if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z
+ 0.25 * self.enemy.size_z)
return FALSE;
dist = self.enemy.origin - self.origin;
dist_z = 0;
d = vlen(dist);
if (d < 100)
return FALSE;
if (d > 200)
{
if (random() < 0.9)
return FALSE;
}
return TRUE;
};
float() DemonCheckAttack =
{
local vector vec;
// if close enough for slashing, go for it
if (CheckDemonMelee ())
{
self.attack_state = AS_MELEE;
return TRUE;
}
if (CheckDemonJump ())
{
self.attack_state = AS_MISSILE;
sound (self, CHAN_VOICE, "demon/djump.wav", 1, ATTN_NORM);
return TRUE;
}
return FALSE;
};
//===========================================================================
void(float side) Demon_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, "demon/dhit2.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() Demon_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)
{ // jump randomly to not get hung up
//dprint ("popjump\n");
self.touch = SUB_Null;
self.think = demon1_jump1;
self.nextthink = time + 0.1;
// self.velocity_x = (random() - 0.5) * 600;
// self.velocity_y = (random() - 0.5) * 600;
// self.velocity_z = 200;
// self.flags = self.flags - FL_ONGROUND;
}
return; // not on ground yet
}
self.touch = SUB_Null;
self.think = demon1_jump11;
self.nextthink = time + 0.1;
};

185
DMATCH.QC Normal file
View File

@ -0,0 +1,185 @@
// dmatch - general deathmatch additions
// =======================================
// =======================================
void() tag_token_respawn =
{
local entity spawnPoint;
local entity tagToken;
tagToken = find (world, classname, "dmatch_tag_token");
if(tagToken == world)
return;
spawnPoint = SelectSpawnPoint();
setorigin(tagToken, spawnPoint.origin);
tag_token_owner = world;
tagToken.solid = SOLID_TRIGGER;
tagToken.touch = tag_token_touch;
tagToken.think = SUB_Null;
tagToken.owner = world;
tagToken.tag_frags = 0;
droptofloor();
};
// =======================================
// =======================================
void() tag_token_fall =
{
self.tag_frags = 0;
self.think = tag_token_respawn;
self.nextthink = time + 30;
droptofloor();
};
// =======================================
// =======================================
void() tag_token_drop =
{
local entity tagToken;
tagToken = find (world, classname, "dmatch_tag_token");
if(tagToken == world)
return;
bprint ( tagToken.owner.netname );
bprint ( " lost the tag token!\n");
tagToken.tag_frags = 0;
tagToken.solid = SOLID_TRIGGER;
tagToken.owner = world;
tagToken.touch = tag_token_touch;
tagToken.think = tag_token_fall;
tagToken.nextthink = time + 0.1;
};
// =======================================
// =======================================
void() tag_token_think =
{
if ( self.owner.health > 0)
{
if ( self.tag_message_time < time )
{
bprint ( self.owner.netname );
bprint ( " has the tag token!\n");
self.tag_message_time = time + 30;
}
setorigin ( self, self.owner.origin + '0 0 48');
self.think = tag_token_think;
self.nextthink = time + 0.1;
}
else
{
tag_token_drop();
}
};
// =======================================
// =======================================
void() tag_token_touch =
{
if (other.classname != "player")
return;
tag_token_owner = other;
self.tag_frags = 0;
sound ( self, CHAN_AUTO, "runes/end1.wav", 1, ATTN_NORM);
bprint ( other.netname );
bprint ( " got the tag token!\n");
self.tag_message_time = time + 30;
self.owner = other;
self.solid = SOLID_NOT;
self.touch = SUB_Null;
self.think = tag_token_think;
self.nextthink = time + 0.1;
};
/*QUAKED dmatch_tag_token (1 1 0) (-16 -16 -16) (16 16 16)
The deathmatch tag token.
*/
void() dmatch_tag_token =
{
if ( cvar("teamplay") != TEAM_DMATCH_TAG )
{
remove (self);
return;
}
precache_model ("progs/sphere.mdl");
precache_sound ("runes/end1.wav");
setmodel(self, "progs/sphere.mdl");
self.skin = 1;
setsize (self, '-16 -16 -16', '16 16 16');
self.touch = tag_token_touch;
self.effects = self.effects | EF_DIMLIGHT;
StartItem();
};
// =======================================
// =======================================
void(entity targ, entity attacker) dmatch_score =
{
local entity tagToken;
if ( teamplay == TEAM_DMATCH_TAG )
{
tagToken = find (world, classname, "dmatch_tag_token");
if(tagToken == world)
{
attacker.frags = attacker.frags + 1;
return;
}
if ( attacker == tag_token_owner)
{
tagToken.tag_frags = tagToken.tag_frags + 1;
attacker.frags = attacker.frags + 3;
if ( tagToken.tag_frags == 5 )
{
sprint (attacker, "You got the Quad Damage\n");
attacker.items = attacker.items | IT_QUAD;
stuffcmd (attacker, "bf\n");
sound (attacker,CHAN_VOICE,"items/damage.wav", 1, ATTN_NORM);
attacker.super_time = 1;
attacker.super_damage_finished = time + 30;
}
else if (tagToken.tag_frags == 10)
{
bprint ( attacker.netname );
bprint ( " lost the tag token\n" );
tagToken.solid = SOLID_TRIGGER;
tagToken.tag_frags = 0;
tagToken.touch = tag_token_touch;
tag_token_respawn();
}
}
else
{
if (targ == tag_token_owner)
{
attacker.frags = attacker.frags + 5;
sound ( self, CHAN_AUTO, "runes/end1.wav", 1, ATTN_NORM);
if (attacker.classname == "player")
{
tag_token_owner = attacker;
tagToken.tag_frags = 0;
tagToken.tag_message_time = time + 0.5;
tagToken.owner = attacker;
tagToken.solid = SOLID_NOT;
tagToken.touch = SUB_Null;
tagToken.think = tag_token_think;
tagToken.nextthink = time + 0.1;
}
}
else
attacker.frags = attacker.frags + 1;
}
}
};

363
DOG.QC Normal file
View File

@ -0,0 +1,363 @@
/*
==============================================================================
DOG
==============================================================================
*/
$cd /raid/quake/id1/models/dog
$origin 0 0 24
$base base
$skin skin
$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
$frame deathb9
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
$frame painb11 painb12 painb13 painb14 painb15 painb16
$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12
$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
void() dog_leap1;
void() dog_run1;
/*
================
dog_bite
================
*/
void() dog_bite =
{
local vector delta;
local float ldmg;
if (!self.enemy)
return;
ai_charge(10);
if (!CanDamage (self.enemy, self))
return;
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 100)
return;
ldmg = (random() + random() + random()) * 8;
T_Damage (self.enemy, self, self, ldmg);
};
void() Dog_JumpTouch =
{
local float ldmg;
if (self.health <= 0)
return;
if (other.takedamage)
{
if ( vlen(self.velocity) > 300 )
{
ldmg = 10 + 10*random();
T_Damage (other, self, self, ldmg);
}
}
if (!checkbottom(self))
{
if (self.flags & FL_ONGROUND)
{ // jump randomly to not get hung up
//dprint ("popjump\n");
self.touch = SUB_Null;
self.think = dog_leap1;
self.nextthink = time + 0.1;
// self.velocity_x = (random() - 0.5) * 600;
// self.velocity_y = (random() - 0.5) * 600;
// self.velocity_z = 200;
// self.flags = self.flags - FL_ONGROUND;
}
return; // not on ground yet
}
self.touch = SUB_Null;
self.think = dog_run1;
self.nextthink = time + 0.1;
};
void() dog_stand1 =[ $stand1, dog_stand2 ] {ai_stand();};
void() dog_stand2 =[ $stand2, dog_stand3 ] {ai_stand();};
void() dog_stand3 =[ $stand3, dog_stand4 ] {ai_stand();};
void() dog_stand4 =[ $stand4, dog_stand5 ] {ai_stand();};
void() dog_stand5 =[ $stand5, dog_stand6 ] {ai_stand();};
void() dog_stand6 =[ $stand6, dog_stand7 ] {ai_stand();};
void() dog_stand7 =[ $stand7, dog_stand8 ] {ai_stand();};
void() dog_stand8 =[ $stand8, dog_stand9 ] {ai_stand();};
void() dog_stand9 =[ $stand9, dog_stand1 ] {ai_stand();};
void() dog_walk1 =[ $walk1 , dog_walk2 ] {
if (random() < 0.2)
sound (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE);
ai_walk(8);};
void() dog_walk2 =[ $walk2 , dog_walk3 ] {ai_walk(8);};
void() dog_walk3 =[ $walk3 , dog_walk4 ] {ai_walk(8);};
void() dog_walk4 =[ $walk4 , dog_walk5 ] {ai_walk(8);};
void() dog_walk5 =[ $walk5 , dog_walk6 ] {ai_walk(8);};
void() dog_walk6 =[ $walk6 , dog_walk7 ] {ai_walk(8);};
void() dog_walk7 =[ $walk7 , dog_walk8 ] {ai_walk(8);};
void() dog_walk8 =[ $walk8 , dog_walk1 ] {ai_walk(8);};
void() dog_run1 =[ $run1 , dog_run2 ] {
if (random() < 0.2)
sound (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE);
ai_run(16);};
void() dog_run2 =[ $run2 , dog_run3 ] {ai_run(32);};
void() dog_run3 =[ $run3 , dog_run4 ] {ai_run(32);};
void() dog_run4 =[ $run4 , dog_run5 ] {ai_run(20);};
void() dog_run5 =[ $run5 , dog_run6 ] {ai_run(64);};
void() dog_run6 =[ $run6 , dog_run7 ] {ai_run(32);};
void() dog_run7 =[ $run7 , dog_run8 ] {ai_run(16);};
void() dog_run8 =[ $run8 , dog_run9 ] {ai_run(32);};
void() dog_run9 =[ $run9 , dog_run10 ] {ai_run(32);};
void() dog_run10 =[ $run10 , dog_run11 ] {ai_run(20);};
void() dog_run11 =[ $run11 , dog_run12 ] {ai_run(64);};
void() dog_run12 =[ $run12 , dog_run1 ] {ai_run(32);};
void() dog_atta1 =[ $attack1, dog_atta2 ] {ai_charge(10);};
void() dog_atta2 =[ $attack2, dog_atta3 ] {ai_charge(10);};
void() dog_atta3 =[ $attack3, dog_atta4 ] {ai_charge(10);};
void() dog_atta4 =[ $attack4, dog_atta5 ] {
sound (self, CHAN_VOICE, "dog/dattack1.wav", 1, ATTN_NORM);
dog_bite();};
void() dog_atta5 =[ $attack5, dog_atta6 ] {ai_charge(10);};
void() dog_atta6 =[ $attack6, dog_atta7 ] {ai_charge(10);};
void() dog_atta7 =[ $attack7, dog_atta8 ] {ai_charge(10);};
void() dog_atta8 =[ $attack8, dog_run1 ] {ai_charge(10);};
void() dog_leap1 =[ $leap1, dog_leap2 ] {ai_face();};
void() dog_leap2 =[ $leap2, dog_leap3 ]
{
ai_face();
self.touch = Dog_JumpTouch;
makevectors (self.angles);
self.origin_z = self.origin_z + 1;
self.velocity = v_forward * 300 + '0 0 200';
if (self.flags & FL_ONGROUND)
self.flags = self.flags - FL_ONGROUND;
};
void() dog_leap3 =[ $leap3, dog_leap4 ] {};
void() dog_leap4 =[ $leap4, dog_leap5 ] {};
void() dog_leap5 =[ $leap5, dog_leap6 ] {};
void() dog_leap6 =[ $leap6, dog_leap7 ] {};
void() dog_leap7 =[ $leap7, dog_leap8 ] {};
void() dog_leap8 =[ $leap8, dog_leap9 ] {};
void() dog_leap9 =[ $leap9, dog_leap9 ] {};
void() dog_pain1 =[ $pain1 , dog_pain2 ] {};
void() dog_pain2 =[ $pain2 , dog_pain3 ] {};
void() dog_pain3 =[ $pain3 , dog_pain4 ] {};
void() dog_pain4 =[ $pain4 , dog_pain5 ] {};
void() dog_pain5 =[ $pain5 , dog_pain6 ] {};
void() dog_pain6 =[ $pain6 , dog_run1 ] {};
void() dog_painb1 =[ $painb1 , dog_painb2 ] {};
void() dog_painb2 =[ $painb2 , dog_painb3 ] {};
void() dog_painb3 =[ $painb3 , dog_painb4 ] {ai_pain(4);};
void() dog_painb4 =[ $painb4 , dog_painb5 ] {ai_pain(12);};
void() dog_painb5 =[ $painb5 , dog_painb6 ] {ai_pain(12);};
void() dog_painb6 =[ $painb6 , dog_painb7 ] {ai_pain(2);};
void() dog_painb7 =[ $painb7 , dog_painb8 ] {};
void() dog_painb8 =[ $painb8 , dog_painb9 ] {ai_pain(4);};
void() dog_painb9 =[ $painb9 , dog_painb10 ] {};
void() dog_painb10 =[ $painb10 , dog_painb11 ] {ai_pain(10);};
void() dog_painb11 =[ $painb11 , dog_painb12 ] {};
void() dog_painb12 =[ $painb12 , dog_painb13 ] {};
void() dog_painb13 =[ $painb13 , dog_painb14 ] {};
void() dog_painb14 =[ $painb14 , dog_painb15 ] {};
void() dog_painb15 =[ $painb15 , dog_painb16 ] {};
void() dog_painb16 =[ $painb16 , dog_run1 ] {};
void() dog_pain =
{
sound (self, CHAN_VOICE, "dog/dpain1.wav", 1, ATTN_NORM);
if (random() > 0.5)
dog_pain1 ();
else
dog_painb1 ();
};
void() dog_die1 =[ $death1, dog_die2 ] {};
void() dog_die2 =[ $death2, dog_die3 ] {};
void() dog_die3 =[ $death3, dog_die4 ] {};
void() dog_die4 =[ $death4, dog_die5 ] {};
void() dog_die5 =[ $death5, dog_die6 ] {};
void() dog_die6 =[ $death6, dog_die7 ] {};
void() dog_die7 =[ $death7, dog_die8 ] {};
void() dog_die8 =[ $death8, dog_die9 ] {};
void() dog_die9 =[ $death9, dog_die9 ] {};
void() dog_dieb1 =[ $deathb1, dog_dieb2 ] {};
void() dog_dieb2 =[ $deathb2, dog_dieb3 ] {};
void() dog_dieb3 =[ $deathb3, dog_dieb4 ] {};
void() dog_dieb4 =[ $deathb4, dog_dieb5 ] {};
void() dog_dieb5 =[ $deathb5, dog_dieb6 ] {};
void() dog_dieb6 =[ $deathb6, dog_dieb7 ] {};
void() dog_dieb7 =[ $deathb7, dog_dieb8 ] {};
void() dog_dieb8 =[ $deathb8, dog_dieb9 ] {};
void() dog_dieb9 =[ $deathb9, dog_dieb9 ] {};
void() dog_die =
{
// check for gib
if (self.health < -35)
{
sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
ThrowGib ("progs/gib3.mdl", self.health);
ThrowGib ("progs/gib3.mdl", self.health);
ThrowGib ("progs/gib3.mdl", self.health);
ThrowHead ("progs/h_dog.mdl", self.health);
return;
}
// regular death
sound (self, CHAN_VOICE, "dog/ddeath.wav", 1, ATTN_NORM);
self.solid = SOLID_NOT;
if (random() > 0.5)
dog_die1 ();
else
dog_dieb1 ();
};
//============================================================================
/*
==============
CheckDogMelee
Returns TRUE if a melee attack would hit right now
==============
*/
float() CheckDogMelee =
{
if (enemy_range == RANGE_MELEE)
{ // FIXME: check canreach
self.attack_state = AS_MELEE;
return TRUE;
}
return FALSE;
};
/*
==============
CheckDogJump
==============
*/
float() CheckDogJump =
{
local vector dist;
local float d;
if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z
+ 0.75 * self.enemy.size_z)
return FALSE;
if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z
+ 0.25 * self.enemy.size_z)
return FALSE;
dist = self.enemy.origin - self.origin;
dist_z = 0;
d = vlen(dist);
if (d < 80)
return FALSE;
if (d > 150)
return FALSE;
return TRUE;
};
float() DogCheckAttack =
{
local vector vec;
// if close enough for slashing, go for it
if (CheckDogMelee ())
{
self.attack_state = AS_MELEE;
return TRUE;
}
if (CheckDogJump ())
{
self.attack_state = AS_MISSILE;
return TRUE;
}
return FALSE;
};
//===========================================================================
/*QUAKED monster_dog (1 0 0) (-32 -32 -24) (32 32 40) Ambush
*/
void() monster_dog =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/h_dog.mdl");
precache_model ("progs/dog.mdl");
precache_sound ("dog/dattack1.wav");
precache_sound ("dog/ddeath.wav");
precache_sound ("dog/dpain1.wav");
precache_sound ("dog/dsight.wav");
precache_sound ("dog/idle.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/dog.mdl");
setsize (self, '-32 -32 -24', '32 32 40');
self.health = 25;
self.th_stand = dog_stand1;
self.th_walk = dog_walk1;
self.th_run = dog_run1;
self.th_pain = dog_pain;
self.th_die = dog_die;
self.th_melee = dog_atta1;
self.th_missile = dog_leap1;
walkmonster_start();
};

793
DOORS.QC Normal file
View File

@ -0,0 +1,793 @@
// updated to quake 1.06 - 10/8/96
float DOOR_START_OPEN = 1;
float DOOR_DONT_LINK = 4;
float DOOR_GOLD_KEY = 8;
float DOOR_SILVER_KEY = 16;
float DOOR_TOGGLE = 32;
/*
Doors are similar to buttons, but can spawn a fat trigger field around them
to open without a touch, and they link together to form simultanious
double/quad doors.
Door.owner is the master door. If there is only one door, it points to itself.
If multiple doors, all will point to a single one.
Door.enemy chains from the master door through all doors linked in the chain.
*/
/*
=============================================================================
THINK FUNCTIONS
=============================================================================
*/
void() door_go_down;
void() door_go_up;
void() door_blocked =
{
T_Damage (other, self, self, self.dmg);
// if a door has a negative wait, it would never come back if blocked,
// so let it just squash the object to death real fast
if (self.wait >= 0)
{
if (self.state == STATE_DOWN)
door_go_up ();
else
door_go_down ();
}
};
void() door_hit_top =
{
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_TOP;
if (self.spawnflags & DOOR_TOGGLE)
return; // don't come down automatically
self.think = door_go_down;
self.nextthink = self.ltime + self.wait;
};
void() door_hit_bottom =
{
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_BOTTOM;
};
void() door_go_down =
{
sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
if (self.max_health)
{
self.takedamage = DAMAGE_YES;
self.health = self.max_health;
}
self.state = STATE_DOWN;
SUB_CalcMove (self.pos1, self.speed, door_hit_bottom);
};
void() door_go_up =
{
if (self.state == STATE_UP)
return; // allready going up
if (self.state == STATE_TOP)
{ // reset top wait time
self.nextthink = self.ltime + self.wait;
return;
}
sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
self.state = STATE_UP;
SUB_CalcMove (self.pos2, self.speed, door_hit_top);
SUB_UseTargets();
};
/*
=============================================================================
ACTIVATION FUNCTIONS
=============================================================================
*/
void() door_fire =
{
local entity oself;
local entity starte;
if (self.owner != self)
objerror ("door_fire: self.owner != self");
// play use key sound
if (self.items)
sound (self, CHAN_VOICE, self.noise4, 1, ATTN_NORM);
self.message = string_null; // no more message
oself = self;
if (self.spawnflags & DOOR_TOGGLE)
{
if (self.state == STATE_UP || self.state == STATE_TOP)
{
starte = self;
do
{
door_go_down ();
self = self.enemy;
} while ( (self != starte) && (self != world) );
self = oself;
return;
}
}
// trigger all paired doors
starte = self;
do
{
door_go_up ();
self = self.enemy;
} while ( (self != starte) && (self != world) );
self = oself;
};
void() door_use =
{
local entity oself;
self.message = ""; // door message are for touch only
self.owner.message = "";
self.enemy.message = "";
oself = self;
self = self.owner;
door_fire ();
self = oself;
};
void() door_trigger_touch =
{
if (other.health <= 0)
return;
if (time < self.attack_finished)
return;
self.attack_finished = time + 1;
activator = other;
self = self.owner;
door_use ();
};
void() door_killed =
{
local entity oself;
oself = self;
self = self.owner;
self.health = self.max_health;
self.takedamage = DAMAGE_NO; // wil be reset upon return
door_use ();
self = oself;
};
/*
================
door_touch
Prints messages and opens key doors
================
*/
void() door_touch =
{
if (other.classname != "player")
return;
if (self.owner.attack_finished > time)
return;
self.owner.attack_finished = time + 2;
if (self.owner.message != "")
{
centerprint (other, self.owner.message);
sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
}
// key door stuff
if (!self.items)
return;
// FIXME: blink key on player's status bar
if ( (self.items & other.items) != self.items )
{
if (self.owner.items == IT_KEY1)
{
if (world.worldtype == 2)
{
centerprint (other, "You need the silver keycard");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
else if (world.worldtype == 1)
{
centerprint (other, "You need the silver runekey");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
else if (world.worldtype == 0)
{
centerprint (other, "You need the silver key");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
}
else
{
if (world.worldtype == 2)
{
centerprint (other, "You need the gold keycard");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
else if (world.worldtype == 1)
{
centerprint (other, "You need the gold runekey");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
else if (world.worldtype == 0)
{
centerprint (other, "You need the gold key");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
}
return;
}
other.items = other.items - self.items;
self.touch = SUB_Null;
if (self.enemy)
self.enemy.touch = SUB_Null; // get paired door
door_use ();
};
/*
=============================================================================
SPAWNING FUNCTIONS
=============================================================================
*/
entity(vector fmins, vector fmaxs) spawn_field =
{
local entity trigger;
local vector t1, t2;
trigger = spawn();
trigger.movetype = MOVETYPE_NONE;
trigger.solid = SOLID_TRIGGER;
trigger.owner = self;
trigger.touch = door_trigger_touch;
t1 = fmins;
t2 = fmaxs;
setsize (trigger, t1 - '60 60 8', t2 + '60 60 8');
return (trigger);
};
float (entity e1, entity e2) EntitiesTouching =
{
if (e1.mins_x > e2.maxs_x)
return FALSE;
if (e1.mins_y > e2.maxs_y)
return FALSE;
if (e1.mins_z > e2.maxs_z)
return FALSE;
if (e1.maxs_x < e2.mins_x)
return FALSE;
if (e1.maxs_y < e2.mins_y)
return FALSE;
if (e1.maxs_z < e2.mins_z)
return FALSE;
return TRUE;
};
/*
=============
LinkDoors
=============
*/
void() LinkDoors =
{
local entity t, starte;
local vector cmins, cmaxs;
if (self.enemy)
return; // already linked by another door
if (self.spawnflags & 4)
{
self.owner = self.enemy = self;
return; // don't want to link this door
}
cmins = self.mins;
cmaxs = self.maxs;
starte = self;
t = self;
do
{
self.owner = starte; // master door
if (self.health)
starte.health = self.health;
if (self.targetname)
starte.targetname = self.targetname;
if (self.message != "")
starte.message = self.message;
t = find (t, classname, self.classname);
if (!t)
{
self.enemy = starte; // make the chain a loop
// shootable, fired, or key doors just needed the owner/enemy links,
// they don't spawn a field
self = self.owner;
if (self.health)
return;
if (self.targetname)
return;
if (self.items)
return;
self.owner.trigger_field = spawn_field(cmins, cmaxs);
return;
}
if (EntitiesTouching(self,t))
{
if (t.enemy)
objerror ("cross connected doors");
self.enemy = t;
self = t;
if (t.mins_x < cmins_x)
cmins_x = t.mins_x;
if (t.mins_y < cmins_y)
cmins_y = t.mins_y;
if (t.mins_z < cmins_z)
cmins_z = t.mins_z;
if (t.maxs_x > cmaxs_x)
cmaxs_x = t.maxs_x;
if (t.maxs_y > cmaxs_y)
cmaxs_y = t.maxs_y;
if (t.maxs_z > cmaxs_z)
cmaxs_z = t.maxs_z;
}
} while (1 );
};
/*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE
if two doors touch, they are assumed to be connected and operate as a unit.
TOGGLE causes the door to wait in both the start and end states for a trigger event.
START_OPEN causes the door to move to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not usefull for touch or takedamage doors).
Key doors are allways wait -1.
"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet
"angle" determines the opening direction
"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door.
"health" if set, door must be shot open
"speed" movement speed (100 default)
"wait" wait before returning (3 default, -1 = never return)
"lip" lip remaining at end of move (8 default)
"dmg" damage to inflict when blocked (2 default)
"sounds"
0) no sound
1) stone
2) base
3) stone chain
4) screechy metal
*/
void() func_door =
{
local vector tempVect;
if (world.worldtype == 0)
{
precache_sound ("doors/medtry.wav");
precache_sound ("doors/meduse.wav");
self.noise3 = "doors/medtry.wav";
self.noise4 = "doors/meduse.wav";
}
else if (world.worldtype == 1)
{
precache_sound ("doors/runetry.wav");
precache_sound ("doors/runeuse.wav");
self.noise3 = "doors/runetry.wav";
self.noise4 = "doors/runeuse.wav";
}
else if (world.worldtype == 2)
{
precache_sound ("doors/basetry.wav");
precache_sound ("doors/baseuse.wav");
self.noise3 = "doors/basetry.wav";
self.noise4 = "doors/baseuse.wav";
}
else
{
dprint ("no worldtype set!\n");
}
if (self.sounds == 0)
{
precache_sound ("misc/null.wav");
precache_sound ("misc/null.wav");
self.noise1 = "misc/null.wav";
self.noise2 = "misc/null.wav";
}
if (self.sounds == 1)
{
precache_sound ("doors/drclos4.wav");
precache_sound ("doors/doormv1.wav");
self.noise1 = "doors/drclos4.wav";
self.noise2 = "doors/doormv1.wav";
}
if (self.sounds == 2)
{
precache_sound ("doors/hydro1.wav");
precache_sound ("doors/hydro2.wav");
self.noise2 = "doors/hydro1.wav";
self.noise1 = "doors/hydro2.wav";
}
if (self.sounds == 3)
{
precache_sound ("doors/stndr1.wav");
precache_sound ("doors/stndr2.wav");
self.noise2 = "doors/stndr1.wav";
self.noise1 = "doors/stndr2.wav";
}
if (self.sounds == 4)
{
precache_sound ("doors/ddoor1.wav");
precache_sound ("doors/ddoor2.wav");
self.noise1 = "doors/ddoor2.wav";
self.noise2 = "doors/ddoor1.wav";
}
SetMovedir ();
self.max_health = self.health;
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_PUSH;
setorigin (self, self.origin);
setmodel (self, self.model);
self.classname = "door";
self.blocked = door_blocked;
self.use = door_use;
if (self.spawnflags & DOOR_SILVER_KEY)
self.items = IT_KEY1;
if (self.spawnflags & DOOR_GOLD_KEY)
self.items = IT_KEY2;
if (!self.speed)
self.speed = 100;
if (!self.wait)
self.wait = 3;
if (!self.lip)
self.lip = 8;
if (!self.dmg)
self.dmg = 2;
self.pos1=self.origin;
// self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
// PGM fix for cameron's door problem - 02/19/97
tempVect = self.movedir;
if (tempVect_x < 0)
tempVect_x = 0 - tempVect_x;
if (tempVect_y < 0)
tempVect_y = 0 - tempVect_y;
// if (tempVect_z < 0)
// tempVect_z = 0 - tempVect_z;
// self.pos2 = self.pos1 + self.movedir*(tempVect*self.size - self.lip);
self.pos2 = self.pos1 + self.movedir*(fabs(tempVect*self.size) - self.lip);
// DOOR_START_OPEN is to allow an entity to be lighted in the closed position
// but spawn in the open position
if (self.spawnflags & DOOR_START_OPEN)
{
setorigin (self, self.pos2);
self.pos2 = self.pos1;
self.pos1 = self.origin;
}
self.state = STATE_BOTTOM;
if (self.health)
{
self.takedamage = DAMAGE_YES;
self.th_die = door_killed;
}
if (self.items)
self.wait = -1;
self.touch = door_touch;
// LinkDoors can't be done until all of the doors have been spawned, so
// the sizes can be detected properly.
self.think = LinkDoors;
self.nextthink = self.ltime + 0.1;
};
/*
=============================================================================
SECRET DOORS
=============================================================================
*/
void() fd_secret_move1;
void() fd_secret_move2;
void() fd_secret_move3;
void() fd_secret_move4;
void() fd_secret_move5;
void() fd_secret_move6;
void() fd_secret_done;
float SECRET_OPEN_ONCE = 1; // stays open
float SECRET_1ST_LEFT = 2; // 1st move is left of arrow
float SECRET_1ST_DOWN = 4; // 1st move is down from arrow
float SECRET_NO_SHOOT = 8; // only opened by trigger
float SECRET_YES_SHOOT = 16; // shootable even if targeted
void () fd_secret_use =
{
local float temp;
self.health = 10000;
// exit if still moving around...
if (self.origin != self.oldorigin)
return;
self.message = string_null; // no more message
SUB_UseTargets(); // fire all targets / killtargets
if (!(self.spawnflags & SECRET_NO_SHOOT))
{
self.th_pain = SUB_Null;
self.takedamage = DAMAGE_NO;
}
self.velocity = '0 0 0';
// Make a sound, wait a little...
sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.nextthink = self.ltime + 0.1;
temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1
makevectors(self.mangle);
if (!self.t_width)
{
if (self.spawnflags & SECRET_1ST_DOWN)
self. t_width = fabs(v_up * self.size);
else
self. t_width = fabs(v_right * self.size);
}
if (!self.t_length)
self. t_length = fabs(v_forward * self.size);
if (self.spawnflags & SECRET_1ST_DOWN)
self.dest1 = self.origin - v_up * self.t_width;
else
self.dest1 = self.origin + v_right * (self.t_width * temp);
self.dest2 = self.dest1 + v_forward * self.t_length;
SUB_CalcMove(self.dest1, self.speed, fd_secret_move1);
sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
};
// Wait after first movement...
void () fd_secret_move1 =
{
self.nextthink = self.ltime + 1.0;
self.think = fd_secret_move2;
sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
};
// Start moving sideways w/sound...
void () fd_secret_move2 =
{
sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
SUB_CalcMove(self.dest2, self.speed, fd_secret_move3);
};
// Wait here until time to go back...
void () fd_secret_move3 =
{
sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
if (!(self.spawnflags & SECRET_OPEN_ONCE))
{
self.nextthink = self.ltime + self.wait;
self.think = fd_secret_move4;
}
};
// Move backward...
void () fd_secret_move4 =
{
sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
SUB_CalcMove(self.dest1, self.speed, fd_secret_move5);
};
// Wait 1 second...
void () fd_secret_move5 =
{
self.nextthink = self.ltime + 1.0;
self.think = fd_secret_move6;
sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
};
void () fd_secret_move6 =
{
sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
SUB_CalcMove(self.oldorigin, self.speed, fd_secret_done);
};
void () fd_secret_done =
{
if (!self.targetname || self.spawnflags&SECRET_YES_SHOOT)
{
self.health = 10000;
self.takedamage = DAMAGE_YES;
self.th_pain = fd_secret_use;
}
sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
};
void () secret_blocked =
{
if (time < self.attack_finished)
return;
self.attack_finished = time + 0.5;
T_Damage (other, self, self, self.dmg);
};
/*
================
secret_touch
Prints messages
================
*/
void() secret_touch =
{
if (other.classname != "player")
return;
if (self.attack_finished > time)
return;
self.attack_finished = time + 2;
if (self.message)
{
centerprint (other, self.message);
sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
}
};
/*QUAKED func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot
Basic secret door. Slides back, then to the side. Angle determines direction.
wait = # of seconds before coming back
1st_left = 1st move is left of arrow
1st_down = 1st move is down from arrow
always_shoot = even if targeted, keep shootable
t_width = override WIDTH to move back (or height if going down)
t_length = override LENGTH to move sideways
"dmg" damage to inflict when blocked (2 default)
If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage.
"sounds"
1) medieval
2) metal
3) base
*/
void () func_door_secret =
{
if (self.sounds == 0)
self.sounds = 3;
if (self.sounds == 1)
{
precache_sound ("doors/latch2.wav");
precache_sound ("doors/winch2.wav");
precache_sound ("doors/drclos4.wav");
self.noise1 = "doors/latch2.wav";
self.noise2 = "doors/winch2.wav";
self.noise3 = "doors/drclos4.wav";
}
if (self.sounds == 2)
{
precache_sound ("doors/airdoor1.wav");
precache_sound ("doors/airdoor2.wav");
self.noise2 = "doors/airdoor1.wav";
self.noise1 = "doors/airdoor2.wav";
self.noise3 = "doors/airdoor2.wav";
}
if (self.sounds == 3)
{
precache_sound ("doors/basesec1.wav");
precache_sound ("doors/basesec2.wav");
self.noise2 = "doors/basesec1.wav";
self.noise1 = "doors/basesec2.wav";
self.noise3 = "doors/basesec2.wav";
}
if (!self.dmg)
self.dmg = 2;
// Magic formula...
self.mangle = self.angles;
self.angles = '0 0 0';
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_PUSH;
self.classname = "door";
setmodel (self, self.model);
setorigin (self, self.origin);
self.touch = secret_touch;
self.blocked = secret_blocked;
self.speed = 50;
self.use = fd_secret_use;
if ( !self.targetname || self.spawnflags&SECRET_YES_SHOOT)
{
self.health = 10000;
self.takedamage = DAMAGE_YES;
self.th_pain = fd_secret_use;
self.th_die = fd_secret_use;
}
self.oldorigin = self.origin;
if (!self.wait)
self.wait = 5; // 5 seconds before closing
};

834
DRAGON.QC Normal file
View File

@ -0,0 +1,834 @@
// dragon.qc
$base dragrest
$skin dragskin
$frame dragon6
$frame drgfly01 drgfly02 drgfly03 drgfly04
$frame drgfly05 drgfly06 drgfly07 drgfly08
$frame drgfly09 drgfly10 drgfly11 drgfly12 drgfly13
$frame drgtrn01 drgtrn02 drgtrn03 drgtrn04 drgtrn05 drgtrn06
$frame drgslh01 drgslh02 drgslh03 drgslh04 drgslh05 drgslh06
$frame drgslh07 drgslh08 drgslh09 drgslh10 drgslh11 drgslh12 drgslh13
$frame drgfir01 drgfir02 drgfir03 drgfir04 drgfir05
$frame drgfir06 drgfir07 drgfir08 drgfir09 drgfir10
$frame drgfix1a drgfix1b drgfix1c
$frame drgfix2a drgfix2b drgfix2c
$frame drgfix3a drgfix3b drgfix3c
$frame drgfix4a drgfix4b drgfix4c
$frame drgfix5a drgfix5b drgfix5c
$frame drgfix6a drgfix6b drgfix6c drgfix6d
$frame drgpan1a drgpan1b drgpan1c
$frame drgpan2a drgpan2b drgpan2c
$frame drgpan3a drgpan3b drgpan3c
$frame drgpan4a drgpan4b drgpan4c
$frame drgpan5a drgpan5b drgpan5c
$frame drgpan6a drgpan6b drgpan6c
$frame drgdth01 drgdth02 drgdth03 drgdth04 drgdth05 drgdth06
$frame drgdth07 drgdth08 drgdth09 drgdth10 drgdth11 drgdth12
$frame drgdth13 drgdth14 drgdth15 drgdth16 drgdth17 drgdth18
$frame drgdth19 drgdth20 drgdth21
void() dragon_fireball;
void() dragon_melee1;
// ===================================
// global variables
// ===================================
float DDIE_FALLING = 1;
float DDIE_STOPPED = 2;
float DDIE_EXPLODED = 3;
float DT_ROOM_A = 1;
float DT_ROOM_B = 2;
float DT_ROOM_C = 4;
float FIRE_PLASMA = 1;
float FIRE_FIREBALL = 2;
// ===================================
// dragon_stop_attack
// ===================================
void() dragon_stop_attack =
{
local entity tempDest;
if (self.dragonAttacking == FALSE)
return;
// skill ramp?
self.attack_finished = time + (random() * 2 ) + 4;
self.attack_finished = self.attack_finished - skill;
self.dragonAttacking = FALSE;
traceline (self.origin, self.movetarget.origin, TRUE, world);
if (trace_fraction == 1)
return;
else
bprint ("Error: Dragon cannot get to next target!\n");
};
// ===================================
// dragon_check_attack
// ===================================
void() dragon_check_attack =
{
local vector vec;
local float dot;
if ( self.dragonAttacking == TRUE)
return;
if ( self.th_missile == SUB_Null)
return;
if ( self.attack_finished > time )
return;
if ( self.enemy.health < 0)
self.enemy = world;
if ( self.enemy.flags & FL_NOTARGET )
return;
if (self.enemy == world)
FindTarget();
else
{
makevectors (self.angles);
vec = normalize (self.enemy.origin - self.origin);
dot = vec * v_forward;
// if ( dot > 0.55 )
if ( dot > 0.3 )
{
traceline (self.origin, self.enemy.origin, TRUE, world);
if (trace_fraction == 1)
{
dot = vlen ( self.enemy.origin - self.origin );
if (dot < 350)
{
self.dragonAttacking = TRUE;
self.think = dragon_melee1;
return;
}
else
{
self.dragonAttacking = TRUE;
self.think = self.th_missile;
}
}
// else
// bprint ("can't see player!\n");
}
}
};
// ===================================
// dragon_move
// ===================================
void(float dist) dragon_move =
{
local vector moveDir;
local vector moveAngles;
local float leftTurn, rightTurn, turnOffset;
local entity oldEnemy;
if ( self.health < 1 )
{
remove(self);
return;
}
if (self.dragonAttacking == FALSE) // && self.dragonInTransit == FALSE)
dragon_check_attack();
oldEnemy = self.enemy;
if ( self.dragonAttacking == FALSE )
{
moveDir = self.movetarget.origin - self.origin;
moveAngles = vectoangles ( moveDir );
self.enemy = self.movetarget;
}
else
{
moveDir = self.enemy.origin - self.origin;
moveAngles = vectoangles ( moveDir );
}
turnOffset = self.angles_y - moveAngles_y;
if (turnOffset != 0)
{
turnOffset = 180 - self.angles_y;
leftTurn = anglemod ( moveAngles_y + turnOffset ) - 180;
rightTurn = 180 - anglemod ( moveAngles_y + turnOffset );
if (leftTurn < 0)
leftTurn = 360;
else if (rightTurn < 0)
rightTurn = 360;
self.yaw_speed = 10;
if (rightTurn < 180)
{
if ( self.yaw_speed < rightTurn )
self.angles_y = self.angles_y - self.yaw_speed;
else
self.angles_y = moveAngles_y;
if ( rightTurn > 5 )
{
self.angles_z = self.angles_z + 5;
if (self.angles_z > 30)
self.angles_z = 30;
}
turnOffset = rightTurn;
}
else
{
if ( self.yaw_speed < rightTurn )
self.angles_y = self.angles_y + self.yaw_speed;
else
self.angles_y = moveAngles_y;
if ( leftTurn > 5 )
{
self.angles_z = self.angles_z - 5;
if (self.angles_z < -30)
self.angles_z = -30;
}
turnOffset = leftTurn;
}
}
else if (self.angles_z != 0)
{
if (self.angles_z < -5)
self.angles_z = self.angles_z + 5;
else if (self.angles_z < 5)
self.angles_z = 0;
else if (self.angles_z > 5)
self.angles_z = self.angles_z - 5;
}
if ( moveDir_z > 5)
setorigin ( self, self.origin + '0 0 5');
else if ( moveDir_z < -5)
setorigin ( self, self.origin - '0 0 5');
moveAngles = self.origin;
walkmove ( self.angles_y, dist );
if (moveAngles == self.origin)
{
// bprint ( "Cannot move smoothly. movetogoal..\n");
movetogoal ( dist );
}
self.enemy = oldEnemy;
};
// ===================================
// movement
// ===================================
void() dragon_stand1 = [ $drgfly01, dragon_walk1 ]
{
// bprint ( "dragon_stand1: ERROR - got to stand frame!\n");
};
// attack A: start - walk1 stop - walk 5
// ================
void() dragon_atk_a1=[$drgfix1a, dragon_atk_a2 ]
{ dragon_move(17); };
void() dragon_atk_a2=[$drgfix1b, dragon_atk_a3 ]
{ dragon_move(17);dragon_fireball();};
void() dragon_atk_a3=[$drgfix1c, dragon_walk5 ]
{ dragon_move(17);dragon_stop_attack();};
// attack B: start - walk3 stop - walk7
// ================
void() dragon_atk_b1=[$drgfix2a, dragon_atk_b2 ]
{ dragon_move(17); };
void() dragon_atk_b2=[$drgfix2b, dragon_atk_b3 ]
{ dragon_move(17);dragon_fireball();};
void() dragon_atk_b3=[$drgfix2c, dragon_walk7 ]
{ dragon_move(17);dragon_stop_attack();};
// attack C: start - walk5 stop - walk9
// ================
void() dragon_atk_c1=[$drgfix3a, dragon_atk_c2 ]
{dragon_move(17); };
void() dragon_atk_c2=[$drgfix3b, dragon_atk_c3 ]
{ dragon_move(17);dragon_fireball();};
void() dragon_atk_c3=[$drgfix3c, dragon_walk9 ]
{ dragon_move(17);dragon_stop_attack();};
// attack d: start - walk7 stop - walk11
// ================
void() dragon_atk_d1=[$drgfix4a, dragon_atk_d2 ]
{ dragon_move(17); };
void() dragon_atk_d2=[$drgfix4b, dragon_atk_d3 ]
{ dragon_move(17);dragon_fireball();};
void() dragon_atk_d3=[$drgfix4c, dragon_walk11 ]
{ dragon_move(17);dragon_stop_attack();};
// attack E: start - walk9 stop - walk13
// ================
void() dragon_atk_e1=[$drgfix5a, dragon_atk_e2 ]
{ dragon_move(17); };
void() dragon_atk_e2=[$drgfix5b, dragon_atk_e3 ]
{ dragon_move(17);dragon_fireball();};
void() dragon_atk_e3=[$drgfix5c, dragon_walk13 ]
{ dragon_move(17);dragon_stop_attack();};
// attack F: start - walk11 stop - walk3
// ================
void() dragon_atk_f1=[$drgfix6a, dragon_atk_f2 ]
{dragon_move(17); };
void() dragon_atk_f2=[$drgfix6b, dragon_atk_f3 ]
{ dragon_move(17);dragon_fireball();};
void() dragon_atk_f3=[$drgfix6c, dragon_atk_f4 ]
{ dragon_move(17); };
void() dragon_atk_f4=[$drgfix6c, dragon_walk3 ]
{ dragon_move(17);dragon_stop_attack();};
// ===================================
// dragon walk frames
// ===================================
void() dragon_walk1 =[ $drgfly01, dragon_walk2 ]
{
if (self.dragonAttacking)
dragon_stop_attack();
self.th_missile=dragon_atk_a1;
self.dragonPainSequence = 1;
dragon_move(17);
if (random() < 0.2)
sound (self, CHAN_VOICE, "dragon/active.wav", 0.6, ATTN_IDLE);
};
void() dragon_walk2 =[ $drgfly02, dragon_walk3 ]
{ self.th_missile=SUB_Null; dragon_move(17);};
void() dragon_walk3 =[ $drgfly03, dragon_walk4 ]
{
self.th_missile=dragon_atk_b1; dragon_move(17);
self.dragonPainSequence=2;
};
void() dragon_walk4 =[ $drgfly04, dragon_walk5 ]
{ self.th_missile=SUB_Null; dragon_move(17);};
void() dragon_walk5 =[ $drgfly05, dragon_walk6 ]
{
self.th_missile=dragon_atk_c1; dragon_move(17);
self.dragonPainSequence=3;
};
void() dragon_walk6 =[ $drgfly06, dragon_walk7 ]
{ self.th_missile=SUB_Null; dragon_move(17); };
void() dragon_walk7 =[ $drgfly07, dragon_walk8 ]
{
self.th_missile=dragon_atk_d1; dragon_move(17);
self.dragonPainSequence=4;
};
void() dragon_walk8 =[ $drgfly08, dragon_walk9 ]
{ self.th_missile=SUB_Null; dragon_move(17); };
void() dragon_walk9 =[ $drgfly09, dragon_walk10 ]
{
self.th_missile=dragon_atk_e1; dragon_move(17);
self.dragonPainSequence=5;
};
void() dragon_walk10 =[ $drgfly10, dragon_walk11 ]
{ self.th_missile=SUB_Null; dragon_move(17); };
void() dragon_walk11 =[ $drgfly11, dragon_walk12 ]
{
self.th_missile=dragon_atk_f1; dragon_move(17);
self.dragonPainSequence=6;
};
void() dragon_walk12 =[ $drgfly12, dragon_walk13 ]
{ self.th_missile=SUB_Null; dragon_move(17); };
void() dragon_walk13 =[ $drgfly13, dragon_walk1 ]
{ self.th_missile=SUB_Null; dragon_move(17); self.dragonPainSequence=1;};
// ===================================
// attack
// ===================================
void() FireballTouch =
{
if (other == self.owner)
return; // don't explode on owner
if (self.owner.classname == "monster_dragon")
T_RadiusDamage (self, self.owner, 90, self.owner);
else
T_RadiusDamage (self, self.owner, 30, world);
sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION2);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
WriteByte (MSG_BROADCAST, 228); // 247
WriteByte (MSG_BROADCAST, 5);
remove(self);
// BecomeExplosion();
};
void(vector org, vector dir) launch_fireball =
{
local entity fireball;
local float fireSpeed;
self.effects = self.effects | EF_MUZZLEFLASH;
fireball = spawn();
fireball.owner = self;
fireball.movetype = MOVETYPE_FLYMISSILE;
fireball.solid = SOLID_BBOX;
fireball.classname = "fireball";
setmodel (fireball, "progs/fireball.mdl");
setorigin (fireball, org);
setsize (fireball, '0 0 0', '0 0 0');
fireSpeed = random() * 300 + 900;
fireball.velocity = dir * fireSpeed;
fireball.avelocity = '0 0 300';
fireball.angles = vectoangles(fireball.velocity);
fireball.enemy = self.enemy;
fireball.touch = FireballTouch;
fireball.nextthink = time + 6;
fireball.think = SUB_Remove;
};
// ===========================================
// dragon_fireball
// ===========================================
void() dragon_fireball =
{
local float fireCount;
local vector org, dir;
local float distortion;
local float fireType;
sound (self, CHAN_VOICE, "dragon/attack.wav", 1, ATTN_NORM);
makevectors (self.angles);
org = self.origin + v_forward*112 + v_up*32;
if (random() > 0.66)
{
fireCount = 1;
if ( skill > 1)
fireCount = 2;
fireType = FIRE_PLASMA;
}
else
{
fireType = FIRE_FIREBALL;
fireCount = random() * skill; // easy 0, med 0-1, hard 0-2
fireCount = rint ( fireCount ) + 1; // easy 1, med 1-2, hard 1-3
}
while (fireCount > 0)
{
distortion = ( random() - 0.5 ) * 0.25;
dir = normalize ( self.enemy.origin - org );
makevectors (dir);
dir = dir + v_right * distortion;
if (fireType == FIRE_FIREBALL)
launch_fireball(org, dir);
else
launch_plasma(org, dir);
fireCount = fireCount - 1;
}
};
// ===================================
// melee attacks
// ===================================
void() dragon_tail_touch =
{
local vector delta;
local float tailDamage;
if (!self.enemy)
return;
if (!CanDamage (self.enemy, self))
return;
ai_charge(10);
delta = self.enemy.origin - self.origin;
tailDamage = vlen(delta);
if (vlen(delta) > 150)
{
return;
}
tailDamage = ( random() * 30 ) + 30;
T_Damage ( self.enemy, self, self, tailDamage);
};
void() dragon_tail =
{
local float dist;
local vector dir;
if (!self.enemy)
return;
if (!CanDamage (self.enemy, self))
return;
dragon_move(10);
dir = self.enemy.origin - self.origin;
dist = vlen ( dir );
if ( dist < 250 )
{
T_Damage ( self.enemy, self, self, 30 );
dir = normalize (dir);
self.enemy.velocity = dir * 500;
self.enemy.velocity_z = 350;
}
dragon_stop_attack();
};
void() dragon_melee1=[$drgslh01, dragon_melee2 ] { dragon_move(12);};
void() dragon_melee2=[$drgslh02, dragon_melee3 ] { dragon_move(12);};
void() dragon_melee3=[$drgslh03, dragon_melee4 ] { dragon_move(12);};
void() dragon_melee4=[$drgslh04, dragon_melee5 ] { dragon_move(12);};
void() dragon_melee5=[$drgslh05, dragon_melee6 ] { dragon_move(12);};
void() dragon_melee6=[$drgslh06, dragon_melee7 ] { dragon_move(12);};
void() dragon_melee7=[$drgslh07, dragon_melee8 ] { dragon_move(12);};
void() dragon_melee8=[$drgslh08, dragon_melee9 ] { dragon_move(12);};
void() dragon_melee9=[$drgslh09, dragon_melee10] { dragon_move(12);};
void() dragon_melee10=[$drgslh10, dragon_melee11] { dragon_tail();};
void() dragon_melee11=[$drgslh11, dragon_melee12] { dragon_move(10);};
void() dragon_melee12=[$drgslh12, dragon_melee13] { dragon_move(10);};
void() dragon_melee13=[$drgslh13, dragon_walk1 ] { dragon_move(10);};
// ===================================
// pain
// ===================================
void() dragon_painA1 = [ $drgpan1a, dragon_painA2 ] {dragon_move(12);};
void() dragon_painA2 = [ $drgpan1b, dragon_painA3 ] {dragon_move(12);};
void() dragon_painA3 = [ $drgpan1c, dragon_walk5 ] {dragon_move(12);};
void() dragon_painB1 = [ $drgpan2a, dragon_painB2 ] {dragon_move(12);};
void() dragon_painB2 = [ $drgpan2b, dragon_painB3 ] {dragon_move(12);};
void() dragon_painB3 = [ $drgpan2c, dragon_walk7 ] {dragon_move(12);};
void() dragon_painC1 = [ $drgpan3a, dragon_painC2 ] {dragon_move(12);};
void() dragon_painC2 = [ $drgpan3b, dragon_painC3 ] {dragon_move(12);};
void() dragon_painC3 = [ $drgpan3c, dragon_walk9 ] {dragon_move(12);};
void() dragon_painD1 = [ $drgpan4a, dragon_painD2 ] {dragon_move(12);};
void() dragon_painD2 = [ $drgpan4b, dragon_painD3 ] {dragon_move(12);};
void() dragon_painD3 = [ $drgpan4c, dragon_walk11 ] {dragon_move(12);};
void() dragon_painE1 = [ $drgpan5a, dragon_painE2 ] {dragon_move(12);};
void() dragon_painE2 = [ $drgpan5b, dragon_painE3 ] {dragon_move(12);};
void() dragon_painE3 = [ $drgpan5c, dragon_walk13 ] {dragon_move(12);};
void() dragon_painF1 = [ $drgpan6a, dragon_painF2 ] {dragon_move(12);};
void() dragon_painF2 = [ $drgpan6b, dragon_painF3 ] {dragon_move(12);};
void() dragon_painF3 = [ $drgpan6c, dragon_walk2 ] {dragon_move(12);};
void() dragon_pain =
{
local float r;
if (self.pain_finished > time)
return;
r = random();
if (r < 0.25)
{
dragon_stop_attack();
sound (self, CHAN_VOICE, "dragon/pain.wav", 1, ATTN_NORM);
self.pain_finished = time + 2;
if (self.dragonPainSequence == 1)
self.think = dragon_painA1;
else if (self.dragonPainSequence == 2)
self.think = dragon_painF1;
else if (self.dragonPainSequence == 3)
self.think = dragon_painE1;
else if (self.dragonPainSequence == 4)
self.think = dragon_painD1;
else if (self.dragonPainSequence == 5)
self.think = dragon_painC1;
else if (self.dragonPainSequence == 6)
self.think = dragon_painB1;
}
};
// ===================================
// death
// ===================================
void() dragon_boom2 =
{
self.velocity = self.dragonLastVelocity;
ViolentDeath(15);
self.target = "dragondoor";
SUB_UseTargets();
remove(self);
};
void() dragon_boom1 =
{
if ( self.dragonDeathState > DDIE_STOPPED )
// objerror ( "dragon_boom1");
return;
self.dragonDeathState = DDIE_EXPLODED;
ThrowGib ("progs/drggib01.mdl", -100);
ThrowGib ("progs/drggib02.mdl", -100);
ThrowGib ("progs/drggib03.mdl", -100);
sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE);
self.think = dragon_boom2;
self.nextthink = time + 0.1;
};
void() dragon_explode =
{
if ( self.dragonDeathState > DDIE_FALLING )
// objerror ( "dragon_explode");
return;
if (vlen(self.velocity) < 100 || self.flags & FL_INWATER)
{
self.dragonDeathState = DDIE_STOPPED;
dragon_boom1();
}
else
{
makevectors ( self.angles );
self.velocity = self.velocity - 40 * v_up;
self.dragonLastVelocity = self.velocity;
}
};
void() dragon_squish =
{
if (other.classname == "player")
{
self.classname = "monster_dragon_dead";
T_Damage( other, self, self, 200);
}
if (other == world)
{
self.velocity = '0 0 0';
dragon_explode();
}
};
void() dragon_death1 = [ $drgdth01, dragon_death2 ]
{
if ( self.dragonDeathState > 0)
// objerror ( "dragon_death1");
return;
self.dragonDeathState = DDIE_FALLING;
self.use = SUB_Null;
makevectors ( self.angles );
self.velocity = 300 * v_forward - 40 * v_up;
self.flags = self.flags - (self.flags & FL_ONGROUND);
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
self.touch = dragon_squish;
sound (self, CHAN_VOICE, "dragon/death.wav", 1, ATTN_NONE);
self.dragonAttacking = FALSE;
};
void() dragon_death2 = [ $drgdth02, dragon_death3 ] {dragon_explode();};
void() dragon_death3 = [ $drgdth03, dragon_death4 ] {dragon_explode();};
void() dragon_death4 = [ $drgdth04, dragon_death5 ] {dragon_explode();};
void() dragon_death5 = [ $drgdth05, dragon_death6 ] {dragon_explode();};
void() dragon_death6 = [ $drgdth06, dragon_death7 ] {dragon_explode();};
void() dragon_death7 = [ $drgdth07, dragon_death8 ] {dragon_explode();};
void() dragon_death8 = [ $drgdth08, dragon_death9 ] {dragon_explode();};
void() dragon_death9 = [ $drgdth09, dragon_death10 ] {dragon_explode();};
void() dragon_death10 = [ $drgdth10, dragon_death11 ] {dragon_explode();};
void() dragon_death11 = [ $drgdth11, dragon_death12 ] {dragon_explode();};
void() dragon_death12 = [ $drgdth12, dragon_death13 ] {dragon_explode();};
void() dragon_death13 = [ $drgdth13, dragon_death14 ] {dragon_explode();};
void() dragon_death14 = [ $drgdth14, dragon_death15 ] {dragon_explode();};
void() dragon_death15 = [ $drgdth15, dragon_death16 ] {dragon_explode();};
void() dragon_death16 = [ $drgdth16, dragon_death17 ] {dragon_explode();};
void() dragon_death17 = [ $drgdth17, dragon_death18 ] {dragon_explode();};
void() dragon_death18 = [ $drgdth18, dragon_death19 ] {dragon_explode();};
void() dragon_death19 = [ $drgdth19, dragon_death20 ] {dragon_explode();};
void() dragon_death20 = [ $drgdth20, dragon_death21 ] {dragon_explode();};
void() dragon_death21 = [ $drgdth21, dragon_death21 ]
{
ViolentDeath(39);
self.target = "dragondoor";
SUB_UseTargets();
remove(self);
};
// ===================================
// Delayed Activation
// ===================================
void() dragon_use =
{
if (self.health < 1)
{
self.use = SUB_Null;
return;
}
self.th_stand = dragon_walk1;
self.th_walk = dragon_walk1;
self.think = dragon_walk1;
self.nextthink = time + 0.1;
};
// ===================================
// dragon activation code
// ===================================
void() dragon_activate =
{
self.takedamage = DAMAGE_AIM;
self.ideal_yaw = self.angles * '0 1 0';
if (!self.yaw_speed)
self.yaw_speed = 10;
self.view_ofs = '0 0 25';
self.flags = self.flags | FL_FLY;
self.flags = self.flags | FL_MONSTER;
if (!walkmove(0,0))
{
dprint ("flymonster in wall!\n");
dprint (self.classname);
dprint (" at ");
dprint (vtos(self.origin));
dprint ("\n");
}
if (self.target)
{
self.movetarget = find(world, targetname, self.target);
self.goalentity = self.movetarget;
if (!self.movetarget)
{
dprint ("Monster can't find target at ");
dprint (vtos(self.origin));
dprint ("\n");
}
}
if (self.targetname)
self.use = dragon_use;
else
dragon_use();
};
/*QUAKED monster_dragon (1 0 0) (-32 -32 -24) (32 32 64) Ambush
*/
void() monster_dragon =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/dragon.mdl");
precache_model ("progs/fireball.mdl");
precache_model ("progs/drggib01.mdl");
precache_model ("progs/drggib02.mdl");
precache_model ("progs/drggib03.mdl");
precache_sound ("dragon/see.wav");
precache_sound ("dragon/active.wav");
precache_sound ("dragon/attack.wav");
precache_sound ("dragon/pain.wav");
precache_sound ("dragon/death.wav");
self.dragonInRoom = DT_ROOM_A;
self.dragonInTransit = 0;
self.dragonAttacking = FALSE;
self.playerInRoom = DT_ROOM_A;
self.playerInTransit = 0;
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/dragon.mdl");
setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
self.health = 3000 + (1000 * cvar("skill"));
self.th_run = dragon_walk1;
self.th_pain = dragon_pain;
self.th_die = dragon_death1;
self.dragonPainSequence=1;
total_monsters = total_monsters + 1;
self.nextthink = self.nextthink + 0.1;
self.think = dragon_activate;
};
// =================================================
// dragon trigger -- OBSOLETE!!
// =================================================
/*QUAKED trigger_dragon (.5 .5 .5) ? A B C
Trigger to let dragon know what room you're in.
Set the A,B,C to which room this trigger is at.
Point the trigger towards the room. If the player is going
the direction the trigger points, he is entering the room.
If not, he is leaving.
*/
void() trigger_dragon =
{
remove(self);
};
// =================================================
// dragon corners
// =================================================
void() dragon_corner_touch =
{
if (other.movetarget != self)
return;
if (other.classname != "monster_dragon")
return;
other.movetarget = find (world, targetname, self.target);
other.goalentity = other.movetarget;
other.target = self.target;
if (!other.movetarget)
{
objerror ("dragon_corner: no target found");
}
};
/*QUAKED dragon_corner (0.5 0.3 0) (-16 -16 -16) (16 16 16)
Only for use with monster_dragon. Use only as transitions
between rooms.
*/
void() dragon_corner =
{
if (!self.targetname)
objerror ("dragon_corner: no targetname");
self.solid = SOLID_TRIGGER;
self.movetype = MOVETYPE_NONE;
self.touch = dragon_corner_touch;
self.modelindex = 0;
self.model = "";
setsize (self, '-16 -16 -16', '16 16 16');
};

162
EARTHQ.QC Normal file
View File

@ -0,0 +1,162 @@
// earthquake
// ============================================================
// Level-Wide Earthquakes
// ============================================================
float EQ_RANDOM = 1;
void() stop_earthquake;
void() earthquake_rumble =
{
if (self.attack_finished < time)
stop_earthquake();
else
{
sound( self, CHAN_VOICE, "equake/rumble.wav", 1, ATTN_NONE );
self.think = earthquake_rumble;
self.nextthink = time + 1;
}
};
void() start_earthquake =
{
earthquake_active = 1;
if ( self.spawnflags & EQ_RANDOM )
self.attack_finished = time + random() * self.delay;
else
self.attack_finished = time + self.delay;
earthquake_rumble();
};
void() stop_earthquake =
{
earthquake_active = 0;
self.think = start_earthquake;
if ( self.spawnflags & EQ_RANDOM )
self.nextthink = time + random() * self.wait;
else
self.nextthink = time + self.wait;
};
/*QUAKED earthquake (0 1 0) (-8 -8 -8) (8 8 8) Random
The Earthquake generator.
delay - duration of the tremor (default 20)
wait - time between tremors (default 60)
weapon - richter scale of movement (default 40)
RANDOM affects the times only. It will change the randomly between
0-n where n is the duration or time between.
weapon - if you give a weapon value of 40, the X and Y displacement
can vary between -20 and +20, a range of 40.
*/
void() earthquake =
{
if (!self.delay)
self.delay = 20;
if (!self.wait)
self.wait = 60;
if (!self.weapon)
self.weapon = 40;
precache_sound ("equake/rumble.wav");
earthquake_active = 0;
earthquake_intensity = self.weapon * 0.5;
setsize (self, '0 0 0', '0 0 0');
self.think = stop_earthquake;
self.nextthink = time + 1;
};
// ============================================================
// Earthquake trigger
// ============================================================
void() earthquake_touch =
{
if (self.delay)
{
if ( self.attack_finished < time )
{
sound ( self, CHAN_VOICE, "equake/rumble.wav", 1, ATTN_NORM );
self.attack_finished = time + 1;
}
if ( other.classname == "player" )
{
if ( other.flags & FL_ONGROUND )
{
other.velocity_x = other.velocity_x +
(random() * self.weapon * 2) -
self.weapon;
other.velocity_y = other.velocity_y +
(random() * self.weapon * 2) -
self.weapon;
other.velocity_z = other.velocity_z +
(random() * self.weapon * 2) -
self.weapon;
}
}
}
};
void() earthquake_use =
{
self.delay = !self.delay;
};
/*QUAKED trigger_earthquake (.5 .5 .5) ?
The Earthquake generator.
Anytime a person is in an active field, they shake. If the trigger is a target, it will be OFF until triggered. It will then toggle between ON and OFF.
weapon - richter scale of movement (default 40)
weapon - if you give a weapon value of 40, the X and Y displacement
can vary between -20 and +20, a range of 40.
*/
void() trigger_earthquake =
{
precache_sound ("equake/rumble.wav");
if (!self.weapon)
self.weapon = 40;
self.weapon = self.weapon * 0.5;
self.delay = 1;
self.touch = earthquake_touch;
if (self.targetname)
{
self.use = earthquake_use;
self.delay = 0;
}
InitTrigger();
};
void() kill_earthquake =
{
local entity eq;
if ( other.classname != "player" )
return;
eq = find (world, classname, "earthquake");
if (eq != world)
{
earthquake_active = 0;
remove (eq);
}
};
/*QUAKED trigger_earthquake_kill (.5 .5 .5) ?
Trigger to kill the level-wide earthquake.
*/
void() trigger_earthquake_kill =
{
self.touch = kill_earthquake;
InitTrigger();
};

223
EEL.QC Normal file
View File

@ -0,0 +1,223 @@
$cd /qwork/xpack/models/eel
$origin 0 0 0
$scale .12
$base eelrest3
$skin eelfin
$frame eelswim1 eelswim2 eelswim3 eelswim4 eelswim5 eelswim6
$frame eeldth1 eeldth2 eeldth3 eeldth4 eeldth5
$frame eeldth6 eeldth7 eeldth8 eeldth9 eeldth10
void() swimmonster_start;
void() eel_pain1;
void() eel_pitch_change =
{
if ( pointcontents ( self.origin ) != CONTENT_WATER )
{
droptofloor();
T_Damage ( self, world, world, 6);
return;
}
if ( time < self.delay )
return;
if ( self.weapon > 10 )
self.weapon = -10;
if ( self.weapon < 0 )
self.angles_x = self.angles_x - 1.5;
else if ( self.weapon > 0)
self.angles_x = self.angles_x + 1.5;
self.weapon = self.weapon + 1;
};
void() eel_stand1 =[ $eelswim1, eel_stand2 ]
{ ai_stand(); eel_pitch_change();} ;
void() eel_stand2 =[ $eelswim2, eel_stand3 ]
{ ai_stand(); eel_pitch_change();};
void() eel_stand3 =[ $eelswim3, eel_stand4 ]
{ ai_stand(); eel_pitch_change();};
void() eel_stand4 =[ $eelswim4, eel_stand5 ]
{ ai_stand(); eel_pitch_change();};
void() eel_stand5 =[ $eelswim5, eel_stand6 ]
{ ai_stand(); eel_pitch_change();};
void() eel_stand6 =[ $eelswim6, eel_stand1 ]
{ ai_stand(); eel_pitch_change();};
void() eel_walk1 =[ $eelswim1, eel_walk2 ]
{
if (random() < 0.2)
sound (self, CHAN_VOICE, "eel/eactive1.wav", 1, ATTN_IDLE);
ai_walk(6);
eel_pitch_change();
};
void() eel_walk2 =[ $eelswim2, eel_walk3 ] {ai_walk(6);eel_pitch_change();};
void() eel_walk3 =[ $eelswim3, eel_walk4 ] {ai_walk(6);eel_pitch_change();};
void() eel_walk4 =[ $eelswim4, eel_walk5 ] {ai_walk(6);eel_pitch_change();};
void() eel_walk5 =[ $eelswim5, eel_walk6 ] {ai_walk(6);eel_pitch_change();};
void() eel_walk6 =[ $eelswim6, eel_walk1 ] {ai_walk(6);eel_pitch_change();};
void() eel_run1 =[ $eelswim1, eel_run2 ]
{
if (random() < 0.4)
sound (self, CHAN_VOICE, "eel/eactive1.wav", 1, ATTN_IDLE);
ai_run(10);
eel_pitch_change();
};
void() eel_run2 =[ $eelswim2, eel_run3 ] {ai_run(10);eel_pitch_change();};
void() eel_run3 =[ $eelswim3, eel_run4 ] {ai_run(10);eel_pitch_change();};
void() eel_run4 =[ $eelswim4, eel_run5 ] {ai_run(10);eel_pitch_change();};
void() eel_run5 =[ $eelswim5, eel_run6 ] {ai_run(10);eel_pitch_change();};
void() eel_run6 =[ $eelswim6, eel_run1 ] {ai_run(10);eel_pitch_change();};
void() eel_melee =
{
local float attackOK;
attackOK = 1;
traceline (self.origin, self.enemy.origin, FALSE, self);
if (trace_ent != self.enemy)
attackOK = FALSE; // don't have a clear shot
if (trace_inopen && trace_inwater)
attackOK = FALSE; // sight line crossed contents
if (attackOK)
T_EELZap (self, self, 45);
self.skin=0;
self.effects=0;
};
void() eel_attack1 =[ $eelswim1, eel_attack2 ]
{ ai_charge(8); eel_pitch_change();};
void() eel_attack2 =[ $eelswim2, eel_attack3 ]
{ ai_charge(8); eel_pitch_change();};
void() eel_attack3 =[ $eelswim3, eel_attack4 ]
{ ai_charge(8); eel_pitch_change();};
void() eel_attack4 =[ $eelswim4, eel_attack5 ]
{ ai_charge(8); eel_pitch_change();};
void() eel_attack5 =[ $eelswim5, eel_attack6 ]
{ ai_charge(8); eel_pitch_change();};
void() eel_attack6 =[ $eelswim6, eel_attack7 ]
{ ai_charge(8); eel_pitch_change();};
void() eel_attack7 =[ $eelswim1, eel_attack8 ]
{ ai_charge(8); eel_pitch_change();};
void() eel_attack8 =[ $eelswim2, eel_attack9 ]
{
self.effects = EF_DIMLIGHT;
self.skin=1;
ai_charge(8);
eel_pitch_change();
sound (self, CHAN_WEAPON, "eel/eatt1.wav", 1, ATTN_NORM);
};
void() eel_attack9 =[ $eelswim3, eel_attack10 ]
{ self.skin=2;ai_charge(8);eel_pitch_change(); };
void() eel_attack10=[ $eelswim4, eel_attack11 ]
{ self.skin=3;ai_charge(8);eel_pitch_change(); };
void() eel_attack11=[ $eelswim5, eel_attack12 ]
{ self.effects = EF_BRIGHTLIGHT; self.skin=4;ai_charge(8);eel_pitch_change();};
void() eel_attack12=[ $eelswim6, eel_run1 ]
{ self.skin=5;eel_melee(); };
void() eel_death1 =[ $eeldth1, eel_death2 ]
{
self.skin = 0;
self.effects = 0;
sound (self, CHAN_VOICE, "eel/edie3r.wav", 1, ATTN_NORM);
};
void() eel_death2 =[ $eeldth2, eel_death3 ] {};
void() eel_death3 =[ $eeldth3, eel_death4 ] {};
void() eel_death4 =[ $eeldth4, eel_death5 ] {};
void() eel_death5 =[ $eeldth3, eel_death6 ] {};
void() eel_death6 =[ $eeldth2, eel_death7 ] {};
void() eel_death7 =[ $eeldth1, eel_death8 ] {};
void() eel_death8 =[ $eeldth2, eel_death9 ] {};
void() eel_death9 =[ $eeldth3, eel_death10 ] {};
void() eel_death10 =[ $eeldth4, eel_death11 ] {};
void() eel_death11 =[ $eeldth5, eel_death12 ] { self.flags = self.flags - FL_SWIM; };
void() eel_death12 =[ $eeldth6, eel_death13 ] {};
void() eel_death13 =[ $eeldth7, eel_death14 ] {};
void() eel_death14 =[ $eeldth8, eel_death15 ] {};
void() eel_death15 =[ $eeldth9, eel_death16 ] {droptofloor();};
void() eel_death16 =[ $eeldth10, eel_death16 ] {self.solid = SOLID_NOT;};
void() eel_death =
{
self.flags = self.flags + FL_SWIM;
setsize (self, '0 0 0', '0 0 0');
// self.skin = 1; // change to bloody eel skin!
if (self.health < -12)
{
self.skin = 0;
self.effects = 0;
ThrowHead ("progs/eelgib.mdl", self.health);
ThrowGib ("progs/gib1.mdl", self.health);
ThrowGib ("progs/gib1.mdl", self.health);
ThrowGib ("progs/gib1.mdl", self.health);
return;
}
else
{
eel_death1 ();
}
};
void() eel_pain1 =[ $eeldth1, eel_pain2 ]
{
if (self.pain_finished > time)
return;
self.pain_finished = time + 1;
sound (self, CHAN_VOICE, "eel/epain3.wav", 1, ATTN_NORM);
self.skin=0;
};
void() eel_pain2 =[ $eeldth2, eel_pain3 ] {};
void() eel_pain3 =[ $eeldth3, eel_pain4 ] {};
void() eel_pain4 =[ $eeldth4, eel_pain5 ] {};
void() eel_pain5 =[ $eeldth3, eel_pain6 ] {};
void() eel_pain6 =[ $eeldth2, eel_pain7 ] {};
void() eel_pain7 =[ $eeldth1, eel_run1 ] {};
/*QUAKED monster_eel (1 0 0) (-16 -16 -24) (16 16 32) Ambush
*/
void() monster_eel =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/eel2.mdl");
precache_model ("progs/eelgib.mdl");
precache_model ("progs/gib1.mdl");
precache_sound ("eel/edie3r.wav");
precache_sound ("eel/epain3.wav");
precache_sound ("eel/eactive1.wav");
precache_sound ("eel/eatt1.wav");
precache_sound ("eel/eelc5.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/eel2.mdl");
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
self.health = 60;
self.th_stand = eel_stand1;
self.th_walk = eel_walk1;
self.th_run = eel_run1;
self.th_die = eel_death;
self.th_pain = eel_pain1;
self.th_melee = eel_attack1;
self.delay = time + random() * 6;
self.weapon = 0;
swimmonster_start ();
};

156
ELEVATR.QC Normal file
View File

@ -0,0 +1,156 @@
// elevator button
// pmack
// sept 96
float ELVTR_DOWN = 1;
void() elvtr_button_wait;
void() elvtr_button_return;
void() elvtr_button_wait =
{
ELV_BUTN_DIR = 0;
if (self.spawnflags & ELVTR_DOWN)
ELV_BUTN_DIR = -1;
else
ELV_BUTN_DIR = 1;
self.state = STATE_TOP;
self.nextthink = self.ltime + self.wait;
self.think = elvtr_button_return;
activator = self.enemy;
SUB_UseTargets();
self.frame = 1; // use alternate textures
};
void() elvtr_button_done =
{
self.state = STATE_BOTTOM;
};
void() elvtr_button_return =
{
self.state = STATE_DOWN;
SUB_CalcMove (self.pos1, self.speed, elvtr_button_done);
self.frame = 0; // use normal textures
if (self.health)
self.takedamage = DAMAGE_YES; // can be shot again
};
void() elvtr_button_blocked =
{ // do nothing, just don't ome all the way back out
};
void() elvtr_button_fire =
{
if (self.state == STATE_UP || self.state == STATE_TOP)
return;
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
self.state = STATE_UP;
SUB_CalcMove (self.pos2, self.speed, elvtr_button_wait);
};
void() elvtr_button_use =
{
self.enemy = activator;
elvtr_button_fire ();
};
void() elvtr_button_touch =
{
if (other.classname != "player")
return;
self.enemy = other;
elvtr_button_fire ();
};
void() elvtr_button_killed =
{
self.enemy = damage_attacker;
self.health = self.max_health;
self.takedamage = DAMAGE_NO; // wil be reset upon return
elvtr_button_fire ();
};
/*QUAKED func_elvtr_button (0 .5 .8) ? ELVTR_DOWN
ELEVATOR BUTTON ONLY!
ELVTR_DOWN causes this to be a DOWN button.
Default is UP.
When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again.
"angle" determines the opening direction
"target" all entities with a matching targetname will be used
"speed" override the default 40 speed
"wait" override the default 1 second wait (-1 = never return)
"lip" override the default 4 pixel lip remaining at end of move
"health" if set, the button must be killed instead of touched
"sounds"
0) steam metal
1) wooden clunk
2) metallic click
3) in-out
*/
void() func_elvtr_button =
{
local float gtemp, ftemp;
if (self.sounds == 0)
{
precache_sound ("buttons/airbut1.wav");
self.noise = "buttons/airbut1.wav";
}
if (self.sounds == 1)
{
precache_sound ("buttons/switch21.wav");
self.noise = "buttons/switch21.wav";
}
if (self.sounds == 2)
{
precache_sound ("buttons/switch02.wav");
self.noise = "buttons/switch02.wav";
}
if (self.sounds == 3)
{
precache_sound ("buttons/switch04.wav");
self.noise = "buttons/switch04.wav";
}
SetMovedir ();
self.movetype = MOVETYPE_PUSH;
self.solid = SOLID_BSP;
setmodel (self, self.model);
self.blocked = elvtr_button_blocked;
self.use = elvtr_button_use;
if (self.health)
{
self.max_health = self.health;
self.th_die = elvtr_button_killed;
self.takedamage = DAMAGE_YES;
}
else
self.touch = elvtr_button_touch;
if (!self.speed)
self.speed = 40;
if (!self.wait)
self.wait = 1;
if (!self.lip)
self.lip = 4;
self.state = STATE_BOTTOM;
self.pos1 = self.origin;
self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
};

361
ENDING.QC Normal file
View File

@ -0,0 +1,361 @@
// ending.qc
// code to handle big ending of Xpack.
// ------------------------------------------------
$frame axrun1 axrun2 axrun3 axrun4 axrun5 axrun6
$frame rockrun1 rockrun2 rockrun3 rockrun4 rockrun5 rockrun6
$frame stand1 stand2 stand3 stand4 stand5
$frame axstnd1 axstnd2 axstnd3 axstnd4 axstnd5 axstnd6
$frame axstnd7 axstnd8 axstnd9 axstnd10 axstnd11 axstnd12
$frame axpain1 axpain2 axpain3 axpain4 axpain5 axpain6
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame axdeth1 axdeth2 axdeth3 axdeth4 axdeth5 axdeth6
$frame axdeth7 axdeth8 axdeth9
$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8
$frame deatha9 deatha10 deatha11
$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
$frame deathb9
$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
$frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15
$frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7
$frame deathd8 deathd9
$frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7
$frame deathe8 deathe9
$frame nailatt1 nailatt2
$frame light1 light2
$frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6
$frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6
$frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6
$frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6
$frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6
$frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6
entity theActor;
entity theMachine;
float actorStage;
float STAGE_START = 0;
float STAGE_TO_POINT1 = 1;
float STAGE_AT_POINT1 = 2;
float STAGE_TO_POINT2 = 3;
float STAGE_AT_POINT2 = 4;
float STAGE_FIRING = 5;
void(entity thePlayer) spawn_actor;
void() actor_control;
void(entity playerEnt) move_camera;
void() time_crash;
void() ending_remove_stuff;
void() ending_for_coop =
{
intermission_exittime = time + 10000000; // never allow exit
intermission_running = 1;
self.model = "";
self.yaw_speed = 20;
self.view_ofs = '0 0 0';
self.takedamage = DAMAGE_NO;
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_NONE;
self.modelindex = 0;
setorigin (self, self.origin + '0 0 48');
WriteByte (MSG_ALL, SVC_FINALE);
WriteString (MSG_ALL, "You have destroyed Quake's\nTemporal Teleporter. His assault\non Time has been defeated.");
ending_remove_stuff();
theMachine.think = time_crash;
theMachine.nextthink = time + 0.1;
};
// ------------------------------------------------
// Camera and control functions
// ------------------------------------------------
void() xpackEnding =
{
local entity cameraview;
if (coop)
{
ending_for_coop();
return;
}
intermission_exittime = time + 10000000; // never allow exit
intermission_running = 1;
WriteByte (MSG_ALL, SVC_CUTSCENE);
WriteString (MSG_ALL, "");
cameraview = find ( world, targetname, "cameraview");
if (cameraview == world)
{
ending_for_coop();
return;
}
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_NONE;
spawn_actor(self);
move_camera(self);
};
void() track_camera =
{
local vector cameraAngle;
cameraAngle = theActor.origin - self.origin;
cameraAngle_z = 0 - cameraAngle_z;
self.angles = vectoangles ( cameraAngle );
self.v_angle = self.angles;
self.think = track_camera;
self.nextthink = time + 0.1;
};
void(entity playerEnt) move_camera =
{
local entity cameraPoint;
local vector cameraAngle;
cameraPoint = find ( world, targetname, "cameraview");
if ( cameraPoint == world )
objerror ("Could not find camerapoint!");
self.model = "";
self.yaw_speed = 20;
self.view_ofs = '0 0 0';
self.takedamage = DAMAGE_NO;
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_NONE;
self.modelindex = 0;
setorigin (self, cameraPoint.origin);
cameraAngle = theActor.origin - self.origin;
self.angles = vectoangles ( cameraAngle );
self.v_angle = self.angles;
self.think = track_camera;
self.nextthink = time + 0.05;
};
void() ending_remove_stuff =
{
local entity curEnt;
local entity removeEnt;
curEnt = find ( world, classname, "ltrail_start");
while(curEnt)
{
remove(curEnt);
curEnt = find ( world, classname, "ltrail_start");
}
curEnt = find ( world, classname, "item_time_core");
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION2);
WriteCoord (MSG_BROADCAST, curEnt.origin_x);
WriteCoord (MSG_BROADCAST, curEnt.origin_y);
WriteCoord (MSG_BROADCAST, curEnt.origin_z);
WriteByte (MSG_BROADCAST, 230);
WriteByte (MSG_BROADCAST, 5);
curEnt.think = SUB_Remove;
curEnt.nextthink = time + 0.1;
};
// ------------------------------------------------
// actor code
// ------------------------------------------------
void() actor_run =
{
local vector dist;
local float ang;
local entity pointOne;
if ( pointcontents (self.origin) == CONTENT_LAVA )
{
pointOne = find ( world, targetname, "point1" );
if (pointOne != world)
setorigin ( self, pointOne.origin );
}
if ( self.goalentity.targetname == "endpoint1")
{
actorStage = STAGE_AT_POINT1;
self.think = actor_control;
self.nextthink = time + 0.1;
return;
}
if ( self.goalentity.targetname == "endpoint2")
{
actorStage = STAGE_AT_POINT2;
self.think = actor_control;
self.nextthink = time + 0.1;
return;
}
self.frame = self.frame + 1;
if (self.frame > 11)
self.frame = 6;
dist = self.goalentity.origin - self.origin;
// self.ideal_yaw = vectoyaw ( dist );
// ChangeYaw();
movetogoal ( 15 );
self.think = actor_run;
self.nextthink = time + 0.1;
};
void() actor_fire1 =[$rockatt1, actor_fire2 ]
{
self.goalentity = theMachine;
theMachine.th_pain = time_crash;
theMachine.th_die = time_crash;
theMachine.health = 1;
self.angles = vectoangles ( self.goalentity.origin - self.origin );
self.v_angle = self.angles;
self.v_angle_x = 0 - self.angles_x;
self.effects = EF_MUZZLEFLASH;
W_FireRocket();
// start the end text
WriteByte (MSG_ALL, SVC_FINALE);
WriteString (MSG_ALL, "\nFinally, Quake's Temporal Teleporter\nyields to your assault. A high\npitched scream emits from the\ndevastated device as stressed steel\nblasts outward to rock the cavern.\nThe machine is devoured by molten lava.\n\nThe ground shudders as reality shifts\nback to its predestined path.\n\nYou run to enter the charged time pod,\nscrambling in as the chamber closes.\nYour consciousness fades as you realize\nyou have halted Quake's plans for...\n\nThe Dissolution of Eternity.");
};
void() actor_fire2 =[$rockatt2, actor_fire3 ]
{self.v_angle_x = 0; self.angles_x = 0; self.nextthink=time+0.15;};
void() actor_fire3 =[$rockatt3, actor_fire4 ] {self.nextthink=time+0.15;};
void() actor_fire4 =[$rockatt4, actor_fire5 ] {self.nextthink=time+0.15;};
void() actor_fire5 =[$rockatt5, actor_fire6 ]
{
self.nextthink=time+0.15;
ending_remove_stuff();
if (theMachine.health > 0)
{
theMachine.think = time_crash;
theMachine.nextthink = time + 0.1;
}
};
void() actor_fire6 =[$rockatt6, actor_fire7 ]
{ self.effects=0;self.nextthink=time+0.15;};
void() actor_fire7 =[$stand1, actor_fire8 ] {self.nextthink=time+0.15;};
void() actor_fire8 =[$stand2, actor_fire9 ] {self.nextthink=time+0.15;};
void() actor_fire9 =[$stand3, actor_fire10 ] {self.nextthink=time+0.15;};
void() actor_fire10 =[$stand4, actor_fire11 ] {self.nextthink=time+0.15;};
void() actor_fire11 =[$stand5, actor_fire12 ] {self.nextthink=time+0.15;};
void() actor_fire12 =[$stand1, actor_fire13 ] {self.nextthink=time+0.15;};
void() actor_fire13 =[$stand2, actor_fire14 ] {self.nextthink=time+0.15;};
void() actor_fire14 =[$stand3, actor_fire15 ] {self.nextthink=time+0.15;};
void() actor_fire15 =[$stand4, actor_fire16 ] {self.nextthink=time+0.15;};
void() actor_fire16 =[$stand5, actor_fire17 ] {self.nextthink=time+0.15;};
void() actor_fire17 =[$stand1, actor_fire18 ] {self.nextthink=time+0.15;};
void() actor_fire18 =[$stand2, actor_fire19 ] {self.nextthink=time+0.15;};
void() actor_fire19 =[$stand3, actor_fire20 ] {self.nextthink=time+0.15;};
void() actor_fire20 =[$stand4, actor_fire21 ] {self.nextthink=time+0.15;};
void() actor_fire21 =[$stand5, actor_control ]
{
self.nextthink=time+0.15;
actorStage = STAGE_TO_POINT2;
};
void() actor_teleport =
{
spawn_tfog(self.origin);
self.model = string_null;
self.think = SUB_Null;
self.nextthink = time + 999999;
};
void() actor_control =
{
local entity timepod;
if (actorStage == STAGE_START)
{
self.target = "point1";
self.movetarget = find (world, targetname, self.target);
self.goalentity = self.movetarget;
if ( self.goalentity == world )
objerror ("End Sequence point1 placing screwed up!");
self.frame = 6;
self.think = actor_run;
self.nextthink = time + 0.1;
actorStage = STAGE_TO_POINT1;
}
else if (actorStage == STAGE_AT_POINT1)
{
self.target = "machine";
self.movetarget = find (world, targetname, self.target);
self.goalentity = self.movetarget;
if ( self.goalentity == world )
objerror ("End Sequence machine placing screwed up!");
actorStage = STAGE_FIRING;
self.think = actor_fire1;
self.nextthink = time + 0.1;
}
else if (actorStage == STAGE_AT_POINT2)
{
self.frame = $stand1;
self.think = actor_teleport;
self.nextthink = time + 2;
}
else if (actorStage == STAGE_TO_POINT2)
{
self.target = "timepod";
SUB_UseTargets();
self.target = "point2";
self.movetarget = find (world, targetname, self.target);
self.goalentity = self.movetarget;
if ( self.goalentity == world )
objerror ("End Sequence point2 placing screwed up!");
self.frame = 6;
self.think = actor_run;
self.nextthink = time + 0.1;
}
};
// ==============
// player actor spawn function
// ==============
void(entity thePlayer) spawn_actor =
{
local entity pointOne;
theActor = spawn();
theActor.owner = self;
theActor.classname = "actor";
theActor.health = 100;
theActor.solid = SOLID_SLIDEBOX;
theActor.movetype = MOVETYPE_STEP;
theActor.frame = self.frame;
setmodel ( theActor, "progs/player.mdl");
setorigin ( theActor, self.origin);
setsize (theActor, VEC_HULL_MIN, VEC_HULL_MAX);
theActor.view_ofs = '0 0 22';
theActor.angles = self.angles;
theActor.ideal_yaw = theActor.angles * '0 1 0';
if (!theActor.yaw_speed)
theActor.yaw_speed = 20;
theActor.view_ofs = '0 0 25';
theActor.flags = theActor.flags | FL_MONSTER;
actorStage == STAGE_START;
if ( pointcontents (theActor.origin) == CONTENT_LAVA )
{
pointOne = find ( world, targetname, "point1" );
if (pointOne != world)
setorigin ( theActor, pointOne.origin );
}
theActor.think = actor_control;
theActor.nextthink = time + 0.1;
};

357
ENFORCER.QC Normal file
View File

@ -0,0 +1,357 @@
/*
==============================================================================
SOLDIER / PLAYER
==============================================================================
*/
$cd /raid/quake/id1/models/enforcer
$origin 0 -6 24
$base base
$skin skin
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
$frame walk11 walk12 walk13 walk14 walk15 walk16
$frame run1 run2 run3 run4 run5 run6 run7 run8
$frame attack1 attack2 attack3 attack4 attack5 attack6
$frame attack7 attack8 attack9 attack10
$frame death1 death2 death3 death4 death5 death6 death7 death8
$frame death9 death10 death11 death12 death13 death14
$frame fdeath1 fdeath2 fdeath3 fdeath4 fdeath5 fdeath6 fdeath7 fdeath8
$frame fdeath9 fdeath10 fdeath11
$frame paina1 paina2 paina3 paina4
$frame painb1 painb2 painb3 painb4 painb5
$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8
$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8
$frame paind9 paind10 paind11 paind12 paind13 paind14 paind15 paind16
$frame paind17 paind18 paind19
void() Laser_Touch =
{
local vector org;
if (other == self.owner)
return; // don't explode on owner
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC);
org = self.origin - 8*normalize(self.velocity);
if (other.health)
{
SpawnBlood (org, self.velocity*0.2, 15);
T_Damage (other, self, self.owner, 15);
}
else
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_GUNSHOT);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
}
remove(self);
};
void(vector org, vector vec) LaunchLaser =
{
local vector vec;
if (self.classname == "monster_enforcer")
sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
vec = normalize(vec);
newmis = spawn();
newmis.owner = self;
newmis.movetype = MOVETYPE_FLY;
newmis.solid = SOLID_BBOX;
newmis.effects = EF_DIMLIGHT;
newmis.classname = "enforcer_laser";
setmodel (newmis, "progs/laser.mdl");
setsize (newmis, '0 0 0', '0 0 0');
if (self.classname == "monster_morph")
{
if (!self.owner)
newmis.skin = 1;
}
setorigin (newmis, org);
newmis.velocity = vec * 600;
newmis.angles = vectoangles(newmis.velocity);
newmis.nextthink = time + 5;
newmis.think = SUB_Remove;
newmis.touch = Laser_Touch;
};
void() enforcer_fire =
{
local vector org;
self.effects = self.effects | EF_MUZZLEFLASH;
makevectors (self.angles);
org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
LaunchLaser(org, self.enemy.origin - self.origin);
};
//============================================================================
void() enf_stand1 =[ $stand1, enf_stand2 ] {ai_stand();};
void() enf_stand2 =[ $stand2, enf_stand3 ] {ai_stand();};
void() enf_stand3 =[ $stand3, enf_stand4 ] {ai_stand();};
void() enf_stand4 =[ $stand4, enf_stand5 ] {ai_stand();};
void() enf_stand5 =[ $stand5, enf_stand6 ] {ai_stand();};
void() enf_stand6 =[ $stand6, enf_stand7 ] {ai_stand();};
void() enf_stand7 =[ $stand7, enf_stand1 ] {ai_stand();};
void() enf_walk1 =[ $walk1 , enf_walk2 ] {
if (random() < 0.2)
sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
ai_walk(2);};
void() enf_walk2 =[ $walk2 , enf_walk3 ] {ai_walk(4);};
void() enf_walk3 =[ $walk3 , enf_walk4 ] {ai_walk(4);};
void() enf_walk4 =[ $walk4 , enf_walk5 ] {ai_walk(3);};
void() enf_walk5 =[ $walk5 , enf_walk6 ] {ai_walk(1);};
void() enf_walk6 =[ $walk6 , enf_walk7 ] {ai_walk(2);};
void() enf_walk7 =[ $walk7 , enf_walk8 ] {ai_walk(2);};
void() enf_walk8 =[ $walk8 , enf_walk9 ] {ai_walk(1);};
void() enf_walk9 =[ $walk9 , enf_walk10 ] {ai_walk(2);};
void() enf_walk10 =[ $walk10, enf_walk11 ] {ai_walk(4);};
void() enf_walk11 =[ $walk11, enf_walk12 ] {ai_walk(4);};
void() enf_walk12 =[ $walk12, enf_walk13 ] {ai_walk(1);};
void() enf_walk13 =[ $walk13, enf_walk14 ] {ai_walk(2);};
void() enf_walk14 =[ $walk14, enf_walk15 ] {ai_walk(3);};
void() enf_walk15 =[ $walk15, enf_walk16 ] {ai_walk(4);};
void() enf_walk16 =[ $walk16, enf_walk1 ] {ai_walk(2);};
void() enf_run1 =[ $run1 , enf_run2 ] {
if (random() < 0.2)
sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
ai_run(18);};
void() enf_run2 =[ $run2 , enf_run3 ] {ai_run(14);};
void() enf_run3 =[ $run3 , enf_run4 ] {ai_run(7);};
void() enf_run4 =[ $run4 , enf_run5 ] {ai_run(12);};
void() enf_run5 =[ $run5 , enf_run6 ] {ai_run(14);};
void() enf_run6 =[ $run6 , enf_run7 ] {ai_run(14);};
void() enf_run7 =[ $run7 , enf_run8 ] {ai_run(7);};
void() enf_run8 =[ $run8 , enf_run1 ] {ai_run(11);};
void() enf_atk1 =[ $attack1, enf_atk2 ] {ai_face();};
void() enf_atk2 =[ $attack2, enf_atk3 ] {ai_face();};
void() enf_atk3 =[ $attack3, enf_atk4 ] {ai_face();};
void() enf_atk4 =[ $attack4, enf_atk5 ] {ai_face();};
void() enf_atk5 =[ $attack5, enf_atk6 ] {ai_face();};
void() enf_atk6 =[ $attack6, enf_atk7 ] {enforcer_fire();};
void() enf_atk7 =[ $attack7, enf_atk8 ] {ai_face();};
void() enf_atk8 =[ $attack8, enf_atk9 ] {ai_face();};
void() enf_atk9 =[ $attack5, enf_atk10 ] {ai_face();};
void() enf_atk10 =[ $attack6, enf_atk11 ] {enforcer_fire();};
void() enf_atk11 =[ $attack7, enf_atk12 ] {ai_face();};
void() enf_atk12 =[ $attack8, enf_atk13 ] {ai_face();};
void() enf_atk13 =[ $attack9, enf_atk14 ] {ai_face();};
void() enf_atk14 =[ $attack10, enf_run1 ] {ai_face();
SUB_CheckRefire (enf_atk1);
};
void() enf_paina1 =[ $paina1, enf_paina2 ] {};
void() enf_paina2 =[ $paina2, enf_paina3 ] {};
void() enf_paina3 =[ $paina3, enf_paina4 ] {};
void() enf_paina4 =[ $paina4, enf_run1 ] {};
void() enf_painb1 =[ $painb1, enf_painb2 ] {};
void() enf_painb2 =[ $painb2, enf_painb3 ] {};
void() enf_painb3 =[ $painb3, enf_painb4 ] {};
void() enf_painb4 =[ $painb4, enf_painb5 ] {};
void() enf_painb5 =[ $painb5, enf_run1 ] {};
void() enf_painc1 =[ $painc1, enf_painc2 ] {};
void() enf_painc2 =[ $painc2, enf_painc3 ] {};
void() enf_painc3 =[ $painc3, enf_painc4 ] {};
void() enf_painc4 =[ $painc4, enf_painc5 ] {};
void() enf_painc5 =[ $painc5, enf_painc6 ] {};
void() enf_painc6 =[ $painc6, enf_painc7 ] {};
void() enf_painc7 =[ $painc7, enf_painc8 ] {};
void() enf_painc8 =[ $painc8, enf_run1 ] {};
void() enf_paind1 =[ $paind1, enf_paind2 ] {};
void() enf_paind2 =[ $paind2, enf_paind3 ] {};
void() enf_paind3 =[ $paind3, enf_paind4 ] {};
void() enf_paind4 =[ $paind4, enf_paind5 ] {ai_painforward(2);};
void() enf_paind5 =[ $paind5, enf_paind6 ] {ai_painforward(1);};
void() enf_paind6 =[ $paind6, enf_paind7 ] {};
void() enf_paind7 =[ $paind7, enf_paind8 ] {};
void() enf_paind8 =[ $paind8, enf_paind9 ] {};
void() enf_paind9 =[ $paind9, enf_paind10 ] {};
void() enf_paind10 =[ $paind10, enf_paind11 ] {};
void() enf_paind11 =[ $paind11, enf_paind12 ] {ai_painforward(1);};
void() enf_paind12 =[ $paind12, enf_paind13 ] {ai_painforward(1);};
void() enf_paind13 =[ $paind13, enf_paind14 ] {ai_painforward(1);};
void() enf_paind14 =[ $paind14, enf_paind15 ] {};
void() enf_paind15 =[ $paind15, enf_paind16 ] {};
void() enf_paind16 =[ $paind16, enf_paind17 ] {ai_pain(1);};
void() enf_paind17 =[ $paind17, enf_paind18 ] {ai_pain(1);};
void() enf_paind18 =[ $paind18, enf_paind19 ] {};
void() enf_paind19 =[ $paind19, enf_run1 ] {};
void(entity attacker, float damage) enf_pain =
{
local float r;
r = random ();
if (self.pain_finished > time)
return;
if (r < 0.5)
sound (self, CHAN_VOICE, "enforcer/pain1.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "enforcer/pain2.wav", 1, ATTN_NORM);
if (r < 0.2)
{
self.pain_finished = time + 1;
enf_paina1 ();
}
else if (r < 0.4)
{
self.pain_finished = time + 1;
enf_painb1 ();
}
else if (r < 0.7)
{
self.pain_finished = time + 1;
enf_painc1 ();
}
else
{
self.pain_finished = time + 2;
enf_paind1 ();
}
};
//============================================================================
void() enf_die1 =[ $death1, enf_die2 ] {};
void() enf_die2 =[ $death2, enf_die3 ] {};
void() enf_die3 =[ $death3, enf_die4 ]
{self.solid = SOLID_NOT;self.ammo_cells = 5;DropBackpack();};
void() enf_die4 =[ $death4, enf_die5 ] {ai_forward(14);};
void() enf_die5 =[ $death5, enf_die6 ] {ai_forward(2);};
void() enf_die6 =[ $death6, enf_die7 ] {};
void() enf_die7 =[ $death7, enf_die8 ] {};
void() enf_die8 =[ $death8, enf_die9 ] {};
void() enf_die9 =[ $death9, enf_die10 ] {ai_forward(3);};
void() enf_die10 =[ $death10, enf_die11 ] {ai_forward(5);};
void() enf_die11 =[ $death11, enf_die12 ] {ai_forward(5);};
void() enf_die12 =[ $death12, enf_die13 ] {ai_forward(5);};
void() enf_die13 =[ $death13, enf_die14 ] {};
void() enf_die14 =[ $death14, enf_die14 ] {};
void() enf_fdie1 =[ $fdeath1, enf_fdie2 ] {
};
void() enf_fdie2 =[ $fdeath2, enf_fdie3 ] {};
void() enf_fdie3 =[ $fdeath3, enf_fdie4 ]
{self.solid = SOLID_NOT;self.ammo_cells = 5;DropBackpack();};
void() enf_fdie4 =[ $fdeath4, enf_fdie5 ] {};
void() enf_fdie5 =[ $fdeath5, enf_fdie6 ] {};
void() enf_fdie6 =[ $fdeath6, enf_fdie7 ] {};
void() enf_fdie7 =[ $fdeath7, enf_fdie8 ] {};
void() enf_fdie8 =[ $fdeath8, enf_fdie9 ] {};
void() enf_fdie9 =[ $fdeath9, enf_fdie10 ] {};
void() enf_fdie10 =[ $fdeath10, enf_fdie11 ] {};
void() enf_fdie11 =[ $fdeath11, enf_fdie11 ] {};
void() enf_die =
{
// check for gib
if (self.health < -35)
{
sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
ThrowHead ("progs/h_mega.mdl", self.health);
ThrowGib ("progs/gib1.mdl", self.health);
ThrowGib ("progs/gib2.mdl", self.health);
ThrowGib ("progs/gib3.mdl", self.health);
return;
}
// regular death
sound (self, CHAN_VOICE, "enforcer/death1.wav", 1, ATTN_NORM);
if (random() > 0.5)
enf_die1 ();
else
enf_fdie1 ();
};
/*QUAKED monster_enforcer (1 0 0) (-16 -16 -24) (16 16 40) Ambush
*/
void() monster_enforcer =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model2 ("progs/enforcer.mdl");
precache_model2 ("progs/h_mega.mdl");
precache_model2 ("progs/laser.mdl");
precache_sound2 ("enforcer/death1.wav");
precache_sound2 ("enforcer/enfire.wav");
precache_sound2 ("enforcer/enfstop.wav");
precache_sound2 ("enforcer/idle1.wav");
precache_sound2 ("enforcer/pain1.wav");
precache_sound2 ("enforcer/pain2.wav");
precache_sound2 ("enforcer/sight1.wav");
precache_sound2 ("enforcer/sight2.wav");
precache_sound2 ("enforcer/sight3.wav");
precache_sound2 ("enforcer/sight4.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/enforcer.mdl");
setsize (self, '-16 -16 -24', '16 16 40');
self.health = 80;
self.th_stand = enf_stand1;
self.th_walk = enf_walk1;
self.th_run = enf_run1;
self.th_pain = enf_pain;
self.th_die = enf_die;
self.th_missile = enf_atk1;
walkmonster_start();
};

408
FIGHT.QC Normal file
View File

@ -0,0 +1,408 @@
/*
A monster is in fight mode if it thinks it can effectively attack its
enemy.
When it decides it can't attack, it goes into hunt mode.
*/
float(float v) anglemod;
void() knight_atk1;
void() knight_runatk1;
void() ogre_smash1;
void() ogre_swing1;
void() sham_smash1;
void() sham_swingr1;
void() sham_swingl1;
float() DemonCheckAttack;
void(float side) Demon_Melee;
void(vector dest) ChooseTurn;
void() ai_face;
float enemy_vis, enemy_infront, enemy_range;
float enemy_yaw;
void() knight_attack =
{
local float len;
// decide if now is a good swing time
len = vlen(self.enemy.origin+self.enemy.view_ofs - (self.origin+self.view_ofs));
if (len<80)
knight_atk1 ();
else
knight_runatk1 ();
};
//=============================================================================
/*
===========
CheckAttack
The player is in view, so decide to move or launch an attack
Returns FALSE if movement should continue
============
*/
float() CheckAttack =
{
local vector spot1, spot2;
local entity targ;
local float chance;
targ = self.enemy;
// see if any entities are in the way of the shot
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
traceline (spot1, spot2, FALSE, self);
if (trace_ent != targ)
return FALSE; // don't have a clear shot
if (trace_inopen && trace_inwater)
return FALSE; // sight line crossed contents
if (enemy_range == RANGE_MELEE)
{ // melee attack
if (self.th_melee)
{
if (self.classname == "monster_knight")
knight_attack ();
else
self.th_melee ();
return TRUE;
}
}
// missile attack
if (!self.th_missile)
return FALSE;
if (time < self.attack_finished)
return FALSE;
if (enemy_range == RANGE_FAR)
return FALSE;
if (enemy_range == RANGE_MELEE)
{
chance = 0.9;
self.attack_finished = 0;
}
else if (enemy_range == RANGE_NEAR)
{
if (self.th_melee)
chance = 0.2;
else
chance = 0.4;
}
else if (enemy_range == RANGE_MID)
{
if (self.th_melee)
chance = 0.05;
else
chance = 0.1;
}
else
chance = 0;
if (random () < chance)
{
self.th_missile ();
SUB_AttackFinished (2*random());
return TRUE;
}
return FALSE;
};
/*
=============
ai_face
Stay facing the enemy
=============
*/
void() ai_face =
{
self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
ChangeYaw ();
};
/*
=============
ai_charge
The monster is in a melee attack, so get as close as possible to .enemy
=============
*/
float (entity targ) visible;
float(entity targ) infront;
float(entity targ) range;
void(float d) ai_charge =
{
ai_face ();
movetogoal (d); // done in C code...
};
void() ai_charge_side =
{
local vector dtemp;
local float heading;
// aim to the left of the enemy for a flyby
self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
ChangeYaw ();
makevectors (self.angles);
dtemp = self.enemy.origin - 30*v_right;
heading = vectoyaw(dtemp - self.origin);
walkmove(heading, 20);
};
/*
=============
ai_melee
=============
*/
void() ai_melee =
{
local vector delta;
local float ldmg;
if (!self.enemy)
return; // removed before stroke
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 60)
return;
ldmg = (random() + random() + random()) * 3;
T_Damage (self.enemy, self, self, ldmg);
};
void() ai_melee_side =
{
local vector delta;
local float ldmg;
if (!self.enemy)
return; // removed before stroke
ai_charge_side();
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 60)
return;
if (!CanDamage (self.enemy, self))
return;
ldmg = (random() + random() + random()) * 3;
T_Damage (self.enemy, self, self, ldmg);
};
//=============================================================================
/*
===========
SoldierCheckAttack
The player is in view, so decide to move or launch an attack
Returns FALSE if movement should continue
============
*/
float() SoldierCheckAttack =
{
local vector spot1, spot2;
local entity targ;
local float chance;
targ = self.enemy;
// see if any entities are in the way of the shot
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
traceline (spot1, spot2, FALSE, self);
if (trace_inopen && trace_inwater)
return FALSE; // sight line crossed contents
if (trace_ent != targ)
return FALSE; // don't have a clear shot
// missile attack
if (time < self.attack_finished)
return FALSE;
if (enemy_range == RANGE_FAR)
return FALSE;
if (enemy_range == RANGE_MELEE)
chance = 0.9;
else if (enemy_range == RANGE_NEAR)
chance = 0.4;
else if (enemy_range == RANGE_MID)
chance = 0.05;
else
chance = 0;
if (random () < chance)
{
self.th_missile ();
SUB_AttackFinished (1 + random());
if (random() < 0.3)
self.lefty = !self.lefty;
return TRUE;
}
return FALSE;
};
//=============================================================================
/*
===========
ShamCheckAttack
The player is in view, so decide to move or launch an attack
Returns FALSE if movement should continue
============
*/
float() ShamCheckAttack =
{
local vector spot1, spot2;
local entity targ;
local float chance;
local float enemy_yaw;
if (enemy_range == RANGE_MELEE)
{
if (CanDamage (self.enemy, self))
{
self.attack_state = AS_MELEE;
return TRUE;
}
}
if (time < self.attack_finished)
return FALSE;
if (!enemy_vis)
return FALSE;
targ = self.enemy;
// 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(spot1 - spot2) > 600)
return FALSE;
traceline (spot1, spot2, FALSE, self);
if (trace_inopen && trace_inwater)
return FALSE; // sight line crossed contents
if (trace_ent != targ)
{
return FALSE; // don't have a clear shot
}
// missile attack
if (enemy_range == RANGE_FAR)
return FALSE;
self.attack_state = AS_MISSILE;
SUB_AttackFinished (2 + 2*random());
return TRUE;
};
//============================================================================
/*
===========
OgreCheckAttack
The player is in view, so decide to move or launch an attack
Returns FALSE if movement should continue
============
*/
float() OgreCheckAttack =
{
local vector spot1, spot2;
local entity targ;
local float chance;
if (enemy_range == RANGE_MELEE)
{
if (CanDamage (self.enemy, self))
{
self.attack_state = AS_MELEE;
return TRUE;
}
}
if (time < self.attack_finished)
return FALSE;
if (!enemy_vis)
return FALSE;
targ = self.enemy;
// see if any entities are in the way of the shot
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
traceline (spot1, spot2, FALSE, self);
if (trace_inopen && trace_inwater)
return FALSE; // sight line crossed contents
if (trace_ent != targ)
{
return FALSE; // don't have a clear shot
}
// missile attack
if (time < self.attack_finished)
return FALSE;
if (enemy_range == RANGE_FAR)
return FALSE;
else if (enemy_range == RANGE_NEAR)
chance = 0.10;
else if (enemy_range == RANGE_MID)
chance = 0.05;
else
chance = 0;
self.attack_state = AS_MISSILE;
SUB_AttackFinished (1 + 2*random());
return TRUE;
};

530
FILES.DAT Normal file
View File

@ -0,0 +1,530 @@
272
1 misc/flagtk.wav
1 misc/flagcap.wav
1 misc/flagret.wav
1 runes/end1.wav
1 runes/end2.wav
1 runes/end3.wav
1 runes/end4.wav
1 items/r_item1.wav
1 items/r_item2.wav
1 items/health1.wav
1 misc/medkey.wav
1 misc/runekey.wav
2 misc/basekey.wav
1 items/protect.wav
1 items/protect2.wav
1 items/protect3.wav
1 items/suit.wav
1 items/suit2.wav
1 items/inv1.wav
1 items/inv2.wav
1 items/inv3.wav
1 items/damage.wav
1 items/damage2.wav
1 items/damage3.wav
1 weapons/r_exp3.wav
1 weapons/rocket1i.wav
1 weapons/sgun1.wav
1 weapons/guncock.wav
1 weapons/ric1.wav
1 weapons/ric2.wav
1 weapons/ric3.wav
1 weapons/spike2.wav
1 weapons/tink1.wav
1 weapons/grenade.wav
1 weapons/bounce.wav
1 weapons/shotgn2.wav
1 weapons/chain1.wav
1 pendulum/hit.wav
1 lavagun/snail.wav
1 misc/menu1.wav
1 misc/menu2.wav
1 misc/menu3.wav
1 ambience/water1.wav
1 ambience/wind2.wav
1 demon/dland2.wav
1 misc/h2ohit1.wav
1 items/itembk2.wav
1 player/plyrjmp8.wav
1 player/land.wav
1 player/land2.wav
1 player/drown1.wav
1 player/drown2.wav
1 player/gasp1.wav
1 player/gasp2.wav
1 player/h2odeath.wav
1 misc/talk.wav
1 player/teledth1.wav
1 misc/r_tele1.wav
1 misc/r_tele2.wav
1 misc/r_tele3.wav
1 misc/r_tele4.wav
1 misc/r_tele5.wav
1 weapons/lock4.wav
1 weapons/pkup.wav
1 items/armor1.wav
1 weapons/lhit.wav
1 weapons/lstart.wav
1 misc/power.wav
1 player/gib.wav
1 player/udeath.wav
1 player/tornoff2.wav
1 player/pain1.wav
1 player/pain2.wav
1 player/pain3.wav
1 player/pain4.wav
1 player/pain5.wav
1 player/pain6.wav
1 player/death1.wav
1 player/death2.wav
1 player/death3.wav
1 player/death4.wav
1 player/death5.wav
1 weapons/ax1.wav
1 player/axhit1.wav
1 player/axhit2.wav
1 player/h2ojump.wav
1 player/slimbrn2.wav
1 player/inh2o.wav
1 player/inlava.wav
1 misc/outwater.wav
1 player/lburn1.wav
1 player/lburn2.wav
1 misc/water1.wav
1 misc/water2.wav
1 enforcer/enfstop.wav
1 plasma/explode.wav
1 plasma/flight.wav
1 plasma/fire.wav
1 shield/hit.wav
1 belt/use.wav
1 doors/medtry.wav
1 doors/meduse.wav
1 doors/runetry.wav
1 doors/runeuse.wav
1 doors/basetry.wav
1 doors/baseuse.wav
1 misc/null.wav
1 doors/drclos4.wav
1 doors/doormv1.wav
1 doors/hydro1.wav
1 doors/hydro2.wav
1 doors/stndr1.wav
1 doors/stndr2.wav
1 doors/ddoor1.wav
1 doors/ddoor2.wav
1 doors/latch2.wav
1 doors/winch2.wav
1 doors/airdoor1.wav
1 doors/airdoor2.wav
1 doors/basesec1.wav
1 doors/basesec2.wav
1 buttons/airbut1.wav
1 buttons/switch21.wav
1 buttons/switch02.wav
1 buttons/switch04.wav
1 misc/secret.wav
1 misc/trigger1.wav
1 ambience/hum1.wav
1 ambience/windfly.wav
1 plats/plat1.wav
1 plats/plat2.wav
1 plats/medplat1.wav
1 plats/medplat2.wav
1 plats/train2.wav
1 plats/train1.wav
1 ambience/fl_hum1.wav
1 ambience/buzz1.wav
1 ambience/fire1.wav
2 enforcer/enfire.wav
1 ambience/suck1.wav
1 ambience/drone6.wav
1 ambience/drip1.wav
1 ambience/comp1.wav
1 ambience/thunder1.wav
1 ambience/swamp1.wav
1 ambience/swamp2.wav
2 enforcer/sight1.wav
2 enforcer/sight2.wav
2 enforcer/sight3.wav
2 enforcer/sight4.wav
2 enforcer/pain1.wav
2 enforcer/pain2.wav
2 enforcer/death1.wav
2 enforcer/idle1.wav
1 ogre/ogdrag.wav
1 ogre/ogdth.wav
1 ogre/ogidle.wav
1 ogre/ogidle2.wav
1 ogre/ogpain1.wav
1 ogre/ogsawatk.wav
1 ogre/ogwake.wav
1 demon/ddeath.wav
1 demon/dhit2.wav
1 demon/djump.wav
1 demon/dpain1.wav
1 demon/idle1.wav
1 demon/sight2.wav
1 shambler/sattck1.wav
1 shambler/sboom.wav
1 shambler/sdeath.wav
1 shambler/shurt2.wav
1 shambler/sidle.wav
1 shambler/ssight.wav
1 shambler/melee1.wav
1 shambler/melee2.wav
1 shambler/smack.wav
1 statue/see.wav
1 statue/idle.wav
1 statue/pain.wav
1 statue/death.wav
1 knight/kdeath.wav
1 knight/khurt.wav
1 knight/ksight.wav
1 knight/idle.wav
1 knight/sword1.wav
1 knight/sword2.wav
1 soldier/death1.wav
1 soldier/idle.wav
1 soldier/pain1.wav
1 soldier/pain2.wav
1 soldier/sattck1.wav
1 soldier/sight1.wav
1 wizard/hit.wav
1 wizard/wattack.wav
1 wizard/wdeath.wav
1 wizard/widle1.wav
1 wizard/widle2.wav
1 wizard/wpain.wav
1 wizard/wsight.wav
1 dog/dattack1.wav
1 dog/ddeath.wav
1 dog/dpain1.wav
1 dog/dsight.wav
1 dog/idle.wav
1 zombie/z_idle.wav
1 zombie/z_idle1.wav
1 zombie/z_shot1.wav
1 zombie/z_gib.wav
1 zombie/z_pain.wav
1 zombie/z_pain1.wav
1 zombie/z_fall.wav
1 zombie/z_miss.wav
1 zombie/z_hit.wav
1 zombie/idle_w2.wav
1 boss1/out1.wav
1 boss1/sight1.wav
1 boss1/throw.wav
1 boss1/pain.wav
1 boss1/death.wav
2 blob/death1.wav
2 blob/hit1.wav
2 blob/land1.wav
2 blob/sight1.wav
2 blob/mytosis.wav
2 hknight/death1.wav
2 hknight/pain1.wav
2 hknight/sight1.wav
2 hknight/idle.wav
2 hknight/attack1.wav
1 hknight/hit.wav
2 hknight/slash1.wav
2 hknight/grunt.wav
2 fish/death.wav
2 fish/bite.wav
2 fish/idle.wav
2 shalrath/attack.wav
2 shalrath/attack2.wav
2 shalrath/death.wav
2 shalrath/idle.wav
2 shalrath/pain.wav
2 shalrath/sight.wav
2 boss2/death.wav
2 boss2/idle.wav
2 boss2/sight.wav
2 boss2/pop2.wav
1 eel/edie3r.wav
1 eel/epain3.wav
1 eel/eactive1.wav
1 eel/eatt1.wav
1 eel/eelc5.wav
1 shield/pickup.wav
1 shield/fadeout.wav
1 belt/pickup.wav
1 belt/fadeout.wav
1 pendulum/swing.wav
1 wrath/wsee.wav
1 wrath/watt.wav
1 wrath/wpain.wav
1 wrath/wdthc.wav
1 dragon/see.wav
1 dragon/active.wav
1 dragon/attack.wav
1 dragon/pain.wav
1 dragon/death.wav
1 s_wrath/smash.wav
1 equake/rumble.wav
1 sphere/sphere.wav
1 buzz/buzz.wav
1 buzz/buzz1.wav
2 guard/death.wav
2 guard/pain1.wav
2 guard/see1.wav
151
1 progs/ctfbase.mdl
1 progs/ctfmodel.mdl
1 progs/end1.mdl
1 progs/end2.mdl
1 progs/end3.mdl
1 progs/end4.mdl
1 maps/b_bh10.bsp
1 maps/b_bh100.bsp
1 maps/b_bh25.bsp
1 progs/armor.mdl
1 progs/g_shot.mdl
1 progs/g_nail.mdl
1 progs/g_nail2.mdl
1 progs/g_rock.mdl
1 progs/g_rock2.mdl
1 progs/g_light.mdl
1 maps/b_shell1.bsp
1 maps/b_shell0.bsp
1 maps/b_nail1.bsp
1 maps/b_nail0.bsp
1 maps/b_lnail1.bsp
1 maps/b_lnail0.bsp
1 maps/b_rock1.bsp
1 maps/b_rock0.bsp
1 maps/b_mrock1.bsp
1 maps/b_mrock0.bsp
1 maps/b_batt1.bsp
1 maps/b_batt0.bsp
1 maps/b_plas1.bsp
1 maps/b_plas0.bsp
1 progs/w_s_key.mdl
1 progs/m_s_key.mdl
2 progs/b_s_key.mdl
1 progs/w_g_key.mdl
1 progs/m_g_key.mdl
2 progs/b_g_key.mdl
1 progs/invulner.mdl
1 progs/suit.mdl
1 progs/invisibl.mdl
1 progs/quaddama.mdl
1 progs/player.mdl
1 progs/eyes.mdl
1 progs/h_player.mdl
1 progs/gib1.mdl
1 progs/gib2.mdl
1 progs/gib3.mdl
1 progs/s_bubble.spr
1 progs/s_explod.spr
1 progs/v_axe.mdl
1 progs/v_shot.mdl
1 progs/v_nail.mdl
1 progs/v_rock.mdl
1 progs/v_shot2.mdl
1 progs/v_nail2.mdl
1 progs/v_rock2.mdl
1 progs/v_lava.mdl
1 progs/v_lava2.mdl
1 progs/v_multi.mdl
1 progs/v_multi2.mdl
1 progs/bolt.mdl
1 progs/bolt2.mdl
1 progs/bolt3.mdl
1 progs/lavaball.mdl
1 progs/missile.mdl
1 progs/grenade.mdl
1 progs/spike.mdl
1 progs/s_spike.mdl
1 progs/mervup.mdl
1 progs/rockup.mdl
1 progs/rockup_d.mdl
1 progs/lspike.mdl
1 progs/shield.mdl
1 progs/p_shield.mdl
1 progs/backpack.mdl
1 progs/zom_gib.mdl
1 progs/v_light.mdl
1 progs/plasma.mdl
1 progs/v_plasma.mdl
1 progs/hook.mdl
1 progs/v_grpple.mdl
2 progs/teleport.mdl
1 progs/s_light.spr
1 progs/flame.mdl
1 progs/flame2.mdl
1 maps/b_explob.bsp
2 maps/b_exbox2.bsp
2 progs/laser.mdl
1 progs/fireball.mdl
1 progs/ogre.mdl
1 progs/h_ogre.mdl
1 progs/demon.mdl
1 progs/h_demon.mdl
1 progs/shambler.mdl
1 progs/s_light.mdl
1 progs/h_shams.mdl
1 progs/knight.mdl
1 progs/h_knight.mdl
1 progs/statgib1.mdl
1 progs/statgib2.mdl
1 progs/statgib3.mdl
1 progs/soldier.mdl
1 progs/h_guard.mdl
1 progs/wizard.mdl
1 progs/h_wizard.mdl
1 progs/w_spike.mdl
1 progs/h_dog.mdl
1 progs/dog.mdl
1 progs/zombie.mdl
1 progs/h_zombie.mdl
1 progs/boss.mdl
2 progs/tarbaby.mdl
2 progs/hknight.mdl
2 progs/k_spike.mdl
2 progs/h_hellkn.mdl
2 progs/fish.mdl
2 progs/shalrath.mdl
2 progs/h_shal.mdl
2 progs/v_spike.mdl
2 progs/enforcer.mdl
2 progs/h_mega.mdl
2 progs/oldone.mdl
1 progs/eel2.mdl
1 progs/eelgib.mdl
1 progs/sword.mdl
1 progs/beltup.mdl
1 progs/lantern.mdl
1 progs/candle.mdl
1 progs/rubble.mdl
1 progs/pendulum.mdl
1 progs/wrath.mdl
1 progs/w_ball.mdl
1 progs/wrthgib1.mdl
1 progs/wrthgib2.mdl
1 progs/wrthgib3.mdl
1 progs/dragon.mdl
1 progs/drggib01.mdl
1 progs/drggib02.mdl
1 progs/drggib03.mdl
1 progs/s_wrath.mdl
1 progs/s_wrtgb2.mdl
1 progs/s_wrtgb3.mdl
1 progs/lavaman.mdl
1 progs/sphere.mdl
1 progs/buzzsaw.mdl
1 progs/morph_az.mdl
1 progs/morph_eg.mdl
1 progs/morph_gr.mdl
1 progs/mummy.mdl
1 progs/timemach.mdl
1 progs/timegib.mdl
1 progs/timecore.mdl
104
1 progs.dat
1 gfx.wad
1 quake.rc
1 default.cfg
1 end1.bin
2 end2.bin
1 demo1.dem
1 demo2.dem
1 demo3.dem
1 gfx/palette.lmp
1 gfx/colormap.lmp
2 gfx/pop.lmp
1 gfx/complete.lmp
1 gfx/inter.lmp
1 gfx/ranking.lmp
1 gfx/vidmodes.lmp
1 gfx/finale.lmp
1 gfx/conback.lmp
1 gfx/qplaque.lmp
1 gfx/menudot1.lmp
1 gfx/menudot2.lmp
1 gfx/menudot3.lmp
1 gfx/menudot4.lmp
1 gfx/menudot5.lmp
1 gfx/menudot6.lmp
1 gfx/menuplyr.lmp
1 gfx/bigbox.lmp
1 gfx/dim_modm.lmp
1 gfx/dim_drct.lmp
1 gfx/dim_ipx.lmp
1 gfx/dim_tcp.lmp
1 gfx/dim_mult.lmp
1 gfx/mainmenu.lmp
1 gfx/box_tl.lmp
1 gfx/box_tm.lmp
1 gfx/box_tr.lmp
1 gfx/box_ml.lmp
1 gfx/box_mm.lmp
1 gfx/box_mm2.lmp
1 gfx/box_mr.lmp
1 gfx/box_bl.lmp
1 gfx/box_bm.lmp
1 gfx/box_br.lmp
1 gfx/sp_menu.lmp
1 gfx/ttl_sgl.lmp
1 gfx/ttl_main.lmp
1 gfx/ttl_cstm.lmp
1 gfx/mp_menu.lmp
1 gfx/netmen1.lmp
1 gfx/netmen2.lmp
1 gfx/netmen3.lmp
1 gfx/netmen4.lmp
1 gfx/netmen5.lmp
1 gfx/sell.lmp
1 gfx/help0.lmp
1 gfx/help1.lmp
1 gfx/help2.lmp
1 gfx/help3.lmp
1 gfx/help4.lmp
1 gfx/help5.lmp
1 gfx/pause.lmp
1 gfx/loading.lmp
1 gfx/p_option.lmp
1 gfx/p_load.lmp
1 gfx/p_save.lmp
1 gfx/p_multi.lmp
1 maps/start.bsp
1 maps/e1m1.bsp
1 maps/e1m2.bsp
1 maps/e1m3.bsp
1 maps/e1m4.bsp
1 maps/e1m5.bsp
1 maps/e1m6.bsp
1 maps/e1m7.bsp
1 maps/e1m8.bsp
2 maps/e2m1.bsp
2 maps/e2m2.bsp
2 maps/e2m3.bsp
2 maps/e2m4.bsp
2 maps/e2m5.bsp
2 maps/e2m6.bsp
2 maps/e2m7.bsp
2 maps/e3m1.bsp
2 maps/e3m2.bsp
2 maps/e3m3.bsp
2 maps/e3m4.bsp
2 maps/e3m5.bsp
2 maps/e3m6.bsp
2 maps/e3m7.bsp
2 maps/e4m1.bsp
2 maps/e4m2.bsp
2 maps/e4m3.bsp
2 maps/e4m4.bsp
2 maps/e4m5.bsp
2 maps/e4m6.bsp
2 maps/e4m7.bsp
2 maps/e4m8.bsp
2 maps/end.bsp
2 maps/dm1.bsp
2 maps/dm2.bsp
2 maps/dm3.bsp
2 maps/dm4.bsp
2 maps/dm5.bsp
2 maps/dm6.bsp

187
FISH.QC Normal file
View File

@ -0,0 +1,187 @@
$cd /raid/quake/id1/models/fish
$origin 0 0 24
$base base
$skin skin
$frame attack1 attack2 attack3 attack4 attack5 attack6
$frame attack7 attack8 attack9 attack10 attack11 attack12 attack13
$frame attack14 attack15 attack16 attack17 attack18
$frame death1 death2 death3 death4 death5 death6 death7
$frame death8 death9 death10 death11 death12 death13 death14 death15
$frame death16 death17 death18 death19 death20 death21
$frame swim1 swim2 swim3 swim4 swim5 swim6 swim7 swim8
$frame swim9 swim10 swim11 swim12 swim13 swim14 swim15 swim16 swim17
$frame swim18
$frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8
$frame pain9
void() swimmonster_start;
void() f_stand1 =[ $swim1, f_stand2 ] {ai_stand();};
void() f_stand2 =[ $swim2, f_stand3 ] {ai_stand();};
void() f_stand3 =[ $swim3, f_stand4 ] {ai_stand();};
void() f_stand4 =[ $swim4, f_stand5 ] {ai_stand();};
void() f_stand5 =[ $swim5, f_stand6 ] {ai_stand();};
void() f_stand6 =[ $swim6, f_stand7 ] {ai_stand();};
void() f_stand7 =[ $swim7, f_stand8 ] {ai_stand();};
void() f_stand8 =[ $swim8, f_stand9 ] {ai_stand();};
void() f_stand9 =[ $swim9, f_stand10 ] {ai_stand();};
void() f_stand10 =[ $swim10, f_stand11 ] {ai_stand();};
void() f_stand11 =[ $swim11, f_stand12 ] {ai_stand();};
void() f_stand12 =[ $swim12, f_stand13 ] {ai_stand();};
void() f_stand13 =[ $swim13, f_stand14 ] {ai_stand();};
void() f_stand14 =[ $swim14, f_stand15 ] {ai_stand();};
void() f_stand15 =[ $swim15, f_stand16 ] {ai_stand();};
void() f_stand16 =[ $swim16, f_stand17 ] {ai_stand();};
void() f_stand17 =[ $swim17, f_stand18 ] {ai_stand();};
void() f_stand18 =[ $swim18, f_stand1 ] {ai_stand();};
void() f_walk1 =[ $swim1, f_walk2 ] {ai_walk(8);};
void() f_walk2 =[ $swim2, f_walk3 ] {ai_walk(8);};
void() f_walk3 =[ $swim3, f_walk4 ] {ai_walk(8);};
void() f_walk4 =[ $swim4, f_walk5 ] {ai_walk(8);};
void() f_walk5 =[ $swim5, f_walk6 ] {ai_walk(8);};
void() f_walk6 =[ $swim6, f_walk7 ] {ai_walk(8);};
void() f_walk7 =[ $swim7, f_walk8 ] {ai_walk(8);};
void() f_walk8 =[ $swim8, f_walk9 ] {ai_walk(8);};
void() f_walk9 =[ $swim9, f_walk10 ] {ai_walk(8);};
void() f_walk10 =[ $swim10, f_walk11 ] {ai_walk(8);};
void() f_walk11 =[ $swim11, f_walk12 ] {ai_walk(8);};
void() f_walk12 =[ $swim12, f_walk13 ] {ai_walk(8);};
void() f_walk13 =[ $swim13, f_walk14 ] {ai_walk(8);};
void() f_walk14 =[ $swim14, f_walk15 ] {ai_walk(8);};
void() f_walk15 =[ $swim15, f_walk16 ] {ai_walk(8);};
void() f_walk16 =[ $swim16, f_walk17 ] {ai_walk(8);};
void() f_walk17 =[ $swim17, f_walk18 ] {ai_walk(8);};
void() f_walk18 =[ $swim18, f_walk1 ] {ai_walk(8);};
void() f_run1 =[ $swim1, f_run2 ] {ai_run(12);
if (random() < 0.5)
sound (self, CHAN_VOICE, "fish/idle.wav", 1, ATTN_NORM);
};
void() f_run2 =[ $swim3, f_run3 ] {ai_run(12);};
void() f_run3 =[ $swim5, f_run4 ] {ai_run(12);};
void() f_run4 =[ $swim7, f_run5 ] {ai_run(12);};
void() f_run5 =[ $swim9, f_run6 ] {ai_run(12);};
void() f_run6 =[ $swim11, f_run7 ] {ai_run(12);};
void() f_run7 =[ $swim13, f_run8 ] {ai_run(12);};
void() f_run8 =[ $swim15, f_run9 ] {ai_run(12);};
void() f_run9 =[ $swim17, f_run1 ] {ai_run(12);};
void() fish_melee =
{
local vector delta;
local float ldmg;
if (!self.enemy)
return; // removed before stroke
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 60)
return;
sound (self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
ldmg = (random() + random()) * 3;
T_Damage (self.enemy, self, self, ldmg);
};
void() f_attack1 =[ $attack1, f_attack2 ] {ai_charge(10);};
void() f_attack2 =[ $attack2, f_attack3 ] {ai_charge(10);};
void() f_attack3 =[ $attack3, f_attack4 ] {fish_melee();};
void() f_attack4 =[ $attack4, f_attack5 ] {ai_charge(10);};
void() f_attack5 =[ $attack5, f_attack6 ] {ai_charge(10);};
void() f_attack6 =[ $attack6, f_attack7 ] {ai_charge(10);};
void() f_attack7 =[ $attack7, f_attack8 ] {ai_charge(10);};
void() f_attack8 =[ $attack8, f_attack9 ] {ai_charge(10);};
void() f_attack9 =[ $attack9, f_attack10] {fish_melee();};
void() f_attack10 =[ $attack10, f_attack11] {ai_charge(10);};
void() f_attack11 =[ $attack11, f_attack12] {ai_charge(10);};
void() f_attack12 =[ $attack12, f_attack13] {ai_charge(10);};
void() f_attack13 =[ $attack13, f_attack14] {ai_charge(10);};
void() f_attack14 =[ $attack14, f_attack15] {ai_charge(10);};
void() f_attack15 =[ $attack15, f_attack16] {fish_melee();};
void() f_attack16 =[ $attack16, f_attack17] {ai_charge(10);};
void() f_attack17 =[ $attack17, f_attack18] {ai_charge(10);};
void() f_attack18 =[ $attack18, f_run1 ] {ai_charge(10);};
void() f_death1 =[ $death1, f_death2 ] {
sound (self, CHAN_VOICE, "fish/death.wav", 1, ATTN_NORM);
};
void() f_death2 =[ $death2, f_death3 ] {};
void() f_death3 =[ $death3, f_death4 ] {};
void() f_death4 =[ $death4, f_death5 ] {};
void() f_death5 =[ $death5, f_death6 ] {};
void() f_death6 =[ $death6, f_death7 ] {};
void() f_death7 =[ $death7, f_death8 ] {};
void() f_death8 =[ $death8, f_death9 ] {};
void() f_death9 =[ $death9, f_death10 ] {};
void() f_death10 =[ $death10, f_death11 ] {};
void() f_death11 =[ $death11, f_death12 ] {};
void() f_death12 =[ $death12, f_death13 ] {};
void() f_death13 =[ $death13, f_death14 ] {};
void() f_death14 =[ $death14, f_death15 ] {};
void() f_death15 =[ $death15, f_death16 ] {};
void() f_death16 =[ $death16, f_death17 ] {};
void() f_death17 =[ $death17, f_death18 ] {};
void() f_death18 =[ $death18, f_death19 ] {};
void() f_death19 =[ $death19, f_death20 ] {};
void() f_death20 =[ $death20, f_death21 ] {};
void() f_death21 =[ $death21, f_death21 ] {self.solid = SOLID_NOT;};
void() f_pain1 =[ $pain1, f_pain2 ] {};
void() f_pain2 =[ $pain2, f_pain3 ] {ai_pain(6);};
void() f_pain3 =[ $pain3, f_pain4 ] {ai_pain(6);};
void() f_pain4 =[ $pain4, f_pain5 ] {ai_pain(6);};
void() f_pain5 =[ $pain5, f_pain6 ] {ai_pain(6);};
void() f_pain6 =[ $pain6, f_pain7 ] {ai_pain(6);};
void() f_pain7 =[ $pain7, f_pain8 ] {ai_pain(6);};
void() f_pain8 =[ $pain8, f_pain9 ] {ai_pain(6);};
void() f_pain9 =[ $pain9, f_run1 ] {ai_pain(6);};
void(entity attacker, float damage) fish_pain =
{
// fish allways do pain frames
f_pain1 ();
};
//(-16 -16 -24) (16 16 24)
/*QUAKED monster_fish (1 0 0) (-16 -16 -24) (16 16 32) Ambush
*/
void() monster_fish =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model2 ("progs/fish.mdl");
precache_sound2 ("fish/death.wav");
precache_sound2 ("fish/bite.wav");
precache_sound2 ("fish/idle.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/fish.mdl");
// setsize (self, '-16 -16 -24', '16 16 24');
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
self.health = 25;
self.th_stand = f_stand1;
self.th_walk = f_walk1;
self.th_run = f_run1;
self.th_die = f_death1;
self.th_pain = fish_pain;
self.th_melee = f_attack1;
swimmonster_start ();
};

309
GRAPPLE.QC Normal file
View File

@ -0,0 +1,309 @@
// Rogue Grapple Implementation
// Jan'97 by ZOID <zoid@threewave.com>
// Under contract to id software for Rogue Entertainment
// New entity fields
.entity hook; // this is my hook
.float on_hook; // we're on it
.float hook_out; // it's out
// prototypes for WEAPONS.QC functions
float() crandom;
void(vector org, vector vel, float damage) SpawnBlood;
void(entity h, entity player) GrappleTrail =
{
// draw a line to the hook
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_BEAM);
WriteEntity (MSG_BROADCAST, h);
WriteCoord (MSG_BROADCAST, h.origin_x);
WriteCoord (MSG_BROADCAST, h.origin_y);
WriteCoord (MSG_BROADCAST, h.origin_z);
WriteCoord (MSG_BROADCAST, player.origin_x);
WriteCoord (MSG_BROADCAST, player.origin_y);
WriteCoord (MSG_BROADCAST, player.origin_z + 16);
};
void() GrappleReset =
{
self.owner.on_hook = FALSE;
self.owner.hook_out = FALSE;
self.owner.weaponframe = 0;
self.owner.attack_finished = time +0.25;
remove(self);
};
void() GrappleTrack =
{
local vector spray;
// Release dead targets
if (self.enemy.classname == "player" && self.enemy.health <= 0)
self.owner.on_hook = FALSE;
// drop the hook if owner is dead or has released the button
if (!self.owner.on_hook || self.owner.health <= 0) {
GrappleReset();
return;
}
if (self.enemy.classname == "player")
{
if (self.enemy.teleport_time > time)
{
GrappleReset();
return;
}
// move the hook along with the player. It's invisible, but
// we need this to make the sound come from the right spot
setorigin(self, self.enemy.origin);
// sound (self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM);
sound (self, CHAN_WEAPON, "pendulum/hit.wav", 1, ATTN_NORM);
T_Damage (self.enemy, self, self.owner, 1);
makevectors (self.v_angle);
spray_x = 100 * crandom();
spray_y = 100 * crandom();
spray_z = 100 * crandom() + 50;
SpawnBlood(self.origin, spray, 20);
}
if (self.enemy.solid == SOLID_SLIDEBOX) {
self.velocity = '0 0 0';
setorigin(self, self.enemy.origin + self.enemy.mins +
self.enemy.size * 0.5);
} else
self.velocity = self.enemy.velocity;
self.nextthink = time + 0.1;
};
/*
entity(float head) GrappleMakeLink =
{
newmis = spawn ();
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_NOT;
newmis.owner = self;// SELF is the hook!
newmis.avelocity = '200 200 200';
setmodel (newmis, "progs/bit.mdl");
setorigin (newmis, self.origin);
setsize (newmis, '0 0 0' , '0 0 0');
return newmis;
};
*/
// Removes all chain link entities; this is a separate function because CLIENT
// also needs to be able to remove the chain. Only one function required to
// remove all links.
/*
void () GrappleRemoveChain =
{
self.think = SUB_Remove;
self.nextthink = time;
if (self.goalentity) {
self.goalentity.think = SUB_Remove;
self.goalentity.nextthink = time;
if (self.goalentity.goalentity) {
self.goalentity.goalentity.think = SUB_Remove;
self.goalentity.goalentity.nextthink = time;
}
}
};
*/
// Repositions the chain links each frame. This single function maintains the
// positions of all of the links. Only one link is thinking every frame.
/*
void() GrappleUpdateChain =
{
local vector temp;
if (!self.owner.hook_out) {
GrappleRemoveChain();
return;
}
temp = (self.owner.hook.origin - self.owner.origin);
// These numbers are correct assuming 3 links.
// 4 links would be *20 *40 *60 and *80
setorigin (self, self.owner.origin + temp * 0.25);
setorigin (self.goalentity, self.owner.origin + temp * 0.5);
setorigin (self.goalentity.goalentity, self.owner.origin + temp * 0.75);
self.nextthink = time + 0.1;
};
*/
//
// Build_Chain - Builds the chain (linked list)
//
/*
void() GrappleBuildChain =
{
self.goalentity = GrappleMakeLink();
self.goalentity.think = GrappleUpdateChain;
self.goalentity.nextthink = time + 0.1;
self.goalentity.owner = self.owner;
self.goalentity.goalentity = GrappleMakeLink();
self.goalentity.goalentity.goalentity = GrappleMakeLink();
};
*/
// Tries to anchor the grapple to whatever it touches
void () GrappleAnchor =
{
if (other == self.owner) // don't hook the guy that fired it
return;
if (pointcontents(self.origin) == CONTENT_SKY) {
GrappleReset();
return;
}
if (other.classname == "player")
{
// glance off of teammates
if (other.steam == self.owner.steam)
{
GrappleReset(); // PGM - fix drift after teammate hit 01/20/97
return;
}
sound (self, CHAN_WEAPON, "player/axhit1.wav", 1, ATTN_NORM);
T_Damage (other, self, self.owner, 10);
} else {
sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
// One point of damage inflicted upon impact. Subsequent
// damage will only be done to PLAYERS... this way secret
// doors and triggers will only be damaged once.
if (other.takedamage)
T_Damage (other, self, self.owner, 1);
self.velocity = '0 0 0';
self.avelocity = '0 0 0';
}
self.frame = 2; // anchored
sound (self.owner, CHAN_WEAPON, "weapons/tink1.wav", 1, ATTN_NORM);
if (!self.owner.button0) {
GrappleReset();
return;
}
self.owner.on_hook = TRUE;
if (self.owner.flags & FL_ONGROUND)
self.owner.flags = self.owner.flags - FL_ONGROUND;
// CHAIN2 is a looping sample. Use LEFTY as a flag so that client.qc
// will know to only play the tink sound ONCE to clear the weapons
// sound channel. (Lefty is a leftover from AI.QC, so I reused it to
// avoid adding a field)
self.owner.lefty = TRUE;
self.enemy = other;// remember this guy!
self.think = GrappleTrack;
self.nextthink = time;
self.solid = SOLID_NOT;
self.touch = SUB_Null;
};
void () W_FireGrapple =
{
if (self.hook_out)// reject subsequent calls from player.qc
return;
self.punchangle_x = -2; // bump him
// chain out sound (loops)
sound (self, CHAN_WEAPON, "weapons/chain1.wav", 1, ATTN_NORM);
newmis = spawn();
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_BBOX;
newmis.owner = self; // newmis belongs to me
self.hook = newmis; // This is my newmis
newmis.classname = "hook";
makevectors (self.v_angle);
newmis.velocity = v_forward * 800;
// newmis.avelocity = '0 0 -500';
newmis.angles = vectoangles(v_forward);
newmis.touch = GrappleAnchor;
newmis.think = GrappleReset;
// grapple only lives for two seconds, this gives max range on it
newmis.nextthink = time + 2;
newmis.frame = 1; // hook spread
setmodel (newmis,"progs/hook.mdl");
setorigin (newmis, self.origin + v_forward * 16 + '0 0 16');
setsize(newmis, '0 0 0' , '0 0 0 ');
self.hook_out = TRUE;
};
// called each frame by CLIENT.QC if client has hook_out
void() GrappleService =
{
local vector o, dist, vel;
local float v;
if (!self.on_hook) {
// just draw a line to the hook
if (vlen(self.hook.origin - self.origin) > 50)
GrappleTrail(self.hook, self);
return;
}
// drop the hook if player lets go of button
if ((!self.button0 && self.weapon == IT_GRAPPLE) ||
self.teleport_time > time)
{ // release when we get 'ported
self = self.hook;
GrappleReset();
return;
}
makevectors (self.angles);
dist = self.hook.origin - self.origin;
vel = self.hook.origin - ( self.origin + (v_up * 16 *
(!self.button2)) + (v_forward * 16));
v = vlen (vel);
if (v <= 100)
vel = normalize(vel) * v * 10;
else
vel = normalize(vel) * 1000;
self.velocity = vel;
if ( vlen(dist) <= 50) {
if (self.lefty) { // cancel chain sound
// If there is a chain, ditch it now. We're
// close enough. Having extra entities lying around
// is never a good idea.
// if (self.hook.goalentity) {
// self.hook.goalentity.think = GrappleRemoveChain;
// self.hook.goalentity.nextthink = time;
// }
self.lefty = FALSE;// we've reset the sound channel.
}
} else
GrappleTrail(self.hook, self);
};

539
HKNIGHT.QC Normal file
View File

@ -0,0 +1,539 @@
/*
==============================================================================
KNIGHT
==============================================================================
*/
$cd /raid/quake/id1/models/knight2
$origin 0 0 24
$base base
$skin skin
$skin statue2
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9
$frame walk10 walk11 walk12 walk13 walk14 walk15 walk16 walk17
$frame walk18 walk19 walk20
$frame run1 run2 run3 run4 run5 run6 run7 run8
$frame pain1 pain2 pain3 pain4 pain5
$frame death1 death2 death3 death4 death5 death6 death7 death8
$frame death9 death10 death11 death12
$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
$frame deathb9
$frame char_a1 char_a2 char_a3 char_a4 char_a5 char_a6 char_a7 char_a8
$frame char_a9 char_a10 char_a11 char_a12 char_a13 char_a14 char_a15 char_a16
$frame magica1 magica2 magica3 magica4 magica5 magica6 magica7 magica8
$frame magica9 magica10 magica11 magica12 magica13 magica14
$frame magicb1 magicb2 magicb3 magicb4 magicb5 magicb6 magicb7 magicb8
$frame magicb9 magicb10 magicb11 magicb12 magicb13
$frame char_b1 char_b2 char_b3 char_b4 char_b5 char_b6
$frame slice1 slice2 slice3 slice4 slice5 slice6 slice7 slice8 slice9 slice10
$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 smash8 smash9 smash10
$frame smash11
$frame w_attack1 w_attack2 w_attack3 w_attack4 w_attack5 w_attack6 w_attack7
$frame w_attack8 w_attack9 w_attack10 w_attack11 w_attack12 w_attack13 w_attack14
$frame w_attack15 w_attack16 w_attack17 w_attack18 w_attack19 w_attack20
$frame w_attack21 w_attack22
$frame magicc1 magicc2 magicc3 magicc4 magicc5 magicc6 magicc7 magicc8
$frame magicc9 magicc10 magicc11
void() hknight_char_a1;
void() hknight_run1;
void() hk_idle_sound;
void(float offset) hknight_shot =
{
local vector offang;
local vector org, vec;
offang = vectoangles (self.enemy.origin - self.origin);
offang_y = offang_y + offset * 6;
makevectors (offang);
org = self.origin + self.mins + self.size*0.5 + v_forward * 20;
// set missile speed
vec = normalize (v_forward);
vec_z = 0 - vec_z + (random() - 0.5)*0.1;
launch_spike (org, vec);
newmis.classname = "knightspike";
setmodel (newmis, "progs/k_spike.mdl");
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
newmis.velocity = vec*300;
sound (self, CHAN_WEAPON, "hknight/attack1.wav", 1, ATTN_NORM);
};
void() CheckForCharge =
{
// check for mad charge
if (!enemy_vis)
return;
if (time < self.attack_finished)
return;
if ( fabs(self.origin_z - self.enemy.origin_z) > 20)
return; // too much height change
if ( vlen (self.origin - self.enemy.origin) < 80)
return; // use regular attack
// charge
SUB_AttackFinished (2);
hknight_char_a1 ();
};
void() CheckContinueCharge =
{
if (time > self.attack_finished)
{
SUB_AttackFinished (3);
hknight_run1 ();
return; // done charging
}
if (random() > 0.5)
sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM);
else
sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
};
//===========================================================================
void() hknight_stand1 =[ $stand1, hknight_stand2 ] {ai_stand();};
void() hknight_stand2 =[ $stand2, hknight_stand3 ] {ai_stand();};
void() hknight_stand3 =[ $stand3, hknight_stand4 ] {ai_stand();};
void() hknight_stand4 =[ $stand4, hknight_stand5 ] {ai_stand();};
void() hknight_stand5 =[ $stand5, hknight_stand6 ] {ai_stand();};
void() hknight_stand6 =[ $stand6, hknight_stand7 ] {ai_stand();};
void() hknight_stand7 =[ $stand7, hknight_stand8 ] {ai_stand();};
void() hknight_stand8 =[ $stand8, hknight_stand9 ] {ai_stand();};
void() hknight_stand9 =[ $stand9, hknight_stand1 ] {ai_stand();};
//===========================================================================
void() hknight_walk1 =[ $walk1, hknight_walk2 ] {
hk_idle_sound();
ai_walk(2);};
void() hknight_walk2 =[ $walk2, hknight_walk3 ] {ai_walk(5);};
void() hknight_walk3 =[ $walk3, hknight_walk4 ] {ai_walk(5);};
void() hknight_walk4 =[ $walk4, hknight_walk5 ] {ai_walk(4);};
void() hknight_walk5 =[ $walk5, hknight_walk6 ] {ai_walk(4);};
void() hknight_walk6 =[ $walk6, hknight_walk7 ] {ai_walk(2);};
void() hknight_walk7 =[ $walk7, hknight_walk8 ] {ai_walk(2);};
void() hknight_walk8 =[ $walk8, hknight_walk9 ] {ai_walk(3);};
void() hknight_walk9 =[ $walk9, hknight_walk10 ] {ai_walk(3);};
void() hknight_walk10 =[ $walk10, hknight_walk11 ] {ai_walk(4);};
void() hknight_walk11 =[ $walk11, hknight_walk12 ] {ai_walk(3);};
void() hknight_walk12 =[ $walk12, hknight_walk13 ] {ai_walk(4);};
void() hknight_walk13 =[ $walk13, hknight_walk14 ] {ai_walk(6);};
void() hknight_walk14 =[ $walk14, hknight_walk15 ] {ai_walk(2);};
void() hknight_walk15 =[ $walk15, hknight_walk16 ] {ai_walk(2);};
void() hknight_walk16 =[ $walk16, hknight_walk17 ] {ai_walk(4);};
void() hknight_walk17 =[ $walk17, hknight_walk18 ] {ai_walk(3);};
void() hknight_walk18 =[ $walk18, hknight_walk19 ] {ai_walk(3);};
void() hknight_walk19 =[ $walk19, hknight_walk20 ] {ai_walk(3);};
void() hknight_walk20 =[ $walk20, hknight_walk1 ] {ai_walk(2);};
//===========================================================================
void() hknight_run1 =[ $run1, hknight_run2 ] {
hk_idle_sound();
ai_run (20); CheckForCharge (); };
void() hknight_run2 =[ $run2, hknight_run3 ] {ai_run(25);};
void() hknight_run3 =[ $run3, hknight_run4 ] {ai_run(18);};
void() hknight_run4 =[ $run4, hknight_run5 ] {ai_run(16);};
void() hknight_run5 =[ $run5, hknight_run6 ] {ai_run(14);};
void() hknight_run6 =[ $run6, hknight_run7 ] {ai_run(25);};
void() hknight_run7 =[ $run7, hknight_run8 ] {ai_run(21);};
void() hknight_run8 =[ $run8, hknight_run1 ] {ai_run(13);};
//============================================================================
void() hknight_pain1 =[ $pain1, hknight_pain2 ]
{
if (self.spawnflags & 2) // statue
sound (self, CHAN_VOICE, "statue/pain.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);
};
void() hknight_pain2 =[ $pain2, hknight_pain3 ] {};
void() hknight_pain3 =[ $pain3, hknight_pain4 ] {};
void() hknight_pain4 =[ $pain4, hknight_pain5 ] {};
void() hknight_pain5 =[ $pain5, hknight_run1 ] {};
//============================================================================
void() hknight_die1 =[ $death1, hknight_die2 ] {ai_forward(10);};
void() hknight_die2 =[ $death2, hknight_die3 ] {ai_forward(8);};
void() hknight_die3 =[ $death3, hknight_die4 ]
{self.solid = SOLID_NOT; ai_forward(7);};
void() hknight_die4 =[ $death4, hknight_die5 ] {};
void() hknight_die5 =[ $death5, hknight_die6 ] {};
void() hknight_die6 =[ $death6, hknight_die7 ] {};
void() hknight_die7 =[ $death7, hknight_die8 ] {};
void() hknight_die8 =[ $death8, hknight_die9 ] {ai_forward(10);};
void() hknight_die9 =[ $death9, hknight_die10 ] {ai_forward(11);};
void() hknight_die10 =[ $death10, hknight_die11 ] {};
void() hknight_die11 =[ $death11, hknight_die12 ] {};
void() hknight_die12 =[ $death12, hknight_die12 ] {};
void() hknight_dieb1 =[ $deathb1, hknight_dieb2 ] {};
void() hknight_dieb2 =[ $deathb2, hknight_dieb3 ] {};
void() hknight_dieb3 =[ $deathb3, hknight_dieb4 ]
{self.solid = SOLID_NOT;};
void() hknight_dieb4 =[ $deathb4, hknight_dieb5 ] {};
void() hknight_dieb5 =[ $deathb5, hknight_dieb6 ] {};
void() hknight_dieb6 =[ $deathb6, hknight_dieb7 ] {};
void() hknight_dieb7 =[ $deathb7, hknight_dieb8 ] {};
void() hknight_dieb8 =[ $deathb8, hknight_dieb9 ] {};
void() hknight_dieb9 =[ $deathb9, hknight_dieb9 ] {};
void() hknight_die =
{
// check for gib
if (self.health < -40)
{
sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
ThrowHead ("progs/h_hellkn.mdl", self.health);
if (self.spawnflags & 2) // statue
{
ThrowGib ( "progs/statgib1.mdl", self.health);
ThrowGib ( "progs/statgib2.mdl", self.health);
ThrowGib ( "progs/statgib3.mdl", self.health);
}
else
{
ThrowGib ("progs/gib1.mdl", self.health);
ThrowGib ("progs/gib2.mdl", self.health);
ThrowGib ("progs/gib3.mdl", self.health);
}
return;
}
// regular death
if (self.spawnflags & 2) // statue
sound (self, CHAN_VOICE, "statue/death.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "hknight/death1.wav", 1, ATTN_NORM);
if (random() > 0.5)
hknight_die1 ();
else
hknight_dieb1 ();
};
//============================================================================
void() hknight_magica1 =[ $magica1, hknight_magica2 ] {ai_face();};
void() hknight_magica2 =[ $magica2, hknight_magica3 ] {ai_face();};
void() hknight_magica3 =[ $magica3, hknight_magica4 ] {ai_face();};
void() hknight_magica4 =[ $magica4, hknight_magica5 ] {ai_face();};
void() hknight_magica5 =[ $magica5, hknight_magica6 ] {ai_face();};
void() hknight_magica6 =[ $magica6, hknight_magica7 ] {ai_face();};
void() hknight_magica7 =[ $magica7, hknight_magica8 ] {hknight_shot(-2);};
void() hknight_magica8 =[ $magica8, hknight_magica9 ] {hknight_shot(-1);};
void() hknight_magica9 =[ $magica9, hknight_magica10] {hknight_shot(0);};
void() hknight_magica10 =[ $magica10, hknight_magica11] {hknight_shot(1);};
void() hknight_magica11 =[ $magica11, hknight_magica12] {hknight_shot(2);};
void() hknight_magica12 =[ $magica12, hknight_magica13] {hknight_shot(3);};
void() hknight_magica13 =[ $magica13, hknight_magica14] {ai_face();};
void() hknight_magica14 =[ $magica14, hknight_run1 ] {ai_face();};
//============================================================================
void() hknight_magicb1 =[ $magicb1, hknight_magicb2 ] {ai_face();};
void() hknight_magicb2 =[ $magicb2, hknight_magicb3 ] {ai_face();};
void() hknight_magicb3 =[ $magicb3, hknight_magicb4 ] {ai_face();};
void() hknight_magicb4 =[ $magicb4, hknight_magicb5 ] {ai_face();};
void() hknight_magicb5 =[ $magicb5, hknight_magicb6 ] {ai_face();};
void() hknight_magicb6 =[ $magicb6, hknight_magicb7 ] {ai_face();};
void() hknight_magicb7 =[ $magicb7, hknight_magicb8 ] {hknight_shot(-2);};
void() hknight_magicb8 =[ $magicb8, hknight_magicb9 ] {hknight_shot(-1);};
void() hknight_magicb9 =[ $magicb9, hknight_magicb10] {hknight_shot(0);};
void() hknight_magicb10 =[ $magicb10, hknight_magicb11] {hknight_shot(1);};
void() hknight_magicb11 =[ $magicb11, hknight_magicb12] {hknight_shot(2);};
void() hknight_magicb12 =[ $magicb12, hknight_magicb13] {hknight_shot(3);};
void() hknight_magicb13 =[ $magicb13, hknight_run1] {ai_face();};
//============================================================================
void() hknight_magicc1 =[ $magicc1, hknight_magicc2 ] {ai_face();};
void() hknight_magicc2 =[ $magicc2, hknight_magicc3 ] {ai_face();};
void() hknight_magicc3 =[ $magicc3, hknight_magicc4 ] {ai_face();};
void() hknight_magicc4 =[ $magicc4, hknight_magicc5 ] {ai_face();};
void() hknight_magicc5 =[ $magicc5, hknight_magicc6 ] {ai_face();};
void() hknight_magicc6 =[ $magicc6, hknight_magicc7 ] {hknight_shot(-2);};
void() hknight_magicc7 =[ $magicc7, hknight_magicc8 ] {hknight_shot(-1);};
void() hknight_magicc8 =[ $magicc8, hknight_magicc9 ] {hknight_shot(0);};
void() hknight_magicc9 =[ $magicc9, hknight_magicc10] {hknight_shot(1);};
void() hknight_magicc10 =[ $magicc10, hknight_magicc11] {hknight_shot(2);};
void() hknight_magicc11 =[ $magicc11, hknight_run1] {hknight_shot(3);};
//===========================================================================
void() hknight_char_a1 =[ $char_a1, hknight_char_a2 ] {ai_charge(20);};
void() hknight_char_a2 =[ $char_a2, hknight_char_a3 ] {ai_charge(25);};
void() hknight_char_a3 =[ $char_a3, hknight_char_a4 ] {ai_charge(18);};
void() hknight_char_a4 =[ $char_a4, hknight_char_a5 ] {ai_charge(16);};
void() hknight_char_a5 =[ $char_a5, hknight_char_a6 ] {ai_charge(14);};
void() hknight_char_a6 =[ $char_a6, hknight_char_a7 ] {ai_charge(20); ai_melee();};
void() hknight_char_a7 =[ $char_a7, hknight_char_a8 ] {ai_charge(21); ai_melee();};
void() hknight_char_a8 =[ $char_a8, hknight_char_a9 ] {ai_charge(13); ai_melee();};
void() hknight_char_a9 =[ $char_a9, hknight_char_a10 ] {ai_charge(20); ai_melee();};
void() hknight_char_a10=[ $char_a10, hknight_char_a11 ] {ai_charge(20); ai_melee();};
void() hknight_char_a11=[ $char_a11, hknight_char_a12 ] {ai_charge(18); ai_melee();};
void() hknight_char_a12=[ $char_a12, hknight_char_a13 ] {ai_charge(16);};
void() hknight_char_a13=[ $char_a13, hknight_char_a14 ] {ai_charge(14);};
void() hknight_char_a14=[ $char_a14, hknight_char_a15 ] {ai_charge(25);};
void() hknight_char_a15=[ $char_a15, hknight_char_a16 ] {ai_charge(21);};
void() hknight_char_a16=[ $char_a16, hknight_run1 ] {ai_charge(13);};
//===========================================================================
void() hknight_char_b1 =[ $char_b1, hknight_char_b2 ]
{CheckContinueCharge (); ai_charge(23); ai_melee();};
void() hknight_char_b2 =[ $char_b2, hknight_char_b3 ] {ai_charge(17); ai_melee();};
void() hknight_char_b3 =[ $char_b3, hknight_char_b4 ] {ai_charge(12); ai_melee();};
void() hknight_char_b4 =[ $char_b4, hknight_char_b5 ] {ai_charge(22); ai_melee();};
void() hknight_char_b5 =[ $char_b5, hknight_char_b6 ] {ai_charge(18); ai_melee();};
void() hknight_char_b6 =[ $char_b6, hknight_char_b1 ] {ai_charge(8); ai_melee();};
//===========================================================================
void() hknight_slice1 =[ $slice1, hknight_slice2 ] {ai_charge(9);};
void() hknight_slice2 =[ $slice2, hknight_slice3 ] {ai_charge(6);};
void() hknight_slice3 =[ $slice3, hknight_slice4 ] {ai_charge(13);};
void() hknight_slice4 =[ $slice4, hknight_slice5 ] {ai_charge(4);};
void() hknight_slice5 =[ $slice5, hknight_slice6 ] {ai_charge(7); ai_melee();};
void() hknight_slice6 =[ $slice6, hknight_slice7 ] {ai_charge(15); ai_melee();};
void() hknight_slice7 =[ $slice7, hknight_slice8 ] {ai_charge(8); ai_melee();};
void() hknight_slice8 =[ $slice8, hknight_slice9 ] {ai_charge(2); ai_melee();};
void() hknight_slice9 =[ $slice9, hknight_slice10 ] {ai_melee();};
void() hknight_slice10 =[ $slice10, hknight_run1 ] {ai_charge(3);};
//===========================================================================
void() hknight_smash1 =[ $smash1, hknight_smash2 ] {ai_charge(1);};
void() hknight_smash2 =[ $smash2, hknight_smash3 ] {ai_charge(13);};
void() hknight_smash3 =[ $smash3, hknight_smash4 ] {ai_charge(9);};
void() hknight_smash4 =[ $smash4, hknight_smash5 ] {ai_charge(11);};
void() hknight_smash5 =[ $smash5, hknight_smash6 ] {ai_charge(10); ai_melee();};
void() hknight_smash6 =[ $smash6, hknight_smash7 ] {ai_charge(7); ai_melee();};
void() hknight_smash7 =[ $smash7, hknight_smash8 ] {ai_charge(12); ai_melee();};
void() hknight_smash8 =[ $smash8, hknight_smash9 ] {ai_charge(2); ai_melee();};
void() hknight_smash9 =[ $smash9, hknight_smash10 ] {ai_charge(3); ai_melee();};
void() hknight_smash10 =[ $smash10, hknight_smash11 ] {ai_charge(0);};
void() hknight_smash11 =[ $smash11, hknight_run1 ] {ai_charge(0);};
//============================================================================
void() hknight_watk1 =[ $w_attack1, hknight_watk2 ] {ai_charge(2);};
void() hknight_watk2 =[ $w_attack2, hknight_watk3 ] {ai_charge(0);};
void() hknight_watk3 =[ $w_attack3, hknight_watk4 ] {ai_charge(0);};
void() hknight_watk4 =[ $w_attack4, hknight_watk5 ] {ai_melee();};
void() hknight_watk5 =[ $w_attack5, hknight_watk6 ] {ai_melee();};
void() hknight_watk6 =[ $w_attack6, hknight_watk7 ] {ai_melee();};
void() hknight_watk7 =[ $w_attack7, hknight_watk8 ] {ai_charge(1);};
void() hknight_watk8 =[ $w_attack8, hknight_watk9 ] {ai_charge(4);};
void() hknight_watk9 =[ $w_attack9, hknight_watk10 ] {ai_charge(5);};
void() hknight_watk10 =[ $w_attack10, hknight_watk11 ] {ai_charge(3); ai_melee();};
void() hknight_watk11 =[ $w_attack11, hknight_watk12 ] {ai_charge(2); ai_melee();};
void() hknight_watk12 =[ $w_attack12, hknight_watk13 ] {ai_charge(2); ai_melee();};
void() hknight_watk13 =[ $w_attack13, hknight_watk14 ] {ai_charge(0);};
void() hknight_watk14 =[ $w_attack14, hknight_watk15 ] {ai_charge(0);};
void() hknight_watk15 =[ $w_attack15, hknight_watk16 ] {ai_charge(0);};
void() hknight_watk16 =[ $w_attack16, hknight_watk17 ] {ai_charge(1);};
void() hknight_watk17 =[ $w_attack17, hknight_watk18 ] {ai_charge(1); ai_melee();};
void() hknight_watk18 =[ $w_attack18, hknight_watk19 ] {ai_charge(3); ai_melee();};
void() hknight_watk19 =[ $w_attack19, hknight_watk20 ] {ai_charge(4); ai_melee();};
void() hknight_watk20 =[ $w_attack20, hknight_watk21 ] {ai_charge(6);};
void() hknight_watk21 =[ $w_attack21, hknight_watk22 ] {ai_charge(7);};
void() hknight_watk22 =[ $w_attack22, hknight_run1 ] {ai_charge(3);};
//============================================================================
void() hk_idle_sound =
{
if (random() < 0.2)
{
if (self.spawnflags & 2) // statue
sound (self, CHAN_VOICE, "statue/idle.wav", 1, ATTN_IDLE);
else
sound (self, CHAN_VOICE, "hknight/idle.wav", 1, ATTN_NORM);
}
};
void(entity attacker, float damage) hknight_pain =
{
if (self.pain_finished > time)
return;
if (self.spawnflags & 2) // statue
sound (self, CHAN_VOICE, "statue/pain.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);
if (time - self.pain_finished > 5)
{ // allways go into pain frame if it has been a while
hknight_pain1 ();
self.pain_finished = time + 1;
return;
}
if ((random()*30 > damage) )
return; // didn't flinch
self.pain_finished = time + 1;
hknight_pain1 ();
};
float hknight_type;
void() hknight_melee =
{
hknight_type = hknight_type + 1;
sound (self, CHAN_WEAPON, "hknight/slash1.wav", 1, ATTN_NORM);
if (hknight_type == 1)
hknight_slice1 ();
else if (hknight_type == 2)
hknight_smash1 ();
else if (hknight_type == 3)
{
hknight_watk1 ();
hknight_type = 0;
}
};
void() hknight_pause =
{
sound ( self, CHAN_VOICE, "statue/see.wav", 1, ATTN_NORM);
self.takedamage = DAMAGE_AIM;
self.th_stand = hknight_stand1;
self.th_walk = hknight_walk1;
self.th_run = hknight_run1;
self.th_melee = hknight_melee;
self.th_missile = hknight_magicc1;
self.th_pain = hknight_pain;
self.th_die = hknight_die;
self.use = SUB_Null;
self.enemy = activator;
self.nextthink = time + 0.1;
self.think = FoundTarget;
self.delay = 0;
};
void() hknight_pause1 =
{
self.takedamage = DAMAGE_NO;
self.use = hknight_pause;
self.think = hknight_pause1;
self.nextthink = time + 0.1;
};
/*QUAKED monster_hell_knight (1 0 0) (-16 -16 -24) (16 16 40) Ambush Statue
Statue - select this to use the stone skin and have him frozen in place.
delay: time from sight to attack (default 5)
frame: frame to be frozen in. (default 73)
*/
void() monster_hell_knight =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model2 ("progs/hknight.mdl");
precache_model2 ("progs/k_spike.mdl");
precache_model2 ("progs/h_hellkn.mdl");
if (self.spawnflags & 2) // statue
{
precache_model ( "progs/statgib1.mdl");
precache_model ( "progs/statgib2.mdl");
precache_model ( "progs/statgib3.mdl");
precache_sound ( "statue/see.wav");
precache_sound ( "statue/idle.wav");
precache_sound ( "statue/pain.wav");
precache_sound ( "statue/death.wav");
}
else
{
precache_sound2 ("hknight/death1.wav");
precache_sound2 ("hknight/pain1.wav");
precache_sound2 ("hknight/sight1.wav");
precache_sound2 ("hknight/idle.wav");
}
precache_sound2 ("hknight/attack1.wav");
precache_sound ("hknight/hit.wav"); // used by C code, so don't sound2
precache_sound2 ("hknight/slash1.wav");
precache_sound2 ("hknight/grunt.wav");
precache_sound ("knight/sword1.wav");
precache_sound ("knight/sword2.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/hknight.mdl");
setsize (self, '-16 -16 -24', '16 16 40');
self.health = 250;
if (self.spawnflags & 2) // statue
{
if (self.frame == 0)
self.frame = 73;
self.skin = 1;
if (!self.targetname)
{
dprint ("statue not targeted\n");
dprint (self.classname);
dprint (" at ");
dprint (vtos(self.origin));
dprint ("\n");
return;
}
self.use = hknight_pause;
self.th_stand = hknight_pause1;
self.th_walk = hknight_pause1;
self.th_run = hknight_pause1;
walkmonster_start ();
}
else
{
self.th_stand = hknight_stand1;
self.th_walk = hknight_walk1;
self.th_run = hknight_run1;
self.th_melee = hknight_melee;
self.th_missile = hknight_magicc1;
self.th_pain = hknight_pain;
self.th_die = hknight_die;
walkmonster_start ();
}
};

184
INVIS_SW.QC Normal file
View File

@ -0,0 +1,184 @@
/*
==============================================================================
SWORD
==============================================================================
*/
$cd /qwork/xpack/models/sword
$origin 0 0 24
$base base
$skin badass3
$frame stand1
//$stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame runb1 runb2 runb3 runb4 runb5 runb6 runb7 runb8
//frame runc1 runc2 runc3 runc4 runc5 runc6
//$frame runattack1 runattack2 runattack3 runattack4 runattack5
//$frame runattack6 runattack7 runattack8 runattack9 runattack10
//$frame runattack11
//$frame pain1 pain2 pain3
//$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9
//$frame painb10 painb11
//frame attack1 attack2 attack3 attack4 attack5 attack6 attack7
//frame attack8 attack9 attack10 attack11
$frame attackb1 attackb2 attackb3 attackb4 attackb5
$frame attackb6 attackb7 attackb8 attackb9 attackb10
//$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9
//$frame walk10 walk11 walk12 walk13 walk14
//$frame kneel1 kneel2 kneel3 kneel4 kneel5
//$frame standing2 standing3 standing4 standing5
$frame death1 death2 death3 death4 death5 death6 death7 death8
$frame death9 death10
$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
$frame deathb9 deathb10 deathb11
void() sword_stand1 =[ $stand1, sword_stand1 ] {ai_stand();};
/*
void() sword_walk1 =[ $walk1, sword_walk2 ] {ai_walk(4);};
void() sword_walk2 =[ $walk2, sword_walk3 ] {ai_walk(4);};
void() sword_walk3 =[ $walk3, sword_walk4 ] {ai_walk(4);};
void() sword_walk4 =[ $walk4, sword_walk5 ] {ai_walk(4);};
void() sword_walk5 =[ $walk5, sword_walk6 ] {ai_walk(4);};
void() sword_walk6 =[ $walk6, sword_walk7 ] {ai_walk(4);};
void() sword_walk7 =[ $walk7, sword_walk8 ] {ai_walk(4);};
void() sword_walk8 =[ $walk8, sword_walk9 ] {ai_walk(4);};
void() sword_walk9 =[ $walk9, sword_walk10 ] {ai_walk(4);};
void() sword_walk10 =[ $walk10, sword_walk11 ] {ai_walk(4);};
void() sword_walk11 =[ $walk11, sword_walk12 ] {ai_walk(4);};
void() sword_walk12 =[ $walk12, sword_walk13 ] {ai_walk(4);};
void() sword_walk13 =[ $walk13, sword_walk14 ] {ai_walk(4);};
void() sword_walk14 =[ $walk14, sword_walk1 ] {ai_walk(4);};
*/
void() sword_run1 =[ $runb1, sword_run2 ]
{self.effects = EF_DIMLIGHT; ai_run(14);};
void() sword_run2 =[ $runb2, sword_run3 ] {ai_run(14);};
void() sword_run3 =[ $runb3, sword_run4 ] {ai_run(14);};
void() sword_run4 =[ $runb4, sword_run5 ] {ai_run(14);};
void() sword_run5 =[ $runb5, sword_run6 ] {ai_run(14);};
void() sword_run6 =[ $runb6, sword_run7 ] {ai_run(14);};
void() sword_run7 =[ $runb7, sword_run8 ] {ai_run(14);};
void() sword_run8 =[ $runb8, sword_run1 ] {ai_run(14);};
void() sword_atk1 =[ $attackb1, sword_atk2 ]
{sound (self,0,"knight/sword1.wav", 1, 1);ai_charge(14);};
void() sword_atk2 =[ $attackb2, sword_atk3 ] {ai_charge(14);};
void() sword_atk3 =[ $attackb3, sword_atk4 ] {ai_charge(14);};
void() sword_atk4 =[ $attackb4, sword_atk5 ] {ai_charge(14);};
void() sword_atk5 =[ $attackb5, sword_atk6 ] {ai_melee();};
void() sword_atk6 =[ $attackb6, sword_atk7 ] {ai_melee();};
void() sword_atk7 =[ $attackb7, sword_atk8 ] {ai_melee();};
void() sword_atk8 =[ $attackb8, sword_atk9 ] {ai_charge(14);};
void() sword_atk9 =[ $attackb9, sword_atk10] {ai_charge(14);};
void() sword_atk10=[ $attackb10, sword_run1 ] {ai_charge(14);};
//===========================================================================
void() sword_die1 =[ $death1, sword_die2 ] {};
void() sword_die2 =[ $death2, sword_die3 ] {};
void() sword_die3 =[ $death3, sword_die4 ]
{self.solid = SOLID_NOT;};
void() sword_die4 =[ $death4, sword_die5 ] {};
void() sword_die5 =[ $death5, sword_die6 ] {};
void() sword_die6 =[ $death6, sword_die7 ] {};
void() sword_die7 =[ $death7, sword_die8 ]
{ sound (self, 1, "player/axhit2.wav", 0.5, ATTN_NORM);};
void() sword_die8 =[ $death8, sword_die9 ] {};
void() sword_die9 =[ $death9, sword_die10] {};
void() sword_die10=[ $death10, sword_die10] {};
void() sword_dieb1 =[ $deathb1, sword_dieb2 ] {};
void() sword_dieb2 =[ $deathb2, sword_dieb3 ] {};
void() sword_dieb3 =[ $deathb3, sword_dieb4 ]
{self.solid = SOLID_NOT;};
void() sword_dieb4 =[ $deathb4, sword_dieb5 ] {};
void() sword_dieb5 =[ $deathb5, sword_dieb6 ] {};
void() sword_dieb6 =[ $deathb6, sword_dieb7 ] {};
void() sword_dieb7 =[ $deathb7, sword_dieb8 ]
{ sound (self, 1, "player/axhit2.wav", 0.5, ATTN_NORM); };
void() sword_dieb8 =[ $deathb8, sword_dieb9 ] {};
void() sword_dieb9 =[ $deathb9, sword_dieb10] {};
void() sword_dieb10 = [ $deathb10, sword_dieb11] {};
void() sword_dieb11 = [ $deathb11, sword_dieb11] {};
void() sword_die =
{
// regular death
self.effects=0;
if (random() < 0.5)
sword_die1 ();
else
sword_dieb1 ();
};
void() sword_pause =
{
self.th_run = sword_run1;
self.think = sword_run1;
self.nextthink = time + self.delay;
self.delay = 0;
};
void() sword_pain =
{
self.th_run = sword_run1;
self.think = sword_run1;
self.nextthink = time + 0.1;
self.delay = 0;
self.th_pain = SUB_Null;
};
/*QUAKED monster_sword (1 0 0) (-16 -16 -24) (16 16 40) Ambush
The Invisible Swordsman
delay - seconds after first sighting before it attacks (default 10)
*/
void() monster_sword =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/sword.mdl");
precache_sound ("knight/sword1.wav");
precache_sound ("knight/ksight.wav");
precache_sound ("player/axhit2.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/sword.mdl");
setsize (self, '-16 -16 -24', '16 16 40');
self.health = 150; // 75;
if ( !self.delay)
self.delay = 10;
self.th_stand = sword_stand1;
// self.th_walk = sword_walk1;
self.th_walk = sword_stand1;
self.th_run = sword_pause;
self.th_melee = sword_atk1;
self.th_die = sword_die;
self.th_pain = sword_pain;
walkmonster_start ();
};

1703
ITEMS.QC Normal file

File diff suppressed because it is too large Load Diff

374
KNIGHT.QC Normal file
View File

@ -0,0 +1,374 @@
/*
==============================================================================
KNIGHT
==============================================================================
*/
$cd /raid/quake/id1/models/knight
$origin 0 0 24
$base base
$skin badass3
$skin statue
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame runb1 runb2 runb3 runb4 runb5 runb6 runb7 runb8
//frame runc1 runc2 runc3 runc4 runc5 runc6
$frame runattack1 runattack2 runattack3 runattack4 runattack5
$frame runattack6 runattack7 runattack8 runattack9 runattack10
$frame runattack11
$frame pain1 pain2 pain3
$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9
$frame painb10 painb11
//frame attack1 attack2 attack3 attack4 attack5 attack6 attack7
//frame attack8 attack9 attack10 attack11
$frame attackb1 attackb1 attackb2 attackb3 attackb4 attackb5
$frame attackb6 attackb7 attackb8 attackb9 attackb10
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9
$frame walk10 walk11 walk12 walk13 walk14
$frame kneel1 kneel2 kneel3 kneel4 kneel5
$frame standing2 standing3 standing4 standing5
$frame death1 death2 death3 death4 death5 death6 death7 death8
$frame death9 death10
$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
$frame deathb9 deathb10 deathb11
void() knight_stand1 =[ $stand1, knight_stand2 ] {ai_stand();};
void() knight_stand2 =[ $stand2, knight_stand3 ] {ai_stand();};
void() knight_stand3 =[ $stand3, knight_stand4 ] {ai_stand();};
void() knight_stand4 =[ $stand4, knight_stand5 ] {ai_stand();};
void() knight_stand5 =[ $stand5, knight_stand6 ] {ai_stand();};
void() knight_stand6 =[ $stand6, knight_stand7 ] {ai_stand();};
void() knight_stand7 =[ $stand7, knight_stand8 ] {ai_stand();};
void() knight_stand8 =[ $stand8, knight_stand9 ] {ai_stand();};
void() knight_stand9 =[ $stand9, knight_stand1 ] {ai_stand();};
void() kn_idle_sound =
{
if (random() < 0.2)
{
if (self.spawnflags & 2) // statue
sound (self, CHAN_VOICE, "statue/idle.wav", 1, ATTN_IDLE);
else
sound (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE);
}
};
void() knight_walk1 =[ $walk1, knight_walk2 ]
{ kn_idle_sound(); ai_walk(3);};
void() knight_walk2 =[ $walk2, knight_walk3 ] {ai_walk(2);};
void() knight_walk3 =[ $walk3, knight_walk4 ] {ai_walk(3);};
void() knight_walk4 =[ $walk4, knight_walk5 ] {ai_walk(4);};
void() knight_walk5 =[ $walk5, knight_walk6 ] {ai_walk(3);};
void() knight_walk6 =[ $walk6, knight_walk7 ] {ai_walk(3);};
void() knight_walk7 =[ $walk7, knight_walk8 ] {ai_walk(3);};
void() knight_walk8 =[ $walk8, knight_walk9 ] {ai_walk(4);};
void() knight_walk9 =[ $walk9, knight_walk10 ] {ai_walk(3);};
void() knight_walk10 =[ $walk10, knight_walk11 ] {ai_walk(3);};
void() knight_walk11 =[ $walk11, knight_walk12 ] {ai_walk(2);};
void() knight_walk12 =[ $walk12, knight_walk13 ] {ai_walk(3);};
void() knight_walk13 =[ $walk13, knight_walk14 ] {ai_walk(4);};
void() knight_walk14 =[ $walk14, knight_walk1 ] {ai_walk(3);};
void() knight_run1 =[ $runb1, knight_run2 ]
{ kn_idle_sound(); ai_run(16); };
void() knight_run2 =[ $runb2, knight_run3 ] {ai_run(20);};
void() knight_run3 =[ $runb3, knight_run4 ] {ai_run(13);};
void() knight_run4 =[ $runb4, knight_run5 ] {ai_run(7);};
void() knight_run5 =[ $runb5, knight_run6 ] {ai_run(16);};
void() knight_run6 =[ $runb6, knight_run7 ] {ai_run(20);};
void() knight_run7 =[ $runb7, knight_run8 ] {ai_run(14);};
void() knight_run8 =[ $runb8, knight_run1 ] {ai_run(6);};
void() knight_runatk1 =[ $runattack1, knight_runatk2 ]
{
if (random() > 0.5)
sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM);
else
sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
ai_charge(20);
};
void() knight_runatk2 =[ $runattack2, knight_runatk3 ] {ai_charge_side();};
void() knight_runatk3 =[ $runattack3, knight_runatk4 ] {ai_charge_side();};
void() knight_runatk4 =[ $runattack4, knight_runatk5 ] {ai_charge_side();};
void() knight_runatk5 =[ $runattack5, knight_runatk6 ] {ai_melee_side();};
void() knight_runatk6 =[ $runattack6, knight_runatk7 ] {ai_melee_side();};
void() knight_runatk7 =[ $runattack7, knight_runatk8 ] {ai_melee_side();};
void() knight_runatk8 =[ $runattack8, knight_runatk9 ] {ai_melee_side();};
void() knight_runatk9 =[ $runattack9, knight_runatk10 ] {ai_melee_side();};
void() knight_runatk10 =[ $runattack10, knight_runatk11 ] {ai_charge_side();};
void() knight_runatk11 =[ $runattack11, knight_run1 ] {ai_charge(10);};
void() knight_atk1 =[ $attackb1, knight_atk2 ]
{
sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
ai_charge(0);};
void() knight_atk2 =[ $attackb2, knight_atk3 ] {ai_charge(7);};
void() knight_atk3 =[ $attackb3, knight_atk4 ] {ai_charge(4);};
void() knight_atk4 =[ $attackb4, knight_atk5 ] {ai_charge(0);};
void() knight_atk5 =[ $attackb5, knight_atk6 ] {ai_charge(3);};
void() knight_atk6 =[ $attackb6, knight_atk7 ] {ai_charge(4); ai_melee();};
void() knight_atk7 =[ $attackb7, knight_atk8 ] {ai_charge(1); ai_melee();};
void() knight_atk8 =[ $attackb8, knight_atk9 ] {ai_charge(3);
ai_melee();};
void() knight_atk9 =[ $attackb9, knight_atk10] {ai_charge(1);};
void() knight_atk10=[ $attackb10, knight_run1 ] {ai_charge(5);};
//void() knight_atk9 =[ $attack9, knight_atk10 ] {};
//void() knight_atk10 =[ $attack10, knight_atk11 ] {};
//void() knight_atk11 =[ $attack11, knight_run1 ] {};
//===========================================================================
void() knight_pain1 =[ $pain1, knight_pain2 ] {};
void() knight_pain2 =[ $pain2, knight_pain3 ] {};
void() knight_pain3 =[ $pain3, knight_run1 ] {};
void() knight_painb1 =[ $painb1, knight_painb2 ] {ai_painforward(0);};
void() knight_painb2 =[ $painb2, knight_painb3 ] {ai_painforward(3);};
void() knight_painb3 =[ $painb3, knight_painb4 ] {};
void() knight_painb4 =[ $painb4, knight_painb5 ] {};
void() knight_painb5 =[ $painb5, knight_painb6 ] {ai_painforward(2);};
void() knight_painb6 =[ $painb6, knight_painb7 ] {ai_painforward(4);};
void() knight_painb7 =[ $painb7, knight_painb8 ] {ai_painforward(2);};
void() knight_painb8 =[ $painb8, knight_painb9 ] {ai_painforward(5);};
void() knight_painb9 =[ $painb9, knight_painb10 ] {ai_painforward(5);};
void() knight_painb10 =[ $painb10, knight_painb11 ] {ai_painforward(0);};
void() knight_painb11 =[ $painb11, knight_run1 ] {};
void(entity attacker, float damage) knight_pain =
{
local float r;
if (self.pain_finished > time)
return;
r = random();
if (self.spawnflags & 2) // statue
sound (self, CHAN_VOICE, "statue/pain.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "knight/khurt.wav", 1, ATTN_NORM);
if (r < 0.85)
{
knight_pain1 ();
self.pain_finished = time + 1;
}
else
{
knight_painb1 ();
self.pain_finished = time + 1;
}
};
//===========================================================================
void() knight_bow1 =[ $kneel1, knight_bow2 ] {ai_turn();};
void() knight_bow2 =[ $kneel2, knight_bow3 ] {ai_turn();};
void() knight_bow3 =[ $kneel3, knight_bow4 ] {ai_turn();};
void() knight_bow4 =[ $kneel4, knight_bow5 ] {ai_turn();};
void() knight_bow5 =[ $kneel5, knight_bow5 ] {ai_turn();};
void() knight_bow6 =[ $kneel4, knight_bow7 ] {ai_turn();};
void() knight_bow7 =[ $kneel3, knight_bow8 ] {ai_turn();};
void() knight_bow8 =[ $kneel2, knight_bow9 ] {ai_turn();};
void() knight_bow9 =[ $kneel1, knight_bow10 ] {ai_turn();};
void() knight_bow10 =[ $walk1, knight_walk1 ] {ai_turn();};
void() knight_die1 =[ $death1, knight_die2 ] {};
void() knight_die2 =[ $death2, knight_die3 ] {};
void() knight_die3 =[ $death3, knight_die4 ]
{self.solid = SOLID_NOT;};
void() knight_die4 =[ $death4, knight_die5 ] {};
void() knight_die5 =[ $death5, knight_die6 ] {};
void() knight_die6 =[ $death6, knight_die7 ] {};
void() knight_die7 =[ $death7, knight_die8 ] {};
void() knight_die8 =[ $death8, knight_die9 ] {};
void() knight_die9 =[ $death9, knight_die10] {};
void() knight_die10=[ $death10, knight_die10] {};
void() knight_dieb1 =[ $deathb1, knight_dieb2 ] {};
void() knight_dieb2 =[ $deathb2, knight_dieb3 ] {};
void() knight_dieb3 =[ $deathb3, knight_dieb4 ]
{self.solid = SOLID_NOT;};
void() knight_dieb4 =[ $deathb4, knight_dieb5 ] {};
void() knight_dieb5 =[ $deathb5, knight_dieb6 ] {};
void() knight_dieb6 =[ $deathb6, knight_dieb7 ] {};
void() knight_dieb7 =[ $deathb7, knight_dieb8 ] {};
void() knight_dieb8 =[ $deathb8, knight_dieb9 ] {};
void() knight_dieb9 =[ $deathb9, knight_dieb10] {};
void() knight_dieb10 = [ $deathb10, knight_dieb11] {};
void() knight_dieb11 = [ $deathb11, knight_dieb11] {};
void() knight_die =
{
// check for gib
if (self.health < -40)
{
sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
ThrowHead ("progs/h_knight.mdl", self.health);
if (self.spawnflags & 2) // statue
{
ThrowGib ( "progs/statgib1.mdl", self.health);
ThrowGib ( "progs/statgib2.mdl", self.health);
ThrowGib ( "progs/statgib3.mdl", self.health);
}
else
{
ThrowGib ("progs/gib1.mdl", self.health);
ThrowGib ("progs/gib2.mdl", self.health);
ThrowGib ("progs/gib3.mdl", self.health);
}
return;
}
// regular death
if (self.spawnflags & 2) // statue
sound (self, CHAN_VOICE, "statue/death.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "knight/kdeath.wav", 1, ATTN_NORM);
if (random() < 0.5)
knight_die1 ();
else
knight_dieb1 ();
};
void() knight_pause =
{
sound ( self, CHAN_VOICE, "statue/see.wav", 1, ATTN_NORM);
self.takedamage = DAMAGE_AIM;
self.th_stand = knight_stand1;
self.th_walk = knight_walk1;
self.th_run = knight_run1;
self.th_melee = knight_atk1;
self.th_pain = knight_pain;
self.th_die = knight_die;
self.use = SUB_Null;
self.think = knight_run1;
self.enemy = activator;
self.nextthink = time + 0.1;
self.think = FoundTarget;
self.delay = 0;
};
void() knight_pause1 =
{
self.takedamage = DAMAGE_NO;
self.use = knight_pause;
self.think = knight_pause1;
self.nextthink = time + 0.1;
};
/*QUAKED monster_knight (1 0 0) (-16 -16 -24) (16 16 40) Ambush Statue
Statue - select this to use the stone skin and have him frozen in place.
delay: time from sight to attack (default 5)
frame: frame to be frozen in. (default 44)
*/
void() monster_knight =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/knight.mdl");
precache_model ("progs/h_knight.mdl");
if (self.spawnflags & 2) // statue
{
precache_model ( "progs/statgib1.mdl");
precache_model ( "progs/statgib2.mdl");
precache_model ( "progs/statgib3.mdl");
precache_sound ( "statue/see.wav");
precache_sound ( "statue/idle.wav");
precache_sound ( "statue/pain.wav");
precache_sound ( "statue/death.wav");
}
else
{
precache_sound ("knight/kdeath.wav");
precache_sound ("knight/khurt.wav");
precache_sound ("knight/ksight.wav");
precache_sound ("knight/idle.wav");
}
precache_sound ("knight/sword1.wav");
precache_sound ("knight/sword2.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/knight.mdl");
setsize (self, '-16 -16 -24', '16 16 40');
self.health = 75;
if (self.spawnflags & 2) // statue
{
if (self.frame == 0)
self.frame = 44;
self.skin = 1;
if (!self.targetname)
{
dprint ("statue not targeted\n");
dprint (self.classname);
dprint (" at ");
dprint (vtos(self.origin));
dprint ("\n");
return;
}
self.use = knight_pause;
self.th_stand = knight_pause1;
self.th_walk = knight_pause1;
self.th_run = knight_pause1;
/*
self.th_stand = knight_pause1;
self.th_walk = knight_pause;
self.th_run = knight_pause;
self.th_melee = knight_atk1;
self.th_pain = knight_pause;
self.th_die = knight_die;
*/
walkmonster_start ();
}
else
{
self.th_stand = knight_stand1;
self.th_walk = knight_walk1;
self.th_run = knight_run1;
self.th_melee = knight_atk1;
self.th_pain = knight_pain;
self.th_die = knight_die;
walkmonster_start ();
}
};

478
LAVAMAN.QC Normal file
View File

@ -0,0 +1,478 @@
/*
==============================================================================
LavaMan (Smaller version of Boss E1M7)
==============================================================================
*/
$frame rise1 rise2 rise3 rise4 rise5 rise6 rise7 rise8 rise9 rise10
$frame rise11 rise12 rise13 rise14 rise15 rise16 rise17
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
$frame walk9 walk10 walk11 walk12 walk13 walk14 walk15
$frame walk16 walk17 walk18 walk19 walk20 walk21 walk22
$frame walk23 walk24 walk25 walk26 walk27 walk28 walk29 walk30 walk31
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
$frame attack9 attack10 attack11 attack12 attack13 attack14 attack15
$frame attack16 attack17 attack18 attack19 attack20 attack21 attack22
$frame attack23
$frame shocka1 shocka2 shocka3 shocka4 shocka5 shocka6 shocka7 shocka8
$frame shocka9 shocka10
//$frame shockb1 shockb2 shockb3 shockb4 shockb5 shockb6
//$frame shockc1 shockc2 shockc3 shockc4 shockc5 shockc6 shockc7 shockc8
//$frame shockc9 shockc10
void(float AttackNumber) lavaman_missile;
/*
===========
LavaManCheckAttack
The player is in view, so decide to move or launch an attack
Returns FALSE if movement should continue
============
*/
float() LavaManCheckAttack =
{
local vector spot1, spot2;
local entity targ;
ai_face();
targ = self.enemy;
// see if any entities are in the way of the shot
spot1 = self.origin + '0 0 64';
traceline (spot1, targ.origin, FALSE, self);
if (trace_inopen && trace_inwater)
return FALSE; // sight line crossed contents
if (trace_ent != targ)
return FALSE; // don't have a clear shot
// missile attack
if (time < self.attack_finished)
return FALSE;
self.th_missile ();
SUB_AttackFinished (1 + random());
return TRUE;
};
// ============
// ============
void() lavaman_hunt =
{
local entity possibleEnemy;
local vector viewPoint;
// go for another player if multi player
if (self.enemy.health <= 0)
{
viewPoint = self.origin + '0 0 96';
possibleEnemy = find(self.enemy, classname, "player");
traceline ( viewPoint, possibleEnemy.origin, TRUE, world );
if (trace_fraction == 1)
self.enemy = possibleEnemy;
}
if (self.enemy)
{
ai_face();
self.movetarget = self.enemy;
self.goalentity = self.enemy;
}
};
/*
void(float dist) lavaman_walk =
{
lavaman_hunt();
ai_walk(dist);
};
*/
void() lavaman_rise1 =[ $rise1, lavaman_rise2 ]
{ sound (self, CHAN_WEAPON, "boss1/out1.wav", 1, ATTN_NORM); };
void() lavaman_rise2 =[ $rise2, lavaman_rise3 ]
{ sound (self, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM); };
void() lavaman_rise3 =[ $rise3, lavaman_rise4 ] {};
void() lavaman_rise4 =[ $rise4, lavaman_rise5 ] {};
void() lavaman_rise5 =[ $rise5, lavaman_rise6 ] {};
void() lavaman_rise6 =[ $rise6, lavaman_rise7 ] {};
void() lavaman_rise7 =[ $rise7, lavaman_rise8 ] {};
void() lavaman_rise8 =[ $rise8, lavaman_rise9 ] {};
void() lavaman_rise9 =[ $rise9, lavaman_rise10 ] {};
void() lavaman_rise10 =[ $rise10, lavaman_rise11 ] {};
void() lavaman_rise11 =[ $rise11, lavaman_rise12 ] {};
void() lavaman_rise12 =[ $rise12, lavaman_rise13 ] {};
void() lavaman_rise13 =[ $rise13, lavaman_rise14 ] {};
void() lavaman_rise14 =[ $rise14, lavaman_rise15 ] {};
void() lavaman_rise15 =[ $rise15, lavaman_rise16 ] {};
void() lavaman_rise16 =[ $rise16, lavaman_rise17 ] {};
void() lavaman_rise17 =[ $rise17, lavaman_fire1 ] {};
// ============
// ============
void() lavaman_stand =
{
if (self.enemy)
LavaManCheckAttack();
else
lavaman_hunt();
ai_stand ();
};
void() lavaman_idle1 =[ $walk1, lavaman_idle2 ]
{
if ( random() < 0.2 )
sound (self, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM);
// look for other players
};
void() lavaman_idle2 =[ $walk2, lavaman_idle3 ] {lavaman_stand();};
void() lavaman_idle3 =[ $walk3, lavaman_idle4 ] {lavaman_stand();};
void() lavaman_idle4 =[ $walk4, lavaman_idle5 ] {lavaman_stand();};
void() lavaman_idle5 =[ $walk5, lavaman_idle6 ] {lavaman_stand();};
void() lavaman_idle6 =[ $walk4, lavaman_idle7 ] {lavaman_stand();};
void() lavaman_idle7 =[ $walk3, lavaman_idle8 ] {lavaman_stand();};
void() lavaman_idle8 =[ $walk2, lavaman_idle9 ] {lavaman_stand();};
void() lavaman_idle9 =[ $walk1, lavaman_idle1 ] {lavaman_stand();};
// ============
// ============
void() lavaman_walk =
{
if (self.enemy)
LavaManCheckAttack();
else
lavaman_hunt();
ai_walk (2);
};
void() lavaman_walk1 =[ $walk1, lavaman_walk2 ] {lavaman_walk();};
void() lavaman_walk2 =[ $walk2, lavaman_walk3 ] {lavaman_walk();};
void() lavaman_walk3 =[ $walk3, lavaman_walk4 ] {lavaman_walk();};
void() lavaman_walk4 =[ $walk4, lavaman_walk5 ] {lavaman_walk();};
void() lavaman_walk5 =[ $walk5, lavaman_walk6 ] {lavaman_walk();};
void() lavaman_walk6 =[ $walk6, lavaman_walk7 ] {lavaman_walk();};
void() lavaman_walk7 =[ $walk7, lavaman_walk8 ] {lavaman_walk();};
void() lavaman_walk8 =[ $walk8, lavaman_walk9 ] {lavaman_walk();};
void() lavaman_walk9 =[ $walk9, lavaman_walk10 ] {lavaman_walk();};
void() lavaman_walk10 =[ $walk10, lavaman_walk11 ] {lavaman_walk();};
void() lavaman_walk11 =[ $walk11, lavaman_walk12 ] {lavaman_walk();};
void() lavaman_walk12 =[ $walk12, lavaman_walk13 ] {lavaman_walk();};
void() lavaman_walk13 =[ $walk13, lavaman_walk14 ] {lavaman_walk();};
void() lavaman_walk14 =[ $walk14, lavaman_walk15 ] {lavaman_walk();};
void() lavaman_walk15 =[ $walk15, lavaman_walk16 ] {lavaman_walk();};
void() lavaman_walk16 =[ $walk16, lavaman_walk17 ] {lavaman_walk();};
void() lavaman_walk17 =[ $walk17, lavaman_walk18 ] {lavaman_walk();};
void() lavaman_walk18 =[ $walk18, lavaman_walk19 ] {lavaman_walk();};
void() lavaman_walk19 =[ $walk19, lavaman_walk20 ] {lavaman_walk();};
void() lavaman_walk20 =[ $walk20, lavaman_walk21 ] {lavaman_walk();};
void() lavaman_walk21 =[ $walk21, lavaman_walk22 ] {lavaman_walk();};
void() lavaman_walk22 =[ $walk22, lavaman_walk23 ] {lavaman_walk();};
void() lavaman_walk23 =[ $walk23, lavaman_walk24 ] {lavaman_walk();};
void() lavaman_walk24 =[ $walk24, lavaman_walk25 ] {lavaman_walk();};
void() lavaman_walk25 =[ $walk25, lavaman_walk26 ] {lavaman_walk();};
void() lavaman_walk26 =[ $walk26, lavaman_walk27 ] {lavaman_walk();};
void() lavaman_walk27 =[ $walk27, lavaman_walk28 ] {lavaman_walk();};
void() lavaman_walk28 =[ $walk28, lavaman_walk29 ] {lavaman_walk();};
void() lavaman_walk29 =[ $walk29, lavaman_walk30 ] {lavaman_walk();};
void() lavaman_walk30 =[ $walk30, lavaman_walk31 ] {lavaman_walk();};
void() lavaman_walk31 =[ $walk31, lavaman_walk1 ] {};
void() lavaman_run =
{
if (self.enemy)
LavaManCheckAttack();
else
lavaman_hunt();
ai_run (2);
};
void() lavaman_run1 =[ $walk1, lavaman_run2 ] {lavaman_run();};
void() lavaman_run2 =[ $walk2, lavaman_run3 ] {lavaman_run();};
void() lavaman_run3 =[ $walk3, lavaman_run4 ] {lavaman_run();};
void() lavaman_run4 =[ $walk4, lavaman_run5 ] {lavaman_run();};
void() lavaman_run5 =[ $walk5, lavaman_run6 ] {lavaman_run();};
void() lavaman_run6 =[ $walk6, lavaman_run7 ] {lavaman_run();};
void() lavaman_run7 =[ $walk7, lavaman_run8 ] {lavaman_run();};
void() lavaman_run8 =[ $walk8, lavaman_run9 ] {lavaman_run();};
void() lavaman_run9 =[ $walk9, lavaman_run10 ] {lavaman_run();};
void() lavaman_run10 =[ $walk10, lavaman_run11 ] {lavaman_run ();};
void() lavaman_run11 =[ $walk11, lavaman_run12 ] {lavaman_run ();};
void() lavaman_run12 =[ $walk12, lavaman_run13 ] {lavaman_run ();};
void() lavaman_run13 =[ $walk13, lavaman_run14 ] {lavaman_run ();};
void() lavaman_run14 =[ $walk14, lavaman_run15 ] {lavaman_run ();};
void() lavaman_run15 =[ $walk15, lavaman_run16 ] {lavaman_run ();};
void() lavaman_run16 =[ $walk16, lavaman_run17 ] {lavaman_run ();};
void() lavaman_run17 =[ $walk17, lavaman_run18 ] {lavaman_run ();};
void() lavaman_run18 =[ $walk18, lavaman_run19 ] {lavaman_run ();};
void() lavaman_run19 =[ $walk19, lavaman_run20 ] {lavaman_run ();};
void() lavaman_run20 =[ $walk20, lavaman_run21 ] {lavaman_run ();};
void() lavaman_run21 =[ $walk21, lavaman_run22 ] {lavaman_run ();};
void() lavaman_run22 =[ $walk22, lavaman_run23 ] {lavaman_run ();};
void() lavaman_run23 =[ $walk23, lavaman_run24 ] {lavaman_run ();};
void() lavaman_run24 =[ $walk24, lavaman_run25 ] {lavaman_run ();};
void() lavaman_run25 =[ $walk25, lavaman_run26 ] {lavaman_run ();};
void() lavaman_run26 =[ $walk26, lavaman_run27 ] {lavaman_run ();};
void() lavaman_run27 =[ $walk27, lavaman_run28 ] {lavaman_run ();};
void() lavaman_run28 =[ $walk28, lavaman_run29 ] {lavaman_run ();};
void() lavaman_run29 =[ $walk29, lavaman_run30 ] {lavaman_run ();};
void() lavaman_run30 =[ $walk30, lavaman_run31 ] {lavaman_run ();};
void() lavaman_run31 =[ $walk31, lavaman_run1 ] {};
void() lavaman_fire1 =[ $attack1, lavaman_fire2 ] { ai_face();};
void() lavaman_fire2 =[ $attack2, lavaman_fire3 ] {ai_charge(1);};
void() lavaman_fire3 =[ $attack3, lavaman_fire4 ] { ai_face();};
void() lavaman_fire4 =[ $attack4, lavaman_fire5 ] {ai_face();};
void() lavaman_fire5 =[ $attack5, lavaman_fire6 ] {ai_charge(1);};
void() lavaman_fire6 =[ $attack6, lavaman_fire7 ] {ai_face();};
void() lavaman_fire7 =[ $attack7, lavaman_fire8 ] {lavaman_missile(1);};
void() lavaman_fire8 =[ $attack8, lavaman_fire9 ] {ai_face();};
void() lavaman_fire9 =[ $attack9, lavaman_fire10 ] {ai_face();};
void() lavaman_fire10 =[ $attack10, lavaman_fire11 ] {ai_charge(1);};
void() lavaman_fire11 =[ $attack11, lavaman_fire12 ] {ai_face();};
void() lavaman_fire12 =[ $attack12, lavaman_fire13 ] {ai_charge(1);};
void() lavaman_fire13 =[ $attack13, lavaman_fire14 ] {ai_face();};
void() lavaman_fire14 =[ $attack14, lavaman_fire15 ] {ai_face();};
void() lavaman_fire15 =[ $attack15, lavaman_fire16 ] {ai_charge(1);};
void() lavaman_fire16 =[ $attack16, lavaman_fire17 ] {ai_charge(1);};
void() lavaman_fire17 =[ $attack17, lavaman_fire18 ] {ai_face();};
void() lavaman_fire18 =[ $attack18, lavaman_fire19 ] {lavaman_missile(2);};
void() lavaman_fire19 =[ $attack19, lavaman_fire20 ] {ai_face();};
void() lavaman_fire20 =[ $attack20, lavaman_fire21 ] {ai_face();};
void() lavaman_fire21 =[ $attack21, lavaman_fire22 ] {ai_face();};
void() lavaman_fire22 =[ $attack22, lavaman_fire23 ] {ai_charge(1);};
void() lavaman_fire23 =[ $attack23, lavaman_run1 ] {};
void() lavaman_shocka1 =[ $shocka1, lavaman_shocka2 ] {};
void() lavaman_shocka2 =[ $shocka2, lavaman_shocka3 ] {};
void() lavaman_shocka3 =[ $shocka3, lavaman_shocka4 ] {};
void() lavaman_shocka4 =[ $shocka4, lavaman_shocka5 ] {};
void() lavaman_shocka5 =[ $shocka5, lavaman_shocka6 ] {};
void() lavaman_shocka6 =[ $shocka6, lavaman_shocka7 ] {};
void() lavaman_shocka7 =[ $shocka7, lavaman_shocka8 ] {};
void() lavaman_shocka8 =[ $shocka8, lavaman_shocka9 ] {};
void() lavaman_shocka9 =[ $shocka9, lavaman_shocka10 ] {};
void() lavaman_shocka10 =[ $shocka10, lavaman_run1 ] {};
void() lavaman_pain =
{
if ( self.pain_finished > time )
return;
if (random() < 0.05)
{
self.pain_finished = time + 2;
lavaman_shocka1();
}
};
void() lavaman_death1 = [$death1, lavaman_death2]
{ sound (self, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM); };
void() lavaman_death2 = [$death2, lavaman_death3] {};
void() lavaman_death3 = [$death3, lavaman_death4] {};
void() lavaman_death4 = [$death4, lavaman_death5] {};
void() lavaman_death5 = [$death5, lavaman_death6] {};
void() lavaman_death6 = [$death6, lavaman_death7] {};
void() lavaman_death7 = [$death7, lavaman_death8] {};
void() lavaman_death8 = [$death8, lavaman_death9] {};
void() lavaman_death9 = [$death9, lavaman_death10]
{
sound (self, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
};
void() lavaman_death10 = [$death9, lavaman_death10]
{
remove (self);
};
void() lavaman_touch =
{
local float damg;
if (other == self.owner)
return; // don't explode on owner
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
damg = 40;
if (other.health)
{
if (other.classname == "monster_shambler")
damg = damg * 0.5; // mostly immune
T_Damage (other, self, self.owner, damg );
}
// don't do radius damage to the other, because all the damage
// was done in the impact
T_RadiusDamage (self, self.owner, 40, other);
// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
self.origin = self.origin - 8*normalize(self.velocity);
// Change to an explosion2!!! Ramp in the non-diminishing reds...
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 ();
};
void(float AttackNumber) lavaman_missile =
{
local entity fireball;
local vector offang;
local vector org, vec, d;
local float t;
makevectors (self.angles);
// Right handed throw
if ( AttackNumber == 1)
{
// org = self.origin - v_forward*40 + v_right*90 + v_up*110;
org = self.origin + v_forward*40 + v_right*65 + v_up*130;
}
// Left handed throw
else if ( AttackNumber == 2)
{
// org = self.origin - v_forward*40 - v_right*90 + v_up*110;
org = self.origin + v_forward*40 - v_right*75 + v_up*125;
}
d = self.enemy.origin;
t = vlen ( d - org );
t = t / 380;
if ( t > 1.75 )
t = 1.75;
if ( t < 1 )
t = 1;
vec = normalize (d - org);
fireball = spawn ();
fireball.owner = self;
// fireball.movetype = MOVETYPE_FLYMISSILE;
fireball.movetype = MOVETYPE_BOUNCE;
fireball.solid = SOLID_BBOX;
fireball.angles = vectoangles(vec);
fireball.touch = lavaman_touch;
fireball.classname = "lavaman_ball";
setmodel (fireball, "progs/lavaball.mdl");
setsize (fireball, '0 0 0', '0 0 0');
setorigin (fireball, org);
// fireball.velocity = vec * 600 + '0 0 200';
fireball.velocity = vec * 600 * t;
fireball.velocity_z = fireball.velocity_z + (200 * t);
fireball.avelocity = '200 100 300';
fireball.think = SUB_Remove;
fireball.nextthink = time + 6;
sound (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);
// check for dead enemy
if (self.enemy.health <= 0)
lavaman_idle1 ();
};
void() lavaman_awake =
{
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
self.takedamage = DAMAGE_AIM;
self.flags = self.flags | FL_MONSTER;
self.ideal_yaw = self.angles * '0 1 0';
if (!self.yaw_speed)
self.yaw_speed = 20;
setmodel (self, "progs/lavaman.mdl");
// setsize (self, '-64 -64 -12', '64 64 128');
// setsize (self, '-32 -32 0', '32 32 120');
setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
self.view_ofs = '0 0 48';
// self.health = 1500;
self.health = 1250 + (250 * cvar("skill"));
self.th_stand = lavaman_idle1;
self.th_walk = lavaman_walk1;
self.th_run = lavaman_walk1;
self.th_missile = lavaman_fire1;
self.th_pain = lavaman_pain;
self.th_die = lavaman_death1;
self.th_melee = lavaman_fire1;
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
if (!(activator.items & IT_INVISIBILITY))
{
if (!(activator.flags & FL_NOTARGET))
{
if (activator.classname == "player")
self.enemy = activator;
}
}
droptofloor();
lavaman_rise1 ();
};
// (-64 -64 -12) (64 64 128)
/*QUAKED monster_lava_man (1 0 0) (-32 -32 -24) (32 32 64) Ambush Sleeping
*/
void() monster_lava_man =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/lavaman.mdl");
precache_model ("progs/lavaball.mdl");
precache_sound ("weapons/rocket1i.wav");
precache_sound ("boss1/out1.wav");
precache_sound ("boss1/sight1.wav");
precache_sound ("misc/power.wav");
precache_sound ("boss1/throw.wav");
precache_sound ("boss1/pain.wav");
precache_sound ("boss1/death.wav");
total_monsters = total_monsters + 1;
// cause the lavaman to rise from the lava when triggered.
if (self.spawnflags & 2)
{
self.use = lavaman_awake;
return;
}
lavaman_awake();
};

205
LAVA_WPN.QC Normal file
View File

@ -0,0 +1,205 @@
// LAVA Weapon Routines
/*
===============
launch_lava_spike
Used for both the player and the ogre
===============
*/
void(vector org, vector dir) launch_lava_spike =
{
newmis = spawn ();
newmis.owner = self;
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_BBOX;
newmis.angles = vectoangles(dir);
newmis.touch = lavaspike_touch;
newmis.classname = "lava_spike";
newmis.think = SUB_Remove;
newmis.nextthink = time + 6;
setmodel (newmis, "progs/lspike.mdl");
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
setorigin (newmis, org);
newmis.velocity = dir * 1000;
};
void() W_FireSuperLavaSpikes =
{
local vector dir;
local entity old;
sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
self.attack_finished = time + 0.2;
self.currentammo = self.ammo_lava_nails = self.ammo_lava_nails - 2;
UpdateAmmoCounts (self);
dir = aim (self, 1000);
launch_lava_spike (self.origin + '0 0 16', dir);
newmis.touch = superlavaspike_touch;
// setmodel (newmis, "progs/lspike.mdl");
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
self.punchangle_x = -2;
};
void(float ox) W_FireLavaSpikes =
{
local vector dir;
local entity old;
makevectors (self.v_angle);
if (self.ammo_lava_nails >= 2 && self.weapon == IT_LAVA_SUPER_NAILGUN)
{
W_FireSuperLavaSpikes ();
return;
}
if (self.ammo_lava_nails < 1)
{
sprint (self, "Out of Lava Nails\n");
self.weapon = W_BestWeapon ();
W_SetCurrentAmmo ();
return;
}
sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
self.attack_finished = time + 0.2;
self.currentammo = self.ammo_lava_nails = self.ammo_lava_nails - 1;
UpdateAmmoCounts (self);
dir = aim (self, 1000);
launch_lava_spike (self.origin + '0 0 16' + v_right*ox, dir);
self.punchangle_x = -2;
};
// =============== Lava Spike Touch Routines
void() lavaspike_touch =
{
local float rand;
local float old_armortype;
local float old_armorvalue;
local float old_armormask;
if (other == self.owner)
return;
if (other.solid == SOLID_TRIGGER)
return; // trigger field, do nothing
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
// hit something that bleeds
if (other.takedamage)
{
spawn_touchblood (9);
if(other.classname == "player")
{
old_armortype = other.armortype;
old_armorvalue = other.armorvalue;
old_armormask = other.items2 & (IT2_ARMOR1|IT2_ARMOR2|IT2_ARMOR3);
other.armortype = 0;
other.armorvalue = 0;
T_Damage (other, self, self.owner, 9);
other.armortype = old_armortype;
other.armorvalue = old_armorvalue;
other.items2 = other.items2 | old_armormask;
}
else // is a monster
{
if ( other.classname != "monster_lava_man")
{
T_Damage (other, self, self.owner, 15);
}
}
}
else
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
if (self.classname == "wizspike")
WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
else if (self.classname == "knightspike")
WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
else
WriteByte (MSG_BROADCAST, TE_SPIKE);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
}
remove(self);
};
void() superlavaspike_touch =
{
local float rand;
local float old_armortype;
//local float old_armorvalue;
if (other == self.owner)
return;
if (other.solid == SOLID_TRIGGER)
return; // trigger field, do nothing
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
// hit something that bleeds
if (other.takedamage)
{
spawn_touchblood (18);
// halve the effectiveness of the armor for players..
if(other.classname == "player")
{
// save the old armor values...
old_armortype = other.armortype;
// old_armorvalue = other.armorvalue;
other.armortype = other.armortype * 0.5;
// other.armorvalue = 0;
T_Damage (other, self, self.owner, 18);
// if the damage didn't wipe out the armor, armortype
if(other.armortype != 0)
{
other.armortype = old_armortype;
// other.armorvalue = old_armorvalue;
}
}
else // is a monster, do 50% more damage
{
if ( other.classname != "monster_lava_man")
{
T_Damage (other, self, self.owner, 30);
}
}
}
else
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
}
remove(self);
};

183
LIGHTNIN.QC Normal file
View File

@ -0,0 +1,183 @@
// lightning trail
// pmack
// sept 96
// float ltrailLastUsed; -- now an entity field.
float LT_TOGGLE = 1;
float LT_ACTIVE = 2;
void() ltrail_chain =
{
SUB_UseTargets();
self.think = SUB_Null;
};
void() ltrail_fire =
{
local entity myTarget;
if (self.classname != "ltrail_end")
{
sound (self, CHAN_VOICE, "weapons/lhit.wav", 1, ATTN_NORM);
myTarget = find(world, targetname, self.target);
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, myTarget.origin_x);
WriteCoord (MSG_BROADCAST, myTarget.origin_y);
WriteCoord (MSG_BROADCAST, myTarget.origin_z);
LightningDamage (self.origin, myTarget.origin, self, self.currentammo);
}
if ( self.items < time)
{
self.think = ltrail_chain;
self.nextthink = time + self.frags;
}
else
{
self.think = ltrail_fire;
self.nextthink = time + 0.05;
}
};
void() ltrail_start_fire =
{
// if it's a toggle ltrail, we ignore triggers from ltrail_end's
// when toggled off.
if (self.spawnflags & LT_TOGGLE)
{
// user is not a lightning trail - change activity state.
if ( other.classname != "ltrail_end" )
{
if (self.spawnflags & LT_ACTIVE)
// currently active
{
self.spawnflags = self.spawnflags - LT_ACTIVE;
return;
}
else
// not active
{
self.spawnflags = self.spawnflags + LT_ACTIVE;
}
}
// user is lightning trail, but trail has been turned off.
// ignore the message.
else if (!(self.spawnflags & LT_ACTIVE))
return;
}
if (self.classname == "ltrail_start")
{
self.items = time + self.weapon;
ltrail_fire();
self.ltrailLastUsed = time;
}
else if (self.classname == "ltrail_relay")
{
self.items = time + self.weapon;
ltrail_fire();
}
else
{
self.think = ltrail_chain;
self.nextthink = time + self.frags;
}
};
/*QUAKED ltrail_start (0 1 0) (-8 -8 -8) (8 8 8) LT_TOGGLE
Starting point of a lightning trail.
Set currentammo to amount of damage you want the lightning to do.
Default is 25.
Set frags to amount of time before next item is triggered.
Default is 0.3 seconds.
Set weapon to amount of time to be firing the lightning.
Default is 0.3 seconds.
Set the LT_TOGGLE checkbox if you want the lightning shooter to continuously fire until triggered again.
*/
void() ltrail_start =
{
self.ltrailLastUsed = time;
precache_sound ("weapons/lhit.wav");
self.movetype = MOVETYPE_NONE;
self.solid = SOLID_BBOX;
self.use = ltrail_start_fire;
if (self.currentammo == 0)
self.currentammo = 25;
if (self.weapon == 0)
self.weapon = 0.3;
if (self.frags == 0)
self.frags = 0.3;
if (self.spawnflags & LT_ACTIVE)
{
self.items = time + 99999999;
self.think = ltrail_fire;
self.nextthink = time + 0.1;
}
};
/*QUAKED ltrail_relay (0 1 0) (-8 -8 -8) (8 8 8)
Relay point of a lightning trail.
Set currentammo to amount of damage you want the lightning to do.
Default is 25.
Set frags to amount of time before next item is triggered.
Default is 0.3 seconds.
Set weapon to amount of time to be firing the lightning.
Default is 0.3 seconds.
*/
void() ltrail_relay =
{
precache_sound ("weapons/lhit.wav");
self.movetype = MOVETYPE_NONE;
self.solid = SOLID_BBOX;
self.use = ltrail_start_fire;
if (self.currentammo == 0)
self.currentammo = 25;
if (self.weapon == 0)
self.weapon = 0.3;
if (self.frags == 0)
self.frags = 0.3;
};
/*QUAKED ltrail_end (0 1 0) (-8 -8 -8) (8 8 8)
Ending point of a lightning trail.
Does not fire any lightning.
Set frags to amount of time before next item is triggered.
Default is 0.3 seconds.
*/
void() ltrail_end =
{
precache_sound ("weapons/lhit.wav");
self.movetype = MOVETYPE_NONE;
self.solid = SOLID_BBOX;
self.use = ltrail_start_fire;
if (self.currentammo == 0)
self.currentammo = 25;
if (self.weapon == 0)
self.weapon = 0.3;
if (self.frags == 0)
self.frags = 0.3;
};

727
MISC.QC Normal file
View File

@ -0,0 +1,727 @@
/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4)
Used as a positional target for spotlights, etc.
*/
void() info_null =
{
remove(self);
};
/*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4)
Used as a positional target for lightning.
*/
void() info_notnull =
{
};
//============================================================================
float START_OFF = 1;
void() light_use =
{
if (self.spawnflags & START_OFF)
{
lightstyle(self.style, "m");
self.spawnflags = self.spawnflags - START_OFF;
}
else
{
lightstyle(self.style, "a");
self.spawnflags = self.spawnflags + START_OFF;
}
};
/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
Non-displayed light.
Default light value is 300
Default style is 0
If targeted, it will toggle between on or off.
*/
void() light =
{
if (!self.targetname)
{ // inert light
remove(self);
return;
}
if (self.style >= 32)
{
self.use = light_use;
if (self.spawnflags & START_OFF)
lightstyle(self.style, "a");
else
lightstyle(self.style, "m");
}
};
/*QUAKED light_fluoro (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
Non-displayed light.
Default light value is 300
Default style is 0
If targeted, it will toggle between on or off.
Makes steady fluorescent humming sound
*/
void() light_fluoro =
{
if (self.style >= 32)
{
self.use = light_use;
if (self.spawnflags & START_OFF)
lightstyle(self.style, "a");
else
lightstyle(self.style, "m");
}
precache_sound ("ambience/fl_hum1.wav");
ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC);
};
/*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8)
Non-displayed light.
Default light value is 300
Default style is 10
Makes sparking, broken fluorescent sound
*/
void() light_fluorospark =
{
if (!self.style)
self.style = 10;
precache_sound ("ambience/buzz1.wav");
ambientsound (self.origin, "ambience/buzz1.wav", 0.5, ATTN_STATIC);
};
/*QUAKED light_globe (0 1 0) (-8 -8 -8) (8 8 8)
Sphere globe light.
Default light value is 300
Default style is 0
*/
void() light_globe =
{
precache_model ("progs/s_light.spr");
setmodel (self, "progs/s_light.spr");
makestatic (self);
};
void() FireAmbient =
{
precache_sound ("ambience/fire1.wav");
// attenuate fast
ambientsound (self.origin, "ambience/fire1.wav", 0.5, ATTN_STATIC);
};
/*QUAKED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20) Quiet
Short wall torch
Default light value is 300
Default style is 0
*/
void() light_torch_small_walltorch =
{
precache_model ("progs/flame.mdl");
setmodel (self, "progs/flame.mdl");
if (!(self.spawnflags & 1))
FireAmbient ();
makestatic (self);
};
/*QUAKED light_flame_large_yellow (0 1 0) (-10 -10 -12) (12 12 18)
Large yellow flame ball
*/
void() light_flame_large_yellow =
{
precache_model ("progs/flame2.mdl");
setmodel (self, "progs/flame2.mdl");
self.frame = 1;
FireAmbient ();
makestatic (self);
};
/*QUAKED light_flame_small_yellow (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
Small yellow flame ball
*/
void() light_flame_small_yellow =
{
precache_model ("progs/flame2.mdl");
setmodel (self, "progs/flame2.mdl");
FireAmbient ();
makestatic (self);
};
/*QUAKED light_flame_small_white (0 1 0) (-10 -10 -40) (10 10 40) START_OFF
Small white flame ball
*/
void() light_flame_small_white =
{
precache_model ("progs/flame2.mdl");
setmodel (self, "progs/flame2.mdl");
FireAmbient ();
makestatic (self);
};
//============================================================================
/*QUAKED misc_fireball (0 .5 .8) (-8 -8 -8) (8 8 8)
Lava Balls
*/
void() fire_fly;
void() fire_touch;
void() misc_fireball =
{
precache_model ("progs/lavaball.mdl");
self.classname = "fireball";
self.nextthink = time + (random() * 5);
self.think = fire_fly;
if (!self.speed)
self.speed == 1000;
};
void() fire_fly =
{
local entity fireball;
fireball = spawn();
fireball.solid = SOLID_TRIGGER;
fireball.movetype = MOVETYPE_TOSS;
fireball.velocity = '0 0 1000';
fireball.velocity_x = (random() * 100) - 50;
fireball.velocity_y = (random() * 100) - 50;
fireball.velocity_z = self.speed + (random() * 200);
fireball.classname = "fireball";
setmodel (fireball, "progs/lavaball.mdl");
setsize (fireball, '0 0 0', '0 0 0');
setorigin (fireball, self.origin);
fireball.nextthink = time + 5;
fireball.think = SUB_Remove;
fireball.touch = fire_touch;
self.nextthink = time + (random() * 5) + 3;
self.think = fire_fly;
};
void() fire_touch =
{
T_Damage (other, self, self, 20);
remove(self);
};
//============================================================================
void() barrel_explode =
{
self.takedamage = DAMAGE_NO;
self.classname = "explo_box";
// did say self.owner
T_RadiusDamage (self, self, 160, world);
sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
particle (self.origin, '0 0 0', 75, 255);
self.origin_z = self.origin_z + 32;
BecomeExplosion ();
};
/*QUAKED misc_explobox (0 .5 .8) (0 0 0) (32 32 64)
TESTING THING
*/
void() misc_explobox =
{
local float oldz;
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_NONE;
precache_model ("maps/b_explob.bsp");
setmodel (self, "maps/b_explob.bsp");
precache_sound ("weapons/r_exp3.wav");
self.health = 20;
self.th_die = barrel_explode;
self.takedamage = DAMAGE_AIM;
self.origin_z = self.origin_z + 2;
oldz = self.origin_z;
droptofloor();
if (oldz - self.origin_z > 250)
{
dprint ("item fell out of level at ");
dprint (vtos(self.origin));
dprint ("\n");
remove(self);
}
};
/*QUAKED misc_explobox2 (0 .5 .8) (0 0 0) (32 32 64)
Smaller exploding box, REGISTERED ONLY
*/
void() misc_explobox2 =
{
local float oldz;
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_NONE;
precache_model2 ("maps/b_exbox2.bsp");
setmodel (self, "maps/b_exbox2.bsp");
precache_sound ("weapons/r_exp3.wav");
self.health = 20;
self.th_die = barrel_explode;
self.takedamage = DAMAGE_AIM;
self.origin_z = self.origin_z + 2;
oldz = self.origin_z;
droptofloor();
if (oldz - self.origin_z > 250)
{
dprint ("item fell out of level at ");
dprint (vtos(self.origin));
dprint ("\n");
remove(self);
}
};
//============================================================================
float SPAWNFLAG_SUPERSPIKE = 1;
float SPAWNFLAG_LASER = 2;
float SPAWNFLAG_LAVASPIKE = 4;
float SPAWNFLAG_SUPERLAVA = 8;
float SPAWNFLAG_LAVASKILL = 16;
float SPAWNFLAG_FIREBALL = 32;
void(vector org, vector vec) LaunchLaser;
void(vector org, vector dir) launch_lava_spike;
void(vector org, vector dir) launch_fireball;
void() spikeshooter_use =
{
if (self.spawnflags & SPAWNFLAG_SUPERSPIKE || !(self.spawnflags))
{
sound (self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM);
launch_spike (self.origin, self.movedir);
newmis.velocity = self.movedir * 500;
if (self.spawnflags & SPAWNFLAG_SUPERSPIKE)
newmis.touch = superspike_touch;
}
else if (self.spawnflags & SPAWNFLAG_LASER)
{
sound (self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM);
LaunchLaser (self.origin, self.movedir);
}
else if (self.spawnflags & SPAWNFLAG_FIREBALL)
{
launch_fireball (self.origin, self.movedir);
}
else
{
sound (self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM);
launch_lava_spike (self.origin, self.movedir);
newmis.velocity = self.movedir * 500;
if (self.spawnflags & SPAWNFLAG_SUPERLAVA)
newmis.touch = superlavaspike_touch;
else if((self.spawnflags & SPAWNFLAG_LAVASKILL) && (skill > 1))
newmis.touch = superlavaspike_touch;
}
};
void() shooter_think =
{
spikeshooter_use ();
self.nextthink = time + self.wait;
newmis.velocity = self.movedir * 500;
};
/*QUAKED trap_spikeshooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lava superlava skilllava fireball
When triggered, fires a spike in the direction set in QuakeEd.
Laser, Lava and SuperLava are only for REGISTERED.
*/
void() trap_spikeshooter =
{
SetMovedir ();
self.use = spikeshooter_use;
if (self.spawnflags & SPAWNFLAG_LASER)
{
precache_model2 ("progs/laser.mdl");
precache_sound2 ("enforcer/enfire.wav");
precache_sound2 ("enforcer/enfstop.wav");
}
else if (self.spawnflags & SPAWNFLAG_LAVASPIKE)
{
precache_model2 ("progs/lspike.mdl");
precache_sound2 ("lavagun/snail.wav"); // lava nail gun cooldown
precache_sound2 ("weapons/rocket1i.wav");
}
else if (self.spawnflags & SPAWNFLAG_SUPERLAVA)
{
precache_model2 ("progs/lspike.mdl");
precache_sound2 ("lavagun/snail.wav"); // lava nail gun cooldown
precache_sound2 ("weapons/spike2.wav");
}
else if (self.spawnflags & SPAWNFLAG_LAVASKILL)
{
precache_model2 ("progs/lspike.mdl");
precache_sound2 ("lavagun/snail.wav"); // lava nail gun cooldown
precache_sound2 ("weapons/rocket1i.wav");
precache_sound2 ("weapons/spike2.wav");
}
else if (self.spawnflags & SPAWNFLAG_FIREBALL)
{
precache_model ("progs/fireball.mdl");
}
else
precache_sound ("weapons/spike2.wav");
};
/*QUAKED trap_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser
Continuously fires spikes.
"wait" time between spike (1.0 default)
"nextthink" delay before firing first spike, so multiple shooters can be stagered.
*/
void() trap_shooter =
{
trap_spikeshooter ();
if (self.wait == 0)
self.wait = 1;
self.nextthink = self.nextthink + self.wait + self.ltime;
self.think = shooter_think;
};
/*
===============================================================================
===============================================================================
*/
void() make_bubbles;
void() bubble_remove;
void() bubble_bob;
/*QUAKED air_bubbles (0 .5 .8) (-8 -8 -8) (8 8 8)
testing air bubbles
*/
void() air_bubbles =
{
if (deathmatch)
{
remove (self);
return;
}
precache_model ("progs/s_bubble.spr");
self.nextthink = time + 1;
self.think = make_bubbles;
};
void() make_bubbles =
{
local entity bubble;
bubble = spawn();
setmodel (bubble, "progs/s_bubble.spr");
setorigin (bubble, self.origin);
bubble.movetype = MOVETYPE_NOCLIP;
bubble.solid = SOLID_NOT;
bubble.velocity = '0 0 15';
bubble.nextthink = time + 0.5;
bubble.think = bubble_bob;
bubble.touch = bubble_remove;
bubble.classname = "bubble";
bubble.frame = 0;
bubble.cnt = 0;
setsize (bubble, '-8 -8 -8', '8 8 8');
self.nextthink = time + random() + 0.5;
self.think = make_bubbles;
};
void() bubble_split =
{
local entity bubble;
bubble = spawn();
setmodel (bubble, "progs/s_bubble.spr");
setorigin (bubble, self.origin);
bubble.movetype = MOVETYPE_NOCLIP;
bubble.solid = SOLID_NOT;
bubble.velocity = self.velocity;
bubble.nextthink = time + 0.5;
bubble.think = bubble_bob;
bubble.touch = bubble_remove;
bubble.classname = "bubble";
bubble.frame = 1;
bubble.cnt = 10;
setsize (bubble, '-8 -8 -8', '8 8 8');
self.frame = 1;
self.cnt = 10;
if (self.waterlevel != 3)
remove (self);
};
void() bubble_remove =
{
if (other.classname == self.classname)
{
// dprint ("bump");
return;
}
remove(self);
};
void() bubble_bob =
{
local float rnd1, rnd2, rnd3;
local vector vtmp1, modi;
// PGM fix - 02/25/97 so bubbles won't go through walls
rnd1 = pointcontents(self.origin);
if (rnd1 == CONTENT_SOLID)
remove(self);
// PGM fix - 02/25/97 so bubbles pop 2 seconds after leaving water
else if (rnd1 == CONTENT_EMPTY)
{
if (self.cnt < 16)
self.cnt = 16;
}
self.cnt = self.cnt + 1;
if (self.cnt == 4)
bubble_split();
if (self.cnt == 20)
remove(self);
rnd1 = self.velocity_x + (-10 + (random() * 20));
rnd2 = self.velocity_y + (-10 + (random() * 20));
rnd3 = self.velocity_z + 10 + random() * 10;
if (rnd1 > 10)
rnd1 = 5;
if (rnd1 < -10)
rnd1 = -5;
if (rnd2 > 10)
rnd2 = 5;
if (rnd2 < -10)
rnd2 = -5;
if (rnd3 < 10)
rnd3 = 15;
if (rnd3 > 30)
rnd3 = 25;
self.velocity_x = rnd1;
self.velocity_y = rnd2;
self.velocity_z = rnd3;
self.nextthink = time + 0.5;
self.think = bubble_bob;
};
/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>
~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/
/*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8)
Just for the debugging level. Don't use
*/
void() viewthing =
{
self.movetype = MOVETYPE_NONE;
self.solid = SOLID_NOT;
precache_model ("progs/player.mdl");
setmodel (self, "progs/player.mdl");
};
/*
==============================================================================
SIMPLE BMODELS
==============================================================================
*/
void() func_wall_use =
{ // change to alternate textures
self.frame = 1 - self.frame;
};
/*QUAKED func_wall (0 .5 .8) ?
This is just a solid wall if not inhibitted
*/
void() func_wall =
{
self.angles = '0 0 0';
self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
self.solid = SOLID_BSP;
self.use = func_wall_use;
setmodel (self, self.model);
};
/*QUAKED func_illusionary (0 .5 .8) ?
A simple entity that looks solid but lets you walk through it.
*/
void() func_illusionary =
{
self.angles = '0 0 0';
self.movetype = MOVETYPE_NONE;
self.solid = SOLID_NOT;
setmodel (self, self.model);
makestatic ();
};
/*QUAKED func_episodegate (0 .5 .8) ? E1 E2 E3 E4
This bmodel will appear if the episode has allready been completed, so players can't reenter it.
*/
void() func_episodegate =
{
if (!(serverflags & self.spawnflags))
return; // can still enter episode
self.angles = '0 0 0';
self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
self.solid = SOLID_BSP;
self.use = func_wall_use;
setmodel (self, self.model);
};
/*QUAKED func_bossgate (0 .5 .8) ?
This bmodel appears unless players have all of the episode sigils.
*/
void() func_bossgate =
{
if ( (serverflags & 15) == 15)
return; // all episodes completed
self.angles = '0 0 0';
self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
self.solid = SOLID_BSP;
self.use = func_wall_use;
setmodel (self, self.model);
};
//============================================================================
/*QUAKED ambient_suck_wind (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_suck_wind =
{
precache_sound ("ambience/suck1.wav");
ambientsound (self.origin, "ambience/suck1.wav", 1, ATTN_STATIC);
};
/*QUAKED ambient_drone (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_drone =
{
precache_sound ("ambience/drone6.wav");
ambientsound (self.origin, "ambience/drone6.wav", 0.5, ATTN_STATIC);
};
/*QUAKED ambient_flouro_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_flouro_buzz =
{
precache_sound ("ambience/buzz1.wav");
ambientsound (self.origin, "ambience/buzz1.wav", 1, ATTN_STATIC);
};
/*QUAKED ambient_drip (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_drip =
{
precache_sound ("ambience/drip1.wav");
ambientsound (self.origin, "ambience/drip1.wav", 0.5, ATTN_STATIC);
};
/*QUAKED ambient_comp_hum (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_comp_hum =
{
precache_sound ("ambience/comp1.wav");
ambientsound (self.origin, "ambience/comp1.wav", 1, ATTN_STATIC);
};
/*QUAKED ambient_thunder (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_thunder =
{
precache_sound ("ambience/thunder1.wav");
ambientsound (self.origin, "ambience/thunder1.wav", 0.5, ATTN_STATIC);
};
/*QUAKED ambient_light_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_light_buzz =
{
precache_sound ("ambience/fl_hum1.wav");
ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC);
};
/*QUAKED ambient_swamp1 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_swamp1 =
{
precache_sound ("ambience/swamp1.wav");
ambientsound (self.origin, "ambience/swamp1.wav", 0.5, ATTN_STATIC);
};
/*QUAKED ambient_swamp2 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_swamp2 =
{
precache_sound ("ambience/swamp2.wav");
ambientsound (self.origin, "ambience/swamp2.wav", 0.5, ATTN_STATIC);
};
//============================================================================
void() noise_think =
{
self.nextthink = time + 0.5;
sound (self, 1, "enforcer/enfire.wav", 1, ATTN_NORM);
sound (self, 2, "enforcer/enfstop.wav", 1, ATTN_NORM);
sound (self, 3, "enforcer/sight1.wav", 1, ATTN_NORM);
sound (self, 4, "enforcer/sight2.wav", 1, ATTN_NORM);
sound (self, 5, "enforcer/sight3.wav", 1, ATTN_NORM);
sound (self, 6, "enforcer/sight4.wav", 1, ATTN_NORM);
sound (self, 7, "enforcer/pain1.wav", 1, ATTN_NORM);
};
/*QUAKED misc_noisemaker (1 0.5 0) (-10 -10 -10) (10 10 10)
For optimzation testing, starts a lot of sounds.
*/
void() misc_noisemaker =
{
precache_sound2 ("enforcer/enfire.wav");
precache_sound2 ("enforcer/enfstop.wav");
precache_sound2 ("enforcer/sight1.wav");
precache_sound2 ("enforcer/sight2.wav");
precache_sound2 ("enforcer/sight3.wav");
precache_sound2 ("enforcer/sight4.wav");
precache_sound2 ("enforcer/pain1.wav");
precache_sound2 ("enforcer/pain2.wav");
precache_sound2 ("enforcer/death1.wav");
precache_sound2 ("enforcer/idle1.wav");
self.nextthink = time + 0.1 + random();
self.think = noise_think;
};

243
MONSTERS.QC Normal file
View File

@ -0,0 +1,243 @@
/* ALL MONSTERS SHOULD BE 1 0 0 IN COLOR */
// name =[framenum, nexttime, nextthink] {code}
// expands to:
// name ()
// {
// self.frame=framenum;
// self.nextthink = time + nexttime;
// self.think = nextthink
// <code>
// };
/*
================
monster_use
Using a monster makes it angry at the current activator
================
*/
void() monster_use =
{
if (self.enemy)
return;
if (self.health <= 0)
return;
if (activator.items & IT_INVISIBILITY)
return;
if (activator.flags & FL_NOTARGET)
return;
if (activator.classname != "player")
return;
// delay reaction so if the monster is teleported, its sound is still
// heard
self.enemy = activator;
self.nextthink = time + 0.1;
self.think = FoundTarget;
};
/*
================
monster_death_use
When a mosnter dies, it fires all of its targets with the current
enemy as activator.
================
*/
void() monster_death_use =
{
local entity ent, otemp, stemp;
// fall to ground
if (self.flags & FL_FLY)
self.flags = self.flags - FL_FLY;
if (self.flags & FL_SWIM)
self.flags = self.flags - FL_SWIM;
if (!self.target)
return;
activator = self.enemy;
SUB_UseTargets ();
};
//============================================================================
void() walkmonster_start_go =
{
local string stemp;
local entity etemp;
self.origin_z = self.origin_z + 1; // raise off floor a bit
droptofloor();
if (!walkmove(0,0))
{
dprint ("walkmonster in wall!\n");
dprint (self.classname);
dprint (" at ");
dprint (vtos(self.origin));
dprint ("\n");
}
self.takedamage = DAMAGE_AIM;
self.ideal_yaw = self.angles * '0 1 0';
if (!self.yaw_speed)
self.yaw_speed = 20;
self.view_ofs = '0 0 25';
self.use = monster_use;
self.flags = self.flags | FL_MONSTER;
if (self.target)
{
self.goalentity = self.movetarget = find(world, targetname, self.target);
self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
if (!self.movetarget)
{
dprint ("Monster can't find target at ");
dprint (vtos(self.origin));
dprint ("\n");
}
// this used to be an objerror
if (self.movetarget.classname == "path_corner")
self.th_walk ();
else
self.pausetime = 99999999;
self.th_stand ();
}
else
{
self.pausetime = 99999999;
self.th_stand ();
}
// spread think times so they don't all happen at same time
self.nextthink = self.nextthink + random()*0.5;
};
void() walkmonster_start =
{
// delay drop to floor to make sure all doors have been spawned
// spread think times so they don't all happen at same time
self.nextthink = self.nextthink + random()*0.5;
self.think = walkmonster_start_go;
total_monsters = total_monsters + 1;
};
void() flymonster_start_go =
{
self.takedamage = DAMAGE_AIM;
self.ideal_yaw = self.angles * '0 1 0';
if (!self.yaw_speed)
self.yaw_speed = 10;
self.view_ofs = '0 0 25';
self.use = monster_use;
self.flags = self.flags | FL_FLY;
self.flags = self.flags | FL_MONSTER;
if (!walkmove(0,0))
{
dprint ("flymonster in wall!\n");
dprint (self.classname);
dprint (" at ");
dprint (vtos(self.origin));
dprint ("\n");
}
if (self.target)
{
self.goalentity = self.movetarget = find(world, targetname, self.target);
if (!self.movetarget)
{
dprint ("Monster can't find target at ");
dprint (vtos(self.origin));
dprint ("\n");
}
// this used to be an objerror
if (self.movetarget.classname == "path_corner")
self.th_walk ();
else
self.pausetime = 99999999;
self.th_stand ();
}
else
{
self.pausetime = 99999999;
self.th_stand ();
}
};
void() flymonster_start =
{
// spread think times so they don't all happen at same time
self.nextthink = self.nextthink + random()*0.5;
self.think = flymonster_start_go;
total_monsters = total_monsters + 1;
};
void() swimmonster_start_go =
{
if (deathmatch)
{
remove(self);
return;
}
self.takedamage = DAMAGE_AIM;
total_monsters = total_monsters + 1;
self.ideal_yaw = self.angles * '0 1 0';
if (!self.yaw_speed)
self.yaw_speed = 10;
self.view_ofs = '0 0 10';
self.use = monster_use;
self.flags = self.flags | FL_SWIM;
self.flags = self.flags | FL_MONSTER;
if (self.target)
{
self.goalentity = self.movetarget = find(world, targetname, self.target);
if (!self.movetarget)
{
dprint ("Monster can't find target at ");
dprint (vtos(self.origin));
dprint ("\n");
}
// this used to be an objerror
self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
self.th_walk ();
}
else
{
self.pausetime = 99999999;
self.th_stand ();
}
// spread think times so they don't all happen at same time
self.nextthink = self.nextthink + random()*0.5;
};
void() swimmonster_start =
{
// spread think times so they don't all happen at same time
self.nextthink = self.nextthink + random()*0.5;
self.think = swimmonster_start_go;
// Don't count here. swimmonster_start_go already increments
// the monster count!!!
// total_monsters = total_monsters + 1;
};

567
MORPH.QC Normal file
View File

@ -0,0 +1,567 @@
// morph.qc
$skin aztec
$skin pharoah
$skin roman
$skin florskin
$frame mfstand1
//$frame mfup01 mfup02 mfup03 mfup04 mfup05 mfup06
//$frame mfup07 mfup08 mfup09 mfup10 mfup11 mfup12
$frame start01 start02 start03 start04 start05 start06
$frame start07 start08 start09 start10 start11 start12
$frame start13 start14 start15 start16 start17 start18
$frame start19 start20 start21 start22 start23 start24
$frame start25 start26 start27 start28 start29 start30 start31
$frame mfrun01 mfrun02 mfrun03 mfrun04 mfrun05 mfrun06
$frame mfrun07 mfrun08 mfrun09 mfrun10 mfrun11
$frame mfwlk01 mfwlk02 mfwlk03 mfwlk04 mfwlk05 mfwlk06 mfwlk07 mfwlk08
$frame mfwlk09 mfwlk10 mfwlk11 mfwlk12 mfwlk13
$frame mfata01 mfata02 mfata03 mfata04 mfata05
$frame mfata06 mfata07 mfata08 mfata09
$frame mfatb01 mfatb02 mfatb03 mfatb04 mfatb05 mfatb06
$frame mfatb07 mfatb08 mfatb09 mfatb10 mfatb11
$frame mfatc01 mfatc02 mfatc03 mfatc04 mfatc05 mfatc06
$frame mfatc07 mfatc08 mfatc09 mfatc10 mfatc11 mfatc12
$frame mfatc13 mfatc14 mfatc15 mfatc16
$frame mfknck01 mfknck02 mfknck03 mfknck04 mfknck05 mfknck06
$frame mfknck07 mfknck08 mfknck09 mfknck10 mfknck11 mfknck12
$frame mfpain01 mfpain02 mfpain03 mfpain04 mfpain05
$frame mfpain06 mfpain07 mfpain08 mfpain09 mfpain10
$frame mfpbin01 mfpbin02 mfpbin03 mfpbin04 mfpbin05
$frame mfpbin06 mfpbin07
$frame mfdth01 mfdth02 mfdth03 mfdth04 mfdth05
$frame mfdth06 mfdth07 mfdth08 mfdth09 mfdth10
$frame mfdth11 mfdth12 mfdth13 mfdth14 mfdth15
$frame mfdth16 mfdth17 mfdth18 mfdth19 mfdth20
$frame mfdth21
float MORPH_AZTEC = 2;
float MORPH_EGYPT = 4;
float MORPH_GREEK = 8;
void() morph_teleport;
// ========================
// standing
// ========================
void() morph_stand1 = [ $mfstand1, morph_stand1 ] { ai_stand(); };
// ========================
// movement
// ========================
// 3 2 1 1 0 1 2 3 4 5 4 2 1 0
// 3 2 1 2 3 4 4 3 2 1 2 3 3
// 2 4 4 4 3 3 2 2 4 4 3 2 1
// 4 5 5 4 3 2 2 4 5 4 3 2 2
void() morph_walk1 = [ $mfwlk01, morph_walk2 ] {ai_walk(3);};
void() morph_walk2 = [ $mfwlk02, morph_walk3 ] {ai_walk(2);};
void() morph_walk3 = [ $mfwlk03, morph_walk4 ] {ai_walk(4);};
void() morph_walk4 = [ $mfwlk04, morph_walk5 ] {ai_walk(5);};
void() morph_walk5 = [ $mfwlk05, morph_walk6 ] {ai_walk(5);};
void() morph_walk6 = [ $mfwlk06, morph_walk7 ] {ai_walk(4);}; //1
void() morph_walk7 = [ $mfwlk07, morph_walk8 ] {ai_walk(2);}; //1
void() morph_walk8 = [ $mfwlk08, morph_walk9 ] {ai_walk(3);};
void() morph_walk9 = [ $mfwlk09, morph_walk10 ] {ai_walk(4);};
void() morph_walk10 = [ $mfwlk10, morph_walk11 ] {ai_walk(5);};
void() morph_walk11 = [ $mfwlk11, morph_walk12 ] {ai_walk(5);};
void() morph_walk12 = [ $mfwlk12, morph_walk13 ] {ai_walk(4);};
void() morph_walk13 = [ $mfwlk13, morph_walk1 ] {ai_walk(3);}; // 1
// 8 6 4 10 13 13 11 10
// 11 15 10 10 8 15 10 8 8 8 8
// 6 9 13 13 9 6 9 13 15 13 9
void() morph_run1 = [ $mfrun01, morph_run2 ] { ai_run( 7);}; // 33
void() morph_run2 = [ $mfrun02, morph_run3 ] { ai_run(11);};
void() morph_run3 = [ $mfrun03, morph_run4 ] { ai_run(16);};
void() morph_run4 = [ $mfrun04, morph_run5 ] { ai_run(16);}; // 36
void() morph_run5 = [ $mfrun05, morph_run6 ] { ai_run(11);};
void() morph_run6 = [ $mfrun06, morph_run7 ] { ai_run( 7);}; // 38
void() morph_run7 = [ $mfrun07, morph_run8 ] { ai_run(11);};
void() morph_run8 = [ $mfrun08, morph_run9 ] { ai_run(15);}; // 40
void() morph_run9 = [ $mfrun09, morph_run10 ] {ai_run(19);};
void() morph_run10 =[ $mfrun10, morph_run11 ] {ai_run(15);};
void() morph_run11 =[ $mfrun11, morph_run1 ] { ai_run(11);}; // 43
// ========================
// new attack code
// ========================
void() morph_stab2 =
{
local float dist;
local float attackDamage;
local vector org, dir;
if (!self.enemy)
return;
if (!CanDamage (self.enemy, self))
return;
ai_face();
dir = self.enemy.origin - self.origin + self.enemy.view_ofs;
dist = vlen ( dir );
dir = normalize ( dir );
makevectors (self.angles);
if ( dist <= 90 )
{
sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC);
attackDamage = (random() * 10) + 20;
T_Damage (self.enemy, self, self, attackDamage);
SpawnBlood ( self.enemy.origin, v_forward * 150, 14);
}
else
{
self.effects = self.effects | EF_MUZZLEFLASH;
org = self.origin + v_forward * 80 + v_right * 4 + '0 0 4';
LaunchLaser(org, dir);
if ( dist )
{
LaunchLaser(org, (dir + v_right * 0.04));
LaunchLaser(org, (dir - v_right * 0.04));
}
else
{
LaunchLaser(org, (dir + v_right * 0.10));
LaunchLaser(org, (dir - v_right * 0.10));
}
}
};
// ========================
// hand to hand attack
// ========================
void() morph_attack01 = [ $mfatb01, morph_attack02 ] {ai_face();};
void() morph_attack02 = [ $mfatb02, morph_attack03 ] {ai_face();};
void() morph_attack03 = [ $mfatb03, morph_attack04 ] {ai_face();};
void() morph_attack04 = [ $mfatb04, morph_attack05 ] {ai_face();};
void() morph_attack05 = [ $mfatb05, morph_attack06 ] {ai_face();};
void() morph_attack06 = [ $mfatb06, morph_attack07 ] {ai_face();};
void() morph_attack07 = [ $mfatb07, morph_attack08 ] {morph_stab2();};
void() morph_attack08 = [ $mfatb08, morph_attack09 ] {ai_face();};
void() morph_attack09 = [ $mfatb09, morph_attack10 ] {ai_face();};
void() morph_attack10 = [ $mfatb10, morph_attack11 ] {ai_face();};
void() morph_attack11 = [ $mfatb11, morph_attack12 ] {ai_face();};
void() morph_attack12 = [ $mfatb01, morph_run1 ] {ai_face();};
void() morph_bigattack01 = [ $mfatc01, morph_bigattack02 ] { ai_face(); };
void() morph_bigattack02 = [ $mfatc02, morph_bigattack03 ] { ai_face(); };
void() morph_bigattack03 = [ $mfatc03, morph_bigattack04 ] { ai_face(); };
void() morph_bigattack04 = [ $mfatc04, morph_bigattack05 ] { ai_face(); };
void() morph_bigattack05 = [ $mfatc05, morph_bigattack06 ] { ai_face(); };
void() morph_bigattack06 = [ $mfatc06, morph_bigattack07 ] { ai_face(); };
void() morph_bigattack07 = [ $mfatc07, morph_bigattack08 ] { ai_face(); };
void() morph_bigattack08 = [ $mfatc08, morph_bigattack09 ] { ai_face(); };
void() morph_bigattack09 = [ $mfatc09, morph_bigattack10 ] { ai_face(); };
void() morph_bigattack10 = [ $mfatc10, morph_bigattack11 ] { morph_stab2();};
void() morph_bigattack11 = [ $mfatc11, morph_bigattack12 ] { ai_face(); };
void() morph_bigattack12 = [ $mfatc12, morph_bigattack13 ] { ai_face(); };
void() morph_bigattack13 = [ $mfatc13, morph_bigattack14 ] { ai_face(); };
void() morph_bigattack14 = [ $mfatc14, morph_bigattack15 ] { ai_face(); };
void() morph_bigattack15 = [ $mfatc15, morph_bigattack16 ] { ai_face(); };
void() morph_bigattack16 = [ $mfatc16, morph_bigattack17 ] { ai_face(); };
void() morph_bigattack17 = [ $mfatc01, morph_run1 ] { ai_face(); };
void() morph_smack =
{
local vector delta;
local float ldmg;
if (!self.enemy)
return;
if (!CanDamage (self.enemy, self))
return;
ai_face();
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 100)
return;
ldmg = (random() * 10) + 10;
T_Damage (self.enemy, self, self, ldmg);
makevectors (self.angles);
self.enemy.velocity = v_forward * 100 + '0 0 100';
};
void() morph_knockback01 = [ $mfknck01, morph_knockback02 ] { ai_face(); };
void() morph_knockback02 = [ $mfknck02, morph_knockback03 ] { ai_face(); };
void() morph_knockback03 = [ $mfknck03, morph_knockback04 ] { ai_face(); };
void() morph_knockback04 = [ $mfknck04, morph_knockback05 ] { ai_face(); };
void() morph_knockback05 = [ $mfknck05, morph_knockback06 ] { ai_face(); };
void() morph_knockback06 = [ $mfknck06, morph_knockback07 ] { ai_face(); };
void() morph_knockback07 = [ $mfknck07, morph_knockback08 ] { ai_face(); };
void() morph_knockback08 = [ $mfknck08, morph_knockback09 ] { ai_face(); };
void() morph_knockback09 = [ $mfknck09, morph_knockback10 ] { morph_smack(); };
void() morph_knockback10 = [ $mfknck10, morph_knockback11 ] { ai_face(); };
void() morph_knockback11 = [ $mfknck11, morph_knockback12 ] { ai_face(); };
void() morph_knockback12 = [ $mfknck12, morph_run1 ] { ai_face(); };
void() morph_attack =
{
local float attackChoice;
attackChoice = random();
if (attackChoice < 0.50)
morph_bigattack01();
else if (attackChoice < 0.75)
morph_attack01();
else
morph_knockback01();
};
// ========================
// ranged attack
// ========================
void() morph_fire =
{
local vector org, dir;
ai_face();
self.effects = self.effects | EF_MUZZLEFLASH;
makevectors (self.angles);
org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
dir = normalize ( self.enemy.origin - self.origin ) ;
LaunchLaser(org, dir);
if ( vlen (self.enemy.origin - self.origin) > 400 )
{
LaunchLaser(org, (dir + v_right * 0.04));
LaunchLaser(org, (dir - v_right * 0.04));
}
else
{
LaunchLaser(org, (dir + v_right * 0.10));
LaunchLaser(org, (dir - v_right * 0.10));
}
};
void() morph_fire1 = [ $mfata01, morph_fire2 ] {ai_face();};
void() morph_fire2 = [ $mfata02, morph_fire3 ] {ai_face();};
void() morph_fire3 = [ $mfata03, morph_fire4 ] {ai_face();};
void() morph_fire4 = [ $mfata04, morph_fire5 ] {morph_fire();};
void() morph_fire5 = [ $mfata05, morph_fire6 ] {ai_face();};
void() morph_fire6 = [ $mfata06, morph_fire7 ] {ai_face();};
void() morph_fire7 = [ $mfata07, morph_fire8 ] {ai_face();};
void() morph_fire8 = [ $mfata08, morph_fire9] {ai_face();};
void() morph_fire9 = [ $mfata09, morph_run1 ] {ai_face();};
// ========================
// pain
// ========================
void() morph_painA1 = [ $mfpain01, morph_painA2 ] {};
void() morph_painA2 = [ $mfpain02, morph_painA3 ] {};
void() morph_painA3 = [ $mfpain03, morph_painA4 ] {};
void() morph_painA4 = [ $mfpain04, morph_painA5 ] {};
void() morph_painA5 = [ $mfpain05, morph_painA6 ] {};
void() morph_painA6 = [ $mfpain06, morph_painA7 ] {};
void() morph_painA7 = [ $mfpain07, morph_painA8 ] {};
void() morph_painA8 = [ $mfpain08, morph_painA9 ] {};
void() morph_painA9 = [ $mfpain09, morph_painA10 ] {};
void() morph_painA10 = [ $mfpain10, morph_run1 ] {morph_teleport();};
void() morph_painB1 = [ $mfpbin01, morph_painB2 ] {};
void() morph_painB2 = [ $mfpbin02, morph_painB3 ] {};
void() morph_painB3 = [ $mfpbin03, morph_painB4 ] {};
void() morph_painB4 = [ $mfpbin04, morph_painB5 ] {};
void() morph_painB5 = [ $mfpbin05, morph_painB6 ] {};
void() morph_painB6 = [ $mfpbin06, morph_painB7 ] {};
void() morph_painB7 = [ $mfpbin07, morph_run1 ] {morph_teleport();};
void() morph_pain =
{
local float painChoice;
if (skill == 3)
{
if (random() > 0.5)
morph_teleport();
return;
}
if (self.pain_finished > time)
return;
if (random() > 0.25)
return;
painChoice = random();
self.pain_finished = time + 2;
sound (self, CHAN_VOICE, "guard/pain1.wav", 1, ATTN_NORM );
if ( painChoice > 0.6)
self.think = morph_painB1;
else
self.think = morph_painA1;
self.nextthink = time + 0.1;
};
// ========================
// die
// ========================
void() morph_die1 = [ $mfdth01, morph_die2 ] {}; // 122
void() morph_die2 = [ $mfdth02, morph_die3 ] {};
void() morph_die3 = [ $mfdth03, morph_die4 ] {};
void() morph_die4 = [ $mfdth04, morph_die5 ] {};
void() morph_die5 = [ $mfdth05, morph_die6 ] {}; // 126
void() morph_die6 = [ $mfdth06, morph_die7 ] {};
void() morph_die7 = [ $mfdth07, morph_die8 ] {};
void() morph_die8 = [ $mfdth08, morph_die9 ] {}; // 129
void() morph_die9 = [ $mfdth09, morph_die10 ] { self.skin = self.skin + 1; };
void() morph_die10 = [ $mfdth10, morph_die11 ] {};
void() morph_die11 = [ $mfdth11, morph_die12 ] {};
void() morph_die12 = [ $mfdth12, morph_die13 ] {}; // 132
void() morph_die13 = [ $mfdth13, morph_die14 ] {};
void() morph_die14 = [ $mfdth14, morph_die15 ] {};
void() morph_die15 = [ $mfdth15, morph_die16 ] {};
void() morph_die16 = [ $mfdth16, morph_die17 ] {}; // 136
void() morph_die17 = [ $mfdth17, morph_die18 ] {};
void() morph_die18 = [ $mfdth18, morph_die19 ] {};
void() morph_die19 = [ $mfdth19, morph_die20 ] {};
void() morph_die20 = [ $mfdth20, morph_die21 ] {}; // 140
void() morph_die21 = [ $mfdth21, morph_die21 ]
{
remove(self);
};
void() morph_die =
{
sound ( self, CHAN_VOICE, "guard/death.wav", 1, ATTN_NORM);
self.solid = SOLID_NOT;
self.think = morph_die1;
self.nextthink = time + 0.1;
};
// ========================
// hide in floor
// ========================
void() morph_wake1 = [ $start01, morph_wake2 ]
{
sound ( self, CHAN_VOICE, "guard/see1.wav", 1, ATTN_NORM );
if(self.owner)
{
// self.solid = SOLID_SLIDEBOX;
// self.takedamage = DAMAGE_NO;
total_monsters = total_monsters + 1;
self.owner.childrenSpawned = self.owner.childrenSpawned + 1;
WriteByte (MSG_BROADCAST, SVC_UPDATESTAT);
WriteByte (MSG_BROADCAST, STAT_TOTALMONSTERS);
WriteLong (MSG_BROADCAST, total_monsters);
}
};
void() morph_wake2 = [ $start02, morph_wake3 ] {};
void() morph_wake3 = [ $start03, morph_wake4 ] {};
void() morph_wake4 = [ $start04, morph_wake5 ] {};
void() morph_wake5 = [ $start05, morph_wake6 ] {};
void() morph_wake6 = [ $start06, morph_wake7 ] {};
void() morph_wake7 = [ $start07, morph_wake8 ] {};
void() morph_wake8 = [ $start08, morph_wake9 ] {};
void() morph_wake9 = [ $start09, morph_wake10 ] {};
void() morph_wake10 = [ $start10, morph_wake11 ] {};
void() morph_wake11 = [ $start11, morph_wake12 ] {};
void() morph_wake12 = [ $start12, morph_wake13 ] {};
void() morph_wake13 = [ $start13, morph_wake14 ] {};
void() morph_wake14 = [ $start14, morph_wake15 ] {};
void() morph_wake15 = [ $start15, morph_wake16 ]
{ self.skin = 1; };
void() morph_wake16 = [ $start16, morph_wake17 ] {};
void() morph_wake17 = [ $start17, morph_wake18 ] {};
void() morph_wake18 = [ $start18, morph_wake20 ] {};
//void() morph_wake18 = [ $start18, morph_wake19 ] {};
//void() morph_wake19 = [ $start19, morph_wake20 ] {};
void() morph_wake20 = [ $start20, morph_wake21 ] {};
void() morph_wake21 = [ $start21, morph_wake22 ] {};
void() morph_wake22 = [ $start22, morph_wake23 ] {};
void() morph_wake23 = [ $start23, morph_wake24 ] {};
void() morph_wake24 = [ $start24, morph_wake25 ] {};
void() morph_wake25 = [ $start25, morph_wake26 ] {};
void() morph_wake26 = [ $start26, morph_wake27 ] {};
void() morph_wake27 = [ $start27, morph_wake28 ] {};
void() morph_wake28 = [ $start28, morph_wake29 ] {};
void() morph_wake29 = [ $start29, morph_wake30 ] {};
void() morph_wake30 = [ $start30, morph_wake31 ] {};
void() morph_wake31 = [ $start31, morph_stand1 ]
{
self.solid = SOLID_SLIDEBOX;
self.takedamage = DAMAGE_AIM;
self.skin = self.skin - 1;
if ( self.owner )
{
self.think = morph_run1;
self.nextthink = time + 0.1;
}
};
void(entity theMorph) morph_setup =
{
theMorph.solid = SOLID_SLIDEBOX;
theMorph.movetype = MOVETYPE_STEP;
theMorph.takedamage = DAMAGE_NO;
theMorph.flags = theMorph.flags | FL_MONSTER;
theMorph.ideal_yaw = theMorph.angles * '0 1 0';
if (!theMorph.yaw_speed)
theMorph.yaw_speed = 20;
theMorph.view_ofs = '0 0 25';
theMorph.frame = $start01;
setmodel (theMorph, theMorph.model);
setsize (theMorph, VEC_HULL_MIN, VEC_HULL_MAX);
theMorph.th_stand = morph_stand1;
theMorph.th_walk = morph_walk1;
theMorph.th_run = morph_run1;
theMorph.th_missile = morph_fire1;
theMorph.th_melee = morph_attack;
theMorph.th_pain = morph_pain;
theMorph.th_die = morph_die;
if ( theMorph.owner )
{
theMorph.effects = 0;
theMorph.health = 200;
theMorph.spawnflags = theMorph.owner.spawnflags;
}
else
{
theMorph.effects = theMorph.effects | EF_DIMLIGHT;
theMorph.health = 2000;
}
// theMorph.frame = $start01;
theMorph.skin = 2;
};
void() morph_wake =
{
if (isSpawnPointEmpty(self))
{
morph_setup(self);
self.think = morph_wake1;
}
else
{
self.think = morph_wake;
}
self.nextthink = time + 0.1;
};
void() morph_use =
{
// self.enemy = activator;
if ( self.delay )
{
self.think = morph_wake;
self.nextthink = time + self.delay;
}
else
{
self.think = morph_wake;
self.nextthink = time + 0.1;
}
};
void() morph_teleport =
{
local entity theDest;
local entity theChild;
local entity selfTemp;
if (self.owner)
return;
if (self.childrenSpawned > (1+skill))
return;
theDest = overlord_find_dest3();
if (theDest == world)
return;
theChild = spawn();
theChild.model = self.model;
theChild.angles = theDest.mangle;
theChild.owner = self;
theChild.enemy = self.enemy;
theChild.movetarget = self.movetarget;
theChild.goalentity = self.goalentity;
theChild.mangle = theDest.mangle;
theChild.classname = "monster_morph";
morph_setup (theChild);
setorigin (theChild, theDest.origin);
droptofloor();
theChild.think = morph_wake1;
theChild.nextthink = time + 0.3;
};
/*QUAKED monster_morph (1 0 0) (-16 -16 -24) (16 16 32) Ambush Aztec Egyptian Greek
The morphing monster.
Select the look of the monster (Aztec,Greek,Egyptian).
If the monster has a targetname (triggered by something) he will rise up out of the floor when triggered.
*/
void() monster_morph =
{
if (deathmatch)
{
remove(self);
return;
}
if (self.spawnflags & MORPH_AZTEC) // Aztec
{
precache_model ("progs/morph_az.mdl");
self.model = "progs/morph_az.mdl";
}
else if (self.spawnflags & MORPH_EGYPT) // Egyptian
{
precache_model ("progs/morph_eg.mdl");
self.model = "progs/morph_eg.mdl";
}
else if (self.spawnflags & MORPH_GREEK) // greek
{
precache_model ("progs/morph_gr.mdl");
self.model = "progs/morph_gr.mdl";
}
else
objerror ( "monster_morph: no skin selection!");
precache_model2 ("progs/laser.mdl");
precache_sound2 ("enforcer/enfire.wav");
precache_sound2 ("guard/death.wav");
precache_sound2 ("guard/pain1.wav");
precache_sound2 ("guard/see1.wav");
total_monsters = total_monsters + 1;
if(self.targetname)
{
self.use = morph_use;
}
else
{
morph_wake ();
}
};

70
MOTD.QC Normal file
View File

@ -0,0 +1,70 @@
// Rogue Teamplay Variants Message of the Day function
// Feb'97 by ZOID <zoid@threewave.com>
// Under contract to id software for Rogue Entertainment
.float motd_time;
.float motd_count;
void() MOTD =
{
local string tp;
if (self.motd_count < 5) {
if (teamplay > 3 && teamplay < 7)
{
tp = ftos(teamplay);
stuffcmd(self, "teamplay ");
stuffcmd(self, tp);
stuffcmd(self, "\n");
}
self.motd_time = time + 1;
self.motd_count = self.motd_count + 1;
/*
if (teamplay == TEAM_NORMAL_NODAMAGE)
centerprint(self, "Welcome to\nThe Dissolution of Eternity!\nBy Rogue Entertainment\n\nTeam play: No Friendly Fire\n");
else if (teamplay == TEAM_NORMAL_DAMAGE)
centerprint(self, "Welcome to\nThe Dissolution of Eternity!\nBy Rogue Entertainment\n\nTeam play: Friendly Fire\n");
*/
if (teamplay == TEAM_DMATCH_TAG)
centerprint(self, "Welcome to\nThe Dissolution of Eternity!\nBy Rogue Entertainment\n\nDeathmatch Tag!\n");
else if (teamplay == TEAM_CTF)
if (self.steam == TEAM1)
centerprint(self, "Welcome to\nThe Dissolution of Eternity!\nBy Rogue Entertainment\n\nCAPTURE THE FLAG!\n\nYou are ÒÅÄ team!\n");
else
centerprint(self, "Welcome to\nThe Dissolution of Eternity!\nBy Rogue Entertainment\n\nCAPTURE THE FLAG!\n\nYou are ÂÌÕÅ team!\n");
else if (teamplay == TEAM_CTF_ONEFLAG)
if (self.steam == TEAM1)
centerprint(self, "Welcome to\nThe Dissolution of Eternity!\nBy Rogue Entertainment\n\nCAPTURE THE FLAG!\n(One Flag Mode)\n\nYou are ÒÅÄ team!\n");
else
centerprint(self, "Welcome to\nThe Dissolution of Eternity!\nBy Rogue Entertainment\n\nCAPTURE THE FLAG!\n(One Flag Mode)\n\nYou are ÂÌÕÅ team!\n");
else if (teamplay == TEAM_CTF_ALT)
if (self.steam == TEAM1)
centerprint(self, "Welcome to\nThe Dissolution of Eternity!\nBy Rogue Entertainment\n\nCAPTURE THE FLAG!\n(Three Team Mode)\n\nYou are ÒÅÄ team!\n");
else if (self.steam == TEAM2)
centerprint(self, "Welcome to\nThe Dissolution of Eternity!\nBy Rogue Entertainment\n\nCAPTURE THE FLAG!\n(Three Team Mode)\n\nYou are ÂÌÕÅ team!\n");
else
centerprint(self, "Welcome to\nThe Dissolution of Eternity!\nBy Rogue Entertainment\n\nCAPTURE THE FLAG!\n(Three Team Mode)\n\nYou are ÇÒÅÙ team!\n");
return;
}
self.motd_time = 0;
};
void() CheckMOTD =
{
// if (self.motd_time && self.motd_time < time)
if (self.motd_time)
{
if(self.motd_time < time)
MOTD();
}
};
void() SetMOTD =
{
self.motd_time = time + 3;
if ( teamplay == 3 )
self.motd_count = 2;
else
self.motd_count = 0;
};

551
MULT_WPN.QC Normal file
View File

@ -0,0 +1,551 @@
// multi_weapons.qc
// pmack
// sept 96
//=============================================================================
// Multi Grenade Code
//=============================================================================
void() MultiGrenadeTouch;
//================================
//================================
void() MiniGrenadeExplode =
{
if ( self.owner.classname == "player")
T_RadiusDamage (self, self.owner, 90, world);
else
T_RadiusDamage (self, self.owner, 60, world);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION2);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
WriteByte (MSG_BROADCAST, 230);
WriteByte (MSG_BROADCAST, 5);
BecomeExplosion ();
};
//================================
//================================
void(float offsetAngle) MiniGrenadeLaunch =
{
local entity missile, mpuff;
local float tempRand;
missile = spawn ();
missile.owner = self.owner;
missile.movetype = MOVETYPE_BOUNCE;
missile.solid = SOLID_BBOX;
missile.classname = "MiniGrenade";
// set missile speed
missile.v_angle = self.v_angle;
missile.v_angle_y = missile.v_angle_y + offsetAngle;
makevectors (missile.v_angle);
missile.velocity = v_forward*100 + v_up*400;
tempRand = (crandom()*60) - 30;
missile.velocity = missile.velocity + tempRand * v_forward;
tempRand = (crandom()*40) - 20;
missile.velocity = missile.velocity + tempRand * v_right;
tempRand = (crandom()*60) - 30;
missile.velocity = missile.velocity + tempRand * v_up;
missile.avelocity = '300 300 300';
missile.angles = vectoangles(missile.velocity);
missile.touch = MultiGrenadeTouch;
setmodel (missile, "progs/mervup.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin);
// set missile duration
missile.nextthink = time + 1 + (crandom() * 0.5);
missile.think = MiniGrenadeExplode;
};
//================================
//================================
void() MultiGrenadeExplode =
{
MiniGrenadeLaunch(0);
MiniGrenadeLaunch(72);
MiniGrenadeLaunch(144);
MiniGrenadeLaunch(216);
MiniGrenadeLaunch(288);
remove (self);
};
//================================
//================================
void() MultiGrenadeTouch =
{
if (other == self.owner)
return; // don't explode on owner
if (other.takedamage == DAMAGE_AIM)
{
if (self.classname == "MiniGrenade")
MiniGrenadeExplode();
else
{
if (self.owner.classname == "player")
GrenadeExplode();
else
MiniGrenadeExplode();
}
return;
}
// bounce sound
sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);
if (self.velocity == '0 0 0')
self.avelocity = '0 0 0';
};
//================================
//================================
void() W_FireMultiGrenade =
{
local entity missile, mpuff;
self.currentammo = self.ammo_multi_rockets = self.ammo_multi_rockets - 1;
UpdateAmmoCounts (self);
sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
self.punchangle_x = -2;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_BOUNCE;
missile.solid = SOLID_BBOX;
missile.classname = "MultiGrenade";
// set missile speed
makevectors (self.v_angle);
if (self.v_angle_x)
missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
else
{
missile.velocity = aim(self, 10000);
missile.velocity = missile.velocity * 600;
missile.velocity_z = 200;
}
missile.avelocity = '300 300 300';
missile.angles = vectoangles(missile.velocity);
missile.touch = MultiGrenadeTouch;
// set missile duration
missile.nextthink = time + 1;
missile.think = MultiGrenadeExplode;
setmodel (missile, "progs/mervup.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin);
};
//=============================================================================
// Multi Rocket Code
//=============================================================================
//================================
//================================
void() MultiRocketExplode =
{
local float damg;
// Stock Single Rocket Damage...
// damg = 100 + random()*20;
damg = 60 + random()*15;
if (other.health)
{
if (other.classname == "monster_shambler")
damg = damg * 0.5; // mostly immune
if (other.classname == "monster_dragon")
damg = damg * 0.5; // mostly immune
T_Damage (other, self, self.owner, damg );
}
// don't do radius damage to the other, because all the damage
// was done in the impact
// Stock single rocket damage.
// T_RadiusDamage (self, self.owner, 120, other);
T_RadiusDamage (self, self.owner, 75, other);
// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
self.origin = self.origin - 8*normalize(self.velocity);
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 ();
};
//================================
//================================
void() MultiRocketTouch =
{
if (other == self.owner)
return; // don't explode on owner
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
MultiRocketExplode ();
};
//================================
//================================
void() HomingMissileThink =
{
local vector dir;
if (self.enemy.health < 1)
{
remove(self);
return;
}
dir = normalize(self.enemy.origin - self.origin);
self.velocity = dir * 1000;
self.nextthink = time + 0.1;
self.think = HomingMissileThink;
};
//================================
//================================
void() HomingMissileAcquire =
{
local vector oldVelocity;
local vector aimangle;
if ( self.delay < time )
{
MultiRocketExplode ();
return;
}
oldVelocity = self.velocity;
makevectors (self.v_angle);
self.velocity = aim (self, 1000);
self.velocity = self.velocity * 1000;
aimangle = self.origin + self.velocity;
traceline ( self.origin, aimangle, FALSE, self );
if (trace_fraction < 1)
{
if (trace_ent.flags & FL_MONSTER)
{
self.enemy = trace_ent;
HomingMissileThink();
return;
}
}
self.velocity = oldVelocity;
self.v_angle = vectoangles ( self.velocity );
self.angles = self.v_angle;
self.think = HomingMissileAcquire;
self.nextthink = time + 0.2;
};
//================================
//================================
void(float offset, float frameNum) MultiRocketLaunch =
{
local entity missile, mpuff;
local vector aimangle;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_FLYMISSILE;
missile.solid = SOLID_BBOX;
missile.classname = "MultiRocket";
missile.delay = time + 4;
missile.frame = frameNum;
missile.touch = MultiRocketTouch;
if (deathmatch || coop)
setmodel (missile, "progs/rockup_d.mdl");
else
setmodel (missile, "progs/rockup.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin + v_forward*8 + '0 0 16');
if ( coop || deathmatch)
{
aimangle = self.v_angle;
aimangle_y = aimangle_y + (offset * 0.66);
makevectors (aimangle);
missile.velocity = aim(self, 1000);
missile.velocity = missile.velocity * 1000;
missile.angles = vectoangles(missile.velocity);
missile.think = MultiRocketExplode;
missile.nextthink = time + 4;
}
else
{
makevectors (self.v_angle);
missile.velocity = v_forward * 1000 - v_right*offset*8;
missile.angles = vectoangles(missile.velocity);
missile.v_angle = self.v_angle;
aimangle = missile.origin + missile.velocity;
traceline ( missile.origin, aimangle, FALSE, self );
if (trace_fraction < 1)
{
if (trace_ent.flags & FL_MONSTER)
{
missile.enemy = trace_ent;
missile.think = HomingMissileThink;
return;
}
}
missile.think = HomingMissileAcquire;
missile.nextthink = time + 0.1;
}
};
//================================
//================================
void() W_FireMultiRocket =
{
self.currentammo = self.ammo_multi_rockets = self.ammo_multi_rockets - 1;
UpdateAmmoCounts (self);
sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
self.punchangle_x = -2;
MultiRocketLaunch ( -10, 2 );
MultiRocketLaunch ( -5, 3 );
MultiRocketLaunch ( 5, 0 );
MultiRocketLaunch ( 10, 1 );
};
//=============================================================================
// Plasma Gun Code
//=============================================================================
void(vector p1, vector p2, entity from, float damage) PlasmaDamage =
{
local entity e1, e2;
local vector f;
f = p2 - p1;
normalize (f);
f_x = 0 - f_y;
f_y = f_x;
f_z = 0;
f = f*16;
e1 = e2 = world;
traceline (p1, p2, FALSE, self);
if (trace_ent.takedamage)
{
particle (trace_endpos, '0 0 100', 225, damage*4);
T_Damage (trace_ent, from, from.owner, damage);
if (self.classname == "player")
{
if (other.classname == "player")
trace_ent.velocity_z = trace_ent.velocity_z + 400;
}
}
e1 = trace_ent;
traceline (p1 + f, p2 + f, FALSE, self);
if (trace_ent != e1 && trace_ent.takedamage)
{
particle (trace_endpos, '0 0 100', 225, damage*4);
T_Damage (trace_ent, from, from.owner, damage);
}
e2 = trace_ent;
traceline (p1 - f, p2 - f, FALSE, self);
if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
{
particle (trace_endpos, '0 0 100', 225, damage*4);
T_Damage (trace_ent, from, from.owner, damage);
}
};
//================================
//================================
void(entity current, float doDamage) PlasmaDischarge =
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
WriteEntity (MSG_BROADCAST, current);
WriteCoord (MSG_BROADCAST, current.origin_x);
WriteCoord (MSG_BROADCAST, current.origin_y);
WriteCoord (MSG_BROADCAST, current.origin_z);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
sound (self, CHAN_VOICE, "weapons/lhit.wav", 1, ATTN_NORM);
if (doDamage == 1)
PlasmaDamage (self.origin, current.origin, self, 50);
};
//================================
//================================
void() PlasmaGroundOut =
{
local entity current, start;
local float monstersHit;
monstersHit = 0;
current = findradius ( self.origin, 320 );
start = current;
while ( monstersHit < 5 )
{
if ( current.flags & FL_MONSTER || current.classname == "player")
{
if ( current != self.owner )
{
traceline ( self.origin, current.origin, TRUE, world );
if (trace_fraction == 1)
{
monstersHit = monstersHit + 1;
PlasmaDischarge ( current, 1 );
}
}
}
current = current.chain;
if (start == current || !current)
return;
}
};
//================================
//================================
void() PlasmaTouch =
{
local float damg;
if (other == self.owner)
return; // don't explode on owner
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
damg = 80 + random()*20;
sound (self, CHAN_WEAPON, "plasma/explode.wav", 1, ATTN_NORM);
if (other.health)
{
if (other.classname == "monster_shambler")
damg = damg * 0.5; // mostly immune
T_Damage (other, self, self.owner, damg );
}
// don't do radius damage to the other, because all the damage
// was done in the impact
T_RadiusDamage (self, self.owner, 70, other);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION2);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
WriteByte (MSG_BROADCAST, 244);
WriteByte (MSG_BROADCAST, 3);
PlasmaGroundOut();
remove (self);
};
//================================
//================================
void() PlasmaLaunch =
{
self.velocity = normalize(self.velocity);
self.velocity = self.velocity * 1250;
self.nextthink = time + 5;
self.think = SUB_Remove;
};
void(vector org, vector dir) launch_plasma =
{
local entity missile, mpuff;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_FLYMISSILE;
missile.solid = SOLID_BBOX;
missile.classname = "plasma";
// set missile speed
missile.velocity = dir * 0.01;
missile.avelocity = '300 300 300';
missile.angles = vectoangles(missile.velocity);
missile.touch = PlasmaTouch;
setmodel (missile, "progs/plasma.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, org);
sound (missile, CHAN_WEAPON, "plasma/flight.wav", 1, ATTN_NORM);
if (!deathmatch && !coop)
missile.effects = EF_BRIGHTLIGHT;
// set missile duration
missile.think = PlasmaLaunch;
missile.nextthink = time + 0.1;
};
//================================
//================================
void() W_FirePlasma =
{
local float cells;
local vector dir;
if (self.ammo_plasma < 1)
{
self.weapon = W_BestWeapon ();
W_SetCurrentAmmo ();
return;
}
// explode if under water
if (self.waterlevel > 1)
{
cells = self.ammo_plasma;
self.ammo_plasma = 0;
W_SetCurrentAmmo ();
T_RadiusDamage (self, self, 35*cells, world);
return;
}
self.currentammo = self.ammo_plasma = self.ammo_plasma - 1;
UpdateAmmoCounts (self);
sound (self, CHAN_WEAPON, "plasma/fire.wav", 0.5, ATTN_NORM);
self.punchangle_x = -2;
makevectors (self.v_angle);
dir = aim ( self, 1000 );
launch_plasma (self.origin + v_forward*24 + '0 0 16', dir);
};

506
MUMMY.QC Normal file
View File

@ -0,0 +1,506 @@
/*
==============================================================================
mummy
==============================================================================
*/
$cd /qwork/xpack/models/mummy
$origin 0 0 24
$base base
$skin skin
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8
$frame stand9 stand10 stand11 stand12 stand13 stand14 stand15
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 walk11
$frame walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19
$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12
$frame run13 run14 run15 run16 run17 run18
$frame atta1 atta2 atta3 atta4 atta5 atta6 atta7 atta8 atta9 atta10 atta11
$frame atta12 atta13
$frame attb1 attb2 attb3 attb4 attb5 attb6 attb7 attb8 attb9 attb10 attb11
$frame attb12 attb13 attb14
$frame attc1 attc2 attc3 attc4 attc5 attc6 attc7 attc8 attc9 attc10 attc11
$frame attc12
$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10
$frame paina11 paina12
$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
$frame painb11 painb12 painb13 painb14 painb15 painb16 painb17 painb18 painb19
$frame painb20 painb21 painb22 painb23 painb24 painb25 painb26 painb27 painb28
$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10
$frame painc11 painc12 painc13 painc14 painc15 painc16 painc17 painc18
$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10
$frame paind11 paind12 paind13
$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10
$frame paine11 paine12 paine13 paine14 paine15 paine16 paine17 paine18 paine19
$frame paine20 paine21 paine22 paine23 paine24 paine25 paine26 paine27 paine28
$frame paine29 paine30
//=============================================================================
.float inpain;
void() mummy_stand1 =[ $stand1, mummy_stand2 ] {ai_stand();};
void() mummy_stand2 =[ $stand2, mummy_stand3 ] {ai_stand();};
void() mummy_stand3 =[ $stand3, mummy_stand4 ] {ai_stand();};
void() mummy_stand4 =[ $stand4, mummy_stand5 ] {ai_stand();};
void() mummy_stand5 =[ $stand5, mummy_stand6 ] {ai_stand();};
void() mummy_stand6 =[ $stand6, mummy_stand7 ] {ai_stand();};
void() mummy_stand7 =[ $stand7, mummy_stand8 ] {ai_stand();};
void() mummy_stand8 =[ $stand8, mummy_stand9 ] {ai_stand();};
void() mummy_stand9 =[ $stand9, mummy_stand10 ] {ai_stand();};
void() mummy_stand10 =[ $stand10, mummy_stand11 ] {ai_stand();};
void() mummy_stand11 =[ $stand11, mummy_stand12 ] {ai_stand();};
void() mummy_stand12 =[ $stand12, mummy_stand13 ] {ai_stand();};
void() mummy_stand13 =[ $stand13, mummy_stand14 ] {ai_stand();};
void() mummy_stand14 =[ $stand14, mummy_stand15 ] {ai_stand();};
void() mummy_stand15 =[ $stand15, mummy_stand1 ] {ai_stand();};
void() mummy_walk1 =[ $walk1, mummy_walk2 ] {ai_walk(0);};
void() mummy_walk2 =[ $walk2, mummy_walk3 ] {ai_walk(3);};
void() mummy_walk3 =[ $walk3, mummy_walk4 ] {ai_walk(5);};
void() mummy_walk4 =[ $walk4, mummy_walk5 ] {ai_walk(4);};
void() mummy_walk5 =[ $walk5, mummy_walk6 ] {ai_walk(2);};
void() mummy_walk6 =[ $walk6, mummy_walk7 ] {ai_walk(0);};
void() mummy_walk7 =[ $walk7, mummy_walk8 ] {ai_walk(0);};
void() mummy_walk8 =[ $walk8, mummy_walk9 ] {ai_walk(0);};
void() mummy_walk9 =[ $walk9, mummy_walk10 ] {ai_walk(0);};
void() mummy_walk10 =[ $walk10, mummy_walk11 ] {ai_walk(0);};
void() mummy_walk11 =[ $walk11, mummy_walk12 ] {ai_walk(3);};
void() mummy_walk12 =[ $walk12, mummy_walk13 ] {ai_walk(4);};
void() mummy_walk13 =[ $walk13, mummy_walk14 ] {ai_walk(2);};
void() mummy_walk14 =[ $walk14, mummy_walk15 ] {ai_walk(0);};
void() mummy_walk15 =[ $walk15, mummy_walk16 ] {ai_walk(0);};
void() mummy_walk16 =[ $walk16, mummy_walk17 ] {ai_walk(0);};
void() mummy_walk17 =[ $walk17, mummy_walk18 ] {ai_walk(0);};
void() mummy_walk18 =[ $walk18, mummy_walk19 ] {ai_walk(0);};
void() mummy_walk19 =[ $walk19, mummy_walk1 ]
{
ai_walk(0);
if (random() < 0.2)
sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
};
void() mummy_run1 =[ $run1, mummy_run2 ] {ai_run(2);self.inpain = 0;};
void() mummy_run2 =[ $run2, mummy_run3 ] {ai_run(2);};
void() mummy_run3 =[ $run3, mummy_run4 ] {ai_run(0);};
void() mummy_run4 =[ $run4, mummy_run5 ] {ai_run(2);};
void() mummy_run5 =[ $run5, mummy_run6 ] {ai_run(4);};
void() mummy_run6 =[ $run6, mummy_run7 ] {ai_run(6);};
void() mummy_run7 =[ $run7, mummy_run8 ] {ai_run(8);};
void() mummy_run8 =[ $run8, mummy_run9 ] {ai_run(8);};
void() mummy_run9 =[ $run9, mummy_run10 ] {ai_run(4);};
void() mummy_run10 =[ $run10, mummy_run11 ] {ai_run(0);};
void() mummy_run11 =[ $run11, mummy_run12 ] {ai_run(0);};
void() mummy_run12 =[ $run12, mummy_run13 ] {ai_run(0);};
void() mummy_run13 =[ $run13, mummy_run14 ] {ai_run(4);};
void() mummy_run14 =[ $run14, mummy_run15 ] {ai_run(8);};
void() mummy_run15 =[ $run15, mummy_run16 ] {ai_run(12);};
void() mummy_run16 =[ $run16, mummy_run17 ] {ai_run(14);};
void() mummy_run17 =[ $run17, mummy_run18 ] {ai_run(6);};
void() mummy_run18 =[ $run18, mummy_run1 ]
{
ai_run(16);
if (random() < 0.2)
sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
if (random() > 0.8)
sound (self, CHAN_VOICE, "zombie/z_idle1.wav", 1, ATTN_IDLE);
};
/*
=============================================================================
ATTACKS
=============================================================================
*/
void() mummyGrenadeTouch =
{
local float mummyDamage;
if (other == self.owner)
return; // don't explode on owner
if (other.takedamage)
{
mummyDamage = 15 + random() * 15;
T_Damage (other, self, self.owner, mummyDamage );
sound (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
remove (self);
return;
}
sound (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
self.velocity = '0 0 0';
self.avelocity = '0 0 0';
self.touch = SUB_Remove;
};
/*
================
mummyFireGrenade
================
*/
void(vector st) mummyFireGrenade =
{
local entity missile, mpuff;
local vector org;
sound (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM);
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_BOUNCE;
missile.solid = SOLID_BBOX;
// calc org
org = self.origin + st_x * v_forward + st_y * v_right + (st_z - 24) * v_up;
// set missile speed
makevectors (self.angles);
missile.velocity = normalize(self.enemy.origin - org);
missile.velocity = missile.velocity * 600;
missile.velocity_z = 200;
missile.avelocity = '3000 1000 2000';
missile.touch = mummyGrenadeTouch;
// set missile duration
missile.nextthink = time + 2.5;
missile.think = SUB_Remove;
setmodel (missile, "progs/zom_gib.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, org);
};
void() mummy_atta1 =[ $atta1, mummy_atta2 ] {ai_face();};
void() mummy_atta2 =[ $atta2, mummy_atta3 ] {ai_face();};
void() mummy_atta3 =[ $atta3, mummy_atta4 ] {ai_face();};
void() mummy_atta4 =[ $atta4, mummy_atta5 ] {ai_face();};
void() mummy_atta5 =[ $atta5, mummy_atta6 ] {ai_face();};
void() mummy_atta6 =[ $atta6, mummy_atta7 ] {ai_face();};
void() mummy_atta7 =[ $atta7, mummy_atta8 ] {ai_face();};
void() mummy_atta8 =[ $atta8, mummy_atta9 ] {ai_face();};
void() mummy_atta9 =[ $atta9, mummy_atta10 ] {ai_face();};
void() mummy_atta10 =[ $atta10, mummy_atta11 ] {ai_face();};
void() mummy_atta11 =[ $atta11, mummy_atta12 ] {ai_face();};
void() mummy_atta12 =[ $atta12, mummy_atta13 ] {ai_face();};
void() mummy_atta13 =[ $atta13, mummy_run1 ]
{ ai_face(); mummyFireGrenade('-10 -22 30'); };
void() mummy_attb1 =[ $attb1, mummy_attb2 ] {ai_face();};
void() mummy_attb2 =[ $attb2, mummy_attb3 ] {ai_face();};
void() mummy_attb3 =[ $attb3, mummy_attb4 ] {ai_face();};
void() mummy_attb4 =[ $attb4, mummy_attb5 ] {ai_face();};
void() mummy_attb5 =[ $attb5, mummy_attb6 ] {ai_face();};
void() mummy_attb6 =[ $attb6, mummy_attb7 ] {ai_face();};
void() mummy_attb7 =[ $attb7, mummy_attb8 ] {ai_face();};
void() mummy_attb8 =[ $attb8, mummy_attb9 ] {ai_face();};
void() mummy_attb9 =[ $attb9, mummy_attb10 ] {ai_face();};
void() mummy_attb10 =[ $attb10, mummy_attb11 ] {ai_face();};
void() mummy_attb11 =[ $attb11, mummy_attb12 ] {ai_face();};
void() mummy_attb12 =[ $attb12, mummy_attb13 ] {ai_face();};
void() mummy_attb13 =[ $attb13, mummy_attb14 ] {ai_face();};
void() mummy_attb14 =[ $attb13, mummy_run1 ]
{ ai_face(); mummyFireGrenade('-10 -24 29'); };
void() mummy_attc1 =[ $attc1, mummy_attc2 ] {ai_face();};
void() mummy_attc2 =[ $attc2, mummy_attc3 ] {ai_face();};
void() mummy_attc3 =[ $attc3, mummy_attc4 ] {ai_face();};
void() mummy_attc4 =[ $attc4, mummy_attc5 ] {ai_face();};
void() mummy_attc5 =[ $attc5, mummy_attc6 ] {ai_face();};
void() mummy_attc6 =[ $attc6, mummy_attc7 ] {ai_face();};
void() mummy_attc7 =[ $attc7, mummy_attc8 ] {ai_face();};
void() mummy_attc8 =[ $attc8, mummy_attc9 ] {ai_face();};
void() mummy_attc9 =[ $attc9, mummy_attc10 ] {ai_face();};
void() mummy_attc10 =[ $attc10, mummy_attc11 ] {ai_face();};
void() mummy_attc11 =[ $attc11, mummy_attc12 ] {ai_face();};
void() mummy_attc12 =[ $attc12, mummy_run1 ]
{ ai_face(); mummyFireGrenade('-12 -19 29'); };
void() mummy_missile =
{
local float r;
r = random();
if (r < 0.3)
mummy_atta1 ();
else if (r < 0.6)
mummy_attb1 ();
else
mummy_attc1 ();
};
/*
=============================================================================
PAIN
=============================================================================
*/
void() mummy_paina1 =[ $paina1, mummy_paina2 ]
{sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);};
void() mummy_paina2 =[ $paina2, mummy_paina3 ] {ai_painforward(3);};
void() mummy_paina3 =[ $paina3, mummy_paina4 ] {ai_painforward(1);};
void() mummy_paina4 =[ $paina4, mummy_paina5 ] {ai_pain(1);};
void() mummy_paina5 =[ $paina5, mummy_paina6 ] {ai_pain(3);};
void() mummy_paina6 =[ $paina6, mummy_paina7 ] {ai_pain(1);};
void() mummy_paina7 =[ $paina7, mummy_paina8 ] {};
void() mummy_paina8 =[ $paina8, mummy_paina9 ] {};
void() mummy_paina9 =[ $paina9, mummy_paina10 ] {};
void() mummy_paina10 =[ $paina10, mummy_paina11 ] {};
void() mummy_paina11 =[ $paina11, mummy_paina12 ] {};
void() mummy_paina12 =[ $paina12, mummy_run1 ] {};
void() mummy_painb1 =[ $painb1, mummy_painb2 ]
{sound (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
void() mummy_painb2 =[ $painb2, mummy_painb3 ] {ai_pain(2);};
void() mummy_painb3 =[ $painb3, mummy_painb4 ] {ai_pain(8);};
void() mummy_painb4 =[ $painb4, mummy_painb5 ] {ai_pain(6);};
void() mummy_painb5 =[ $painb5, mummy_painb6 ] {ai_pain(2);};
void() mummy_painb6 =[ $painb6, mummy_painb7 ] {};
void() mummy_painb7 =[ $painb7, mummy_painb8 ] {};
void() mummy_painb8 =[ $painb8, mummy_painb9 ] {};
void() mummy_painb9 =[ $painb9, mummy_painb10 ]
{sound (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);};
void() mummy_painb10 =[ $painb10, mummy_painb11 ] {};
void() mummy_painb11 =[ $painb11, mummy_painb12 ] {};
void() mummy_painb12 =[ $painb12, mummy_painb13 ] {};
void() mummy_painb13 =[ $painb13, mummy_painb14 ] {};
void() mummy_painb14 =[ $painb14, mummy_painb15 ] {};
void() mummy_painb15 =[ $painb15, mummy_painb16 ] {};
void() mummy_painb16 =[ $painb16, mummy_painb17 ] {};
void() mummy_painb17 =[ $painb17, mummy_painb18 ] {};
void() mummy_painb18 =[ $painb18, mummy_painb19 ] {};
void() mummy_painb19 =[ $painb19, mummy_painb20 ] {};
void() mummy_painb20 =[ $painb20, mummy_painb21 ] {};
void() mummy_painb21 =[ $painb21, mummy_painb22 ] {};
void() mummy_painb22 =[ $painb22, mummy_painb23 ] {};
void() mummy_painb23 =[ $painb23, mummy_painb24 ] {};
void() mummy_painb24 =[ $painb24, mummy_painb25 ] {};
void() mummy_painb25 =[ $painb25, mummy_painb26 ] {ai_painforward(1);};
void() mummy_painb26 =[ $painb26, mummy_painb27 ] {};
void() mummy_painb27 =[ $painb27, mummy_painb28 ] {};
void() mummy_painb28 =[ $painb28, mummy_run1 ] {};
void() mummy_painc1 =[ $painc1, mummy_painc2 ]
{sound (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
void() mummy_painc2 =[ $painc2, mummy_painc3 ] {};
void() mummy_painc3 =[ $painc3, mummy_painc4 ] {ai_pain(3);};
void() mummy_painc4 =[ $painc4, mummy_painc5 ] {ai_pain(1);};
void() mummy_painc5 =[ $painc5, mummy_painc6 ] {};
void() mummy_painc6 =[ $painc6, mummy_painc7 ] {};
void() mummy_painc7 =[ $painc7, mummy_painc8 ] {};
void() mummy_painc8 =[ $painc8, mummy_painc9 ] {};
void() mummy_painc9 =[ $painc9, mummy_painc10 ] {};
void() mummy_painc10 =[ $painc10, mummy_painc11 ] {};
void() mummy_painc11 =[ $painc11, mummy_painc12 ] {ai_painforward(1);};
void() mummy_painc12 =[ $painc12, mummy_painc13 ] {ai_painforward(1);};
void() mummy_painc13 =[ $painc13, mummy_painc14 ] {};
void() mummy_painc14 =[ $painc14, mummy_painc15 ] {};
void() mummy_painc15 =[ $painc15, mummy_painc16 ] {};
void() mummy_painc16 =[ $painc16, mummy_painc17 ] {};
void() mummy_painc17 =[ $painc17, mummy_painc18 ] {};
void() mummy_painc18 =[ $painc18, mummy_run1 ] {};
void() mummy_paind1 =[ $paind1, mummy_paind2 ]
{sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);};
void() mummy_paind2 =[ $paind2, mummy_paind3 ] {};
void() mummy_paind3 =[ $paind3, mummy_paind4 ] {};
void() mummy_paind4 =[ $paind4, mummy_paind5 ] {};
void() mummy_paind5 =[ $paind5, mummy_paind6 ] {};
void() mummy_paind6 =[ $paind6, mummy_paind7 ] {};
void() mummy_paind7 =[ $paind7, mummy_paind8 ] {};
void() mummy_paind8 =[ $paind8, mummy_paind9 ] {};
void() mummy_paind9 =[ $paind9, mummy_paind10 ] {ai_pain(1);};
void() mummy_paind10 =[ $paind10, mummy_paind11 ] {};
void() mummy_paind11 =[ $paind11, mummy_paind12 ] {};
void() mummy_paind12 =[ $paind12, mummy_paind13 ] {};
void() mummy_paind13 =[ $paind13, mummy_run1 ] {};
void() mummy_paine1 =[ $paine1, mummy_paine2 ]
{ sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM); };
void() mummy_paine2 =[ $paine2, mummy_paine3 ] {ai_pain(8);};
void() mummy_paine3 =[ $paine3, mummy_paine4 ] {ai_pain(5);};
void() mummy_paine4 =[ $paine4, mummy_paine5 ] {ai_pain(3);};
void() mummy_paine5 =[ $paine5, mummy_paine6 ] {ai_pain(1);};
void() mummy_paine6 =[ $paine6, mummy_paine7 ] {ai_pain(2);};
void() mummy_paine7 =[ $paine7, mummy_paine8 ] {ai_pain(1);};
void() mummy_paine8 =[ $paine8, mummy_paine9 ] {ai_pain(1);};
void() mummy_paine9 =[ $paine9, mummy_paine10 ] {ai_pain(2);};
void() mummy_paine10 =[ $paine10, mummy_paine11 ]
{
sound (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);
self.solid = SOLID_NOT;
};
void() mummy_paine11 =[ $paine11, mummy_paine12 ]
{ self.nextthink = self.nextthink + 5; };
void() mummy_paine12 =[ $paine12, mummy_paine13 ]
{
// see if ok to stand up
sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
self.solid = SOLID_SLIDEBOX;
if (!walkmove (0, 0))
{
self.think = mummy_paine11;
self.solid = SOLID_NOT;
return;
}
};
void() mummy_paine13 =[ $paine13, mummy_paine14 ] {};
void() mummy_paine14 =[ $paine14, mummy_paine15 ] {};
void() mummy_paine15 =[ $paine15, mummy_paine16 ] {};
void() mummy_paine16 =[ $paine16, mummy_paine17 ] {};
void() mummy_paine17 =[ $paine17, mummy_paine18 ] {};
void() mummy_paine18 =[ $paine18, mummy_paine19 ] {};
void() mummy_paine19 =[ $paine19, mummy_paine20 ] {};
void() mummy_paine20 =[ $paine20, mummy_paine21 ] {};
void() mummy_paine21 =[ $paine21, mummy_paine22 ] {};
void() mummy_paine22 =[ $paine22, mummy_paine23 ] {};
void() mummy_paine23 =[ $paine23, mummy_paine24 ] {};
void() mummy_paine24 =[ $paine24, mummy_paine25 ] {};
void() mummy_paine25 =[ $paine25, mummy_paine26 ] {ai_painforward(5);};
void() mummy_paine26 =[ $paine26, mummy_paine27 ] {ai_painforward(3);};
void() mummy_paine27 =[ $paine27, mummy_paine28 ] {ai_painforward(1);};
void() mummy_paine28 =[ $paine28, mummy_paine29 ] {ai_pain(1);};
void() mummy_paine29 =[ $paine29, mummy_paine30 ] {};
void() mummy_paine30 =[ $paine30, mummy_run1 ]
{ };
void() mummy_die =
{
self.health = -35;
sound (self, CHAN_VOICE, "zombie/z_gib.wav", 1, ATTN_NORM);
ThrowHead ("progs/h_zombie.mdl", self.health);
ThrowGib ("progs/gib1.mdl", self.health);
ThrowGib ("progs/gib2.mdl", self.health);
ThrowGib ("progs/gib3.mdl", self.health);
};
/*
=================
mummy_pain
=================
*/
void(entity attacker, float take) mummy_pain =
{
local float r;
if ( self.pain_finished > time )
return;
r = random();
if (r > 0.24)
return;
self.pain_finished = time + 2.5;
if (r < 0.06)
mummy_paina1 ();
else if (r < 0.12)
mummy_painb1 ();
else if (r < 0.18)
mummy_painc1 ();
else
mummy_paind1 ();
};
void() mummy_sleep = [ $paine11, mummy_sleep ] { ai_stand(); };
void() mummy_wake =
{
self.th_stand = mummy_stand1;
self.th_walk = mummy_walk1;
self.th_pain = mummy_pain;
self.th_run = mummy_run1;
self.th_missile = mummy_missile;
mummy_paine12();
};
//============================================================================
float MUMMY_STRONG = 4;
/*QUAKED monster_mummy (1 0 0) (-16 -16 -24) (16 16 32) Ambush Lying Stronger
Lying - mummy will start lying down, and stand when player spotted.
Stronger - mummy starts with 1000 hitpoints, rather than 500.
*/
void() monster_mummy =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/mummy.mdl");
precache_model ("progs/h_zombie.mdl");
precache_model ("progs/zom_gib.mdl");
precache_sound ("zombie/z_idle.wav");
precache_sound ("zombie/z_idle1.wav");
precache_sound ("zombie/z_shot1.wav");
precache_sound ("zombie/z_gib.wav");
precache_sound ("zombie/z_pain.wav");
precache_sound ("zombie/z_pain1.wav");
precache_sound ("zombie/z_fall.wav");
precache_sound ("zombie/z_miss.wav");
precache_sound ("zombie/z_hit.wav");
precache_sound ("zombie/idle_w2.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/mummy.mdl");
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
if (self.spawnflags & MUMMY_STRONG)
self.health = 1000;
else
self.health = 500;
self.th_stand = mummy_stand1;
self.th_walk = mummy_walk1;
self.th_run = mummy_run1;
self.th_pain = mummy_pain;
self.th_die = mummy_die;
self.th_missile = mummy_missile;
if (self.spawnflags & SPAWN_LYING)
{
setsize (self, '-16 -16 -24', '16 16 -16');
self.solid = SOLID_NOT;
self.th_stand = mummy_sleep;
self.th_run = mummy_wake;
self.th_walk = mummy_wake;
self.th_pain = mummy_wake;
self.th_missile = mummy_wake;
walkmonster_start();
}
else
walkmonster_start();
};

133
NEWITEMS.QC Normal file
View File

@ -0,0 +1,133 @@
// New Items
//
// Items added for the Rogue XPACK.
void() sphere_spawn;
void(entity theEntity) UpdateAmmoCounts =
{
if ( self.weapon >= IT_LAVA_NAILGUN )
{
theEntity.ammo_shells = theEntity.ammo_shells1;
theEntity.ammo_nails = theEntity.ammo_lava_nails;
theEntity.ammo_rockets = theEntity.ammo_multi_rockets;
theEntity.ammo_cells = theEntity.ammo_plasma;
}
else
{
theEntity.ammo_shells = theEntity.ammo_shells1;
theEntity.ammo_nails = theEntity.ammo_nails1;
theEntity.ammo_rockets = theEntity.ammo_rockets1;
theEntity.ammo_cells = theEntity.ammo_cells1;
}
};
void() newitems_touch =
{
if (other.classname != "player")
return;
if (other.health <= 0)
return;
// only one per person, please.
if (self.classname == "item_sphere")
if (other.items2 & IT2_V_SPHERE)
return;
sprint (other, "You got the ");
sprint (other, self.netname);
sprint (other,"\n");
if (deathmatch)
{
if (self.classname == "item_random_powerup")
{
self.nextthink = time + 60;
self.think = random_regen;
}
else if (self.classname == "item_sphere")
{
self.mdl = self.model;
self.nextthink = time + 60*3;
self.think = SUB_regen;
}
else
{
self.mdl = self.model;
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.items = other.items | self.items;
other.items2 = other.items2 | self.items2;
self.model = string_null;
// do the apropriate action
if (self.netname == "Power Shield")
{
other.shield_time = 1;
other.shield_finished = time + 30;
}
else if (self.netname == "Anti-Grav Belt")
{
other.antigrav_time = 1;
other.antigrav_finished = time + 45;
other.gravity = 0.25;
}
else if (self.classname == "item_sphere")
{
other.items2 = other.items2 | IT2_V_SPHERE;
sphere_spawn();
}
activator = other;
SUB_UseTargets(); // fire all targets / killtargets
};
/*QUAKED item_powerup_shield (0 .5 .8) (-16 -16 -24) (16 16 32)
The shield upgrade
*/
void() item_powerup_shield =
{
self.touch = newitems_touch;
precache_model ("progs/shield.mdl");
precache_model ("progs/p_shield.mdl");
precache_sound ("shield/pickup.wav");
precache_sound ("shield/hit.wav");
precache_sound ("shield/fadeout.wav");
self.noise = "shield/pickup.wav";
setmodel (self, "progs/shield.mdl");
self.netname = "Power Shield";
self.items2 = IT2_SHIELD;
setsize (self, '-16 -16 -24', '16 16 32');
StartItem ();
};
/*QUAKED item_powerup_belt (0 .5 .8) (-16 -16 -24) (16 16 32)
The anti-grav belt
*/
void() item_powerup_belt =
{
self.touch = newitems_touch;
precache_model ("progs/beltup.mdl");
precache_sound ("belt/pickup.wav");
precache_sound ("belt/use.wav");
precache_sound ("belt/fadeout.wav");
self.noise = "belt/pickup.wav";
setmodel (self, "progs/beltup.mdl");
self.netname = "Anti-Grav Belt";
self.items2 = IT2_ANTIGRAV;
setsize (self, '-16 -16 -24', '16 16 32');
StartItem ();
};

144
NEWMISC.QC Normal file
View File

@ -0,0 +1,144 @@
// Miscellaneous items used in the Rogue XPACK
/*QUAKED light_lantern (0 .5 0) (-10 -10 -20) (10 10 20)
Light-emitting lantern.
Default light value is 200
Default style is 0
*/
void() light_lantern =
{
precache_model ("progs/lantern.mdl");
setmodel (self, "progs/lantern.mdl");
makestatic (self);
};
/*QUAKED light_candle (0 .5 0) (-4 -4 -10) (4 4 10)
Candle
Default light value is 200
Default style is 0
*/
void() light_candle =
{
precache_model ("progs/candle.mdl");
setmodel (self, "progs/candle.mdl");
makestatic (self);
};
// ==========================================
// rubble generator
// ==========================================
void() rubble_touch =
{
if ( other.classname == "player" || other.flags & FL_MONSTER )
{
if ( vlen ( self.velocity ) > 0)
{
T_Damage ( other, self, self, 10 );
}
}
};
void() rubble_throw =
{
local vector throw;
local entity rubble;
rubble = find ( world, targetname, self.target );
throw = normalize ( rubble.origin - self.origin );
throw_x = throw_x + (random() * 0.2) - 0.1;
throw_y = throw_y + (random() * 0.2) - 0.1;
throw_z = throw_z + (random() * 0.2) - 0.1;
rubble = spawn ();
rubble.owner = self;
rubble.classname = "rubble";
rubble.movetype = MOVETYPE_BOUNCE;
rubble.solid = SOLID_BBOX;
rubble.velocity = throw * 300;
setmodel ( rubble, "progs/rubble.mdl");
setsize ( rubble, '-16 -16 -16', '16 16 16');
setorigin ( rubble, self.origin );
rubble.touch = rubble_touch;
rubble.think = SUB_Remove;
rubble.nextthink = time + 30;
if (self.spawnflags & 1)
rubble.skin = 1;
else
rubble.skin = 0;
self.think = rubble_throw;
self.nextthink = time + self.delay;
};
void() rubble_use =
{
if (self.wait == 0)
{
self.think = rubble_throw;
self.nextthink = time + self.delay;
self.wait = 1;
}
else
{
self.nextthink = time - 1;
self.wait = 0;
}
};
/*QUAKED rubble_generator (1 1 0) (-8 -8 -8) (8 8 8) LavaRock Active
Rubble Generator - cave colored rock chunks flung at the target. Triggering the generator will turn it off and on.
LavaRock - a lava rock texture, based on rich's pumice
Active - start the generator immediately.
delay - time between rubble pieces (Default 5 sec)
*/
void() rubble_generator =
{
precache_model ("progs/rubble.mdl");
if (!self.target)
objerror ("rubble_generator has no target!");
if (!self.delay)
self.delay = 5;
self.solid = SOLID_NOT;
self.use = rubble_use;
if (self.spawnflags & 2)
rubble_use();
};
void() trigEx_die =
{
SUB_UseTargets();
self.touch = SUB_Null;
self.nextthink = time + 0.1;
self.think = SUB_Remove;
};
/*QUAKED trigger_explosion (.5 .5 .5) ?
Variable sized repeatable trigger. Must be targeted at one or more entities. Only set off when killed, and is only damaged by T_RadiusDamage.
health: amount of damage needed to set off trigger.
*/
void() trigger_explosion =
{
InitTrigger ();
if (!self.health)
self.health = 20;
self.max_health = self.health;
self.th_die = trigEx_die;
self.takedamage = DAMAGE_YES;
self.solid = SOLID_BBOX;
setorigin (self, self.origin); // make sure it links into the world
};

602
NEWPLATS.QC Normal file
View File

@ -0,0 +1,602 @@
// newplats.qc
// pmack
// september 1996
// TYPES
float DN_N_WAIT = 1;
float PLT_TOGGLE = 2;
float ELEVATOR = 4;
float START_AT_TOP = 8;
float PLAT2 = 16;
float PLAT2_BOTTOM = 32;
float ELV_BUTN_DIR = 0;
// ==================================
// down N and wait code
// ==================================
void() dn_and_wait_go_up;
void() dn_and_wait_go_down;
void() dn_and_wait_crush;
void() dn_and_wait_hit_top =
{
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_TOP;
};
void() dn_and_wait_hit_bottom =
{
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_BOTTOM;
self.think = dn_and_wait_go_up;
self.nextthink = self.ltime + self.health;
};
void() dn_and_wait_go_down =
{
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
self.state = STATE_DOWN;
SUB_CalcMove (self.pos2, self.speed, dn_and_wait_hit_bottom);
};
void() dn_and_wait_go_up =
{
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
self.state = STATE_UP;
SUB_CalcMove (self.pos1, self.speed, dn_and_wait_hit_top);
};
void() dn_and_wait_crush =
{
T_Damage (other, self, self, 1);
if (self.state == STATE_UP)
dn_and_wait_go_down ();
else if (self.state == STATE_DOWN)
dn_and_wait_go_up ();
else
objerror ("plat_new_crush: bad self.state\n");
};
void() dn_and_wait_use =
{
if (self.state != STATE_TOP)
return;
dn_and_wait_go_down ();
};
// ==================================
// toggle type code
// ==================================
void() toggle_go_up;
void() toggle_go_down;
void() toggle_crush;
void() toggle_hit_top =
{
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_TOP;
};
void() toggle_hit_bottom =
{
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_BOTTOM;
};
void() toggle_go_down =
{
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
self.state = STATE_DOWN;
SUB_CalcMove (self.pos2, self.speed, toggle_hit_bottom);
};
void() toggle_go_up =
{
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
self.state = STATE_UP;
SUB_CalcMove (self.pos1, self.speed, toggle_hit_top);
};
void() toggle_crush =
{
T_Damage (other, self, self, 1);
if (self.state == STATE_UP)
toggle_go_down ();
else if (self.state == STATE_DOWN)
toggle_go_up ();
else
objerror ("plat_new_crush: bad self.state\n");
};
void() toggle_use =
{
if (self.state == STATE_TOP)
toggle_go_down ();
else if(self.state == STATE_BOTTOM)
toggle_go_up ();
};
// ==================================
// elvtr type code
// ==================================
void() elvtr_crush;
void() elvtr_stop =
{
self.elevatorOnFloor = self.elevatorToFloor;
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_BOTTOM;
self.elevatorLastUse = time;
};
void() elvtr_go =
{
self.elevatorDestination = self.pos2;
self.elevatorDestination_z = self.pos2_z +
(self.height * self.elevatorToFloor);
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
self.state = STATE_UP;
SUB_CalcMove (self.elevatorDestination, self.speed, elvtr_stop);
self.elevatorLastUse = time;
};
void() elvtr_crush =
{
// T_Damage (other, self, self, 1);
self.elevatorToFloor = self.elevatorOnFloor;
elvtr_go ();
};
// ===============
// elevator use function
// self = plat, other = elevator button, other.enemy = player
// ===============
void() elvtr_use =
{
local float tempDist, elvPos, btnPos;
if ( (self.elevatorLastUse + 2) > time)
return;
self.elevatorLastUse = time;
if (ELV_BUTN_DIR == 0)
return;
elvPos = (self.absmin_z + self.absmax_z) * 0.5;
btnPos = (other.absmin_z + other.absmax_z) * 0.5;
if (elvPos > btnPos)
{
tempDist = (elvPos - btnPos) / self.height;
tempDist = ceil ( tempDist);
self.elevatorToFloor = self.elevatorOnFloor - tempDist;
elvtr_go ();
return;
}
else
{
tempDist = btnPos - elvPos;
if (tempDist > self.height)
{
tempDist = tempDist / self.height;
tempDist = floor ( tempDist );
self.elevatorToFloor = self.elevatorOnFloor + tempDist;
elvtr_go ();
return;
}
}
if (ELV_BUTN_DIR == -1)
{
if(self.elevatorOnFloor > 0)
{
self.elevatorToFloor = self.elevatorOnFloor - 1;
elvtr_go ();
}
}
else if(ELV_BUTN_DIR == 1)
{
if(self.elevatorOnFloor < (self.cnt - 1))
{
self.elevatorToFloor = self.elevatorOnFloor + 1;
elvtr_go ();
}
}
};
// ==================================
// PLAT2 type code
// ==================================
void() plat2_center_touch;
void() plat2_go_up;
void() plat2_go_down;
void() plat2_crush;
void() plat2_spawn_inside_trigger =
{
local entity trigger;
local vector tmin, tmax;
//
// middle trigger
//
trigger = spawn();
trigger.touch = plat2_center_touch;
trigger.movetype = MOVETYPE_NONE;
trigger.solid = SOLID_TRIGGER;
trigger.enemy = self;
tmin = self.mins + '25 25 0';
tmax = self.maxs - '25 25 -8';
tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8);
if (self.spawnflags & PLAT_LOW_TRIGGER)
tmax_z = tmin_z + 8;
if (self.size_x <= 50)
{
tmin_x = (self.mins_x + self.maxs_x) / 2;
tmax_x = tmin_x + 1;
}
if (self.size_y <= 50)
{
tmin_y = (self.mins_y + self.maxs_y) / 2;
tmax_y = tmin_y + 1;
}
setsize (trigger, tmin, tmax);
};
void() plat2_hit_top =
{
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_TOP;
self.plat2LastMove = time;
if(self.plat2Called == 1)
{
self.think = plat2_go_down;
self.nextthink = self.ltime + 1.5;
self.plat2Called = 0;
self.plat2LastMove = 0; // allow immediate move
}
else if(!(self.spawnflags & START_AT_TOP))
{
self.think = plat2_go_down;
self.nextthink = self.ltime + self.delay;
self.plat2Called = 0;
}
};
void() plat2_hit_bottom =
{
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_BOTTOM;
self.plat2LastMove = time;
if(self.plat2Called == 1)
{
self.think = plat2_go_up;
self.nextthink = self.ltime + 1.5;
self.plat2Called = 0;
self.plat2LastMove = 0; // allow immediate move
}
else if(self.spawnflags & START_AT_TOP)
{
self.think = plat2_go_up;
self.nextthink = self.ltime + self.delay;
self.plat2Called = 0;
}
};
void() plat2_go_down =
{
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
self.state = STATE_DOWN;
SUB_CalcMove (self.pos2, self.speed, plat2_hit_bottom);
};
void() plat2_go_up =
{
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
self.state = STATE_UP;
SUB_CalcMove (self.pos1, self.speed, plat2_hit_top);
};
void() plat2_use =
{
if(self.state > 4)
self.state = self.state - 10;
self.use = SUB_Null;
};
void() plat2_center_touch =
{
local float otherState;
local vector platPosition;
if (other.classname != "player")
return;
if (other.health <= 0)
return;
// at this point, self is the trigger. self.enemy is the plat.
// this changes self to be the plat, other is the player.
self = self.enemy;
if ((self.plat2LastMove + 2) > time)
return;
if (self.state > 4) // disabled.
return;
if (self.plat2GoTo > STATE_BOTTOM)
{
if (self.plat2GoTime < time)
{
if (self.plat2GoTo == STATE_UP)
plat2_go_up();
else
plat2_go_down();
self.plat2GoTo = 0;
}
return;
}
if (self.state > STATE_BOTTOM) // STATE_UP or STATE_DOWN
return;
platPosition = (self.absmax + self.absmin) * 0.5;
if (self.state == STATE_TOP)
{
otherState = STATE_TOP;
if ( platPosition_z > other.origin_z )
otherState = STATE_BOTTOM;
}
else
{
otherState = STATE_BOTTOM;
if ( (other.origin_z - platPosition_z) > self.height)
otherState = STATE_TOP;
}
if (self.state == otherState)
{
self.plat2Called = 0;
self.plat2GoTime = time + 0.5;
}
else
{
self.plat2GoTime = time + 0.1;
self.plat2Called = 1;
}
if (self.state == STATE_BOTTOM)
self.plat2GoTo = STATE_UP;
else if(self.state == STATE_TOP)
self.plat2GoTo = STATE_DOWN;
};
void() plat2_crush =
{
T_Damage (other, self, self, 1);
if (self.state == STATE_UP)
plat2_go_down ();
else if (self.state == STATE_DOWN)
plat2_go_up ();
else
objerror ("plat2_crush: bad self.state\n");
};
// ==================================
// Common Plat Code
// ==================================
/*QUAKED func_new_plat (0 .5 .8) ? DN_N_WAIT PLT_TOGGLE ELEVATOR START_AT_TOP PLAT2 P2_BOTTOM
--------------
DN_N_WAIT is a plat that starts at the top and when triggered, goes down, waits, then comes back up.
health - number of seconds to wait (default 5)
--------------
PLT_TOGGLE is a plat that will change between the top and bottom each time it is triggered.
--------------
ELEVATOR is an elevator plat. You can have as many levels as you want but they must be all the same distance away. Use elevator button entity as the trigger.
cnt is the number of floors
height is the distance between floors
START_AT_TOP is an optional flag for elevators. It just tells the elevator that it's position is the top floor. (Default is the bottom floor) USE THIS ONLY WITH ELEVATORS!
--------------
PLAT2 is a fixed version of the original plat. If you want the plat to start at the bottom and move to the top on demand, use a negative height. That will tell Quake to lower the plat at spawn time. Always place this plat type in the top position when making the map. This will ensure correct lighting, hopefully. If a plat2 is the target of a trigger, it will be disabled until it has been triggered. Delay is the wait before the plat returns to original position.
If you don't want to bother figuring out the height, don't put a
value in the height
delay default 3
speed default 150
cnt default 2
P2_BOTTOM is an optional switch to have an auto-sized plat2 start at the bottom.
--------------
Plats are always drawn in the extended position, so they will light correctly.
If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat.
If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height.
Set "sounds" to one of the following:
1) base fast
2) chain slow
*/
void() func_new_plat =
{
//local entity t;
local float negativeHeight;
negativeHeight = 0;
if (!self.t_length)
self.t_length = 80;
if (!self.t_width)
self.t_width = 10;
if (self.sounds == 0)
self.sounds = 2;
// FIX THIS TO LOAD A GENERIC PLAT SOUND
if (self.sounds == 1)
{
precache_sound ("plats/plat1.wav");
precache_sound ("plats/plat2.wav");
self.noise = "plats/plat1.wav";
self.noise1 = "plats/plat2.wav";
}
if (self.sounds == 2)
{
precache_sound ("plats/medplat1.wav");
precache_sound ("plats/medplat2.wav");
self.noise = "plats/medplat1.wav";
self.noise1 = "plats/medplat2.wav";
}
self.mangle = self.angles;
self.angles = '0 0 0';
self.classname = "plat";
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_PUSH;
setorigin (self, self.origin);
setmodel (self, self.model);
setsize (self, self.mins , self.maxs);
if (!self.speed)
self.speed = 150;
// pos1 is the top position, pos2 is the bottom
self.pos1 = self.origin;
self.pos2 = self.origin;
if (self.height < 0)
{
negativeHeight = 1;
self.height = 0 - self.height;
}
if (self.height)
self.pos2_z = self.origin_z - self.height;
else
{
negativeHeight = 1;
self.height = self.size_z - 8;
self.pos2_z = self.origin_z - self.height;
}
if (self.spawnflags & DN_N_WAIT)
{
self.use = dn_and_wait_use;
self.blocked = dn_and_wait_crush;
if (negativeHeight == 1)
{
self.state = STATE_BOTTOM;
setorigin (self, self.pos2);
}
else
self.state = STATE_TOP;
if (!self.health)
self.health = 5;
}
else if (self.spawnflags & PLT_TOGGLE)
{
self.use = toggle_use;
self.blocked = toggle_crush;
if (negativeHeight == 1)
{
setorigin (self, self.pos2);
self.state = STATE_BOTTOM;
}
else
{
self.state = STATE_TOP;
}
}
else if (self.spawnflags & ELEVATOR)
{
self.elevatorOnFloor = 0;
self.elevatorToFloor = 0;
self.elevatorLastUse = 0;
if (self.spawnflags & START_AT_TOP)
{
self.pos1 = self.origin;
self.pos2 = self.origin;
self.pos2_z = self.origin_z - (self.height * (self.cnt - 1));
self.elevatorOnFloor = self.cnt - 1;
}
else
{
self.pos1 = self.origin;
self.pos2 = self.origin;
self.pos1_z = self.origin_z + (self.height * (self.cnt - 1));
self.elevatorOnFloor = 0;
}
self.use = elvtr_use;
self.blocked = elvtr_crush;
}
else if (self.spawnflags & PLAT2)
{
plat2_spawn_inside_trigger (); // the "start moving" trigger
self.plat2Called = 0;
self.plat2LastMove = 0;
self.plat2GoTo = 0;
self.plat2GoTime = 0;
self.blocked = plat2_crush;
if (!self.delay)
self.delay = 3;
if (negativeHeight == 1)
{
self.state = STATE_BOTTOM;
// make sure START_AT_TOP isn't set. We need that...
self.spawnflags = PLAT2;
setorigin (self, self.pos2);
}
else
{
// default position is top.
self.spawnflags = self.spawnflags | START_AT_TOP;
self.state = STATE_TOP;
}
if (self.targetname)
{
self.use = plat2_use;
self.state = self.state + 10;
}
}
};

151
NEW_AI.QC Normal file
View File

@ -0,0 +1,151 @@
// new ai functions
//
// pmack
// ================================================================
// ai_orbit - used to have an object orbit an entity.
//
// destEnt: the entity to orbit
// radius: how large a radius to orbit at (0 will just track)
// offset: center of the orbit. this is added to dest.origin.
//
// Uses self.orbitPosition to determine current destination.
// ================================================================
void(entity destEnt, float radius, vector offset) ai_orbit =
{
local vector dir;
local float dist;
if (self.orbitPosition > 3)
self.orbitPosition = 0;
else if (self.orbitPosition < 0)
self.orbitPosition = 0;
traceline ( self.origin, destEnt.origin + offset, TRUE, world);
if ( trace_fraction < 1 )
{
setorigin (self, destEnt.origin + offset);
self.orbitPosition = self.orbitPosition + 1;
return;
}
if ( self.orbitPosition == 0)
{
dir = (destEnt.origin + offset) - self.origin;
dir_x = dir_x + radius;
}
else if ( self.orbitPosition == 1)
{
dir = (destEnt.origin + offset) - self.origin;
dir_y = dir_y + radius;
}
else if ( self.orbitPosition == 2)
{
dir = (destEnt.origin + offset) - self.origin;
dir_x = dir_x - radius;
}
else
{
dir = (destEnt.origin + offset) - self.origin;
dir_y = dir_y - radius;
}
dist = vlen(dir);
if( dist < 8 )
{
self.orbitPosition = self.orbitPosition + 1;
}
else if( dist < 50 )
{
self.velocity = normalize(dir);
self.velocity = self.velocity * 150;
}
else
{
self.velocity = normalize(dir);
self.velocity = self.velocity * 500;
}
};
// ================================================================
// ai_track - used to have an object chase/track an enemy. the object
// flies directly at the destEnt's view_ofs point.
//
// destEnt: the entity to orbit
// trackSpeed: the velocity multiplier (speed) of the object
// ================================================================
void(entity destEnt, float trackSpeed) ai_track =
{
local vector dir;
dir = destEnt.origin + destEnt.view_ofs;
dir = normalize(dir - self.origin);
self.velocity = dir * trackSpeed;
};
// ================================================================
// ViolentDeath
// ================================================================
void(string gibname, float dm) AccelerateGib =
{
local entity new;
local float offset1;
new = spawn();
new.origin = self.origin;
setmodel (new, gibname);
setsize (new, '-8 -8 -8', '8 8 8');
new.velocity = -1.25 * self.velocity;
makevectors ( new.velocity );
offset1 = random() * 300 - 150;
new.velocity = new.velocity + v_right * offset1;
offset1 = random() * 300 - 150;
new.velocity = new.velocity + v_up * offset1;
new.movetype = MOVETYPE_BOUNCE;
new.solid = SOLID_NOT;
new.avelocity_x = random()*600;
new.avelocity_y = random()*600;
new.avelocity_z = random()*600;
new.think = SUB_Remove;
new.ltime = time;
new.nextthink = time + 10 + random()*10;
new.frame = 0;
new.flags = 0;
};
void(float gibCount) ViolentDeath =
{
while(gibCount > 0)
{
AccelerateGib ("progs/gib1.mdl", (-4 * gibCount));
AccelerateGib ("progs/gib2.mdl", (-6 * gibCount));
AccelerateGib ("progs/gib3.mdl", (-8 * gibCount));
gibCount = gibCount - 3;
}
};
entity(string gibname) StartGib =
{
local entity new;
new = spawn();
new.origin = self.origin;
setmodel (new, gibname);
setsize (new, '0 0 0', '0 0 0');
new.movetype = MOVETYPE_BOUNCE;
new.solid = SOLID_NOT;
new.think = SUB_Remove;
new.ltime = time;
new.nextthink = time + 10 + random()*10;
new.frame = 0;
new.flags = 0;
return new;
};

499
OGRE.QC Normal file
View File

@ -0,0 +1,499 @@
/*
==============================================================================
OGRE
==============================================================================
*/
$cd id1/models/ogre_c
$origin 0 0 24
$base base
$skin base
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7
$frame walk8 walk9 walk10 walk11 walk12 walk13 walk14 walk15 walk16
$frame run1 run2 run3 run4 run5 run6 run7 run8
$frame swing1 swing2 swing3 swing4 swing5 swing6 swing7
$frame swing8 swing9 swing10 swing11 swing12 swing13 swing14
$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7
$frame smash8 smash9 smash10 smash11 smash12 smash13 smash14
$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6
$frame pain1 pain2 pain3 pain4 pain5
$frame painb1 painb2 painb3
$frame painc1 painc2 painc3 painc4 painc5 painc6
$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10
$frame paind11 paind12 paind13 paind14 paind15 paind16
$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10
$frame paine11 paine12 paine13 paine14 paine15
$frame death1 death2 death3 death4 death5 death6
$frame death7 death8 death9 death10 death11 death12
$frame death13 death14
$frame bdeath1 bdeath2 bdeath3 bdeath4 bdeath5 bdeath6
$frame bdeath7 bdeath8 bdeath9 bdeath10
$frame pull1 pull2 pull3 pull4 pull5 pull6 pull7 pull8 pull9 pull10 pull11
//=============================================================================
float OGRE_BOSS = 2;
float OGRE_NORMAL = 4;
void() OgreGrenadeExplode =
{
T_RadiusDamage (self, self.owner, 40, world);
sound (self, CHAN_VOICE, "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);
self.velocity = '0 0 0';
self.touch = SUB_Null;
setmodel (self, "progs/s_explod.spr");
self.solid = SOLID_NOT;
s_explode1 ();
};
void() OgreGrenadeTouch =
{
if (other == self.owner)
return; // don't explode on owner
if (other.takedamage == DAMAGE_AIM)
{
OgreGrenadeExplode();
return;
}
sound (self, CHAN_VOICE, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
if (self.velocity == '0 0 0')
self.avelocity = '0 0 0';
};
/*
================
OgreFireGrenade
================
*/
void() MultiGrenadeTouch;
void() MultiGrenadeExplode;
void() OgreFireGrenade =
{
local entity missile, mpuff;
self.effects = self.effects | EF_MUZZLEFLASH;
sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_BOUNCE;
missile.solid = SOLID_BBOX;
missile.classname = "ogre_grenade";
// set missile speed
makevectors (self.angles);
missile.velocity = normalize(self.enemy.origin - self.origin);
missile.velocity = missile.velocity * 600;
missile.velocity_z = 200;
missile.avelocity = '300 300 300';
missile.angles = vectoangles(missile.velocity);
// set missile duration
if(self.spawnflags & OGRE_BOSS)
{
missile.touch = MultiGrenadeTouch;
missile.nextthink = time + 2.5;
missile.think = MultiGrenadeExplode;
setmodel (missile, "progs/mervup.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin);
missile.classname = "MultiGrenade";
}
else
{
missile.touch = OgreGrenadeTouch;
missile.nextthink = time + 2.5;
missile.think = OgreGrenadeExplode;
setmodel (missile, "progs/grenade.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin);
}
};
//=============================================================================
/*
================
chainsaw
FIXME
================
*/
void(float side) chainsaw =
{
local vector delta;
local float ldmg;
if (!self.enemy)
return;
if (!CanDamage (self.enemy, self))
return;
ai_charge(10);
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 100)
return;
ldmg = (random() + random() + random()) * 4;
T_Damage (self.enemy, self, self, ldmg);
if (side)
{
makevectors (self.angles);
if (side == 1)
SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
else
SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
}
};
void() ogre_stand1 =[ $stand1, ogre_stand2 ] {ai_stand();};
void() ogre_stand2 =[ $stand2, ogre_stand3 ] {ai_stand();};
void() ogre_stand3 =[ $stand3, ogre_stand4 ] {ai_stand();};
void() ogre_stand4 =[ $stand4, ogre_stand5 ] {ai_stand();};
void() ogre_stand5 =[ $stand5, ogre_stand6 ] {
if (random() < 0.2)
sound (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
ai_stand();
};
void() ogre_stand6 =[ $stand6, ogre_stand7 ] {ai_stand();};
void() ogre_stand7 =[ $stand7, ogre_stand8 ] {ai_stand();};
void() ogre_stand8 =[ $stand8, ogre_stand9 ] {ai_stand();};
void() ogre_stand9 =[ $stand9, ogre_stand1 ] {ai_stand();};
void() ogre_walk1 =[ $walk1, ogre_walk2 ] {ai_walk(3);};
void() ogre_walk2 =[ $walk2, ogre_walk3 ] {ai_walk(2);};
void() ogre_walk3 =[ $walk3, ogre_walk4 ] {
ai_walk(2);
if (random() < 0.2)
sound (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
};
void() ogre_walk4 =[ $walk4, ogre_walk5 ] {ai_walk(2);};
void() ogre_walk5 =[ $walk5, ogre_walk6 ] {ai_walk(2);};
void() ogre_walk6 =[ $walk6, ogre_walk7 ] {
ai_walk(5);
if (random() < 0.1)
sound (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);
};
void() ogre_walk7 =[ $walk7, ogre_walk8 ] {ai_walk(3);};
void() ogre_walk8 =[ $walk8, ogre_walk9 ] {ai_walk(2);};
void() ogre_walk9 =[ $walk9, ogre_walk10 ] {ai_walk(3);};
void() ogre_walk10 =[ $walk10, ogre_walk11 ] {ai_walk(1);};
void() ogre_walk11 =[ $walk11, ogre_walk12 ] {ai_walk(2);};
void() ogre_walk12 =[ $walk12, ogre_walk13 ] {ai_walk(3);};
void() ogre_walk13 =[ $walk13, ogre_walk14 ] {ai_walk(3);};
void() ogre_walk14 =[ $walk14, ogre_walk15 ] {ai_walk(3);};
void() ogre_walk15 =[ $walk15, ogre_walk16 ] {ai_walk(3);};
void() ogre_walk16 =[ $walk16, ogre_walk1 ] {ai_walk(4);};
void() ogre_run1 =[ $run1, ogre_run2 ] {ai_run(9);
if (random() < 0.2)
sound (self, CHAN_VOICE, "ogre/ogidle2.wav", 1, ATTN_IDLE);
};
void() ogre_run2 =[ $run2, ogre_run3 ] {ai_run(12);};
void() ogre_run3 =[ $run3, ogre_run4 ] {ai_run(8);};
void() ogre_run4 =[ $run4, ogre_run5 ] {ai_run(22);};
void() ogre_run5 =[ $run5, ogre_run6 ] {ai_run(16);};
void() ogre_run6 =[ $run6, ogre_run7 ] {ai_run(4);};
void() ogre_run7 =[ $run7, ogre_run8 ] {ai_run(13);};
void() ogre_run8 =[ $run8, ogre_run1 ] {ai_run(24);};
void() ogre_swing1 =[ $swing1, ogre_swing2 ] {ai_charge(11);
sound (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM);
};
void() ogre_swing2 =[ $swing2, ogre_swing3 ] {ai_charge(1);};
void() ogre_swing3 =[ $swing3, ogre_swing4 ] {ai_charge(4);};
void() ogre_swing4 =[ $swing4, ogre_swing5 ] {ai_charge(13);};
void() ogre_swing5 =[ $swing5, ogre_swing6 ] {ai_charge(9); chainsaw(0);self.angles_y = self.angles_y + random()*25;};
void() ogre_swing6 =[ $swing6, ogre_swing7 ] {chainsaw(200);self.angles_y = self.angles_y + random()* 25;};
void() ogre_swing7 =[ $swing7, ogre_swing8 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
void() ogre_swing8 =[ $swing8, ogre_swing9 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
void() ogre_swing9 =[ $swing9, ogre_swing10 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
void() ogre_swing10 =[ $swing10, ogre_swing11 ] {chainsaw(-200);self.angles_y = self.angles_y + random()* 25;};
void() ogre_swing11 =[ $swing11, ogre_swing12 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
void() ogre_swing12 =[ $swing12, ogre_swing13 ] {ai_charge(3);};
void() ogre_swing13 =[ $swing13, ogre_swing14 ] {ai_charge(8);};
void() ogre_swing14 =[ $swing14, ogre_run1 ] {ai_charge(9);};
void() ogre_smash1 =[ $smash1, ogre_smash2 ] {ai_charge(6);
sound (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM);
};
void() ogre_smash2 =[ $smash2, ogre_smash3 ] {ai_charge(0);};
void() ogre_smash3 =[ $smash3, ogre_smash4 ] {ai_charge(0);};
void() ogre_smash4 =[ $smash4, ogre_smash5 ] {ai_charge(1);};
void() ogre_smash5 =[ $smash5, ogre_smash6 ] {ai_charge(4);};
void() ogre_smash6 =[ $smash6, ogre_smash7 ] {ai_charge(4); chainsaw(0);};
void() ogre_smash7 =[ $smash7, ogre_smash8 ] {ai_charge(4); chainsaw(0);};
void() ogre_smash8 =[ $smash8, ogre_smash9 ] {ai_charge(10); chainsaw(0);};
void() ogre_smash9 =[ $smash9, ogre_smash10 ] {ai_charge(13); chainsaw(0);};
void() ogre_smash10 =[ $smash10, ogre_smash11 ] {chainsaw(1);};
void() ogre_smash11 =[ $smash11, ogre_smash12 ] {ai_charge(2); chainsaw(0);
self.nextthink = self.nextthink + random()*0.2;}; // slight variation
void() ogre_smash12 =[ $smash12, ogre_smash13 ] {ai_charge();};
void() ogre_smash13 =[ $smash13, ogre_smash14 ] {ai_charge(4);};
void() ogre_smash14 =[ $smash14, ogre_run1 ] {ai_charge(12);};
void() ogre_nail1 =[ $shoot1, ogre_nail2 ] {ai_face();};
void() ogre_nail2 =[ $shoot2, ogre_nail3 ] {ai_face();};
void() ogre_nail3 =[ $shoot2, ogre_nail4 ] {ai_face();};
void() ogre_nail4 =[ $shoot3, ogre_nail5 ] {ai_face();OgreFireGrenade();};
void() ogre_nail5 =[ $shoot4, ogre_nail6 ] {ai_face();};
void() ogre_nail6 =[ $shoot5, ogre_nail7 ] {ai_face();};
void() ogre_nail7 =[ $shoot6, ogre_run1 ] {ai_face();};
void() ogre_pain1 =[ $pain1, ogre_pain2 ] {};
void() ogre_pain2 =[ $pain2, ogre_pain3 ] {};
void() ogre_pain3 =[ $pain3, ogre_pain4 ] {};
void() ogre_pain4 =[ $pain4, ogre_pain5 ] {};
void() ogre_pain5 =[ $pain5, ogre_run1 ] {};
void() ogre_painb1 =[ $painb1, ogre_painb2 ] {};
void() ogre_painb2 =[ $painb2, ogre_painb3 ] {};
void() ogre_painb3 =[ $painb3, ogre_run1 ] {};
void() ogre_painc1 =[ $painc1, ogre_painc2 ] {};
void() ogre_painc2 =[ $painc2, ogre_painc3 ] {};
void() ogre_painc3 =[ $painc3, ogre_painc4 ] {};
void() ogre_painc4 =[ $painc4, ogre_painc5 ] {};
void() ogre_painc5 =[ $painc5, ogre_painc6 ] {};
void() ogre_painc6 =[ $painc6, ogre_run1 ] {};
void() ogre_paind1 =[ $paind1, ogre_paind2 ] {};
void() ogre_paind2 =[ $paind2, ogre_paind3 ] {ai_pain(10);};
void() ogre_paind3 =[ $paind3, ogre_paind4 ] {ai_pain(9);};
void() ogre_paind4 =[ $paind4, ogre_paind5 ] {ai_pain(4);};
void() ogre_paind5 =[ $paind5, ogre_paind6 ] {};
void() ogre_paind6 =[ $paind6, ogre_paind7 ] {};
void() ogre_paind7 =[ $paind7, ogre_paind8 ] {};
void() ogre_paind8 =[ $paind8, ogre_paind9 ] {};
void() ogre_paind9 =[ $paind9, ogre_paind10 ] {};
void() ogre_paind10=[ $paind10, ogre_paind11 ] {};
void() ogre_paind11=[ $paind11, ogre_paind12 ] {};
void() ogre_paind12=[ $paind12, ogre_paind13 ] {};
void() ogre_paind13=[ $paind13, ogre_paind14 ] {};
void() ogre_paind14=[ $paind14, ogre_paind15 ] {};
void() ogre_paind15=[ $paind15, ogre_paind16 ] {};
void() ogre_paind16=[ $paind16, ogre_run1 ] {};
void() ogre_paine1 =[ $paine1, ogre_paine2 ] {};
void() ogre_paine2 =[ $paine2, ogre_paine3 ] {ai_pain(10);};
void() ogre_paine3 =[ $paine3, ogre_paine4 ] {ai_pain(9);};
void() ogre_paine4 =[ $paine4, ogre_paine5 ] {ai_pain(4);};
void() ogre_paine5 =[ $paine5, ogre_paine6 ] {};
void() ogre_paine6 =[ $paine6, ogre_paine7 ] {};
void() ogre_paine7 =[ $paine7, ogre_paine8 ] {};
void() ogre_paine8 =[ $paine8, ogre_paine9 ] {};
void() ogre_paine9 =[ $paine9, ogre_paine10 ] {};
void() ogre_paine10=[ $paine10, ogre_paine11 ] {};
void() ogre_paine11=[ $paine11, ogre_paine12 ] {};
void() ogre_paine12=[ $paine12, ogre_paine13 ] {};
void() ogre_paine13=[ $paine13, ogre_paine14 ] {};
void() ogre_paine14=[ $paine14, ogre_paine15 ] {};
void() ogre_paine15=[ $paine15, ogre_run1 ] {};
void(entity attacker, float damage) ogre_pain =
{
local float r;
// don't make multiple pain sounds right after each other
if (self.pain_finished > time)
return;
sound (self, CHAN_VOICE, "ogre/ogpain1.wav", 1, ATTN_NORM);
r = random();
if (r < 0.25)
{
ogre_pain1 ();
self.pain_finished = time + 1;
}
else if (r < 0.5)
{
ogre_painb1 ();
self.pain_finished = time + 1;
}
else if (r < 0.75)
{
ogre_painc1 ();
self.pain_finished = time + 1;
}
else if (r < 0.88)
{
ogre_paind1 ();
self.pain_finished = time + 2;
}
else
{
ogre_paine1 ();
self.pain_finished = time + 2;
}
};
void() ogre_die1 =[ $death1, ogre_die2 ] {};
void() ogre_die2 =[ $death2, ogre_die3 ] {};
void() ogre_die3 =[ $death3, ogre_die4 ]
{
self.solid = SOLID_NOT;
if (self.spawnflags & OGRE_BOSS)
self.ammo_multi_rockets = 2;
else
self.ammo_rockets = 2;
DropBackpack();
};
void() ogre_die4 =[ $death4, ogre_die5 ] {};
void() ogre_die5 =[ $death5, ogre_die6 ] {};
void() ogre_die6 =[ $death6, ogre_die7 ] {};
void() ogre_die7 =[ $death7, ogre_die8 ] {};
void() ogre_die8 =[ $death8, ogre_die9 ] {};
void() ogre_die9 =[ $death9, ogre_die10 ] {};
void() ogre_die10 =[ $death10, ogre_die11 ] {};
void() ogre_die11 =[ $death11, ogre_die12 ] {};
void() ogre_die12 =[ $death12, ogre_die13 ] {};
void() ogre_die13 =[ $death13, ogre_die14 ] {};
void() ogre_die14 =[ $death14, ogre_die14 ] {};
void() ogre_bdie1 =[ $bdeath1, ogre_bdie2 ] {};
void() ogre_bdie2 =[ $bdeath2, ogre_bdie3 ] {ai_forward(5);};
void() ogre_bdie3 =[ $bdeath3, ogre_bdie4 ]
{
self.solid = SOLID_NOT;
if (self.spawnflags & OGRE_BOSS)
self.ammo_multi_rockets = 2;
else
self.ammo_rockets = 2;
DropBackpack();
};
void() ogre_bdie4 =[ $bdeath4, ogre_bdie5 ] {ai_forward(1);};
void() ogre_bdie5 =[ $bdeath5, ogre_bdie6 ] {ai_forward(3);};
void() ogre_bdie6 =[ $bdeath6, ogre_bdie7 ] {ai_forward(7);};
void() ogre_bdie7 =[ $bdeath7, ogre_bdie8 ] {ai_forward(25);};
void() ogre_bdie8 =[ $bdeath8, ogre_bdie9 ] {};
void() ogre_bdie9 =[ $bdeath9, ogre_bdie10 ] {};
void() ogre_bdie10 =[ $bdeath10, ogre_bdie10 ] {};
void() ogre_die =
{
// check for gib
if (self.health < -80)
{
sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
ThrowHead ("progs/h_ogre.mdl", self.health);
ThrowGib ("progs/gib3.mdl", self.health);
ThrowGib ("progs/gib3.mdl", self.health);
ThrowGib ("progs/gib3.mdl", self.health);
return;
}
sound (self, CHAN_VOICE, "ogre/ogdth.wav", 1, ATTN_NORM);
if (random() < 0.5)
ogre_die1 ();
else
ogre_bdie1 ();
};
void() ogre_melee =
{
if (random() > 0.5)
ogre_smash1 ();
else
ogre_swing1 ();
};
/*QUAKED monster_ogre (1 0 0) (-32 -32 -24) (32 32 64) Ambush Boss Normal
The Ogre
Boss: use the modified skin and fire multigrenades.
Normal: use the original skin and fire normal grenades.
*/
void() monster_ogre =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/ogre.mdl");
precache_model ("progs/h_ogre.mdl");
precache_model ("progs/grenade.mdl");
precache_sound ("ogre/ogdrag.wav");
precache_sound ("ogre/ogdth.wav");
precache_sound ("ogre/ogidle.wav");
precache_sound ("ogre/ogidle2.wav");
precache_sound ("ogre/ogpain1.wav");
precache_sound ("ogre/ogsawatk.wav");
precache_sound ("ogre/ogwake.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/ogre.mdl");
// none specified - choose random. 25% boss on normal, hard, bloodbath
if (self.spawnflags <= 1)
{
if (cvar("skill") > 0)
{
if ( random() <= 0.25 )
{
self.spawnflags = self.spawnflags | OGRE_BOSS;
}
}
}
if (self.spawnflags & OGRE_BOSS)
{
self.skin = 1;
}
setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
self.health = 200;
self.th_stand = ogre_stand1;
self.th_walk = ogre_walk1;
self.th_run = ogre_run1;
self.th_die = ogre_die;
self.th_melee = ogre_melee;
self.th_missile = ogre_nail1;
self.th_pain = ogre_pain;
walkmonster_start();
};

283
OLDONE.QC Normal file
View File

@ -0,0 +1,283 @@
/*
==============================================================================
OLD ONE
==============================================================================
*/
$cd /raid/quake/id1/models/old_one
$origin 0 0 24
$base base
$skin skin
$scale 1
void() finale_1;
void() finale_2;
void() finale_3;
void() finale_4;
entity shub;
$frame old1 old2 old3 old4 old5 old6 old7 old8 old9
$frame old10 old11 old12 old13 old14 old15 old16 old17 old18 old19
$frame old20 old21 old22 old23 old24 old25 old26 old27 old28 old29
$frame old30 old31 old32 old33 old34 old35 old36 old37 old38 old39
$frame old40 old41 old42 old43 old44 old45 old46
$frame shake1 shake2 shake3 shake4 shake5 shake6 shake7 shake8
$frame shake9 shake10 shake11 shake12 shake12 shake13 shake14
$frame shake15 shake16 shake17 shake18 shake19 shake20
//void() old_stand =[ $old1, old_stand ] {};
void() old_idle1 =[ $old1, old_idle2 ] {};
void() old_idle2 =[ $old2, old_idle3 ] {};
void() old_idle3 =[ $old3, old_idle4 ] {};
void() old_idle4 =[ $old4, old_idle5 ] {};
void() old_idle5 =[ $old5, old_idle6 ] {};
void() old_idle6 =[ $old6, old_idle7 ] {};
void() old_idle7 =[ $old7, old_idle8 ] {};
void() old_idle8 =[ $old8, old_idle9 ] {};
void() old_idle9 =[ $old9, old_idle10 ] {};
void() old_idle10 =[ $old10, old_idle11 ] {};
void() old_idle11 =[ $old11, old_idle12 ] {};
void() old_idle12 =[ $old12, old_idle13 ] {};
void() old_idle13 =[ $old13, old_idle14 ] {};
void() old_idle14 =[ $old14, old_idle15 ] {};
void() old_idle15 =[ $old15, old_idle16 ] {};
void() old_idle16 =[ $old16, old_idle17 ] {};
void() old_idle17 =[ $old17, old_idle18 ] {};
void() old_idle18 =[ $old18, old_idle19 ] {};
void() old_idle19 =[ $old19, old_idle20 ] {};
void() old_idle20 =[ $old20, old_idle21 ] {};
void() old_idle21 =[ $old21, old_idle22 ] {};
void() old_idle22 =[ $old22, old_idle23 ] {};
void() old_idle23 =[ $old23, old_idle24 ] {};
void() old_idle24 =[ $old24, old_idle25 ] {};
void() old_idle25 =[ $old25, old_idle26 ] {};
void() old_idle26 =[ $old26, old_idle27 ] {};
void() old_idle27 =[ $old27, old_idle28 ] {};
void() old_idle28 =[ $old28, old_idle29 ] {};
void() old_idle29 =[ $old29, old_idle30 ] {};
void() old_idle30 =[ $old30, old_idle31 ] {};
void() old_idle31 =[ $old31, old_idle32 ] {};
void() old_idle32 =[ $old32, old_idle33 ] {};
void() old_idle33 =[ $old33, old_idle34 ] {};
void() old_idle34 =[ $old34, old_idle35 ] {};
void() old_idle35 =[ $old35, old_idle36 ] {};
void() old_idle36 =[ $old36, old_idle37 ] {};
void() old_idle37 =[ $old37, old_idle38 ] {};
void() old_idle38 =[ $old38, old_idle39 ] {};
void() old_idle39 =[ $old39, old_idle40 ] {};
void() old_idle40 =[ $old40, old_idle41 ] {};
void() old_idle41 =[ $old41, old_idle42 ] {};
void() old_idle42 =[ $old42, old_idle43 ] {};
void() old_idle43 =[ $old43, old_idle44 ] {};
void() old_idle44 =[ $old44, old_idle45 ] {};
void() old_idle45 =[ $old45, old_idle46 ] {};
void() old_idle46 =[ $old46, old_idle1 ] {};
void() old_thrash1 =[ $shake1, old_thrash2 ] {lightstyle(0, "m");};
void() old_thrash2 =[ $shake2, old_thrash3 ] {lightstyle(0, "k");};
void() old_thrash3 =[ $shake3, old_thrash4 ] {lightstyle(0, "k");};
void() old_thrash4 =[ $shake4, old_thrash5 ] {lightstyle(0, "i");};
void() old_thrash5 =[ $shake5, old_thrash6 ] {lightstyle(0, "g");};
void() old_thrash6 =[ $shake6, old_thrash7 ] {lightstyle(0, "e");};
void() old_thrash7 =[ $shake7, old_thrash8 ] {lightstyle(0, "c");};
void() old_thrash8 =[ $shake8, old_thrash9 ] {lightstyle(0, "a");};
void() old_thrash9 =[ $shake9, old_thrash10 ] {lightstyle(0, "c");};
void() old_thrash10 =[ $shake10, old_thrash11 ] {lightstyle(0, "e");};
void() old_thrash11 =[ $shake11, old_thrash12 ] {lightstyle(0, "g");};
void() old_thrash12 =[ $shake12, old_thrash13 ] {lightstyle(0, "i");};
void() old_thrash13 =[ $shake13, old_thrash14 ] {lightstyle(0, "k");};
void() old_thrash14 =[ $shake14, old_thrash15 ] {lightstyle(0, "m");};
void() old_thrash15 =[ $shake15, old_thrash16 ] {lightstyle(0, "m");
self.cnt = self.cnt + 1;
if (self.cnt != 3)
self.think = old_thrash1;
};
void() old_thrash16 =[ $shake16, old_thrash17 ] {lightstyle(0, "g");};
void() old_thrash17 =[ $shake17, old_thrash18 ] {lightstyle(0, "c");};
void() old_thrash18 =[ $shake18, old_thrash19 ] {lightstyle(0, "b");};
void() old_thrash19 =[ $shake19, old_thrash20 ] {lightstyle(0, "a");};
void() old_thrash20 =[ $shake20, old_thrash20 ] {finale_4();};
//============================================================================
void() finale_1 =
{
local entity pos, pl;
local entity timer;
intermission_exittime = time + 10000000; // never allow exit
intermission_running = 1;
// find the intermission spot
pos = find (world, classname, "info_intermission");
if (!pos)
error ("no info_intermission");
pl = find (world, classname, "misc_teleporttrain");
if (!pl)
error ("no teleporttrain");
remove (pl);
WriteByte (MSG_ALL, SVC_FINALE);
WriteString (MSG_ALL, "");
pl = find (world, classname, "player");
while (pl != world)
{
pl.view_ofs = '0 0 0';
pl.angles = other.v_angle = pos.mangle;
pl.fixangle = TRUE; // turn this way immediately
pl.map = self.map;
pl.nextthink = time + 0.5;
pl.takedamage = DAMAGE_NO;
pl.solid = SOLID_NOT;
pl.movetype = MOVETYPE_NONE;
pl.modelindex = 0;
setorigin (pl, pos.origin);
pl = find (pl, classname, "player");
}
// make fake versions of all players as standins, and move the real
// players to the intermission spot
// wait for 1 second
timer = spawn();
timer.nextthink = time + 1;
timer.think = finale_2;
};
void() finale_2 =
{
local vector o;
// start a teleport splash inside shub
o = shub.origin - '0 100 0';
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_TELEPORT);
WriteCoord (MSG_BROADCAST, o_x);
WriteCoord (MSG_BROADCAST, o_y);
WriteCoord (MSG_BROADCAST, o_z);
sound (shub, CHAN_VOICE, "misc/r_tele1.wav", 1, ATTN_NORM);
self.nextthink = time + 2;
self.think = finale_3;
};
void() finale_3 =
{
// start shub thrashing wildly
shub.think = old_thrash1;
sound (shub, CHAN_VOICE, "boss2/death.wav", 1, ATTN_NORM);
lightstyle(0, "abcdefghijklmlkjihgfedcb");
};
void() finale_4 =
{
// throw tons of meat chunks
local vector oldo;
local float x, y, z;
local float r;
local entity n;
sound (self, CHAN_VOICE, "boss2/pop2.wav", 1, ATTN_NORM);
oldo = self.origin;
z = 16;
while (z <= 144)
{
x = -64;
while (x <= 64)
{
y = -64;
while (y <= 64)
{
self.origin_x = oldo_x + x;
self.origin_y = oldo_y + y;
self.origin_z = oldo_z + z;
r = random();
if (r < 0.3)
ThrowGib ("progs/gib1.mdl", -999);
else if (r < 0.6)
ThrowGib ("progs/gib2.mdl", -999);
else
ThrowGib ("progs/gib3.mdl", -999);
y = y + 32;
}
x = x + 32;
}
z = z + 96;
}
// start the end text
WriteByte (MSG_ALL, SVC_FINALE);
WriteString (MSG_ALL, "Congratulations and well done! You have\nbeaten the hideous Shub-Niggurath, and\nher hundreds of ugly changelings and\nmonsters. You have proven that your\nskill and your cunning are greater than\nall the powers of Quake. You are the\nmaster now. Id Software salutes you.");
// put a player model down
n = spawn();
setmodel (n, "progs/player.mdl");
oldo = oldo - '32 264 0';
setorigin (n, oldo);
n.angles = '0 290 0';
n.frame = 1;
remove (self);
// switch cd track
WriteByte (MSG_ALL, SVC_CDTRACK);
WriteByte (MSG_ALL, 3);
WriteByte (MSG_ALL, 3);
lightstyle(0, "m");
};
//============================================================================
void () nopain =
{
self.health = 40000;
};
//============================================================================
/*QUAKED monster_oldone (1 0 0) (-16 -16 -24) (16 16 32)
*/
void() monster_oldone =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model2 ("progs/oldone.mdl");
precache_sound2 ("boss2/death.wav");
precache_sound2 ("boss2/idle.wav");
precache_sound2 ("boss2/sight.wav");
precache_sound2 ("boss2/pop2.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/oldone.mdl");
setsize (self, '-160 -128 -24', '160 128 256');
self.health = 40000; // kill by telefrag
self.think = old_idle1;
self.nextthink = time + 0.1;
self.takedamage = DAMAGE_YES;
self.th_pain = nopain;
self.th_die = finale_1;
shub = self;
total_monsters = total_monsters + 1;
};

391
PENDULUM.QC Normal file
View File

@ -0,0 +1,391 @@
// pendulum.qc
$frame frame1 frame2 frame3 frame4 frame5 frame6 frame7
$frame frame8 frame9 frame10 frame11 frame12 frame13
float impactVelocity;
//float pend_frame;
float PEND_X = 1;
float PEND_Y = 2;
float PEND_Z = 4;
float PEND_TRG = 8;
/*
void() pend_stand =[ $frame4, pend_stand ] {};
*/
void() pend_swing1 =[ $frame1, pend_swing2 ]
{
//// pend_frame = 1;
// 0 -148 88 (center) W 56, H 80 (28,40)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 -176 48', '8 -120 128' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '-176 -8 48', '-120 8 128' );
self.nextthink = time + 0.17;
impactVelocity = 1;
};
void() pend_swing2 =[ $frame2, pend_swing3 ]
{
//// pend_frame = pend_frame + 1;
// 0 -142 50 (center) W 60, H 76 (30, 38)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 -172 12', '8 -112 88' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '-172 -8 12', '-112 8 88' );
self.nextthink = time + 0.15;
};
void() pend_swing3 =[ $frame3, pend_swing4 ]
{
//// pend_frame = pend_frame + 1;
// 0 -128 14 (center) W 64, H 72 (32, 36)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 -160 -22', '8 -96 50' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '-160 -8 -22', '-96 8 50' );
self.nextthink = time + 0.13;
};
void() pend_swing4 =[ $frame4, pend_swing5 ]
{
sound ( self, CHAN_AUTO, "pendulum/swing.wav", 0.5, ATTN_NORM);
//// pend_frame = pend_frame + 1;
// 0 -104 -17 (center) W 68, H 68 (34, 34)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 -138 -51', '8 -70 17' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '-138 -8 -51', '-70 8 17' );
self.nextthink = time + 0.11;
};
void() pend_swing5 =[ $frame5, pend_swing6 ]
{
// pend_frame = pend_frame + 1;
// 0 -74 40 (center) W 72, H 64 (36, 32)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 -110 -72', '8 -38 -8' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '-110 -8 -72', '-38 8 -8' );
self.nextthink = time + 0.09;
};
void() pend_swing6 =[ $frame6, pend_swing7 ]
{
// pend_frame = pend_frame + 1;
// 0 -38 53 (center) W 76, H 60 (38, 30)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 -76 -83', '8 0 -23' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '-76 -8 -83', '0 8 -23' );
self.nextthink = time + 0.07;
};
void() pend_swing7 =[ $frame7, pend_swing8 ]
{
// pend_frame = pend_frame + 1;
// 0 0 60 (center) W 80, H 56 (40, 28)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 -40 -88', '8 40 -32' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '-40 -8 -88', '40 8 -32' );
self.nextthink = time + 0.05;
};
void() pend_swing8 =[ $frame8, pend_swing9 ]
{
// pend_frame = pend_frame + 1;
// 0 38 53 (center) W 76, H 60 (38, 30)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 0 -83', '8 76 -23' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '0 -8 -83', '76 8 -23' );
self.nextthink = time + 0.07;
};
void() pend_swing9 =[ $frame9, pend_swing10 ]
{
// pend_frame = pend_frame + 1;
// 0 74 40 (center) W 72, H 64 (36, 32)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 38 -72', '8 100 -8' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '38 -8 -72', '100 8 -8' );
self.nextthink = time + 0.09;
};
void() pend_swing10 =[ $frame10, pend_swing11 ]
{
// pend_frame = pend_frame + 1;
// 0 104 17 (center) W 68, H 68 (34, 34)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 70 -51', '8 138 17' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '70 -8 -51', '138 8 17' );
self.nextthink = time + 0.11;
};
void() pend_swing11 =[ $frame11, pend_swing12 ]
{
// pend_frame = pend_frame + 1;
// 0 128 -14 (center) W 64, H 72 (32, 36)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 96 -22', '8 160 50' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '96 -8 -22', '160 8 50' );
self.nextthink = time + 0.13;
};
void() pend_swing12 =[ $frame12, pend_swing13 ]
{
// pend_frame = pend_frame + 1;
// 0 142 -50 (center) W 60, H 76 (30, 38)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 112 12', '8 172 88' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '112 -8 12', '172 8 88' );
self.nextthink = time + 0.15;
};
void() pend_swing13 =[ $frame13, pend_swing14 ]
{
// pend_frame = pend_frame + 1;
// 0 148 -88 (center) W 56, H 80 (28, 40)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 120 48', '8 176 128' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '120 -8 48', '176 8 128' );
self.nextthink = time + 0.17;
};
void() pend_swing14 =[ $frame13, pend_swing15 ]
{
// pend_frame = pend_frame + 1;
// same frame, same location. no change to bbox.
self.nextthink = time + 0.17;
};
void() pend_swing15 =[ $frame12, pend_swing16 ]
{
// pend_frame = pend_frame + 1;
// 0 142 -50 (center) W 60, H 76 (30, 38)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 112 12', '8 172 88' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '112 -8 12', '172 8 88' );
self.nextthink = time + 0.15;
impactVelocity = -1;
};
void() pend_swing16 =[ $frame11, pend_swing17 ]
{
// pend_frame = pend_frame + 1;
// 0 128 -14 (center) W 64, H 72 (32, 36)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 96 -22', '8 160 50' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '96 -8 -22', '160 8 50' );
self.nextthink = time + 0.13;
};
void() pend_swing17 =[ $frame10, pend_swing18 ]
{
sound ( self, CHAN_AUTO, "pendulum/swing.wav", 0.5, ATTN_NORM);
// pend_frame = pend_frame + 1;
// 0 104 17 (center) W 68, H 68 (34, 34)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 70 -51', '8 138 17' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '70 -8 -51', '138 8 17' );
self.nextthink = time + 0.11;
};
void() pend_swing18 =[ $frame9, pend_swing19 ]
{
// pend_frame = pend_frame + 1;
// 0 74 40 (center) W 72, H 64 (36, 32)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 38 -72', '8 100 -8' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '38 -8 -72', '100 8 -8' );
self.nextthink = time + 0.09;
};
void() pend_swing19 =[ $frame8, pend_swing20 ]
{
// pend_frame = pend_frame + 1;
// 0 38 53 (center) W 76, H 60 (38, 30)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 0 -83', '8 76 -23' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '0 -8 -83', '76 8 -23' );
self.nextthink = time + 0.07;
};
void() pend_swing20 =[ $frame7, pend_swing21 ]
{
// pend_frame = pend_frame + 1;
// 0 0 60 (center) W 80, H 56 (40, 28)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 -40 -88', '8 40 -32' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '-40 -8 -88', '40 8 -32' );
self.nextthink = time + 0.05;
};
void() pend_swing21 =[ $frame6, pend_swing22 ]
{
// pend_frame = pend_frame + 1;
// 0 -38 53 (center) W 76, H 60 (38, 30)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 -76 -83', '8 0 -23' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '-76 -8 -83', '0 8 -23' );
self.nextthink = time + 0.07;
};
void() pend_swing22 =[ $frame5, pend_swing23 ]
{
// pend_frame = pend_frame + 1;
// 0 -74 40 (center) W 72, H 64 (36, 32)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 -110 -72', '8 -28 -8' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '-110 -8 -72', '-28 8 -8' );
self.nextthink = time + 0.09;
};
void() pend_swing23 =[ $frame4, pend_swing24 ]
{
// pend_frame = pend_frame + 1;
// 0 -104 17 (center) W 68, H 68 (34, 34)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 -172 -51', '8 -70 17' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '-172 -8 -51', '-70 8 17' );
self.nextthink = time + 0.11;
};
void() pend_swing24 =[ $frame3, pend_swing25 ]
{
// pend_frame = pend_frame + 1;
// 0 -128 -14 (center) W 64, H 72 (32, 36)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 -160 -22', '8 -96 50' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '-160 -8 -22', '-96 8 50' );
self.nextthink = time + 0.13;
};
void() pend_swing25 =[ $frame2, pend_swing26 ]
{
// pend_frame = pend_frame + 1;
// 0 -142 -50 (center) W 60, H 76 (30, 38)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 -172 12', '8 -112 88' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '-172 -8 12', '-112 8 88' );
self.nextthink = time + 0.15;
};
void() pend_swing26 =[ $frame1, pend_swing1 ]
{
// pend_frame = pend_frame + 1;
// 0 -148 -88 (center) W 56, H 80 (28,40)
if( self.spawnflags & PEND_Y)
setsize ( self, '-8 -176 48', '8 -120 128' );
else if ( self.spawnflags & PEND_X )
setsize ( self, '-176 -8 48', '-120 8 128' );
self.nextthink = time + 0.17;
};
void() pend_touch =
{
if (other.health < 1 || other.takedamage == DAMAGE_NO)
return;
if (self.attack_finished < time)
{
sound ( self, CHAN_VOICE, "pendulum/hit.wav", 1, ATTN_NORM);
self.attack_finished = time + 1;
}
T_Damage (other, self, self, self.currentammo);
// Fling the impactee in the direction the blade was swinging.
if (self.spawnflags & PEND_Y)
{
// other.velocity_y = other.velocity_y - impactVelocity * 250;
other.velocity_y = impactVelocity * -250;
}
else if(self.spawnflags & PEND_X)
{
// other.velocity_x = other.velocity_x + impactVelocity * 250;
other.velocity_x = impactVelocity * 250;
}
// Fling the impactee up a little bit.
// other.velocity_z = other.velocity_z + 200;
other.velocity_z = 200;
SpawnMeatSpray ( other.origin, other.velocity);
};
void() pend_use =
{
self.nextthink = time + self.delay;
self.think = pend_swing1;
};
/*QUAKED pendulum (0 .5 .8) (-8 -24 -100) (8 24 100) PEND_X PEND_Y PEND_TRG
The Pendulum
Values:
delay - amount of time (in seconds) before starting swinging. default 1.
currentammo - amount of damage for each contact. default 5.
Directional Flags: Pendulum swings perpendicular to it's angle. (eg. A pendulum facing east will swing north/south).
Default: PEND_Y
The pendulum angle is set automatically depending on the PEND_ choice.
PEND_X - a pendulum hanging from the ceiling swinging parallel to the X axis.
PEND_Y - a pendulum hanging from the ceiling swinging parallel to the Y axis.
PEND_TRG - the pendulum must be triggered to start swinging. The delay value still affects the pendulum.
*/
void() pendulum =
{
local vector center;
precache_model ("progs/pendulum.mdl");
precache_sound ("pendulum/swing.wav");
precache_sound ("pendulum/hit.wav");
setmodel (self, "progs/pendulum.mdl");
if (!self.spawnflags)
self.spawnflags = self.spawnflags + PEND_Y;
if (self.spawnflags & PEND_Y)
{
setsize (self, '-8 -24 -100', '8 24 100');
self.angles = '0 0 0';
self.v_angle = '0 0 0';
// if (self.angles_y != 0 )
// self.angles_y = 0;
}
else if ( self.spawnflags & PEND_X )
{
setsize (self, '-24 -8 -100', '24 8 100');
self.angles = '0 270 0';
self.v_angle = '0 270 0';
// if (self.angles_y != 270 )
// self.angles_y = 270;
}
else
error ( "ERROR: Unimplemented Pendulum Type (pendulum.qc)" );
if (!self.currentammo)
self.currentammo = 5;
if (!self.delay)
self.delay = 1;
impactVelocity = 0;
self.solid = SOLID_TRIGGER;
self.takedamage = DAMAGE_NO;
self.touch = pend_touch;
if (self.spawnflags & PEND_TRG)
{
self.use = pend_use;
}
else
{
self.nextthink = time + self.delay;
self.think = pend_swing1;
}
};

364
PLATS.QC Normal file
View File

@ -0,0 +1,364 @@
void() plat_center_touch;
void() plat_outside_touch;
void() plat_trigger_use;
void() plat_go_up;
void() plat_go_down;
void() plat_crush;
float PLAT_LOW_TRIGGER = 1;
void() plat_spawn_inside_trigger =
{
local entity trigger;
local vector tmin, tmax;
//
// middle trigger
//
trigger = spawn();
trigger.touch = plat_center_touch;
trigger.movetype = MOVETYPE_NONE;
trigger.solid = SOLID_TRIGGER;
trigger.enemy = self;
tmin = self.mins + '25 25 0';
tmax = self.maxs - '25 25 -8';
tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8);
if (self.spawnflags & PLAT_LOW_TRIGGER)
tmax_z = tmin_z + 8;
if (self.size_x <= 50)
{
tmin_x = (self.mins_x + self.maxs_x) / 2;
tmax_x = tmin_x + 1;
}
if (self.size_y <= 50)
{
tmin_y = (self.mins_y + self.maxs_y) / 2;
tmax_y = tmin_y + 1;
}
setsize (trigger, tmin, tmax);
};
void() plat_hit_top =
{
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_TOP;
self.think = plat_go_down;
self.nextthink = self.ltime + 3;
};
void() plat_hit_bottom =
{
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_BOTTOM;
};
void() plat_go_down =
{
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
self.state = STATE_DOWN;
SUB_CalcMove (self.pos2, self.speed, plat_hit_bottom);
};
void() plat_go_up =
{
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
self.state = STATE_UP;
SUB_CalcMove (self.pos1, self.speed, plat_hit_top);
};
void() plat_center_touch =
{
if (other.classname != "player")
return;
if (other.health <= 0)
return;
self = self.enemy;
if (self.state == STATE_BOTTOM)
plat_go_up ();
else if (self.state == STATE_TOP)
self.nextthink = self.ltime + 1; // delay going down
};
void() plat_outside_touch =
{
if (other.classname != "player")
return;
if (other.health <= 0)
return;
//dprint ("plat_outside_touch\n");
self = self.enemy;
if (self.state == STATE_TOP)
plat_go_down ();
};
void() plat_trigger_use =
{
if (self.think)
return; // allready activated
plat_go_down();
};
void() plat_crush =
{
//dprint ("plat_crush\n");
T_Damage (other, self, self, 1);
if (self.state == STATE_UP)
plat_go_down ();
else if (self.state == STATE_DOWN)
plat_go_up ();
else
objerror ("plat_crush: bad self.state\n");
};
void() plat_use =
{
self.use = SUB_Null;
if (self.state != STATE_UP)
objerror ("plat_use: not in up state");
plat_go_down();
};
/*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER
speed default 150
Plats are always drawn in the extended position, so they will light correctly.
If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is triggered, when it will lower and become a normal plat.
If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height.
Set "sounds" to one of the following:
1) base fast
2) chain slow
*/
void() func_plat =
{
local entity t;
if (!self.t_length)
self.t_length = 80;
if (!self.t_width)
self.t_width = 10;
if (self.sounds == 0)
self.sounds = 2;
// FIX THIS TO LOAD A GENERIC PLAT SOUND
if (self.sounds == 1)
{
precache_sound ("plats/plat1.wav");
precache_sound ("plats/plat2.wav");
self.noise = "plats/plat1.wav";
self.noise1 = "plats/plat2.wav";
}
if (self.sounds == 2)
{
precache_sound ("plats/medplat1.wav");
precache_sound ("plats/medplat2.wav");
self.noise = "plats/medplat1.wav";
self.noise1 = "plats/medplat2.wav";
}
self.mangle = self.angles;
self.angles = '0 0 0';
self.classname = "plat";
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_PUSH;
setorigin (self, self.origin);
setmodel (self, self.model);
setsize (self, self.mins , self.maxs);
self.blocked = plat_crush;
if (!self.speed)
self.speed = 150;
// pos1 is the top position, pos2 is the bottom
self.pos1 = self.origin;
self.pos2 = self.origin;
if (self.height)
self.pos2_z = self.origin_z - self.height;
else
self.pos2_z = self.origin_z - self.size_z + 8;
self.use = plat_trigger_use;
plat_spawn_inside_trigger (); // the "start moving" trigger
if (self.targetname)
{
self.state = STATE_UP;
self.use = plat_use;
}
else
{
setorigin (self, self.pos2);
self.state = STATE_BOTTOM;
}
};
//============================================================================
void() train_next;
void() func_train_find;
void() train_blocked =
{
if (time < self.attack_finished)
return;
self.attack_finished = time + 0.5;
T_Damage (other, self, self, self.dmg);
};
void() train_use =
{
if (self.think != func_train_find)
return; // already activated
train_next();
};
void() train_wait =
{
if (self.wait)
{
self.nextthink = self.ltime + self.wait;
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
}
else
self.nextthink = self.ltime + 0.1;
self.think = train_next;
};
void() train_next =
{
local entity targ;
targ = find (world, targetname, self.target);
self.target = targ.target;
if (!self.target)
objerror ("train_next: no next target");
if (targ.wait)
self.wait = targ.wait;
else
self.wait = 0;
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
SUB_CalcMove (targ.origin - self.mins, self.speed, train_wait);
};
void() func_train_find =
{
local entity targ;
targ = find (world, targetname, self.target);
self.target = targ.target;
setorigin (self, targ.origin - self.mins);
if (!self.targetname)
{ // not triggered, so start immediately
self.nextthink = self.ltime + 0.1;
self.think = train_next;
}
};
/*QUAKED func_train (0 .5 .8) ?
Trains are moving platforms that players can ride.
The targets origin specifies the min point of the train at each corner.
The train spawns at the first target it is pointing at.
If the train is the target of a button or trigger, it will not begin moving until activated.
speed default 100
dmg default 2
sounds
1) ratchet metal
*/
void() func_train =
{
if (!self.speed)
self.speed = 100;
if (!self.target)
objerror ("func_train without a target");
if (!self.dmg)
self.dmg = 2;
if (self.sounds == 0)
{
self.noise = ("misc/null.wav");
precache_sound ("misc/null.wav");
self.noise1 = ("misc/null.wav");
precache_sound ("misc/null.wav");
}
if (self.sounds == 1)
{
self.noise = ("plats/train2.wav");
precache_sound ("plats/train2.wav");
self.noise1 = ("plats/train1.wav");
precache_sound ("plats/train1.wav");
}
self.cnt = 1;
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_PUSH;
self.blocked = train_blocked;
self.use = train_use;
self.classname = "train";
setmodel (self, self.model);
setsize (self, self.mins , self.maxs);
setorigin (self, self.origin);
// start trains on the second frame, to make sure their targets have had
// a chance to spawn
self.nextthink = self.ltime + 0.1;
self.think = func_train_find;
};
/*QUAKED misc_teleporttrain (0 .5 .8) (-8 -8 -8) (8 8 8)
This is used for the final bos
*/
void() misc_teleporttrain =
{
if (!self.speed)
self.speed = 100;
if (!self.target)
objerror ("func_train without a target");
self.cnt = 1;
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_PUSH;
self.blocked = train_blocked;
self.use = train_use;
self.avelocity = '100 200 300';
self.noise = ("misc/null.wav");
precache_sound ("misc/null.wav");
self.noise1 = ("misc/null.wav");
precache_sound ("misc/null.wav");
precache_model2 ("progs/teleport.mdl");
setmodel (self, "progs/teleport.mdl");
setsize (self, self.mins , self.maxs);
setorigin (self, self.origin);
// start trains on the second frame, to make sure their targets have had
// a chance to spawn
self.nextthink = self.ltime + 0.1;
self.think = func_train_find;
};

817
PLAYER.QC Normal file
View File

@ -0,0 +1,817 @@
void() bubble_bob;
/*
==============================================================================
PLAYER
==============================================================================
*/
$cd /raid/quake/id1/models/player_4
$origin 0 -6 24
$base base
$skin skin
//
// running
//
$frame axrun1 axrun2 axrun3 axrun4 axrun5 axrun6
$frame rockrun1 rockrun2 rockrun3 rockrun4 rockrun5 rockrun6
//
// standing
//
$frame stand1 stand2 stand3 stand4 stand5
$frame axstnd1 axstnd2 axstnd3 axstnd4 axstnd5 axstnd6
$frame axstnd7 axstnd8 axstnd9 axstnd10 axstnd11 axstnd12
//
// pain
//
$frame axpain1 axpain2 axpain3 axpain4 axpain5 axpain6
$frame pain1 pain2 pain3 pain4 pain5 pain6
//
// death
//
$frame axdeth1 axdeth2 axdeth3 axdeth4 axdeth5 axdeth6
$frame axdeth7 axdeth8 axdeth9
$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8
$frame deatha9 deatha10 deatha11
$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
$frame deathb9
$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
$frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15
$frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7
$frame deathd8 deathd9
$frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7
$frame deathe8 deathe9
//
// attacks
//
$frame nailatt1 nailatt2
$frame light1 light2
$frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6
$frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6
$frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6
$frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6
$frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6
$frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6
/*
==============================================================================
PLAYER
==============================================================================
*/
void() player_run;
void() player_stand1 =[ $axstnd1, player_stand1 ]
{
self.weaponframe=0;
if (self.velocity_x || self.velocity_y)
{
self.walkframe=0;
player_run();
return;
}
if (self.weapon == IT_AXE)
{
if (self.walkframe >= 12)
self.walkframe = 0;
self.frame = $axstnd1 + self.walkframe;
}
else
{
if (self.walkframe >= 5)
self.walkframe = 0;
self.frame = $stand1 + self.walkframe;
}
self.walkframe = self.walkframe + 1;
};
void() player_run =[ $rockrun1, player_run ]
{
self.weaponframe=0;
if (!self.velocity_x && !self.velocity_y)
{
self.walkframe=0;
player_stand1();
return;
}
if (self.weapon == IT_AXE)
{
if (self.walkframe == 6)
self.walkframe = 0;
self.frame = $axrun1 + self.walkframe;
}
else
{
if (self.walkframe == 6)
self.walkframe = 0;
self.frame = self.frame + self.walkframe;
}
self.walkframe = self.walkframe + 1;
};
void() player_shot1 = [$shotatt1, player_shot2 ] {self.weaponframe=1;
self.effects = self.effects | EF_MUZZLEFLASH;};
void() player_shot2 = [$shotatt2, player_shot3 ] {self.weaponframe=2;};
void() player_shot3 = [$shotatt3, player_shot4 ] {self.weaponframe=3;};
void() player_shot4 = [$shotatt4, player_shot5 ] {self.weaponframe=4;};
void() player_shot5 = [$shotatt5, player_shot6 ] {self.weaponframe=5;};
void() player_shot6 = [$shotatt6, player_run ] {self.weaponframe=6;};
void() player_axe1 = [$axatt1, player_axe2 ] {self.weaponframe=1;};
void() player_axe2 = [$axatt2, player_axe3 ] {self.weaponframe=2;};
void() player_axe3 = [$axatt3, player_axe4 ] {self.weaponframe=3;W_FireAxe();};
void() player_axe4 = [$axatt4, player_run ] {self.weaponframe=4;};
void() player_axeb1 = [$axattb1, player_axeb2 ] {self.weaponframe=5;};
void() player_axeb2 = [$axattb2, player_axeb3 ] {self.weaponframe=6;};
void() player_axeb3 = [$axattb3, player_axeb4 ] {self.weaponframe=7;W_FireAxe();};
void() player_axeb4 = [$axattb4, player_run ] {self.weaponframe=8;};
void() player_axec1 = [$axattc1, player_axec2 ] {self.weaponframe=1;};
void() player_axec2 = [$axattc2, player_axec3 ] {self.weaponframe=2;};
void() player_axec3 = [$axattc3, player_axec4 ] {self.weaponframe=3;W_FireAxe();};
void() player_axec4 = [$axattc4, player_run ] {self.weaponframe=4;};
void() player_axed1 = [$axattd1, player_axed2 ] {self.weaponframe=5;};
void() player_axed2 = [$axattd2, player_axed3 ] {self.weaponframe=6;};
void() player_axed3 = [$axattd3, player_axed4 ] {self.weaponframe=7;W_FireAxe();};
void() player_axed4 = [$axattd4, player_run ] {self.weaponframe=8;};
//============================================================================
//ZOID--
void() player_grapple3;
void() player_grapple4;
void() player_grapple5;
void() player_grapple1 = [$axattd1, player_grapple2 ]
{ self.weaponframe=1; W_FireGrapple(); };
// { self.weaponframe=2; W_FireGrapple(); };
void() player_grapple2 = [$axattd2, player_grapple3 ]
{ self.weaponframe=2; };
// { self.weaponframe=3; };
void() player_grapple3 = [$axattd3, player_grapple3 ]
{
// self.weaponframe=3;
self.weaponframe=2;
if (!self.hook_out) {
player_grapple5();
return;
}
if (vlen(self.hook.origin - self.origin) >= 50) {
if (self.on_hook) {
player_grapple4();
return;
}
}
};
void() player_grapple4 = [$deathc4, player_grapple4 ]
{
// self.weaponframe=4;
self.weaponframe=2;
if (!self.hook_out) {
player_grapple5();
return;
}
if (vlen(self.hook.origin - self.origin) < 50 || !self.on_hook) {
player_grapple3();
return;
}
};
void() player_grapple5 = [$axattd4, player_run ]
// {self.weaponframe=5;};
{self.weaponframe=1;};
//--ZOID
//============================================================================
void() player_nail1 =[$nailatt1, player_nail2 ]
{
self.effects = self.effects | EF_MUZZLEFLASH;
if (!self.button0)
{player_run ();return;}
self.weaponframe = self.weaponframe + 1;
if (self.weaponframe == 9)
self.weaponframe = 1;
SuperDamageSound();
W_FireSpikes (4);
self.attack_finished = time + 0.2;
};
void() player_nail2 =[$nailatt2, player_nail1 ]
{
self.effects = self.effects | EF_MUZZLEFLASH;
if (!self.button0)
{player_run ();return;}
self.weaponframe = self.weaponframe + 1;
if (self.weaponframe == 9)
self.weaponframe = 1;
SuperDamageSound();
W_FireSpikes (-4);
self.attack_finished = time + 0.2;
};
//============================================================================
void(float ox) W_FireLavaSpikes;
void() player_lava_nail1 =[$nailatt1, player_lava_nail2 ]
{
self.effects = self.effects | EF_MUZZLEFLASH;
if (!self.button0)
{player_run ();return;}
self.weaponframe = self.weaponframe + 1;
if (self.weaponframe == 9)
self.weaponframe = 1;
SuperDamageSound();
W_FireLavaSpikes (4);
self.attack_finished = time + 0.2;
};
void() player_lava_nail2 =[$nailatt2, player_lava_nail1 ]
{
self.effects = self.effects | EF_MUZZLEFLASH;
if (!self.button0)
{player_run ();return;}
self.weaponframe = self.weaponframe + 1;
if (self.weaponframe == 9)
self.weaponframe = 1;
SuperDamageSound();
W_FireLavaSpikes (-4);
self.attack_finished = time + 0.2;
};
//============================================================================
void() W_FirePlasma;
void() player_light1 =[$light1, player_light2 ]
{
self.effects = self.effects | EF_MUZZLEFLASH;
if (!self.button0)
{player_run ();return;}
self.weaponframe = self.weaponframe + 1;
if (self.weaponframe == 5)
self.weaponframe = 1;
SuperDamageSound();
if (self.weapon == IT_LIGHTNING)
{
W_FireLightning();
self.attack_finished = time + 0.2;
}
else if (self.weapon == IT_PLASMA_GUN)
{
W_FirePlasma();
player_run();
return;
}
};
void() player_light2 =[$light2, player_light1 ]
{
self.effects = self.effects | EF_MUZZLEFLASH;
if (!self.button0)
{player_run ();return;}
self.weaponframe = self.weaponframe + 1;
if (self.weaponframe == 5)
self.weaponframe = 1;
SuperDamageSound();
if (self.weapon == IT_LIGHTNING)
{
W_FireLightning();
self.attack_finished = time + 0.2;
}
};
//============================================================================
void() player_rocket1 =[$rockatt1, player_rocket2 ] {self.weaponframe=1;
self.effects = self.effects | EF_MUZZLEFLASH;};
void() player_rocket2 =[$rockatt2, player_rocket3 ] {self.weaponframe=2;};
void() player_rocket3 =[$rockatt3, player_rocket4 ] {self.weaponframe=3;};
void() player_rocket4 =[$rockatt4, player_rocket5 ] {self.weaponframe=4;};
void() player_rocket5 =[$rockatt5, player_rocket6 ] {self.weaponframe=5;};
void() player_rocket6 =[$rockatt6, player_run ] {self.weaponframe=6;};
void(float num_bubbles) DeathBubbles;
void() PainSound =
{
local float rs;
if (self.health < 0)
return;
if (damage_attacker.classname == "teledeath")
{
sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
return;
}
// water pain sounds
if (self.watertype == CONTENT_WATER && self.waterlevel == 3)
{
DeathBubbles(1);
if (random() > 0.5)
sound (self, CHAN_VOICE, "player/drown1.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "player/drown2.wav", 1, ATTN_NORM);
return;
}
// slime pain sounds
if (self.watertype == CONTENT_SLIME)
{
// FIX ME put in some steam here
if (random() > 0.5)
sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM);
return;
}
if (self.watertype == CONTENT_LAVA)
{
if (random() > 0.5)
sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM);
else
sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM);
return;
}
if (self.pain_finished > time)
{
self.axhitme = 0;
return;
}
self.pain_finished = time + 0.5;
// don't make multiple pain sounds right after each other
// ax pain sound
if (self.axhitme == 1)
{
self.axhitme = 0;
sound (self, CHAN_VOICE, "player/axhit1.wav", 1, ATTN_NORM);
return;
}
rs = rint((random() * 5) + 1);
self.noise = "";
if (rs == 1)
self.noise = "player/pain1.wav";
else if (rs == 2)
self.noise = "player/pain2.wav";
else if (rs == 3)
self.noise = "player/pain3.wav";
else if (rs == 4)
self.noise = "player/pain4.wav";
else if (rs == 5)
self.noise = "player/pain5.wav";
else
self.noise = "player/pain6.wav";
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
return;
};
void() player_pain1 = [ $pain1, player_pain2 ] {PainSound();self.weaponframe=0;};
void() player_pain2 = [ $pain2, player_pain3 ] {};
void() player_pain3 = [ $pain3, player_pain4 ] {};
void() player_pain4 = [ $pain4, player_pain5 ] {};
void() player_pain5 = [ $pain5, player_pain6 ] {};
void() player_pain6 = [ $pain6, player_run ] {};
void() player_axpain1 = [ $axpain1, player_axpain2 ] {PainSound();self.weaponframe=0;};
void() player_axpain2 = [ $axpain2, player_axpain3 ] {};
void() player_axpain3 = [ $axpain3, player_axpain4 ] {};
void() player_axpain4 = [ $axpain4, player_axpain5 ] {};
void() player_axpain5 = [ $axpain5, player_axpain6 ] {};
void() player_axpain6 = [ $axpain6, player_run ] {};
void() player_pain =
{
if (self.weaponframe)
return;
if (self.invisible_finished > time)
return; // eyes don't have pain frames
if (self.weapon == IT_AXE)
player_axpain1 ();
else
player_pain1 ();
};
void() player_diea1;
void() player_dieb1;
void() player_diec1;
void() player_died1;
void() player_diee1;
void() player_die_ax1;
void() DeathBubblesSpawn =
{
local entity bubble;
if (self.owner.waterlevel != 3)
return;
bubble = spawn();
setmodel (bubble, "progs/s_bubble.spr");
setorigin (bubble, self.owner.origin + '0 0 24');
bubble.movetype = MOVETYPE_NOCLIP;
bubble.solid = SOLID_NOT;
bubble.velocity = '0 0 15';
bubble.nextthink = time + 0.5;
bubble.think = bubble_bob;
bubble.classname = "bubble";
bubble.frame = 0;
bubble.cnt = 0;
setsize (bubble, '-8 -8 -8', '8 8 8');
self.nextthink = time + 0.1;
self.think = DeathBubblesSpawn;
self.air_finished = self.air_finished + 1;
if (self.air_finished >= self.bubble_count)
remove(self);
};
void(float num_bubbles) DeathBubbles =
{
local entity bubble_spawner;
bubble_spawner = spawn();
setorigin (bubble_spawner, self.origin);
bubble_spawner.movetype = MOVETYPE_NONE;
bubble_spawner.solid = SOLID_NOT;
bubble_spawner.nextthink = time + 0.1;
bubble_spawner.think = DeathBubblesSpawn;
bubble_spawner.air_finished = 0;
bubble_spawner.owner = self;
bubble_spawner.bubble_count = num_bubbles;
return;
};
void() DeathSound =
{
local float rs;
// water death sounds
if (self.waterlevel == 3)
{
DeathBubbles(20);
sound (self, CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NONE);
return;
}
rs = rint ((random() * 4) + 1);
if (rs == 1)
self.noise = "player/death1.wav";
if (rs == 2)
self.noise = "player/death2.wav";
if (rs == 3)
self.noise = "player/death3.wav";
if (rs == 4)
self.noise = "player/death4.wav";
if (rs == 5)
self.noise = "player/death5.wav";
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NONE);
return;
};
void() PlayerDead =
{
self.nextthink = -1;
// allow respawn after a certain time
self.deadflag = DEAD_DEAD;
};
vector(float dm) VelocityForDamage =
{
local vector v;
v_x = 100 * crandom();
v_y = 100 * crandom();
v_z = 200 + 100 * random();
if (dm > -50)
{
// dprint ("level 1\n");
v = v * 0.7;
}
else if (dm > -200)
{
// dprint ("level 3\n");
v = v * 2;
}
else
v = v * 10;
return v;
};
void(string gibname, float dm) ThrowGib =
{
local entity new;
new = spawn();
new.origin = self.origin;
setmodel (new, gibname);
setsize (new, '0 0 0', '0 0 0');
new.velocity = VelocityForDamage (dm);
new.movetype = MOVETYPE_BOUNCE;
new.solid = SOLID_NOT;
new.avelocity_x = random()*600;
new.avelocity_y = random()*600;
new.avelocity_z = random()*600;
new.think = SUB_Remove;
new.ltime = time;
new.nextthink = time + 10 + random()*10;
new.frame = 0;
new.flags = 0;
};
void(string gibname, float dm) ThrowHead =
{
setmodel (self, gibname);
self.frame = 0;
self.nextthink = -1;
self.movetype = MOVETYPE_BOUNCE;
self.takedamage = DAMAGE_NO;
self.solid = SOLID_NOT;
self.view_ofs = '0 0 8';
setsize (self, '-16 -16 0', '16 16 56');
self.velocity = VelocityForDamage (dm);
self.origin_z = self.origin_z - 24;
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.avelocity = crandom() * '0 600 0';
};
void() GibPlayer =
{
ThrowHead ("progs/h_player.mdl", self.health);
ThrowGib ("progs/gib1.mdl", self.health);
ThrowGib ("progs/gib2.mdl", self.health);
ThrowGib ("progs/gib3.mdl", self.health);
self.deadflag = DEAD_DEAD;
if (damage_attacker.classname == "teledeath")
{
sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
return;
}
if (damage_attacker.classname == "teledeath2")
{
sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
return;
}
if (random() < 0.5)
sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NONE);
else
sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NONE);
};
void() PlayerDie =
{
local float i;
self.items = self.items - (self.items & IT_INVISIBILITY);
self.invisible_finished = 0; // don't die as eyes
self.invincible_finished = 0;
self.super_damage_finished = 0;
self.radsuit_finished = 0;
self.modelindex = modelindex_player; // don't use eyes
self.gravity = 1.0;
self.shield_finished = 0;
self.antigrav_finished = 0;
//ZOID--
if (deathmatch || coop)
{
DropBackpack();
TeamDropFlagOfPlayer(self);
DropRune();
}
if (self.ctf_killed == 2)
self.ctf_killed = 0;
else
self.ctf_killed = 1;
//--ZOID
self.weaponmodel="";
self.view_ofs = '0 0 -8';
self.deadflag = DEAD_DYING;
self.solid = SOLID_NOT;
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.movetype = MOVETYPE_TOSS;
if (self.velocity_z < 10)
self.velocity_z = self.velocity_z + random()*300;
if (self.health < -40)
{
GibPlayer ();
return;
}
DeathSound();
self.angles_x = 0;
self.angles_z = 0;
if (self.weapon == IT_AXE)
{
player_die_ax1 ();
return;
}
i = cvar("temp1");
if (!i)
i = 1 + floor(random()*6);
if (i == 1)
player_diea1();
else if (i == 2)
player_dieb1();
else if (i == 3)
player_diec1();
else if (i == 4)
player_died1();
else
player_diee1();
};
void() set_suicide_frame =
{ // used by klill command and diconnect command
if (self.model != "progs/player.mdl")
return; // allready gibbed
self.frame = $deatha11;
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_TOSS;
self.deadflag = DEAD_DEAD;
self.nextthink = -1;
};
void() player_diea1 = [ $deatha1, player_diea2 ] {};
void() player_diea2 = [ $deatha2, player_diea3 ] {};
void() player_diea3 = [ $deatha3, player_diea4 ] {};
void() player_diea4 = [ $deatha4, player_diea5 ] {};
void() player_diea5 = [ $deatha5, player_diea6 ] {};
void() player_diea6 = [ $deatha6, player_diea7 ] {};
void() player_diea7 = [ $deatha7, player_diea8 ] {};
void() player_diea8 = [ $deatha8, player_diea9 ] {};
void() player_diea9 = [ $deatha9, player_diea10 ] {};
void() player_diea10 = [ $deatha10, player_diea11 ] {};
void() player_diea11 = [ $deatha11, player_diea11 ] {PlayerDead();};
void() player_dieb1 = [ $deathb1, player_dieb2 ] {};
void() player_dieb2 = [ $deathb2, player_dieb3 ] {};
void() player_dieb3 = [ $deathb3, player_dieb4 ] {};
void() player_dieb4 = [ $deathb4, player_dieb5 ] {};
void() player_dieb5 = [ $deathb5, player_dieb6 ] {};
void() player_dieb6 = [ $deathb6, player_dieb7 ] {};
void() player_dieb7 = [ $deathb7, player_dieb8 ] {};
void() player_dieb8 = [ $deathb8, player_dieb9 ] {};
void() player_dieb9 = [ $deathb9, player_dieb9 ] {PlayerDead();};
void() player_diec1 = [ $deathc1, player_diec2 ] {};
void() player_diec2 = [ $deathc2, player_diec3 ] {};
void() player_diec3 = [ $deathc3, player_diec4 ] {};
void() player_diec4 = [ $deathc4, player_diec5 ] {};
void() player_diec5 = [ $deathc5, player_diec6 ] {};
void() player_diec6 = [ $deathc6, player_diec7 ] {};
void() player_diec7 = [ $deathc7, player_diec8 ] {};
void() player_diec8 = [ $deathc8, player_diec9 ] {};
void() player_diec9 = [ $deathc9, player_diec10 ] {};
void() player_diec10 = [ $deathc10, player_diec11 ] {};
void() player_diec11 = [ $deathc11, player_diec12 ] {};
void() player_diec12 = [ $deathc12, player_diec13 ] {};
void() player_diec13 = [ $deathc13, player_diec14 ] {};
void() player_diec14 = [ $deathc14, player_diec15 ] {};
void() player_diec15 = [ $deathc15, player_diec15 ] {PlayerDead();};
void() player_died1 = [ $deathd1, player_died2 ] {};
void() player_died2 = [ $deathd2, player_died3 ] {};
void() player_died3 = [ $deathd3, player_died4 ] {};
void() player_died4 = [ $deathd4, player_died5 ] {};
void() player_died5 = [ $deathd5, player_died6 ] {};
void() player_died6 = [ $deathd6, player_died7 ] {};
void() player_died7 = [ $deathd7, player_died8 ] {};
void() player_died8 = [ $deathd8, player_died9 ] {};
void() player_died9 = [ $deathd9, player_died9 ] {PlayerDead();};
void() player_diee1 = [ $deathe1, player_diee2 ] {};
void() player_diee2 = [ $deathe2, player_diee3 ] {};
void() player_diee3 = [ $deathe3, player_diee4 ] {};
void() player_diee4 = [ $deathe4, player_diee5 ] {};
void() player_diee5 = [ $deathe5, player_diee6 ] {};
void() player_diee6 = [ $deathe6, player_diee7 ] {};
void() player_diee7 = [ $deathe7, player_diee8 ] {};
void() player_diee8 = [ $deathe8, player_diee9 ] {};
void() player_diee9 = [ $deathe9, player_diee9 ] {PlayerDead();};
void() player_die_ax1 = [ $axdeth1, player_die_ax2 ] {};
void() player_die_ax2 = [ $axdeth2, player_die_ax3 ] {};
void() player_die_ax3 = [ $axdeth3, player_die_ax4 ] {};
void() player_die_ax4 = [ $axdeth4, player_die_ax5 ] {};
void() player_die_ax5 = [ $axdeth5, player_die_ax6 ] {};
void() player_die_ax6 = [ $axdeth6, player_die_ax7 ] {};
void() player_die_ax7 = [ $axdeth7, player_die_ax8 ] {};
void() player_die_ax8 = [ $axdeth8, player_die_ax9 ] {};
void() player_die_ax9 = [ $axdeth9, player_die_ax9 ] {PlayerDead();};
void(entity shieldOwner, vector dir) shield_spawn;
void() player_touch =
{
local vector vec;
local float dot;
local float doDamage;
if ( self.items2 & IT2_SHIELD)
{
if ( other.classname == "player")
{
makevectors ( self.angles );
vec = normalize (other.origin - self.origin);
dot = vec * v_forward;
if (dot < 0.3)
return;
makevectors ( self.angles );
other.velocity = v_forward * 500;
other.velocity_z = 250;
doDamage = FALSE;
if (TeamArmorDam(other, self, self, 15))
{
if(self.shield_death_time < time)
doDamage = TRUE;
}
// if shield has timed out, respawn it.
// don't do particles more than twice a second.
if ( self.shield_death_time < time)
{
sound(self,CHAN_WEAPON,"enforcer/enfstop.wav", 1, ATTN_NORM);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION2);
WriteCoord (MSG_BROADCAST, other.origin_x);
WriteCoord (MSG_BROADCAST, other.origin_y);
WriteCoord (MSG_BROADCAST, other.origin_z);
WriteByte (MSG_BROADCAST, 230);
WriteByte (MSG_BROADCAST, 5);
shield_spawn ( self, v_forward );
}
if (doDamage)
T_Damage (other, self.shield_entity, self.shield_entity, 15);
// self.shield_death_time = time + 0.5;
}
}
};

143
PROGDEFS.H Normal file
View File

@ -0,0 +1,143 @@
/* file generated by qcc, do not modify */
typedef struct
{ int pad[28];
int self;
int other;
int world;
float time;
float frametime;
float force_retouch;
string_t mapname;
float deathmatch;
float coop;
float teamplay;
float serverflags;
float total_secrets;
float total_monsters;
float found_secrets;
float killed_monsters;
float parm1;
float parm2;
float parm3;
float parm4;
float parm5;
float parm6;
float parm7;
float parm8;
float parm9;
float parm10;
float parm11;
float parm12;
float parm13;
float parm14;
float parm15;
float parm16;
vec3_t v_forward;
vec3_t v_up;
vec3_t v_right;
float trace_allsolid;
float trace_startsolid;
float trace_fraction;
vec3_t trace_endpos;
vec3_t trace_plane_normal;
float trace_plane_dist;
int trace_ent;
float trace_inopen;
float trace_inwater;
int msg_entity;
func_t main;
func_t StartFrame;
func_t PlayerPreThink;
func_t PlayerPostThink;
func_t ClientKill;
func_t ClientConnect;
func_t PutClientInServer;
func_t ClientDisconnect;
func_t SetNewParms;
func_t SetChangeParms;
} globalvars_t;
typedef struct
{
float modelindex;
vec3_t absmin;
vec3_t absmax;
float ltime;
float movetype;
float solid;
vec3_t origin;
vec3_t oldorigin;
vec3_t velocity;
vec3_t angles;
vec3_t avelocity;
vec3_t punchangle;
string_t classname;
string_t model;
float frame;
float skin;
float effects;
vec3_t mins;
vec3_t maxs;
vec3_t size;
func_t touch;
func_t use;
func_t think;
func_t blocked;
float nextthink;
int groundentity;
float health;
float frags;
float weapon;
string_t weaponmodel;
float weaponframe;
float currentammo;
float ammo_shells;
float ammo_nails;
float ammo_rockets;
float ammo_cells;
float items;
float takedamage;
int chain;
float deadflag;
vec3_t view_ofs;
float button0;
float button1;
float button2;
float impulse;
float fixangle;
vec3_t v_angle;
float idealpitch;
string_t netname;
int enemy;
float flags;
float colormap;
float team;
float max_health;
float teleport_time;
float armortype;
float armorvalue;
float waterlevel;
float watertype;
float ideal_yaw;
float yaw_speed;
int aiment;
int goalentity;
float spawnflags;
string_t target;
string_t targetname;
float dmg_take;
float dmg_save;
int dmg_inflictor;
int owner;
vec3_t movedir;
string_t message;
float sounds;
string_t noise;
string_t noise1;
string_t noise2;
string_t noise3;
} entvars_t;
#define PROGHEADER_CRC 5927

66
PROGS.SRC Normal file
View File

@ -0,0 +1,66 @@
progs.dat
defs.qc
teamplay.qc // ZOID - teamplay stuff
runes.qc
motd.qc
subs.qc
fight.qc
ai.qc
combat.qc
items.qc
grapple.qc // ZOID - grappling hook
weapons.qc
world.qc
client.qc
player.qc
monsters.qc
doors.qc
buttons.qc
triggers.qc
plats.qc
misc.qc
ogre.qc
demon.qc
shambler.qc
knight.qc
soldier.qc
wizard.qc
dog.qc
zombie.qc
boss.qc
tarbaby.qc // registered
hknight.qc // registered
fish.qc // registered
shalrath.qc // registered
enforcer.qc // registered
oldone.qc // registered
new_ai.qc
eel.qc
invis_sw.qc
newitems.qc
newplats.qc
newmisc.qc
elevatr.qc
pendulum.qc
lightnin.qc
wrath.qc
shield.qc
lava_wpn.qc
mult_wpn.qc
dragon.qc
s_wrath.qc
random.qc
earthq.qc
lavaman.qc
sphere.qc
buzzsaw.qc
dmatch.qc
morph.qc
ending.qc
mummy.qc
timemach.qc

122
RANDOM.QC Normal file
View File

@ -0,0 +1,122 @@
// Random.qc
// =======================================================
// Random Items!
// =======================================================
// equal divisions of 1:
// 5: 0.2, 0.4, 0.6, 0.8, 1
// 6: 0.16, 0.33, 0.48, 0.66, 0.83, 1
// 7: 0.14, 0.28, 0.43, 0.56, 0.71, 0.86, 1
// 8: 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1
void() random_pick_type =
{
local float randItem;
randItem = random();
self.touch = powerup_touch;
setsize (self, '-16 -16 -24', '16 16 32');
if(randItem < 0.2)
{
self.touch = newitems_touch;
self.noise = "shield/pickup.wav";
setmodel (self, "progs/shield.mdl");
self.netname = "Power Shield";
self.items = 0;
self.items2 = IT2_SHIELD;
// if(norandom == 1)
// self.classname = "item_powerup_shield";
}
else if (randItem < 0.4)
{
self.touch = newitems_touch;
self.noise = "belt/pickup.wav";
setmodel (self, "progs/beltup.mdl");
self.netname = "Anti-Grav Belt";
self.items = 0;
self.items2 = IT2_ANTIGRAV;
// if(norandom == 1)
// self.classname = "item_powerup_belt";
}
else if (randItem < 0.6)
{
self.noise = "items/protect.wav";
setmodel (self, "progs/invulner.mdl");
self.netname = "Pentagram of Protection";
self.items = IT_INVULNERABILITY;
self.items2 = 0;
// if(norandom == 1)
// self.classname = "item_artifact_invulnerability";
}
else if (randItem < 0.8)
{
self.noise = "items/inv1.wav";
setmodel (self, "progs/invisibl.mdl");
self.netname = "Ring of Shadows";
self.items = IT_INVISIBILITY;
self.items2 = 0;
// if(norandom == 1)
// self.classname = "item_artifact_invisibility";
}
else
{
self.noise = "items/damage.wav";
setmodel (self, "progs/quaddama.mdl");
self.netname = "Quad Damage";
self.items = IT_QUAD;
self.items2 = 0;
// if(norandom == 1)
// self.classname = "item_artifact_super_damage";
}
};
/*QUAKED item_random_powerup (0 .5 .8) (-16 -16 -24) (16 16 32)
The Random Box!
Contains a random powerup.
*/
void() item_random_powerup =
{
if (!deathmatch)
{
remove(self);
return;
}
// Precache the lot of it....
precache_model ("progs/shield.mdl");
precache_model ("progs/p_shield.mdl");
precache_model ("progs/beltup.mdl");
precache_model ("progs/invulner.mdl");
precache_model ("progs/invisibl.mdl");
precache_model ("progs/quaddama.mdl");
precache_sound ("items/inv1.wav");
precache_sound ("items/inv2.wav");
precache_sound ("items/inv3.wav");
precache_sound ("items/protect.wav");
precache_sound ("items/protect2.wav");
precache_sound ("items/protect3.wav");
precache_sound ("items/damage.wav");
precache_sound ("items/damage2.wav");
precache_sound ("items/damage3.wav");
precache_sound ("belt/pickup.wav");
precache_sound ("belt/use.wav");
precache_sound ("belt/fadeout.wav");
precache_sound ("shield/pickup.wav");
precache_sound ("shield/hit.wav");
precache_sound ("shield/fadeout.wav");
random_pick_type();
StartItem ();
};
void() random_regen =
{
random_pick_type();
SUB_regen();
};

223
RUNES.QC Normal file
View File

@ -0,0 +1,223 @@
// Rogue Runes
// Jan'97 by ZOID <zoid@threewave.com>
// Under contract to id software for Rogue Entertainment
.float rune; // what rune does this guy have?
.float runetime; // last time we told him he's already got a rune
.float rune1_last_noise_time;
.float rune2_last_noise_time;
.float rune3_last_noise_time;
.float rune4_last_regen_time;
float runespawn; // have we spawned runes?
entity rune_spawn_spot; // spawn spot for runes
float ITEM_RUNE1 = 1; // Rune of Earth Magic: Resistance
float ITEM_RUNE2 = 2; // Rune of Black Magic: Strength
float ITEM_RUNE3 = 4; // Rune of Hell Magic: Haste
float ITEM_RUNE4 = 8; // Rune of Edler Magic: Regeneration
//prototypes
void() RuneTouch =
{
if (other.classname != "player" || other.health <= 0)
return;
if (other.rune) {
if (other.runetime < time)
centerprint(other, "You already have a rune\n");
other.runetime = time + 5;
return;
}
other.rune = other.rune | self.rune;
sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
if (self.rune & ITEM_RUNE1)
centerprint(other, "Earth Magic\n\nRESISTANCE");
else if (self.rune & ITEM_RUNE2)
centerprint(other, "Black Magic\n\nSTRENGTH");
else if (self.rune & ITEM_RUNE3)
centerprint(other, "Hell Magic\n\nHASTE");
else if (self.rune & ITEM_RUNE4)
centerprint(other, "Edler Magic\n\nRegeneration");
remove(self);
};
entity() RuneSpawnPoint =
{
while (1) {
rune_spawn_spot = find(rune_spawn_spot, classname,
"info_player_deathmatch");
if (rune_spawn_spot != world)
return rune_spawn_spot;
}
};
void() RuneRespawn =
{
local entity spot;
spot = RuneSpawnPoint();
setorigin(self, spot.origin);
self.velocity_z = 300;
self.velocity_x = -300 + (random() * 600);
self.velocity_y = -300 + (random() * 600);
self.nextthink = time + 120;
};
void(float r, entity spot) SpawnRune =
{
local entity item;
if (spot == world)
spot = RuneSpawnPoint();
item = spawn();
setorigin(item, spot.origin);
item.rune = r;
item.velocity_z = 300;
item.velocity_x = -300 + (random() * 600);
item.velocity_y = -300 + (random() * 600);
item.flags = FL_ITEM;
item.solid = SOLID_TRIGGER;
item.movetype = MOVETYPE_TOSS;
if (r & ITEM_RUNE1)
setmodel (item, "progs/end1.mdl");
else if (r & ITEM_RUNE2)
setmodel (item, "progs/end2.mdl");
else if (r & ITEM_RUNE3)
setmodel (item, "progs/end3.mdl");
else if (r & ITEM_RUNE4)
setmodel (item, "progs/end4.mdl");
setsize (item, '-16 -16 0', '16 16 56');
item.touch = RuneTouch;
item.nextthink = time + 120; // remove after 2 minutes
item.think = RuneRespawn;
};
// self is player
void() DropRune =
{
if (self.rune & ITEM_RUNE1)
SpawnRune(ITEM_RUNE1, self);
if (self.rune & ITEM_RUNE2)
SpawnRune(ITEM_RUNE2, self);
if (self.rune & ITEM_RUNE3)
SpawnRune(ITEM_RUNE3, self);
if (self.rune & ITEM_RUNE4)
SpawnRune(ITEM_RUNE4, self);
self.rune = 0;
};
void() DoSpawnRunes =
{
remove(self);
SpawnRune(ITEM_RUNE1, world);
SpawnRune(ITEM_RUNE2, world);
SpawnRune(ITEM_RUNE3, world);
SpawnRune(ITEM_RUNE4, world);
};
void() SpawnRunes =
{
local entity spawner;
if (!deathmatch || !(cvar("gamecfg") & GAMECFG_ENABLE_RUNES) || runespawn)
return;
runespawn = 1;
spawner = spawn();
spawner.think = DoSpawnRunes;
spawner.nextthink = time + 0.1;
};
float(float damage, entity who) RuneApplyEarth =
{
if (who.rune & ITEM_RUNE1) {
if (who.rune1_last_noise_time < time) {
sound (who, CHAN_ITEM, "runes/end1.wav", 1, ATTN_NORM);
// tune as needed
who.rune1_last_noise_time = time + 1.0;
}
return damage/2;
}
return damage;
};
void(entity who) RuneApplyBlackNoise =
{
if (who.rune & ITEM_RUNE2)
if (who.rune2_last_noise_time < time) {
sound (who, CHAN_ITEM, "runes/end2.wav", 1, ATTN_NORM);
// tune as needed
who.rune2_last_noise_time = time + 1.0;
}
};
float(float damage, entity who) RuneApplyBlack =
{
if (who.rune & ITEM_RUNE2)
return damage*2;
return damage;
};
float(float tvalue, entity who) RuneApplyHell =
{
if (who.rune & ITEM_RUNE3) {
if (who.rune3_last_noise_time < time) {
sound (who, CHAN_ITEM, "runes/end3.wav", 1, ATTN_NORM);
// tune as needed
who.rune3_last_noise_time = time + 1.0;
}
return (tvalue * 2) / 3;
}
return tvalue;
};
void(entity who) RuneApplyElder =
{
if (who.rune & ITEM_RUNE4) {
if (who.rune4_last_regen_time < time && who.health < 100) {
sound (who, CHAN_ITEM, "runes/end4.wav", 1, ATTN_NORM);
who.health = who.health + 5;
if (who.health > 100)
who.health = 100;
who.rune4_last_regen_time = time + 1.0;
}
}
};
float(entity who) RuneHasElder =
{
if (who.rune & ITEM_RUNE4)
return TRUE;
return FALSE;
};
void() RunePrecache =
{
if (cvar("deathmatch"))
if (cvar("gamecfg") & GAMECFG_ENABLE_RUNES) {
precache_model("progs/end1.mdl");
precache_model("progs/end2.mdl");
precache_model("progs/end3.mdl");
precache_model("progs/end4.mdl");
precache_sound("runes/end1.wav");
precache_sound("runes/end2.wav");
precache_sound("runes/end3.wav");
precache_sound("runes/end4.wav");
}
};

239
SHALRATH.QC Normal file
View File

@ -0,0 +1,239 @@
/*
==============================================================================
SHAL-RATH
==============================================================================
*/
$cd /raid/quake/id1/models/shalrath
$origin 0 0 24
$base base
$skin skin
$scale 0.7
$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
$frame attack9 attack10 attack11
$frame pain1 pain2 pain3 pain4 pain5
$frame death1 death2 death3 death4 death5 death6 death7
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
$frame walk11 walk12
void() shalrath_pain;
void() ShalMissile;
void() shal_stand =[ $walk1, shal_stand ] {ai_stand();};
void() shal_walk1 =[ $walk2, shal_walk2 ] {
if (random() < 0.2)
sound (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE);
ai_walk(6);};
void() shal_walk2 =[ $walk3, shal_walk3 ] {ai_walk(4);};
void() shal_walk3 =[ $walk4, shal_walk4 ] {ai_walk(0);};
void() shal_walk4 =[ $walk5, shal_walk5 ] {ai_walk(0);};
void() shal_walk5 =[ $walk6, shal_walk6 ] {ai_walk(0);};
void() shal_walk6 =[ $walk7, shal_walk7 ] {ai_walk(0);};
void() shal_walk7 =[ $walk8, shal_walk8 ] {ai_walk(5);};
void() shal_walk8 =[ $walk9, shal_walk9 ] {ai_walk(6);};
void() shal_walk9 =[ $walk10, shal_walk10 ] {ai_walk(5);};
void() shal_walk10 =[ $walk11, shal_walk11 ] {ai_walk(0);};
void() shal_walk11 =[ $walk12, shal_walk12 ] {ai_walk(4);};
void() shal_walk12 =[ $walk1, shal_walk1 ] {ai_walk(5);};
void() shal_run1 =[ $walk2, shal_run2 ] {
if (random() < 0.2)
sound (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE);
ai_run(6);};
void() shal_run2 =[ $walk3, shal_run3 ] {ai_run(4);};
void() shal_run3 =[ $walk4, shal_run4 ] {ai_run(0);};
void() shal_run4 =[ $walk5, shal_run5 ] {ai_run(0);};
void() shal_run5 =[ $walk6, shal_run6 ] {ai_run(0);};
void() shal_run6 =[ $walk7, shal_run7 ] {ai_run(0);};
void() shal_run7 =[ $walk8, shal_run8 ] {ai_run(5);};
void() shal_run8 =[ $walk9, shal_run9 ] {ai_run(6);};
void() shal_run9 =[ $walk10, shal_run10 ] {ai_run(5);};
void() shal_run10 =[ $walk11, shal_run11 ] {ai_run(0);};
void() shal_run11 =[ $walk12, shal_run12 ] {ai_run(4);};
void() shal_run12 =[ $walk1, shal_run1 ] {ai_run(5);};
void() shal_attack1 =[ $attack1, shal_attack2 ] {
sound (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM);
ai_face();
};
void() shal_attack2 =[ $attack2, shal_attack3 ] {ai_face();};
void() shal_attack3 =[ $attack3, shal_attack4 ] {ai_face();};
void() shal_attack4 =[ $attack4, shal_attack5 ] {ai_face();};
void() shal_attack5 =[ $attack5, shal_attack6 ] {ai_face();};
void() shal_attack6 =[ $attack6, shal_attack7 ] {ai_face();};
void() shal_attack7 =[ $attack7, shal_attack8 ] {ai_face();};
void() shal_attack8 =[ $attack8, shal_attack9 ] {ai_face();};
void() shal_attack9 =[ $attack9, shal_attack10 ] {ShalMissile();};
void() shal_attack10 =[ $attack10, shal_attack11 ] {ai_face();};
void() shal_attack11 =[ $attack11, shal_run1 ] {};
void() shal_pain1 =[ $pain1, shal_pain2 ] {};
void() shal_pain2 =[ $pain2, shal_pain3 ] {};
void() shal_pain3 =[ $pain3, shal_pain4 ] {};
void() shal_pain4 =[ $pain4, shal_pain5 ] {};
void() shal_pain5 =[ $pain5, shal_run1 ] {};
void() shal_death1 =[ $death1, shal_death2 ] {};
void() shal_death2 =[ $death2, shal_death3 ] {};
void() shal_death3 =[ $death3, shal_death4 ] {};
void() shal_death4 =[ $death4, shal_death5 ] {};
void() shal_death5 =[ $death5, shal_death6 ] {};
void() shal_death6 =[ $death6, shal_death7 ] {};
void() shal_death7 =[ $death7, shal_death7 ] {};
void() shalrath_pain =
{
if (self.pain_finished > time)
return;
sound (self, CHAN_VOICE, "shalrath/pain.wav", 1, ATTN_NORM);
shal_pain1();
self.pain_finished = time + 3;
};
void() shalrath_die =
{
// check for gib
if (self.health < -90)
{
sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
ThrowHead ("progs/h_shal.mdl", self.health);
ThrowGib ("progs/gib1.mdl", self.health);
ThrowGib ("progs/gib2.mdl", self.health);
ThrowGib ("progs/gib3.mdl", self.health);
return;
}
sound (self, CHAN_VOICE, "shalrath/death.wav", 1, ATTN_NORM);
shal_death1();
self.solid = SOLID_NOT;
// insert death sounds here
};
/*
================
ShalMissile
================
*/
void() ShalMissileTouch;
void() ShalHome;
void() ShalMissile =
{
local entity missile;
local vector dir;
local float dist, flytime;
dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
dist = vlen (self.enemy.origin - self.origin);
flytime = dist * 0.002;
if (flytime < 0.1)
flytime = 0.1;
self.effects = self.effects | EF_MUZZLEFLASH;
sound (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM);
missile = spawn ();
missile.owner = self;
missile.solid = SOLID_BBOX;
missile.movetype = MOVETYPE_FLYMISSILE;
setmodel (missile, "progs/v_spike.mdl");
setsize (missile, '0 0 0', '0 0 0');
missile.origin = self.origin + '0 0 10';
missile.velocity = dir * 400;
missile.avelocity = '300 300 300';
missile.nextthink = flytime + time;
missile.think = ShalHome;
missile.enemy = self.enemy;
missile.touch = ShalMissileTouch;
};
void() ShalHome =
{
local vector dir, vtemp;
vtemp = self.enemy.origin + '0 0 10';
if (self.enemy.health < 1)
{
remove(self);
return;
}
dir = normalize(vtemp - self.origin);
if (skill == 3)
self.velocity = dir * 350;
else
self.velocity = dir * 250;
self.nextthink = time + 0.2;
self.think = ShalHome;
};
void() ShalMissileTouch =
{
if (other == self.owner)
return; // don't explode on owner
if (other.classname == "monster_zombie")
T_Damage (other, self, self, 110);
T_RadiusDamage (self, self.owner, 40, 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);
self.velocity = '0 0 0';
self.touch = SUB_Null;
setmodel (self, "progs/s_explod.spr");
self.solid = SOLID_NOT;
s_explode1 ();
};
//=================================================================
/*QUAKED monster_shalrath (1 0 0) (-32 -32 -24) (32 32 48) Ambush
*/
void() monster_shalrath =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model2 ("progs/shalrath.mdl");
precache_model2 ("progs/h_shal.mdl");
precache_model2 ("progs/v_spike.mdl");
precache_sound2 ("shalrath/attack.wav");
precache_sound2 ("shalrath/attack2.wav");
precache_sound2 ("shalrath/death.wav");
precache_sound2 ("shalrath/idle.wav");
precache_sound2 ("shalrath/pain.wav");
precache_sound2 ("shalrath/sight.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/shalrath.mdl");
setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
self.health = 400;
self.th_stand = shal_stand;
self.th_walk = shal_walk1;
self.th_run = shal_run1;
self.th_die = shalrath_die;
self.th_pain = shalrath_pain;
self.th_missile = shal_attack1;
self.think = walkmonster_start;
self.nextthink = time + 0.1 + random ()*0.1;
};

367
SHAMBLER.QC Normal file
View File

@ -0,0 +1,367 @@
/*
==============================================================================
SHAMBLER
==============================================================================
*/
$cd /raid/quake/id1/models/shams
$origin 0 0 24
$base base
$skin base
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame stand10 stand11 stand12 stand13 stand14 stand15 stand16 stand17
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7
$frame walk8 walk9 walk10 walk11 walk12
$frame run1 run2 run3 run4 run5 run6
$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7
$frame smash8 smash9 smash10 smash11 smash12
$frame swingr1 swingr2 swingr3 swingr4 swingr5
$frame swingr6 swingr7 swingr8 swingr9
$frame swingl1 swingl2 swingl3 swingl4 swingl5
$frame swingl6 swingl7 swingl8 swingl9
$frame magic1 magic2 magic3 magic4 magic5
$frame magic6 magic7 magic8 magic9 magic10 magic11 magic12
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame death1 death2 death3 death4 death5 death6
$frame death7 death8 death9 death10 death11
void() sham_stand1 =[ $stand1, sham_stand2 ] {ai_stand();};
void() sham_stand2 =[ $stand2, sham_stand3 ] {ai_stand();};
void() sham_stand3 =[ $stand3, sham_stand4 ] {ai_stand();};
void() sham_stand4 =[ $stand4, sham_stand5 ] {ai_stand();};
void() sham_stand5 =[ $stand5, sham_stand6 ] {ai_stand();};
void() sham_stand6 =[ $stand6, sham_stand7 ] {ai_stand();};
void() sham_stand7 =[ $stand7, sham_stand8 ] {ai_stand();};
void() sham_stand8 =[ $stand8, sham_stand9 ] {ai_stand();};
void() sham_stand9 =[ $stand9, sham_stand10] {ai_stand();};
void() sham_stand10 =[ $stand10, sham_stand11] {ai_stand();};
void() sham_stand11 =[ $stand11, sham_stand12] {ai_stand();};
void() sham_stand12 =[ $stand12, sham_stand13] {ai_stand();};
void() sham_stand13 =[ $stand13, sham_stand14] {ai_stand();};
void() sham_stand14 =[ $stand14, sham_stand15] {ai_stand();};
void() sham_stand15 =[ $stand15, sham_stand16] {ai_stand();};
void() sham_stand16 =[ $stand16, sham_stand17] {ai_stand();};
void() sham_stand17 =[ $stand17, sham_stand1 ] {ai_stand();};
void() sham_walk1 =[ $walk1, sham_walk2 ] {ai_walk(10);};
void() sham_walk2 =[ $walk2, sham_walk3 ] {ai_walk(9);};
void() sham_walk3 =[ $walk3, sham_walk4 ] {ai_walk(9);};
void() sham_walk4 =[ $walk4, sham_walk5 ] {ai_walk(5);};
void() sham_walk5 =[ $walk5, sham_walk6 ] {ai_walk(6);};
void() sham_walk6 =[ $walk6, sham_walk7 ] {ai_walk(12);};
void() sham_walk7 =[ $walk7, sham_walk8 ] {ai_walk(8);};
void() sham_walk8 =[ $walk8, sham_walk9 ] {ai_walk(3);};
void() sham_walk9 =[ $walk9, sham_walk10] {ai_walk(13);};
void() sham_walk10 =[ $walk10, sham_walk11] {ai_walk(9);};
void() sham_walk11 =[ $walk11, sham_walk12] {ai_walk(7);};
void() sham_walk12 =[ $walk12, sham_walk1 ] {ai_walk(7);
if (random() > 0.8)
sound (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);};
void() sham_run1 =[ $run1, sham_run2 ] {ai_run(20);};
void() sham_run2 =[ $run2, sham_run3 ] {ai_run(24);};
void() sham_run3 =[ $run3, sham_run4 ] {ai_run(20);};
void() sham_run4 =[ $run4, sham_run5 ] {ai_run(20);};
void() sham_run5 =[ $run5, sham_run6 ] {ai_run(24);};
void() sham_run6 =[ $run6, sham_run1 ] {ai_run(20);
if (random() > 0.8)
sound (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);
};
void() sham_smash1 =[ $smash1, sham_smash2 ] {
sound (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM);
ai_charge(2);};
void() sham_smash2 =[ $smash2, sham_smash3 ] {ai_charge(6);};
void() sham_smash3 =[ $smash3, sham_smash4 ] {ai_charge(6);};
void() sham_smash4 =[ $smash4, sham_smash5 ] {ai_charge(5);};
void() sham_smash5 =[ $smash5, sham_smash6 ] {ai_charge(4);};
void() sham_smash6 =[ $smash6, sham_smash7 ] {ai_charge(1);};
void() sham_smash7 =[ $smash7, sham_smash8 ] {ai_charge(0);};
void() sham_smash8 =[ $smash8, sham_smash9 ] {ai_charge(0);};
void() sham_smash9 =[ $smash9, sham_smash10 ] {ai_charge(0);};
void() sham_smash10 =[ $smash10, sham_smash11 ] {
local vector delta;
local float ldmg;
if (!self.enemy)
return;
ai_charge(0);
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 100)
return;
if (!CanDamage (self.enemy, self))
return;
ldmg = (random() + random() + random()) * 40;
T_Damage (self.enemy, self, self, ldmg);
sound (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM);
SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
};
void() sham_smash11 =[ $smash11, sham_smash12 ] {ai_charge(5);};
void() sham_smash12 =[ $smash12, sham_run1 ] {ai_charge(4);};
void() sham_swingr1;
void(float side) ShamClaw =
{
local vector delta;
local float ldmg;
if (!self.enemy)
return;
ai_charge(10);
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 100)
return;
ldmg = (random() + random() + random()) * 20;
T_Damage (self.enemy, self, self, ldmg);
sound (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM);
if (side)
{
makevectors (self.angles);
SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
}
};
void() sham_swingl1 =[ $swingl1, sham_swingl2 ] {
sound (self, CHAN_VOICE, "shambler/melee2.wav", 1, ATTN_NORM);
ai_charge(5);};
void() sham_swingl2 =[ $swingl2, sham_swingl3 ] {ai_charge(3);};
void() sham_swingl3 =[ $swingl3, sham_swingl4 ] {ai_charge(7);};
void() sham_swingl4 =[ $swingl4, sham_swingl5 ] {ai_charge(3);};
void() sham_swingl5 =[ $swingl5, sham_swingl6 ] {ai_charge(7);};
void() sham_swingl6 =[ $swingl6, sham_swingl7 ] {ai_charge(9);};
void() sham_swingl7 =[ $swingl7, sham_swingl8 ] {ai_charge(5); ShamClaw(250);};
void() sham_swingl8 =[ $swingl8, sham_swingl9 ] {ai_charge(4);};
void() sham_swingl9 =[ $swingl9, sham_run1 ] {
ai_charge(8);
if (random()<0.5)
self.think = sham_swingr1;
};
void() sham_swingr1 =[ $swingr1, sham_swingr2 ] {
sound (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM);
ai_charge(1);};
void() sham_swingr2 =[ $swingr2, sham_swingr3 ] {ai_charge(8);};
void() sham_swingr3 =[ $swingr3, sham_swingr4 ] {ai_charge(14);};
void() sham_swingr4 =[ $swingr4, sham_swingr5 ] {ai_charge(7);};
void() sham_swingr5 =[ $swingr5, sham_swingr6 ] {ai_charge(3);};
void() sham_swingr6 =[ $swingr6, sham_swingr7 ] {ai_charge(6);};
void() sham_swingr7 =[ $swingr7, sham_swingr8 ] {ai_charge(6); ShamClaw(-250);};
void() sham_swingr8 =[ $swingr8, sham_swingr9 ] {ai_charge(3);};
void() sham_swingr9 =[ $swingr9, sham_run1 ] {ai_charge(1);
ai_charge(10);
if (random()<0.5)
self.think = sham_swingl1;
};
void() sham_melee =
{
local float chance;
chance = random();
if (chance > 0.6 || self.health == 600)
sham_smash1 ();
else if (chance > 0.3)
sham_swingr1 ();
else
sham_swingl1 ();
};
//============================================================================
void() CastLightning =
{
local vector org, dir;
self.effects = self.effects | EF_MUZZLEFLASH;
ai_face ();
org = self.origin + '0 0 40';
dir = self.enemy.origin + '0 0 16' - org;
dir = normalize (dir);
traceline (org, self.origin + dir*600, TRUE, self);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
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, self, 10);
};
void() sham_magic1 =[ $magic1, sham_magic2 ] {ai_face();
sound (self, CHAN_WEAPON, "shambler/sattck1.wav", 1, ATTN_NORM);
};
void() sham_magic2 =[ $magic2, sham_magic3 ] {ai_face();};
void() sham_magic3 =[ $magic3, sham_magic4 ] {ai_face();self.nextthink = self.nextthink + 0.2;
local entity o;
self.effects = self.effects | EF_MUZZLEFLASH;
ai_face();
self.owner = spawn();
o = self.owner;
setmodel (o, "progs/s_light.mdl");
setorigin (o, self.origin);
o.angles = self.angles;
o.nextthink = time + 0.7;
o.think = SUB_Remove;
};
void() sham_magic4 =[ $magic4, sham_magic5 ]
{
self.effects = self.effects | EF_MUZZLEFLASH;
self.owner.frame = 1;
};
void() sham_magic5 =[ $magic5, sham_magic6 ]
{
self.effects = self.effects | EF_MUZZLEFLASH;
self.owner.frame = 2;
};
void() sham_magic6 =[ $magic6, sham_magic9 ]
{
remove (self.owner);
CastLightning();
sound (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);
};
void() sham_magic9 =[ $magic9, sham_magic10 ]
{CastLightning();};
void() sham_magic10 =[ $magic10, sham_magic11 ]
{CastLightning();};
void() sham_magic11 =[ $magic11, sham_magic12 ]
{
if (skill == 3)
CastLightning();
};
void() sham_magic12 =[ $magic12, sham_run1 ] {};
void() sham_pain1 =[ $pain1, sham_pain2 ] {};
void() sham_pain2 =[ $pain2, sham_pain3 ] {};
void() sham_pain3 =[ $pain3, sham_pain4 ] {};
void() sham_pain4 =[ $pain4, sham_pain5 ] {};
void() sham_pain5 =[ $pain5, sham_pain6 ] {};
void() sham_pain6 =[ $pain6, sham_run1 ] {};
void(entity attacker, float damage) sham_pain =
{
sound (self, CHAN_VOICE, "shambler/shurt2.wav", 1, ATTN_NORM);
if (self.health <= 0)
return; // allready dying, don't go into pain frame
if (random()*400 > damage)
return; // didn't flinch
if (self.pain_finished > time)
return;
self.pain_finished = time + 2;
sham_pain1 ();
};
//============================================================================
void() sham_death1 =[ $death1, sham_death2 ] {};
void() sham_death2 =[ $death2, sham_death3 ] {};
void() sham_death3 =[ $death3, sham_death4 ] {self.solid = SOLID_NOT;};
void() sham_death4 =[ $death4, sham_death5 ] {};
void() sham_death5 =[ $death5, sham_death6 ] {};
void() sham_death6 =[ $death6, sham_death7 ] {};
void() sham_death7 =[ $death7, sham_death8 ] {};
void() sham_death8 =[ $death8, sham_death9 ] {};
void() sham_death9 =[ $death9, sham_death10 ] {};
void() sham_death10 =[ $death10, sham_death11 ] {};
void() sham_death11 =[ $death11, sham_death11 ] {};
void() sham_die =
{
// check for gib
if (self.health < -60)
{
sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
ThrowHead ("progs/h_shams.mdl", self.health);
ThrowGib ("progs/gib1.mdl", self.health);
ThrowGib ("progs/gib2.mdl", self.health);
ThrowGib ("progs/gib3.mdl", self.health);
return;
}
// regular death
sound (self, CHAN_VOICE, "shambler/sdeath.wav", 1, ATTN_NORM);
sham_death1 ();
};
//============================================================================
/*QUAKED monster_shambler (1 0 0) (-32 -32 -24) (32 32 64) Ambush
*/
void() monster_shambler =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/shambler.mdl");
precache_model ("progs/s_light.mdl");
precache_model ("progs/h_shams.mdl");
precache_model ("progs/bolt.mdl");
precache_sound ("shambler/sattck1.wav");
precache_sound ("shambler/sboom.wav");
precache_sound ("shambler/sdeath.wav");
precache_sound ("shambler/shurt2.wav");
precache_sound ("shambler/sidle.wav");
precache_sound ("shambler/ssight.wav");
precache_sound ("shambler/melee1.wav");
precache_sound ("shambler/melee2.wav");
precache_sound ("shambler/smack.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/shambler.mdl");
setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
self.health = 600;
self.th_stand = sham_stand1;
self.th_walk = sham_walk1;
self.th_run = sham_run1;
self.th_die = sham_die;
self.th_melee = sham_melee;
self.th_missile = sham_magic1;
self.th_pain = sham_pain;
walkmonster_start();
};

103
SHIELD.QC Normal file
View File

@ -0,0 +1,103 @@
// Shield
//
// ===================
// shield_think
// ===================
void() shield_think =
{
if ( self.owner.shield_death_time < time)
{
self.owner.shield_entity = world;
remove (self);
return;
}
if ( (self.owner.shield_death_time - 0.25) <= time)
{
self.model = string_null;
}
else
{
setorigin ( self, self.owner.origin );
self.v_angle = self.owner.v_angle;
self.angles = self.owner.angles;
}
self.think = shield_think;
self.nextthink = time + 0.05;
};
// ===================
// shield_spawn
// ===================
void(entity shieldOwner, vector dir) shield_spawn =
{
local entity newShield;
if ( shieldOwner.shield_death_time > time)
{
return;
}
newShield = spawn ();
newShield.owner = shieldOwner;
newShield.solid = SOLID_NOT;
newShield.takedamage = DAMAGE_NO;
newShield.movetype = MOVETYPE_NONE;
newShield.classname = "power_shield";
// time for shield to live
// shieldOwner.shield_death_time = time + 0.5;
shieldOwner.shield_death_time = time + 0.3;
shieldOwner.shield_entity = newShield;
newShield.v_angle = shieldOwner.v_angle;
newShield.angles = shieldOwner.angles;
setorigin (newShield, shieldOwner.origin);
setmodel (newShield, "progs/p_shield.mdl");
setsize (newShield, '0 0 0', '0 0 0');
newShield.nextthink = time + 0.1;
newShield.think = shield_think;
};
// ===================
// shield_hit
// ===================
float(entity targ, entity inflictor, entity attacker, float damage) shield_hit=
{
local vector dir;
local float save;
local float hitAngle;
dir = inflictor.origin - targ.origin;
save = vectoyaw ( dir );
makevectors (targ.angles);
hitAngle = save - vectoyaw ( v_forward );
if(hitAngle > 90 && hitAngle < 270)
{
return damage;
}
else if(hitAngle < -90 && hitAngle > -270 )
{
return damage;
}
shield_spawn ( targ, dir);
if (targ.shieldSoundTime < time)
{
sound (targ, CHAN_ITEM, "shield/hit.wav", 1, ATTN_NORM);
targ.shieldSoundTime = time + 0.5;
}
if (inflictor.classname == "lava_spike")
save = damage * 0.70;
else
save = damage * 0.30;
return save;
};

284
SOLDIER.QC Normal file
View File

@ -0,0 +1,284 @@
/*
==============================================================================
SOLDIER / PLAYER
==============================================================================
*/
$cd /raid/quake/id1/models/soldier3
$origin 0 -6 24
$base base
$skin skin
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8
$frame death1 death2 death3 death4 death5 death6 death7 death8
$frame death9 death10
$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
$frame deathc9 deathc10 deathc11
$frame load1 load2 load3 load4 load5 load6 load7 load8 load9 load10 load11
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
$frame painb11 painb12 painb13 painb14
$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10
$frame painc11 painc12 painc13
$frame run1 run2 run3 run4 run5 run6 run7 run8
$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 shoot7 shoot8 shoot9
$frame prowl_1 prowl_2 prowl_3 prowl_4 prowl_5 prowl_6 prowl_7 prowl_8
$frame prowl_9 prowl_10 prowl_11 prowl_12 prowl_13 prowl_14 prowl_15 prowl_16
$frame prowl_17 prowl_18 prowl_19 prowl_20 prowl_21 prowl_22 prowl_23 prowl_24
/*
==============================================================================
SOLDIER CODE
==============================================================================
*/
void() army_fire;
void() army_stand1 =[ $stand1, army_stand2 ] {ai_stand();};
void() army_stand2 =[ $stand2, army_stand3 ] {ai_stand();};
void() army_stand3 =[ $stand3, army_stand4 ] {ai_stand();};
void() army_stand4 =[ $stand4, army_stand5 ] {ai_stand();};
void() army_stand5 =[ $stand5, army_stand6 ] {ai_stand();};
void() army_stand6 =[ $stand6, army_stand7 ] {ai_stand();};
void() army_stand7 =[ $stand7, army_stand8 ] {ai_stand();};
void() army_stand8 =[ $stand8, army_stand1 ] {ai_stand();};
void() army_walk1 =[ $prowl_1, army_walk2 ] {
if (random() < 0.2)
sound (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE);
ai_walk(1);};
void() army_walk2 =[ $prowl_2, army_walk3 ] {ai_walk(1);};
void() army_walk3 =[ $prowl_3, army_walk4 ] {ai_walk(1);};
void() army_walk4 =[ $prowl_4, army_walk5 ] {ai_walk(1);};
void() army_walk5 =[ $prowl_5, army_walk6 ] {ai_walk(2);};
void() army_walk6 =[ $prowl_6, army_walk7 ] {ai_walk(3);};
void() army_walk7 =[ $prowl_7, army_walk8 ] {ai_walk(4);};
void() army_walk8 =[ $prowl_8, army_walk9 ] {ai_walk(4);};
void() army_walk9 =[ $prowl_9, army_walk10 ] {ai_walk(2);};
void() army_walk10 =[ $prowl_10, army_walk11 ] {ai_walk(2);};
void() army_walk11 =[ $prowl_11, army_walk12 ] {ai_walk(2);};
void() army_walk12 =[ $prowl_12, army_walk13 ] {ai_walk(1);};
void() army_walk13 =[ $prowl_13, army_walk14 ] {ai_walk(0);};
void() army_walk14 =[ $prowl_14, army_walk15 ] {ai_walk(1);};
void() army_walk15 =[ $prowl_15, army_walk16 ] {ai_walk(1);};
void() army_walk16 =[ $prowl_16, army_walk17 ] {ai_walk(1);};
void() army_walk17 =[ $prowl_17, army_walk18 ] {ai_walk(3);};
void() army_walk18 =[ $prowl_18, army_walk19 ] {ai_walk(3);};
void() army_walk19 =[ $prowl_19, army_walk20 ] {ai_walk(3);};
void() army_walk20 =[ $prowl_20, army_walk21 ] {ai_walk(3);};
void() army_walk21 =[ $prowl_21, army_walk22 ] {ai_walk(2);};
void() army_walk22 =[ $prowl_22, army_walk23 ] {ai_walk(1);};
void() army_walk23 =[ $prowl_23, army_walk24 ] {ai_walk(1);};
void() army_walk24 =[ $prowl_24, army_walk1 ] {ai_walk(1);};
void() army_run1 =[ $run1, army_run2 ] {
if (random() < 0.2)
sound (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE);
ai_run(11);};
void() army_run2 =[ $run2, army_run3 ] {ai_run(15);};
void() army_run3 =[ $run3, army_run4 ] {ai_run(10);};
void() army_run4 =[ $run4, army_run5 ] {ai_run(10);};
void() army_run5 =[ $run5, army_run6 ] {ai_run(8);};
void() army_run6 =[ $run6, army_run7 ] {ai_run(15);};
void() army_run7 =[ $run7, army_run8 ] {ai_run(10);};
void() army_run8 =[ $run8, army_run1 ] {ai_run(8);};
void() army_atk1 =[ $shoot1, army_atk2 ] {ai_face();};
void() army_atk2 =[ $shoot2, army_atk3 ] {ai_face();};
void() army_atk3 =[ $shoot3, army_atk4 ] {ai_face();};
void() army_atk4 =[ $shoot4, army_atk5 ] {ai_face();};
void() army_atk5 =[ $shoot5, army_atk6 ] {ai_face();army_fire();
self.effects = self.effects | EF_MUZZLEFLASH;};
void() army_atk6 =[ $shoot6, army_atk7 ] {ai_face();};
void() army_atk7 =[ $shoot7, army_atk8 ] {ai_face();SUB_CheckRefire (army_atk1);};
void() army_atk8 =[ $shoot8, army_atk9 ] {ai_face();};
void() army_atk9 =[ $shoot9, army_run1 ] {ai_face();};
void() army_pain1 =[ $pain1, army_pain2 ] {};
void() army_pain2 =[ $pain2, army_pain3 ] {};
void() army_pain3 =[ $pain3, army_pain4 ] {};
void() army_pain4 =[ $pain4, army_pain5 ] {};
void() army_pain5 =[ $pain5, army_pain6 ] {};
void() army_pain6 =[ $pain6, army_run1 ] {ai_pain(1);};
void() army_painb1 =[ $painb1, army_painb2 ] {};
void() army_painb2 =[ $painb2, army_painb3 ] {ai_painforward(13);};
void() army_painb3 =[ $painb3, army_painb4 ] {ai_painforward(9);};
void() army_painb4 =[ $painb4, army_painb5 ] {};
void() army_painb5 =[ $painb5, army_painb6 ] {};
void() army_painb6 =[ $painb6, army_painb7 ] {};
void() army_painb7 =[ $painb7, army_painb8 ] {};
void() army_painb8 =[ $painb8, army_painb9 ] {};
void() army_painb9 =[ $painb9, army_painb10] {};
void() army_painb10=[ $painb10, army_painb11] {};
void() army_painb11=[ $painb11, army_painb12] {};
void() army_painb12=[ $painb12, army_painb13] {ai_pain(2);};
void() army_painb13=[ $painb13, army_painb14] {};
void() army_painb14=[ $painb14, army_run1 ] {};
void() army_painc1 =[ $painc1, army_painc2 ] {};
void() army_painc2 =[ $painc2, army_painc3 ] {ai_pain(1);};
void() army_painc3 =[ $painc3, army_painc4 ] {};
void() army_painc4 =[ $painc4, army_painc5 ] {};
void() army_painc5 =[ $painc5, army_painc6 ] {ai_painforward(1);};
void() army_painc6 =[ $painc6, army_painc7 ] {ai_painforward(1);};
void() army_painc7 =[ $painc7, army_painc8 ] {};
void() army_painc8 =[ $painc8, army_painc9 ] {ai_pain(1);};
void() army_painc9 =[ $painc9, army_painc10] {ai_painforward(4);};
void() army_painc10=[ $painc10, army_painc11] {ai_painforward(3);};
void() army_painc11=[ $painc11, army_painc12] {ai_painforward(6);};
void() army_painc12=[ $painc12, army_painc13] {ai_painforward(8);};
void() army_painc13=[ $painc13, army_run1] {};
void(entity attacker, float damage) army_pain =
{
local float r;
if (self.pain_finished > time)
return;
r = random();
if (r < 0.2)
{
self.pain_finished = time + 0.6;
army_pain1 ();
sound (self, CHAN_VOICE, "soldier/pain1.wav", 1, ATTN_NORM);
}
else if (r < 0.6)
{
self.pain_finished = time + 1.1;
army_painb1 ();
sound (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM);
}
else
{
self.pain_finished = time + 1.1;
army_painc1 ();
sound (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM);
}
};
void() army_fire =
{
local vector dir;
local entity en;
ai_face();
sound (self, CHAN_WEAPON, "soldier/sattck1.wav", 1, ATTN_NORM);
// fire somewhat behind the player, so a dodging player is harder to hit
en = self.enemy;
dir = en.origin - en.velocity*0.2;
dir = normalize (dir - self.origin);
FireBullets (4, dir, '0.1 0.1 0');
};
void() army_die1 =[ $death1, army_die2 ] {};
void() army_die2 =[ $death2, army_die3 ] {};
void() army_die3 =[ $death3, army_die4 ]
{self.solid = SOLID_NOT;self.ammo_shells = 5;DropBackpack();};
void() army_die4 =[ $death4, army_die5 ] {};
void() army_die5 =[ $death5, army_die6 ] {};
void() army_die6 =[ $death6, army_die7 ] {};
void() army_die7 =[ $death7, army_die8 ] {};
void() army_die8 =[ $death8, army_die9 ] {};
void() army_die9 =[ $death9, army_die10 ] {};
void() army_die10 =[ $death10, army_die10 ] {};
void() army_cdie1 =[ $deathc1, army_cdie2 ] {};
void() army_cdie2 =[ $deathc2, army_cdie3 ] {ai_back(5);};
void() army_cdie3 =[ $deathc3, army_cdie4 ]
{self.solid = SOLID_NOT;self.ammo_shells = 5;DropBackpack();ai_back(4);};
void() army_cdie4 =[ $deathc4, army_cdie5 ] {ai_back(13);};
void() army_cdie5 =[ $deathc5, army_cdie6 ] {ai_back(3);};
void() army_cdie6 =[ $deathc6, army_cdie7 ] {ai_back(4);};
void() army_cdie7 =[ $deathc7, army_cdie8 ] {};
void() army_cdie8 =[ $deathc8, army_cdie9 ] {};
void() army_cdie9 =[ $deathc9, army_cdie10 ] {};
void() army_cdie10 =[ $deathc10, army_cdie11 ] {};
void() army_cdie11 =[ $deathc11, army_cdie11 ] {};
void() army_die =
{
// check for gib
if (self.health < -35)
{
sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
ThrowHead ("progs/h_guard.mdl", self.health);
ThrowGib ("progs/gib1.mdl", self.health);
ThrowGib ("progs/gib2.mdl", self.health);
ThrowGib ("progs/gib3.mdl", self.health);
return;
}
// regular death
sound (self, CHAN_VOICE, "soldier/death1.wav", 1, ATTN_NORM);
if (random() < 0.5)
army_die1 ();
else
army_cdie1 ();
};
/*QUAKED monster_army (1 0 0) (-16 -16 -24) (16 16 40) Ambush
*/
void() monster_army =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/soldier.mdl");
precache_model ("progs/h_guard.mdl");
precache_model ("progs/gib1.mdl");
precache_model ("progs/gib2.mdl");
precache_model ("progs/gib3.mdl");
precache_sound ("soldier/death1.wav");
precache_sound ("soldier/idle.wav");
precache_sound ("soldier/pain1.wav");
precache_sound ("soldier/pain2.wav");
precache_sound ("soldier/sattck1.wav");
precache_sound ("soldier/sight1.wav");
precache_sound ("player/udeath.wav"); // gib death
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/soldier.mdl");
setsize (self, '-16 -16 -24', '16 16 40');
self.health = 30;
self.th_stand = army_stand1;
self.th_walk = army_walk1;
self.th_run = army_run1;
self.th_missile = army_atk1;
self.th_pain = army_pain;
self.th_die = army_die;
walkmonster_start ();
};

159
SPHERE.QC Normal file
View File

@ -0,0 +1,159 @@
// vengeance sphere
// ==============================
// sphere_impact
// ==============================
void() sphere_impact =
{
if (other.health)
{
T_Damage (other, self, self, 1000 );
}
// don't do radius damage to the other, because all the damage
// was done in the impact
T_RadiusDamage (self, self, 300, other);
// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
self.origin = self.origin - 8*normalize(self.velocity);
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 ();
};
void(entity ownerEntity) sphere_remove =
{
local entity theSphere;
theSphere = find(world, classname, "Vengeance");
while(theSphere != world)
{
if(theSphere.owner == self)
{
bprint ( theSphere.owner.netname );
bprint ( " is denied Vengeance.\n" );
remove (theSphere);
theSphere = find(world, classname, "Vengeance");
}
else
theSphere = find(theSphere, classname, "Vengeance");
}
};
// ==============================
// sphere_attack
// ==============================
void() sphere_attack =
{
self.solid = SOLID_TRIGGER;
self.touch = sphere_impact;
if (self.enemy.health < 1)
{
sprint ( self.owner, "You are denied Vengeance");
remove(self);
return;
}
ai_track(self.enemy, 650);
self.nextthink = time + 0.1;
self.think = sphere_attack;
};
// ==============================
// sphere_think
// ==============================
void() sphere_think =
{
if (self.shieldSoundTime < time)
{
sound ( self, CHAN_VOICE, "sphere/sphere.wav", 1, ATTN_NORM);
self.shieldSoundTime = time + 4;
}
if (time > self.delay)
{
if (self.owner.items2 & IT2_V_SPHERE)
self.owner.items2 = self.owner.items2 - IT2_V_SPHERE;
sprint ( self.owner, "Vengeance Sphere Lost\n");
remove (self);
return;
}
if (self.owner.health < 1)
{
if (self.owner.items2 & IT2_V_SPHERE)
self.owner.items2 = self.owner.items2 - IT2_V_SPHERE;
if ( self.owner.enemy.classname == "player" )
{
self.enemy = self.owner.enemy;
sphere_attack();
return;
}
if ( self.owner.enemy.owner.classname == "player")
{
self.enemy = self.owner.enemy.owner;
sphere_attack();
return;
}
remove (self);
return;
}
ai_orbit(self.owner, 16, '0 0 48');
self.think = sphere_think;
self.nextthink = time + 0.1;
};
// ==============================
// sphere_spawn
// ==============================
void() sphere_spawn =
{
local entity missile;
missile = spawn();
missile.movetype = MOVETYPE_FLYMISSILE;
// missile.solid = SOLID_BBOX;
missile.solid = SOLID_NOT;
missile.classname = "Vengeance";
missile.owner = other;
missile.weapon = 0;
missile.delay = time + 30;
setmodel (missile, "progs/sphere.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin );
missile.avelocity = '40 40 40';
missile.think = sphere_think;
missile.nextthink = time + 0.1;
};
/*QUAKED item_sphere (0 0 1) (-8 -8 -8) (8 8 8) ?
The Vengeance Sphere. DEATHMATCH ONLY.
*/
void() item_sphere =
{
if (!deathmatch)
{
remove(self);
return;
}
precache_model ("progs/sphere.mdl");
precache_sound ("sphere/sphere.wav");
self.noise = "sphere/sphere.wav";
self.netname = "Vengeance Sphere";
self.touch = newitems_touch;
setmodel (self, "progs/sphere.mdl");
setsize (self, '-8 -8 -8', '8 8 8');
self.avelocity = '40 40 40';
StartItem ();
};

26
SPRITES.QC Normal file
View File

@ -0,0 +1,26 @@
// these are the only sprites still in the game...
$spritename s_explod
$type vp_parallel
$load /raid/quake/id1/gfx/sprites/explod03.lbm
$frame 24 24 56 56
$frame 120 24 56 56
$frame 216 24 56 56
$frame 24 88 56 56
$frame 120 88 56 56
$frame 216 88 56 56
$spritename s_bubble
$type vp_parallel
$load /raid/quake/id1/gfx/sprites/bubble.lbm
$frame 16 16 16 16
$frame 40 16 16 16
$spritename s_light
$type vp_parallel
$load /raid/quake/id1/gfx/sprites/light.lbm
$frame 104 32 32 32

316
SUBS.QC Normal file
View File

@ -0,0 +1,316 @@
void() SUB_Null = {};
void() SUB_Remove = {remove(self);};
/*
QuakeEd only writes a single float for angles (bad idea), so up and down are
just constant angles.
*/
vector() SetMovedir =
{
if (self.angles == '0 -1 0')
self.movedir = '0 0 1';
else if (self.angles == '0 -2 0')
self.movedir = '0 0 -1';
else
{
makevectors (self.angles);
self.movedir = v_forward;
}
self.angles = '0 0 0';
};
/*
================
InitTrigger
================
*/
void() InitTrigger =
{
// trigger angles are used for one-way touches. An angle of 0 is assumed
// to mean no restrictions, so use a yaw of 360 instead.
if (self.angles != '0 0 0')
SetMovedir ();
self.solid = SOLID_TRIGGER;
setmodel (self, self.model); // set size and link into world
self.movetype = MOVETYPE_NONE;
self.modelindex = 0;
self.model = "";
};
/*
=============
SUB_CalcMove
calculate self.velocity and self.nextthink to reach dest from
self.origin traveling at speed
===============
*/
void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt =
{
local entity stemp;
stemp = self;
self = ent;
SUB_CalcMove (tdest, tspeed, func);
self = stemp;
};
void(vector tdest, float tspeed, void() func) SUB_CalcMove =
{
local vector vdestdelta;
local float len, traveltime;
if (!tspeed)
objerror("No speed is defined!");
self.think1 = func;
self.finaldest = tdest;
self.think = SUB_CalcMoveDone;
if (tdest == self.origin)
{
self.velocity = '0 0 0';
self.nextthink = self.ltime + 0.1;
return;
}
// set destdelta to the vector needed to move
vdestdelta = tdest - self.origin;
// calculate length of vector
len = vlen (vdestdelta);
// divide by speed to get time to reach dest
traveltime = len / tspeed;
if (traveltime < 0.1)
{
self.velocity = '0 0 0';
self.nextthink = self.ltime + 0.1;
return;
}
// set nextthink to trigger a think when dest is reached
self.nextthink = self.ltime + traveltime;
// scale the destdelta vector by the time spent traveling to get velocity
self.velocity = vdestdelta * (1/traveltime); // qcc won't take vec/float
};
/*
============
After moving, set origin to exact final destination
============
*/
void() SUB_CalcMoveDone =
{
setorigin(self, self.finaldest);
self.velocity = '0 0 0';
self.nextthink = -1;
if (self.think1)
self.think1();
};
/*
=============
SUB_CalcAngleMove
calculate self.avelocity and self.nextthink to reach destangle from
self.angles rotating
The calling function should make sure self.think is valid
===============
*/
void(entity ent, vector destangle, float tspeed, void() func) SUB_CalcAngleMoveEnt =
{
local entity stemp;
stemp = self;
self = ent;
SUB_CalcAngleMove (destangle, tspeed, func);
self = stemp;
};
void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove =
{
local vector destdelta;
local float len, traveltime;
if (!tspeed)
objerror("No speed is defined!");
// set destdelta to the vector needed to move
destdelta = destangle - self.angles;
// calculate length of vector
len = vlen (destdelta);
// divide by speed to get time to reach dest
traveltime = len / tspeed;
// set nextthink to trigger a think when dest is reached
self.nextthink = self.ltime + traveltime;
// scale the destdelta vector by the time spent traveling to get velocity
self.avelocity = destdelta * (1 / traveltime);
self.think1 = func;
self.finalangle = destangle;
self.think = SUB_CalcAngleMoveDone;
};
/*
============
After rotating, set angle to exact final angle
============
*/
void() SUB_CalcAngleMoveDone =
{
self.angles = self.finalangle;
self.avelocity = '0 0 0';
self.nextthink = -1;
if (self.think1)
self.think1();
};
//=============================================================================
void() DelayThink =
{
activator = self.enemy;
SUB_UseTargets ();
remove(self);
};
/*
==============================
SUB_UseTargets
the global "activator" should be set to the entity that initiated the firing.
If self.delay is set, a DelayedUse entity will be created that will actually
do the SUB_UseTargets after that many seconds have passed.
Centerprints any self.message to the activator.
Removes all entities with a targetname that match self.killtarget,
and removes them, so some events can remove other triggers.
Search for (string)targetname in all entities that
match (string)self.target and call their .use function
==============================
*/
void() SUB_UseTargets =
{
local entity t, stemp, otemp, act;
//
// check for a delay
//
if (self.delay)
{
// create a temp object to fire at a later time
t = spawn();
t.classname = "DelayedUse";
t.nextthink = time + self.delay;
t.think = DelayThink;
t.enemy = activator;
t.message = self.message;
t.killtarget = self.killtarget;
t.target = self.target;
return;
}
//
// print the message
//
if (activator.classname == "player" && self.message != "")
{
centerprint (activator, self.message);
if (!self.noise)
sound (activator, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
}
//
// kill the killtagets
//
if (self.killtarget)
{
t = world;
do
{
t = find (t, targetname, self.killtarget);
if (!t)
return;
remove (t);
} while ( 1 );
}
//
// fire targets
//
if (self.target)
{
act = activator;
t = world;
do
{
t = find (t, targetname, self.target);
if (!t)
{
return;
}
stemp = self;
otemp = other;
self = t;
other = stemp;
if (self.use != SUB_Null)
{
if (self.use)
self.use ();
}
self = stemp;
other = otemp;
activator = act;
} while ( 1 );
}
};
/*
in nightmare mode, all attack_finished times become 0
some monsters refire twice automatically
*/
void(float normal) SUB_AttackFinished =
{
self.cnt = 0; // refire count for nightmare
if (skill != 3)
self.attack_finished = time + normal;
};
float (entity targ) visible;
void (void() thinkst) SUB_CheckRefire =
{
if (skill != 3)
return;
if (self.cnt == 1)
return;
if (!visible (self.enemy))
return;
self.cnt = 1;
self.think = thinkst;
};

556
S_WRATH.QC Normal file
View File

@ -0,0 +1,556 @@
// overlord.qc
$skin s_wrtrst
$frame s_wrtfrm
// walk
$frame s_wtwk01 s_wtwk02 s_wtwk03 s_wtwk04 s_wtwk05
$frame s_wtwk06 s_wtwk07 s_wtwk08 s_wtwk09 s_wtwk10
$frame s_wtwk11 s_wtwk12 s_wtwk13 s_wtwk14 s_wtwk15
// hand to hand attacks
$frame s_wtaa01 s_wtaa02 s_wtaa03 s_wtaa04 s_wtaa05
$frame s_wtaa06 s_wtaa07 s_wtaa08 s_wtaa09 s_wtaa10
$frame s_wtab01 s_wtab02 s_wtab03 s_wtab04 s_wtab05
$frame s_wtab06 s_wtab07 s_wtab08 s_wtab09 s_wtab10
$frame s_wtab11 s_wtab12 s_wtab13 s_wtab14
$frame s_wtac01 s_wtac02 s_wtac03 s_wtac04 s_wtac05
$frame s_wtac06 s_wtac07 s_wtac08 s_wtac09 s_wtac10
$frame s_wtac11 s_wtac12 s_wtac13 s_wtac14
// ranged attack
$frame s_wtba01 s_wtba02 s_wtba03 s_wtba04 s_wtba05
$frame s_wtba06 s_wtba07 s_wtba08 s_wtba09 s_wtba10 s_wtba11 s_wtba12
// pain
$frame s_wtpa01 s_wtpa02 s_wtpa03 s_wtpa04 s_wtpa05
$frame s_wtpa06 s_wtpa07 s_wtpa08 s_wtpa09 s_wtpa10
$frame s_wtpa11 s_wtpa12 s_wtpa13 s_wtpa14
$frame s_wtpb01 s_wtpb02 s_wtpb03 s_wtpb04 s_wtpb05
$frame s_wtpb06 s_wtpb07 s_wtpb08 s_wtpb09 s_wtpb10
$frame s_wtpb11
// death
$frame s_wtdt01 s_wtdt02 s_wtdt03 s_wtdt04 s_wtdt05
$frame s_wtdt06 s_wtdt07 s_wtdt08 s_wtdt09 s_wtdt10
$frame s_wtdt11 s_wtdt12 s_wtdt13 s_wtdt14 s_wtdt15
$frame s_wtdt16 s_wtdt17
float(entity thePoint) isSpawnPointEmpty =
{
local entity neighbors;
local entity start;
neighbors = findradius ( thePoint.origin, 64 );
if (neighbors == world)
return 1;
start = neighbors;
while (neighbors)
{
if (neighbors != thePoint)
{
if (neighbors.flags & FL_MONSTER)
{
return 0;
}
else if (neighbors.classname == "player")
{
return 0;
}
else if (neighbors.think)
{
return 0;
}
}
neighbors = neighbors.chain;
if (neighbors == start)
return 1;
}
return 1;
};
entity() overlord_find_dest3 =
{
local entity furthestDest;
local entity bestDest;
local entity curDest;
local entity thePlayer;
local float theDist;
local float curDist;
local float dot;
local vector curVector;
furthestDest = world;
bestDest = world;
theDist=0;
thePlayer=find(world, classname, "player");
curDest=world;
makevectors (thePlayer.angles);
while (1)
{
curDest = find ( curDest, classname, "info_overlord_destination");
if ( curDest == world )
{
if (bestDest != world)
return bestDest;
return furthestDest;
}
if (isSpawnPointEmpty(curDest))
{
curVector = curDest.origin - thePlayer.origin;
curDist = vlen ( curVector );
curVector = normalize (curVector);
dot = curVector * v_forward;
if ( dot > 0.6 )
{
if (curDist > 150)
{
bestDest = curDest;
}
}
if (curDist > theDist )
{
furthestDest = curDest;
theDist = curDist;
}
}
}
// just in case, return the world.
return world;
};
// =======================================================
entity() overlord_find_dest =
{
local entity curDest, lastDest;
local float loopCount;
curDest = find ( world, classname, "info_overlord_destination");
if (curDest != world)
{
lastDest = curDest;
loopCount = random()*5;
while (loopCount > 1)
{
curDest = nextent ( curDest );
curDest = find ( curDest, classname, "info_overlord_destination");
if (curDest != world)
{
if (isSpawnPointEmpty(curDest))
{
loopCount = loopCount - 1;
lastDest = curDest;
}
else
curDest = world;
}
else
{
return lastDest;
}
}
return curDest;
}
return curDest;
};
void() overlord_teleport =
{
local float chance;
local entity theDest;
local vector org;
if (!(self.spawnflags & 2))
return;
chance = random();
if (chance > 0.75)
return;
// theDest = overlord_find_dest();
theDest = overlord_find_dest3();
if (theDest == world)
return;
// put a tfog where the player was
spawn_tfog (self.origin);
// spawn a tfog flash in front of the destination
makevectors (self.angles);
org = theDest.origin + 32 * v_forward;
spawn_tfog (org);
spawn_tdeath(theDest.origin, self);
setorigin (self, theDest.origin);
self.flags = self.flags - self.flags & FL_ONGROUND;
};
// =======================================================
void() overlord_stand1 =[ $s_wtwk01, overlord_stand1 ] { ai_stand();};
void() overlord_walk01 =[ $s_wtwk01, overlord_walk02 ] { ai_walk(8); };
void() overlord_walk02 =[ $s_wtwk02, overlord_walk03 ] { ai_walk(8); };
void() overlord_walk03 =[ $s_wtwk03, overlord_walk04 ] { ai_walk(8); };
void() overlord_walk04 =[ $s_wtwk04, overlord_walk05 ] { ai_walk(8); };
void() overlord_walk05 =[ $s_wtwk05, overlord_walk06 ] { ai_walk(8); };
void() overlord_walk06 =[ $s_wtwk06, overlord_walk07 ] { ai_walk(8); };
void() overlord_walk07 =[ $s_wtwk07, overlord_walk08 ] { ai_walk(8); };
void() overlord_walk08 =[ $s_wtwk08, overlord_walk09 ] { ai_walk(8); };
void() overlord_walk09 =[ $s_wtwk09, overlord_walk10 ] { ai_walk(8); };
void() overlord_walk10 =[ $s_wtwk10, overlord_walk11 ] { ai_walk(8); };
void() overlord_walk11 =[ $s_wtwk11, overlord_walk12 ] { ai_walk(8); };
void() overlord_walk12 =[ $s_wtwk12, overlord_walk13 ] { ai_walk(8); };
void() overlord_walk13 =[ $s_wtwk13, overlord_walk14 ] { ai_walk(8); };
void() overlord_walk14 =[ $s_wtwk14, overlord_walk15 ] { ai_walk(8); };
void() overlord_walk15 =[ $s_wtwk15, overlord_walk01 ] { ai_walk(8); };
void() overlord_run01 =[ $s_wtwk01, overlord_run02 ] { ai_run(12); };
void() overlord_run02 =[ $s_wtwk02, overlord_run03 ] { ai_run(12); };
void() overlord_run03 =[ $s_wtwk03, overlord_run04 ] { ai_run(12); };
void() overlord_run04 =[ $s_wtwk04, overlord_run05 ] { ai_run(12); };
void() overlord_run05 =[ $s_wtwk05, overlord_run06 ] { ai_run(12); };
void() overlord_run06 =[ $s_wtwk06, overlord_run07 ] { ai_run(12); };
void() overlord_run07 =[ $s_wtwk07, overlord_run08 ] { ai_run(12); };
void() overlord_run08 =[ $s_wtwk08, overlord_run09 ] { ai_run(12); };
void() overlord_run09 =[ $s_wtwk09, overlord_run10 ] { ai_run(12); };
void() overlord_run10 =[ $s_wtwk10, overlord_run11 ] { ai_run(12); };
void() overlord_run11 =[ $s_wtwk11, overlord_run12 ] { ai_run(12); };
void() overlord_run12 =[ $s_wtwk12, overlord_run13 ] { ai_run(12); };
void() overlord_run13 =[ $s_wtwk13, overlord_run14 ] { ai_run(12); };
void() overlord_run14 =[ $s_wtwk14, overlord_run15 ] { ai_run(12); };
void() overlord_run15 =[ $s_wtwk15, overlord_run01 ] { ai_run(12); };
// =================================================
// overlord hand-to-hand attack
// =================================================
void() overlord_smash;
void() overlord_at_a01 =[ $s_wtaa01, overlord_at_a02 ] { ai_charge(12);};
void() overlord_at_a02 =[ $s_wtaa02, overlord_at_a03 ] { ai_charge(12);};
void() overlord_at_a03 =[ $s_wtaa03, overlord_at_a04 ] { ai_charge(12);};
void() overlord_at_a04 =[ $s_wtaa04, overlord_at_a05 ] { ai_charge(12);};
void() overlord_at_a05 =[ $s_wtaa05, overlord_at_a06 ] { ai_charge(12);};
void() overlord_at_a06 =[ $s_wtaa06, overlord_at_a07 ] { ai_charge(12);};
void() overlord_at_a07 =[ $s_wtaa07, overlord_at_a08 ] {overlord_smash();};
void() overlord_at_a08 =[ $s_wtaa08, overlord_at_a09 ] { ai_charge(12);};
void() overlord_at_a09 =[ $s_wtaa09, overlord_at_a10 ] { ai_charge(12);};
void() overlord_at_a10 =[ $s_wtaa10, overlord_run01 ] { ai_charge(12);};
void() overlord_at_b01 =[ $s_wtab01, overlord_at_b02 ] { ai_charge(12);};
void() overlord_at_b02 =[ $s_wtab02, overlord_at_b03 ] { ai_charge(12);};
void() overlord_at_b03 =[ $s_wtab03, overlord_at_b04 ] { ai_charge(12);};
void() overlord_at_b04 =[ $s_wtab04, overlord_at_b05 ] { ai_charge(12);};
void() overlord_at_b05 =[ $s_wtab05, overlord_at_b06 ] { ai_charge(12);};
void() overlord_at_b06 =[ $s_wtab06, overlord_at_b07 ] { ai_charge(12);};
void() overlord_at_b07 =[ $s_wtab07, overlord_at_b08 ] { ai_charge(12);};
void() overlord_at_b08 =[ $s_wtab08, overlord_at_b09 ] {overlord_smash();};
void() overlord_at_b09 =[ $s_wtab09, overlord_at_b10 ] { ai_charge(12);};
void() overlord_at_b10 =[ $s_wtab10, overlord_at_b11 ] { ai_charge(12);};
void() overlord_at_b11 =[ $s_wtab11, overlord_at_b12 ] { ai_charge(12);};
void() overlord_at_b12 =[ $s_wtab12, overlord_at_b13 ] { ai_charge(12);};
void() overlord_at_b13 =[ $s_wtab13, overlord_at_b14 ] { ai_charge(12);};
void() overlord_at_b14 =[ $s_wtab14, overlord_run01 ] { ai_charge(12);};
void() overlord_at_c01 =[ $s_wtac01, overlord_at_c02 ] { ai_charge(12);};
void() overlord_at_c02 =[ $s_wtac02, overlord_at_c03 ] { ai_charge(12);};
void() overlord_at_c03 =[ $s_wtac03, overlord_at_c04 ] { ai_charge(12);};
void() overlord_at_c04 =[ $s_wtac04, overlord_at_c05 ] { ai_charge(12);};
void() overlord_at_c05 =[ $s_wtac05, overlord_at_c06 ] { ai_charge(12);};
void() overlord_at_c06 =[ $s_wtac06, overlord_at_c07 ] {overlord_smash();};
void() overlord_at_c07 =[ $s_wtac07, overlord_at_c08 ] { ai_charge(12);};
void() overlord_at_c08 =[ $s_wtac08, overlord_at_c09 ] { ai_charge(12);};
void() overlord_at_c09 =[ $s_wtac09, overlord_at_c10 ] { ai_charge(12);};
void() overlord_at_c10 =[ $s_wtac10, overlord_at_c11 ] { ai_charge(12);};
void() overlord_at_c11 =[ $s_wtac11, overlord_at_c12 ] {overlord_smash();};
void() overlord_at_c12 =[ $s_wtac12, overlord_at_c13 ] { ai_charge(12);};
void() overlord_at_c13 =[ $s_wtac13, overlord_at_c14 ] { ai_charge(12);};
void() overlord_at_c14 =[ $s_wtac14, overlord_run01 ] { ai_charge(12);};
void() overlord_smash =
{
local vector delta;
local float smashDmg;
if (!self.enemy)
return;
if (!CanDamage (self.enemy, self))
return;
ai_charge(10);
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 100)
return;
smashDmg = 20 + random () * 10;
sound (self, CHAN_WEAPON, "s_wrath/smash.wav", 1, ATTN_NORM);
T_Damage (self.enemy, self, self, smashDmg);
delta = normalize (self.enemy.origin - self.origin + self.enemy.view_ofs);
SpawnBlood ( self.enemy.origin - delta * 30, delta * -100, smashDmg);
};
void() overlord_melee =
{
local float r;
r = random();
if (r < 0.33)
{
overlord_at_a01 ();
}
else if (r < 0.66)
{
overlord_at_b01 ();
}
else
{
overlord_at_c01 ();
}
};
// ==================================================
// missile attacks
// ==================================================
void(float AttackNumber) WrathMissile;
void() overlord_msl_a01 =[ $s_wtba01, overlord_msl_a02 ] { ai_charge(12);};
void() overlord_msl_a02 =[ $s_wtba02, overlord_msl_a03 ] { ai_charge(12);};
void() overlord_msl_a03 =[ $s_wtba03, overlord_msl_a04 ] { ai_charge(12);};
void() overlord_msl_a04 =[ $s_wtba04, overlord_msl_a05 ] { ai_charge(12);};
void() overlord_msl_a05 =[ $s_wtba05, overlord_msl_a06 ] { ai_charge(12);};
void() overlord_msl_a06 =[ $s_wtba06, overlord_msl_a07 ] {WrathMissile(4);};
void() overlord_msl_a07 =[ $s_wtba07, overlord_msl_a08 ] { ai_charge(12);};
void() overlord_msl_a08 =[ $s_wtba08, overlord_msl_a09 ] { ai_charge(12);};
void() overlord_msl_a09 =[ $s_wtba09, overlord_msl_a10 ] { ai_charge(12);};
void() overlord_msl_a10 =[ $s_wtba10, overlord_msl_a11 ] { ai_charge(12);};
void() overlord_msl_a11 =[ $s_wtba11, overlord_msl_a12 ] { ai_charge(12);};
void() overlord_msl_a12 =[ $s_wtba12, overlord_run01 ] {overlord_teleport();};
void() overlord_missile =
{
local float r;
r = random();
overlord_msl_a01();
};
// ==================================================
// pain
// ==================================================
void() overlord_pn_a01 =[ $s_wtpa01, overlord_pn_a02 ] {};
void() overlord_pn_a02 =[ $s_wtpa02, overlord_pn_a03 ] {};
void() overlord_pn_a03 =[ $s_wtpa03, overlord_pn_a04 ] {overlord_teleport();};
void() overlord_pn_a04 =[ $s_wtpa04, overlord_pn_a05 ] {};
void() overlord_pn_a05 =[ $s_wtpa05, overlord_pn_a06 ] {};
void() overlord_pn_a06 =[ $s_wtpa06, overlord_pn_a07 ] {};
void() overlord_pn_a07 =[ $s_wtpa07, overlord_run01 ] {};
void() overlord_pn_b01 =[ $s_wtpb01, overlord_pn_b02 ] {};
void() overlord_pn_b02 =[ $s_wtpb02, overlord_pn_b03 ] {};
void() overlord_pn_b03 =[ $s_wtpb03, overlord_pn_b04 ] {overlord_teleport();};
void() overlord_pn_b04 =[ $s_wtpb04, overlord_pn_b05 ] {};
void() overlord_pn_b05 =[ $s_wtpb05, overlord_pn_b06 ] {};
void() overlord_pn_b06 =[ $s_wtpb06, overlord_pn_b07 ] {};
void() overlord_pn_b07 =[ $s_wtpb07, overlord_run01 ] {};
void() overlord_pain =
{
local float r;
if (self.pain_finished > time)
return;
r = random();
if (r > 0.2)
return;
if (r < 0.15)
overlord_pn_a01 ();
else
overlord_pn_b01 ();
self.pain_finished = time + 2;
sound (self, CHAN_VOICE, "wrath/wpain.wav", 1, ATTN_NORM);
};
void(string gibName) ol_toss =
{
local vector flingVelocity;
local entity myGib;
makevectors(self.angles);
flingVelocity = v_forward*250 + v_up*300;
flingVelocity = flingVelocity + v_up * (random() * 100 - 50);
flingVelocity = flingVelocity + v_right * (random() * 200 - 100);
myGib = StartGib (gibName);
myGib.velocity = flingVelocity;
};
// note - death frame 9 is intentionally done twice.
void() overlord_die01 =[ $s_wtdt01, overlord_die02 ] {self.nextthink = time +0.05;};
void() overlord_die02 =[ $s_wtdt02, overlord_die03 ]
{ self.flags = self.flags | FL_FLY; self.nextthink = time +0.05;};
void() overlord_die03 =[ $s_wtdt03, overlord_die04 ] {self.nextthink = time +0.05;};
void() overlord_die04 =[ $s_wtdt04, overlord_die05 ] {self.nextthink = time +0.05;};
void() overlord_die05 =[ $s_wtdt05, overlord_die06 ] {self.nextthink = time +0.05;};
void() overlord_die06 =[ $s_wtdt06, overlord_die07 ] {self.nextthink = time +0.05;};
void() overlord_die07 =[ $s_wtdt07, overlord_die08 ] {self.nextthink = time +0.05;};
void() overlord_die08 =[ $s_wtdt08, overlord_die09 ] {self.nextthink = time +0.05;};
void() overlord_die09 =[ $s_wtdt09, overlord_die10 ] {self.nextthink = time +0.05;};
void() overlord_die10 =[ $s_wtdt09, overlord_die11 ] {self.nextthink = time +0.05;};
void() overlord_die11 =[ $s_wtdt10, overlord_die12 ] {self.nextthink = time +0.05;};
void() overlord_die12 =[ $s_wtdt11, overlord_die13 ] {self.nextthink = time +0.05;};
void() overlord_die13 =[ $s_wtdt12, overlord_die14 ] {self.nextthink = time +0.05;};
void() overlord_die14 =[ $s_wtdt13, overlord_die15 ] {self.nextthink = time +0.05;};
void() overlord_die15 =[ $s_wtdt14, overlord_die16 ] {self.nextthink = time +0.05;};
void() overlord_die16 =[ $s_wtdt15, overlord_die17 ] {self.nextthink = time +0.05;};
void() overlord_die17 =[ $s_wtdt16, overlord_die18 ]
{
self.model = "";
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION2);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
WriteByte (MSG_BROADCAST, 0);
WriteByte (MSG_BROADCAST, 4);
ol_toss("progs/s_wrtgb2.mdl");
ol_toss("progs/s_wrtgb3.mdl");
ol_toss("progs/wrthgib1.mdl");
ol_toss("progs/wrthgib2.mdl");
ol_toss("progs/wrthgib3.mdl");
self.nextthink = time + 0.1;
};
void() overlord_die18 =[ $s_wtdt17, overlord_die19 ]
{
local float counter;
counter = 2;
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION2);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
WriteByte (MSG_BROADCAST, 0);
WriteByte (MSG_BROADCAST, 4);
while(counter>0)
{
ol_toss("progs/gib1.mdl");
ol_toss("progs/gib2.mdl");
ol_toss("progs/gib3.mdl");
counter = counter - 1;
}
self.nextthink = time + 0.1;
};
void() overlord_die19 = [ $s_wtdt17, overlord_die19 ]
{
local float counter;
counter = 2;
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION2);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
WriteByte (MSG_BROADCAST, 0);
WriteByte (MSG_BROADCAST, 4);
while(counter>0)
{
ol_toss("progs/gib1.mdl");
ol_toss("progs/gib2.mdl");
ol_toss("progs/gib3.mdl");
counter = counter - 1;
}
remove(self);
};
/*QUAKED monster_super_wrath (1 0 0) (-16 -16 -24) (16 16 32) Ambush BossMode
The super wrath (Overlord).
BossMode enables the superwrath's powershield and the random teleporting.
*/
void() monster_super_wrath =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/s_wrath.mdl");
// precache_model ("progs/s_wrtgb1.mdl");
precache_model ("progs/s_wrtgb2.mdl");
precache_model ("progs/s_wrtgb3.mdl");
precache_model ("progs/wrthgib1.mdl");
precache_model ("progs/wrthgib2.mdl");
precache_model ("progs/wrthgib3.mdl");
precache_model ("progs/w_ball.mdl");
precache_sound ("wrath/wsee.wav");
precache_sound ("wrath/watt.wav");
precache_sound ("wrath/wpain.wav");
precache_sound ("wrath/wdthc.wav");
precache_sound ("s_wrath/smash.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/s_wrath.mdl");
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
self.health = 1000;
self.pain_finished = 0;
// if(self.spawnflags & 2)
// self.items2 = IT2_SHIELD;
self.th_stand = overlord_stand1;
self.th_walk = overlord_walk01;
self.th_run = overlord_run01;
self.th_missile = overlord_missile;
self.th_melee = overlord_melee;
self.th_pain = overlord_pain;
self.th_die = overlord_die02;
flymonster_start ();
};
/*QUAKED info_overlord_destination (.5 .5 .5) (-8 -8 -8) (8 8 32)
This is the destination marker for the overlord.
It does not require any other fields filled in.
*/
void() info_overlord_destination =
{
// this does nothing, just serves as a target spot
self.mangle = self.angles;
self.angles = '0 0 0';
self.model = "";
self.origin = self.origin + '0 0 27';
};

347
TARBABY.QC Normal file
View File

@ -0,0 +1,347 @@
/*
==============================================================================
BLOB
==============================================================================
*/
$cd /raid/quake/id1/models/tarbaby
$origin 0 0 24
$base base
//$skin skin
$skin base
$skin skin2
$skin skin
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
$frame walk11 walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19
$frame walk20 walk21 walk22 walk23 walk24 walk25
$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12 run13
$frame run14 run15 run16 run17 run18 run19 run20 run21 run22 run23
$frame run24 run25
$frame jump1 jump2 jump3 jump4 jump5 jump6
$frame fly1 fly2 fly3 fly4
$frame exp
void() tbaby_stand1 =[ $walk1, tbaby_stand1 ] {ai_stand();};
void() tbaby_hang1 =[ $walk1, tbaby_hang1 ] {ai_stand();};
void() tbaby_walk1 =[ $walk1, tbaby_walk2 ] {ai_turn();};
void() tbaby_walk2 =[ $walk2, tbaby_walk3 ] {ai_turn();};
void() tbaby_walk3 =[ $walk3, tbaby_walk4 ] {ai_turn();};
void() tbaby_walk4 =[ $walk4, tbaby_walk5 ] {ai_turn();};
void() tbaby_walk5 =[ $walk5, tbaby_walk6 ] {ai_turn();};
void() tbaby_walk6 =[ $walk6, tbaby_walk7 ] {ai_turn();};
void() tbaby_walk7 =[ $walk7, tbaby_walk8 ] {ai_turn();};
void() tbaby_walk8 =[ $walk8, tbaby_walk9 ] {ai_turn();};
void() tbaby_walk9 =[ $walk9, tbaby_walk10 ] {ai_turn();};
void() tbaby_walk10 =[ $walk10, tbaby_walk11 ] {ai_turn();};
void() tbaby_walk11 =[ $walk11, tbaby_walk12 ] {ai_walk(2);};
void() tbaby_walk12 =[ $walk12, tbaby_walk13 ] {ai_walk(2);};
void() tbaby_walk13 =[ $walk13, tbaby_walk14 ] {ai_walk(2);};
void() tbaby_walk14 =[ $walk14, tbaby_walk15 ] {ai_walk(2);};
void() tbaby_walk15 =[ $walk15, tbaby_walk16 ] {ai_walk(2);};
void() tbaby_walk16 =[ $walk16, tbaby_walk17 ] {ai_walk(2);};
void() tbaby_walk17 =[ $walk17, tbaby_walk18 ] {ai_walk(2);};
void() tbaby_walk18 =[ $walk18, tbaby_walk19 ] {ai_walk(2);};
void() tbaby_walk19 =[ $walk19, tbaby_walk20 ] {ai_walk(2);};
void() tbaby_walk20 =[ $walk20, tbaby_walk21 ] {ai_walk(2);};
void() tbaby_walk21 =[ $walk21, tbaby_walk22 ] {ai_walk(2);};
void() tbaby_walk22 =[ $walk22, tbaby_walk23 ] {ai_walk(2);};
void() tbaby_walk23 =[ $walk23, tbaby_walk24 ] {ai_walk(2);};
void() tbaby_walk24 =[ $walk24, tbaby_walk25 ] {ai_walk(2);};
void() tbaby_walk25 =[ $walk25, tbaby_walk1 ] {ai_walk(2);};
void() tbaby_run1 =[ $run1, tbaby_run2 ] {ai_face();};
void() tbaby_run2 =[ $run2, tbaby_run3 ] {ai_face();};
void() tbaby_run3 =[ $run3, tbaby_run4 ] {ai_face();};
void() tbaby_run4 =[ $run4, tbaby_run5 ] {ai_face();};
void() tbaby_run5 =[ $run5, tbaby_run6 ] {ai_face();};
void() tbaby_run6 =[ $run6, tbaby_run7 ] {ai_face();};
void() tbaby_run7 =[ $run7, tbaby_run8 ] {ai_face();};
void() tbaby_run8 =[ $run8, tbaby_run9 ] {ai_face();};
void() tbaby_run9 =[ $run9, tbaby_run10 ] {ai_face();};
void() tbaby_run10 =[ $run10, tbaby_run11 ] {ai_face();};
void() tbaby_run11 =[ $run11, tbaby_run12 ] {ai_run(2);};
void() tbaby_run12 =[ $run12, tbaby_run13 ] {ai_run(2);};
void() tbaby_run13 =[ $run13, tbaby_run14 ] {ai_run(2);};
void() tbaby_run14 =[ $run14, tbaby_run15 ] {ai_run(2);};
void() tbaby_run15 =[ $run15, tbaby_run16 ] {ai_run(2);};
void() tbaby_run16 =[ $run16, tbaby_run17 ] {ai_run(2);};
void() tbaby_run17 =[ $run17, tbaby_run18 ] {ai_run(2);};
void() tbaby_run18 =[ $run18, tbaby_run19 ] {ai_run(2);};
void() tbaby_run19 =[ $run19, tbaby_run20 ] {ai_run(2);};
void() tbaby_run20 =[ $run20, tbaby_run21 ] {ai_run(2);};
void() tbaby_run21 =[ $run21, tbaby_run22 ] {ai_run(2);};
void() tbaby_run22 =[ $run22, tbaby_run23 ] {ai_run(2);};
void() tbaby_run23 =[ $run23, tbaby_run24 ] {ai_run(2);};
void() tbaby_run24 =[ $run24, tbaby_run25 ] {ai_run(2);};
void() tbaby_run25 =[ $run25, tbaby_run1 ] {ai_run(2);};
//============================================================================
void() tbaby_jump1;
void() Tar_JumpTouch =
{
local float ldmg;
if (other.takedamage && other.classname != self.classname)
{
if ( vlen(self.velocity) > 400 )
{
ldmg = 10 + 10*random();
T_Damage (other, self, self, ldmg);
sound (self, CHAN_WEAPON, "blob/hit1.wav", 1, ATTN_NORM);
}
}
else
sound (self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM);
if (!checkbottom(self))
{
if (self.flags & FL_ONGROUND)
{ // jump randomly to not get hung up
//dprint ("popjump\n");
self.touch = SUB_Null;
self.think = tbaby_run1;
self.movetype = MOVETYPE_STEP;
self.nextthink = time + 0.1;
// self.velocity_x = (random() - 0.5) * 600;
// self.velocity_y = (random() - 0.5) * 600;
// self.velocity_z = 200;
// self.flags = self.flags - FL_ONGROUND;
}
return; // not on ground yet
}
self.touch = SUB_Null;
self.think = tbaby_jump1;
self.nextthink = time + 0.1;
};
void() tbaby_jump5;
void() tbaby_fly1 =[ $fly1, tbaby_fly2 ] {};
void() tbaby_fly2 =[ $fly2, tbaby_fly3 ] {};
void() tbaby_fly3 =[ $fly3, tbaby_fly4 ] {};
void() tbaby_fly4 =[ $fly4, tbaby_fly1 ] {
self.cnt = self.cnt + 1;
if (self.cnt == 4)
{
//dprint ("spawn hop\n");
tbaby_jump5 ();
}
};
void() tbaby_jump1 =[ $jump1, tbaby_jump2 ] {ai_face();};
void() tbaby_jump2 =[ $jump2, tbaby_jump3 ] {ai_face();};
void() tbaby_jump3 =[ $jump3, tbaby_jump4 ] {ai_face();};
void() tbaby_jump4 =[ $jump4, tbaby_jump5 ] {ai_face();};
void() tbaby_jump5 =[ $jump5, tbaby_jump6 ]
{
self.movetype = MOVETYPE_BOUNCE;
self.touch = Tar_JumpTouch;
makevectors (self.angles);
self.origin_z = self.origin_z + 1;
self.velocity = v_forward * 600 + '0 0 200';
self.velocity_z = self.velocity_z + random()*150;
if (self.flags & FL_ONGROUND)
self.flags = self.flags - FL_ONGROUND;
self.cnt = 0;
};
void() tbaby_jump6 =[ $jump6,tbaby_fly1 ] {};
//=============================================================================
void() tbaby_die1 =[ $exp, tbaby_die2 ] {
self.takedamage = DAMAGE_NO;
};
void() tbaby_die2 =[ $exp, tbaby_run1 ]
{
T_RadiusDamage (self, self, 120, world);
sound (self, CHAN_VOICE, "blob/death1.wav", 1, ATTN_NORM);
self.origin = self.origin - 8*normalize(self.velocity);
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() tbaby_mitosis;
void() tbaby_checknew =
{
if (!walkmove(0,0))
{
remove(self);
return;
}
self.enemy = self.enemy;
self.th_stand = tbaby_stand1;
self.th_walk = tbaby_walk1;
self.th_run = tbaby_run1;
self.th_missile = tbaby_jump1;
self.th_melee = tbaby_jump1;
self.th_die = tbaby_die1;
self.origin_z = self.origin_z + 1; // raise off floor a bit
droptofloor();
if (!walkmove(0,0))
{
self.owner.th_pain = tbaby_mitosis;
remove(self);
return;
}
self.takedamage = DAMAGE_AIM;
self.ideal_yaw = self.angles * '0 1 0';
if (!self.yaw_speed)
self.yaw_speed = 20;
self.view_ofs = '0 0 25';
self.use = monster_use;
self.flags = self.flags | FL_MONSTER;
self.pausetime = 99999999;
self.th_stand ();
self.nextthink = self.nextthink + random()*0.5;
total_monsters = total_monsters + 1;
WriteByte (MSG_BROADCAST, SVC_UPDATESTAT);
WriteByte (MSG_BROADCAST, STAT_TOTALMONSTERS);
WriteLong (MSG_BROADCAST, total_monsters);
};
void() tbaby_mitosis =
{
local entity newSpawn;
if ( random() < 0.35 )
{
newSpawn = spawn();
newSpawn.classname = self.classname;
newSpawn.movetype = MOVETYPE_STEP;
setsize (newSpawn, '-16 -16 -24', '16 16 40');
newSpawn.health = 80;
if (self.skin == 1)
newSpawn.health = 60;
else if (self.skin == 2)
newSpawn.health = 100;
newSpawn.owner = self;
self.th_pain = SUB_Null;
setmodel (newSpawn, "progs/tarbaby.mdl");
newSpawn.solid = SOLID_SLIDEBOX;
newSpawn.skin = self.skin;
setorigin (newSpawn, self.origin);
newSpawn.think = tbaby_checknew;
newSpawn.nextthink = time + 0.5;
sound (newSpawn, CHAN_VOICE, "blob/mytosis.wav", 1, ATTN_NORM);
}
};
/*QUAKED monster_tarbaby (1 0 0) (-16 -16 -24) (16 16 24) Ambush Blue Green Spots
The Spawn (and hellspawn)
The spawn type is random by default.
If you want a specific type, select "Blue", "Green", or "Spots".
*/
void() monster_tarbaby =
{
local float myRand;
local float skillLevel;
if (deathmatch)
{
remove(self);
return;
}
precache_model2 ("progs/tarbaby.mdl");
precache_sound2 ("blob/death1.wav");
precache_sound2 ("blob/hit1.wav");
precache_sound2 ("blob/land1.wav");
precache_sound2 ("blob/sight1.wav");
precache_sound2 ("blob/mytosis.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/tarbaby.mdl");
setsize (self, '-16 -16 -24', '16 16 40');
self.health = 80;
self.th_stand = tbaby_stand1;
self.th_walk = tbaby_walk1;
self.th_run = tbaby_run1;
self.th_missile = tbaby_jump1;
self.th_melee = tbaby_jump1;
self.th_die = tbaby_die1;
if (self.spawnflags & 8)
{
self.th_pain = tbaby_mitosis;
self.skin = 2;
self.health = 100;
}
else if (self.spawnflags & 4)
{
self.th_pain = tbaby_mitosis;
self.skin = 1;
self.health = 60;
}
else if (self.spawnflags & 2)
{
self.skin = 0;
}
else
{
skillLevel = cvar ( "skill" );
myRand = skillLevel * 0.2;
myRand = myRand + random();
if (myRand > 0.8 && skillLevel > 1)
{
self.th_pain = tbaby_mitosis;
self.skin = 2;
self.health = 100;
}
else if (myRand > 0.5)
{
self.th_pain = tbaby_mitosis;
self.skin = 1;
self.health = 60;
}
else
{
self.skin = 0;
}
}
walkmonster_start ();
};

1887
TEAMPLAY.QC Normal file

File diff suppressed because it is too large Load Diff

223
TIMEMACH.QC Normal file
View File

@ -0,0 +1,223 @@
// timemach.qc
// pmack
// jan97
// ------------------------------------------------
// time machine and related parts
// ------------------------------------------------
void() time_chunk =
{
local entity timeChunk;
timeChunk = spawn();
setmodel(timeChunk, "progs/timegib.mdl");
timeChunk.solid = SOLID_NOT;
timeChunk.movetype = MOVETYPE_TOSS;
makevectors (self.owner.angles);
setorigin ( timeChunk, self.owner.origin + v_forward*84 - v_up * 136);
timeChunk.velocity = v_up * -50;
timeChunk.avelocity = '300 300 300';
timeChunk.angles = self.owner.angles;
sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NONE);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, timeChunk.origin_x);
WriteCoord (MSG_BROADCAST, timeChunk.origin_y);
WriteCoord (MSG_BROADCAST, timeChunk.origin_z);
self.owner.frame = 1;
timeChunk.think = SUB_Remove;
timeChunk.nextthink = time + 5;
};
void() time_stop_shake =
{
SUB_UseTargets();
remove (self);
};
void() time_boom =
{
local entity stopShakeEnt;
SUB_UseTargets();
if(self.owner.health < 1250 && self.owner.frame > 0)
{
if ( self.owner.skin < 2)
{
self.owner.frame = 2;
self.owner.skin = 2;
}
}
else if(self.owner.health < 1500)
{
if ( self.owner.frame == 0 )
{
time_chunk();
self.owner.frame = 1;
self.owner.skin = 1;
}
}
sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NONE);
if (random() < 0.5)
{
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);
}
else
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION2);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
WriteByte (MSG_BROADCAST, 244);
WriteByte (MSG_BROADCAST, 3);
}
BecomeExplosion();
stopShakeEnt = spawn();
stopShakeEnt.target = self.target;
stopShakeEnt.think = time_stop_shake;
stopShakeEnt.nextthink = time + 0.7;
};
void() time_fall =
{
if (!self.pain_finished)
{
if ( self.origin_z < -20 )
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z - 80);
self.pain_finished = 1;
}
else if (random() < 0.3)
{
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);
}
}
self.velocity_z = self.velocity_z - 5;
self.nextthink = time + 0.1;
self.think = time_fall;
};
void() time_crash =
{
self.takedamage = DAMAGE_NO;
self.movetype = MOVETYPE_FLY;
self.solid = SOLID_NOT;
self.velocity = '0 0 -50';
self.avelocity = '15 0 5';
setsize (self, '0 0 0', '0 0 0');
self.think = time_fall;
self.nextthink = time + 0.1;
self.target = "timeramp";
SUB_UseTargets();
};
void(entity attacker, float take) time_pain =
{
local entity painEnt;
local vector painOrg;
local float painRnd;
if ( self.health > 1100 )
if ( self.pain_finished > time )
return;
painRnd = random();
if(painRnd < 0.4)
{
self.pain_finished = time + 2;
painRnd = random();
makevectors ( self.angles );
painEnt = spawn();
if ( painRnd < 0.33 )
painEnt.origin = self.origin + v_forward*80 - v_up*64;
else if (painRnd < 0.66)
painEnt.origin = self.origin + v_right*80 - v_up*24;
else
painEnt.origin = self.origin + v_forward*64 - v_up*48 - v_right*48;
painEnt.target = self.target;
painEnt.owner = self;
painEnt.think = time_boom;
painEnt.nextthink = time + 0.2 + random() * 0.3;
}
if ( self.health < 1000 )
{
self.pain_finished = 0;
self.th_pain = SUB_Null;
self.th_die = SUB_Null;
cutscene_running = 1;
return;
}
};
//(-16 -16 -32) (16 16 0)
/*QUAKED item_time_machine (1 1 0) (-64 -64 -144) (64 64 0)
*/
void() item_time_machine =
{
if (deathmatch)
{
remove (self);
return;
}
precache_model("progs/timemach.mdl");
precache_model("progs/timegib.mdl");
setmodel(self, "progs/timemach.mdl");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
self.health = 1600;
self.takedamage = DAMAGE_YES;
self.view_ofs = '0 0 25';
self.movetype = MOVETYPE_FLY;
setsize(self, '-64 -64 -144', '64 64 0');
self.avelocity = '0 60 0';
self.flags = self.flags | FL_MONSTER;
self.th_stand = SUB_Null;
self.th_walk = SUB_Null;
self.th_run = SUB_Null;
self.th_die = time_pain;
self.th_missile = SUB_Null;
self.th_pain = time_pain;
theMachine = self;
};
/*QUAKED item_time_core (1 0 0) (-8 -8 -8) (8 8 8)
*/
void() item_time_core =
{
if (deathmatch)
{
remove (self);
return;
}
precache_model ("progs/timecore.mdl");
setmodel(self, "progs/timecore.mdl");
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_FLY;
self.avelocity = '60 60 60';
};

675
TRIGGERS.QC Normal file
View File

@ -0,0 +1,675 @@
entity stemp, otemp, s, old;
void() trigger_reactivate =
{
self.solid = SOLID_TRIGGER;
};
//=============================================================================
float SPAWNFLAG_NOMESSAGE = 1;
float SPAWNFLAG_NOTOUCH = 1;
// the wait time has passed, so set back up for another activation
void() multi_wait =
{
if (self.max_health)
{
self.health = self.max_health;
self.takedamage = DAMAGE_YES;
self.solid = SOLID_BBOX;
}
};
// the trigger was just touched/killed/used
// self.enemy should be set to the activator so it can be held through a delay
// so wait for the delay time before firing
void() multi_trigger =
{
if (self.nextthink > time)
{
return; // allready been triggered
}
if (self.classname == "trigger_secret")
{
if (self.enemy.classname != "player")
return;
found_secrets = found_secrets + 1;
WriteByte (MSG_ALL, SVC_FOUNDSECRET);
}
if (self.noise)
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
// don't trigger again until reset
self.takedamage = DAMAGE_NO;
activator = self.enemy;
SUB_UseTargets();
if (self.wait > 0)
{
self.think = multi_wait;
self.nextthink = time + self.wait;
}
else
{ // we can't just remove (self) here, because this is a touch function
// called wheil C code is looping through area links...
self.touch = SUB_Null;
self.nextthink = time + 0.1;
self.think = SUB_Remove;
}
};
void() multi_killed =
{
self.enemy = damage_attacker;
multi_trigger();
};
void() multi_use =
{
self.enemy = activator;
multi_trigger();
};
void() multi_touch =
{
if (other.classname != "player")
return;
// if the trigger has an angles field, check player's facing direction
if (self.movedir != '0 0 0')
{
makevectors (other.angles);
if (v_forward * self.movedir < 0)
return; // not facing the right way
}
self.enemy = other;
multi_trigger ();
};
/*QUAKED trigger_multiple (.5 .5 .5) ? notouch
Variable sized repeatable trigger. Must be targeted at one or more entities. If "health" is set, the trigger must be killed to activate each time.
If "delay" is set, the trigger waits some time after activating before firing.
"wait" : Seconds between triggerings. (.2 default)
If notouch is set, the trigger is only fired by other entities, not by touching.
NOTOUCH has been obsoleted by trigger_relay!
sounds
1) secret
2) beep beep
3) large switch
4)
set "message" to text string
*/
void() trigger_multiple =
{
if (self.sounds == 1)
{
precache_sound ("misc/secret.wav");
self.noise = "misc/secret.wav";
}
else if (self.sounds == 2)
{
precache_sound ("misc/talk.wav");
self.noise = "misc/talk.wav";
}
else if (self.sounds == 3)
{
precache_sound ("misc/trigger1.wav");
self.noise = "misc/trigger1.wav";
}
if (!self.wait)
self.wait = 0.2;
self.use = multi_use;
InitTrigger ();
if (self.health)
{
if (self.spawnflags & SPAWNFLAG_NOTOUCH)
objerror ("health and notouch don't make sense\n");
self.max_health = self.health;
self.th_die = multi_killed;
self.takedamage = DAMAGE_YES;
self.solid = SOLID_BBOX;
setorigin (self, self.origin); // make sure it links into the world
}
else
{
if ( !(self.spawnflags & SPAWNFLAG_NOTOUCH) )
{
self.touch = multi_touch;
}
}
};
/*QUAKED trigger_once (.5 .5 .5) ? notouch
Variable sized trigger. Triggers once, then removes itself. You must set the key "target" to the name of another object in the level that has a matching
"targetname". If "health" is set, the trigger must be killed to activate.
If notouch is set, the trigger is only fired by other entities, not by touching.
if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired.
if "angle" is set, the trigger will only fire when someone is facing the direction of the angle. Use "360" for an angle of 0.
sounds
1) secret
2) beep beep
3) large switch
4)
set "message" to text string
*/
void() trigger_once =
{
self.wait = -1;
trigger_multiple();
};
//=============================================================================
/*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8)
This fixed size trigger cannot be touched, it can only be fired by other events. It can contain killtargets, targets, delays, and messages.
*/
void() trigger_relay =
{
self.use = SUB_UseTargets;
};
//=============================================================================
/*QUAKED trigger_secret (.5 .5 .5) ?
secret counter trigger
sounds
1) secret
2) beep beep
3)
4)
set "message" to text string
*/
void() trigger_secret =
{
total_secrets = total_secrets + 1;
self.wait = -1;
if (!self.message)
self.message = "You found a secret area!";
if (!self.sounds)
self.sounds = 1;
if (self.sounds == 1)
{
precache_sound ("misc/secret.wav");
self.noise = "misc/secret.wav";
}
else if (self.sounds == 2)
{
precache_sound ("misc/talk.wav");
self.noise = "misc/talk.wav";
}
trigger_multiple ();
};
//=============================================================================
void() counter_use =
{
local string junk;
self.count = self.count - 1;
if (self.count < 0)
return;
if (self.count != 0)
{
if (activator.classname == "player"
&& (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
{
if (self.count >= 4)
centerprint (activator, "There are more to go...");
else if (self.count == 3)
centerprint (activator, "Only 3 more to go...");
else if (self.count == 2)
centerprint (activator, "Only 2 more to go...");
else
centerprint (activator, "Only 1 more to go...");
}
return;
}
if (activator.classname == "player"
&& (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
centerprint(activator, "Sequence completed!");
self.enemy = activator;
multi_trigger ();
};
/*QUAKED trigger_counter (.5 .5 .5) ? nomessage
Acts as an intermediary for an action that takes multiple inputs.
If nomessage is not set, t will print "1 more.. " etc when triggered and "sequence complete" when finished.
After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself.
*/
void() trigger_counter =
{
self.wait = -1;
if (!self.count)
self.count = 2;
self.use = counter_use;
};
/*
==============================================================================
TELEPORT TRIGGERS
==============================================================================
*/
float PLAYER_ONLY = 1;
float SILENT = 2;
float CTF_ONLY = 4;
void() play_teleport =
{
local float v;
local string tmpstr;
v = random() * 5;
if (v < 1)
tmpstr = "misc/r_tele1.wav";
else if (v < 2)
tmpstr = "misc/r_tele2.wav";
else if (v < 3)
tmpstr = "misc/r_tele3.wav";
else if (v < 4)
tmpstr = "misc/r_tele4.wav";
else
tmpstr = "misc/r_tele5.wav";
sound (self, CHAN_VOICE, tmpstr, 1, ATTN_NORM);
remove (self);
};
void(vector org) spawn_tfog =
{
s = spawn ();
s.origin = org;
s.nextthink = time + 0.2;
s.think = play_teleport;
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_TELEPORT);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
};
void() tdeath_touch =
{
if (other == self.owner)
return;
// frag anyone who teleports in on top of an invincible player
if (other.classname == "player")
{
if (other.invincible_finished > time)
self.classname = "teledeath2";
if (self.owner.classname != "player")
{ // other monsters explode themselves
T_Damage (self.owner, self, self, 50000);
return;
}
}
if (other.health)
{
T_Damage (other, self, self, 50000);
}
};
void(vector org, entity death_owner) spawn_tdeath =
{
local entity death;
death = spawn();
death.classname = "teledeath";
death.movetype = MOVETYPE_NONE;
death.solid = SOLID_TRIGGER;
death.angles = '0 0 0';
setsize (death, death_owner.mins - '1 1 1', death_owner.maxs + '1 1 1');
setorigin (death, org);
death.touch = tdeath_touch;
death.nextthink = time + 0.2;
death.think = SUB_Remove;
death.owner = death_owner;
force_retouch = 2; // make sure even still objects get hit
};
void() teleport_touch =
{
local entity t;
local vector org;
if (self.targetname)
{
if (self.nextthink < time)
{
return; // not fired yet
}
}
if (self.spawnflags & PLAYER_ONLY)
{
if (other.classname != "player")
return;
}
// only teleport living creatures
if (other.health <= 0 || other.solid != SOLID_SLIDEBOX)
return;
SUB_UseTargets ();
// put a tfog where the player was
spawn_tfog (other.origin);
t = find (world, targetname, self.target);
if (!t)
objerror ("couldn't find target");
// spawn a tfog flash in front of the destination
makevectors (t.mangle);
org = t.origin + 32 * v_forward;
spawn_tfog (org);
spawn_tdeath(t.origin, other);
// move the player and lock him down for a little while
if (!other.health)
{
other.origin = t.origin;
other.velocity = (v_forward * other.velocity_x) + (v_forward * other.velocity_y);
return;
}
setorigin (other, t.origin);
other.angles = t.mangle;
if (other.classname == "player")
{
other.fixangle = 1; // turn this way immediately
other.teleport_time = time + 0.7;
if (other.flags & FL_ONGROUND)
other.flags = other.flags - FL_ONGROUND;
other.velocity = v_forward * 300;
}
other.flags = other.flags - other.flags & FL_ONGROUND;
};
/*QUAKED info_teleport_destination (.5 .5 .5) (-8 -8 -8) (8 8 32)
This is the destination marker for a teleporter. It should have a "targetname" field with the same value as a teleporter's "target" field.
*/
void() info_teleport_destination =
{
// this does nothing, just serves as a target spot
self.mangle = self.angles;
self.angles = '0 0 0';
self.model = "";
self.origin = self.origin + '0 0 27';
if (!self.targetname)
objerror ("no targetname");
};
void() teleport_use =
{
self.nextthink = time + 0.2;
force_retouch = 2; // make sure even still objects get hit
self.think = SUB_Null;
};
/*QUAKED trigger_teleport (.5 .5 .5) ? PLAYER_ONLY SILENT CTF_ONLY
Any object touching this will be transported to the corresponding info_teleport_destination entity. You must set the "target" field, and create an object with a "targetname" field that matches.
If the trigger_teleport has a targetname, it will only teleport entities when it has been fired.
*/
void() trigger_teleport =
{
local vector o;
if (self.spawnflags & CTF_ONLY)
{
if (teamplay < TEAM_CTF || teamplay > TEAM_CTF_ALT)
{
remove (self);
return;
}
}
InitTrigger ();
self.touch = teleport_touch;
// find the destination
if (!self.target)
objerror ("no target");
self.use = teleport_use;
if (!(self.spawnflags & SILENT))
{
precache_sound ("ambience/hum1.wav");
o = (self.mins + self.maxs)*0.5;
ambientsound (o, "ambience/hum1.wav",0.5 , ATTN_STATIC);
}
};
/*
==============================================================================
trigger_setskill
==============================================================================
*/
void() trigger_skill_touch =
{
if (other.classname != "player")
return;
cvar_set ("skill", self.message);
};
/*QUAKED trigger_setskill (.5 .5 .5) ?
sets skill level to the value of "message".
Only used on start map.
*/
void() trigger_setskill =
{
InitTrigger ();
self.touch = trigger_skill_touch;
};
/*
==============================================================================
ONLY REGISTERED TRIGGERS
==============================================================================
*/
void() trigger_onlyregistered_touch =
{
if (other.classname != "player")
return;
if (self.attack_finished > time)
return;
self.attack_finished = time + 2;
if (cvar("registered"))
{
self.message = "";
SUB_UseTargets ();
remove (self);
}
else
{
if (self.message != "")
{
centerprint (other, self.message);
sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
}
}
};
/*QUAKED trigger_onlyregistered (.5 .5 .5) ?
Only fires if playing the registered version, otherwise prints the message
*/
void() trigger_onlyregistered =
{
precache_sound ("misc/talk.wav");
InitTrigger ();
self.touch = trigger_onlyregistered_touch;
};
//============================================================================
void() hurt_on =
{
self.solid = SOLID_TRIGGER;
self.nextthink = -1;
};
void() hurt_touch =
{
if (other.takedamage)
{
self.solid = SOLID_NOT;
T_Damage (other, self, self, self.dmg);
self.think = hurt_on;
self.nextthink = time + 1;
}
return;
};
/*QUAKED trigger_hurt (.5 .5 .5) ?
Any object touching this will be hurt
set dmg to damage amount
defalt dmg = 5
*/
void() trigger_hurt =
{
InitTrigger ();
self.touch = hurt_touch;
if (!self.dmg)
self.dmg = 5;
};
//============================================================================
float PUSH_ONCE = 1;
float PUSH_TOGL = 2;
float PUSH_ACTIVE = 4;
void() trigger_push_touch =
{
if (!(self.spawnflags & PUSH_ACTIVE))
return;
if (other.classname == "grenade")
other.velocity = self.speed * self.movedir * 10;
else if (other.classname == "MiniGrenade")
other.velocity = self.speed * self.movedir * 10;
else if (other.classname == "MultiGrenade")
other.velocity = self.speed * self.movedir * 10;
else if (other.health > 0)
{
other.velocity = self.speed * self.movedir * 10;
if (other.classname == "player")
{
if (other.fly_sound < time)
{
other.fly_sound = time + 1.5;
sound (other, CHAN_AUTO, "ambience/windfly.wav", 1, ATTN_NORM);
}
}
}
if (self.spawnflags & PUSH_ONCE)
remove(self);
};
void() trigger_push_use =
{
if (self.spawnflags & PUSH_ACTIVE)
self.spawnflags = self.spawnflags - PUSH_ACTIVE;
else
self.spawnflags = self.spawnflags + PUSH_ACTIVE;
};
/*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE PUSH_TOGL PUSH_ACTIVE
Pushes the player.
speed: velocity of push. (default 1000)
*/
void() trigger_push =
{
if (self.spawnflags & PUSH_TOGL)
self.use = trigger_push_use;
else
self.spawnflags = self.spawnflags + PUSH_ACTIVE;
InitTrigger ();
precache_sound ("ambience/windfly.wav");
self.touch = trigger_push_touch;
if (!self.speed)
self.speed = 1000;
};
//============================================================================
void() trigger_monsterjump_touch =
{
if ( other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER )
return;
// set XY even if not on ground, so the jump will clear lips
other.velocity_x = self.movedir_x * self.speed;
other.velocity_y = self.movedir_y * self.speed;
if ( !(other.flags & FL_ONGROUND) )
return;
other.flags = other.flags - FL_ONGROUND;
other.velocity_z = self.height;
};
/*QUAKED trigger_monsterjump (.5 .5 .5) ?
Walking monsters that touch this will jump in the direction of the trigger's angle
"speed" default to 200, the speed thrown forward
"height" default to 200, the speed thrown upwards
*/
void() trigger_monsterjump =
{
if (!self.speed)
self.speed = 200;
if (!self.height)
self.height = 200;
if (self.angles == '0 0 0')
self.angles = '0 360 0';
InitTrigger ();
self.touch = trigger_monsterjump_touch;
};

1691
WEAPONS.QC Normal file

File diff suppressed because it is too large Load Diff

410
WIZARD.QC Normal file
View File

@ -0,0 +1,410 @@
/*
==============================================================================
WIZARD
==============================================================================
*/
$cd /raid/quake/id1/models/a_wizard
$origin 0 0 24
$base wizbase
$skin wizbase
$frame hover1 hover2 hover3 hover4 hover5 hover6 hover7 hover8
$frame hover9 hover10 hover11 hover12 hover13 hover14 hover15
$frame fly1 fly2 fly3 fly4 fly5 fly6 fly7 fly8 fly9 fly10
$frame fly11 fly12 fly13 fly14
$frame magatt1 magatt2 magatt3 magatt4 magatt5 magatt6 magatt7
$frame magatt8 magatt9 magatt10 magatt11 magatt12 magatt13
$frame pain1 pain2 pain3 pain4
$frame death1 death2 death3 death4 death5 death6 death7 death8
/*
==============================================================================
WIZARD
If the player moves behind cover before the missile is launched, launch it
at the last visible spot with no velocity leading, in hopes that the player
will duck back out and catch it.
==============================================================================
*/
/*
=============
LaunchMissile
Sets the given entities velocity and angles so that it will hit self.enemy
if self.enemy maintains it's current velocity
0.1 is moderately accurate, 0.0 is totally accurate
=============
*/
void(entity missile, float mspeed, float accuracy) LaunchMissile =
{
local vector vec, move;
local float fly;
makevectors (self.angles);
// set missile speed
vec = self.enemy.origin + self.enemy.mins + self.enemy.size * 0.7 - missile.origin;
// calc aproximate time for missile to reach vec
fly = vlen (vec) / mspeed;
// get the entities xy velocity
move = self.enemy.velocity;
move_z = 0;
// project the target forward in time
vec = vec + move * fly;
vec = normalize(vec);
vec = vec + accuracy*v_up*(random()- 0.5) + accuracy*v_right*(random()- 0.5);
missile.velocity = vec * mspeed;
missile.angles = '0 0 0';
missile.angles_y = vectoyaw(missile.velocity);
// set missile duration
missile.nextthink = time + 5;
missile.think = SUB_Remove;
};
void() wiz_run1;
void() wiz_side1;
/*
=================
WizardCheckAttack
=================
*/
float() WizardCheckAttack =
{
local vector spot1, spot2;
local entity targ;
local float chance;
if (time < self.attack_finished)
return FALSE;
if (!enemy_vis)
return FALSE;
if (enemy_range == RANGE_FAR)
{
if (self.attack_state != AS_STRAIGHT)
{
self.attack_state = AS_STRAIGHT;
wiz_run1 ();
}
return FALSE;
}
targ = self.enemy;
// see if any entities are in the way of the shot
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
traceline (spot1, spot2, FALSE, self);
if (trace_ent != targ)
{ // don't have a clear shot, so move to a side
if (self.attack_state != AS_STRAIGHT)
{
self.attack_state = AS_STRAIGHT;
wiz_run1 ();
}
return FALSE;
}
if (enemy_range == RANGE_MELEE)
chance = 0.9;
else if (enemy_range == RANGE_NEAR)
chance = 0.6;
else if (enemy_range == RANGE_MID)
chance = 0.2;
else
chance = 0;
if (random () < chance)
{
self.attack_state = AS_MISSILE;
return TRUE;
}
if (enemy_range == RANGE_MID)
{
if (self.attack_state != AS_STRAIGHT)
{
self.attack_state = AS_STRAIGHT;
wiz_run1 ();
}
}
else
{
if (self.attack_state != AS_SLIDING)
{
self.attack_state = AS_SLIDING;
wiz_side1 ();
}
}
return FALSE;
};
/*
=================
WizardAttackFinished
=================
*/
float() WizardAttackFinished =
{
if (enemy_range >= RANGE_MID || !enemy_vis)
{
self.attack_state = AS_STRAIGHT;
self.think = wiz_run1;
}
else
{
self.attack_state = AS_SLIDING;
self.think = wiz_side1;
}
};
/*
==============================================================================
FAST ATTACKS
==============================================================================
*/
void() Wiz_FastFire =
{
local vector vec;
local vector dst;
if (self.owner.health > 0)
{
self.owner.effects = self.owner.effects | EF_MUZZLEFLASH;
makevectors (self.enemy.angles);
dst = self.enemy.origin - 13*self.movedir;
vec = normalize(dst - self.origin);
sound (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM);
launch_spike (self.origin, vec);
newmis.velocity = vec*600;
newmis.owner = self.owner;
newmis.classname = "wizspike";
setmodel (newmis, "progs/w_spike.mdl");
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
}
remove (self);
};
void() Wiz_StartFast =
{
local entity missile;
sound (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM);
self.v_angle = self.angles;
makevectors (self.angles);
missile = spawn ();
missile.owner = self;
missile.nextthink = time + 0.6;
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right*14);
missile.enemy = self.enemy;
missile.nextthink = time + 0.8;
missile.think = Wiz_FastFire;
missile.movedir = v_right;
missile = spawn ();
missile.owner = self;
missile.nextthink = time + 1;
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right* -14);
missile.enemy = self.enemy;
missile.nextthink = time + 0.3;
missile.think = Wiz_FastFire;
missile.movedir = VEC_ORIGIN - v_right;
};
void() Wiz_idlesound =
{
local float wr;
wr = random() * 5;
if (self.waitmin < time)
{
self.waitmin = time + 2;
if (wr > 4.5)
sound (self, CHAN_VOICE, "wizard/widle1.wav", 1, ATTN_IDLE);
if (wr < 1.5)
sound (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE);
}
return;
};
void() wiz_stand1 =[ $hover1, wiz_stand2 ] {ai_stand();};
void() wiz_stand2 =[ $hover2, wiz_stand3 ] {ai_stand();};
void() wiz_stand3 =[ $hover3, wiz_stand4 ] {ai_stand();};
void() wiz_stand4 =[ $hover4, wiz_stand5 ] {ai_stand();};
void() wiz_stand5 =[ $hover5, wiz_stand6 ] {ai_stand();};
void() wiz_stand6 =[ $hover6, wiz_stand7 ] {ai_stand();};
void() wiz_stand7 =[ $hover7, wiz_stand8 ] {ai_stand();};
void() wiz_stand8 =[ $hover8, wiz_stand1 ] {ai_stand();};
void() wiz_walk1 =[ $hover1, wiz_walk2 ] {ai_walk(8);
Wiz_idlesound();};
void() wiz_walk2 =[ $hover2, wiz_walk3 ] {ai_walk(8);};
void() wiz_walk3 =[ $hover3, wiz_walk4 ] {ai_walk(8);};
void() wiz_walk4 =[ $hover4, wiz_walk5 ] {ai_walk(8);};
void() wiz_walk5 =[ $hover5, wiz_walk6 ] {ai_walk(8);};
void() wiz_walk6 =[ $hover6, wiz_walk7 ] {ai_walk(8);};
void() wiz_walk7 =[ $hover7, wiz_walk8 ] {ai_walk(8);};
void() wiz_walk8 =[ $hover8, wiz_walk1 ] {ai_walk(8);};
void() wiz_side1 =[ $hover1, wiz_side2 ] {ai_run(8);
Wiz_idlesound();};
void() wiz_side2 =[ $hover2, wiz_side3 ] {ai_run(8);};
void() wiz_side3 =[ $hover3, wiz_side4 ] {ai_run(8);};
void() wiz_side4 =[ $hover4, wiz_side5 ] {ai_run(8);};
void() wiz_side5 =[ $hover5, wiz_side6 ] {ai_run(8);};
void() wiz_side6 =[ $hover6, wiz_side7 ] {ai_run(8);};
void() wiz_side7 =[ $hover7, wiz_side8 ] {ai_run(8);};
void() wiz_side8 =[ $hover8, wiz_side1 ] {ai_run(8);};
void() wiz_run1 =[ $fly1, wiz_run2 ] {ai_run(16);
Wiz_idlesound();
};
void() wiz_run2 =[ $fly2, wiz_run3 ] {ai_run(16);};
void() wiz_run3 =[ $fly3, wiz_run4 ] {ai_run(16);};
void() wiz_run4 =[ $fly4, wiz_run5 ] {ai_run(16);};
void() wiz_run5 =[ $fly5, wiz_run6 ] {ai_run(16);};
void() wiz_run6 =[ $fly6, wiz_run7 ] {ai_run(16);};
void() wiz_run7 =[ $fly7, wiz_run8 ] {ai_run(16);};
void() wiz_run8 =[ $fly8, wiz_run9 ] {ai_run(16);};
void() wiz_run9 =[ $fly9, wiz_run10 ] {ai_run(16);};
void() wiz_run10 =[ $fly10, wiz_run11 ] {ai_run(16);};
void() wiz_run11 =[ $fly11, wiz_run12 ] {ai_run(16);};
void() wiz_run12 =[ $fly12, wiz_run13 ] {ai_run(16);};
void() wiz_run13 =[ $fly13, wiz_run14 ] {ai_run(16);};
void() wiz_run14 =[ $fly14, wiz_run1 ] {ai_run(16);};
void() wiz_fast1 =[ $magatt1, wiz_fast2 ] {ai_face();Wiz_StartFast();};
void() wiz_fast2 =[ $magatt2, wiz_fast3 ] {ai_face();};
void() wiz_fast3 =[ $magatt3, wiz_fast4 ] {ai_face();};
void() wiz_fast4 =[ $magatt4, wiz_fast5 ] {ai_face();};
void() wiz_fast5 =[ $magatt5, wiz_fast6 ] {ai_face();};
void() wiz_fast6 =[ $magatt6, wiz_fast7 ] {ai_face();};
void() wiz_fast7 =[ $magatt5, wiz_fast8 ] {ai_face();};
void() wiz_fast8 =[ $magatt4, wiz_fast9 ] {ai_face();};
void() wiz_fast9 =[ $magatt3, wiz_fast10 ] {ai_face();};
void() wiz_fast10 =[ $magatt2, wiz_run1 ] {ai_face();SUB_AttackFinished(2);WizardAttackFinished ();};
void() wiz_pain1 =[ $pain1, wiz_pain2 ] {};
void() wiz_pain2 =[ $pain2, wiz_pain3 ] {};
void() wiz_pain3 =[ $pain3, wiz_pain4 ] {};
void() wiz_pain4 =[ $pain4, wiz_run1 ] {};
void() wiz_death1 =[ $death1, wiz_death2 ] {
self.velocity_x = -200 + 400*random();
self.velocity_y = -200 + 400*random();
self.velocity_z = 100 + 100*random();
self.flags = self.flags - (self.flags & FL_ONGROUND);
sound (self, CHAN_VOICE, "wizard/wdeath.wav", 1, ATTN_NORM);
};
void() wiz_death2 =[ $death2, wiz_death3 ] {};
void() wiz_death3 =[ $death3, wiz_death4 ]{self.solid = SOLID_NOT;};
void() wiz_death4 =[ $death4, wiz_death5 ] {};
void() wiz_death5 =[ $death5, wiz_death6 ] {};
void() wiz_death6 =[ $death6, wiz_death7 ] {};
void() wiz_death7 =[ $death7, wiz_death8 ] {};
void() wiz_death8 =[ $death8, wiz_death8 ] {};
void() wiz_die =
{
// check for gib
if (self.health < -40)
{
sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
ThrowHead ("progs/h_wizard.mdl", self.health);
ThrowGib ("progs/gib2.mdl", self.health);
ThrowGib ("progs/gib2.mdl", self.health);
ThrowGib ("progs/gib2.mdl", self.health);
return;
}
wiz_death1 ();
};
void(entity attacker, float damage) Wiz_Pain =
{
sound (self, CHAN_VOICE, "wizard/wpain.wav", 1, ATTN_NORM);
if (random()*70 > damage)
return; // didn't flinch
wiz_pain1 ();
};
void() Wiz_Missile =
{
wiz_fast1();
};
/*QUAKED monster_wizard (1 0 0) (-16 -16 -24) (16 16 40) Ambush
*/
void() monster_wizard =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/wizard.mdl");
precache_model ("progs/h_wizard.mdl");
precache_model ("progs/w_spike.mdl");
precache_sound ("wizard/hit.wav"); // used by c code
precache_sound ("wizard/wattack.wav");
precache_sound ("wizard/wdeath.wav");
precache_sound ("wizard/widle1.wav");
precache_sound ("wizard/widle2.wav");
precache_sound ("wizard/wpain.wav");
precache_sound ("wizard/wsight.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/wizard.mdl");
setsize (self, '-16 -16 -24', '16 16 40');
self.health = 80;
self.th_stand = wiz_stand1;
self.th_walk = wiz_walk1;
self.th_run = wiz_run1;
self.th_missile = Wiz_Missile;
self.th_pain = Wiz_Pain;
self.th_die = wiz_die;
flymonster_start ();
};

429
WORLD.QC Normal file
View File

@ -0,0 +1,429 @@
void() InitBodyQue;
void() main =
{
dprint ("main function\n");
// these are just commands the the prog compiler to copy these files
precache_file ("progs.dat");
precache_file ("gfx.wad");
precache_file ("quake.rc");
precache_file ("default.cfg");
precache_file ("end1.bin");
precache_file2 ("end2.bin");
precache_file ("demo1.dem");
precache_file ("demo2.dem");
precache_file ("demo3.dem");
//
// these are all of the lumps from the cached.ls files
//
precache_file ("gfx/palette.lmp");
precache_file ("gfx/colormap.lmp");
precache_file2 ("gfx/pop.lmp");
precache_file ("gfx/complete.lmp");
precache_file ("gfx/inter.lmp");
precache_file ("gfx/ranking.lmp");
precache_file ("gfx/vidmodes.lmp");
precache_file ("gfx/finale.lmp");
precache_file ("gfx/conback.lmp");
precache_file ("gfx/qplaque.lmp");
precache_file ("gfx/menudot1.lmp");
precache_file ("gfx/menudot2.lmp");
precache_file ("gfx/menudot3.lmp");
precache_file ("gfx/menudot4.lmp");
precache_file ("gfx/menudot5.lmp");
precache_file ("gfx/menudot6.lmp");
precache_file ("gfx/menuplyr.lmp");
precache_file ("gfx/bigbox.lmp");
precache_file ("gfx/dim_modm.lmp");
precache_file ("gfx/dim_drct.lmp");
precache_file ("gfx/dim_ipx.lmp");
precache_file ("gfx/dim_tcp.lmp");
precache_file ("gfx/dim_mult.lmp");
precache_file ("gfx/mainmenu.lmp");
precache_file ("gfx/box_tl.lmp");
precache_file ("gfx/box_tm.lmp");
precache_file ("gfx/box_tr.lmp");
precache_file ("gfx/box_ml.lmp");
precache_file ("gfx/box_mm.lmp");
precache_file ("gfx/box_mm2.lmp");
precache_file ("gfx/box_mr.lmp");
precache_file ("gfx/box_bl.lmp");
precache_file ("gfx/box_bm.lmp");
precache_file ("gfx/box_br.lmp");
precache_file ("gfx/sp_menu.lmp");
precache_file ("gfx/ttl_sgl.lmp");
precache_file ("gfx/ttl_main.lmp");
precache_file ("gfx/ttl_cstm.lmp");
precache_file ("gfx/mp_menu.lmp");
precache_file ("gfx/netmen1.lmp");
precache_file ("gfx/netmen2.lmp");
precache_file ("gfx/netmen3.lmp");
precache_file ("gfx/netmen4.lmp");
precache_file ("gfx/netmen5.lmp");
precache_file ("gfx/sell.lmp");
precache_file ("gfx/help0.lmp");
precache_file ("gfx/help1.lmp");
precache_file ("gfx/help2.lmp");
precache_file ("gfx/help3.lmp");
precache_file ("gfx/help4.lmp");
precache_file ("gfx/help5.lmp");
precache_file ("gfx/pause.lmp");
precache_file ("gfx/loading.lmp");
precache_file ("gfx/p_option.lmp");
precache_file ("gfx/p_load.lmp");
precache_file ("gfx/p_save.lmp");
precache_file ("gfx/p_multi.lmp");
// sounds loaded by C code
precache_sound ("misc/menu1.wav");
precache_sound ("misc/menu2.wav");
precache_sound ("misc/menu3.wav");
precache_sound ("ambience/water1.wav");
precache_sound ("ambience/wind2.wav");
// shareware
precache_file ("maps/start.bsp");
precache_file ("maps/e1m1.bsp");
precache_file ("maps/e1m2.bsp");
precache_file ("maps/e1m3.bsp");
precache_file ("maps/e1m4.bsp");
precache_file ("maps/e1m5.bsp");
precache_file ("maps/e1m6.bsp");
precache_file ("maps/e1m7.bsp");
precache_file ("maps/e1m8.bsp");
// registered
precache_file2 ("gfx/pop.lmp");
precache_file2 ("maps/e2m1.bsp");
precache_file2 ("maps/e2m2.bsp");
precache_file2 ("maps/e2m3.bsp");
precache_file2 ("maps/e2m4.bsp");
precache_file2 ("maps/e2m5.bsp");
precache_file2 ("maps/e2m6.bsp");
precache_file2 ("maps/e2m7.bsp");
precache_file2 ("maps/e3m1.bsp");
precache_file2 ("maps/e3m2.bsp");
precache_file2 ("maps/e3m3.bsp");
precache_file2 ("maps/e3m4.bsp");
precache_file2 ("maps/e3m5.bsp");
precache_file2 ("maps/e3m6.bsp");
precache_file2 ("maps/e3m7.bsp");
precache_file2 ("maps/e4m1.bsp");
precache_file2 ("maps/e4m2.bsp");
precache_file2 ("maps/e4m3.bsp");
precache_file2 ("maps/e4m4.bsp");
precache_file2 ("maps/e4m5.bsp");
precache_file2 ("maps/e4m6.bsp");
precache_file2 ("maps/e4m7.bsp");
precache_file2 ("maps/e4m8.bsp");
precache_file2 ("maps/end.bsp");
precache_file2 ("maps/dm1.bsp");
precache_file2 ("maps/dm2.bsp");
precache_file2 ("maps/dm3.bsp");
precache_file2 ("maps/dm4.bsp");
precache_file2 ("maps/dm5.bsp");
precache_file2 ("maps/dm6.bsp");
};
entity lastspawn;
//=======================
/*QUAKED worldspawn (0 0 0) ?
Only used for the world entity.
Set message to the level name.
Set sounds to the cd track to play.
World Types:
0: medieval
1: metal
2: base
*/
//=======================
void() worldspawn =
{
lastspawn = world;
InitBodyQue ();
// custom map attributes
if (self.model == "maps/e1m8.bsp")
cvar_set ("sv_gravity", "100");
else
cvar_set ("sv_gravity", "800");
// the area based ambient sounds MUST be the first precache_sounds
// player precaches
W_Precache (); // get weapon precaches
RunePrecache(); // precache the runes
// sounds used from C physics code
precache_sound ("demon/dland2.wav"); // landing thud
precache_sound ("misc/h2ohit1.wav"); // landing splash
// setup precaches allways needed
precache_sound ("items/itembk2.wav"); // item respawn sound
precache_sound ("player/plyrjmp8.wav"); // player jump
precache_sound ("player/land.wav"); // player landing
precache_sound ("player/land2.wav"); // player hurt landing
precache_sound ("player/drown1.wav"); // drowning pain
precache_sound ("player/drown2.wav"); // drowning pain
precache_sound ("player/gasp1.wav"); // gasping for air
precache_sound ("player/gasp2.wav"); // taking breath
precache_sound ("player/h2odeath.wav"); // drowning death
precache_sound ("misc/talk.wav"); // talk
precache_sound ("player/teledth1.wav"); // telefrag
precache_sound ("misc/r_tele1.wav"); // teleport sounds
precache_sound ("misc/r_tele2.wav");
precache_sound ("misc/r_tele3.wav");
precache_sound ("misc/r_tele4.wav");
precache_sound ("misc/r_tele5.wav");
precache_sound ("weapons/lock4.wav"); // ammo pick up
precache_sound ("weapons/pkup.wav"); // weapon up
precache_sound ("items/armor1.wav"); // armor up
precache_sound ("weapons/lhit.wav"); //lightning
precache_sound ("weapons/lstart.wav"); //lightning start
precache_sound ("items/damage3.wav");
precache_sound ("misc/power.wav"); //lightning for boss
// player gib sounds
precache_sound ("player/gib.wav"); // player gib sound
precache_sound ("player/udeath.wav"); // player gib sound
precache_sound ("player/tornoff2.wav"); // gib sound
// player pain sounds
precache_sound ("player/pain1.wav");
precache_sound ("player/pain2.wav");
precache_sound ("player/pain3.wav");
precache_sound ("player/pain4.wav");
precache_sound ("player/pain5.wav");
precache_sound ("player/pain6.wav");
// player death sounds
precache_sound ("player/death1.wav");
precache_sound ("player/death2.wav");
precache_sound ("player/death3.wav");
precache_sound ("player/death4.wav");
precache_sound ("player/death5.wav");
// ax sounds
precache_sound ("weapons/ax1.wav"); // ax swoosh
precache_sound ("player/axhit1.wav"); // ax hit meat
precache_sound ("player/axhit2.wav"); // ax hit world
precache_sound ("player/h2ojump.wav"); // player jumping into water
precache_sound ("player/slimbrn2.wav"); // player enter slime
precache_sound ("player/inh2o.wav"); // player enter water
precache_sound ("player/inlava.wav"); // player enter lava
precache_sound ("misc/outwater.wav"); // leaving water sound
precache_sound ("player/lburn1.wav"); // lava burn
precache_sound ("player/lburn2.wav"); // lava burn
precache_sound ("misc/water1.wav"); // swimming
precache_sound ("misc/water2.wav"); // swimming
// PGM Addition Sounds
precache_sound ("enforcer/enfstop.wav"); // shield impact
precache_sound ("plasma/explode.wav");
precache_sound ("plasma/flight.wav");
precache_sound ("plasma/fire.wav");
precache_sound ("shield/hit.wav");
precache_sound ("belt/use.wav");
precache_sound ("items/damage2.wav");
precache_model ("progs/player.mdl");
precache_model ("progs/eyes.mdl");
precache_model ("progs/h_player.mdl");
precache_model ("progs/gib1.mdl");
precache_model ("progs/gib2.mdl");
precache_model ("progs/gib3.mdl");
precache_model ("progs/s_bubble.spr"); // drowning bubbles
precache_model ("progs/s_explod.spr"); // sprite explosion
precache_model ("progs/v_axe.mdl");
precache_model ("progs/v_shot.mdl");
precache_model ("progs/v_nail.mdl");
precache_model ("progs/v_rock.mdl");
precache_model ("progs/v_shot2.mdl");
precache_model ("progs/v_nail2.mdl");
precache_model ("progs/v_rock2.mdl");
// Lava Gun models - pgm change
precache_model ("progs/v_lava.mdl");
precache_model ("progs/v_lava2.mdl");
precache_model ("progs/v_multi.mdl");
precache_model ("progs/v_multi2.mdl");
precache_model ("progs/bolt.mdl"); // for lightning gun
precache_model ("progs/bolt2.mdl"); // for lightning gun
precache_model ("progs/bolt3.mdl"); // for boss shock
precache_model ("progs/lavaball.mdl"); // for testing
precache_model ("progs/missile.mdl");
precache_model ("progs/grenade.mdl");
precache_model ("progs/spike.mdl");
precache_model ("progs/s_spike.mdl");
// PGM addition
precache_model ("progs/mervup.mdl");
precache_model ("progs/rockup.mdl");
precache_model ("progs/rockup_d.mdl");
precache_model ("progs/lspike.mdl");
precache_model ("progs/shield.mdl");
precache_model ("progs/p_shield.mdl");
precache_model ("progs/backpack.mdl");
precache_model ("progs/zom_gib.mdl");
precache_model ("progs/v_light.mdl");
precache_model ("progs/plasma.mdl");
precache_model ("progs/v_plasma.mdl");
//ZOID--
// hook for CTF
precache_model ("progs/hook.mdl");
precache_model ("progs/v_grpple.mdl");
// precache_model ("progs/bit.mdl");
//--ZOID
//
// Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
//
// 0 normal
lightstyle(0, "m");
// 1 FLICKER (first variety)
lightstyle(1, "mmnmmommommnonmmonqnmmo");
// 2 SLOW STRONG PULSE
lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
// 3 CANDLE (first variety)
lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
// 4 FAST STROBE
lightstyle(4, "mamamamamama");
// 5 GENTLE PULSE 1
lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");
// 6 FLICKER (second variety)
lightstyle(6, "nmonqnmomnmomomno");
// 7 CANDLE (second variety)
lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm");
// 8 CANDLE (third variety)
lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
// 9 SLOW STROBE (fourth variety)
lightstyle(9, "aaaaaaaazzzzzzzz");
// 10 FLUORESCENT FLICKER
lightstyle(10, "mmamammmmammamamaaamammma");
// 11 SLOW PULSE NOT FADE TO BLACK
lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba");
// styles 32-62 are assigned by the light program for switchable lights
// 63 testing
lightstyle(63, "a");
};
void() StartFrame =
{
teamplay = cvar("teamplay");
skill = cvar("skill");
framecount = framecount + 1;
};
/*
==============================================================================
BODY QUE
==============================================================================
*/
entity bodyque_head;
void() bodyque =
{ // just here so spawn functions don't complain after the world
// creates bodyques
};
void() InitBodyQue =
{
local entity e;
bodyque_head = spawn();
bodyque_head.classname = "bodyque";
bodyque_head.owner = spawn();
bodyque_head.owner.classname = "bodyque";
bodyque_head.owner.owner = spawn();
bodyque_head.owner.owner.classname = "bodyque";
bodyque_head.owner.owner.owner = spawn();
bodyque_head.owner.owner.owner.classname = "bodyque";
bodyque_head.owner.owner.owner.owner = bodyque_head;
};
// make a body que entry for the given ent so the ent can be
// respawned elsewhere
void(entity ent) CopyToBodyQue =
{
// PGM - support for new deathmatch skins on corpses too!
bodyque_head.skin = ent.skin;
bodyque_head.angles = ent.angles;
bodyque_head.model = ent.model;
bodyque_head.modelindex = ent.modelindex;
bodyque_head.frame = ent.frame;
bodyque_head.colormap = ent.colormap;
bodyque_head.movetype = ent.movetype;
bodyque_head.velocity = ent.velocity;
bodyque_head.flags = 0;
setorigin (bodyque_head, ent.origin);
setsize (bodyque_head, ent.mins, ent.maxs);
bodyque_head = bodyque_head.owner;
};

339
WRATH.QC Normal file
View File

@ -0,0 +1,339 @@
// wrath.qc
$skin wrthskin
$frame wrthfrme
$frame wrthwk01 wrthwk02 wrthwk03 wrthwk04 wrthwk05 wrthwk06
$frame wrthwk07 wrthwk08 wrthwk09 wrthwk10 wrthwk11 wrthwk12
$frame wrthaa01 wrthaa02 wrthaa03 wrthaa04 wrthaa05 wrthaa06 wrthaa07
$frame wrthaa08 wrthaa09 wrthaa10 wrthaa11 wrthaa12 wrthaa13 wrthaa14
$frame wrthab01 wrthab02 wrthab03 wrthab04 wrthab05 wrthab06 wrthab07
$frame wrthab08 wrthab09 wrthab10 wrthab11 wrthab12 wrthab13
$frame wrthac01 wrthac02 wrthac03 wrthac04 wrthac05
$frame wrthac06 wrthac07 wrthac08 wrthac09 wrthac10
$frame wrthac11 wrthac12 wrthac13 wrthac14 wrthac15
$frame wrthpa01 wrthpa02 wrthpa03 wrthpa04 wrthpa05 wrthpa06
$frame wrthpb01 wrthpb02 wrthpb03 wrthpb04 wrthpb05 wrthpb06
$frame wrthpb07 wrthpb08 wrthpb09 wrthpb10 wrthpb11
$frame wrthdt01 wrthdt02 wrthdt03 wrthdt04 wrthdt05
$frame wrthdt06 wrthdt07 wrthdt08 wrthdt09 wrthdt10
$frame wrthdt11 wrthdt12 wrthdt13 wrthdt14 wrthdt15
void() WrathMissileTouch;
void() WrathHome;
void(float AttackNumber) WrathMissile;
void() wrath_stand1 =[ $wrthwk01, wrath_stand1 ] { ai_stand();};
void() wrath_walk01 =[ $wrthwk01, wrath_walk02 ] { ai_walk(8); };
void() wrath_walk02 =[ $wrthwk02, wrath_walk03 ] { ai_walk(8); };
void() wrath_walk03 =[ $wrthwk03, wrath_walk04 ] { ai_walk(8); };
void() wrath_walk04 =[ $wrthwk04, wrath_walk05 ] { ai_walk(8); };
void() wrath_walk05 =[ $wrthwk05, wrath_walk06 ] { ai_walk(8); };
void() wrath_walk06 =[ $wrthwk06, wrath_walk07 ] { ai_walk(8); };
void() wrath_walk07 =[ $wrthwk07, wrath_walk08 ] { ai_walk(8); };
void() wrath_walk08 =[ $wrthwk08, wrath_walk09 ] { ai_walk(8); };
void() wrath_walk09 =[ $wrthwk09, wrath_walk10 ] { ai_walk(8); };
void() wrath_walk10 =[ $wrthwk10, wrath_walk11 ] { ai_walk(8); };
void() wrath_walk11 =[ $wrthwk11, wrath_walk12 ] { ai_walk(8); };
void() wrath_walk12 =[ $wrthwk12, wrath_walk01 ] { ai_walk(8); };
void() wrath_run01 =[ $wrthwk01, wrath_run02 ] { ai_run(12); };
void() wrath_run02 =[ $wrthwk02, wrath_run03 ] { ai_run(12); };
void() wrath_run03 =[ $wrthwk03, wrath_run04 ] { ai_run(12); };
void() wrath_run04 =[ $wrthwk04, wrath_run05 ] { ai_run(12); };
void() wrath_run05 =[ $wrthwk05, wrath_run06 ] { ai_run(12); };
void() wrath_run06 =[ $wrthwk06, wrath_run07 ] { ai_run(12); };
void() wrath_run07 =[ $wrthwk07, wrath_run08 ] { ai_run(12); };
void() wrath_run08 =[ $wrthwk08, wrath_run09 ] { ai_run(12); };
void() wrath_run09 =[ $wrthwk09, wrath_run10 ] { ai_run(12); };
void() wrath_run10 =[ $wrthwk10, wrath_run11 ] { ai_run(12); };
void() wrath_run11 =[ $wrthwk11, wrath_run12 ] { ai_run(12); };
void() wrath_run12 =[ $wrthwk12, wrath_run01 ] { ai_run(12); };
void() wrath_at_a01 =[ $wrthaa01, wrath_at_a02 ] {ai_charge(12);};
void() wrath_at_a02 =[ $wrthaa02, wrath_at_a03 ] {ai_charge(12);};
void() wrath_at_a03 =[ $wrthaa03, wrath_at_a04 ] {ai_charge(12);};
void() wrath_at_a04 =[ $wrthaa04, wrath_at_a05 ] {ai_charge(12);};
void() wrath_at_a05 =[ $wrthaa05, wrath_at_a06 ] {ai_charge(12);};
void() wrath_at_a06 =[ $wrthaa06, wrath_at_a07 ] {ai_charge(12);};
void() wrath_at_a07 =[ $wrthaa07, wrath_at_a08 ] {ai_charge(12);};
void() wrath_at_a08 =[ $wrthaa08, wrath_at_a09 ] {ai_charge(12);};
void() wrath_at_a09 =[ $wrthaa09, wrath_at_a10 ] {ai_charge(12);};
void() wrath_at_a10 =[ $wrthaa10, wrath_at_a11 ] {ai_charge(12);};
void() wrath_at_a11 =[ $wrthaa11, wrath_at_a12 ] {WrathMissile(1);};
void() wrath_at_a12 =[ $wrthaa12, wrath_at_a13 ] {ai_charge(12);};
void() wrath_at_a13 =[ $wrthaa13, wrath_at_a14 ] {ai_charge(12);};
void() wrath_at_a14 =[ $wrthaa14, wrath_run01 ] {ai_charge(12);};
void() wrath_at_b01 =[ $wrthab01, wrath_at_b02 ] {ai_charge(12);};
void() wrath_at_b02 =[ $wrthab02, wrath_at_b03 ] {ai_charge(12);};
void() wrath_at_b03 =[ $wrthab03, wrath_at_b04 ] {ai_charge(12);};
void() wrath_at_b04 =[ $wrthab04, wrath_at_b05 ] {ai_charge(12);};
void() wrath_at_b05 =[ $wrthab05, wrath_at_b06 ] {ai_charge(12);};
void() wrath_at_b06 =[ $wrthab06, wrath_at_b07 ] {WrathMissile(2);};
void() wrath_at_b07 =[ $wrthab07, wrath_at_b08 ] {ai_charge(12);};
void() wrath_at_b08 =[ $wrthab08, wrath_at_b09 ] {ai_charge(12);};
void() wrath_at_b09 =[ $wrthab09, wrath_at_b10 ] {ai_charge(12);};
void() wrath_at_b10 =[ $wrthab10, wrath_at_b11 ] {ai_charge(12);};
void() wrath_at_b11 =[ $wrthab11, wrath_at_b12 ] {ai_charge(12);};
void() wrath_at_b12 =[ $wrthab12, wrath_at_b13 ] {ai_charge(12);};
void() wrath_at_b13 =[ $wrthab13, wrath_run01 ] {ai_charge(12);};
void() wrath_at_c01 =[ $wrthac01, wrath_at_c02 ] {ai_charge(12);};
void() wrath_at_c02 =[ $wrthac02, wrath_at_c03 ] {ai_charge(12);};
void() wrath_at_c03 =[ $wrthac03, wrath_at_c04 ] {ai_charge(12);};
void() wrath_at_c04 =[ $wrthac04, wrath_at_c05 ] {ai_charge(12);};
void() wrath_at_c05 =[ $wrthac05, wrath_at_c06 ] {ai_charge(12);};
void() wrath_at_c06 =[ $wrthac06, wrath_at_c07 ] {ai_charge(12);};
void() wrath_at_c07 =[ $wrthac07, wrath_at_c08 ] {WrathMissile(3);};
void() wrath_at_c08 =[ $wrthac08, wrath_at_c09 ] {ai_charge(12);};
void() wrath_at_c09 =[ $wrthac09, wrath_at_c10 ] {ai_charge(12);};
void() wrath_at_c10 =[ $wrthac10, wrath_at_c11 ] {ai_charge(12);};
void() wrath_at_c11 =[ $wrthac11, wrath_at_c12 ] {ai_charge(12);};
void() wrath_at_c12 =[ $wrthac12, wrath_at_c13 ] {ai_charge(12);};
void() wrath_at_c13 =[ $wrthac13, wrath_at_c14 ] {ai_charge(12);};
void() wrath_at_c14 =[ $wrthac14, wrath_at_c15 ] {ai_charge(12);};
void() wrath_at_c15 =[ $wrthac15, wrath_run01 ] {ai_charge(12);};
void() wrath_attack =
{
local float r;
r = random();
if (r < 0.25)
{
wrath_at_a01 ();
}
else if (r < 0.65)
{
wrath_at_b01 ();
}
else
{
wrath_at_c01 ();
}
sound (self, CHAN_VOICE, "wrath/watt.wav", 1, ATTN_NORM);
};
void() wrath_pn_a01 =[ $wrthpa01, wrath_pn_a02 ] {};
void() wrath_pn_a02 =[ $wrthpa02, wrath_pn_a03 ] {};
void() wrath_pn_a03 =[ $wrthpa03, wrath_pn_a04 ] {};
void() wrath_pn_a04 =[ $wrthpa04, wrath_pn_a05 ] {};
void() wrath_pn_a05 =[ $wrthpa05, wrath_pn_a06 ] {};
void() wrath_pn_a06 =[ $wrthpa06, wrath_run01 ] {};
void() wrath_pn_b01 =[ $wrthpb01, wrath_pn_b02 ] {};
void() wrath_pn_b02 =[ $wrthpb02, wrath_pn_b03 ] {};
void() wrath_pn_b03 =[ $wrthpb03, wrath_pn_b04 ] {};
void() wrath_pn_b04 =[ $wrthpb04, wrath_pn_b05 ] {};
void() wrath_pn_b05 =[ $wrthpb05, wrath_pn_b06 ] {};
void() wrath_pn_b06 =[ $wrthpb06, wrath_pn_b07 ] {};
void() wrath_pn_b07 =[ $wrthpb07, wrath_pn_b08 ] {};
void() wrath_pn_b08 =[ $wrthpb08, wrath_pn_b09 ] {};
void() wrath_pn_b09 =[ $wrthpb09, wrath_pn_b10 ] {};
void() wrath_pn_b10 =[ $wrthpb10, wrath_pn_b11 ] {};
void() wrath_pn_b11 =[ $wrthpb11, wrath_run01 ] {};
void() wrath_pain =
{
local float r;
if (self.pain_finished > time)
return;
r = random();
if (r > 0.1)
{
self.pain_finished = time + 0.5;
return;
}
if (r < 0.07)
wrath_pn_a01 ();
else
wrath_pn_b01 ();
self.pain_finished = time + 3;
sound (self, CHAN_VOICE, "wrath/wpain.wav", 1, ATTN_NORM);
};
void() wrath_die02 =[ $wrthdt02, wrath_die03 ]
{ sound (self, CHAN_VOICE, "wrath/wdthc.wav", 1, ATTN_NORM); };
void() wrath_die03 =[ $wrthdt03, wrath_die04 ] {};
void() wrath_die04 =[ $wrthdt04, wrath_die05 ] {};
void() wrath_die05 =[ $wrthdt05, wrath_die07 ] {};
void() wrath_die07 =[ $wrthdt07, wrath_die09 ] {};
void() wrath_die09 =[ $wrthdt09, wrath_die11 ] {};
void() wrath_die11 =[ $wrthdt11, wrath_die13 ] {};
void() wrath_die13 =[ $wrthdt13, wrath_die15 ] {};
void() wrath_die15 =[ $wrthdt15, wrath_die15 ]
{
ThrowGib ("progs/wrthgib1.mdl", self.health);
ThrowGib ("progs/wrthgib2.mdl", self.health);
ThrowGib ("progs/wrthgib3.mdl", self.health);
T_RadiusDamage (self, self, 80, world);
self.origin = self.origin + '0 0 24';
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION2);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
WriteByte (MSG_BROADCAST, 0);
WriteByte (MSG_BROADCAST, 4);
remove (self);
};
/*QUAKED monster_wrath (1 0 0) (-16 -16 -24) (16 16 32) Ambush
*/
void() monster_wrath =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/wrath.mdl");
precache_model ("progs/w_ball.mdl");
precache_model ("progs/wrthgib1.mdl");
precache_model ("progs/wrthgib2.mdl");
precache_model ("progs/wrthgib3.mdl");
precache_sound ("wrath/wsee.wav");
precache_sound ("wrath/watt.wav");
precache_sound ("wrath/wpain.wav");
precache_sound ("wrath/wdthc.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/wrath.mdl");
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
self.health = 400;
self.yaw_speed = 35;
self.th_stand = wrath_stand1;
self.th_walk = wrath_walk01;
self.th_run = wrath_run01;
self.th_missile = wrath_attack;
self.th_pain = wrath_pain;
self.th_die = wrath_die02;
flymonster_start ();
};
/*
================
WrathMissile
================
*/
void(float AttackNumber) WrathMissile =
{
local entity missile;
local vector dir, org;
local float dist, flytime;
dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
dist = vlen (self.enemy.origin - self.origin);
flytime = dist * 0.002;
if (flytime < 0.1)
flytime = 0.1;
self.effects = self.effects | EF_MUZZLEFLASH;
makevectors (self.angles);
missile = spawn ();
missile.owner = self;
missile.solid = SOLID_BBOX;
missile.movetype = MOVETYPE_FLYMISSILE;
setmodel (missile, "progs/w_ball.mdl");
setsize (missile, '0 0 0', '0 0 0');
if ( AttackNumber == 1)
{
org = self.origin + v_forward*20 + v_up*12; // 20 // 44;
}
else if ( AttackNumber == 2)
{
org = self.origin + v_forward*18 + v_up*10; // 18 // 42;
}
else if ( AttackNumber == 3)
{
org = self.origin + v_forward*12 + v_up*12 + v_right*20; // up20
}
else if ( AttackNumber == 4)
{
org = self.origin + v_forward*20 + v_up*16;
}
setorigin ( missile, org );
missile.velocity = dir * 400;
missile.avelocity = '300 300 300';
missile.enemy = self.enemy;
missile.touch = WrathMissileTouch;
missile.nextthink = time + 0.1;
missile.think = WrathHome;
self.attack_finished = time + 2;
};
void() WrathHome =
{
if (self.enemy.health < 1)
{
remove(self);
return;
}
if (skill == 3)
ai_track (self.enemy, 550);
else
ai_track (self.enemy, 400);
self.nextthink = time + 0.1;
self.think = WrathHome;
};
void() WrathMissileTouch =
{
if (other == self.owner ||
other.classname == "monster_wrath" ||
other.classname == "monster_super_wrath")
{
remove(self);
return; // don't explode on any wraths
}
if (other.classname == "monster_zombie")
T_Damage (other, self, self, 110);
T_RadiusDamage (self, self.owner, 20, 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);
self.velocity = '0 0 0';
self.touch = SUB_Null;
setmodel (self, "progs/s_explod.spr");
self.solid = SOLID_NOT;
s_explode1 ();
};

681
ZOMBIE.QC Normal file
View File

@ -0,0 +1,681 @@
/*
==============================================================================
ZOMBIE
==============================================================================
*/
$cd /raid/quake/id1/models/zombie
$origin 0 0 24
$base base
$skin skin
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8
$frame stand9 stand10 stand11 stand12 stand13 stand14 stand15
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 walk11
$frame walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19
$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12
$frame run13 run14 run15 run16 run17 run18
$frame atta1 atta2 atta3 atta4 atta5 atta6 atta7 atta8 atta9 atta10 atta11
$frame atta12 atta13
$frame attb1 attb2 attb3 attb4 attb5 attb6 attb7 attb8 attb9 attb10 attb11
$frame attb12 attb13 attb14
$frame attc1 attc2 attc3 attc4 attc5 attc6 attc7 attc8 attc9 attc10 attc11
$frame attc12
$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10
$frame paina11 paina12
$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
$frame painb11 painb12 painb13 painb14 painb15 painb16 painb17 painb18 painb19
$frame painb20 painb21 painb22 painb23 painb24 painb25 painb26 painb27 painb28
$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10
$frame painc11 painc12 painc13 painc14 painc15 painc16 painc17 painc18
$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10
$frame paind11 paind12 paind13
$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10
$frame paine11 paine12 paine13 paine14 paine15 paine16 paine17 paine18 paine19
$frame paine20 paine21 paine22 paine23 paine24 paine25 paine26 paine27 paine28
$frame paine29 paine30
$frame cruc_1 cruc_2 cruc_3 cruc_4 cruc_5 cruc_6 cruc_7
$frame cruc_8 cruc_9 cruc_10 cruc_11 cruc_12 cruc_13
$frame cruc_14 cruc_15 cruc_16
float SPAWN_CRUCIFIED = 1;
float SPAWN_LYING = 2;
float SPAWN_AMBUSH = 4;
float SPAWN_SNEAKY = 8;
//=============================================================================
.float inpain;
void() zombie_escape1;
void() zombie_stand1 =[ $stand1, zombie_stand2 ] {ai_stand();};
void() zombie_stand2 =[ $stand2, zombie_stand3 ] {ai_stand();};
void() zombie_stand3 =[ $stand3, zombie_stand4 ] {ai_stand();};
void() zombie_stand4 =[ $stand4, zombie_stand5 ] {ai_stand();};
void() zombie_stand5 =[ $stand5, zombie_stand6 ] {ai_stand();};
void() zombie_stand6 =[ $stand6, zombie_stand7 ] {ai_stand();};
void() zombie_stand7 =[ $stand7, zombie_stand8 ] {ai_stand();};
void() zombie_stand8 =[ $stand8, zombie_stand9 ] {ai_stand();};
void() zombie_stand9 =[ $stand9, zombie_stand10 ] {ai_stand();};
void() zombie_stand10 =[ $stand10, zombie_stand11 ] {ai_stand();};
void() zombie_stand11 =[ $stand11, zombie_stand12 ] {ai_stand();};
void() zombie_stand12 =[ $stand12, zombie_stand13 ] {ai_stand();};
void() zombie_stand13 =[ $stand13, zombie_stand14 ] {ai_stand();};
void() zombie_stand14 =[ $stand14, zombie_stand15 ] {ai_stand();};
void() zombie_stand15 =[ $stand15, zombie_stand1 ] {ai_stand();};
// zombie_lurk is an improved version of what zombie did in zombie_crucXX
// with an added check for enemies if they're sneaky types...
void() zombie_lurk =
{
if (self.spawnflags & SPAWN_SNEAKY)
{
// not pausing before attack, but looking for player.
if (!self.pain_finished)
{
if(FindTarget ())
return;
}
else
{
// if we've waited long enough, pounce!
if ( self.pain_finished < time )
{
self.think = zombie_escape1;
self.nextthink = time + 0.1;
return;
}
}
}
self.nextthink = time + 0.1 + random()*0.1;
};
void() zombie_cruc1 = [ $cruc_1, zombie_cruc2 ]
{
zombie_lurk();
if (random() < 0.1)
sound (self, CHAN_VOICE, "zombie/idle_w2.wav", 1, ATTN_STATIC);
};
void() zombie_cruc2 = [ $cruc_2, zombie_cruc3 ] { zombie_lurk(); };
void() zombie_cruc3 = [ $cruc_3, zombie_cruc4 ] { zombie_lurk(); };
void() zombie_cruc4 = [ $cruc_4, zombie_cruc5 ] { zombie_lurk(); };
void() zombie_cruc5 = [ $cruc_5, zombie_cruc6 ] { zombie_lurk(); };
void() zombie_cruc6 = [ $cruc_6, zombie_cruc1 ] { zombie_lurk(); };
void() zombie_walk1 =[ $walk1, zombie_walk2 ] {ai_walk(0);};
void() zombie_walk2 =[ $walk2, zombie_walk3 ] {ai_walk(2);};
void() zombie_walk3 =[ $walk3, zombie_walk4 ] {ai_walk(3);};
void() zombie_walk4 =[ $walk4, zombie_walk5 ] {ai_walk(2);};
void() zombie_walk5 =[ $walk5, zombie_walk6 ] {ai_walk(1);};
void() zombie_walk6 =[ $walk6, zombie_walk7 ] {ai_walk(0);};
void() zombie_walk7 =[ $walk7, zombie_walk8 ] {ai_walk(0);};
void() zombie_walk8 =[ $walk8, zombie_walk9 ] {ai_walk(0);};
void() zombie_walk9 =[ $walk9, zombie_walk10 ] {ai_walk(0);};
void() zombie_walk10 =[ $walk10, zombie_walk11 ] {ai_walk(0);};
void() zombie_walk11 =[ $walk11, zombie_walk12 ] {ai_walk(2);};
void() zombie_walk12 =[ $walk12, zombie_walk13 ] {ai_walk(2);};
void() zombie_walk13 =[ $walk13, zombie_walk14 ] {ai_walk(1);};
void() zombie_walk14 =[ $walk14, zombie_walk15 ] {ai_walk(0);};
void() zombie_walk15 =[ $walk15, zombie_walk16 ] {ai_walk(0);};
void() zombie_walk16 =[ $walk16, zombie_walk17 ] {ai_walk(0);};
void() zombie_walk17 =[ $walk17, zombie_walk18 ] {ai_walk(0);};
void() zombie_walk18 =[ $walk18, zombie_walk19 ] {ai_walk(0);};
void() zombie_walk19 =[ $walk19, zombie_walk1 ] {
ai_walk(0);
if (random() < 0.2)
sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);};
void() zombie_run1 =[ $run1, zombie_run2 ] {ai_run(1);self.inpain = 0;};
void() zombie_run2 =[ $run2, zombie_run3 ] {ai_run(1);};
void() zombie_run3 =[ $run3, zombie_run4 ] {ai_run(0);};
void() zombie_run4 =[ $run4, zombie_run5 ] {ai_run(1);};
void() zombie_run5 =[ $run5, zombie_run6 ] {ai_run(2);};
void() zombie_run6 =[ $run6, zombie_run7 ] {ai_run(3);};
void() zombie_run7 =[ $run7, zombie_run8 ] {ai_run(4);};
void() zombie_run8 =[ $run8, zombie_run9 ] {ai_run(4);};
void() zombie_run9 =[ $run9, zombie_run10 ] {ai_run(2);};
void() zombie_run10 =[ $run10, zombie_run11 ] {ai_run(0);};
void() zombie_run11 =[ $run11, zombie_run12 ] {ai_run(0);};
void() zombie_run12 =[ $run12, zombie_run13 ] {ai_run(0);};
void() zombie_run13 =[ $run13, zombie_run14 ] {ai_run(2);};
void() zombie_run14 =[ $run14, zombie_run15 ] {ai_run(4);};
void() zombie_run15 =[ $run15, zombie_run16 ] {ai_run(6);};
void() zombie_run16 =[ $run16, zombie_run17 ] {ai_run(7);};
void() zombie_run17 =[ $run17, zombie_run18 ] {ai_run(3);};
void() zombie_run18 =[ $run18, zombie_run1 ] {
ai_run(8);
if (random() < 0.2)
sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
if (random() > 0.8)
sound (self, CHAN_VOICE, "zombie/z_idle1.wav", 1, ATTN_IDLE);
};
/*
=============================================================================
ATTACKS
=============================================================================
*/
void() ZombieGrenadeTouch =
{
if (other == self.owner)
return; // don't explode on owner
if (other.takedamage)
{
T_Damage (other, self, self.owner, 10 );
sound (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
remove (self);
return;
}
sound (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
self.velocity = '0 0 0';
self.avelocity = '0 0 0';
self.touch = SUB_Remove;
};
/*
================
ZombieFireGrenade
================
*/
void(vector st) ZombieFireGrenade =
{
local entity missile, mpuff;
local vector org;
sound (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM);
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_BOUNCE;
missile.solid = SOLID_BBOX;
// calc org
org = self.origin + st_x * v_forward + st_y * v_right + (st_z - 24) * v_up;
// set missile speed
makevectors (self.angles);
missile.velocity = normalize(self.enemy.origin - org);
missile.velocity = missile.velocity * 600;
missile.velocity_z = 200;
missile.avelocity = '3000 1000 2000';
missile.touch = ZombieGrenadeTouch;
// set missile duration
missile.nextthink = time + 2.5;
missile.think = SUB_Remove;
setmodel (missile, "progs/zom_gib.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, org);
};
void() zombie_atta1 =[ $atta1, zombie_atta2 ] {ai_face();};
void() zombie_atta2 =[ $atta2, zombie_atta3 ] {ai_face();};
void() zombie_atta3 =[ $atta3, zombie_atta4 ] {ai_face();};
void() zombie_atta4 =[ $atta4, zombie_atta5 ] {ai_face();};
void() zombie_atta5 =[ $atta5, zombie_atta6 ] {ai_face();};
void() zombie_atta6 =[ $atta6, zombie_atta7 ] {ai_face();};
void() zombie_atta7 =[ $atta7, zombie_atta8 ] {ai_face();};
void() zombie_atta8 =[ $atta8, zombie_atta9 ] {ai_face();};
void() zombie_atta9 =[ $atta9, zombie_atta10 ] {ai_face();};
void() zombie_atta10 =[ $atta10, zombie_atta11 ] {ai_face();};
void() zombie_atta11 =[ $atta11, zombie_atta12 ] {ai_face();};
void() zombie_atta12 =[ $atta12, zombie_atta13 ] {ai_face();};
void() zombie_atta13 =[ $atta13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -22 30');};
void() zombie_attb1 =[ $attb1, zombie_attb2 ] {ai_face();};
void() zombie_attb2 =[ $attb2, zombie_attb3 ] {ai_face();};
void() zombie_attb3 =[ $attb3, zombie_attb4 ] {ai_face();};
void() zombie_attb4 =[ $attb4, zombie_attb5 ] {ai_face();};
void() zombie_attb5 =[ $attb5, zombie_attb6 ] {ai_face();};
void() zombie_attb6 =[ $attb6, zombie_attb7 ] {ai_face();};
void() zombie_attb7 =[ $attb7, zombie_attb8 ] {ai_face();};
void() zombie_attb8 =[ $attb8, zombie_attb9 ] {ai_face();};
void() zombie_attb9 =[ $attb9, zombie_attb10 ] {ai_face();};
void() zombie_attb10 =[ $attb10, zombie_attb11 ] {ai_face();};
void() zombie_attb11 =[ $attb11, zombie_attb12 ] {ai_face();};
void() zombie_attb12 =[ $attb12, zombie_attb13 ] {ai_face();};
void() zombie_attb13 =[ $attb13, zombie_attb14 ] {ai_face();};
void() zombie_attb14 =[ $attb13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -24 29');};
void() zombie_attc1 =[ $attc1, zombie_attc2 ] {ai_face();};
void() zombie_attc2 =[ $attc2, zombie_attc3 ] {ai_face();};
void() zombie_attc3 =[ $attc3, zombie_attc4 ] {ai_face();};
void() zombie_attc4 =[ $attc4, zombie_attc5 ] {ai_face();};
void() zombie_attc5 =[ $attc5, zombie_attc6 ] {ai_face();};
void() zombie_attc6 =[ $attc6, zombie_attc7 ] {ai_face();};
void() zombie_attc7 =[ $attc7, zombie_attc8 ] {ai_face();};
void() zombie_attc8 =[ $attc8, zombie_attc9 ] {ai_face();};
void() zombie_attc9 =[ $attc9, zombie_attc10 ] {ai_face();};
void() zombie_attc10 =[ $attc10, zombie_attc11 ] {ai_face();};
void() zombie_attc11 =[ $attc11, zombie_attc12 ] {ai_face();};
void() zombie_attc12 =[ $attc12, zombie_run1 ] {ai_face();ZombieFireGrenade('-12 -19 29');};
void() zombie_missile =
{
local float r;
droptofloor();
r = random();
if (r < 0.3)
zombie_atta1 ();
else if (r < 0.6)
zombie_attb1 ();
else
zombie_attc1 ();
};
/*
=============================================================================
PAIN
=============================================================================
*/
void() zombie_paina1 =[ $paina1, zombie_paina2 ] {sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);};
void() zombie_paina2 =[ $paina2, zombie_paina3 ] {ai_painforward(3);};
void() zombie_paina3 =[ $paina3, zombie_paina4 ] {ai_painforward(1);};
void() zombie_paina4 =[ $paina4, zombie_paina5 ] {ai_pain(1);};
void() zombie_paina5 =[ $paina5, zombie_paina6 ] {ai_pain(3);};
void() zombie_paina6 =[ $paina6, zombie_paina7 ] {ai_pain(1);};
void() zombie_paina7 =[ $paina7, zombie_paina8 ] {};
void() zombie_paina8 =[ $paina8, zombie_paina9 ] {};
void() zombie_paina9 =[ $paina9, zombie_paina10 ] {};
void() zombie_paina10 =[ $paina10, zombie_paina11 ] {};
void() zombie_paina11 =[ $paina11, zombie_paina12 ] {};
void() zombie_paina12 =[ $paina12, zombie_run1 ] {};
void() zombie_painb1 =[ $painb1, zombie_painb2 ] {sound (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
void() zombie_painb2 =[ $painb2, zombie_painb3 ] {ai_pain(2);};
void() zombie_painb3 =[ $painb3, zombie_painb4 ] {ai_pain(8);};
void() zombie_painb4 =[ $painb4, zombie_painb5 ] {ai_pain(6);};
void() zombie_painb5 =[ $painb5, zombie_painb6 ] {ai_pain(2);};
void() zombie_painb6 =[ $painb6, zombie_painb7 ] {};
void() zombie_painb7 =[ $painb7, zombie_painb8 ] {};
void() zombie_painb8 =[ $painb8, zombie_painb9 ] {};
void() zombie_painb9 =[ $painb9, zombie_painb10 ] {sound (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);};
void() zombie_painb10 =[ $painb10, zombie_painb11 ] {};
void() zombie_painb11 =[ $painb11, zombie_painb12 ] {};
void() zombie_painb12 =[ $painb12, zombie_painb13 ] {};
void() zombie_painb13 =[ $painb13, zombie_painb14 ] {};
void() zombie_painb14 =[ $painb14, zombie_painb15 ] {};
void() zombie_painb15 =[ $painb15, zombie_painb16 ] {};
void() zombie_painb16 =[ $painb16, zombie_painb17 ] {};
void() zombie_painb17 =[ $painb17, zombie_painb18 ] {};
void() zombie_painb18 =[ $painb18, zombie_painb19 ] {};
void() zombie_painb19 =[ $painb19, zombie_painb20 ] {};
void() zombie_painb20 =[ $painb20, zombie_painb21 ] {};
void() zombie_painb21 =[ $painb21, zombie_painb22 ] {};
void() zombie_painb22 =[ $painb22, zombie_painb23 ] {};
void() zombie_painb23 =[ $painb23, zombie_painb24 ] {};
void() zombie_painb24 =[ $painb24, zombie_painb25 ] {};
void() zombie_painb25 =[ $painb25, zombie_painb26 ] {ai_painforward(1);};
void() zombie_painb26 =[ $painb26, zombie_painb27 ] {};
void() zombie_painb27 =[ $painb27, zombie_painb28 ] {};
void() zombie_painb28 =[ $painb28, zombie_run1 ] {};
void() zombie_painc1 =[ $painc1, zombie_painc2 ] {sound (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
void() zombie_painc2 =[ $painc2, zombie_painc3 ] {};
void() zombie_painc3 =[ $painc3, zombie_painc4 ] {ai_pain(3);};
void() zombie_painc4 =[ $painc4, zombie_painc5 ] {ai_pain(1);};
void() zombie_painc5 =[ $painc5, zombie_painc6 ] {};
void() zombie_painc6 =[ $painc6, zombie_painc7 ] {};
void() zombie_painc7 =[ $painc7, zombie_painc8 ] {};
void() zombie_painc8 =[ $painc8, zombie_painc9 ] {};
void() zombie_painc9 =[ $painc9, zombie_painc10 ] {};
void() zombie_painc10 =[ $painc10, zombie_painc11 ] {};
void() zombie_painc11 =[ $painc11, zombie_painc12 ] {ai_painforward(1);};
void() zombie_painc12 =[ $painc12, zombie_painc13 ] {ai_painforward(1);};
void() zombie_painc13 =[ $painc13, zombie_painc14 ] {};
void() zombie_painc14 =[ $painc14, zombie_painc15 ] {};
void() zombie_painc15 =[ $painc15, zombie_painc16 ] {};
void() zombie_painc16 =[ $painc16, zombie_painc17 ] {};
void() zombie_painc17 =[ $painc17, zombie_painc18 ] {};
void() zombie_painc18 =[ $painc18, zombie_run1 ] {};
void() zombie_paind1 =[ $paind1, zombie_paind2 ]
{
sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);
droptofloor();
};
void() zombie_paind2 =[ $paind2, zombie_paind3 ] {};
void() zombie_paind3 =[ $paind3, zombie_paind4 ] {};
void() zombie_paind4 =[ $paind4, zombie_paind5 ] {};
void() zombie_paind5 =[ $paind5, zombie_paind6 ] {};
void() zombie_paind6 =[ $paind6, zombie_paind7 ] {};
void() zombie_paind7 =[ $paind7, zombie_paind8 ] {};
void() zombie_paind8 =[ $paind8, zombie_paind9 ] {};
void() zombie_paind9 =[ $paind9, zombie_paind10 ] {ai_pain(1);};
void() zombie_paind10 =[ $paind10, zombie_paind11 ] {};
void() zombie_paind11 =[ $paind11, zombie_paind12 ] {};
void() zombie_paind12 =[ $paind12, zombie_paind13 ] {};
void() zombie_paind13 =[ $paind13, zombie_run1 ] {};
void() zombie_paine1 =[ $paine1, zombie_paine2 ]
{
sound (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);
self.health = 60;
};
void() zombie_paine2 =[ $paine2, zombie_paine3 ] {ai_pain(8);};
void() zombie_paine3 =[ $paine3, zombie_paine4 ] {ai_pain(5);};
void() zombie_paine4 =[ $paine4, zombie_paine5 ] {ai_pain(3);};
void() zombie_paine5 =[ $paine5, zombie_paine6 ] {ai_pain(1);};
void() zombie_paine6 =[ $paine6, zombie_paine7 ] {ai_pain(2);};
void() zombie_paine7 =[ $paine7, zombie_paine8 ] {ai_pain(1);};
void() zombie_paine8 =[ $paine8, zombie_paine9 ] {ai_pain(1);};
void() zombie_paine9 =[ $paine9, zombie_paine10 ] {ai_pain(2);};
void() zombie_paine10 =[ $paine10, zombie_paine11 ]
{
sound (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);
self.solid = SOLID_NOT;
};
void() zombie_paine11 =[ $paine11, zombie_paine12 ]
{
droptofloor();
self.nextthink = self.nextthink + 5;
self.health = 60;
};
void() zombie_paine12 =[ $paine12, zombie_paine13 ]
{
// see if ok to stand up
droptofloor();
self.health = 60;
sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
self.solid = SOLID_SLIDEBOX;
if (!walkmove (0, 0))
{
self.think = zombie_paine11;
self.solid = SOLID_NOT;
return;
}
};
void() zombie_paine13 =[ $paine13, zombie_paine14 ] {};
void() zombie_paine14 =[ $paine14, zombie_paine15 ] {};
void() zombie_paine15 =[ $paine15, zombie_paine16 ] {};
void() zombie_paine16 =[ $paine16, zombie_paine17 ] {};
void() zombie_paine17 =[ $paine17, zombie_paine18 ] {};
void() zombie_paine18 =[ $paine18, zombie_paine19 ] {};
void() zombie_paine19 =[ $paine19, zombie_paine20 ] {};
void() zombie_paine20 =[ $paine20, zombie_paine21 ] {};
void() zombie_paine21 =[ $paine21, zombie_paine22 ] {};
void() zombie_paine22 =[ $paine22, zombie_paine23 ] {};
void() zombie_paine23 =[ $paine23, zombie_paine24 ] {};
void() zombie_paine24 =[ $paine24, zombie_paine25 ] {};
void() zombie_paine25 =[ $paine25, zombie_paine26 ] {ai_painforward(5);};
void() zombie_paine26 =[ $paine26, zombie_paine27 ] {ai_painforward(3);};
void() zombie_paine27 =[ $paine27, zombie_paine28 ] {ai_painforward(1);};
void() zombie_paine28 =[ $paine28, zombie_paine29 ] {ai_pain(1);};
void() zombie_paine29 =[ $paine29, zombie_paine30 ] {};
void() zombie_paine30 =[ $paine30, zombie_run1 ]
{ };
void() zombie_die =
{
sound (self, CHAN_VOICE, "zombie/z_gib.wav", 1, ATTN_NORM);
ThrowHead ("progs/h_zombie.mdl", self.health);
ThrowGib ("progs/gib1.mdl", self.health);
ThrowGib ("progs/gib2.mdl", self.health);
ThrowGib ("progs/gib3.mdl", self.health);
};
/*
=================
zombie_pain
Zombies can only be killed (gibbed) by doing 60 hit points of damage
in a single frame (rockets, grenades, quad shotgun, quad nailgun).
A hit of 25 points or more (super shotgun, quad nailgun) will allways put it
down to the ground.
A hit of from 10 to 40 points in one frame will cause it to go down if it
has been twice in two seconds, otherwise it goes into one of the four
fast pain frames.
A hit of less than 10 points of damage (winged by a shotgun) will be ignored.
FIXME: don't use pain_finished because of nightmare hack
=================
*/
void(entity attacker, float take) zombie_pain =
{
local float r;
self.health = 60; // allways reset health
if (take < 9)
return; // totally ignore
if (self.inpain == 2)
return; // down on ground, so don't reset any counters
// go down immediately if a big enough hit
if (take >= 25)
{
self.inpain = 2;
zombie_paine1 ();
return;
}
if (self.inpain)
{
// if hit again in next gre seconds while not in pain frames, definately drop
self.pain_finished = time + 3;
return; // currently going through an animation, don't change
}
if (self.pain_finished > time)
{
// hit again, so drop down
self.inpain = 2;
zombie_paine1 ();
return;
}
// gp into one of the fast pain animations
self.inpain = 1;
r = random();
if (r < 0.25)
zombie_paina1 ();
else if (r < 0.5)
zombie_painb1 ();
else if (r < 0.75)
zombie_painc1 ();
else
zombie_paind1 ();
};
void() zombie_sleep = [ $paine11, zombie_sleep ] { ai_stand(); };
void() zombie_wake =
{
self.th_stand = zombie_stand1;
self.th_walk = zombie_walk1;
self.th_pain = zombie_pain;
self.th_run = zombie_run1;
self.th_missile = zombie_missile;
// paine12 will handle setting solid, just make the size box correct.
// self.solid = SOLID_SLIDEBOX;
// setsize (self, '-16 -16 -24', '16 16 40');
zombie_paine12();
};
void() zombie_escape1=[ $cruc_1, zombie_escape2 ] {self.nextthink=time+0.20;};
void() zombie_escape2=[ $cruc_2, zombie_escape3 ] {self.nextthink=time+0.20;};
void() zombie_escape3=[ $cruc_3, zombie_escape4 ] {self.nextthink=time+0.20;};
void() zombie_escape4=[ $cruc_4, zombie_escape5 ] {self.nextthink=time+0.20;};
void() zombie_escape5=[ $cruc_5, zombie_escape6 ] {self.nextthink=time+0.15;};
void() zombie_escape6=[ $cruc_6, zombie_escape7 ] {self.nextthink=time+0.15;};
void() zombie_escape7=[ $cruc_7, zombie_escape8 ] {self.nextthink=time+0.15;};
void() zombie_escape8=[ $cruc_8, zombie_escape9 ] {self.nextthink=time+0.15;};
void() zombie_escape9=[ $cruc_9, zombie_escape10 ] {self.nextthink=time+0.15;};
void() zombie_escape10=[$cruc_10, zombie_escape11] {self.nextthink=time+0.15;};
void() zombie_escape11=[$cruc_11, zombie_escape12] {self.nextthink=time+0.10;};
void() zombie_escape12=[$cruc_12, zombie_escape13] {self.nextthink=time+0.10;};
void() zombie_escape13=[$cruc_13, zombie_escape14] {self.nextthink=time+0.10;};
void() zombie_escape14=[$cruc_14, zombie_escape15]
{
makevectors (self.angles);
setorigin ( self, self.origin + v_forward * 8);
self.nextthink=time+0.15;
};
void() zombie_escape15=[ $cruc_15, zombie_escape16]
{
makevectors (self.angles);
setorigin ( self, self.origin + v_forward * 8);
self.nextthink=time+0.15;
};
void() zombie_escape16 = [ $cruc_16, zombie_run1 ]
{
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
self.takedamage = DAMAGE_AIM;
self.th_stand = zombie_stand1;
self.th_walk = zombie_walk1;
self.th_pain = zombie_pain;
self.th_run = zombie_run1;
self.th_missile = zombie_missile;
self.health = 60;
sound (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
droptofloor();
};
void() zombie_escape =
{
if (!self.pain_finished)
{
self.pain_finished = time + self.delay;
}
self.think = zombie_cruc1;
self.nextthink = time + 0.1;
};
//============================================================================
/*QUAKED monster_zombie (1 0 0) (-16 -16 -24) (16 16 32) Crucified Lying ambush Sneaky
Crucified - Zombie stays stuck in the wall, moans and writhes.
Lying - Zombie will start lying down, and stand when player spotted.
Ambush - Just like all the other ambush flags.
Sneaky - Zombie stays stuck in the wall, but breaks his chains, hops off the wall, and attacks after seeing the player.
If crucified, stick the bounding box 12 pixels back into a wall to look right.
*/
void() monster_zombie =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/zombie.mdl");
precache_model ("progs/h_zombie.mdl");
precache_model ("progs/zom_gib.mdl");
precache_sound ("zombie/z_idle.wav");
precache_sound ("zombie/z_idle1.wav");
precache_sound ("zombie/z_shot1.wav");
precache_sound ("zombie/z_gib.wav");
precache_sound ("zombie/z_pain.wav");
precache_sound ("zombie/z_pain1.wav");
precache_sound ("zombie/z_fall.wav");
precache_sound ("zombie/z_miss.wav");
precache_sound ("zombie/z_hit.wav");
precache_sound ("zombie/idle_w2.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/zombie.mdl");
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
self.health = 60;
self.th_stand = zombie_stand1;
self.th_walk = zombie_walk1;
self.th_run = zombie_run1;
self.th_pain = zombie_pain;
self.th_die = zombie_die;
self.th_missile = zombie_missile;
if (self.spawnflags & SPAWN_CRUCIFIED)
{
self.movetype = MOVETYPE_NONE;
zombie_cruc1 ();
}
else if (self.spawnflags & SPAWN_LYING)
{
self.solid = SOLID_NOT;
self.th_stand = zombie_sleep;
self.th_run = zombie_wake;
self.th_walk = zombie_wake;
self.th_pain = zombie_wake;
self.th_missile = zombie_wake;
setsize (self, '-16 -16 -24', '16 16 -16');
// HOLY HACK, BATMAN! - Don't blame me. Check out FindTarget in ai.qc!
if ( self.spawnflags & SPAWN_AMBUSH)
self.spawnflags = SPAWN_LYING;
walkmonster_start();
}
else if (self.spawnflags & SPAWN_SNEAKY)
{
self.movetype = MOVETYPE_NONE;
self.solid = SOLID_NOT;
self.th_stand = zombie_cruc1;
self.th_run = zombie_escape;
self.th_walk = zombie_escape;
self.th_pain = zombie_escape;
self.th_missile = zombie_escape;
if (!self.delay)
self.delay = 3;
self.ideal_yaw = self.angles * '0 1 0';
if (!self.yaw_speed)
self.yaw_speed = 20;
self.view_ofs = '0 0 25';
self.flags = self.flags | FL_MONSTER;
self.th_stand ();
self.nextthink = self.nextthink + random()*0.5;
total_monsters = total_monsters + 1;
}
else
{
if (self.spawnflags & SPAWN_AMBUSH)
self.spawnflags = SPAWN_LYING;
walkmonster_start();
}
};