as released 1997-05-01
This commit is contained in:
commit
da758653d7
64 changed files with 28656 additions and 0 deletions
763
AI.QC
Normal file
763
AI.QC
Normal 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
385
BOSS.QC
Normal 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
141
BUTTONS.QC
Normal 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
145
BUZZSAW.QC
Normal 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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
376
COMBAT.QC
Normal file
376
COMBAT.QC
Normal 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
790
DEFS.QC
Normal 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
363
DEMON.QC
Normal 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
185
DMATCH.QC
Normal 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
363
DOG.QC
Normal 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
793
DOORS.QC
Normal 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
834
DRAGON.QC
Normal 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
162
EARTHQ.QC
Normal 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
223
EEL.QC
Normal 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
156
ELEVATR.QC
Normal 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
361
ENDING.QC
Normal 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
357
ENFORCER.QC
Normal 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
408
FIGHT.QC
Normal 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
530
FILES.DAT
Normal 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
187
FISH.QC
Normal 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
309
GRAPPLE.QC
Normal 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
539
HKNIGHT.QC
Normal 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
184
INVIS_SW.QC
Normal 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 ();
|
||||||
|
};
|
374
KNIGHT.QC
Normal file
374
KNIGHT.QC
Normal 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
478
LAVAMAN.QC
Normal 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
205
LAVA_WPN.QC
Normal 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
183
LIGHTNIN.QC
Normal 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
727
MISC.QC
Normal 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
243
MONSTERS.QC
Normal 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
567
MORPH.QC
Normal 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
70
MOTD.QC
Normal 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
551
MULT_WPN.QC
Normal 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
506
MUMMY.QC
Normal 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
133
NEWITEMS.QC
Normal 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
144
NEWMISC.QC
Normal 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
602
NEWPLATS.QC
Normal 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
151
NEW_AI.QC
Normal 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
499
OGRE.QC
Normal 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
283
OLDONE.QC
Normal 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
391
PENDULUM.QC
Normal 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
364
PLATS.QC
Normal 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
817
PLAYER.QC
Normal 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
143
PROGDEFS.H
Normal 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
66
PROGS.SRC
Normal 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
122
RANDOM.QC
Normal 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
223
RUNES.QC
Normal 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
239
SHALRATH.QC
Normal 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
367
SHAMBLER.QC
Normal 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
103
SHIELD.QC
Normal 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
284
SOLDIER.QC
Normal 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
159
SPHERE.QC
Normal 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
26
SPRITES.QC
Normal 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
316
SUBS.QC
Normal 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
556
S_WRATH.QC
Normal 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
347
TARBABY.QC
Normal 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
1887
TEAMPLAY.QC
Normal file
File diff suppressed because it is too large
Load diff
223
TIMEMACH.QC
Normal file
223
TIMEMACH.QC
Normal 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
675
TRIGGERS.QC
Normal 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
1691
WEAPONS.QC
Normal file
File diff suppressed because it is too large
Load diff
410
WIZARD.QC
Normal file
410
WIZARD.QC
Normal 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
429
WORLD.QC
Normal 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
339
WRATH.QC
Normal 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
681
ZOMBIE.QC
Normal 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();
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in a new issue