Compare commits

...

5 Commits

Author SHA1 Message Date
archive 0e20a29227 as released 2000-05-04 2000-05-04 00:00:00 +00:00
archive 5ec19369e5 as released 1998-08-26 1998-08-26 00:00:00 +00:00
archive 88be1d246c as released 1997-08-12 1997-08-12 00:00:00 +00:00
archive 2a4c0638b2 as released 1997-08-10 1997-08-10 00:00:00 +00:00
archive ba33f2e180 as released 1997-06-13 1997-06-13 00:00:00 +00:00
20 changed files with 1375 additions and 409 deletions

View File

@ -1,85 +0,0 @@
/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>
~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/
void() test_teleport_touch;
void() tele_done;
/*QUAKED test_teleport (0 .5 .8) ?
Teleporter testing
*/
void() test_teleport =
{
precache_model ("sprites/s_aball.spr");
setsize (self, self.mins, self.maxs);
self.touch = test_teleport_touch;
self.solid = 1;
if (!self.target)
objerror ("no target\n");
};
void() test_teleport_touch =
{
local entity oldself;
other.movetype = MOVETYPE_TOSS;
// other.solid = SOLID_NOT;
other.dest = '256 -128 -128';
oldself = self;
self = other;
// SUB_CalcMove (self.dest, 200, tele_done);
self.velocity = '1000 0 0 ';
self = oldself;
};
void() tele_done =
{
self.movetype = MOVETYPE_WALK;
self.solid = SOLID_SLIDEBOX;
};
/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>
~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/
void() test_goaway;
void() test_spawn;
/*QUAKED test_fodder (0 .5 .8) ?
beating guy
*/
void() test_fodder =
{
self.nextthink = time + 3;
self.think = test_spawn;
};
void() test_spawn =
{
local entity body;
makevectors (self.angles);
body = spawn();
setmodel (body, "progs/soldier.mdl");
setorigin (body, self.origin);
body.classname = "player";
body.health = 1000;
body.frags = 0;
body.takedamage = DAMAGE_AIM;
body.solid = SOLID_SLIDEBOX;
body.movetype = MOVETYPE_WALK;
body.show_hostile = 0;
body.weapon = 1;
body.velocity = v_forward * 200;
body.nextthink = time + 5;
body.think = test_goaway;
self.nextthink = time + 3;
self.think = test_spawn;
};
void() test_goaway =
{
remove (self);
};

View File

@ -1,4 +1,29 @@
// button and multiple button
/*
buttons.qc
button and multiple button
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
void() button_wait;
void() button_return;

433
client.qc
View File

@ -1,3 +1,29 @@
/*
client.qc
client functions
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
// prototypes
void () W_WeaponFrame;
@ -28,6 +54,7 @@ Use mangle instead of angle, so you can set pitch or roll as well as yaw. 'pitc
*/
void() info_intermission =
{
self.angles = self.mangle; // so C can get at it
};
@ -133,11 +160,21 @@ entity() FindIntermission =
void() GotoNextMap =
{
local string newmap;
//ZOID: 12-13-96, samelevel is overloaded, only 1 works for same level
if (cvar("samelevel") == 1) // if samelevel is set, stay on same level
changelevel (mapname);
else
changelevel (nextmap);
else {
// configurable map lists, see if the current map exists as a
// serverinfo/localinfo var
newmap = infokey(world, mapname);
if (newmap != "")
changelevel (newmap);
else
changelevel (nextmap);
}
};
@ -302,8 +339,14 @@ Returns the entity to spawn at
*/
entity() SelectSpawnPoint =
{
local entity spot, thing;
local float pcount;
local entity spot, newspot, thing;
local float numspots, totalspots;
local float rnum, pcount;
local float rs;
local entity spots;
numspots = 0;
totalspots = 0;
// testinfo_player_start is only found in regioned levels
spot = find (world, classname, "testplayerstart");
@ -311,37 +354,61 @@ entity() SelectSpawnPoint =
return spot;
// choose a info_player_deathmatch point
spot = lastspawn;
while (1)
{
spot = find(spot, classname, "info_player_deathmatch");
if (spot != world)
{
if (spot == lastspawn)
return lastspawn;
pcount = 0;
thing = findradius(spot.origin, 50);
while(thing)
{
if (thing.classname == "player")
pcount = pcount + 1;
thing = thing.chain;
}
if (pcount == 0)
{
lastspawn = spot;
return spot;
}
}
}
spot = find (world, classname, "info_player_start");
if (!spot)
error ("PutClientInServer: no info_player_start on level");
return spot;
};
// ok, find all spots that don't have players nearby
spots = world;
spot = find (world, classname, "info_player_deathmatch");
while (spot)
{
totalspots = totalspots + 1;
thing=findradius(spot.origin, 84);
pcount=0;
while (thing)
{
if (thing.classname == "player")
pcount=pcount + 1;
thing=thing.chain;
}
if (pcount == 0) {
spot.goalentity = spots;
spots = spot;
numspots = numspots + 1;
}
// Get the next spot in the chain
spot = find (spot, classname, "info_player_deathmatch");
}
totalspots=totalspots - 1;
if (!numspots) {
// ack, they are all full, just pick one at random
// bprint (PRINT_HIGH, "Ackk! All spots are full. Selecting random spawn spot\n");
totalspots = rint((random() * totalspots));
spot = find (world, classname, "info_player_deathmatch");
while (totalspots > 0) {
totalspots = totalspots - 1;
spot = find (spot, classname, "info_player_deathmatch");
}
return spot;
}
// We now have the number of spots available on the map in numspots
// Generate a random number between 1 and numspots
numspots = numspots - 1;
numspots = rint((random() * numspots ) );
spot = spots;
while (numspots > 0) {
spot = spot.goalentity;
numspots = numspots - 1;
}
return spot;
};
void() DecodeLevelParms;
void() PlayerDie;
@ -412,6 +479,7 @@ called each time a player enters a new level
void() PutClientInServer =
{
local entity spot;
local string s;
self.classname = "player";
self.health = 100;
@ -459,6 +527,11 @@ void() PutClientInServer =
self.view_ofs = '0 0 22';
// Mod - Xian (May.20.97)
// Bug where player would have velocity from their last kill
self.velocity = '0 0 0';
player_stand1 ();
makevectors(self.angles);
@ -472,6 +545,53 @@ void() PutClientInServer =
rj = stof(infokey(world, "rj"));
}
if (deathmatch == 4)
{
self.ammo_shells = 0;
if (stof(infokey(world, "axe")) == 0)
{
self.ammo_nails = 255;
self.ammo_shells = 255;
self.ammo_rockets = 255;
self.ammo_cells = 255;
self.items = self.items | IT_NAILGUN;
self.items = self.items | IT_SUPER_NAILGUN;
self.items = self.items | IT_SUPER_SHOTGUN;
self.items = self.items | IT_ROCKET_LAUNCHER;
// self.items = self.items | IT_GRENADE_LAUNCHER;
self.items = self.items | IT_LIGHTNING;
}
self.items = self.items - (self.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + IT_ARMOR3;
self.armorvalue = 200;
self.armortype = 0.8;
self.health = 250;
self.items = self.items | IT_INVULNERABILITY;
self.invincible_time = 1;
self.invincible_finished = time + 3;
}
if (deathmatch == 5)
{
self.ammo_nails = 80;
self.ammo_shells = 30;
self.ammo_rockets = 10;
self.ammo_cells = 30;
self.items = self.items | IT_NAILGUN;
self.items = self.items | IT_SUPER_NAILGUN;
self.items = self.items | IT_SUPER_SHOTGUN;
self.items = self.items | IT_ROCKET_LAUNCHER;
self.items = self.items | IT_GRENADE_LAUNCHER;
self.items = self.items | IT_LIGHTNING;
self.items = self.items - (self.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + IT_ARMOR3;
self.armorvalue = 200;
self.armortype = 0.8;
self.health = 200;
self.items = self.items | IT_INVULNERABILITY;
self.invincible_time = 1;
self.invincible_finished = time + 3;
}
};
@ -527,6 +647,10 @@ go to the next level for deathmatch
void() NextLevel =
{
local entity o;
local string newmap;
if (nextmap != "")
return; // already done
if (mapname == "start")
{
@ -560,7 +684,7 @@ void() NextLevel =
}
else
{
// find a trigger changelevel
// find a trigger changelevel
o = find(world, classname, "trigger_changelevel");
if (!o || mapname == "start")
{ // go back to same map if no trigger_changelevel
@ -805,6 +929,8 @@ void() PlayerPreThink =
makevectors (self.v_angle); // is this still used
self.deathtype = "";
CheckRules ();
WaterMove ();
/*
@ -921,9 +1047,15 @@ void() CheckPowerups =
self.invincible_finished = 0;
}
if (self.invincible_finished > time)
{
self.effects = self.effects | EF_DIMLIGHT;
self.effects = self.effects | EF_RED;
}
else
{
self.effects = self.effects - (self.effects & EF_DIMLIGHT);
self.effects = self.effects - (self.effects & EF_RED);
}
}
// super damage
@ -936,7 +1068,10 @@ void() CheckPowerups =
{
if (self.super_time == 1)
{
sprint (self, PRINT_HIGH, "Quad Damage is wearing off\n");
if (deathmatch == 4)
sprint (self, PRINT_HIGH, "OctaPower is wearing off\n");
else
sprint (self, PRINT_HIGH, "Quad Damage is wearing off\n");
stuffcmd (self, "bf\n");
sound (self, CHAN_AUTO, "items/damage2.wav", 1, ATTN_NORM);
self.super_time = time + 1;
@ -952,13 +1087,26 @@ void() CheckPowerups =
if (self.super_damage_finished < time)
{ // just stopped
self.items = self.items - IT_QUAD;
if (deathmatch == 4)
{
self.ammo_cells = 255;
self.armorvalue = 1;
self.armortype = 0.8;
self.health = 100;
}
self.super_damage_finished = 0;
self.super_time = 0;
}
if (self.super_damage_finished > time)
{
self.effects = self.effects | EF_DIMLIGHT;
self.effects = self.effects | EF_BLUE;
}
else
{
self.effects = self.effects - (self.effects & EF_DIMLIGHT);
self.effects = self.effects - (self.effects & EF_BLUE);
}
}
// suit
@ -1020,9 +1168,9 @@ void() PlayerPostThink =
sound (self, CHAN_BODY, "player/h2ojump.wav", 1, ATTN_NORM);
else if (self.jump_flag < -650)
{
self.deathtype = "falling";
T_Damage (self, world, world, 5);
sound (self, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
self.deathtype = "falling";
}
else
sound (self, CHAN_VOICE, "player/land.wav", 1, ATTN_NORM);
@ -1066,9 +1214,9 @@ void() ClientDisconnect =
{
// let everyone else know
bprint (PRINT_HIGH, self.netname);
bprint (PRINT_HIGH, " left the game with ");
bprint (PRINT_HIGH, ftos(self.frags));
bprint (PRINT_HIGH, " frags\n");
bprint (PRINT_HIGH, " left the game with ");
bprint (PRINT_HIGH, ftos(self.frags));
bprint (PRINT_HIGH, " frags\n");
sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE);
set_suicide_frame ();
};
@ -1080,6 +1228,7 @@ ClientObituary
called when a player dies
============
*/
void(entity targ, entity attacker) ClientObituary =
{
local float rnum;
@ -1088,15 +1237,31 @@ void(entity targ, entity attacker) ClientObituary =
local string attackerteam, targteam;
rnum = random();
//ZOID 12-13-96: self.team doesn't work in QW. Use keys
attackerteam = infokey(attacker, "team");
targteam = infokey(targ, "team");
if (targ.classname == "player")
{
if (deathmatch > 3)
{
if (targ.deathtype == "selfwater")
{
bprint (PRINT_MEDIUM, targ.netname);
bprint (PRINT_MEDIUM," electrocutes himself.\n ");
targ.frags = targ.frags - 1;
return;
}
}
if (attacker.classname == "teledeath")
{
bprint (PRINT_MEDIUM,targ.netname);
bprint (PRINT_MEDIUM," was telefragged by ");
bprint (PRINT_MEDIUM,attacker.owner.netname);
bprint (PRINT_MEDIUM,"\n");
logfrag (attacker.owner, targ);
attacker.owner.frags = attacker.owner.frags + 1;
return;
@ -1113,30 +1278,72 @@ void(entity targ, entity attacker) ClientObituary =
return;
}
// double 666 telefrag (can happen often in deathmatch 4)
if (attacker.classname == "teledeath3")
{
bprint (PRINT_MEDIUM,targ.netname);
bprint (PRINT_MEDIUM," was telefragged by ");
bprint (PRINT_MEDIUM,attacker.owner.netname);
bprint (PRINT_MEDIUM, "'s Satan's power\n");
targ.frags = targ.frags - 1;
logfrag (targ, targ);
return;
}
if (targ.deathtype == "squish")
{
if (teamplay && targteam == attackerteam && attackerteam != "" && targ != attacker)
{
logfrag (attacker, attacker);
attacker.frags = attacker.frags - 1;
bprint (PRINT_MEDIUM,attacker.netname);
bprint (PRINT_MEDIUM," squished a teammate\n");
return;
}
else if (attacker.classname == "player" && attacker != targ)
{
bprint (PRINT_MEDIUM, attacker.netname);
bprint (PRINT_MEDIUM," squishes ");
bprint (PRINT_MEDIUM,targ.netname);
bprint (PRINT_MEDIUM,"\n");
logfrag (attacker, targ);
attacker.frags = attacker.frags + 1;
return;
}
else
{
logfrag (targ, targ);
targ.frags = targ.frags - 1; // killed self
bprint (PRINT_MEDIUM,targ.netname);
bprint (PRINT_MEDIUM," was squished\n");
return;
}
}
if (attacker.classname == "player")
{
//ZOID 12-13-96: self.team doesn't work in QW. Use keys
attackerteam = infokey(attacker, "team");
targteam = infokey(targ, "team");
if (targ == attacker)
{
// killed self
logfrag (attacker, attacker);
attacker.frags = attacker.frags - 1;
bprint (PRINT_MEDIUM,targ.netname);
if (targ.weapon == 64 && targ.waterlevel > 1)
{
bprint (PRINT_MEDIUM," discharges into the water.\n");
return;
}
if (targ.weapon == 16)
if (targ.deathtype == "grenade")
bprint (PRINT_MEDIUM," tries to put the pin back in\n");
else if (rnum)
else if (targ.deathtype == "rocket")
bprint (PRINT_MEDIUM," becomes bored with life\n");
else if (targ.weapon == 64 && targ.waterlevel > 1)
{
if (targ.watertype == CONTENT_SLIME)
bprint (PRINT_MEDIUM," discharges into the slime\n");
else if (targ.watertype == CONTENT_LAVA)
bprint (PRINT_MEDIUM," discharges into the lava\n");
else
bprint (PRINT_MEDIUM," discharges into the water.\n");
}
else
bprint (PRINT_MEDIUM," checks if his weapon is loaded\n");
bprint (PRINT_MEDIUM," becomes bored with life\n");
return;
}
else if ( (teamplay == 2) && (targteam == attackerteam) &&
@ -1163,32 +1370,17 @@ void(entity targ, entity attacker) ClientObituary =
attacker.frags = attacker.frags + 1;
rnum = attacker.weapon;
if (rnum == IT_AXE)
{
deathstring = " was ax-murdered by ";
deathstring2 = "\n";
}
if (rnum == IT_SHOTGUN)
{
deathstring = " chewed on ";
deathstring2 = "'s boomstick\n";
}
if (rnum == IT_SUPER_SHOTGUN)
{
deathstring = " ate 2 loads of ";
deathstring2 = "'s buckshot\n";
}
if (rnum == IT_NAILGUN)
if (targ.deathtype == "nail")
{
deathstring = " was nailed by ";
deathstring2 = "\n";
}
if (rnum == IT_SUPER_NAILGUN)
else if (targ.deathtype == "supernail")
{
deathstring = " was punctured by ";
deathstring2 = "\n";
}
if (rnum == IT_GRENADE_LAUNCHER)
else if (targ.deathtype == "grenade")
{
deathstring = " eats ";
deathstring2 = "'s pineapple\n";
@ -1198,17 +1390,52 @@ void(entity targ, entity attacker) ClientObituary =
deathstring2 = "'s grenade\n";
}
}
if (rnum == IT_ROCKET_LAUNCHER)
else if (targ.deathtype == "rocket")
{
deathstring = " rides ";
deathstring2 = "'s rocket\n";
if (targ.health < -40)
if (attacker.super_damage_finished > 0 && targ.health < -40)
{
deathstring = " was gibbed by ";
deathstring2 = "'s rocket\n" ;
rnum = random();
if (rnum < 0.3)
deathstring = " was brutalized by ";
else if (rnum < 0.6)
deathstring = " was smeared by ";
else
{
bprint (PRINT_MEDIUM, attacker.netname);
bprint (PRINT_MEDIUM, " rips ");
bprint (PRINT_MEDIUM, targ.netname);
bprint (PRINT_MEDIUM, " a new one\n");
return;
}
deathstring2 = "'s quad rocket\n";
}
else
{
deathstring = " rides ";
deathstring2 = "'s rocket\n";
if (targ.health < -40)
{
deathstring = " was gibbed by ";
deathstring2 = "'s rocket\n" ;
}
}
}
if (rnum == IT_LIGHTNING)
else if (rnum == IT_AXE)
{
deathstring = " was ax-murdered by ";
deathstring2 = "\n";
}
else if (rnum == IT_SHOTGUN)
{
deathstring = " chewed on ";
deathstring2 = "'s boomstick\n";
}
else if (rnum == IT_SUPER_SHOTGUN)
{
deathstring = " ate 2 loads of ";
deathstring2 = "'s buckshot\n";
}
else if (rnum == IT_LIGHTNING)
{
deathstring = " accepts ";
if (attacker.waterlevel > 1)
@ -1260,64 +1487,26 @@ void(entity targ, entity attacker) ClientObituary =
return;
}
if (attacker.flags & FL_MONSTER)
{
if (attacker.classname == "monster_army")
bprint (PRINT_MEDIUM," was shot by a Grunt\n");
if (attacker.classname == "monster_demon1")
bprint (PRINT_MEDIUM," was eviscerated by a Fiend\n");
if (attacker.classname == "monster_dog")
bprint (PRINT_MEDIUM," was mauled by a Rottweiler\n");
if (attacker.classname == "monster_dragon")
bprint (PRINT_MEDIUM," was fried by a Dragon\n");
if (attacker.classname == "monster_enforcer")
bprint (PRINT_MEDIUM," was blasted by an Enforcer\n");
if (attacker.classname == "monster_fish")
bprint (PRINT_MEDIUM," was fed to the Rotfish\n");
if (attacker.classname == "monster_hell_knight")
bprint (PRINT_MEDIUM," was slain by a Death Knight\n");
if (attacker.classname == "monster_knight")
bprint (PRINT_MEDIUM," was slashed by a Knight\n");
if (attacker.classname == "monster_ogre")
bprint (PRINT_MEDIUM," was destroyed by an Ogre\n");
if (attacker.classname == "monster_oldone")
bprint (PRINT_MEDIUM," became one with Shub-Niggurath\n");
if (attacker.classname == "monster_shalrath")
bprint (PRINT_MEDIUM," was exploded by a Vore\n");
if (attacker.classname == "monster_shambler")
bprint (PRINT_MEDIUM," was smashed by a Shambler\n");
if (attacker.classname == "monster_tarbaby")
bprint (PRINT_MEDIUM," was slimed by a Spawn\n");
if (attacker.classname == "monster_vomit")
bprint (PRINT_MEDIUM," was vomited on by a Vomitus\n");
if (attacker.classname == "monster_wizard")
bprint (PRINT_MEDIUM," was scragged by a Scrag\n");
if (attacker.classname == "monster_zombie")
bprint (PRINT_MEDIUM," joins the Zombies\n");
return;
}
if (attacker.classname == "explo_box")
{
bprint (PRINT_MEDIUM," blew up\n");
return;
}
if (attacker.solid == SOLID_BSP && attacker != world)
{
bprint (PRINT_MEDIUM," was squished\n");
return;
}
if (targ.deathtype == "falling")
{
targ.deathtype = "";
bprint (PRINT_MEDIUM," fell to his death\n");
return;
}
if (attacker.classname == "trap_shooter" || attacker.classname == "trap_spikeshooter")
if (targ.deathtype == "nail" || targ.deathtype == "supernail")
{
bprint (PRINT_MEDIUM," was spiked\n");
return;
}
if (targ.deathtype == "laser")
{
bprint (PRINT_MEDIUM," was zapped\n");
return;
}
if (attacker.classname == "fireball")
{
bprint (PRINT_MEDIUM," ate a lavaball\n");

View File

@ -1,7 +1,34 @@
/*
combat.qc
damage, obit, etc related functions
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
void() T_MissileTouch;
void() info_player_start;
void(entity targ, entity attacker) ClientObituary;
void(entity inflictor, entity attacker, float damage, entity ignore, string dtype) T_RadiusDamage;
/*SERVER
void() monster_death_use;
@ -120,8 +147,12 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
// used by buttons and triggers to set activator for target firing
damage_attacker = attacker;
// check for quad damage powerup on the attacker
if (attacker.super_damage_finished > time)
if (attacker.super_damage_finished > time && inflictor.classname != "door")
if (deathmatch == 4)
damage = damage * 8;
else
damage = damage * 4;
// save damage based on the target's armor level
@ -156,10 +187,11 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
dir = normalize(dir);
// Set kickback for smaller weapons
// Read: only if it's not yourself doing the damage
if ( (damage < 60) & ((attacker.classname == "player") & (targ.classname == "player")) & ( attacker.netname != targ.netname))
targ.velocity = targ.velocity + dir * damage * 11;
else
//Zoid -- use normal NQ kickback
// // Read: only if it's not yourself doing the damage
// if ( (damage < 60) & ((attacker.classname == "player") & (targ.classname == "player")) & ( attacker.netname != targ.netname))
// targ.velocity = targ.velocity + dir * damage * 11;
// else
// Otherwise, these rules apply to rockets and grenades
// for blast velocity
targ.velocity = targ.velocity + dir * damage * 8;
@ -170,6 +202,8 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
}
// check for godmode or invincibility
if (targ.flags & FL_GODMODE)
return;
@ -189,16 +223,18 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
targteam = infokey(targ, "team");
if ((teamplay == 1) && (targteam == attackerteam) &&
(attacker.classname == "player") && (attackerteam != ""))
(attacker.classname == "player") && (attackerteam != "") &&
inflictor.classname !="door")
return;
if ((teamplay == 3) && (targteam == attackerteam) &&
(attacker.classname == "player") && (attackerteam != "") &&
(targ != attacker))
(targ != attacker)&& inflictor.classname !="door")
return;
// do the damage
targ.health = targ.health - take;
if (targ.health <= 0)
{
Killed (targ, attacker);
@ -239,7 +275,7 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
T_RadiusDamage
============
*/
void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
void(entity inflictor, entity attacker, float damage, entity ignore, string dtype) T_RadiusDamage =
{
local float points;
local entity head;
@ -249,6 +285,11 @@ void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDam
while (head)
{
//bprint (PRINT_HIGH, head.classname);
//bprint (PRINT_HIGH, " | ");
//bprint (PRINT_HIGH, head.netname);
//bprint (PRINT_HIGH, "\n");
if (head != ignore)
{
if (head.takedamage)
@ -258,16 +299,15 @@ void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDam
if (points < 0)
points = 0;
points = damage - points;
if (head == attacker)
points = points * 0.5;
if (points > 0)
{
if (CanDamage (head, inflictor))
{ // shambler takes half damage from all explosions
if (head.classname == "monster_shambler")
T_Damage (head, inflictor, attacker, points*0.5);
else
T_Damage (head, inflictor, attacker, points);
{
head.deathtype = dtype;
T_Damage (head, inflictor, attacker, points);
}
}
}
@ -301,12 +341,7 @@ void(entity attacker, float damage) T_BeamDamage =
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);
}
T_Damage (head, attacker, attacker, points);
}
}
head = head.chain;

43
defs.qc
View File

@ -1,3 +1,29 @@
/*
defs.qc
global definitions
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
/*
==============================================================================
@ -390,8 +416,9 @@ float EF_BRIGHTLIGHT = 4;
float EF_DIMLIGHT = 8;
float EF_FLAG1 = 16;
float EF_FLAG2 = 32;
// GLQuakeWorld Stuff
float EF_BLUE = 64; // Blue Globe effect for Quad
float EF_RED = 128; // Red Globe effect for Pentagram
// messages
float MSG_BROADCAST = 0; // unreliable to all
float MSG_ONE = 1; // reliable to one (msg_entity)
@ -401,7 +428,7 @@ float MSG_MULTICAST = 4; // for multicast() call
// message levels
float PRINT_LOW = 0; // pickup messages
float PRINT_MEDIUM = 1; // death messages
float PRINT_MEDIUM = 1; // death messages
float PRINT_HIGH = 2; // critical messages
float PRINT_CHAT = 3; // also goes to chat console
@ -413,6 +440,9 @@ float MULTICAST_ALL_R = 3; // every client, reliable
float MULTICAST_PHS_R = 4; // within hearing, reliable
float MULTICAST_PVS_R = 5; // within sight, reliable
//================================================
//
@ -486,8 +516,15 @@ float AS_MISSILE = 4;
//
// player only fields
//
.float voided;
.float walkframe;
// Zoid Additions
.float maxspeed; // Used to set Maxspeed on a player
.float gravity; // Gravity Multiplier (0 to 1.0)
.float attack_finished;
.float pain_finished;

127
doors.qc
View File

@ -1,3 +1,29 @@
/*
doors.qc
door functions
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
float DOOR_START_OPEN = 1;
float DOOR_DONT_LINK = 4;
@ -31,8 +57,9 @@ void() door_go_up;
void() door_blocked =
{
T_Damage (other, self, self, self.dmg);
other.deathtype = "squish";
T_Damage (other, self, self.goalentity, 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)
@ -50,7 +77,7 @@ void() door_hit_top =
sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_TOP;
if (self.spawnflags & DOOR_TOGGLE)
return; // don't come down automatically
return; // don't come down automatically
self.think = door_go_down;
self.nextthink = self.ltime + self.wait;
};
@ -77,10 +104,10 @@ void() door_go_down =
void() door_go_up =
{
if (self.state == STATE_UP)
return; // allready going up
return; // allready going up
if (self.state == STATE_TOP)
{ // reset top wait time
{ // reset top wait time
self.nextthink = self.ltime + self.wait;
return;
}
@ -103,8 +130,8 @@ ACTIVATION FUNCTIONS
void() door_fire =
{
local entity oself;
local entity starte;
local entity oself;
local entity starte;
if (self.owner != self)
objerror ("door_fire: self.owner != self");
@ -114,7 +141,7 @@ void() door_fire =
if (self.items)
sound (self, CHAN_VOICE, self.noise4, 1, ATTN_NORM);
self.message = string_null; // no more message
self.message = string_null; // no more message
oself = self;
if (self.spawnflags & DOOR_TOGGLE)
@ -134,8 +161,10 @@ void() door_fire =
// trigger all paired doors
starte = self;
do
{
self.goalentity = activator; // Who fired us
door_go_up ();
self = self.enemy;
} while ( (self != starte) && (self != world) );
@ -147,9 +176,10 @@ void() door_use =
{
local entity oself;
self.message = ""; // door message are for touch only
self.owner.message = "";
self.message = ""; // door message are for touch only
self.owner.message = "";
self.enemy.message = "";
oself = self;
self = self.owner;
door_fire ();
@ -180,7 +210,7 @@ void() door_killed =
oself = self;
self = self.owner;
self.health = self.max_health;
self.takedamage = DAMAGE_NO; // wil be reset upon return
self.takedamage = DAMAGE_NO; // wil be reset upon return
door_use ();
self = oself;
};
@ -243,7 +273,7 @@ void() door_touch =
else if (world.worldtype == 1)
{
centerprint (other, "You need the gold runekey");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
else if (world.worldtype == 0)
{
@ -257,7 +287,7 @@ void() door_touch =
other.items = other.items - self.items;
self.touch = SUB_Null;
if (self.enemy)
self.enemy.touch = SUB_Null; // get paired door
self.enemy.touch = SUB_Null; // get paired door
door_use ();
};
@ -272,8 +302,8 @@ SPAWNING FUNCTIONS
entity(vector fmins, vector fmaxs) spawn_field =
{
local entity trigger;
local vector t1, t2;
local entity trigger;
local vector t1, t2;
trigger = spawn();
trigger.movetype = MOVETYPE_NONE;
@ -315,15 +345,15 @@ LinkDoors
*/
void() LinkDoors =
{
local entity t, starte;
local vector cmins, cmaxs;
local entity t, starte;
local vector cmins, cmaxs;
if (self.enemy)
return; // already linked by another door
return; // already linked by another door
if (self.spawnflags & 4)
{
self.owner = self.enemy = self;
return; // don't want to link this door
return; // don't want to link this door
}
cmins = self.mins;
@ -334,7 +364,7 @@ void() LinkDoors =
do
{
self.owner = starte; // master door
self.owner = starte; // master door
if (self.health)
starte.health = self.health;
@ -343,10 +373,10 @@ void() LinkDoors =
if (self.message != "")
starte.message = self.message;
t = find (t, classname, self.classname);
t = find (t, classname, self.classname);
if (!t)
{
self.enemy = starte; // make the chain a loop
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
@ -400,20 +430,20 @@ START_OPEN causes the door to move to its destination when spawned, and operate
Key doors are allways wait -1.
"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet
"angle" determines the opening direction
"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet
"angle" determines the opening direction
"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door.
"health" if set, door must be shot open
"speed" movement speed (100 default)
"wait" wait before returning (3 default, -1 = never return)
"lip" lip remaining at end of move (8 default)
"dmg" damage to inflict when blocked (2 default)
"health" if set, door must be shot open
"speed" movement speed (100 default)
"wait" wait before returning (3 default, -1 = never return)
"lip" lip remaining at end of move (8 default)
"dmg" damage to inflict when blocked (2 default)
"sounds"
0) no sound
1) stone
2) base
3) stone chain
4) screechy metal
0) no sound
1) stone
2) base
3) stone chain
4) screechy metal
*/
void() func_door =
@ -487,7 +517,7 @@ void() func_door =
self.max_health = self.health;
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_PUSH;
setorigin (self, self.origin);
setorigin (self, self.origin);
setmodel (self, self.model);
self.classname = "door";
@ -555,11 +585,11 @@ void() fd_secret_move5;
void() fd_secret_move6;
void() fd_secret_done;
float SECRET_OPEN_ONCE = 1; // stays open
float SECRET_1ST_LEFT = 2; // 1st move is left of arrow
float SECRET_1ST_DOWN = 4; // 1st move is down from arrow
float SECRET_NO_SHOOT = 8; // only opened by trigger
float SECRET_YES_SHOOT = 16; // shootable even if targeted
float SECRET_OPEN_ONCE = 1; // stays open
float SECRET_1ST_LEFT = 2; // 1st move is left of arrow
float SECRET_1ST_DOWN = 4; // 1st move is down from arrow
float SECRET_NO_SHOOT = 8; // only opened by trigger
float SECRET_YES_SHOOT = 16; // shootable even if targeted
void () fd_secret_use =
@ -572,9 +602,9 @@ void () fd_secret_use =
if (self.origin != self.oldorigin)
return;
self.message = string_null; // no more message
self.message = string_null; // no more message
SUB_UseTargets(); // fire all targets / killtargets
SUB_UseTargets(); // fire all targets / killtargets
if (!(self.spawnflags & SECRET_NO_SHOOT))
{
@ -588,7 +618,7 @@ void () fd_secret_use =
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
temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1
makevectors(self.mangle);
if (!self.t_width)
@ -642,7 +672,7 @@ void () fd_secret_move3 =
void () fd_secret_move4 =
{
sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
SUB_CalcMove(self.dest1, self.speed, fd_secret_move5);
SUB_CalcMove(self.dest1, self.speed, fd_secret_move5);
};
// Wait 1 second...
@ -665,7 +695,7 @@ void () fd_secret_done =
{
self.health = 10000;
self.takedamage = DAMAGE_YES;
self.th_pain = fd_secret_use;
self.th_pain = fd_secret_use;
self.th_die = fd_secret_use;
}
sound(self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise3, 1, ATTN_NORM);
@ -676,6 +706,7 @@ void () secret_blocked =
if (time < self.attack_finished)
return;
self.attack_finished = time + 0.5;
other.deathtype = "squish";
T_Damage (other, self, self, self.dmg);
};
@ -711,7 +742,7 @@ wait = # of seconds before coming back
always_shoot = even if targeted, keep shootable
t_width = override WIDTH to move back (or height if going down)
t_length = override LENGTH to move sideways
"dmg" damage to inflict when blocked (2 default)
"dmg" damage to inflict when blocked (2 default)
If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage.
"sounds"
@ -760,7 +791,7 @@ void () func_door_secret =
self.movetype = MOVETYPE_PUSH;
self.classname = "door";
setmodel (self, self.model);
setorigin (self, self.origin);
setorigin (self, self.origin);
self.touch = secret_touch;
self.blocked = secret_blocked;
@ -774,5 +805,5 @@ void () func_door_secret =
}
self.oldorigin = self.origin;
if (!self.wait)
self.wait = 5; // 5 seconds before closing
self.wait = 5; // 5 seconds before closing
};

266
items.qc
View File

@ -1,3 +1,29 @@
/*
items.qc
item functions
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
void() W_SetCurrentAmmo;
/* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
BE .8 .3 .4 IN COLOR */
@ -24,7 +50,134 @@ void() noclass =
remove (self);
};
void() q_touch;
void() q_touch =
{
local entity stemp;
local float best;
local string s;
if (other.classname != "player")
return;
if (other.health <= 0)
return;
self.mdl = self.model;
sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
stuffcmd (other, "bf\n");
self.solid = SOLID_NOT;
other.items = other.items | IT_QUAD;
self.model = string_null;
if (deathmatch == 4)
{
other.armortype = 0;
other.armorvalue = 0 * 0.01;
other.ammo_cells = 0;
}
// do the apropriate action
other.super_time = 1;
other.super_damage_finished = self.cnt;
s=ftos(rint(other.super_damage_finished - time));
bprint (PRINT_LOW, other.netname);
if (deathmatch == 4)
bprint (PRINT_LOW, " recovered an OctaPower with ");
else
bprint (PRINT_LOW, " recovered a Quad with ");
bprint (PRINT_LOW, s);
bprint (PRINT_LOW, " seconds remaining!\n");
activator = other;
SUB_UseTargets(); // fire all targets / killtargets
};
void(float timeleft) DropQuad =
{
local entity item;
item = spawn();
item.origin = self.origin;
item.velocity_z = 300;
item.velocity_x = -100 + (random() * 200);
item.velocity_y = -100 + (random() * 200);
item.flags = FL_ITEM;
item.solid = SOLID_TRIGGER;
item.movetype = MOVETYPE_TOSS;
item.noise = "items/damage.wav";
setmodel (item, "progs/quaddama.mdl");
setsize (item, '-16 -16 -24', '16 16 32');
item.cnt = time + timeleft;
item.touch = q_touch;
item.nextthink = time + timeleft; // remove it with the time left on it
item.think = SUB_Remove;
};
void() r_touch;
void() r_touch =
{
local entity stemp;
local float best;
local string s;
if (other.classname != "player")
return;
if (other.health <= 0)
return;
self.mdl = self.model;
sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
stuffcmd (other, "bf\n");
self.solid = SOLID_NOT;
other.items = other.items | IT_INVISIBILITY;
self.model = string_null;
// do the apropriate action
other.invisible_time = 1;
other.invisible_finished = self.cnt;
s=ftos(rint(other.invisible_finished - time));
bprint (PRINT_LOW, other.netname);
bprint (PRINT_LOW, " recovered a Ring with ");
bprint (PRINT_LOW, s);
bprint (PRINT_LOW, " seconds remaining!\n");
activator = other;
SUB_UseTargets(); // fire all targets / killtargets
};
void(float timeleft) DropRing =
{
local entity item;
item = spawn();
item.origin = self.origin;
item.velocity_z = 300;
item.velocity_x = -100 + (random() * 200);
item.velocity_y = -100 + (random() * 200);
item.flags = FL_ITEM;
item.solid = SOLID_TRIGGER;
item.movetype = MOVETYPE_TOSS;
item.noise = "items/inv1.wav";
setmodel (item, "progs/invisibl.mdl");
setsize (item, '-16 -16 -24', '16 16 32');
item.cnt = time + timeleft;
item.touch = r_touch;
item.nextthink = time + timeleft; // remove after 30 seconds
item.think = SUB_Remove;
};
/*
============
@ -152,6 +305,10 @@ void() health_touch =
local float amount;
local string s;
if (deathmatch == 4)
if (other.invincible_time > 0)
return;
if (other.classname != "player")
return;
@ -185,8 +342,11 @@ void() health_touch =
if (self.healtype == 2)
{
other.items = other.items | IT_SUPERHEALTH;
self.nextthink = time + 5;
self.think = item_megahealth_rot;
if (deathmatch != 4)
{
self.nextthink = time + 5;
self.think = item_megahealth_rot;
}
self.owner = other;
}
else
@ -243,6 +403,10 @@ void() armor_touch =
if (other.classname != "player")
return;
if (deathmatch == 4)
if (other.invincible_time > 0)
return;
if (self.classname == "item_armor1")
{
type = 0.3;
@ -428,7 +592,7 @@ void() weapon_touch =
best = W_BestWeapon();
self = stemp;
if (deathmatch == 2 || deathmatch == 3)
if (deathmatch == 2 || deathmatch == 3 || deathmatch == 5)
leave = 1;
else
leave = 0;
@ -522,7 +686,7 @@ void() weapon_touch =
if (leave)
return;
if (deathmatch!=3)
if (deathmatch!=3 || deathmatch !=5)
{
// remove it in single player, or setup for respawning in deathmatch
self.model = string_null;
@ -540,6 +704,8 @@ void() weapon_touch =
*/
void() weapon_supershotgun =
{
if (deathmatch <= 3)
{
precache_model ("progs/g_shot.mdl");
setmodel (self, "progs/g_shot.mdl");
@ -548,12 +714,15 @@ void() weapon_supershotgun =
self.touch = weapon_touch;
setsize (self, '-16 -16 0', '16 16 56');
StartItem ();
}
};
/*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32)
*/
void() weapon_nailgun =
{
if (deathmatch <= 3)
{
precache_model ("progs/g_nail.mdl");
setmodel (self, "progs/g_nail.mdl");
@ -562,12 +731,15 @@ void() weapon_nailgun =
self.touch = weapon_touch;
setsize (self, '-16 -16 0', '16 16 56');
StartItem ();
}
};
/*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32)
*/
void() weapon_supernailgun =
{
if (deathmatch <= 3)
{
precache_model ("progs/g_nail2.mdl");
setmodel (self, "progs/g_nail2.mdl");
@ -576,12 +748,15 @@ void() weapon_supernailgun =
self.touch = weapon_touch;
setsize (self, '-16 -16 0', '16 16 56');
StartItem ();
}
};
/*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32)
*/
void() weapon_grenadelauncher =
{
if (deathmatch <= 3)
{
precache_model ("progs/g_rock.mdl");
setmodel (self, "progs/g_rock.mdl");
@ -590,12 +765,15 @@ void() weapon_grenadelauncher =
self.touch = weapon_touch;
setsize (self, '-16 -16 0', '16 16 56');
StartItem ();
}
};
/*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32)
*/
void() weapon_rocketlauncher =
{
if (deathmatch <= 3)
{
precache_model ("progs/g_rock2.mdl");
setmodel (self, "progs/g_rock2.mdl");
@ -604,6 +782,7 @@ void() weapon_rocketlauncher =
self.touch = weapon_touch;
setsize (self, '-16 -16 0', '16 16 56');
StartItem ();
}
};
@ -611,6 +790,8 @@ void() weapon_rocketlauncher =
*/
void() weapon_lightning =
{
if (deathmatch <= 3)
{
precache_model ("progs/g_light.mdl");
setmodel (self, "progs/g_light.mdl");
@ -619,6 +800,7 @@ void() weapon_lightning =
self.touch = weapon_touch;
setsize (self, '-16 -16 0', '16 16 56');
StartItem ();
}
};
@ -713,7 +895,7 @@ local float best;
// Xian -- If playing in DM 3.0 mode, halve the time ammo respawns
if (deathmatch == 3)
if (deathmatch == 3 || deathmatch == 5)
self.nextthink = time + 15;
self.think = SUB_regen;
@ -732,6 +914,9 @@ float WEAPON_BIG2 = 1;
void() item_shells =
{
if (deathmatch == 4)
return;
self.touch = ammo_touch;
if (self.spawnflags & WEAPON_BIG2)
@ -757,6 +942,9 @@ void() item_shells =
void() item_spikes =
{
if (deathmatch == 4)
return;
self.touch = ammo_touch;
if (self.spawnflags & WEAPON_BIG2)
@ -775,6 +963,7 @@ void() item_spikes =
self.netname = "nails";
setsize (self, '0 0 0', '32 32 56');
StartItem ();
};
/*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big
@ -782,6 +971,9 @@ void() item_spikes =
void() item_rockets =
{
if (deathmatch == 4)
return;
self.touch = ammo_touch;
if (self.spawnflags & WEAPON_BIG2)
@ -800,6 +992,7 @@ void() item_rockets =
self.netname = "rockets";
setsize (self, '0 0 0', '32 32 56');
StartItem ();
};
@ -808,6 +1001,9 @@ void() item_rockets =
void() item_cells =
{
if (deathmatch == 4)
return;
self.touch = ammo_touch;
if (self.spawnflags & WEAPON_BIG2)
@ -826,6 +1022,7 @@ void() item_cells =
self.netname = "cells";
setsize (self, '0 0 0', '32 32 56');
StartItem ();
};
@ -1165,6 +1362,12 @@ local float best;
if (self.classname == "item_artifact_super_damage")
{
if (deathmatch == 4)
{
other.armortype = 0;
other.armorvalue = 0 * 0.01;
other.ammo_cells = 0;
}
other.super_time = 1;
other.super_damage_finished = time + 30;
}
@ -1189,6 +1392,7 @@ void() item_artifact_invulnerability =
self.noise = "items/protect.wav";
setmodel (self, "progs/invulner.mdl");
self.netname = "Pentagram of Protection";
self.effects = self.effects | EF_RED;
self.items = IT_INVULNERABILITY;
setsize (self, '-16 -16 -24', '16 16 32');
StartItem ();
@ -1246,8 +1450,12 @@ void() item_artifact_super_damage =
precache_sound ("items/damage3.wav");
self.noise = "items/damage.wav";
setmodel (self, "progs/quaddama.mdl");
self.netname = "Quad Damage";
if (deathmatch == 4)
self.netname = "OctaPower";
else
self.netname = "Quad Damage";
self.items = IT_QUAD;
self.effects = self.effects | EF_BLUE;
setsize (self, '-16 -16 -24', '16 16 32');
StartItem ();
};
@ -1268,9 +1476,12 @@ void() BackpackTouch =
local float best, old, new;
local entity stemp;
local float acount;
local float b_switch;
if (deathmatch == 4)
if (other.invincible_time > 0)
return;
if ((stof(infokey(other,"b_switch"))) == 0)
b_switch = 8;
else
@ -1285,6 +1496,41 @@ void() BackpackTouch =
acount = 0;
sprint (other, PRINT_LOW, "You get ");
if (deathmatch == 4)
{
other.health = other.health + 10;
sprint (other, PRINT_LOW, "10 additional health\n");
if ((other.health > 250) && (other.health < 300))
sound (other, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
else
sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
stuffcmd (other, "bf\n");
remove(self);
if (other.health >299)
{
if (other.invincible_time != 1)
{
other.invincible_time = 1;
other.invincible_finished = time + 30;
other.items = other.items | IT_INVULNERABILITY;
other.super_time = 1;
other.super_damage_finished = time + 30;
other.items = other.items | IT_QUAD;
other.ammo_cells = 0;
sound (other, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM);
stuffcmd (other, "bf\n");
bprint (PRINT_HIGH, other.netname);
bprint (PRINT_HIGH, " attains bonus powers!!!\n");
}
}
self = other;
return;
}
if (self.items)
if ((other.items & self.items) == 0)
{
@ -1350,7 +1596,7 @@ void() BackpackTouch =
sprint (other,PRINT_LOW, " cells");
}
if ( (deathmatch==3) & ( (WeaponCode(new)==6) || (WeaponCode(new)==7) ) & (other.ammo_rockets < 5) )
if ( (deathmatch==3 || deathmatch == 5) & ( (WeaponCode(new)==6) || (WeaponCode(new)==7) ) & (other.ammo_rockets < 5) )
other.ammo_rockets = 5;
sprint (other, PRINT_LOW, "\n");
@ -1378,8 +1624,6 @@ void() BackpackTouch =
Deathmatch_Weapon (old, new);
}
}
W_SetCurrentAmmo ();
};
@ -1438,3 +1682,5 @@ void() DropBackpack =
item.nextthink = time + 120; // remove after 2 minutes
item.think = SUB_Remove;
};

View File

@ -1,15 +0,0 @@
void() jctrig =
{
dprint ("here\n\n");
lightstyle(0, "az");
};
/*QUAKED trigger_jctest (.5 .5 .5) ?
*/
void() trigger_jctest =
{
setsize (self, self.mins, self.maxs);
self.solid = SOLID_EDGE;
self.touch = jctrig;
};

69
misc.qc
View File

@ -1,3 +1,29 @@
/*
misc.qc
pretty much everything else
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4)
Used as a positional target for spotlights, etc.
@ -41,7 +67,7 @@ If targeted, it will toggle between on or off.
void() light =
{
if (!self.targetname)
{ // inert light
{ // inert light
remove(self);
return;
}
@ -181,7 +207,7 @@ void() misc_fireball =
void() fire_fly =
{
local entity fireball;
local entity fireball;
fireball = spawn();
fireball.solid = SOLID_TRIGGER;
@ -217,7 +243,7 @@ void() barrel_explode =
self.takedamage = DAMAGE_NO;
self.classname = "explo_box";
// did say self.owner
T_RadiusDamage (self, self, 160, world);
T_RadiusDamage (self, self, 160, world, "");
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_EXPLOSION);
WriteCoord (MSG_MULTICAST, self.origin_x);
@ -235,7 +261,7 @@ TESTING THING
void() misc_explobox =
{
local float oldz;
local float oldz;
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_NONE;
@ -268,7 +294,7 @@ Smaller exploding box, REGISTERED ONLY
void() misc_explobox2 =
{
local float oldz;
local float oldz;
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_NONE;
@ -294,7 +320,7 @@ void() misc_explobox2 =
//============================================================================
float SPAWNFLAG_SUPERSPIKE = 1;
float SPAWNFLAG_SUPERSPIKE = 1;
float SPAWNFLAG_LASER = 2;
void() Laser_Touch =
@ -302,7 +328,7 @@ void() Laser_Touch =
local vector org;
if (other == self.owner)
return; // don't explode on owner
return; // don't explode on owner
if (pointcontents(self.origin) == CONTENT_SKY)
{
@ -316,6 +342,7 @@ void() Laser_Touch =
if (other.health)
{
SpawnBlood (org, 15);
other.deathtype = "laser";
T_Damage (other, self, self.owner, 15);
}
else
@ -329,12 +356,12 @@ void() Laser_Touch =
multicast (org, MULTICAST_PVS);
}
remove(self);
remove(self);
};
void(vector org, vector vec) LaunchLaser =
{
local vector vec;
local vector vec;
if (self.classname == "monster_enforcer")
sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
@ -348,7 +375,7 @@ void(vector org, vector vec) LaunchLaser =
newmis.effects = EF_DIMLIGHT;
setmodel (newmis, "progs/laser.mdl");
setsize (newmis, '0 0 0', '0 0 0');
setsize (newmis, '0 0 0', '0 0 0');
setorigin (newmis, org);
@ -447,7 +474,7 @@ void() air_bubbles =
void() make_bubbles =
{
local entity bubble;
local entity bubble;
bubble = spawn();
setmodel (bubble, "progs/s_bubble.spr");
@ -468,7 +495,7 @@ local entity bubble;
void() bubble_split =
{
local entity bubble;
local entity bubble;
bubble = spawn();
setmodel (bubble, "progs/s_bubble.spr");
setorigin (bubble, self.origin);
@ -492,7 +519,7 @@ void() bubble_remove =
{
if (other.classname == self.classname)
{
// dprint ("bump");
// dprint ("bump");
return;
}
remove(self);
@ -500,8 +527,8 @@ void() bubble_remove =
void() bubble_bob =
{
local float rnd1, rnd2, rnd3;
local vector vtmp1, modi;
local float rnd1, rnd2, rnd3;
local vector vtmp1, modi;
self.cnt = self.cnt + 1;
if (self.cnt == 4)
@ -563,7 +590,7 @@ SIMPLE BMODELS
*/
void() func_wall_use =
{ // change to alternate textures
{ // change to alternate textures
self.frame = 1 - self.frame;
};
@ -573,7 +600,7 @@ This is just a solid wall if not inhibitted
void() func_wall =
{
self.angles = '0 0 0';
self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
self.solid = SOLID_BSP;
self.use = func_wall_use;
setmodel (self, self.model);
@ -600,10 +627,10 @@ void() func_episodegate =
{
if (!(serverflags & self.spawnflags))
return; // can still enter episode
return; // can still enter episode
self.angles = '0 0 0';
self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
self.solid = SOLID_BSP;
self.use = func_wall_use;
setmodel (self, self.model);
@ -616,9 +643,9 @@ void() func_bossgate =
{
if ( (serverflags & 15) == 15)
return; // all episodes completed
return; // all episodes completed
self.angles = '0 0 0';
self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
self.solid = SOLID_BSP;
self.use = func_wall_use;
setmodel (self, self.model);

View File

@ -1,3 +1,29 @@
/*
models.qc
model definitions
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
/*
===============================================================================

View File

@ -1,3 +1,29 @@
/*
plats.qc
platform functions
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
void() plat_center_touch;
@ -111,6 +137,7 @@ void() plat_crush =
{
//dprint ("plat_crush\n");
other.deathtype = "squish";
T_Damage (other, self, self, 1);
if (self.state == STATE_UP)
@ -223,8 +250,10 @@ void() train_blocked =
if (time < self.attack_finished)
return;
self.attack_finished = time + 0.5;
other.deathtype = "squish";
T_Damage (other, self, self, self.dmg);
};
void() train_use =
{
if (self.think != func_train_find)

View File

@ -1,3 +1,29 @@
/*
player.qc
player functions/definitions
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
void() bubble_bob;
@ -409,7 +435,7 @@ local float rs;
// water death sounds
if (self.waterlevel == 3)
{
DeathBubbles(20);
DeathBubbles(5);
sound (self, CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NONE);
return;
}
@ -546,8 +572,38 @@ void() GibPlayer =
void() PlayerDie =
{
local float i;
local string s;
self.items = self.items - (self.items & IT_INVISIBILITY);
if ((stof(infokey(world,"dq"))) != 0)
{
if (self.super_damage_finished > 0)
{
DropQuad (self.super_damage_finished - time);
bprint (PRINT_LOW, self.netname);
if (deathmatch == 4)
bprint (PRINT_LOW, " lost an OctaPower with ");
else
bprint (PRINT_LOW, " lost a quad with ");
s = ftos(rint(self.super_damage_finished - time));
bprint (PRINT_LOW, s);
bprint (PRINT_LOW, " seconds remaining\n");
}
}
if ((stof(infokey(world,"dr"))) != 0)
{
if (self.invisible_finished > 0)
{
bprint (PRINT_LOW, self.netname);
bprint (PRINT_LOW, " lost a ring with ");
s = ftos(rint(self.invisible_finished - time));
bprint (PRINT_LOW, s);
bprint (PRINT_LOW, " seconds remaining\n");
DropRing (self.invisible_finished - time);
}
}
self.invisible_finished = 0; // don't die as eyes
self.invincible_finished = 0;
self.super_damage_finished = 0;

View File

@ -1,4 +1,4 @@
../progs.dat
./qwprogs.dat
defs.qc
subs.qc
@ -7,6 +7,7 @@ items.qc
weapons.qc
world.qc
client.qc
spectate.qc
player.qc
doors.qc
buttons.qc

View File

@ -1,3 +1,29 @@
/*
server.qc
server functions (movetarget code)
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
void() monster_ogre = {remove(self);};
void() monster_demon1 = {remove(self);};
@ -14,6 +40,7 @@ void() monster_fish = {remove(self);};
void() monster_shalrath = {remove(self);};
void() monster_enforcer = {remove(self);};
void() monster_oldone = {remove(self);};
void() event_lightning = {remove(self);};
/*
==============================================================================
@ -44,13 +71,13 @@ moving towards it, change the next destination and continue.
*/
void() t_movetarget =
{
local entity temp;
local entity temp;
if (other.movetarget != self)
return;
if (other.enemy)
return; // fighting, not following a path
return; // fighting, not following a path
temp = self;
self = other;

111
spectate.qc Normal file
View File

@ -0,0 +1,111 @@
/*
spectate.qc
spectator functions
PURPOSE
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
// Added Aug11'97 by Zoid <zoid@idsoftware.com>
//
// These functions are called from the server if they exist.
// Note that Spectators only have one think since they movement code doesn't
// track them much. Impulse commands work as usual, but don't call
// the regular ImpulseCommand handler in weapons.qc since Spectators don't
// have any weapons and things can explode.
//
// --- Zoid.
/*
===========
SpectatorConnect
called when a spectator connects to a server
============
*/
void() SpectatorConnect =
{
bprint (PRINT_MEDIUM, "Spectator ");
bprint (PRINT_MEDIUM, self.netname);
bprint (PRINT_MEDIUM, " entered the game\n");
self.goalentity = world; // used for impulse 1 below
};
/*
===========
SpectatorDisconnect
called when a spectator disconnects from a server
============
*/
void() SpectatorDisconnect =
{
bprint (PRINT_MEDIUM, "Spectator ");
bprint (PRINT_MEDIUM, self.netname);
bprint (PRINT_MEDIUM, " left the game\n");
};
/*
================
SpectatorImpulseCommand
Called by SpectatorThink if the spectator entered an impulse
================
*/
void() SpectatorImpulseCommand =
{
if (self.impulse == 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");
if (self.goalentity == world)
self.goalentity = find(self.goalentity, classname, "info_player_deathmatch");
if (self.goalentity != world) {
setorigin(self, self.goalentity.origin);
self.angles = self.goalentity.angles;
self.fixangle = TRUE; // turn this way immediately
}
}
self.impulse = 0;
};
/*
================
SpectatorThink
Called every frame after physics are run
================
*/
void() SpectatorThink =
{
// self.origin, etc contains spectator position, so you could
// do some neat stuff here
if (self.impulse)
SpectatorImpulseCommand();
};

View File

@ -1,3 +1,29 @@
/*
sprites.qc
sprite definitions
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
// these are the only sprites still in the game...

26
subs.qc
View File

@ -1,3 +1,29 @@
/*
subs.qc
sub-functions, mostly movement related
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
void() SUB_Null = {};

View File

@ -1,3 +1,29 @@
/*
triggers.qc
trigger functions
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
entity stemp, otemp, s, old;
@ -318,16 +344,28 @@ void(vector org) spawn_tfog =
void() tdeath_touch =
{
local entity other2;
if (other == self.owner)
return;
// frag anyone who teleports in on top of an invincible player
if (other.classname == "player")
{
if (other.invincible_finished > time &&
self.owner.invincible_finished > time) {
self.classname = "teledeath3";
other.invincible_finished = 0;
self.owner.invincible_finished = 0;
T_Damage (other, self, self, 50000);
other2 = self.owner;
self.owner = other;
T_Damage (other2, self, self, 50000);
}
if (other.invincible_finished > time)
{
self.classname = "teledeath2";
if (self.owner.classname != "player")
{ // other monsters explode themselves
T_Damage (self.owner, self, self, 50000);
return;
}

View File

@ -1,8 +1,33 @@
/*
weapons.qc
weapon and weapon hit functions
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
void () player_run;
void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
void(entity bomb, entity attacker, float rad, entity ignore, string dtype) T_RadiusDamage;
void(vector org, float damage) SpawnBlood;
void() SuperDamageSound;
@ -51,7 +76,10 @@ void() W_FireAxe =
{
trace_ent.axhitme = 1;
SpawnBlood (org, 20);
T_Damage (trace_ent, self, self, 20);
if (deathmatch > 3)
T_Damage (trace_ent, self, self, 75);
else
T_Damage (trace_ent, self, self, 20);
}
else
{ // hit wall
@ -144,7 +172,6 @@ void(float damage) spawn_touchblood =
SpawnBlood (self.origin + vel*0.01, damage);
};
/*
==============================================================================
@ -221,9 +248,7 @@ void() Multi_Finish =
/*
==============================================================================
BULLETS
==============================================================================
*/
@ -279,7 +304,6 @@ void(float shotcount, vector dir, vector spread) FireBullets =
while (shotcount > 0)
{
direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
traceline (src, src + direction*2048, FALSE, self);
if (trace_fraction != 1.0)
@ -305,7 +329,9 @@ void() W_FireShotgun =
msg_entity = self;
WriteByte (MSG_ONE, SVC_SMALLKICK);
self.currentammo = self.ammo_shells = self.ammo_shells - 1;
if (deathmatch != 4 )
self.currentammo = self.ammo_shells = self.ammo_shells - 1;
dir = aim (self, 100000);
FireBullets (6, dir, '0.04 0.04 0');
};
@ -331,7 +357,8 @@ void() W_FireSuperShotgun =
msg_entity = self;
WriteByte (MSG_ONE, SVC_BIGKICK);
self.currentammo = self.ammo_shells = self.ammo_shells - 2;
if (deathmatch != 4)
self.currentammo = self.ammo_shells = self.ammo_shells - 2;
dir = aim (self, 100000);
FireBullets (14, dir, '0.14 0.08 0');
};
@ -349,9 +376,31 @@ void() T_MissileTouch =
{
local float damg;
// if (deathmatch == 4)
// {
// if ( ((other.weapon == 32) || (other.weapon == 16)))
// {
// if (random() < 0.1)
// {
// if (other != world)
// {
// // bprint (PRINT_HIGH, "Got here\n");
// other.deathtype = "blaze";
// T_Damage (other, self, self.owner, 1000 );
// T_RadiusDamage (self, self.owner, 1000, other);
// }
// }
// }
// }
if (other == self.owner)
return; // don't explode on owner
if (self.voided) {
return;
}
self.voided = 1;
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
@ -362,16 +411,17 @@ void() T_MissileTouch =
if (other.health)
{
if (other.classname == "monster_shambler")
damg = damg * 0.5; // mostly immune
other.deathtype = "rocket";
T_Damage (other, self, self.owner, damg );
}
// don't do radius damage to the other, because all the damage
// was done in the impact
T_RadiusDamage (self, self.owner, 120, other);
// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
T_RadiusDamage (self, self.owner, 120, other, "rocket");
// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
self.origin = self.origin - 8 * normalize(self.velocity);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
@ -393,7 +443,8 @@ W_FireRocket
*/
void() W_FireRocket =
{
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
if (deathmatch != 4)
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
@ -413,10 +464,12 @@ void() W_FireRocket =
newmis.angles = vectoangles(newmis.velocity);
newmis.touch = T_MissileTouch;
newmis.voided = 0;
// set newmis duration
newmis.nextthink = time + 5;
newmis.think = SUB_Remove;
newmis.classname = "rocket";
setmodel (newmis, "progs/missile.mdl");
setsize (newmis, '0 0 0', '0 0 0');
@ -425,9 +478,7 @@ void() W_FireRocket =
/*
===============================================================================
LIGHTNING
===============================================================================
*/
@ -463,6 +514,7 @@ void(vector p1, vector p2, entity from, float damage) LightningDamage =
e1 = e2 = world;
traceline (p1, p2, FALSE, self);
if (trace_ent.takedamage)
{
LightningHit (from, damage);
@ -504,11 +556,30 @@ void() W_FireLightning =
// explode if under water
if (self.waterlevel > 1)
{
cells = self.ammo_cells;
self.ammo_cells = 0;
W_SetCurrentAmmo ();
T_RadiusDamage (self, self, 35*cells, world);
return;
if (deathmatch > 3)
{
if (random() <= 0.5)
{
self.deathtype = "selfwater";
T_Damage (self, self, self.owner, 4000 );
}
else
{
cells = self.ammo_cells;
self.ammo_cells = 0;
W_SetCurrentAmmo ();
T_RadiusDamage (self, self, 35*cells, world, "");
return;
}
}
else
{
cells = self.ammo_cells;
self.ammo_cells = 0;
W_SetCurrentAmmo ();
T_RadiusDamage (self, self, 35*cells, world,"");
return;
}
}
if (self.t_width < time)
@ -519,7 +590,8 @@ void() W_FireLightning =
msg_entity = self;
WriteByte (MSG_ONE, SVC_SMALLKICK);
self.currentammo = self.ammo_cells = self.ammo_cells - 1;
if (deathmatch != 4)
self.currentammo = self.ammo_cells = self.ammo_cells - 1;
org = self.origin + '0 0 16';
@ -545,7 +617,12 @@ void() W_FireLightning =
void() GrenadeExplode =
{
T_RadiusDamage (self, self.owner, 120, world);
if (self.voided) {
return;
}
self.voided = 1;
T_RadiusDamage (self, self.owner, 120, world, "grenade");
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_EXPLOSION);
@ -578,7 +655,8 @@ W_FireGrenade
*/
void() W_FireGrenade =
{
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
if (deathmatch != 4)
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
@ -586,6 +664,7 @@ void() W_FireGrenade =
WriteByte (MSG_ONE, SVC_SMALLKICK);
newmis = spawn ();
newmis.voided=0;
newmis.owner = self;
newmis.movetype = MOVETYPE_BOUNCE;
newmis.solid = SOLID_BBOX;
@ -611,7 +690,16 @@ void() W_FireGrenade =
newmis.touch = GrenadeTouch;
// set newmis duration
newmis.nextthink = time + 2.5;
if (deathmatch == 4)
{
newmis.nextthink = time + 2.5;
self.attack_finished = time + 1.1;
// self.health = self.health - 1;
T_Damage (self, self, self.owner, 10 );
}
else
newmis.nextthink = time + 2.5;
newmis.think = GrenadeExplode;
setmodel (newmis, "progs/grenade.mdl");
@ -636,6 +724,7 @@ Used for both the player and the ogre
void(vector org, vector dir) launch_spike =
{
newmis = spawn ();
newmis.voided=0;
newmis.owner = self;
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_BBOX;
@ -660,7 +749,8 @@ void() W_FireSuperSpikes =
sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
self.attack_finished = time + 0.2;
self.currentammo = self.ammo_nails = self.ammo_nails - 2;
if (deathmatch != 4)
self.currentammo = self.ammo_nails = self.ammo_nails - 2;
dir = aim (self, 1000);
launch_spike (self.origin + '0 0 16', dir);
newmis.touch = superspike_touch;
@ -692,7 +782,8 @@ void(float ox) W_FireSpikes =
sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
self.attack_finished = time + 0.2;
self.currentammo = self.ammo_nails = self.ammo_nails - 1;
if (deathmatch != 4)
self.currentammo = self.ammo_nails = self.ammo_nails - 1;
dir = aim (self, 1000);
launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
@ -709,6 +800,11 @@ local float rand;
if (other == self.owner)
return;
if (self.voided) {
return;
}
self.voided = 1;
if (other.solid == SOLID_TRIGGER)
return; // trigger field, do nothing
@ -722,6 +818,7 @@ local float rand;
if (other.takedamage)
{
spawn_touchblood (9);
other.deathtype = "nail";
T_Damage (other, self, self.owner, 9);
}
else
@ -749,6 +846,12 @@ local float rand;
if (other == self.owner)
return;
if (self.voided) {
return;
}
self.voided = 1;
if (other.solid == SOLID_TRIGGER)
return; // trigger field, do nothing
@ -762,6 +865,7 @@ local float rand;
if (other.takedamage)
{
spawn_touchblood (18);
other.deathtype = "supernail";
T_Damage (other, self, self.owner, 18);
}
else

134
world.qc
View File

@ -1,3 +1,29 @@
/*
world.qc
main/world setup functions
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
void() InitBodyQue;
@ -155,7 +181,7 @@ void() main =
};
entity lastspawn;
entity lastspawn;
//=======================
/*QUAKED worldspawn (0 0 0) ?
@ -176,54 +202,52 @@ void() worldspawn =
// custom map attributes
// can't change gravity in QuakeWorld
/*
if (self.model == "maps/e1m8.bsp")
cvar_set ("sv_gravity", "100");
else
cvar_set ("sv_gravity", "800");
*/
// the area based ambient sounds MUST be the first precache_sounds
// player precaches
W_Precache (); // get weapon precaches
// player precaches
W_Precache (); // get weapon precaches
// sounds used from C physics code
precache_sound ("demon/dland2.wav"); // landing thud
precache_sound ("misc/h2ohit1.wav"); // landing splash
precache_sound ("demon/dland2.wav"); // landing thud
precache_sound ("misc/h2ohit1.wav"); // landing splash
// setup precaches allways needed
precache_sound ("items/itembk2.wav"); // item respawn sound
precache_sound ("player/plyrjmp8.wav"); // player jump
precache_sound ("player/land.wav"); // player landing
precache_sound ("player/land2.wav"); // player hurt landing
precache_sound ("player/drown1.wav"); // drowning pain
precache_sound ("player/drown2.wav"); // drowning pain
precache_sound ("player/gasp1.wav"); // gasping for air
precache_sound ("player/gasp2.wav"); // taking breath
precache_sound ("player/h2odeath.wav"); // drowning death
precache_sound ("items/itembk2.wav"); // item respawn sound
precache_sound ("player/plyrjmp8.wav"); // player jump
precache_sound ("player/land.wav"); // player landing
precache_sound ("player/land2.wav"); // player hurt landing
precache_sound ("player/drown1.wav"); // drowning pain
precache_sound ("player/drown2.wav"); // drowning pain
precache_sound ("player/gasp1.wav"); // gasping for air
precache_sound ("player/gasp2.wav"); // taking breath
precache_sound ("player/h2odeath.wav"); // drowning death
precache_sound ("misc/talk.wav"); // talk
precache_sound ("player/teledth1.wav"); // telefrag
precache_sound ("misc/r_tele1.wav"); // teleport sounds
precache_sound ("misc/talk.wav"); // talk
precache_sound ("player/teledth1.wav"); // telefrag
precache_sound ("misc/r_tele1.wav"); // teleport sounds
precache_sound ("misc/r_tele2.wav");
precache_sound ("misc/r_tele3.wav");
precache_sound ("misc/r_tele4.wav");
precache_sound ("misc/r_tele5.wav");
precache_sound ("weapons/lock4.wav"); // ammo pick up
precache_sound ("weapons/pkup.wav"); // weapon up
precache_sound ("items/armor1.wav"); // armor up
precache_sound ("weapons/lhit.wav"); //lightning
precache_sound ("weapons/lstart.wav"); //lightning start
precache_sound ("weapons/lock4.wav"); // ammo pick up
precache_sound ("weapons/pkup.wav"); // weapon up
precache_sound ("items/armor1.wav"); // armor up
precache_sound ("weapons/lhit.wav"); //lightning
precache_sound ("weapons/lstart.wav"); //lightning start
precache_sound ("items/damage3.wav");
precache_sound ("misc/power.wav"); //lightning for boss
precache_sound ("misc/power.wav"); //lightning for boss
// player gib sounds
precache_sound ("player/gib.wav"); // player gib sound
precache_sound ("player/udeath.wav"); // player gib sound
precache_sound ("player/tornoff2.wav"); // gib sound
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
@ -241,22 +265,30 @@ void() worldspawn =
precache_sound ("player/death4.wav");
precache_sound ("player/death5.wav");
// ax sounds
precache_sound ("weapons/ax1.wav"); // ax swoosh
precache_sound ("player/axhit1.wav"); // ax hit meat
precache_sound ("player/axhit2.wav"); // ax hit world
precache_sound ("boss1/sight1.wav");
precache_sound ("player/h2ojump.wav"); // player jumping into water
precache_sound ("player/slimbrn2.wav"); // player enter slime
precache_sound ("player/inh2o.wav"); // player enter water
precache_sound ("player/inlava.wav"); // player enter lava
precache_sound ("misc/outwater.wav"); // leaving water sound
// ax sounds
precache_sound ("weapons/ax1.wav"); // ax swoosh
precache_sound ("player/axhit1.wav"); // ax hit meat
precache_sound ("player/axhit2.wav"); // ax hit world
precache_sound ("player/lburn1.wav"); // lava burn
precache_sound ("player/lburn2.wav"); // lava burn
precache_sound ("player/h2ojump.wav"); // player jumping into water
precache_sound ("player/slimbrn2.wav"); // player enter slime
precache_sound ("player/inh2o.wav"); // player enter water
precache_sound ("player/inlava.wav"); // player enter lava
precache_sound ("misc/outwater.wav"); // leaving water sound
precache_sound ("player/lburn1.wav"); // lava burn
precache_sound ("player/lburn2.wav"); // lava burn
precache_sound ("misc/water1.wav"); // swimming
precache_sound ("misc/water2.wav"); // swimming
// Invulnerability sounds
precache_sound ("items/protect.wav");
precache_sound ("items/protect2.wav");
precache_sound ("items/protect3.wav");
precache_sound ("misc/water1.wav"); // swimming
precache_sound ("misc/water2.wav"); // swimming
precache_model ("progs/player.mdl");
precache_model ("progs/eyes.mdl");
@ -265,8 +297,8 @@ void() worldspawn =
precache_model ("progs/gib2.mdl");
precache_model ("progs/gib3.mdl");
precache_model ("progs/s_bubble.spr"); // drowning bubbles
precache_model ("progs/s_explod.spr"); // sprite explosion
precache_model ("progs/s_bubble.spr"); // drowning bubbles
precache_model ("progs/s_explod.spr"); // sprite explosion
precache_model ("progs/v_axe.mdl");
precache_model ("progs/v_shot.mdl");
@ -276,10 +308,10 @@ void() worldspawn =
precache_model ("progs/v_nail2.mdl");
precache_model ("progs/v_rock2.mdl");
precache_model ("progs/bolt.mdl"); // for lightning gun
precache_model ("progs/bolt2.mdl"); // for lightning gun
precache_model ("progs/bolt3.mdl"); // for boss shock
precache_model ("progs/lavaball.mdl"); // for testing
precache_model ("progs/bolt.mdl"); // for lightning gun
precache_model ("progs/bolt2.mdl"); // for lightning gun
precache_model ("progs/bolt3.mdl"); // for boss shock
precache_model ("progs/lavaball.mdl"); // for testing
precache_model ("progs/missile.mdl");
precache_model ("progs/grenade.mdl");
@ -357,16 +389,16 @@ BODY QUE
==============================================================================
*/
entity bodyque_head;
entity bodyque_head;
void() bodyque =
{ // just here so spawn functions don't complain after the world
{ // just here so spawn functions don't complain after the world
// creates bodyques
};
void() InitBodyQue =
{
local entity e;
local entity e;
bodyque_head = spawn();
bodyque_head.classname = "bodyque";