Update for new QF features.

This commit is contained in:
Ragnvald Maartmann-Moe IV 2003-03-03 19:17:04 +00:00
parent f9c0b28fec
commit e16af82af2
23 changed files with 4122 additions and 4878 deletions

View file

@ -1,5 +1,5 @@
all: qwprogs.dat
qwprogs.dat: progs.src *.qc
qfcc --traditional -Werror -g
qfcc -Werror -Wall -g
clean:
rm -f core *.dat *.sym progdefs.h

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
buttons.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -24,25 +24,28 @@
// button and multiple button
void() button_wait;
void() button_return;
void () button_wait;
void () button_return;
void() button_wait =
void ()
button_wait =
{
self.state = STATE_TOP;
self.nextthink = self.ltime + self.wait;
self.think = button_return;
activator = self.enemy;
SUB_UseTargets();
SUB_UseTargets ();
self.frame = 1; // use alternate textures
};
void() button_done =
void ()
button_done =
{
self.state = STATE_BOTTOM;
};
void() button_return =
void ()
button_return =
{
self.state = STATE_DOWN;
SUB_CalcMove (self.pos1, self.speed, button_done);
@ -52,12 +55,14 @@ void() button_return =
};
void() button_blocked =
{ // do nothing, just don't ome all the way back out
void ()
button_blocked =
{ // do nothing, just don't come all the way back out
};
void() button_fire =
void ()
button_fire =
{
if (self.state == STATE_UP || self.state == STATE_TOP)
return;
@ -68,22 +73,25 @@ void() button_fire =
SUB_CalcMove (self.pos2, self.speed, button_wait);
};
void() button_use =
void ()
button_use =
{
self.enemy = activator;
button_fire ();
};
void() button_touch =
void ()
button_touch =
{
if (other.classname != "player")
return;
self.enemy = other;
button_fire ();
};
void() button_killed =
void ()
button_killed =
{
self.enemy = damage_attacker;
self.health = self.max_health;
@ -91,7 +99,6 @@ void() button_killed =
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.
@ -107,27 +114,26 @@ When a button is touched, it moves some distance in the direction of it's angle,
2) metallic click
3) in-out
*/
void() func_button =
void ()
func_button =
{
if (self.sounds == 0)
{
switch (self.sounds) {
case 0:
precache_sound ("buttons/airbut1.wav");
self.noise = "buttons/airbut1.wav";
}
if (self.sounds == 1)
{
break;
case 1:
precache_sound ("buttons/switch21.wav");
self.noise = "buttons/switch21.wav";
}
if (self.sounds == 2)
{
break;
case 2:
precache_sound ("buttons/switch02.wav");
self.noise = "buttons/switch02.wav";
}
if (self.sounds == 3)
{
case 3:
precache_sound ("buttons/switch04.wav");
self.noise = "buttons/switch04.wav";
default:
break;
}
SetMovedir ();
@ -139,13 +145,11 @@ void() func_button =
self.blocked = button_blocked;
self.use = button_use;
if (self.health)
{
if (self.health) {
self.max_health = self.health;
self.th_die = button_killed;
self.takedamage = DAMAGE_YES;
}
else
} else
self.touch = button_touch;
if (!self.speed)
@ -158,6 +162,6 @@ void() func_button =
self.state = STATE_BOTTOM;
self.pos1 = self.origin;
self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
self.pos2 = self.pos1 + self.movedir * (fabs (self.movedir * self.size)
- self.lip);
};

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
combat.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -22,13 +22,12 @@
$Id$
*/
void () T_MissileTouch;
void () info_player_start;
void (entity targ, entity attacker) ClientObituary;
void (entity who) ResistanceSound;
void() T_MissileTouch;
void() info_player_start;
void(entity targ, entity attacker) ClientObituary;
void(entity who) ResistanceSound;
/*SERVER
/* SERVER
void() monster_death_use;
*/
@ -42,12 +41,13 @@ Returns true if the inflictor can directly damage the target. Used for
explosions and melee attacks.
============
*/
float(entity targ, entity inflictor) CanDamage =
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);
// 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)
@ -55,34 +55,28 @@ float(entity targ, entity inflictor) CanDamage =
return FALSE;
}
traceline(inflictor.origin, targ.origin, TRUE, self);
traceline (inflictor.origin, targ.origin, TRUE, self);
if (trace_fraction == 1)
return TRUE;
traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
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);
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);
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);
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 =
void (entity targ, entity attacker)
Killed =
{
local entity oself;
local entity oself;
oself = self;
self = targ;
@ -90,9 +84,8 @@ void(entity targ, entity attacker) Killed =
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
if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE) {
// doors, triggers, etc
self.th_die ();
self = oself;
return;
@ -100,10 +93,9 @@ void(entity targ, entity attacker) Killed =
self.enemy = attacker;
// bump the monster counter
if (self.flags & FL_MONSTER)
{
killed_monsters = killed_monsters + 1;
// bump the monster counter
if (self.flags & FL_MONSTER) {
killed_monsters++;
WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
}
@ -121,12 +113,13 @@ void(entity targ, entity attacker) Killed =
self = oself;
};
// *TEAMPLAY*
// Prototypes
float(entity targ, entity inflictor, entity attacker, float damage) TeamArmorDam;
float(entity targ, entity inflictor, entity attacker, float damage) TeamHealthDam;
float (entity targ, entity inflictor, entity attacker, float damage)
TeamArmorDam;
float (entity targ, entity inflictor, entity attacker, float damage)
TeamHealthDam;
/*
============
@ -136,87 +129,79 @@ 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=
void (entity targ, entity inflictor, entity attacker, float damage)
T_Damage=
{
local vector dir;
local entity oldself;
local float save;
local float take;
local entity oldself;
local float save, take;
local vector dir;
if (!targ.takedamage)
return;
// used by buttons and triggers to set activator for target firing
// used by buttons and triggers to set activator for target firing
damage_attacker = attacker;
// check for quad damage powerup on the attacker
// check for quad damage powerup on the attacker
if (attacker.super_damage_finished > time)
damage = damage * 4;
// RUNE: check for double damage for rune of Black Magic powerup
damage *= 4;
// RUNE: check for double damage for rune of Black Magic powerup
if (attacker.player_flag & ITEM_RUNE2_FLAG)
damage = damage * 2;
// RUNE
damage *= 2;
//RUNE check if target has rune of Earth Magic (half damage)
//RUNE check if target has rune of Earth Magic (half damage)
if (targ.player_flag & ITEM_RUNE1_FLAG) {
damage = damage / 2;
ResistanceSound(targ);
damage /= 2;
ResistanceSound (targ);
}
//RUNE
// *XXX* EXPERT CTF mark players who hurt the flag carrier, so they
// are worth more points for a while.
if ( (attacker.classname == "player") && // attacker must be a player
(targ.player_flag & ITEM_ENEMY_FLAG) && // target is a flag carrier
(attacker.steam != targ.steam)) // target and attacker on diff teams
attacker.last_hurt_carrier = time;
if ((attacker.classname == "player") // attacker must be a player
&& (targ.player_flag & ITEM_ENEMY_FLAG) // target is a flag carrier
&& (attacker.steam != targ.steam)) // target and attacker on diff teams
attacker.last_hurt_carrier = time;
// save damage based on the target's armor level
// save damage based on the target's armor level
// *TEAMPLAY*
// TeamArmorDam returns true iff the attacker can damage the target's armor
if (TeamArmorDam(targ, inflictor, attacker, damage))
save = ceil(targ.armortype*damage);
// *TEAMPLAY*
// TeamArmorDam returns true iff the attacker can damage the target's armor
if (TeamArmorDam (targ, inflictor, attacker, damage))
save = ceil (targ.armortype * damage);
else
save = 0;
if (save >= targ.armorvalue)
{
if (save >= targ.armorvalue) {
save = targ.armorvalue;
targ.armortype = 0; // lost all armor
targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3));
targ.items &= ~(IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3);
}
targ.armorvalue = targ.armorvalue - save;
take = ceil(damage-save);
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;
// 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 += take;
targ.dmg_save += save;
targ.dmg_inflictor = inflictor;
}
// figure momentum add
if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
{
// 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;
dir = normalize (dir);
targ.velocity += dir * damage * 8;
}
// check for godmode or invincibility
// check for godmode or invincibility
if (self.killed != 99) { // god or 666 doesn't save your from team change
if (targ.flags & FL_GODMODE)
return;
if (targ.invincible_finished >= time)
{
if (self.invincible_sound < time)
{
if (targ.invincible_finished >= time) {
if (self.invincible_sound < time) {
sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
self.invincible_sound = time + 2;
}
@ -224,39 +209,34 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
}
}
// team play damage avoidance
if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) )
// team play damage avoidance
if ((teamplay == 1) && (targ.team > 0) && (targ.team == attacker.team))
return;
// *TEAMPLAY*
// TeamHealthDam will return true if the attacker can damage the target's
// health
if (!TeamHealthDam(targ, inflictor, attacker, damage))
// *TEAMPLAY*
// TeamHealthDam will return true if the attacker can damage the target's
// health
if (!TeamHealthDam (targ, inflictor, attacker, damage))
return;
// do the damage
// do the damage
targ.health = targ.health - take;
if (targ.health <= 0)
{
if (targ.health <= 0) {
Killed (targ, attacker);
return;
}
// react to the damage
// react to the damage
oldself = self;
self = targ;
/*SERVER
if ( (self.flags & FL_MONSTER) && attacker != world)
{
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 != attacker && attacker != self.enemy) {
if ((self.classname != attacker.classname)
|| (self.classname == "monster_army")) {
if (self.enemy.classname == "player")
self.oldenemy = self.enemy;
self.enemy = attacker;
@ -266,45 +246,35 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
}
*/
if (self.th_pain)
{
self.th_pain (attacker, take);
}
self = oldself;
};
/*
============
T_RadiusDamage
============
*/
void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
void (entity inflictor, entity attacker, float damage, entity ignore)
T_RadiusDamage =
{
local float points;
local entity head;
local vector org;
local float points;
local entity head;
local vector org;
head = findradius(inflictor.origin, damage+40);
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);
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);
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);
}
@ -315,34 +285,26 @@ void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDam
}
};
/*
============
T_BeamDamage
============
*/
void(entity attacker, float damage) T_BeamDamage =
void (entity attacker, float damage)
T_BeamDamage =
{
local float points;
local entity head;
local float points;
local entity head;
head = findradius(attacker.origin, damage+40);
head = findradius (attacker.origin, damage + 40);
while (head)
{
if (head.takedamage)
{
points = 0.5*vlen (attacker.origin - head.origin);
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);
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);
}
@ -351,4 +313,3 @@ void(entity attacker, float damage) T_BeamDamage =
head = head.chain;
}
};

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
ctfgame.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -22,21 +22,21 @@
$Id$
*/
float VOTEEXIT_TIME_LIMIT = 60; // 60 seconds after first vote
float voteexit_time;
entity vote_leader; // current leader
entity lastvotespawn;
void(vector org) spawn_tfog;
void(vector org, entity death_owner) spawn_tdeath;
void() InitTrigger;
void (vector org) spawn_tfog;
void (vector org, entity death_owner) spawn_tdeath;
void () InitTrigger;
/*QUAKED info_vote_destination (.5 .5 .5) (-8 -8 -8) (8 8 32)
This is the destination marker for a voteexit. It should have a "targetname"
field with the same value as a voteexit's "target" field.
*/
void() info_vote_destination =
void ()
info_vote_destination =
{
// this does nothing, just serves as a target spot
self.mangle = self.angles;
@ -47,39 +47,41 @@ void() info_vote_destination =
objerror ("no targetname");
};
void() voteexit_teleport =
void ()
voteexit_teleport =
{
local entity t;
local vector org;
local entity t;
local vector org;
// put a tfog where the player was
// put a tfog where the player was
spawn_tfog (other.origin);
// if we aren't in custom mode, just find a deathmatch target
// if we aren't in custom mode, just find a deathmatch target
// find the destination
if (!self.target) {
lastvotespawn = find(lastvotespawn, classname, "info_player_deathmatch");
lastvotespawn = find (lastvotespawn, classname,
"info_player_deathmatch");
if (lastvotespawn == world)
lastvotespawn = find (lastvotespawn, classname, "info_player_deathmatch");
lastvotespawn = find (lastvotespawn, classname,
"info_player_deathmatch");
t = lastvotespawn;
} else
t = find (world, targetname, self.target);
if (!t)
objerror ("couldn't find target");
// spawn a tfog flash in front of the destination
// 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)
{
// 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);
other.velocity = v_forward * (other.velocity_x + other.velocity_y);
return;
}
setorigin (other, t.origin);
@ -89,26 +91,26 @@ local vector org;
other.teleport_time = time + 0.7;
if (other.flags & FL_ONGROUND)
other.flags = other.flags - FL_ONGROUND;
other.flags &= ~FL_ONGROUND;
other.velocity = v_forward * 300;
};
void() voteexit_touch =
void ()
voteexit_touch =
{
local entity t;
local entity t;
if (other.classname != "player")
return;
// only teleport living creatures
// only teleport living creatures
if (other.health <= 0 || other.solid != SOLID_SLIDEBOX)
return;
if (other.voted) {
if (other.voted < time)
TeamPlayerUpdate(other, "You have already voted.");
TeamPlayerUpdate (other, "You have already voted.");
other.voted = time + 1;
voteexit_teleport();
voteexit_teleport ();
return;
}
@ -117,13 +119,13 @@ local entity t;
SUB_UseTargets ();
bprint(PRINT_HIGH, other.netname);
bprint(PRINT_HIGH, " has voted for ");
bprint(PRINT_HIGH, self.message);
bprint(PRINT_HIGH, "\n");
bprint (PRINT_HIGH, other.netname);
bprint (PRINT_HIGH, " has voted for ");
bprint (PRINT_HIGH, self.message);
bprint (PRINT_HIGH, "\n");
// ok, the player has voted for this exit
self.cnt = self.cnt + 1;
// ok, the player has voted for this exit
self.cnt++;
// find new leader
// we're on the start map, something special is happening
@ -146,9 +148,9 @@ local entity t;
voteexit_time = time + VOTEEXIT_TIME_LIMIT;
// notify everyone about the change
TeamCaptureResetUpdate();
TeamCaptureResetUpdate ();
voteexit_teleport();
voteexit_teleport ();
};
/*QUAKED trigger_voteexit (.5 .5 .5) ?
@ -160,10 +162,10 @@ Any object touching this will be transported to the corresponding
info_vote_destination entity. You must set the "target" field, and
create an object with a "targetname" field that matches.
*/
void() trigger_voteexit =
void ()
trigger_voteexit =
{
InitTrigger ();
self.touch = voteexit_touch;
self.cnt = 0;
};

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
defs.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -22,18 +22,9 @@
$Id$
*/
// SOURCE FOR GLOBALVARS_T C STRUCTURE ========================================
/*
==============================================================================
SOURCE FOR GLOBALVARS_T C STRUCTURE
==============================================================================
*/
//
// system globals
//
// system globals =============================================
entity self;
entity other;
entity world;
@ -44,7 +35,6 @@ entity newmis; // if this is set, the entity that just
// run created a new missile that should
// be simulated immediately
float force_retouch; // force all entities to touch triggers
// next frame. this is needed because
// non-moving things don't normally scan
@ -57,22 +47,20 @@ string mapname;
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;
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()
// global variables set by built in functions =================
vector v_forward, v_up, v_right; // set by makevectors ()
// set by traceline / tracebox
float trace_allsolid;
@ -87,21 +75,14 @@ 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
@ -109,22 +90,13 @@ void() SetNewParms; // called when a client first connects to
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 ===========================================
SOURCE FOR ENTVARS_T C STRUCTURE
==============================================================================
*/
//
// system fields (*** = do not set in prog code, maintained by C code)
//
// 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
@ -174,7 +146,6 @@ void end_sys_globals; // flag for structure dumping
.vector view_ofs; // add to origin to get eye point
.float button0; // fire
.float button1; // use
.float button2; // jump
@ -230,23 +201,13 @@ void end_sys_globals; // flag for structure dumping
.string noise, noise1, noise2, noise3; // contains names of wavs to play
//================================================
//====================================
void end_sys_fields; // flag for structure dumping
//================================================
//====================================
/*
==============================================================================
VARS NOT REFERENCED BY C CODE
==============================================================================
*/
//
// constants
//
// VARS NOT REFERENCED BY C CODE ==============================================
// constants =======================
float FALSE = 0;
float TRUE = 1;
@ -292,14 +253,12 @@ 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;
@ -313,7 +272,7 @@ float IT_SUPER_NAILGUN = 8;
float IT_GRENADE_LAUNCHER = 16;
float IT_ROCKET_LAUNCHER = 32;
float IT_LIGHTNING = 64;
float IT_GRAPPLE = 128;
float IT_GRAPPLE = 128;
float IT_SHELLS = 256;
float IT_NAILS = 512;
@ -339,7 +298,6 @@ float IT_SIGIL3 = 1073741824;
float IT_SIGIL4 = 2147483648;
// point content values
float CONTENT_EMPTY = -1;
float CONTENT_SOLID = -2;
float CONTENT_WATER = -3;
@ -371,7 +329,6 @@ float SVC_SMALLKICK = 34;
float SVC_BIGKICK = 35;
float SVC_MUZZLEFLASH = 39;
float TE_SPIKE = 0;
float TE_SUPERSPIKE = 1;
float TE_GUNSHOT = 2;
@ -403,14 +360,12 @@ 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;
@ -418,7 +373,6 @@ float EF_DIMLIGHT = 8;
float EF_FLAG1 = 16;
float EF_FLAG2 = 32;
// messages
float MSG_BROADCAST = 0; // unreliable to all
float MSG_ONE = 1; // reliable to one (msg_entity)
@ -447,9 +401,7 @@ float gamestart; // at start
//================================================
//
// globals
//
// globals ===============
float movedist;
float gameover; // set when a rule exits
@ -461,20 +413,15 @@ entity activator; // the entity that activated a trigger or brush
entity damage_attacker; // set by T_Damage
float framecount;
//
// cvars checked each frame
//
float teamplay;
float timelimit;
float fraglimit;
float deathmatch;
//================================================
//
// world fields (FIXME: make globals)
//
.string wad;
.string map;
.float worldtype; // 0=medieval 1=metal 2=base
@ -483,16 +430,11 @@ float deathmatch;
.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;
@ -505,8 +447,8 @@ float deathmatch;
.float speed;
.float lefty;// Monsters use this. I use it to flag the player's CHAN_WEAP
// to be cleared (see client.qc) -Wedge
.float lefty; // Monsters use this. I use it to flag the player's CHAN_WEAP
// to be cleared (see client.qc) -Wedge
.float search_time;
.float attack_state;
@ -516,12 +458,9 @@ float AS_SLIDING = 2;
float AS_MELEE = 3;
float AS_MISSILE = 4;
//
// player only fields
//
// player only fields ============
// *TEAMPLAY*
.float steam; // Current team player is on
.float lastteamset; // time of last team set
.string ctfskin; // selected ctf skin
@ -530,14 +469,12 @@ float AS_MISSILE = 4;
// *XXX* EXPERT CTF ALTERNATE SCORING
// time values
.float flag_since; // how long a player has had the flag
.float last_returned_flag; // last time player returned his own flag
.float last_fragged_carrier; // last time player fragged a flag carrier
.float last_hurt_carrier; // last time player hurt the flag carrier
// *XXX* end
.float walkframe;
// Zoid Additions
@ -600,9 +537,7 @@ float PF_GHOST = 64;
//McBain: PreviousWeaponCommand
.float previous_weapon; // one of the IT_SHOTGUN, etc flags
//
// object stuff
//
// object stuff ==============
.string mdl;
.vector mangle; // angle at start
@ -610,77 +545,50 @@ float PF_GHOST = 64;
.float t_length, t_width;
//
// doors, etc
//
// 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;
.float height;
//
// sounds
//
.float waitmin, waitmax;
.float distance;
.float volume;
//===========================================================================
//
// 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;
//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;
@ -696,7 +604,7 @@ void(entity e) remove = #15;
// 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;
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;
@ -714,30 +622,23 @@ 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() 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
// #48 was removed
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;
@ -746,6 +647,9 @@ 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;
void(float to, ...) WriteBytes = #0;
void(float to, vector v) WriteCoordV = #0;
void(float to, vector v) WriteAngleV = #0;
// several removed
@ -755,8 +659,6 @@ 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
@ -785,9 +687,7 @@ void(vector where, float set) multicast = #82; // sends the temp message to a se
//============================================================================
//
// 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;
@ -797,22 +697,14 @@ 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;
//
// Grapple.qc - Wedge
//
.float on_hook;// TRUE if hook is anchored and client is being pulled
.float hook_out;// TRUE if hook is in use
.entity hook;// pointer to client's hook

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
doors.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -22,7 +22,6 @@
$Id$
*/
float DOOR_START_OPEN = 1;
float DOOR_DONT_LINK = 4;
float DOOR_GOLD_KEY = 8;
@ -30,7 +29,6 @@ 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.
@ -39,28 +37,21 @@ 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 ============================================================
THINK FUNCTIONS
void () door_go_down;
void () door_go_up;
=============================================================================
*/
void() door_go_down;
void() door_go_up;
void() door_blocked =
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 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
@ -68,8 +59,8 @@ void() door_blocked =
}
};
void() door_hit_top =
void ()
door_hit_top =
{
sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_TOP;
@ -79,17 +70,18 @@ void() door_hit_top =
self.nextthink = self.ltime + self.wait;
};
void() door_hit_bottom =
void ()
door_hit_bottom =
{
sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_BOTTOM;
};
void() door_go_down =
void ()
door_go_down =
{
sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
if (self.max_health)
{
if (self.max_health) {
self.takedamage = DAMAGE_YES;
self.health = self.max_health;
}
@ -98,13 +90,13 @@ void() door_go_down =
SUB_CalcMove (self.pos1, self.speed, door_hit_bottom);
};
void() door_go_up =
void ()
door_go_up =
{
if (self.state == STATE_UP)
return; // allready going up
if (self.state == STATE_TOP)
{ // reset top wait time
if (self.state == STATE_TOP) { // reset top wait time
self.nextthink = self.ltime + self.wait;
return;
}
@ -116,60 +108,48 @@ void() door_go_up =
SUB_UseTargets();
};
// ACTIVATION FUNCTIONS =======================================================
/*
=============================================================================
ACTIVATION FUNCTIONS
=============================================================================
*/
void() door_fire =
void ()
door_fire =
{
local entity oself;
local entity starte;
local entity oself, starte;
if (self.owner != self)
objerror ("door_fire: self.owner != self");
// play use key sound
// 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)
{
if (self.spawnflags & DOOR_TOGGLE) {
if (self.state == STATE_UP || self.state == STATE_TOP) {
starte = self;
do
{
do {
door_go_down ();
self = self.enemy;
} while ( (self != starte) && (self != world) );
} while ((self != starte) && (self != world) );
self = oself;
return;
}
}
// trigger all paired doors
// trigger all paired doors
starte = self;
do
{
do {
door_go_up ();
self = self.enemy;
} while ( (self != starte) && (self != world) );
} while ((self != starte) && (self != world));
self = oself;
};
void() door_use =
void ()
door_use =
{
local entity oself;
local entity oself;
self.message = ""; // door message are for touch only
self.owner.message = "";
@ -181,7 +161,8 @@ void() door_use =
};
void() door_trigger_touch =
void ()
door_trigger_touch =
{
if (other.health <= 0)
return;
@ -196,8 +177,8 @@ void() door_trigger_touch =
door_use ();
};
void() door_killed =
void ()
door_killed =
{
local entity oself;
@ -209,7 +190,6 @@ void() door_killed =
self = oself;
};
/*
================
door_touch
@ -217,7 +197,8 @@ door_touch
Prints messages and opens key doors
================
*/
void() door_touch =
void ()
door_touch =
{
if (other.classname != "player")
return;
@ -226,53 +207,48 @@ void() door_touch =
self.owner.attack_finished = time + 2;
if (self.owner.message != "")
{
if (self.owner.message != "") {
centerprint (other, self.owner.message);
sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
}
// key door stuff
// 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)
{
// FIXME: blink key on player's status bar
if ((self.items & other.items) != self.items) {
if (self.owner.items == IT_KEY1) {
switch (world.worldtype) {
case 2:
centerprint (other, "You need the silver keycard");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
else if (world.worldtype == 1)
{
break;
case 1:
centerprint (other, "You need the silver runekey");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
else if (world.worldtype == 0)
{
break;
case 0:
centerprint (other, "You need the silver key");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
default:
break;
}
}
else
{
if (world.worldtype == 2)
{
} else {
switch (world.worldtype) {
case 2:
centerprint (other, "You need the gold keycard");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
else if (world.worldtype == 1)
{
break;
case 1:
centerprint (other, "You need the gold runekey");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
else if (world.worldtype == 0)
{
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
break;
case 0:
centerprint (other, "You need the gold key");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
default:
break;
}
}
return;
@ -285,19 +261,13 @@ void() door_touch =
door_use ();
};
/*
=============================================================================
// SPAWNING FUNCTIONS =========================================================
SPAWNING FUNCTIONS
=============================================================================
*/
entity(vector fmins, vector fmaxs) spawn_field =
entity (vector fmins, vector fmaxs)
spawn_field =
{
local entity trigger;
local vector t1, t2;
local vector t1, t2;
trigger = spawn();
trigger.movetype = MOVETYPE_NONE;
@ -311,8 +281,8 @@ entity(vector fmins, vector fmaxs) spawn_field =
return (trigger);
};
float (entity e1, entity e2) EntitiesTouching =
float (entity e1, entity e2)
EntitiesTouching =
{
if (e1.mins_x > e2.maxs_x)
return FALSE;
@ -329,23 +299,15 @@ float (entity e1, entity e2) EntitiesTouching =
return TRUE;
};
/*
=============
LinkDoors
=============
*/
void() LinkDoors =
void ()
LinkDoors =
{
local entity t, starte;
local entity starte, t;
local vector cmins, cmaxs;
if (self.enemy)
return; // already linked by another door
if (self.spawnflags & 4)
{
if (self.spawnflags & 4) {
self.owner = self.enemy = self;
return; // don't want to link this door
}
@ -356,8 +318,7 @@ void() LinkDoors =
starte = self;
t = self;
do
{
do {
self.owner = starte; // master door
if (self.health)
@ -368,13 +329,11 @@ void() LinkDoors =
starte.message = self.message;
t = find (t, classname, self.classname);
if (!t)
{
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
// shootable, fired, or key doors just needed the owner/enemy
// links, they don't spawn a field
self = self.owner;
if (self.health)
@ -389,8 +348,7 @@ void() LinkDoors =
return;
}
if (EntitiesTouching(self,t))
{
if (EntitiesTouching (self,t)) {
if (t.enemy)
objerror ("cross connected doors");
@ -410,11 +368,9 @@ void() LinkDoors =
if (t.maxs_z > cmaxs_z)
cmaxs_z = t.maxs_z;
}
} while (1 );
} 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.
@ -440,72 +396,67 @@ Key doors are allways wait -1.
4) screechy metal
*/
void() func_door =
void ()
func_door =
{
if (world.worldtype == 0)
{
switch (world.worldtype) {
case 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)
{
break;
case 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)
{
break;
case 2:
precache_sound ("doors/basetry.wav");
precache_sound ("doors/baseuse.wav");
self.noise3 = "doors/basetry.wav";
self.noise4 = "doors/baseuse.wav";
}
else
{
break;
default:
dprint ("no worldtype set!\n");
break;
}
if (self.sounds == 0)
{
switch (self.sounds) {
case 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)
{
break;
case 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)
{
break;
case 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)
{
break;
case 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)
{
break;
case 4:
precache_sound ("doors/ddoor1.wav");
precache_sound ("doors/ddoor2.wav");
self.noise1 = "doors/ddoor2.wav";
self.noise2 = "doors/ddoor1.wav";
default:
break;
}
SetMovedir ();
self.max_health = self.health;
@ -533,12 +484,12 @@ void() func_door =
self.dmg = 2;
self.pos1 = self.origin;
self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
self.pos2 = self.pos1 + self.movedir * (fabs (self.movedir * 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)
{
// 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;
@ -546,8 +497,7 @@ void() func_door =
self.state = STATE_BOTTOM;
if (self.health)
{
if (self.health) {
self.takedamage = DAMAGE_YES;
self.th_die = door_killed;
}
@ -557,27 +507,21 @@ void() func_door =
self.touch = door_touch;
// LinkDoors can't be done until all of the doors have been spawned, so
// the sizes can be detected properly.
// 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 ===============================================================
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;
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
@ -586,49 +530,46 @@ float SECRET_NO_SHOOT = 8; // only opened by trigger
float SECRET_YES_SHOOT = 16; // shootable even if targeted
float SECRET_NEVER = 32; // lock it shut
void () fd_secret_use =
void ()
fd_secret_use =
{
local float temp;
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_NEVER)
return; // it never opens
if (!(self.spawnflags & SECRET_NO_SHOOT))
{
if (!(self.spawnflags & SECRET_NO_SHOOT)) {
//XXX needed? 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.t_width) {
if (self.spawnflags & SECRET_1ST_DOWN)
self. t_width = fabs(v_up * self.size);
self.t_width = fabs (v_up * self.size);
else
self. t_width = fabs(v_right * self.size);
self.t_width = fabs (v_right * self.size);
}
if (!self.t_length)
self. t_length = fabs(v_forward * self.size);
self.t_length = fabs (v_forward * self.size);
if (self.spawnflags & SECRET_1ST_DOWN)
self.dest1 = self.origin - v_up * self.t_width;
@ -636,78 +577,86 @@ void () fd_secret_use =
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);
SUB_CalcMove (self.dest1, self.speed, fd_secret_move1);
sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
};
void (entity attacker, float damage) fd_secret_pain =
void (entity attacker, float damage)
fd_secret_pain =
{
fd_secret_use ();
};
// Wait after first movement...
void () fd_secret_move1 =
void ()
fd_secret_move1 =
{
self.nextthink = self.ltime + 1.0;
self.think = fd_secret_move2;
sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
};
// Start moving sideways w/sound...
void () fd_secret_move2 =
void ()
fd_secret_move2 =
{
sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
SUB_CalcMove(self.dest2, self.speed, fd_secret_move3);
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 =
void ()
fd_secret_move3 =
{
sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
if (!(self.spawnflags & SECRET_OPEN_ONCE))
{
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 =
void ()
fd_secret_move4 =
{
sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
SUB_CalcMove(self.dest1, self.speed, fd_secret_move5);
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 =
void ()
fd_secret_move5 =
{
self.nextthink = self.ltime + 1.0;
self.think = fd_secret_move6;
sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
};
void () fd_secret_move6 =
void ()
fd_secret_move6 =
{
sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
SUB_CalcMove(self.oldorigin, self.speed, fd_secret_done);
sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
SUB_CalcMove (self.oldorigin, self.speed, fd_secret_done);
};
void () fd_secret_done =
void ()
fd_secret_done =
{
if (!self.targetname || self.spawnflags&SECRET_YES_SHOOT)
{
if (!self.targetname || self.spawnflags & SECRET_YES_SHOOT) {
self.health = 10000;
self.takedamage = DAMAGE_YES;
self.th_pain = fd_secret_pain;
self.th_die = fd_secret_use;
}
sound(self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise3, 1, ATTN_NORM);
sound (self, CHAN_NO_PHS_ADD + CHAN_VOICE, self.noise3, 1, ATTN_NORM);
};
void () secret_blocked =
void ()
secret_blocked =
{
if (time < self.attack_finished)
return;
self.attack_finished = time + 0.5;
T_Damage (other, self, self, self.dmg);
};
@ -719,7 +668,8 @@ secret_touch
Prints messages
================
*/
void() secret_touch =
void ()
secret_touch =
{
if (other.classname != "player")
return;
@ -728,14 +678,12 @@ void() secret_touch =
self.attack_finished = time + 2;
if (self.message)
{
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
@ -752,35 +700,35 @@ If a secret door has a targetname, it will only be opened by it's botton or trig
2) metal
3) base
*/
void () func_door_secret =
void ()
func_door_secret =
{
if (self.sounds == 0)
self.sounds = 3;
if (self.sounds == 1)
{
switch (self.sounds) {
case 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)
{
break;
case 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)
{
break;
case 0:
self.sounds = 3;
case 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";
default:
break;
}
if (!self.dmg)
@ -799,8 +747,7 @@ void () func_door_secret =
self.blocked = secret_blocked;
self.speed = 50;
self.use = fd_secret_use;
if ( !self.targetname || self.spawnflags&SECRET_YES_SHOOT)
{
if (!self.targetname || self.spawnflags & SECRET_YES_SHOOT) {
self.health = 10000;
self.takedamage = DAMAGE_YES;
self.th_pain = fd_secret_pain;

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
grapple.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -37,392 +37,349 @@ Morning Star. Depending on latency, performance should be near exact.
*/
// prototypes for WEAPONS.QC functions
float() crandom;
void(vector org, float damage) SpawnBlood;
float () crandom;
void (vector org, float damage) SpawnBlood;
//
// Reset_Grapple - Removes the hook and resets its owner's state.
// expects a pointer to the hook
//
void (entity rhook) Reset_Grapple =
void (entity rhook)
Reset_Grapple =
{
if (rhook.owner == world)
return;
if (rhook.owner == world)
return;
sound (rhook.owner, CHAN_NO_PHS_ADD+CHAN_WEAPON, "weapons/bounce2.wav", 1, ATTN_NORM);
rhook.owner.on_hook = FALSE;
rhook.owner.hook_out = FALSE;
rhook.owner.weaponframe = 0;
rhook.owner.attack_finished = time + 0.25;
rhook.think = SUB_Remove;
rhook.nextthink = time;
sound (rhook.owner, CHAN_NO_PHS_ADD + CHAN_WEAPON, "weapons/bounce2.wav",
1, ATTN_NORM);
rhook.owner.on_hook = FALSE;
rhook.owner.hook_out = FALSE;
rhook.owner.weaponframe = 0;
rhook.owner.attack_finished = time + 0.25;
rhook.think = SUB_Remove;
rhook.nextthink = time;
};
//
// Grapple_Track - Constantly updates the hook's position relative to
// what it's hooked to. Inflicts damage if attached to
// a player that is not on the same team as the hook's
// owner.
//
void () Grapple_Track =
void ()
Grapple_Track =
{
// Release dead targets
if (self.enemy.classname == "player" && self.enemy.health <= 0)
{
self.owner.on_hook = FALSE;
self.owner.attack_finished = time +0.75;
}
// Release dead targets
if (self.enemy.classname == "player" && self.enemy.health <= 0) {
self.owner.on_hook = FALSE;
self.owner.attack_finished = time +0.75;
}
// drop the hook if owner is dead or has released the button
if (!self.owner.on_hook || self.owner.health <= 0)
{
Reset_Grapple (self);
return;
}
// drop the hook if owner is dead or has released the button
if (!self.owner.on_hook || self.owner.health <= 0) {
Reset_Grapple (self);
return;
}
// bring the pAiN!
if (self.enemy.classname == "player")
{
// bring the pAiN!
if (self.enemy.classname == "player") {
// 4.1, if we can't see our enemy, unlock
if (!CanDamage(self.enemy, self.owner)) {
Reset_Grapple(self);
return;
}
// 4.1, if we can't see our enemy, unlock
if (!CanDamage(self.enemy, self.owner)) {
Reset_Grapple(self);
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);
// 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);
T_Damage (self.enemy, self, self.owner, 1);
makevectors (self.v_angle);
SpawnBlood(self.enemy.origin, 1);
}
sound (self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM);
T_Damage (self.enemy, self, self.owner, 1);
makevectors (self.v_angle);
SpawnBlood (self.enemy.origin, 1);
}
// If the hook is not attached to the player, constantly copy
// copy the target's velocity. Velocity copying DOES NOT work properly
// for a hooked client.
if (self.enemy.classname != "player")
self.velocity = self.enemy.velocity;
// If the hook is not attached to the player, constantly copy the target's
// velocity. Velocity copying DOES NOT work properly for a hooked client.
if (self.enemy.classname != "player")
self.velocity = self.enemy.velocity;
self.nextthink = time + 0.1;
self.nextthink = time + 0.1;
};
//
// MakeLink - spawns the chain link entities
//
entity () MakeLink =
entity ()
MakeLink =
{
newmis = spawn ();
newmis = spawn ();
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_NOT;
newmis.owner = self;// SELF is the hook!
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_NOT;
newmis.owner = self; // SELF is the hook!
newmis.avelocity = '200 200 200';
newmis.avelocity = '200 200 200';
setmodel (newmis, "progs/bit.mdl");
setorigin (newmis, self.origin);
setsize (newmis, '0 0 0' , '0 0 0');
setmodel (newmis, "progs/bit.mdl");
setorigin (newmis, self.origin);
setsize (newmis, '0 0 0' , '0 0 0');
return newmis;
return newmis;
};
//
// Remove_Chain - 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 () Remove_Chain =
void ()
Remove_Chain =
{
self.think = SUB_Remove;
self.nextthink = time;
self.think = SUB_Remove;
self.nextthink = time;
if (self.goalentity)
{
self.goalentity.think = SUB_Remove;
self.goalentity.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;
}
}
if (self.goalentity.goalentity) {
self.goalentity.goalentity.think = SUB_Remove;
self.goalentity.goalentity.nextthink = time;
}
}
};
//
// Update_Chain - 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 () Update_Chain =
void ()
Update_Chain =
{
local vector temp;
local vector temp;
if (!self.owner.hook_out)
{
self.think = Remove_Chain;
self.nextthink = time;
return;
}
if (!self.owner.hook_out) {
self.think = Remove_Chain;
self.nextthink = time;
return;
}
temp = (self.owner.hook.origin - self.owner.origin);
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);
// 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;
self.nextthink = time + 0.1;
};
//
// Build_Chain - Builds the chain (linked list)
//
void () Build_Chain =
void ()
Build_Chain =
{
self.goalentity = MakeLink();
self.goalentity.think = Update_Chain;
self.goalentity.nextthink = time + 0.1;
self.goalentity.owner = self.owner;
self.goalentity = MakeLink();
self.goalentity.think = Update_Chain;
self.goalentity.nextthink = time + 0.1;
self.goalentity.owner = self.owner;
self.goalentity.goalentity = MakeLink();
self.goalentity.goalentity.goalentity = MakeLink();
self.goalentity.goalentity = MakeLink ();
self.goalentity.goalentity.goalentity = MakeLink ();
};
//
// Check_Overhead - Makes sure there is sufficient headroom above the player
// so that setorigin doesn't stick them into a wall. I tried
// to compare pointcontents, but that was too flaky.
//
float () Check_Overhead =
float ()
Check_Overhead =
{
local vector src;
local vector end;
makevectors (self.owner.angles);
makevectors (self.owner.angles);
// quick check right above head
traceline (self.owner.origin - '0 0 24', self.owner.origin - '0 0 24',
FALSE, self.owner);
if (trace_fraction != 1.0)
return FALSE;
// The following comparisons could be optimized by doing away with
// SRC and END, and plugging the values directly into the traceline
// function calls. Using SRC and END made debugging easier. You
// decide if it's worth it.
traceline (self.owner.origin - '0 0 24' - v_forward * 16,
self.owner.origin - '0 0 24' - v_forward * 16 + '0 0 58',
FALSE, self.owner);
if (trace_fraction != 1.0)
return FALSE;
// quick check right above head
src = self.owner.origin - '0 0 24';
end = self.owner.origin - '0 0 24';
traceline (src, end, FALSE, self.owner);
if (trace_fraction != 1.0)
return FALSE;
traceline (self.owner.origin - '0 0 24' + v_forward * 16,
self.owner.origin - '0 0 24' + v_forward * 16 + '0 0 58',
FALSE, self.owner);
if (trace_fraction != 1.0)
return FALSE;
src = self.owner.origin - '0 0 24' - v_forward * 16;
end = self.owner.origin - '0 0 24' - v_forward * 16 + '0 0 58';
traceline (src, end, FALSE, self.owner);
if (trace_fraction != 1.0)
return FALSE;
traceline (self.owner.origin - '0 0 24' - v_right * 16,
self.owner.origin - '0 0 24' - v_right * 16 + '0 0 58',
FALSE, self.owner);
if (trace_fraction != 1.0)
return FALSE;
src = self.owner.origin - '0 0 24' + v_forward * 16;
end = self.owner.origin - '0 0 24' + v_forward * 16 + '0 0 58';
traceline (src, end, FALSE, self.owner);
if (trace_fraction != 1.0)
return FALSE;
traceline (self.owner.origin - '0 0 24' + v_right * 16,
self.owner.origin - '0 0 24' + v_right * 16 + '0 0 58',
FALSE, self.owner);
if (trace_fraction != 1.0)
return FALSE;
src = self.owner.origin - '0 0 24' - v_right * 16;
end = self.owner.origin - '0 0 24' - v_right * 16 + '0 0 58';
traceline (src, end, FALSE, self.owner);
if (trace_fraction != 1.0)
return FALSE;
src = self.owner.origin - '0 0 24' + v_right * 16;
end = self.owner.origin - '0 0 24' + v_right * 16 + '0 0 58';
traceline (src, end, FALSE, self.owner);
if (trace_fraction != 1.0)
return FALSE;
return TRUE;
return TRUE;
};
//
// Anchor_Grapple - Tries to anchor the grapple to whatever it touches
//
void () Anchor_Grapple =
void ()
Anchor_Grapple =
{
if (other == self.owner)
return;
if (other == self.owner)
return;
// DO NOT allow the grapple to hook to any projectiles, no matter WHAT!
// if you create new types of projectiles, make sure you use one of the
// classnames below or write code to exclude your new classname so
// grapples will not stick to them.
if (other.classname == "missile" || other.classname == "grenade" ||
other.classname == "spike" || other.classname == "hook")
// DO NOT allow the grapple to hook to any projectiles, no matter WHAT!
// if you create new types of projectiles, make sure you use one of the
// classnames below or write code to exclude your new classname so
// grapples will not stick to them.
if (other.classname == "missile" || other.classname == "grenade"
|| other.classname == "spike" || other.classname == "hook")
return;
// Don't stick the the sky.
if (pointcontents (self.origin) == CONTENT_SKY) {
Reset_Grapple (self);
return;
}
if (other.classname == "player") {
// glance off of teammates
if (other.steam == self.owner.steam)
return;
// Don't stick the the sky.
if (pointcontents(self.origin) == CONTENT_SKY)
{
Reset_Grapple (self);
return;
}
sound (self, CHAN_WEAPON, "player/axhit1.wav", 1, ATTN_NORM);
T_Damage (other, self, self.owner, 10);
if (other.classname == "player")
{
// glance off of teammates
if (other.steam == self.owner.steam)
return;
// make hook invisible since we will be pulling directly towards the
// player the hook hit. Quakeworld makes it too quirky to try to match
// hook's velocity with that of the client that it hit.
setmodel (self, "");
} else {
sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
sound (self, CHAN_WEAPON, "player/axhit1.wav", 1, ATTN_NORM);
T_Damage (other, self, self.owner, 10);
// 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);
// make hook invisible since we will be pulling directly
// towards the player the hook hit. Quakeworld makes it
// too quirky to try to match hook's velocity with that of
// the client that it hit.
setmodel (self, "");
}
else if (other.classname != "player")
{
sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
self.velocity = '0 0 0';
self.avelocity = '0 0 0';
}
// 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);
// conveniently clears the sound channel of the CHAIN1 sound, which is a
// looping sample and would continue to play. Tink1 is the least offensive
// choice, ass NULL.WAV loops and clogs the channel with silence
sound (self.owner, CHAN_NO_PHS_ADD + CHAN_WEAPON,
"weapons/tink1.wav", 1, ATTN_NORM);
self.velocity = '0 0 0';
self.avelocity = '0 0 0';
}
// conveniently clears the sound channel of the CHAIN1 sound,
// which is a looping sample and would continue to play. Tink1 is
// the least offensive choice, ass NULL.WAV loops and clogs the
// channel with silence
sound (self.owner, CHAN_NO_PHS_ADD+CHAN_WEAPON, "weapons/tink1.wav", 1, ATTN_NORM);
if (!self.owner.button0)
{
Reset_Grapple (self);
return;
}
if (!self.owner.button0) {
Reset_Grapple (self);
return;
}
/*
// our last chance to avoid being picked up off of the ground.
// check over the client's head to make sure there is one unit
// clearance so we can lift him off of the ground.
test = Check_Overhead ();
if (!test)
{
Reset_Grapple (self);
return;
}
// our last chance to avoid being picked up off of the ground. check over
// the client's head to make sure there is one unit clearance so we can
// lift him off of the ground.
test = Check_Overhead ();
if (!test) {
Reset_Grapple (self);
return;
}
*/
if (self.owner.flags & FL_ONGROUND)
{
self.owner.flags = self.owner.flags - FL_ONGROUND;
// setorigin(self.owner,self.owner.origin + '0 0 1');
}
if (self.owner.flags & FL_ONGROUND) {
self.owner.flags &= ~FL_ONGROUND;
// setorigin (self.owner,self.owner.origin + '0 0 1');
}
self.owner.on_hook = TRUE;
self.owner.on_hook = TRUE;
sound (self.owner, CHAN_WEAPON, "weapons/chain2.wav", 1, ATTN_NORM);
sound (self.owner, CHAN_WEAPON, "weapons/chain2.wav", 1, ATTN_NORM);
// 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;
// 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 = Grapple_Track;
self.nextthink = time;
self.solid = SOLID_NOT;
self.touch = SUB_Null;
self.enemy = other; // remember this guy!
self.think = Grapple_Track;
self.nextthink = time;
self.solid = SOLID_NOT;
self.touch = SUB_Null;
};
//
// Throw_Grapple - called from WEAPONS.QC, 'fires' the grapple
//
void () Throw_Grapple =
void ()
Throw_Grapple =
{
if (self.hook_out)// reject subsequent calls from player.qc
return;
if (self.hook_out) // reject subsequent calls from player.qc
return;
msg_entity = self;
msg_entity = self;
WriteByte (MSG_ONE, SVC_SMALLKICK);
// chain out sound (loops)
sound (self, CHAN_WEAPON, "weapons/chain1.wav", 1, ATTN_NORM);
// 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";
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';
makevectors (self.v_angle);
newmis.velocity = v_forward * 800;
newmis.avelocity = '0 0 -500';
newmis.touch = Anchor_Grapple;
newmis.think = Build_Chain;
newmis.nextthink = time + 0.1;// don't jam newmis and links into same packet
newmis.touch = Anchor_Grapple;
newmis.think = Build_Chain;
setmodel (newmis,"progs/star.mdl");
setorigin (newmis, self.origin + v_forward * 16 + '0 0 16');
setsize(newmis, '0 0 0' , '0 0 0 ');
// don't jam newmis & links into same packet
newmis.nextthink = time + 0.1;
self.hook_out = TRUE;
setmodel (newmis,"progs/star.mdl");
setorigin (newmis, self.origin + v_forward * 16 + '0 0 16');
setsize(newmis, '0 0 0' , '0 0 0 ');
self.hook_out = TRUE;
};
//
// Service_Grapple - called each frame by CLIENT.QC if client is ON_HOOK
//
void () Service_Grapple =
void ()
Service_Grapple =
{
local vector hook_dir = '0 0 0';
local vector hook_dir = '0 0 0';
// drop the hook if player lets go of button
if (!self.button0)
{
if (self.weapon == IT_GRAPPLE) {
Reset_Grapple (self.hook);
return;
}
}
// If hooked to a player, track them directly!
if (self.hook.enemy.classname == "player")
hook_dir = (self.hook.enemy.origin - self.origin);
// else, track to hook
else if (self.hook.enemy.classname != "player")
hook_dir = (self.hook.origin - self.origin);
// drop the hook if player lets go of button
if (!self.button0) {
if (self.weapon == IT_GRAPPLE) {
Reset_Grapple (self.hook);
return;
}
}
self.velocity = normalize(hook_dir) * 750;
if ( vlen(hook_dir) <= 100 && 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 = Remove_Chain;
self.hook.goalentity.nextthink = time;
}
// If hooked to a player, track them directly!
if (self.hook.enemy.classname == "player")
hook_dir = (self.hook.enemy.origin - self.origin);
else if (self.hook.enemy.classname != "player") // track to hook
hook_dir = (self.hook.origin - self.origin);
sound(self, CHAN_NO_PHS_ADD+CHAN_WEAPON, "weapons/chain3.wav", 1, ATTN_NORM);
self.lefty = FALSE;// we've reset the sound channel.
}
self.velocity = normalize (hook_dir) * 750;
if (vlen(hook_dir) <= 100 && 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 = Remove_Chain;
self.hook.goalentity.nextthink = time;
}
sound (self, CHAN_NO_PHS_ADD + CHAN_WEAPON, "weapons/chain3.wav", 1,
ATTN_NORM);
self.lefty = FALSE; // we've reset the sound channel.
}
};

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
ident.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -31,42 +31,40 @@
// This is called with the player who wants to know whose in front
// of him as "self." I call it with an impulse in weapons.qc
entity(float disp) identify_player =
entity (float disp)
identify_player =
{
// e is a temp entity; guy is our current best guess
// as to at whom the player is pointing
local entity e, guy = world;
local entity e, guy = world;
// The best "closeness" heuristic so far.
local float closeness = -1;
local float closeness = -1;
// Temp vars.
local vector diff, point;
local float currclose;
local float currclose;
local vector diff, point;
// Walk the list of players...
e=find(world, classname, "player");
while (e!=world)
{
e = find (world, classname, "player");
while (e != world) {
// Get a vector pointing from the viewer to the current
// player under consideration
diff=e.origin - self.origin;
diff = e.origin - self.origin;
// Normalize it since we only care where he's pointing,
// not how far away the guy is.
diff=normalize(diff);
diff = normalize (diff);
// Normalize self.angles so we can do a length-independent
// consideration
point=normalize(self.angles);
point = normalize (self.angles);
// Find the different between the current player's angle
// and the viewer's vision angle
diff=diff - point;
diff -= point;
// The length is going to be our definition of closeness
currclose=vlen(diff);
traceline(self.origin, e.origin, FALSE, self);
currclose = vlen (diff);
traceline (self.origin, e.origin, FALSE, self);
if (trace_ent == e) {
if (closeness == -1) {
closeness = currclose;
@ -76,18 +74,18 @@ entity(float disp) identify_player =
guy = e;
}
}
e=find(e, classname, "player");
e = find (e, classname, "player");
}
// Now we display.
if (disp==0)
if (disp == 0)
return guy;
if (guy == world)
{
if (guy == world) {
TeamPlayerUpdate(self, "You're not looking at anyone!");
return world;
}
TeamPlayerUpdate2(self, "You are looking at ", guy.netname);
TeamPlayerUpdate2 (self, "You are looking at ", guy.netname);
return guy;
};

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
misc.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -26,15 +26,17 @@
/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4)
Used as a positional target for spotlights, etc.
*/
void() info_null =
void ()
info_null =
{
remove(self);
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 =
void ()
info_notnull =
{
};
@ -42,17 +44,15 @@ void() info_notnull =
float START_OFF = 1;
void() light_use =
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;
if (self.spawnflags & START_OFF) {
lightstyle (self.style, "m");
self.spawnflags &= ~START_OFF;
} else {
lightstyle (self.style, "a");
self.spawnflags |= START_OFF;
}
};
@ -62,21 +62,20 @@ Default light value is 300
Default style is 0
If targeted, it will toggle between on or off.
*/
void() light =
void ()
light =
{
if (!self.targetname)
{ // inert light
remove(self);
if (!self.targetname) { // inert light
remove (self);
return;
}
if (self.style >= 32)
{
if (self.style >= 32) {
self.use = light_use;
if (self.spawnflags & START_OFF)
lightstyle(self.style, "a");
lightstyle (self.style, "a");
else
lightstyle(self.style, "m");
lightstyle (self.style, "m");
}
};
@ -87,15 +86,15 @@ Default style is 0
If targeted, it will toggle between on or off.
Makes steady fluorescent humming sound
*/
void() light_fluoro =
void ()
light_fluoro =
{
if (self.style >= 32)
{
if (self.style >= 32) {
self.use = light_use;
if (self.spawnflags & START_OFF)
lightstyle(self.style, "a");
lightstyle (self.style, "a");
else
lightstyle(self.style, "m");
lightstyle (self.style, "m");
}
precache_sound ("ambience/fl_hum1.wav");
@ -108,7 +107,8 @@ Default light value is 300
Default style is 10
Makes sparking, broken fluorescent sound
*/
void() light_fluorospark =
void ()
light_fluorospark =
{
if (!self.style)
self.style = 10;
@ -122,17 +122,19 @@ Sphere globe light.
Default light value is 300
Default style is 0
*/
void() light_globe =
void ()
light_globe =
{
precache_model ("progs/s_light.spr");
setmodel (self, "progs/s_light.spr");
makestatic (self);
};
void() FireAmbient =
void ()
FireAmbient =
{
precache_sound ("ambience/fire1.wav");
// attenuate fast
// attenuate fast
ambientsound (self.origin, "ambience/fire1.wav", 0.5, ATTN_STATIC);
};
@ -141,7 +143,8 @@ Short wall torch
Default light value is 200
Default style is 0
*/
void() light_torch_small_walltorch =
void ()
light_torch_small_walltorch =
{
precache_model ("progs/flame.mdl");
setmodel (self, "progs/flame.mdl");
@ -152,7 +155,8 @@ void() light_torch_small_walltorch =
/*QUAKED light_flame_large_yellow (0 1 0) (-10 -10 -12) (12 12 18)
Large yellow flame ball
*/
void() light_flame_large_yellow =
void ()
light_flame_large_yellow =
{
precache_model ("progs/flame2.mdl");
setmodel (self, "progs/flame2.mdl");
@ -164,7 +168,8 @@ void() light_flame_large_yellow =
/*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 =
void ()
light_flame_small_yellow =
{
precache_model ("progs/flame2.mdl");
setmodel (self, "progs/flame2.mdl");
@ -175,7 +180,8 @@ void() light_flame_small_yellow =
/*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 =
void ()
light_flame_small_white =
{
precache_model ("progs/flame2.mdl");
setmodel (self, "progs/flame2.mdl");
@ -185,35 +191,25 @@ void() light_flame_small_white =
//============================================================================
/*QUAKED misc_fireball (0 .5 .8) (-8 -8 -8) (8 8 8)
Lava Balls
*/
void() fire_fly;
void() fire_touch;
void() misc_fireball =
void ()
fire_touch =
{
precache_model ("progs/lavaball.mdl");
self.classname = "fireball";
self.nextthink = time + (random() * 5);
self.think = fire_fly;
if (!self.speed)
self.speed = 1000;
T_Damage (other, self, self, 20);
remove (self);
};
void() fire_fly =
void ()
fire_fly =
{
local entity fireball;
local entity fireball;
fireball = spawn();
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.velocity_x = 100 * random () - 50;
fireball.velocity_y = 100 * random () - 50;
fireball.velocity_z = self.speed + 200 * random ();
fireball.classname = "fireball";
setmodel (fireball, "progs/lavaball.mdl");
setsize (fireball, '0 0 0', '0 0 0');
@ -222,43 +218,46 @@ local entity fireball;
fireball.think = SUB_Remove;
fireball.touch = fire_touch;
self.nextthink = time + (random() * 5) + 3;
self.nextthink = time + (5 * random ()) + 3;
self.think = fire_fly;
};
void() fire_touch =
/*QUAKED misc_fireball (0 .5 .8) (-8 -8 -8) (8 8 8)
Lava Balls
*/
void ()
misc_fireball =
{
T_Damage (other, self, self, 20);
remove(self);
precache_model ("progs/lavaball.mdl");
self.classname = "fireball";
self.nextthink = time + (5 * random ());
self.think = fire_fly;
if (!self.speed)
self.speed = 1000;
};
//============================================================================
void() barrel_explode =
void ()
barrel_explode =
{
self.takedamage = DAMAGE_NO;
self.classname = "explo_box";
// did say self.owner
T_RadiusDamage (self, self, 160, world);
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+32);
WriteBytes (MSG_BROADCAST, SVC_TEMPENTITY, TE_EXPLOSION);
self.origin_z += 32;
WriteCoordV (MSG_BROADCAST, self.origin);
remove (self);
};
/*QUAKED misc_explobox (0 .5 .8) (0 0 0) (32 32 64)
TESTING THING
*/
void() misc_explobox =
void ()
misc_explobox =
{
local float oldz;
local float oldz;
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_NONE;
@ -270,28 +269,24 @@ void() misc_explobox =
self.th_die = barrel_explode;
self.takedamage = DAMAGE_AIM;
self.origin_z = self.origin_z + 2;
self.origin_z += 2;
oldz = self.origin_z;
droptofloor();
if (oldz - self.origin_z > 250)
{
droptofloor ();
if (oldz - self.origin_z > 250) {
dprint ("item fell out of level at ");
dprint (vtos(self.origin));
dprint ("\n");
remove(self);
remove (self);
}
};
/*QUAKED misc_explobox2 (0 .5 .8) (0 0 0) (32 32 64)
Smaller exploding box, REGISTERED ONLY
*/
void() misc_explobox2 =
void ()
misc_explobox2 =
{
local float oldz;
local float oldz;
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_NONE;
@ -305,9 +300,8 @@ void() misc_explobox2 =
self.origin_z = self.origin_z + 2;
oldz = self.origin_z;
droptofloor();
if (oldz - self.origin_z > 250)
{
droptofloor ();
if (oldz - self.origin_z > 250) {
dprint ("item fell out of level at ");
dprint (vtos(self.origin));
dprint ("\n");
@ -320,52 +314,46 @@ void() misc_explobox2 =
float SPAWNFLAG_SUPERSPIKE = 1;
float SPAWNFLAG_LASER = 2;
void() Laser_Touch =
void ()
Laser_Touch =
{
local vector org;
local vector org;
if (other == self.owner)
return; // don't explode on owner
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
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);
org = self.origin - 8 * normalize (self.velocity);
if (other.health)
{
if (other.health) {
SpawnBlood (org, 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);
} else {
WriteBytes (MSG_BROADCAST, SVC_TEMPENTITY, TE_GUNSHOT);
WriteCoordV (MSG_BROADCAST, org);
}
remove(self);
remove (self);
};
void(vector org, vector vec) LaunchLaser =
void (vector org, vector vec)
LaunchLaser =
{
if (self.classname == "monster_enforcer")
sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
vec = normalize(vec);
vec = normalize (vec);
newmis = spawn();
newmis = spawn ();
newmis.owner = self;
newmis.movetype = MOVETYPE_FLY;
newmis.solid = SOLID_BBOX;
newmis.effects = EF_DIMLIGHT;
newmis.classname = "missile";
newmis.classname = "missile";
setmodel (newmis, "progs/laser.mdl");
setsize (newmis, '0 0 0', '0 0 0');
@ -373,23 +361,21 @@ void(vector org, vector vec) LaunchLaser =
setorigin (newmis, org);
newmis.velocity = vec * 600;
newmis.angles = vectoangles(newmis.velocity);
newmis.angles = vectoangles (newmis.velocity);
newmis.nextthink = time + 5;
newmis.think = SUB_Remove;
newmis.touch = Laser_Touch;
};
void() spikeshooter_use =
void ()
spikeshooter_use =
{
if (self.spawnflags & SPAWNFLAG_LASER)
{
if (self.spawnflags & SPAWNFLAG_LASER) {
return;
sound (self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM);
LaunchLaser (self.origin, self.movedir);
}
else
{
// sound (self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM);
// LaunchLaser (self.origin, self.movedir);
} else {
sound (self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM);
launch_spike (self.origin, self.movedir);
newmis.velocity = self.movedir * 500;
@ -398,79 +384,67 @@ void() spikeshooter_use =
}
};
void() shooter_think =
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
When triggered, fires a spike in the direction set in QuakeEd.
Laser is only for REGISTERED.
*/
void() trap_spikeshooter =
void ()
trap_spikeshooter =
{
SetMovedir ();
self.use = spikeshooter_use;
if (self.spawnflags & SPAWNFLAG_LASER)
{
if (self.spawnflags & SPAWNFLAG_LASER) {
precache_model2 ("progs/laser.mdl");
precache_sound2 ("enforcer/enfire.wav");
precache_sound2 ("enforcer/enfstop.wav");
}
else
} 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 =
void ()
trap_shooter =
{
trap_spikeshooter ();
if (self.wait == 0)
self.wait = 1;
self.nextthink = self.nextthink + self.wait + self.ltime;
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 =
void ()
air_bubbles =
{
remove (self);
};
void() make_bubbles =
void ()
make_bubbles =
{
local entity bubble;
local entity bubble;
bubble = spawn();
bubble = spawn ();
setmodel (bubble, "progs/s_bubble.spr");
setorigin (bubble, self.origin);
bubble.movetype = MOVETYPE_NOCLIP;
@ -483,14 +457,15 @@ local entity bubble;
bubble.frame = 0;
bubble.cnt = 0;
setsize (bubble, '-8 -8 -8', '8 8 8');
self.nextthink = time + random() + 0.5;
self.nextthink = time + random () + 0.5;
self.think = make_bubbles;
};
void() bubble_split =
void ()
bubble_split =
{
local entity bubble;
bubble = spawn();
local entity bubble;
bubble = spawn ();
setmodel (bubble, "progs/s_bubble.spr");
setorigin (bubble, self.origin);
bubble.movetype = MOVETYPE_NOCLIP;
@ -509,49 +484,43 @@ local entity bubble;
remove (self);
};
void() bubble_remove =
void ()
bubble_remove =
{
if (other.classname == self.classname)
{
if (other.classname == self.classname) {
// dprint ("bump");
return;
}
remove(self);
remove (self);
};
void() bubble_bob =
void ()
bubble_bob =
{
local float rnd1, rnd2, rnd3;
self.cnt = self.cnt + 1;
self.cnt++;
if (self.cnt == 4)
bubble_split();
if (self.cnt == 20)
remove(self);
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;
self.velocity_x += 20 * random () - 10;
if (self.velocity_x > 10)
self.velocity_x = 5;
if (self.velocity_x < -10)
self.velocity_x = -5;
self.velocity_y += 20 * random () - 10;
if (self.velocity_y > 10)
self.velocity_y = 5;
if (self.velocity_y < -10)
self.velocity_y = -5;
self.velocity_z += 10 * random () + 10;
if (self.velocity_z < 10)
self.velocity_z = 15;
if (self.velocity_z > 30)
self.velocity_z = 25;
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;
};
@ -560,12 +529,10 @@ local float rnd1, rnd2, rnd3;
~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/
/*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8)
Just for the debugging level. Don't use
Just for the debugging level. Don't use.
*/
void() viewthing =
void ()
viewthing =
{
self.movetype = MOVETYPE_NONE;
self.solid = SOLID_NOT;
@ -573,16 +540,10 @@ void() viewthing =
setmodel (self, "progs/player.mdl");
};
// SIMPLE BMODELS =============================================================
/*
==============================================================================
SIMPLE BMODELS
==============================================================================
*/
void() func_wall_use =
void ()
func_wall_use =
{ // change to alternate textures
self.frame = 1 - self.frame;
};
@ -602,12 +563,11 @@ void() func_wall =
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 =
void ()
func_illusionary =
{
self.angles = '0 0 0';
self.movetype = MOVETYPE_NONE;
@ -619,8 +579,8 @@ void() func_illusionary =
/*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 =
void ()
func_episodegate =
{
if (!(serverflags & self.spawnflags))
return; // can still enter episode
@ -635,11 +595,12 @@ void() func_episodegate =
/*QUAKED func_bossgate (0 .5 .8) ?
This bmodel appears unless players have all of the episode sigils.
*/
void() func_bossgate =
void ()
func_bossgate =
{
if ( (serverflags & 15) == 15 || gamestart)
if ((serverflags & 15) == 15 || gamestart)
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;
@ -648,9 +609,11 @@ void() func_bossgate =
};
//============================================================================
/*QUAKED ambient_suck_wind (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_suck_wind =
void ()
ambient_suck_wind =
{
precache_sound ("ambience/suck1.wav");
ambientsound (self.origin, "ambience/suck1.wav", 1, ATTN_STATIC);
@ -658,7 +621,8 @@ void() ambient_suck_wind =
/*QUAKED ambient_drone (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_drone =
void ()
ambient_drone =
{
precache_sound ("ambience/drone6.wav");
ambientsound (self.origin, "ambience/drone6.wav", 0.5, ATTN_STATIC);
@ -666,49 +630,62 @@ void() ambient_drone =
/*QUAKED ambient_flouro_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_flouro_buzz =
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 =
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 =
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 =
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 =
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 =
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 =
void ()
ambient_swamp2 =
{
precache_sound ("ambience/swamp2.wav");
ambientsound (self.origin, "ambience/swamp2.wav", 0.5, ATTN_STATIC);
@ -716,7 +693,8 @@ void() ambient_swamp2 =
//============================================================================
void() noise_think =
void ()
noise_think =
{
self.nextthink = time + 0.5;
sound (self, 1, "enforcer/enfire.wav", 1, ATTN_NORM);
@ -729,12 +707,10 @@ void() noise_think =
};
/*QUAKED misc_noisemaker (1 0.5 0) (-10 -10 -10) (10 10 10)
For optimzation testing, starts a lot of sounds.
*/
void() misc_noisemaker =
void ()
misc_noisemaker =
{
precache_sound2 ("enforcer/enfire.wav");
precache_sound2 ("enforcer/enfstop.wav");

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
models.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -22,14 +22,7 @@
$Id$
*/
/*
===============================================================================
WORLD WEAPONS
===============================================================================
*/
// WORLD WEAPONS ==============================================================
$modelname g_shot
$cd id1/models/g_shot
@ -39,7 +32,6 @@ $base base
$skin skin
$frame shot1
$modelname g_nail
$cd id1/models/g_nail
$flags 8 // client side rotate
@ -48,7 +40,6 @@ $base base
$skin skin
$frame shot1
$modelname g_nail2
$cd id1/models/g_nail2
$flags 8 // client side rotate
@ -57,7 +48,6 @@ $base base
$skin skin
$frame shot2
$modelname g_rock
$cd id1/models/g_rock
$flags 8 // client side rotate
@ -66,7 +56,6 @@ $base base
$skin skin
$frame shot1
$modelname g_rock2
$cd id1/models/g_rock2
$flags 8 // client side rotate
@ -83,13 +72,7 @@ $base base
$skin skin
$frame shot1
/*
===============================================================================
VIEW WEAPONS
===============================================================================
*/
// VIEW WEAPONS ===============================================================
$modelname v_axe
$cd id1/models/v_axe
@ -98,7 +81,6 @@ $base base
$skin skin
$frame frame1 frame2 frame3 frame4 frame5 frame6 frame7 frame8 frame9
$modelname v_shot
$cd id1/models/v_shot
$origin 0 0 54
@ -106,7 +88,6 @@ $base base
$skin skin
$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7
$modelname v_shot2
$cd id1/models/v_shot2
$origin 0 0 56
@ -114,7 +95,6 @@ $base base
$skin skin
$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7
$modelname v_rock2
$cd id1/models/v_rock2
$origin 0 0 54
@ -122,7 +102,6 @@ $base base
$skin skin
$frame shot1 shot2 shot3 shot4 shot5 shot6 shot6
$modelname v_rock
$cd id1/models/v_rock
$origin 0 0 54
@ -130,7 +109,6 @@ $base base
$skin skin
$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7
$modelname v_nail2
$cd id1/models/v_nail2
$origin 0 0 54
@ -138,7 +116,6 @@ $base base
$skin skin
$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7 shot8 shot9
$modelname v_nail
$cd id1/models/v_nail
$origin 0 0 54
@ -153,14 +130,7 @@ $base base
$skin skin
$frame shot1 shot2 shot3 shot4 shot5
/*
===============================================================================
ITEMS
===============================================================================
*/
// ITEMS ======================================================================
$modelname w_g_key
$cd id1/models/w_g_key
@ -204,7 +174,6 @@ $base base
$skin skin
$frame frame1
$modelname quaddama
$cd id1/models/quaddama
$flags 8 // client side rotate
@ -226,12 +195,14 @@ $base base
$skin skin
$frame frame1
//modelname jetpack
//cd id1/models/jetpack
//flags 8 // client side rotate
//base base
//skin skin
//frame frame1
/*
modelname jetpack
cd id1/models/jetpack
flags 8 // client side rotate
base base
skin skin
frame frame1
*/
$modelname cube
$cd id1/models/cube
@ -282,14 +253,7 @@ $base base
$skin skin
$frame frame1
/*
===============================================================================
GIBS
===============================================================================
*/
// GIBS =======================================================================
$modelname gib1
$cd id1/models/gib1
@ -299,7 +263,6 @@ $base base
$skin skin
$frame frame1
// torso
$modelname gib2
$cd id1/models/gib2
@ -317,9 +280,7 @@ $base base
$skin skin
$frame frame1
// heads
$modelname h_player
$cd id1/models/h_player
$flags 4 // EF_GIB
@ -416,13 +377,7 @@ $base base
$skin skin
$frame frame1
/*
===============================================================================
MISC
===============================================================================
*/
// MISC =======================================================================
$modelname armor
$cd id1/models/armor
@ -606,4 +561,3 @@ $origin 0 0 24
$base base
$skin skin
$frame frame1

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
plats.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -22,24 +22,21 @@
$Id$
*/
void() plat_center_touch;
void() plat_outside_touch;
void() plat_trigger_use;
void() plat_go_up;
void() plat_go_down;
void() plat_crush;
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 =
void ()
plat_spawn_inside_trigger =
{
local entity trigger;
local vector tmin, tmax;
//
// middle trigger
//
// middle trigger
trigger = spawn();
trigger.touch = plat_center_touch;
trigger.movetype = MOVETYPE_NONE;
@ -52,13 +49,11 @@ void() plat_spawn_inside_trigger =
if (self.spawnflags & PLAT_LOW_TRIGGER)
tmax_z = tmin_z + 8;
if (self.size_x <= 50)
{
if (self.size_x <= 50) {
tmin_x = (self.mins_x + self.maxs_x) / 2;
tmax_x = tmin_x + 1;
}
if (self.size_y <= 50)
{
if (self.size_y <= 50) {
tmin_y = (self.mins_y + self.maxs_y) / 2;
tmax_y = tmin_y + 1;
}
@ -66,7 +61,8 @@ void() plat_spawn_inside_trigger =
setsize (trigger, tmin, tmax);
};
void() plat_hit_top =
void ()
plat_hit_top =
{
sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_TOP;
@ -74,31 +70,34 @@ void() plat_hit_top =
self.nextthink = self.ltime + 3;
};
void() plat_hit_bottom =
void ()
plat_hit_bottom =
{
sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_BOTTOM;
};
void() plat_go_down =
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 =
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 =
void ()
plat_center_touch =
{
if (other.classname != "player")
return;
if (other.health <= 0)
return;
@ -113,31 +112,33 @@ void() plat_center_touch =
self.cnt = time + 2;
};
void() plat_outside_touch =
void ()
plat_outside_touch =
{
if (other.classname != "player")
return;
if (other.health <= 0)
return;
//dprint ("plat_outside_touch\n");
// dprint ("plat_outside_touch\n");
self = self.enemy;
if (self.state == STATE_TOP)
plat_go_down ();
};
void() plat_trigger_use =
void ()
plat_trigger_use =
{
if (self.think)
return; // allready activated
plat_go_down();
};
void() plat_crush =
void ()
plat_crush =
{
//dprint ("plat_crush\n");
// dprint ("plat_crush\n");
T_Damage (other, self, self, 1);
@ -145,10 +146,11 @@ void() plat_crush =
plat_go_down ();
else if (self.state == STATE_DOWN)
plat_go_up ();
// objerror ("plat_crush: bad self.state\n");
// objerror ("plat_crush: bad self.state\n");
};
void() plat_use =
void ()
plat_use =
{
self.use = SUB_Null;
if (self.state != STATE_UP)
@ -156,7 +158,6 @@ void() plat_use =
plat_go_down();
};
/*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER
speed default 150
@ -169,10 +170,8 @@ Set "sounds" to one of the following:
1) base fast
2) chain slow
*/
void() func_plat =
void ()
func_plat =
{
if (!self.t_length)
self.t_length = 80;
@ -181,25 +180,24 @@ void() func_plat =
if (self.sounds == 0)
self.sounds = 2;
// FIX THIS TO LOAD A GENERIC PLAT SOUND
if (self.sounds == 1)
{
switch (self.sounds) {
case 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)
{
break;
case 0: // FIX THIS TO LOAD A GENERIC PLAT SOUND
case 2:
precache_sound ("plats/medplat1.wav");
precache_sound ("plats/medplat2.wav");
self.noise = "plats/medplat1.wav";
self.noise1 = "plats/medplat2.wav";
default:
break;
}
self.mangle = self.angles;
self.angles = '0 0 0';
@ -214,7 +212,7 @@ void() func_plat =
if (!self.speed)
self.speed = 150;
// pos1 is the top position, pos2 is the bottom
// pos1 is the top position, pos2 is the bottom
self.pos1 = self.origin;
self.pos2 = self.origin;
if (self.height)
@ -226,13 +224,10 @@ void() func_plat =
plat_spawn_inside_trigger (); // the "start moving" trigger
if (self.targetname)
{
if (self.targetname) {
self.state = STATE_UP;
self.use = plat_use;
}
else
{
} else {
setorigin (self, self.pos2);
self.state = STATE_BOTTOM;
}
@ -240,37 +235,40 @@ void() func_plat =
//============================================================================
void() train_next;
void() func_train_find;
void () train_next;
void () func_train_find;
void() train_blocked =
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 =
void ()
train_use =
{
if (self.think != func_train_find)
return; // already activated
train_next();
};
void() train_wait =
void ()
train_wait =
{
if (self.wait)
{
if (self.wait) {
self.nextthink = self.ltime + self.wait;
sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise, 1, ATTN_NORM);
}
else
} else
self.nextthink = self.ltime + 0.1;
self.think = train_next;
};
void() train_next =
void ()
train_next =
{
local entity targ;
@ -286,16 +284,16 @@ void() train_next =
SUB_CalcMove (targ.origin - self.mins, self.speed, train_wait);
};
void() func_train_find =
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
if (!self.targetname) {
// not triggered, so start immediately
self.nextthink = self.ltime + 0.1;
self.think = train_next;
}
@ -310,9 +308,9 @@ speed default 100
dmg default 2
sounds
1) ratchet metal
*/
void() func_train =
void ()
func_train =
{
if (!self.speed)
self.speed = 100;
@ -321,20 +319,20 @@ void() func_train =
if (!self.dmg)
self.dmg = 2;
if (self.sounds == 0)
{
switch (self.sounds) {
case 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)
{
break;
case 1:
self.noise = ("plats/train2.wav");
precache_sound ("plats/train2.wav");
self.noise1 = ("plats/train1.wav");
precache_sound ("plats/train1.wav");
default:
break;
}
self.cnt = 1;
@ -348,8 +346,8 @@ void() func_train =
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
// 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;
};
@ -357,7 +355,8 @@ void() func_train =
/*QUAKED misc_teleporttrain (0 .5 .8) (-8 -8 -8) (8 8 8)
This is used for the final bos
*/
void() misc_teleporttrain =
void ()
misc_teleporttrain =
{
if (!self.speed)
self.speed = 100;
@ -381,9 +380,8 @@ void() misc_teleporttrain =
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
// 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;
};

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
player.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -22,50 +22,34 @@
$Id$
*/
void() bubble_bob;
void() player_chain5;
void() player_chain4;
/*
==============================================================================
void () bubble_bob;
void () player_chain5;
void () player_chain4;
PLAYER
==============================================================================
*/
// PLAYER =====================================================================
$cd 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
@ -84,9 +68,7 @@ $frame deathd8 deathd9
$frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7
$frame deathe8 deathe9
//
// attacks
//
$frame nailatt1 nailatt2
$frame light1 light2
@ -103,33 +85,25 @@ $frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6
$frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6
// PLAYER =====================================================================
/*
==============================================================================
PLAYER
==============================================================================
*/
void () player_run;
void() player_run;
void() player_stand1 =[ $axstnd1, player_stand1 ]
void ()
player_stand1 =[ $axstnd1, player_stand1 ]
{
self.weaponframe=0;
if (self.velocity_x || self.velocity_y)
{
self.walkframe=0;
player_run();
self.weaponframe = 0;
if (self.velocity_x || self.velocity_y) {
self.walkframe = 0;
player_run ();
return;
}
if (self.weapon == IT_AXE || self.weapon == IT_GRAPPLE)
{
if (self.weapon == IT_AXE || self.weapon == IT_GRAPPLE) {
if (self.walkframe >= 12)
self.walkframe = 0;
self.frame = $axstnd1 + self.walkframe;
}
else
{
} else {
if (self.walkframe >= 5)
self.walkframe = 0;
self.frame = $stand1 + self.walkframe;
@ -137,24 +111,21 @@ void() player_stand1 =[ $axstnd1, player_stand1 ]
self.walkframe = self.walkframe + 1;
};
void() player_run =[ $rockrun1, player_run ]
void ()
player_run =[ $rockrun1, player_run ]
{
self.weaponframe=0;
if (!self.velocity_x && !self.velocity_y)
{
self.walkframe=0;
player_stand1();
self.weaponframe = 0;
if (!self.velocity_x && !self.velocity_y) {
self.walkframe = 0;
player_stand1 ();
return;
}
if (self.weapon == IT_AXE || self.weapon == IT_GRAPPLE)
{
if (self.weapon == IT_AXE || self.weapon == IT_GRAPPLE) {
if (self.walkframe >= 6)
self.walkframe = 0;
self.frame = $axrun1 + self.walkframe;
}
else
{
} else {
if (self.walkframe >= 6)
self.walkframe = 0;
self.frame = self.frame + self.walkframe;
@ -162,15 +133,18 @@ void() player_run =[ $rockrun1, player_run ]
self.walkframe = self.walkframe + 1;
};
void()muzzleflash =
void ()
muzzleflash =
{
WriteByte (MSG_MULTICAST, SVC_MUZZLEFLASH);
WriteEntity (MSG_MULTICAST, self);
multicast (self.origin, MULTICAST_PVS);
};
void() player_shot1 = [$shotatt1, player_shot2 ] {self.weaponframe=1;muzzleflash();};
void() player_shot1 = [$shotatt1, player_shot2 ] {
self.weaponframe = 1;
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;};
@ -179,115 +153,140 @@ 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_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_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_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_axed3 = [$axattd3, player_axed4 ] {
self.weaponframe = 7;
W_FireAxe ();
};
void() player_axed4 = [$axattd4, player_run ] {self.weaponframe=8;};
//============================================================================
void() player_chain1= [$axattd1, player_chain2 ] {self.weaponframe=2;Throw_Grapple();};
void() player_chain1= [$axattd1, player_chain2 ] {
self.weaponframe = 2;
Throw_Grapple ();
};
void() player_chain2= [$axattd2, player_chain3 ] {self.weaponframe=3;};
void() player_chain3= [$axattd3, player_chain3 ]
{
self.weaponframe=3;
if (!self.hook_out) {
player_chain5 ();
return;
}
self.weaponframe=3;
if (!self.hook_out)
{
player_chain5();
return;
}
if (vlen(self.velocity) >= 750)
{
player_chain4();
return;
}
if (vlen (self.velocity) >= 750) {
player_chain4 ();
return;
}
};
void() player_chain4= [$deathc4, player_chain4 ]
void ()
player_chain4= [$deathc4, player_chain4 ]
{
self.weaponframe=4;
if (!self.hook_out)
{
player_chain5();
return;
}
if (vlen(self.velocity) < 750)
{
player_chain3();
return;
}
self.weaponframe = 4;
if (!self.hook_out) {
player_chain5 ();
return;
}
if (vlen(self.velocity) < 750) {
player_chain3 ();
return;
}
};
void() player_chain5= [$axattd4, player_run ] {self.weaponframe=5;};
void () player_chain5= [$axattd4, player_run ] {self.weaponframe=5;};
//============================================================================
//============================================================================
void() player_nail1 =[$nailatt1, player_nail2 ]
void ()
player_nail1 =[$nailatt1, player_nail2 ]
{
muzzleflash();
muzzleflash ();
if (!self.button0 || intermission_running)
{player_run ();return;}
self.weaponframe = self.weaponframe + 1;
if (self.weaponframe == 9)
if (!self.button0 || intermission_running) {
player_run ();
return;
}
self.weaponframe ++;
if (self.weaponframe >= 9)
self.weaponframe = 1;
SuperDamageSound();
SuperDamageSound ();
W_FireSpikes (4);
self.attack_finished = time + 0.2;
};
void() player_nail2 =[$nailatt2, player_nail1 ]
void ()
player_nail2 =[$nailatt2, player_nail1 ]
{
muzzleflash();
muzzleflash ();
if (!self.button0 || intermission_running)
{player_run ();return;}
self.weaponframe = self.weaponframe + 1;
if (self.weaponframe == 9)
if (!self.button0 || intermission_running) {
player_run ();
return;
}
self.weaponframe++;
if (self.weaponframe >= 9)
self.weaponframe = 1;
SuperDamageSound();
SuperDamageSound ();
W_FireSpikes (-4);
self.attack_finished = time + 0.2;
};
//============================================================================
void() player_light1 =[$light1, player_light2 ]
void ()
player_light1 =[$light1, player_light2 ]
{
muzzleflash();
muzzleflash ();
if (!self.button0 || intermission_running)
{player_run ();return;}
if (!self.button0 || intermission_running) {
player_run ();
return;
}
self.weaponframe = self.weaponframe + 1;
if (self.weaponframe == 5)
if (self.weaponframe >= 5)
self.weaponframe = 1;
SuperDamageSound();
W_FireLightning();
self.attack_finished = time + 0.2;
};
void() player_light2 =[$light2, player_light1 ]
void ()
player_light2 =[$light2, player_light1 ]
{
muzzleflash();
muzzleflash ();
if (!self.button0 || intermission_running)
{player_run ();return;}
self.weaponframe = self.weaponframe + 1;
if (self.weaponframe == 5)
if (!self.button0 || intermission_running) {
player_run ();
return;
}
self.weaponframe++;
if (self.weaponframe >= 5)
self.weaponframe = 1;
SuperDamageSound();
W_FireLightning();
@ -296,117 +295,125 @@ void() player_light2 =[$light2, player_light1 ]
//============================================================================
void ()
player_rocket1 =[$rockatt1, player_rocket2 ] {
self.weaponframe = 1;
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() player_rocket1 =[$rockatt1, player_rocket2 ] {self.weaponframe=1;
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 =
void ()
PainSound =
{
local float rs;
if (self.health < 0)
return;
if (damage_attacker.classname == "teledeath")
{
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)
switch (self.watertype) {
case CONTENT_WATER: // water pain sounds
if (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;
}
break;
case CONTENT_SLIME: // slime pain sounds
// FIXME 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)
case CONTENT_LAVA:
// FIXME 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;
default:
break;
}
if (self.pain_finished > time)
{
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
// don't make multiple pain sounds right after each other
// ax pain sound
if (self.axhitme == 1)
{
// 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";
switch (rint ((5 * random()) + 1)) {
case 1:
self.noise = "player/pain1.wav";
break;
case 2:
self.noise = "player/pain2.wav";
break;
case 3:
self.noise = "player/pain3.wav";
break;
case 4:
self.noise = "player/pain4.wav";
break;
case 5:
self.noise = "player/pain5.wav";
break;
default:
self.noise = "player/pain6.wav";
break;
}
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_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_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(entity attacker, float damage) player_pain =
void (entity attacker, float damage)
player_pain =
{
if (self.weaponframe)
return;
if (self.invisible_finished > time)
return; // eyes don't have pain frames
@ -416,19 +423,22 @@ void(entity attacker, float damage) player_pain =
player_pain1 ();
};
void() player_diea1;
void() player_dieb1;
void() player_diec1;
void() player_died1;
void() player_diee1;
void() player_die_ax1;
void () player_diea1;
void () player_dieb1;
void () player_diec1;
void () player_died1;
void () player_diee1;
void () player_die_ax1;
void() DeathBubblesSpawn =
void ()
DeathBubblesSpawn =
{
local entity bubble;
local entity bubble;
if (self.owner.waterlevel != 3)
return;
bubble = spawn();
bubble = spawn ();
setmodel (bubble, "progs/s_bubble.spr");
setorigin (bubble, self.owner.origin + '0 0 24');
bubble.movetype = MOVETYPE_NOCLIP;
@ -444,12 +454,13 @@ local entity bubble;
self.think = DeathBubblesSpawn;
self.air_finished = self.air_finished + 1;
if (self.air_finished >= self.bubble_count)
remove(self);
remove (self);
};
void(float num_bubbles) DeathBubbles =
void (float num_bubbles)
DeathBubbles =
{
local entity bubble_spawner;
local entity bubble_spawner;
bubble_spawner = spawn();
setorigin (bubble_spawner, self.origin);
@ -463,89 +474,93 @@ local entity bubble_spawner;
return;
};
void() DeathSound =
void ()
DeathSound =
{
local float rs;
// water death sounds
if (self.waterlevel == 3)
{
DeathBubbles(20);
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)
switch (rint ((4 * random ()) + 1)) {
case 1:
self.noise = "player/death1.wav";
if (rs == 2)
break;
case 2:
self.noise = "player/death2.wav";
if (rs == 3)
break;
case 3:
self.noise = "player/death3.wav";
if (rs == 4)
break;
case 4:
self.noise = "player/death4.wav";
if (rs == 5)
break;
case 5:
self.noise = "player/death5.wav";
default:
break;
}
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NONE);
return;
};
void() PlayerDead =
void ()
PlayerDead =
{
self.nextthink = -1;
// allow respawn after a certain time
// allow respawn after a certain time
self.deadflag = DEAD_DEAD;
};
vector(float dm) VelocityForDamage =
vector (float dm)
VelocityForDamage =
{
local vector v;
local vector v;
v_x = 100 * crandom();
v_y = 100 * crandom();
v_z = 200 + 100 * random();
v_x = 100 * crandom ();
v_y = 100 * crandom ();
v_z = 200 + 100 * random ();
if (dm > -50)
{
if (dm > -50) {
// dprint ("level 1\n");
v = v * 0.7;
}
else if (dm > -200)
{
} else if (dm > -200) {
// dprint ("level 3\n");
v = v * 2;
}
else
} else
v = v * 10;
return v;
};
void(string gibname, float dm) ThrowGib =
void (string gibname, float dm)
ThrowGib =
{
local entity new;
new = spawn();
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.avelocity_x = 600 * random ();
new.avelocity_y = 600 * random ();
new.avelocity_z = 600 * random ();
new.think = SUB_Remove;
new.ltime = time;
new.nextthink = time + 10 + random()*10;
new.nextthink = time + 10 + 10 * random ();
new.frame = 0;
new.flags = 0;
};
void(string gibname, float dm) ThrowHead =
void (string gibname, float dm)
ThrowHead =
{
setmodel (self, gibname);
self.frame = 0;
@ -561,8 +576,8 @@ void(string gibname, float dm) ThrowHead =
self.avelocity = crandom() * '0 600 0';
};
void() GibPlayer =
void ()
GibPlayer =
{
ThrowHead ("progs/h_player.mdl", self.health);
ThrowGib ("progs/gib1.mdl", self.health);
@ -571,48 +586,47 @@ void() GibPlayer =
self.deadflag = DEAD_DEAD;
if (damage_attacker.classname == "teledeath")
{
switch (damage_attacker.classname) {
case "teledeath":
self.staydeadtime = time + 2 + (random() * 3);
sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
return;
}
if (damage_attacker.classname == "teledeath2")
{
case "teledeath2":
self.staydeadtime = time + 3 + (random() * 6);
sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
return;
default:
break;
}
if (random() < 0.5)
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 =
void ()
PlayerDie =
{
local float i;
// make dead guy release hook (wedge)
if (self.hook_out)
{
Reset_Grapple (self.hook);
self.attack_finished = time + 0.75;
self.hook_out = TRUE;// PutClientInServer will reset this
}
local float i;
self.items = self.items - (self.items & IT_INVISIBILITY);
// make dead guy release hook (wedge)
if (self.hook_out) {
Reset_Grapple (self.hook);
self.attack_finished = time + 0.75;
self.hook_out = TRUE; // PutClientInServer will reset this
}
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
DropBackpack();
DropRune();
TeamCaptureDropFlagOfPlayer(self);
DropBackpack ();
DropRune ();
TeamCaptureDropFlagOfPlayer (self);
if (self.killed == 2)
self.killed = 0;
@ -628,48 +642,54 @@ void() PlayerDie =
if (self.velocity_z < 10)
self.velocity_z = self.velocity_z + random()*300;
if (self.health < -40)
{
if (self.health < -40) {
GibPlayer ();
return;
}
DeathSound();
DeathSound ();
self.angles_x = 0;
self.angles_z = 0;
if (self.weapon == IT_AXE)
{
if (self.weapon == IT_AXE) {
player_die_ax1 ();
return;
}
i = cvar("temp1");
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();
i = 1 + floor (6 * random());
switch (i) {
case 1:
player_diea1();
break;
case 2:
player_dieb1();
break;
case 3:
player_diec1();
break;
case 4:
player_died1();
break;
default:
player_diee1();
break;
}
};
void() set_suicide_frame =
{ // used by klill command and diconnect command
void ()
set_suicide_frame =
{ // used by kill command and disconnect command
/*
if (self.model != "progs/player.mdl")
return; // allready gibbed
*/
if (self.health <= 0)
return;
self.frame = $deatha11;
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_TOSS;
@ -677,7 +697,6 @@ void() set_suicide_frame =
self.nextthink = -1;
};
void() player_diea1 = [ $deatha1, player_diea2 ] {};
void() player_diea2 = [ $deatha2, player_diea3 ] {};
void() player_diea3 = [ $deatha3, player_diea4 ] {};

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
server.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -22,26 +22,24 @@
$Id$
*/
void() monster_ogre = {remove(self);};
void() monster_demon1 = {remove(self);};
void() monster_shambler = {remove(self);};
void() monster_knight = {remove(self);};
void() monster_army = {remove(self);};
void() monster_wizard = {remove(self);};
void() monster_dog = {remove(self);};
void() monster_zombie = {remove(self);};
void() monster_boss = {remove(self);};
void() monster_tarbaby = {remove(self);};
void() monster_hell_knight = {remove(self);};
void() monster_fish = {remove(self);};
void() monster_shalrath = {remove(self);};
void() monster_enforcer = {remove(self);};
void() monster_oldone = {remove(self);};
void() monster_ogre = {remove (self);};
void() monster_demon1 = {remove (self);};
void() monster_shambler = {remove (self);};
void() monster_knight = {remove (self);};
void() monster_army = {remove (self);};
void() monster_wizard = {remove (self);};
void() monster_dog = {remove (self);};
void() monster_zombie = {remove (self);};
void() monster_boss = {remove (self);};
void() monster_tarbaby = {remove (self);};
void() monster_hell_knight = {remove (self);};
void() monster_fish = {remove (self);};
void() monster_shalrath = {remove (self);};
void() monster_enforcer = {remove (self);};
void() monster_oldone = {remove (self);};
/*
==============================================================================
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.
@ -54,7 +52,6 @@ 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
==============================================================================
*/
@ -66,13 +63,13 @@ Something has bumped into a movetarget. If it is a monster
moving towards it, change the next destination and continue.
==============
*/
void() t_movetarget =
void ()
t_movetarget =
{
local entity temp;
local entity temp;
if (other.movetarget != self)
return;
if (other.enemy)
return; // fighting, not following a path
@ -83,20 +80,18 @@ local entity temp;
if (self.classname == "monster_ogre")
sound (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);// play chainsaw drag sound
//dprint ("t_movetarget\n");
// 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.ideal_yaw = vectoyaw (self.goalentity.origin - self.origin);
if (!self.movetarget) {
self.pausetime = time + 999999;
self.th_stand ();
return;
}
};
void() movetarget_f =
void ()
movetarget_f =
{
if (!self.targetname)
objerror ("monster_movetarget: no targetname");
@ -104,17 +99,13 @@ void() movetarget_f =
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 =
void ()
path_corner =
{
movetarget_f ();
};
//============================================================================

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
spectate.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -40,7 +40,8 @@ SpectatorConnect
called when a spectator connects to a server
============
*/
void() SpectatorConnect =
void ()
SpectatorConnect =
{
bprint (PRINT_MEDIUM, "Spectator ");
bprint (PRINT_MEDIUM, self.netname);
@ -58,7 +59,8 @@ SpectatorDisconnect
called when a spectator disconnects from a server
============
*/
void() SpectatorDisconnect =
void ()
SpectatorDisconnect =
{
bprint (PRINT_MEDIUM, "Spectator ");
bprint (PRINT_MEDIUM, self.netname);
@ -73,40 +75,47 @@ SpectatorImpulseCommand
Called by SpectatorThink if the spectator entered an impulse
================
*/
void() SpectatorImpulseCommand =
void ()
SpectatorImpulseCommand =
{
if (self.impulse == 1) {
switch (self.impulse) {
case 1:
// teleport the spectator to the next spawn point
// note that if the spectator is tracking, this doesn't do
// much
self.goalentity = find(self.goalentity, classname, "info_player_deathmatch");
// note that if the spectator is tracking, this doesn't do much
self.goalentity = find(self.goalentity, classname,
"info_player_deathmatch");
if (self.goalentity == world)
self.goalentity = find(self.goalentity, classname, "info_player_deathmatch");
if (self.goalentity != world) {
self.goalentity = find (self.goalentity, classname,
"info_player_deathmatch");
else {
setorigin(self, self.goalentity.origin);
self.angles = self.goalentity.angles;
self.fixangle = TRUE; // turn this way immediately
}
} else if (self.impulse == 23)
TeamFlagStatusReport();
else if (self.impulse == 25)
break;
case 23:
TeamFlagStatusReport ();
break;
case 25:
TeamPrintSettings ();
else if (self.impulse == 70) {
break;
case 70:
if (self.statstate < 0) {
self.statstate = 0;
sprint(self, PRINT_HIGH, "Status bar on (impulse 71 to 81 to set size)\n");
sprint (self, PRINT_HIGH, "Status bar on (impulse 71 to 81 to "
"set size)\n");
} else {
self.statstate = -1;
sprint(self, PRINT_HIGH, "Status bar off.\n");
}
} else if (self.impulse >= 71 && self.impulse <= 81) {
self.statstate = self.impulse - 71;
sprint(self, PRINT_HIGH, "Status bar set\n");
break;
default:
if (self.impulse >= 71 && self.impulse <= 81) {
self.statstate = self.impulse - 71;
sprint (self, PRINT_HIGH, "Status bar set\n");
}
break;
}
self.impulse = 0;
};
@ -117,15 +126,14 @@ SpectatorThink
Called every frame after physics are run
================
*/
void() SpectatorThink =
void ()
SpectatorThink =
{
// self.origin, etc contains spectator position, so you could
// do some neat stuff here
TeamCapturePlayerUpdate();
TeamCapturePlayerUpdate ();
if (self.impulse)
SpectatorImpulseCommand();
SpectatorImpulseCommand ();
};

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
sprites.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -22,7 +22,6 @@
$Id$
*/
// these are the only sprites still in the game...
$spritename s_explod
@ -35,16 +34,13 @@ $frame 24 88 56 56
$frame 120 88 56 56
$frame 216 88 56 56
$spritename s_bubble
$type vp_parallel
$load id1/gfx/sprites/bubble.lbm
$frame 16 16 16 16
$frame 40 16 16 16
$spritename s_light
$type vp_parallel
$load id1/gfx/sprites/light.lbm
$frame 104 32 32 32

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
status.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -22,51 +22,61 @@
$Id$
*/
.float laststattime; // time of last status update
.float motd_count;
.float statstate; // is the status bar on?
float PLAYERSTATTIME = 1.75;
void() MOTD =
void ()
MOTD =
{
if (self.motd_count < 4) {
self.motd_count = self.motd_count + 1;
if (self.classname == "spectator") {
centerprint(self, "Welcome!\nRunning ThreeWave CTF 4.21\n\nÃÁÐÔÕÒÅ ÔÈÅ ÆÌÁÇ!\n");
centerprint (self, "Welcome!\nRunning ThreeWave CTF 4.21\n\n"
"ÃÁÐÔÕÒÅ ÔÈÅ ÆÌÁÇ!\n");
return;
}
if (gamestart) {
centerprint(self, "Welcome!\nRunning ThreeWave CTF 4.21\n\nÃÁÐÔÕÒÅ ÔÈÅ ÆÌÁÇ!\n\nChoose an exit...\n"); //red
centerprint (self, "Welcome!\nRunning ThreeWave CTF 4.21\n\n"
"ÃÁÐÔÕÒÅ ÔÈÅ ÆÌÁÇ!\n\nChoose an exit...\n"); //red
return;
}
if (self.steam == TEAM_COLOR1)
centerprint(self, "Welcome!\nRunning ThreeWave CTF 4.21\n\nÃÁÐÔÕÒÅ ÔÈÅ ÆÌÁÇ!\n\nYou are ÒÅÄ team\n"); //red
centerprint (self, "Welcome!\nRunning ThreeWave CTF 4.21\n\n"
"ÃÁÐÔÕÒÅ ÔÈÅ ÆÌÁÇ!\n\nYou are ÒÅÄ team\n"); //red
else
centerprint(self, "Welcome!\nRunning Threewave CTF 4.21\n\nÃÁÐÔÕÒÅ ÔÈÅ ÆÌÁÇ!\n\nYou are ÂÌÕÅ team"); //blue
centerprint (self, "Welcome!\nRunning Threewave CTF 4.21\n\n"
"ÃÁÐÔÕÒÅ ÔÈÅ ÆÌÁÇ!\n\nYou are ÂÌÕÅ team"); //blue
return;
}
sprint(self, PRINT_HIGH, "Impulse 70 to turn off status bar\n");
sprint(self, PRINT_HIGH, "Impulse 71 through 81 to set status bar resolution\n");
sprint(self, PRINT_HIGH, "71:200 72:240 73:300 74:350 75:384 76:400 77:480 78:600 79:768 81:1024\n");
sprint (self, PRINT_HIGH, "Impulse 70 to turn off status bar\n");
sprint (self, PRINT_HIGH, "Impulse 71 through 81 to set status bar "
"resolution\n");
sprint (self, PRINT_HIGH, "71:200 72:240 73:300 74:350 75:384 76:400 "
"77:480 78:600 79:768 81:1024\n");
self.motd_count = 0;
};
void() MOTD_ChooseTeam =
void ()
MOTD_ChooseTeam =
{
if (self.motd_count < 6) {
self.motd_count = self.motd_count + 1;
centerprint(self, "Welcome!\nRunning ThreeWave CTF 4.2\n\nÃÁÐÔÕÒÅ ÔÈÅ ÆÌÁÇ!\n\nPress 1 for ÒÅÄ team\nPress 2 for ÂÌÕÅ team\nOr Press Jump for automatic team\n");
centerprint (self, "Welcome!\nRunning ThreeWave CTF 4.2\n\nÃÁÐÔÕÒÅ "
"ÔÈÅ ÆÌÁÇ!\n\nPress 1 for ÒÅÄ team\nPress 2 for ÂÌÕÅ "
"team\nOr Press Jump for automatic team\n");
return;
}
self.motd_count = 0;
};
void() TeamCaptureCheckUpdate =
void ()
TeamCaptureCheckUpdate =
{
local entity p;
local entity p;
if (gamestart)
return; // handled by vote exit
@ -77,25 +87,27 @@ void() TeamCaptureCheckUpdate =
// count up teamscr
teamscr1 = teamscr2 = 0;
p = find(world, classname, "player");
p = find (world, classname, "player");
while (p != world) {
if (p.steam == TEAM_COLOR1)
teamscr1 = teamscr1 + p.frags;
else if (p.steam == TEAM_COLOR2)
teamscr2 = teamscr2 + p.frags;
p = find(p, classname, "player");
p = find (p, classname, "player");
}
};
void() TeamCaptureResetUpdate =
void ()
TeamCaptureResetUpdate =
{
lastteamscrtime = 0;
TeamCaptureCheckUpdate();
};
void() TeamEndScore =
void ()
TeamEndScore =
{
local string s;
local string s;
if (gamestart)
return;
@ -104,89 +116,96 @@ void() TeamEndScore =
TeamCaptureCheckUpdate();
if (teamscr1 > teamscr2) {
bprint(PRINT_HIGH, "ÒÅÄ team won the level with ");
s = ftos(teamscr1);
bprint(PRINT_HIGH, s);
bprint(PRINT_HIGH, " points!\n");
bprint(PRINT_HIGH, "ÂÌÕÅ team lost with ");
s = ftos(teamscr2);
bprint(PRINT_HIGH, s);
bprint(PRINT_HIGH, " points.\n");
bprint (PRINT_HIGH, "ÒÅÄ team won the level with ");
s = ftos (teamscr1);
bprint (PRINT_HIGH, s);
bprint (PRINT_HIGH, " points!\n");
bprint (PRINT_HIGH, "ÂÌÕÅ team lost with ");
s = ftos (teamscr2);
bprint (PRINT_HIGH, s);
bprint (PRINT_HIGH, " points.\n");
} else if (teamscr1 < teamscr2) {
bprint(PRINT_HIGH, "ÂÌÕÅ team won the level with ");
s = ftos(teamscr2);
bprint(PRINT_HIGH, s);
bprint(PRINT_HIGH, " points!\n");
bprint(PRINT_HIGH, "ÒÅÄ team lost with ");
s = ftos(teamscr1);
bprint(PRINT_HIGH, s);
bprint(PRINT_HIGH, " points.\n");
bprint (PRINT_HIGH, "ÂÌÕÅ team won the level with ");
s = ftos (teamscr2);
bprint (PRINT_HIGH, s);
bprint (PRINT_HIGH, " points!\n");
bprint (PRINT_HIGH, "ÒÅÄ team lost with ");
s = ftos (teamscr1);
bprint (PRINT_HIGH, s);
bprint (PRINT_HIGH, " points.\n");
} else {
bprint(PRINT_HIGH, "ÂÌÕÅ and ÒÅÄ team tied level with ");
s = ftos(teamscr1);
bprint(PRINT_HIGH, s);
bprint(PRINT_HIGH, " points!\n");
bprint (PRINT_HIGH, "ÂÌÕÅ and ÒÅÄ team tied level with ");
s = ftos (teamscr1);
bprint (PRINT_HIGH, s);
bprint (PRINT_HIGH, " points!\n");
}
};
string(entity who) TeamSetStatRes =
string (entity who)
TeamSetStatRes =
{
if (who.statstate > 7) // 768
switch (who.statstate) {
default: // > 7 = 768+
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
else if (who.statstate == 7) // 600
case 7: // 600
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
else if (who.statstate == 6) // 480
case 6: // 480
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
else if (who.statstate == 5) // 400
case 5: // 400:
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
else if (who.statstate == 4) // 384
case 4: // 384
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
else if (who.statstate == 3) // 350
case 3: // 350
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
else if (who.statstate == 2) // 300
case 2: // 300
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
else if (who.statstate == 1) // 240
case 1: // 240:
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
// 200
return "\n\n\n\n\n\n\n\n\n\n\n\n";
case 0: // 200
return "\n\n\n\n\n\n\n\n\n\n\n\n";
}
};
string(entity who) TeamSetStatRes2 =
string (entity who)
TeamSetStatRes2 =
{
if (who.statstate > 7) // 768
switch (who.statstate) {
default: // >7 = 768+
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
else if (who.statstate == 7) // 600
case 7: // 600
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
else if (who.statstate == 6) // 480
case 6: // 480
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
else if (who.statstate == 5) // 400
case 5: // 400
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
else if (who.statstate == 4) // 384
case 4: // 384
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
else if (who.statstate == 3) // 350
case 3: // 350
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
else if (who.statstate == 2) // 300
case 2: // 300
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
else if (who.statstate == 1) // 240
case 1: // 240
return "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
// 200
return "\n\n\n\n\n\n\n\n\n\n\n";
case 0: // 200
return "\n\n\n\n\n\n\n\n\n\n\n";
}
};
void() TeamCapturePlayerUpdate =
void ()
TeamCapturePlayerUpdate =
{
local entity e;
local string n, t, s1, s2, s3, res;
local entity e;
local string n, t, s1, s2, s3, res;
if (self.laststattime > time)
return;
TeamCaptureCheckUpdate();
TeamCaptureCheckUpdate ();
self.laststattime = time + PLAYERSTATTIME;
if (self.motd_count) {
MOTD();
MOTD ();
return;
}
@ -197,12 +216,12 @@ void() TeamCapturePlayerUpdate =
if (gamestart) {
if (vote_leader == world)
centerprint2(self, res, " Choose an exit...");
centerprint2 (self, res, " Choose an exit...");
else {
res = TeamSetStatRes2(vote_leader);
n = ftos(voteexit_time - time);
centerprint5(self, res, vote_leader.message,
" leads\n", n, " seconds until exit");
res = TeamSetStatRes2 (vote_leader);
n = ftos (voteexit_time - time);
centerprint5 (self, res, vote_leader.message,
" leads\n", n, " seconds until exit");
}
return;
}
@ -221,8 +240,8 @@ void() TeamCapturePlayerUpdate =
s1 = "Regen …";
else
s1 = "";
e = find(world, classname, "item_flag_team1");
e = find (world, classname, "item_flag_team1");
if (e.cnt == FLAG_AT_BASE)
s2 = "";
else if (e.cnt == FLAG_CARRIED)
@ -230,7 +249,7 @@ void() TeamCapturePlayerUpdate =
else
s2 = "Ò…";
e = find(world, classname, "item_flag_team2");
e = find (world, classname, "item_flag_team2");
if (e.cnt == FLAG_AT_BASE)
s3 = "";
else if (e.cnt == FLAG_CARRIED)
@ -239,14 +258,13 @@ void() TeamCapturePlayerUpdate =
s3 = "Â…";
if (teamscr1 == 0 && teamscr2 == 0) {
centerprint5(self, res, s1, s2, s3, " Capture The Flag"); // CTFBOT
// CTFBOT
centerprint5 (self, res, s1, s2, s3, " Capture The Flag");
return;
}
if (time < (last_flag_capture + 6))
{
if (last_capture_team == TEAM_COLOR1)
{
if (time < (last_flag_capture + 6)) {
if (last_capture_team == TEAM_COLOR1) {
if (teamscr1 > teamscr2) {
t = "Red Capture! RED ";
n = ftos(teamscr1 - teamscr2);
@ -257,9 +275,7 @@ void() TeamCapturePlayerUpdate =
t = "Red Capture! TIED ";
n = "";
}
}
else
{
} else {
if (teamscr1 > teamscr2) {
t = "Blue Capture! RED ";
n = ftos(teamscr1 - teamscr2);
@ -271,9 +287,7 @@ void() TeamCapturePlayerUpdate =
n = "";
}
}
}
else
{
} else {
if (teamscr1 > teamscr2) {
t = " RED ";
n = ftos(teamscr1 - teamscr2);
@ -288,7 +302,8 @@ void() TeamCapturePlayerUpdate =
centerprint7(self, res, s1, s2, s3, " ", t, n); //
};
void(entity who, string s) TeamPlayerUpdate =
void (entity who, string s)
TeamPlayerUpdate =
{
local string n, res;
@ -314,32 +329,36 @@ void(entity who, string s) TeamPlayerUpdate =
centerprint3(who, res, s, "\n TIED");
};
void(entity who, string s1, string s2) TeamPlayerUpdate2 =
void (entity who, string s1, string s2)
TeamPlayerUpdate2 =
{
local string n, res;
local string res, n;
TeamCaptureCheckUpdate();
TeamCaptureCheckUpdate ();
who.laststattime = time + PLAYERSTATTIME;
if (who.statstate < 0) {
centerprint2(who, s1, s2);
centerprint2 (who, s1, s2);
return;
}
res = TeamSetStatRes2(who);
res = TeamSetStatRes2 (who);
if (teamscr1 == 0 && teamscr2 == 0) {
centerprint4(who, res, s1, s2, "\n Capture The Flag");
centerprint4 (who, res, s1, s2,
"\n Capture The Flag");
return;
} else if (teamscr1 > teamscr2) {
n = ftos(teamscr1 - teamscr2);
centerprint5(who, res, s1, s2, "\n RED ", n);
centerprint5 (who, res, s1, s2,
"\n RED ", n);
} else if (teamscr1 < teamscr2) {
n = ftos(teamscr2 - teamscr1);
centerprint5(who, res, s1, s2, "\n BLUE ", n);
centerprint5 (who, res, s1, s2,
"\n BLUE ", n);
} else {
centerprint4(who, res, s1, s2, "\n TIED");
centerprint4 (who, res, s1, s2,
"\n TIED");
return;
}
};

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
subs.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -22,41 +22,38 @@
$Id$
*/
void () SUB_Null = {};
void() SUB_Null = {};
void() SUB_Remove = {remove(self);};
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 =
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
{
else {
makevectors (self.angles);
self.movedir = v_forward;
}
self.angles = '0 0 0';
};
/*
================
InitTrigger
================
*/
void() 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.
// 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;
@ -74,9 +71,10 @@ 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 =
void (entity ent, vector tdest, float tspeed, void () func)
SUB_CalcMoveEnt =
{
local entity stemp;
local entity stemp;
stemp = self;
self = ent;
@ -84,10 +82,11 @@ local entity stemp;
self = stemp;
};
void(vector tdest, float tspeed, void() func) SUB_CalcMove =
void (vector tdest, float tspeed, void () func)
SUB_CalcMove =
{
local vector vdestdelta;
local float len, traveltime;
local float len, traveltime;
local vector vdestdelta;
if (!tspeed)
objerror("No speed is defined!");
@ -96,34 +95,32 @@ local float len, traveltime;
self.finaldest = tdest;
self.think = SUB_CalcMoveDone;
if (tdest == self.origin)
{
if (tdest == self.origin) {
self.velocity = '0 0 0';
self.nextthink = self.ltime + 0.1;
return;
}
// set destdelta to the vector needed to move
// set destdelta to the vector needed to move
vdestdelta = tdest - self.origin;
// calculate length of vector
// calculate length of vector
len = vlen (vdestdelta);
// divide by speed to get time to reach dest
// divide by speed to get time to reach dest
traveltime = len / tspeed;
if (traveltime < 0.1)
{
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
// 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
// scale the destdelta vector by the time spent traveling to get velocity
self.velocity = vdestdelta * (1 / traveltime); // qcc won't take vec/float
};
/*
@ -131,7 +128,8 @@ local float len, traveltime;
After moving, set origin to exact final destination
============
*/
void() SUB_CalcMoveDone =
void ()
SUB_CalcMoveDone =
{
setorigin(self, self.finaldest);
self.velocity = '0 0 0';
@ -140,7 +138,6 @@ void() SUB_CalcMoveDone =
self.think1();
};
/*
=============
SUB_CalcAngleMove
@ -151,38 +148,40 @@ self.angles rotating
The calling function should make sure self.think is valid
===============
*/
void(entity ent, vector destangle, float tspeed, void() func) SUB_CalcAngleMoveEnt =
void (entity ent, vector destangle, float tspeed, void () func)
SUB_CalcAngleMoveEnt =
{
local entity stemp;
local entity stemp;
stemp = self;
self = ent;
SUB_CalcAngleMove (destangle, tspeed, func);
self = stemp;
};
void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove =
void (vector destangle, float tspeed, void () func)
SUB_CalcAngleMove =
{
local vector destdelta;
local float len, traveltime;
local float len, traveltime;
local vector destdelta;
if (!tspeed)
objerror("No speed is defined!");
// set destdelta to the vector needed to move
// set destdelta to the vector needed to move
destdelta = destangle - self.angles;
// calculate length of vector
// calculate length of vector
len = vlen (destdelta);
// divide by speed to get time to reach dest
// divide by speed to get time to reach dest
traveltime = len / tspeed;
// set nextthink to trigger a think when dest is reached
// 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
// 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;
@ -202,14 +201,13 @@ void() SUB_CalcAngleMoveDone =
self.think1();
};
//=============================================================================
void() DelayThink =
{
activator = self.enemy;
SUB_UseTargets ();
remove(self);
remove (self);
};
/*
@ -228,20 +226,17 @@ 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 =
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();
// 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;
@ -251,62 +246,45 @@ void() SUB_UseTargets =
t.target = self.target;
return;
}
//
// print the message
//
if (activator.classname == "player" && self.message != "")
{
// 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)
{
// kill the killtagets
if (self.killtarget) {
t = world;
do
{
do {
t = find (t, targetname, self.killtarget);
if (!t)
return;
remove (t);
} while ( 1 );
} while (1);
}
//
// fire targets
//
if (self.target)
{
// fire targets
if (self.target) {
act = activator;
t = world;
do
{
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 != SUB_Null) {
if (self.use)
self.use ();
}
self = stemp;
other = otemp;
activator = act;
} while ( 1 );
} while (1);
}
};

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
triggers.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -22,11 +22,10 @@
$Id$
*/
entity stemp, otemp, s, old;
void() trigger_reactivate =
void ()
trigger_reactivate =
{
self.solid = SOLID_TRIGGER;
};
@ -37,29 +36,26 @@ float SPAWNFLAG_NOMESSAGE = 1;
float SPAWNFLAG_NOTOUCH = 1;
// the wait time has passed, so set back up for another activation
void() multi_wait =
void ()
multi_wait =
{
if (self.max_health)
{
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 =
void ()
multi_trigger =
{
if (self.nextthink > time)
{
return; // allready been triggered
}
if (self.classname == "trigger_secret")
{
if (self.classname == "trigger_secret") {
if (self.enemy.classname != "player")
return;
found_secrets = found_secrets + 1;
@ -69,20 +65,18 @@ void() multi_trigger =
if (self.noise)
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
// don't trigger again until reset
// don't trigger again until reset
self.takedamage = DAMAGE_NO;
activator = self.enemy;
SUB_UseTargets();
if (self.wait > 0)
{
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
} 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;
@ -90,26 +84,28 @@ void() multi_trigger =
}
};
void() multi_killed =
void ()
multi_killed =
{
self.enemy = damage_attacker;
multi_trigger();
multi_trigger ();
};
void() multi_use =
void ()
multi_use =
{
self.enemy = activator;
multi_trigger();
multi_trigger ();
};
void() multi_touch =
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')
{
// 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
@ -132,32 +128,32 @@ sounds
4)
set "message" to text string
*/
void() trigger_multiple =
void ()
trigger_multiple =
{
if (self.sounds == 1)
{
switch (self.sounds) {
case 1:
precache_sound ("misc/secret.wav");
self.noise = "misc/secret.wav";
}
else if (self.sounds == 2)
{
break;
case 2:
precache_sound ("misc/talk.wav");
self.noise = "misc/talk.wav";
}
else if (self.sounds == 3)
{
break;
case 3:
precache_sound ("misc/trigger1.wav");
self.noise = "misc/trigger1.wav";
default:
break;
}
if (!self.wait)
self.wait = 0.2;
self.use = multi_use;
InitTrigger ();
if (self.health)
{
if (self.health) {
if (self.spawnflags & SPAWNFLAG_NOTOUCH)
objerror ("health and notouch don't make sense\n");
self.max_health = self.health;
@ -165,17 +161,12 @@ void() trigger_multiple =
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) )
{
} 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.
@ -189,10 +180,11 @@ sounds
4)
set "message" to text string
*/
void() trigger_once =
void ()
trigger_once =
{
self.wait = -1;
trigger_multiple();
trigger_multiple ();
};
//=============================================================================
@ -200,12 +192,12 @@ void() trigger_once =
/*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 =
void ()
trigger_relay =
{
self.use = SUB_UseTargets;
};
//=============================================================================
/*QUAKED trigger_secret (.5 .5 .5) ?
@ -217,24 +209,25 @@ sounds
4)
set "message" to text string
*/
void() trigger_secret =
void ()
trigger_secret =
{
total_secrets = total_secrets + 1;
total_secrets++;
self.wait = -1;
if (!self.message)
self.message = "You found a secret area!";
if (!self.sounds)
switch (self.sounds) {
default:
self.sounds = 1;
if (self.sounds == 1)
{
case 1:
precache_sound ("misc/secret.wav");
self.noise = "misc/secret.wav";
}
else if (self.sounds == 2)
{
break;
case 2:
precache_sound ("misc/talk.wav");
self.noise = "misc/talk.wav";
break;
}
trigger_multiple ();
@ -242,34 +235,38 @@ void() trigger_secret =
//=============================================================================
void() counter_use =
void ()
counter_use =
{
self.count = self.count - 1;
self.count--;
if (self.count < 0)
return;
if (self.count != 0)
{
if (self.count > 0) {
if (activator.classname == "player"
&& (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
{
if (self.count >= 4)
&& (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0) {
switch (self.count) {
default:
centerprint (activator, "There are more to go...");
else if (self.count == 3)
break;
case 3:
centerprint (activator, "Only 3 more to go...");
else if (self.count == 2)
break;
case 2:
centerprint (activator, "Only 2 more to go...");
else
break;
case 1:
centerprint (activator, "Only 1 more to go...");
break;
}
}
return;
}
if (activator.classname == "player"
&& (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
centerprint(activator, "Sequence completed!");
self.enemy = activator;
&& (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
centerprint (activator, "Sequence completed!");
self.enemy = activator;
multi_trigger ();
};
@ -280,94 +277,87 @@ If nomessage is not set, t will print "1 more.. " etc when triggered and "sequen
After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself.
*/
void() trigger_counter =
void ()
trigger_counter =
{
self.wait = -1;
self.wait--;
if (!self.count)
self.count = 2;
self.use = counter_use;
};
/*
==============================================================================
TELEPORT TRIGGERS
==============================================================================
*/
// TELEPORT TRIGGERS ==========================================================
float PLAYER_ONLY = 1;
float SILENT = 2;
void() play_teleport =
void ()
play_teleport =
{
local float v;
local string tmpstr;
local string tmpstr = "misc/r_tele5.wav";
v = random() * 5;
if (v < 1)
switch (rint (5 * random())) {
case 0:
tmpstr = "misc/r_tele1.wav";
else if (v < 2)
break;
case 1:
tmpstr = "misc/r_tele2.wav";
else if (v < 3)
break;
case 2:
tmpstr = "misc/r_tele3.wav";
else if (v < 4)
break;
case 3:
tmpstr = "misc/r_tele4.wav";
else
tmpstr = "misc/r_tele5.wav";
break;
default:
// tmpstr = "misc/r_tele5.wav";
break;
}
sound (self, CHAN_VOICE, tmpstr, 1, ATTN_NORM);
remove (self);
};
void(vector org) spawn_tfog =
void (vector org)
spawn_tfog =
{
s = spawn ();
s.origin = org;
s.nextthink = time + 0.2;
s.think = play_teleport;
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_TELEPORT);
WriteCoord (MSG_MULTICAST, org_x);
WriteCoord (MSG_MULTICAST, org_y);
WriteCoord (MSG_MULTICAST, org_z);
WriteBytes (MSG_MULTICAST, SVC_TEMPENTITY, TE_TELEPORT);
WriteCoordV (MSG_MULTICAST, org);
multicast (org, MULTICAST_PHS);
};
void() tdeath_touch =
void ()
tdeath_touch =
{
if (other == self.owner)
return;
// frag anyone who teleports in on top of an invincible player
if (other.classname == "player")
{
// 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
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 =
void (vector org, entity death_owner)
spawn_tdeath =
{
local entity death;
local entity death;
death = spawn();
death = spawn ();
death.classname = "teledeath";
death.movetype = MOVETYPE_NONE;
death.solid = SOLID_TRIGGER;
@ -382,82 +372,73 @@ local entity death;
force_retouch = 2; // make sure even still objects get hit
};
void() teleport_touch =
void ()
teleport_touch =
{
local entity t;
local vector org;
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
// only teleport living creatures
if (other.health <= 0 || other.solid != SOLID_SLIDEBOX)
return;
SUB_UseTargets ();
// put a tfog where the player was
// 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
// 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);
spawn_tdeath (t.origin, other);
// move the player and lock him down for a little while
if (!other.health)
{
// 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);
other.velocity = v_forward * (other.velocity_x + other.velocity_y);
return;
}
setorigin (other, t.origin);
other.angles = t.mangle;
if (other.classname == "player")
{
// Teleporting - detach hook (wedge)
if (other.weapon == IT_GRAPPLE && other.hook_out)
{
sound (other, CHAN_WEAPON, "weapons/bounce2.wav", 1, ATTN_NORM);
other.on_hook = FALSE;
other.hook_out = FALSE;
other.weaponframe = 0;
other.attack_finished = time + 0.75;// avoid instant rehook
}
if (other.classname == "player") {
// Teleporting - detach hook (wedge)
if (other.weapon == IT_GRAPPLE && other.hook_out) {
sound (other, CHAN_WEAPON, "weapons/bounce2.wav", 1, ATTN_NORM);
other.on_hook = FALSE;
other.hook_out = FALSE;
other.weaponframe = 0;
other.attack_finished = time + 0.75;// avoid instant rehook
}
other.fixangle = 1; // turn this way immediately
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.flags &= ~FL_ONGROUND;
other.velocity = v_forward * 300;
}
other.flags = other.flags - other.flags & FL_ONGROUND;
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 =
void ()
info_teleport_destination =
{
// this does nothing, just serves as a target spot
// this does nothing, just serves as a target spot
self.mangle = self.angles;
self.angles = '0 0 0';
self.model = "";
@ -466,7 +447,8 @@ void() info_teleport_destination =
objerror ("no targetname");
};
void() teleport_use =
void ()
teleport_use =
{
self.nextthink = time + 0.2;
force_retouch = 2; // make sure even still objects get hit
@ -478,9 +460,10 @@ Any object touching this will be transported to the corresponding info_teleport_
If the trigger_teleport has a targetname, it will only teleport entities when it has been fired.
*/
void() trigger_teleport =
void ()
trigger_teleport =
{
local vector o;
local vector o;
InitTrigger ();
self.touch = teleport_touch;
@ -489,41 +472,30 @@ void() trigger_teleport =
objerror ("no target");
self.use = teleport_use;
if (!(self.spawnflags & SILENT))
{
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);
o = (self.mins + self.maxs) * 0.5;
ambientsound (o, "ambience/hum1.wav", 0.5 , ATTN_STATIC);
}
};
/*
==============================================================================
trigger_setskill
==============================================================================
*/
// trigger_setskill ===========================================================
/*QUAKED trigger_setskill (.5 .5 .5) ?
sets skill level to the value of "message".
Only used on start map.
*/
void() trigger_setskill =
void ()
trigger_setskill =
{
remove (self);
};
/*
==============================================================================
// ONLY REGISTERED TRIGGERS ===================================================
ONLY REGISTERED TRIGGERS
==============================================================================
*/
void() trigger_onlyregistered_touch =
void ()
trigger_onlyregistered_touch =
{
if (other.classname != "player")
return;
@ -531,16 +503,12 @@ void() trigger_onlyregistered_touch =
return;
self.attack_finished = time + 2;
if (cvar("registered"))
{
if (cvar ("registered")) {
self.message = "";
SUB_UseTargets ();
remove (self);
}
else
{
if (self.message != "")
{
} else {
if (self.message != "") {
centerprint (other, self.message);
sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
}
@ -550,7 +518,8 @@ void() trigger_onlyregistered_touch =
/*QUAKED trigger_onlyregistered (.5 .5 .5) ?
Only fires if playing the registered version, otherwise prints the message
*/
void() trigger_onlyregistered =
void ()
trigger_onlyregistered =
{
precache_sound ("misc/talk.wav");
InitTrigger ();
@ -559,16 +528,17 @@ void() trigger_onlyregistered =
//============================================================================
void() hurt_on =
void ()
hurt_on =
{
self.solid = SOLID_TRIGGER;
self.nextthink = -1;
};
void() hurt_touch =
void ()
hurt_touch =
{
if (other.takedamage)
{
if (other.takedamage) {
self.solid = SOLID_NOT;
T_Damage (other, self, self, self.dmg);
self.think = hurt_on;
@ -583,7 +553,8 @@ Any object touching this will be hurt
set dmg to damage amount
defalt dmg = 5
*/
void() trigger_hurt =
void ()
trigger_hurt =
{
InitTrigger ();
self.touch = hurt_touch;
@ -595,17 +566,15 @@ void() trigger_hurt =
float PUSH_ONCE = 1;
void() trigger_push_touch =
void ()
trigger_push_touch =
{
if (other.classname == "grenade")
other.velocity = self.speed * self.movedir * 10;
else if (other.health > 0)
{
else if (other.health > 0) {
other.velocity = self.speed * self.movedir * 10;
if (other.classname == "player")
{
if (other.fly_sound < time)
{
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);
}
@ -615,11 +584,11 @@ void() trigger_push_touch =
remove(self);
};
/*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE
Pushes the player
*/
void() trigger_push =
void ()
trigger_push =
{
InitTrigger ();
precache_sound ("ambience/windfly.wav");
@ -630,19 +599,20 @@ void() trigger_push =
//============================================================================
void() trigger_monsterjump_touch =
void ()
trigger_monsterjump_touch =
{
if ( other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER )
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
// 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) )
if (!(other.flags & FL_ONGROUND))
return;
other.flags = other.flags - FL_ONGROUND;
other.flags &= ~FL_ONGROUND;
other.velocity_z = self.height;
};
@ -652,7 +622,8 @@ Walking monsters that touch this will jump in the direction of the trigger's ang
"speed" default to 200, the speed thrown forward
"height" default to 200, the speed thrown upwards
*/
void() trigger_monsterjump =
void ()
trigger_monsterjump =
{
if (!self.speed)
self.speed = 200;
@ -663,4 +634,3 @@ void() trigger_monsterjump =
InitTrigger ();
self.touch = trigger_monsterjump_touch;
};

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
#FILENAME#
world.qc
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -22,166 +22,10 @@
$Id$
*/
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");
};
void() InitBodyQueue;
entity lastspawn;
//=======================
/*QUAKED worldspawn (0 0 0) ?
Only used for the world entity.
Set message to the level name.
@ -192,17 +36,17 @@ World Types:
1: metal
2: base
*/
//=======================
void() worldspawn =
void ()
worldspawn =
{
lastspawn = world;
runespawn = world;
runespawned = 0;
InitBodyQue ();
InitBodyQueue ();
// custom map attributes
// custom map attributes
// can't change gravity in QuakeWorld
// can't change gravity in QuakeWorld
/*
if (self.model == "maps/e1m8.bsp")
cvar_set ("sv_gravity", "100");
@ -214,16 +58,16 @@ void() worldspawn =
else
gamestart = 0;
// the area based ambient sounds MUST be the first precache_sounds
// the area based ambient sounds MUST be the first precache_sounds
// player precaches
// player precaches
W_Precache (); // get weapon precaches
// sounds used from C physics code
// sounds used from C physics code
precache_sound ("demon/dland2.wav"); // landing thud
precache_sound ("misc/h2ohit1.wav"); // landing splash
// setup precaches allways needed
// 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
@ -244,19 +88,18 @@ void() worldspawn =
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 ("weapons/lhit.wav"); // lightning
precache_sound ("weapons/lstart.wav"); // lightning start
precache_sound ("items/damage3.wav");
precache_sound ("misc/power.wav"); //lightning for boss
precache_sound ("misc/power.wav"); // lightning for boss
// player gib sounds
// 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
// player pain sounds
precache_sound ("player/pain1.wav");
precache_sound ("player/pain2.wav");
precache_sound ("player/pain3.wav");
@ -264,14 +107,14 @@ void() worldspawn =
precache_sound ("player/pain5.wav");
precache_sound ("player/pain6.wav");
// player death sounds
// 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
// 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
@ -306,12 +149,12 @@ void() worldspawn =
precache_model ("progs/v_rock.mdl");
precache_model ("progs/v_shot2.mdl");
precache_model ("progs/v_nail2.mdl");
precache_model ("progs/v_rock2.mdl");
precache_model ("progs/v_star.mdl");// precache grapple (Wedge)
precache_model ("progs/bit.mdl");// precache grapple (Wedge)
precache_model ("progs/star.mdl");// precache grapple (Wedge)
precache_model ("progs/v_rock2.mdl");
precache_model ("progs/v_star.mdl"); // precache grapple (Wedge)
precache_model ("progs/bit.mdl"); // precache grapple (Wedge)
precache_model ("progs/star.mdl"); // precache grapple (Wedge)
precache_model ("progs/bolt.mdl"); // for lightning gun
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
@ -326,54 +169,53 @@ void() worldspawn =
precache_model ("progs/zom_gib.mdl");
precache_model ("progs/v_light.mdl");
//
// Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
//
// Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
// 0 normal
lightstyle(0, "m");
lightstyle (0, "m");
// 1 FLICKER (first variety)
lightstyle(1, "mmnmmommommnonmmonqnmmo");
lightstyle (1, "mmnmmommommnonmmonqnmmo");
// 2 SLOW STRONG PULSE
lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
lightstyle (2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
// 3 CANDLE (first variety)
lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
lightstyle (3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
// 4 FAST STROBE
lightstyle(4, "mamamamamama");
lightstyle (4, "mamamamamama");
// 5 GENTLE PULSE 1
lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");
lightstyle (5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");
// 6 FLICKER (second variety)
lightstyle(6, "nmonqnmomnmomomno");
lightstyle (6, "nmonqnmomnmomomno");
// 7 CANDLE (second variety)
lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm");
lightstyle (7, "mmmaaaabcdefgmmmmaaaammmaamm");
// 8 CANDLE (third variety)
lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
lightstyle (8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
// 9 SLOW STROBE (fourth variety)
lightstyle(9, "aaaaaaaazzzzzzzz");
lightstyle (9, "aaaaaaaazzzzzzzz");
// 10 FLUORESCENT FLICKER
lightstyle(10, "mmamammmmammamamaaamammma");
lightstyle (10, "mmamammmmammamamaaamammma");
// 11 SLOW PULSE NOT FADE TO BLACK
lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba");
lightstyle (11, "abcdefghijklmnopqrrqponmlkjihgfedcba");
// styles 32-62 are assigned by the light program for switchable lights
// 63 testing
lightstyle(63, "a");
lightstyle (63, "a");
};
void() StartFrame =
void ()
StartFrame =
{
timelimit = cvar("timelimit") * 60;
fraglimit = cvar("fraglimit");
@ -383,51 +225,45 @@ void() StartFrame =
framecount = framecount + 1;
};
/*
==============================================================================
// BODY QUEUE =================================================================
BODY QUE
entity bodyqueue_head;
==============================================================================
*/
entity bodyque_head;
void() bodyque =
{ // just here so spawn functions don't complain after the world
// creates bodyques
};
void() InitBodyQue =
void ()
bodyqeuue =
{
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;
// here so spawn functions don't complain after the world creates bodyqueues
};
void ()
InitBodyQueue =
{
bodyqueue_head = spawn ();
bodyqueue_head.classname = "bodyqueue";
bodyqueue_head.owner = spawn ();
bodyqueue_head.owner.classname = "bodyqueue";
bodyqueue_head.owner.owner = spawn ();
bodyqueue_head.owner.owner.classname = "bodyqueue";
bodyqueue_head.owner.owner.owner = spawn ();
bodyqueue_head.owner.owner.owner.classname = "bodyqueue";
bodyqueue_head.owner.owner.owner.owner = bodyqueue_head;
};
// make a body que entry for the given ent so the ent can be
// respawned elsewhere
void(entity ent) CopyToBodyQue =
void (entity ent)
CopyToBodyQueue =
{
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;
bodyqueue_head.skin = ent.skin;
bodyqueue_head.angles = ent.angles;
bodyqueue_head.model = ent.model;
bodyqueue_head.modelindex = ent.modelindex;
bodyqueue_head.frame = ent.frame;
bodyqueue_head.colormap = ent.colormap;
bodyqueue_head.movetype = ent.movetype;
bodyqueue_head.velocity = ent.velocity;
bodyqueue_head.flags = 0;
setorigin (bodyqueue_head, ent.origin);
setsize (bodyqueue_head, ent.mins, ent.maxs);
bodyqueue_head = bodyqueue_head.owner;
};